初始化代码
This commit is contained in:
parent
ac4b051ba0
commit
6650a522cb
|
|
@ -1,4 +1,3 @@
|
|||
# ---> JetBrains
|
||||
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
|
||||
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
|
||||
|
||||
|
|
@ -9,9 +8,6 @@
|
|||
.idea/**/dictionaries
|
||||
.idea/**/shelf
|
||||
|
||||
# AWS User-specific
|
||||
.idea/**/aws.xml
|
||||
|
||||
# Generated files
|
||||
.idea/**/contentModel.xml
|
||||
|
||||
|
|
@ -62,9 +58,6 @@ atlassian-ide-plugin.xml
|
|||
# Cursive Clojure plugin
|
||||
.idea/replstate.xml
|
||||
|
||||
# SonarLint plugin
|
||||
.idea/sonarlint/
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
|
|
@ -76,4 +69,3 @@ fabric.properties
|
|||
|
||||
# Android studio 3.1+ serialized cache file
|
||||
.idea/caches/build_file_checksums.ser
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,135 @@
|
|||
<script>
|
||||
import {
|
||||
mapMutations
|
||||
} from 'vuex'
|
||||
import {
|
||||
version
|
||||
} from './package.json'
|
||||
import checkUpdate from '@/uni_modules/uni-upgrade-center-app/utils/check-update';
|
||||
export default {
|
||||
onLaunch: function() {
|
||||
// #ifdef H5
|
||||
console.log(
|
||||
`%c hello uniapp %c v${version} `,
|
||||
'background:#35495e ; padding: 1px; border-radius: 3px 0 0 3px; color: #fff',
|
||||
'background:#007aff ;padding: 1px; border-radius: 0 3px 3px 0; color: #fff; font-weight: bold;'
|
||||
)
|
||||
// #endif
|
||||
// 线上示例使用
|
||||
// console.log('%c uni-app官方团队诚邀优秀前端工程师加盟,一起打造更卓越的uni-app & uniCloud,欢迎投递简历到 hr2013@dcloud.io', 'color: red');
|
||||
console.log('App Launch');
|
||||
// #ifdef APP-PLUS
|
||||
// App平台检测升级,服务端代码是通过uniCloud的云函数实现的,详情可参考:https://ext.dcloud.net.cn/plugin?id=4542
|
||||
if (plus.runtime.appid !== 'HBuilder') { // 真机运行不需要检查更新,真机运行时appid固定为'HBuilder',这是调试基座的appid
|
||||
checkUpdate()
|
||||
}
|
||||
|
||||
// 一键登录预登陆,可以显著提高登录速度
|
||||
uni.preLogin({
|
||||
provider: 'univerify',
|
||||
success: (res) => {
|
||||
// 成功
|
||||
this.setUniverifyErrorMsg();
|
||||
console.log("preLogin success: ", res);
|
||||
},
|
||||
fail: (res) => {
|
||||
this.setUniverifyLogin(false);
|
||||
this.setUniverifyErrorMsg(res.errMsg);
|
||||
// 失败
|
||||
console.log("preLogin fail res: ", res);
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
onShow: function() {
|
||||
console.log('App Show')
|
||||
},
|
||||
onHide: function() {
|
||||
console.log('App Hide')
|
||||
},
|
||||
globalData: {
|
||||
test: ''
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['setUniverifyErrorMsg', 'setUniverifyLogin'])
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '@/uni_modules/uni-scss/index.scss';
|
||||
/* #ifndef APP-PLUS-NVUE */
|
||||
/* uni.css - 通用组件、模板样式库,可以当作一套ui库应用 */
|
||||
@import './common/uni.css';
|
||||
@import '@/static/customicons.css';
|
||||
/* H5 兼容 pc 所需 */
|
||||
/* #ifdef H5 */
|
||||
@media screen and (min-width: 768px) {
|
||||
body {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
/* 顶栏通栏样式 */
|
||||
/* .uni-top-window {
|
||||
left: 0;
|
||||
right: 0;
|
||||
} */
|
||||
|
||||
uni-page-body {
|
||||
background-color: #F5F5F5 !important;
|
||||
min-height: 100% !important;
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
.uni-top-window uni-tabbar .uni-tabbar {
|
||||
background-color: #fff !important;
|
||||
}
|
||||
|
||||
.uni-app--showleftwindow .hideOnPc {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
|
||||
/* 以下样式用于 hello uni-app 演示所需 */
|
||||
page {
|
||||
background-color: #efeff4;
|
||||
height: 100%;
|
||||
font-size: 28rpx;
|
||||
/* line-height: 1.8; */
|
||||
}
|
||||
|
||||
.fix-pc-padding {
|
||||
padding: 0 50px;
|
||||
}
|
||||
|
||||
.uni-header-logo {
|
||||
padding: 30rpx;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
|
||||
.uni-header-image {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.uni-hello-text {
|
||||
color: #7A7E83;
|
||||
}
|
||||
|
||||
.uni-hello-addfile {
|
||||
text-align: center;
|
||||
line-height: 300rpx;
|
||||
background: #FFF;
|
||||
padding: 50rpx;
|
||||
margin-top: 10px;
|
||||
font-size: 38rpx;
|
||||
color: #808080;
|
||||
}
|
||||
|
||||
/* #endif*/
|
||||
</style>
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2018 DCloud
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
40
README.md
40
README.md
|
|
@ -1,3 +1,39 @@
|
|||
# yitisheng-mini-app
|
||||
# zyb-mini-app
|
||||
|
||||
艺体生 微信小程序 前端代码
|
||||
#### 介绍
|
||||
{**以下是 Gitee 平台说明,您可以替换此简介**
|
||||
Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台
|
||||
无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
|
||||
|
||||
#### 软件架构
|
||||
软件架构说明
|
||||
|
||||
|
||||
#### 安装教程
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### 使用说明
|
||||
|
||||
1. xxxx
|
||||
2. xxxx
|
||||
3. xxxx
|
||||
|
||||
#### 参与贡献
|
||||
|
||||
1. Fork 本仓库
|
||||
2. 新建 Feat_xxx 分支
|
||||
3. 提交代码
|
||||
4. 新建 Pull Request
|
||||
|
||||
|
||||
#### 特技
|
||||
|
||||
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
|
||||
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
|
||||
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
|
||||
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
|
||||
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
|
||||
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,173 @@
|
|||
## 3.4.5(2024-01-11)
|
||||
- 新增 uni-calendar显示
|
||||
## 3.4.4(2024-01-11)
|
||||
- 新增 同步 uni-ui@1.4.20
|
||||
- uni-forms 【重要】组件逻辑重构,部分用法旧版本不兼容,请注意兼容问题
|
||||
- uni-section 新增组件
|
||||
## 3.4.3(2022-07-14)
|
||||
- 修复 HBuilderX 拉取 hello uni-app 项目直接运行提示无服务空间关联的bug
|
||||
## 3.4.2(2022-07-06)
|
||||
- 新增 同步 uni-ui@1.4.18
|
||||
- uni-forms 【重要】组件逻辑重构,部分用法旧版本不兼容,请注意兼容问题
|
||||
- uni-forms 【重要】组件使用 Provide/Inject 方式注入依赖,提供了自定义表单组件调用 uni-forms 校验表单的能力
|
||||
- uni-forms 新增 更多表单示例
|
||||
- uni-forms 新增 model 属性,等同于原 value/modelValue 属性,旧属性即将废弃
|
||||
- uni-forms 新增 validateTrigger 属性的 blur 值,仅 uni-easyinput 生效
|
||||
- uni-forms 新增 onFieldChange 方法,可以对子表单进行校验,可替代binddata方法
|
||||
- uni-forms 新增 子表单的 setRules 方法,配合自定义校验函数使用
|
||||
- uni-forms 新增 uni-forms-item 的 setRules 方法,配置动态表单使用可动态更新校验规则
|
||||
- uni-forms 修复 由 1.4.0 引发的 label 插槽不生效的bug
|
||||
- uni-forms 修复 子组件找不到 setValue 报错的bug
|
||||
- uni-forms 修复 uni-data-picker 在 uni-forms-item 中报错的bug
|
||||
- uni-forms 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
|
||||
- uni-forms 修复 表单校验顺序无序问题
|
||||
- uni-forms 优化 子表单组件uni-datetime-picker、uni-data-select、uni-data-picker的显示样式
|
||||
- uni-forms 优化 动态表单校验方式,废弃拼接name的方式
|
||||
- uni-breadcrumb 修复 微信小程序 separator 不显示问题
|
||||
- uni-data-checkbox 优化 在 uni-forms 中的依赖注入方式
|
||||
- uni-data-picker 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
|
||||
- uni-data-picker 优化 显示样式
|
||||
- uni-data-select 优化 显示样式
|
||||
- uni-datetime-picker 修复 日历顶部年月及底部确认未国际化 bug
|
||||
- uni-datetime-picker 优化 组件样式,调整了组件图标大小、高度、颜色等,与uni-ui风格保持一致
|
||||
- uni-easyinput 新增 在 uni-forms 1.4.0 中使用可以在 blur 时校验内容
|
||||
- uni-easyinput 新增 clear 事件,点击右侧叉号图标触发
|
||||
- uni-easyinput 新增 change 事件 ,仅在输入框失去焦点或用户按下回车时触发
|
||||
- uni-easyinput 优化 组件样式,组件获取焦点时高亮显示,图标颜色调整等
|
||||
- uni-easyinput 优化 clearable 显示策略
|
||||
- uni-file-picker 修复 在uni-forms下样式不生效的bug
|
||||
- uni-nav-bar 修复 组件示例中插槽用法无法显示内容的bug
|
||||
- uni-swipe-action 修复 vue3 下使用组件不能正常运行的Bug
|
||||
- uni-swipe-action 修复 h5端点击click触发两次的Bug
|
||||
- uni-table 修复 微信小程序存在无使用组件的问题
|
||||
## 3.4.1(2022-06-30)
|
||||
- 新增 支持 ios 安全区
|
||||
## 3.3.8(2022-05-08)
|
||||
- 新增 同步 uni-ui@1.4.15
|
||||
- uni-data-picker 修复 字节小程序 本地数据无法选择下一级的Bug
|
||||
- uni-data-select 新增 记住上次的选项(仅 collection 存在时有效)
|
||||
- uni-search-bar 修复 vue3 input 事件不生效的bug
|
||||
- uni-search-bar 修复 多余代码导致的bug
|
||||
- uni-tooltip 更新 text 属性变更为 content
|
||||
- uni-tooltip 更新 移除 width 属性
|
||||
- uni-tooltip 修复 组件根 text 嵌套组件 warning
|
||||
## 3.3.7(2022-04-06)
|
||||
- 新增 更新扩展组件 uni-nav-bar、uni-list 的展示页面
|
||||
## 3.3.6(2022-03-31)
|
||||
- 更新 uni-ui 组件及示例
|
||||
## 3.3.5(2022-03-30)
|
||||
- 修复 插槽兼容 vue3, slot -> v-slot
|
||||
- 新增 更新 uni-ui
|
||||
## 3.3.4(2022-02-25)
|
||||
- 修复 编译到 App 平台的控制台报错
|
||||
## 3.3.3(2022-02-23)
|
||||
- 修复 模板城市选择 vue3 报错的bug
|
||||
- 修复 删除 map.nvue 中多余的 enableOverlooking 变量
|
||||
- 修复 swipe-dot.nvue 中条件编译媒体查询
|
||||
## 3.3.2(2022-01-26)
|
||||
- 修复 默认运行到 vue2
|
||||
## 3.3.1(2022-01-26)
|
||||
- 新增 同步 uni-ui@1.4.11
|
||||
- uni-collapse 修复 微信小程序resize后组件收起的bug
|
||||
- uni-countdown 修复 在微信小程序中样式不生效的bug
|
||||
- uni-countdown 新增 update 方法 ,在动态更新时间后,刷新组件
|
||||
- uni-load-more 新增 showText属性 ,是否显示文本
|
||||
- uni-load-more 修复 nvue 平台下不显示文本的bug
|
||||
- uni-load-more 修复 微信小程序平台样式选择器报警告的问题
|
||||
- uni-nav-bar 修复 在vue下,标题不垂直居中的bug
|
||||
- uni-nav-bar 修复 height 属性类型错误
|
||||
- uni-nav-bar 新增 height 属性,可修改组件高度
|
||||
- uni-nav-bar 新增 dark 属性可可开启暗黑模式
|
||||
- uni-nav-bar 优化 标题字数过多显示省略号
|
||||
- uni-nav-bar 优化 插槽,插入内容可完全覆盖
|
||||
- uni-popup 修复 isMaskClick 失效的bug
|
||||
- uni-popup 新增 cancelText \ confirmText 属性 ,可自定义文本
|
||||
- uni-popup 新增 maskBackgroundColor 属性 ,可以修改蒙版颜色
|
||||
- uni-popup 优化 maskClick属性 更新为 isMaskClick ,解决微信小程序警告的问题
|
||||
## 3.3.0(2022-01-04)
|
||||
- 修复 开发时在 vue3 下由 pc 端切换到手机端,不能返回上一级页面的 bug
|
||||
- 优化 去掉 pc 端 topwindow 右上角用于演示的 url 导航
|
||||
## 3.2.12(2021-12-20)
|
||||
- 新增 适配京东小程序
|
||||
## 3.2.11(2021-12-07)
|
||||
- 修复 uni-ui 在 hello-uniapp 中丢失图标、ui 受到公共样式影响等问题
|
||||
- 修复 微信登录取值报错的问题
|
||||
## 3.2.10(2021-11-30)
|
||||
- 修复 map 组件示例不显示的 bug
|
||||
## 3.2.9(2021-11-19)
|
||||
- 新增 uni-ui 以 uni_modules 方式引入,方便开发者从 hello-uniapp 中 copy 组件及示例
|
||||
- 优化 uni-ui 示例页面,完善组件示例
|
||||
## 3.2.8(2021-11-10)
|
||||
- 新增 适配飞书平台(lark)
|
||||
## 3.2.7(2021-10-26)
|
||||
- 修复 uni-popup 示例的 button 文字在 iPhone 5 上换行的 bug
|
||||
- 修复 uni-table 示例,页面顶部距离不对的 bug
|
||||
- 修复 GlobalData示例,在vue3是无效的 bug
|
||||
- 优化 删除无用的 project.swan.json 文件
|
||||
## 3.2.6(2021-10-08)
|
||||
- 由于体验问题,暂时撤销 uni-ui 以 uni_modules 方式引入的修改
|
||||
|
||||
## 3.2.4(2021-09-07)
|
||||
- 修复 vue3 在 H5 编译报错的 bug
|
||||
- 新增 同步 uni-ui
|
||||
- 新增 uni-ui 组件支持国际化 i18n
|
||||
- uni-data-checkbox 修复 在uni-forms中 modelValue 中不存在当前字段,当前字段必填写也不参与校验的问题
|
||||
- uni-datetime-picker 优化 取消选中时(范围选)直接开始下一次选择, 避免多点一次
|
||||
- uni-datetime-picker 优化 移动端支持清除按钮,同时支持通过 ref 调用组件的 clear 方法
|
||||
- uni-datetime-picker 优化 调整字号大小,美化日历界面
|
||||
- uni-datetime-picker 修复 因国际化导致的 placeholder 失效的 bug
|
||||
- uni-file-picker 修复 return-type="object" 时且存在v-model时,无法删除文件的Bug
|
||||
- uni-file-picker 新增 参数中返回 fileID 字段
|
||||
- uni-file-picker 修复 腾讯云传入fileID 不能回显的bug
|
||||
- uni-file-picker 修复 选择图片后,不能放大的问题
|
||||
- uni-link 修复 在 nvue 下不显示的 bug
|
||||
- uni-list 修复 在vue3中to属性在发行应用的时候报错的bug
|
||||
- uni-search-bar 修复 value 属性与 modelValue 属性不兼容的Bug
|
||||
- uni-swipe-action 优化 close-all 方法
|
||||
- uni-collapse 优化 show-arrow 属性默认为true
|
||||
- uni-collapse 新增 show-arrow 属性,控制是否显示右侧箭头
|
||||
- uni-data-checkbox 修复 单选 list 模式下 ,icon 为 left 时,选中图标不显示的问题
|
||||
- uni-easyinput 修复 在 uni-forms 的动态表单中默认值校验不通过的 bug
|
||||
- uni-file-picker 修复 由于 0.2.11 版本引起的不能回显图片的Bug
|
||||
- uni-file-picker 新增 clearFiles(index) 方法,可以手动删除指定文件
|
||||
- uni-file-picker 修复 v-model 值设为 null 报错的Bug
|
||||
- uni-swipe-action 新增 close-all 方法,关闭所有已打开的组件
|
||||
- uni-swipe-action 新增 resize() 方法,在非微信小程序、h5、app-vue端出现不能滑动的问题的时候,重置组件
|
||||
- uni-swipe-action 修复 app 端偶尔出现类似 Page[x][-x,xx;-x,xx,x,x-x] 的问题
|
||||
- uni-swipe-action 优化 微信小程序、h5、app-vue 滑动逻辑,避免出现动态新增组件后不能滑动的问题
|
||||
|
||||
|
||||
## 3.2.3(2021-08-27)
|
||||
- 优化 tabbar 页面移除 vuex 相关代码
|
||||
- 新增 适配 vue3 (app)
|
||||
## 3.2.2(2021-08-10)
|
||||
- 新增 适配快手小程序
|
||||
- 新增 同步 uni-ui
|
||||
- uni-datetime-picker 新增 return-type 属性支持返回 date 日期对象
|
||||
- uni-file-picker 修复 fileExtname属性不指定值报错的Bug
|
||||
- uni-file-picker 修复 在某种场景下图片不回显的Bug
|
||||
- uni-link 支持自定义插槽
|
||||
- uni-calendar 修复 弹出层被 tabbar 遮盖 bug
|
||||
- uni-dateformat 调整 默认时间不再是当前时间,而是显示'-'字符
|
||||
- uni-datetime-picker 新增 适配 vue3
|
||||
- uni-datetime-picker 新增 支持作为 uni-forms 子组件相关功能
|
||||
- uni-datetime-picker 修复 在 uni-forms 中使用时,选择时间报 NAN 错误的 bug
|
||||
- uni-datetime-picker 修复 type 属性动态赋值无效的 bug
|
||||
- uni-datetime-picker 修复 ‘确认’按钮被 tabbar 遮盖 bug
|
||||
- uni-datetime-picker 修复 组件未赋值时范围选左、右日历相同的 bug
|
||||
- uni-datetime-picker 修复 范围选未正确显示当前值的 bug
|
||||
- uni-datetime-picker 修复 h5 平台(移动端)报错 'cale' of undefined 的 bug
|
||||
- uni-file-picker 修复 auto-upload 属性失效的Bug
|
||||
## 3.2.1(2021-07-31)
|
||||
- 新增 同步 uni-ui@1.3.8
|
||||
## 3.2.0(2021-07-30)
|
||||
- 新增 同时兼容 vue2 & vue3
|
||||
## 3.1.20(2021-07-30)
|
||||
- 新增 同时兼容 vue2 & vue3
|
||||
## 3.1.17(2021-05-26)
|
||||
- 修复 3.1.16 依赖 sass 的问题
|
||||
- 条件编译 nuve 不支持 css 属性
|
||||
## 3.1.16(2021-05-26)
|
||||
- 修复 uni-data-checkbox 不关联服务空间的情况下组件报错的 Bug
|
||||
## 3.1.12(2021-05-07)
|
||||
- hello-uniapp 发布插件市场
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
export default {
|
||||
Major: {
|
||||
recommendMajorPage: '/art/recommendMajor/page',//获取推荐专业列表
|
||||
recommendMajorList: '/art/recommendMajor/list',//获取学校的其他专业
|
||||
schoolMajorDtoPage: '/yx/yxSchoolMajor/dtoPage',//获取学校开设专业分页数据
|
||||
schoolHistoryMajorEnrollList: '/yx/yxHistoryMajorEnroll/list',//获取学校的分数计划
|
||||
schoolMajorList: '/yx/yxSchoolMajor/list',//获取school_major 数据
|
||||
majorList: '/yx/yxMajor/list',//获取专业信息表-分页列表查询
|
||||
majorInfo: '/art/major/majorInfo',//获取专业详情
|
||||
},
|
||||
//用户类
|
||||
User: {
|
||||
exchangeVipCard: '/yx/yxVipCard/exchange',//兑换vip卡
|
||||
},
|
||||
System: {
|
||||
findPassWord: '/sys/findPassWord',//找回密码
|
||||
register: '/sys/register',//注册
|
||||
},
|
||||
//高考分数类
|
||||
Score: {
|
||||
scoreSave: "/yx/yxScore/save",//保存用户专业得分
|
||||
getScore: "/yx/yxScore/getUserScoreInfo",//获取当前用户的高考分数信息
|
||||
conversionScoreBatch: "/yx/yxHistoryScoreBatch/conversionScoreBatch",//获取分数批次段
|
||||
historyScoreControlLineList: '/yx/yxHistoryScoreControlLine/list',//省控线分页列表
|
||||
},
|
||||
//学校类
|
||||
School: {
|
||||
searchSchoolList: "/art/school/search",//搜索 学校列表
|
||||
schoolInfo: "/art/school/schoolInfo",//学校介绍详情
|
||||
hotSchoolList: '/art/school/hotList',//热门院校 列表
|
||||
},
|
||||
//志愿
|
||||
Volunteer: {
|
||||
volunteerSave: "/art/volunteer/save",//保存用户的志愿
|
||||
//volunteerList:'/art/volunteer/list',
|
||||
volunteerInfo: '/art/volunteer/info',//当前使用中志愿单详情
|
||||
volunteerPage: '/art/volunteer/page',//志愿单列表
|
||||
volunteerDelete:'/art/volunteer/delete',//志愿单删除
|
||||
artVolunteerDetail:'/art/volunteer/artVolunteerDetail',//根据id获取志愿单详情
|
||||
volunteerRecordDel: '/art/volunteer/recordDel',//删除志愿明细(失效了)
|
||||
volunteerRecordDelete:'/art/volunteer/volunteerRecordDelete',//删除志愿明细
|
||||
volunteerRecordReplace: '/art/volunteer/replaceVolunteer',//替换志愿明细
|
||||
}
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,262 @@
|
|||
export default {
|
||||
"list": [{
|
||||
"letter": "A",
|
||||
"data": [
|
||||
"阿克苏机场",
|
||||
"阿拉山口机场",
|
||||
"阿勒泰机场",
|
||||
"阿里昆莎机场",
|
||||
"安庆天柱山机场",
|
||||
"澳门国际机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "B",
|
||||
"data": [
|
||||
"保山机场",
|
||||
"包头机场",
|
||||
"北海福成机场",
|
||||
"北京南苑机场",
|
||||
"北京首都国际机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "C",
|
||||
"data": [
|
||||
"长白山机场",
|
||||
"长春龙嘉国际机场",
|
||||
"常德桃花源机场",
|
||||
"昌都邦达机场",
|
||||
"长沙黄花国际机场",
|
||||
"长治王村机场",
|
||||
"常州奔牛机场",
|
||||
"成都双流国际机场",
|
||||
"赤峰机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "D",
|
||||
"data": [
|
||||
"大理机场",
|
||||
"大连周水子国际机场",
|
||||
"大庆萨尔图机场",
|
||||
"大同东王庄机场",
|
||||
"达州河市机场",
|
||||
"丹东浪头机场",
|
||||
"德宏芒市机场",
|
||||
"迪庆香格里拉机场",
|
||||
"东营机场",
|
||||
"敦煌机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "E",
|
||||
"data": [
|
||||
"鄂尔多斯机场",
|
||||
"恩施许家坪机场",
|
||||
"二连浩特赛乌苏国际机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "F",
|
||||
"data": [
|
||||
"阜阳西关机场",
|
||||
"福州长乐国际机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "G",
|
||||
"data": [
|
||||
"赣州黄金机场",
|
||||
"格尔木机场",
|
||||
"固原六盘山机场",
|
||||
"广元盘龙机场",
|
||||
"广州白云国际机场",
|
||||
"桂林两江国际机场",
|
||||
"贵阳龙洞堡国际机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "H",
|
||||
"data": [
|
||||
"哈尔滨太平国际机场",
|
||||
"哈密机场",
|
||||
"海口美兰国际机场",
|
||||
"海拉尔东山国际机场",
|
||||
"邯郸机场",
|
||||
"汉中机场",
|
||||
"杭州萧山国际机场",
|
||||
"合肥骆岗国际机场",
|
||||
"和田机场",
|
||||
"黑河机场",
|
||||
"呼和浩特白塔国际机场",
|
||||
"淮安涟水机场",
|
||||
"黄山屯溪国际机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "I",
|
||||
"data": []
|
||||
}, {
|
||||
"letter": "J",
|
||||
"data": [
|
||||
"济南遥墙国际机场",
|
||||
"济宁曲阜机场",
|
||||
"鸡西兴凯湖机场",
|
||||
"佳木斯东郊机场",
|
||||
"嘉峪关机场",
|
||||
"锦州小岭子机场",
|
||||
"景德镇机场",
|
||||
"井冈山机场",
|
||||
"九江庐山机场",
|
||||
"九寨黄龙机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "K",
|
||||
"data": [
|
||||
"喀什机场",
|
||||
"克拉玛依机场",
|
||||
"库车龟兹机场",
|
||||
"库尔勒机场",
|
||||
"昆明巫家坝国际机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "L",
|
||||
"data": [
|
||||
"拉萨贡嘎机场",
|
||||
"兰州中川机场",
|
||||
"丽江三义机场",
|
||||
"黎平机场",
|
||||
"连云港白塔埠机场",
|
||||
"临沧机场",
|
||||
"临沂机场",
|
||||
"林芝米林机场",
|
||||
"柳州白莲机场",
|
||||
"龙岩冠豸山机场",
|
||||
"泸州蓝田机场",
|
||||
"洛阳北郊机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "M",
|
||||
"data": [
|
||||
"满洲里西郊机场",
|
||||
"绵阳南郊机场",
|
||||
"漠河古莲机场",
|
||||
"牡丹江海浪机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "N",
|
||||
"data": [
|
||||
"南昌昌北国际机场",
|
||||
"南充高坪机场",
|
||||
"南京禄口国际机场",
|
||||
"南宁吴圩机场",
|
||||
"南通兴东机场",
|
||||
"南阳姜营机场",
|
||||
"宁波栎社国际机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "O",
|
||||
"data": []
|
||||
}, {
|
||||
"letter": "P",
|
||||
"data": [
|
||||
"普洱思茅机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "Q",
|
||||
"data": [
|
||||
"齐齐哈尔三家子机场",
|
||||
"秦皇岛山海关机场",
|
||||
"青岛流亭国际机场",
|
||||
"衢州机场",
|
||||
"泉州晋江机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "R",
|
||||
"data": [
|
||||
"日喀则和平机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "S",
|
||||
"data": [
|
||||
"三亚凤凰国际机场",
|
||||
"汕头外砂机场",
|
||||
"上海虹桥国际机场",
|
||||
"上海浦东国际机场",
|
||||
"深圳宝安国际机场",
|
||||
"沈阳桃仙国际机场",
|
||||
"石家庄正定国际机场",
|
||||
"苏南硕放国际机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "T",
|
||||
"data": [
|
||||
"塔城机场",
|
||||
"太原武宿国际机场",
|
||||
"台州路桥机场 (黄岩机场)",
|
||||
"唐山三女河机场",
|
||||
"腾冲驼峰机场",
|
||||
"天津滨海国际机场",
|
||||
"通辽机场",
|
||||
"铜仁凤凰机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "U",
|
||||
"data": []
|
||||
}, {
|
||||
"letter": "V",
|
||||
"data": []
|
||||
}, {
|
||||
"letter": "W",
|
||||
"data": [
|
||||
"万州五桥机场",
|
||||
"潍坊机场",
|
||||
"威海大水泊机场",
|
||||
"文山普者黑机场",
|
||||
"温州永强国际机场",
|
||||
"乌海机场",
|
||||
"武汉天河国际机场",
|
||||
"乌兰浩特机场",
|
||||
"乌鲁木齐地窝堡国际机场",
|
||||
"武夷山机场",
|
||||
"梧州长洲岛机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "X",
|
||||
"data": [
|
||||
"西安咸阳国际机场",
|
||||
"西昌青山机场",
|
||||
"锡林浩特机场",
|
||||
"西宁曹家堡机场",
|
||||
"西双版纳嘎洒机场",
|
||||
"厦门高崎国际机场",
|
||||
"香港国际机场",
|
||||
"襄阳刘集机场",
|
||||
"兴义机场",
|
||||
"徐州观音机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "Y",
|
||||
"data": [
|
||||
"延安二十里堡机场",
|
||||
"盐城机场",
|
||||
"延吉朝阳川机场",
|
||||
"烟台莱山国际机场",
|
||||
"宜宾菜坝机场",
|
||||
"宜昌三峡机场",
|
||||
"伊春林都机场",
|
||||
"伊宁机场",
|
||||
"义乌机场",
|
||||
"银川河东机场",
|
||||
"永州零陵机场",
|
||||
"榆林榆阳机场",
|
||||
"玉树巴塘机场",
|
||||
"运城张孝机场"
|
||||
]
|
||||
}, {
|
||||
"letter": "Z",
|
||||
"data": [
|
||||
"湛江机场",
|
||||
"昭通机场",
|
||||
"郑州新郑国际机场",
|
||||
"芷江机场",
|
||||
"重庆江北国际机场",
|
||||
"中卫香山机场",
|
||||
"舟山朱家尖机场",
|
||||
"珠海三灶机场"
|
||||
]
|
||||
}]
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/**
|
||||
数据验证(表单验证)
|
||||
来自 grace.hcoder.net
|
||||
作者 hcoder 深海
|
||||
*/
|
||||
export default {
|
||||
error:'',
|
||||
check : function (data, rule){
|
||||
for(var i = 0; i < rule.length; i++){
|
||||
if (!rule[i].checkType){return true;}
|
||||
if (!rule[i].name) {return true;}
|
||||
if (!rule[i].errorMsg) {return true;}
|
||||
if (!data[rule[i].name]) {this.error = rule[i].errorMsg; return false;}
|
||||
switch (rule[i].checkType){
|
||||
case 'string':
|
||||
var reg = new RegExp('^.{' + rule[i].checkRule + '}$');
|
||||
if(!reg.test(data[rule[i].name])) {this.error = rule[i].errorMsg; return false;}
|
||||
break;
|
||||
case 'int':
|
||||
var reg = new RegExp('^(-[1-9]|[1-9])[0-9]{' + rule[i].checkRule + '}$');
|
||||
if(!reg.test(data[rule[i].name])) {this.error = rule[i].errorMsg; return false;}
|
||||
break;
|
||||
break;
|
||||
case 'between':
|
||||
if (!this.isNumber(data[rule[i].name])){
|
||||
this.error = rule[i].errorMsg;
|
||||
return false;
|
||||
}
|
||||
var minMax = rule[i].checkRule.split(',');
|
||||
minMax[0] = Number(minMax[0]);
|
||||
minMax[1] = Number(minMax[1]);
|
||||
if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
|
||||
this.error = rule[i].errorMsg;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'betweenD':
|
||||
var reg = /^-?[1-9][0-9]?$/;
|
||||
if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
|
||||
var minMax = rule[i].checkRule.split(',');
|
||||
minMax[0] = Number(minMax[0]);
|
||||
minMax[1] = Number(minMax[1]);
|
||||
if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
|
||||
this.error = rule[i].errorMsg;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'betweenF':
|
||||
var reg = /^-?[0-9][0-9]?.+[0-9]+$/;
|
||||
if (!reg.test(data[rule[i].name])){this.error = rule[i].errorMsg; return false;}
|
||||
var minMax = rule[i].checkRule.split(',');
|
||||
minMax[0] = Number(minMax[0]);
|
||||
minMax[1] = Number(minMax[1]);
|
||||
if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
|
||||
this.error = rule[i].errorMsg;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 'same':
|
||||
if (data[rule[i].name] != rule[i].checkRule) { this.error = rule[i].errorMsg; return false;}
|
||||
break;
|
||||
case 'notsame':
|
||||
if (data[rule[i].name] == rule[i].checkRule) { this.error = rule[i].errorMsg; return false; }
|
||||
break;
|
||||
case 'email':
|
||||
var reg = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
|
||||
if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
|
||||
break;
|
||||
case 'phoneno':
|
||||
var reg = /^1[0-9]{10,10}$/;
|
||||
if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
|
||||
break;
|
||||
case 'zipcode':
|
||||
var reg = /^[0-9]{6}$/;
|
||||
if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
|
||||
break;
|
||||
case 'reg':
|
||||
var reg = new RegExp(rule[i].checkRule);
|
||||
if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
|
||||
break;
|
||||
case 'in':
|
||||
if(rule[i].checkRule.indexOf(data[rule[i].name]) == -1){
|
||||
this.error = rule[i].errorMsg; return false;
|
||||
}
|
||||
break;
|
||||
case 'notnull':
|
||||
if(data[rule[i].name] == null || data[rule[i].name].length < 1){this.error = rule[i].errorMsg; return false;}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
isNumber : function (checkVal){
|
||||
var reg = /^-?[1-9][0-9]?.?[0-9]*$/;
|
||||
return reg.test(checkVal);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,352 @@
|
|||
/*
|
||||
* HTML5 Parser By Sam Blowes
|
||||
*
|
||||
* Designed for HTML5 documents
|
||||
*
|
||||
* Original code by John Resig (ejohn.org)
|
||||
* http://ejohn.org/blog/pure-javascript-html-parser/
|
||||
* Original code by Erik Arvidsson, Mozilla Public License
|
||||
* http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
* License
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* This code is triple licensed using Apache Software License 2.0,
|
||||
* Mozilla Public License or GNU Public License
|
||||
*
|
||||
* ////////////////////////////////////////////////////////////////////////////
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||
* use this file except in compliance with the License. You may obtain a copy
|
||||
* of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* ////////////////////////////////////////////////////////////////////////////
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License
|
||||
* Version 1.1 (the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Simple HTML Parser.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Erik Arvidsson.
|
||||
* Portions created by Erik Arvidssson are Copyright (C) 2004. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* ////////////////////////////////////////////////////////////////////////////
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* ----------------------------------------------------------------------------
|
||||
* Usage
|
||||
* ----------------------------------------------------------------------------
|
||||
*
|
||||
* // Use like so:
|
||||
* HTMLParser(htmlString, {
|
||||
* start: function(tag, attrs, unary) {},
|
||||
* end: function(tag) {},
|
||||
* chars: function(text) {},
|
||||
* comment: function(text) {}
|
||||
* });
|
||||
*
|
||||
* // or to get an XML string:
|
||||
* HTMLtoXML(htmlString);
|
||||
*
|
||||
* // or to get an XML DOM Document
|
||||
* HTMLtoDOM(htmlString);
|
||||
*
|
||||
* // or to inject into an existing document/DOM node
|
||||
* HTMLtoDOM(htmlString, document);
|
||||
* HTMLtoDOM(htmlString, document.body);
|
||||
*
|
||||
*/
|
||||
// Regular Expressions for parsing tags and attributes
|
||||
var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
|
||||
var endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/;
|
||||
var attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; // Empty Elements - HTML 5
|
||||
|
||||
var empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'); // Block Elements - HTML 5
|
||||
// fixed by xxx 将 ins 标签从块级名单中移除
|
||||
|
||||
var block = makeMap('a,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video'); // Inline Elements - HTML 5
|
||||
|
||||
var inline = makeMap('abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'); // Elements that you can, intentionally, leave open
|
||||
// (and which close themselves)
|
||||
|
||||
var closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); // Attributes that have their values filled in disabled="disabled"
|
||||
|
||||
var fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'); // Special Elements (can contain anything)
|
||||
|
||||
var special = makeMap('script,style');
|
||||
function HTMLParser(html, handler) {
|
||||
var index;
|
||||
var chars;
|
||||
var match;
|
||||
var stack = [];
|
||||
var last = html;
|
||||
|
||||
stack.last = function () {
|
||||
return this[this.length - 1];
|
||||
};
|
||||
|
||||
while (html) {
|
||||
chars = true; // Make sure we're not in a script or style element
|
||||
|
||||
if (!stack.last() || !special[stack.last()]) {
|
||||
// Comment
|
||||
if (html.indexOf('<!--') == 0) {
|
||||
index = html.indexOf('-->');
|
||||
|
||||
if (index >= 0) {
|
||||
if (handler.comment) {
|
||||
handler.comment(html.substring(4, index));
|
||||
}
|
||||
|
||||
html = html.substring(index + 3);
|
||||
chars = false;
|
||||
} // end tag
|
||||
|
||||
} else if (html.indexOf('</') == 0) {
|
||||
match = html.match(endTag);
|
||||
|
||||
if (match) {
|
||||
html = html.substring(match[0].length);
|
||||
match[0].replace(endTag, parseEndTag);
|
||||
chars = false;
|
||||
} // start tag
|
||||
|
||||
} else if (html.indexOf('<') == 0) {
|
||||
match = html.match(startTag);
|
||||
|
||||
if (match) {
|
||||
html = html.substring(match[0].length);
|
||||
match[0].replace(startTag, parseStartTag);
|
||||
chars = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (chars) {
|
||||
index = html.indexOf('<');
|
||||
var text = index < 0 ? html : html.substring(0, index);
|
||||
html = index < 0 ? '' : html.substring(index);
|
||||
|
||||
if (handler.chars) {
|
||||
handler.chars(text);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
html = html.replace(new RegExp('([\\s\\S]*?)<\/' + stack.last() + '[^>]*>'), function (all, text) {
|
||||
text = text.replace(/<!--([\s\S]*?)-->|<!\[CDATA\[([\s\S]*?)]]>/g, '$1$2');
|
||||
|
||||
if (handler.chars) {
|
||||
handler.chars(text);
|
||||
}
|
||||
|
||||
return '';
|
||||
});
|
||||
parseEndTag('', stack.last());
|
||||
}
|
||||
|
||||
if (html == last) {
|
||||
throw 'Parse Error: ' + html;
|
||||
}
|
||||
|
||||
last = html;
|
||||
} // Clean up any remaining tags
|
||||
|
||||
|
||||
parseEndTag();
|
||||
|
||||
function parseStartTag(tag, tagName, rest, unary) {
|
||||
tagName = tagName.toLowerCase();
|
||||
|
||||
if (block[tagName]) {
|
||||
while (stack.last() && inline[stack.last()]) {
|
||||
parseEndTag('', stack.last());
|
||||
}
|
||||
}
|
||||
|
||||
if (closeSelf[tagName] && stack.last() == tagName) {
|
||||
parseEndTag('', tagName);
|
||||
}
|
||||
|
||||
unary = empty[tagName] || !!unary;
|
||||
|
||||
if (!unary) {
|
||||
stack.push(tagName);
|
||||
}
|
||||
|
||||
if (handler.start) {
|
||||
var attrs = [];
|
||||
rest.replace(attr, function (match, name) {
|
||||
var value = arguments[2] ? arguments[2] : arguments[3] ? arguments[3] : arguments[4] ? arguments[4] : fillAttrs[name] ? name : '';
|
||||
attrs.push({
|
||||
name: name,
|
||||
value: value,
|
||||
escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') // "
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
if (handler.start) {
|
||||
handler.start(tagName, attrs, unary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function parseEndTag(tag, tagName) {
|
||||
// If no tag name is provided, clean shop
|
||||
if (!tagName) {
|
||||
var pos = 0;
|
||||
} // Find the closest opened tag of the same type
|
||||
else {
|
||||
for (var pos = stack.length - 1; pos >= 0; pos--) {
|
||||
if (stack[pos] == tagName) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pos >= 0) {
|
||||
// Close all the open elements, up the stack
|
||||
for (var i = stack.length - 1; i >= pos; i--) {
|
||||
if (handler.end) {
|
||||
handler.end(stack[i]);
|
||||
}
|
||||
} // Remove the open elements from the stack
|
||||
|
||||
|
||||
stack.length = pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function makeMap(str) {
|
||||
var obj = {};
|
||||
var items = str.split(',');
|
||||
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
obj[items[i]] = true;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
function removeDOCTYPE(html) {
|
||||
return html.replace(/<\?xml.*\?>\n/, '').replace(/<!doctype.*>\n/, '').replace(/<!DOCTYPE.*>\n/, '');
|
||||
}
|
||||
|
||||
function parseAttrs(attrs) {
|
||||
return attrs.reduce(function (pre, attr) {
|
||||
var value = attr.value;
|
||||
var name = attr.name;
|
||||
|
||||
if (pre[name]) {
|
||||
pre[name] = pre[name] + " " + value;
|
||||
} else {
|
||||
pre[name] = value;
|
||||
}
|
||||
|
||||
return pre;
|
||||
}, {});
|
||||
}
|
||||
|
||||
function parseHtml(html) {
|
||||
html = removeDOCTYPE(html);
|
||||
var stacks = [];
|
||||
var results = {
|
||||
node: 'root',
|
||||
children: []
|
||||
};
|
||||
HTMLParser(html, {
|
||||
start: function start(tag, attrs, unary) {
|
||||
var node = {
|
||||
name: tag
|
||||
};
|
||||
|
||||
if (attrs.length !== 0) {
|
||||
node.attrs = parseAttrs(attrs);
|
||||
}
|
||||
|
||||
if (unary) {
|
||||
var parent = stacks[0] || results;
|
||||
|
||||
if (!parent.children) {
|
||||
parent.children = [];
|
||||
}
|
||||
|
||||
parent.children.push(node);
|
||||
} else {
|
||||
stacks.unshift(node);
|
||||
}
|
||||
},
|
||||
end: function end(tag) {
|
||||
var node = stacks.shift();
|
||||
if (node.name !== tag) console.error('invalid state: mismatch end tag');
|
||||
|
||||
if (stacks.length === 0) {
|
||||
results.children.push(node);
|
||||
} else {
|
||||
var parent = stacks[0];
|
||||
|
||||
if (!parent.children) {
|
||||
parent.children = [];
|
||||
}
|
||||
|
||||
parent.children.push(node);
|
||||
}
|
||||
},
|
||||
chars: function chars(text) {
|
||||
var node = {
|
||||
type: 'text',
|
||||
text: text
|
||||
};
|
||||
|
||||
if (stacks.length === 0) {
|
||||
results.children.push(node);
|
||||
} else {
|
||||
var parent = stacks[0];
|
||||
|
||||
if (!parent.children) {
|
||||
parent.children = [];
|
||||
}
|
||||
|
||||
parent.children.push(node);
|
||||
}
|
||||
},
|
||||
comment: function comment(text) {
|
||||
var node = {
|
||||
node: 'comment',
|
||||
text: text
|
||||
};
|
||||
var parent = stacks[0];
|
||||
|
||||
if (!parent.children) {
|
||||
parent.children = [];
|
||||
}
|
||||
|
||||
parent.children.push(node);
|
||||
}
|
||||
});
|
||||
return results.children;
|
||||
}
|
||||
|
||||
export default parseHtml;
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
export default {
|
||||
//接口
|
||||
api: "http://127.0.0.1:8080/jeecg-boot/",
|
||||
/*api: function () {
|
||||
let version = wx.getAccountInfoSync().miniProgram.envVersion;
|
||||
switch (version) {
|
||||
case "dev": //开发预览版
|
||||
return "http://127.0.0.1:8080/jeecg-boot/"
|
||||
break;
|
||||
case 'prod': //正式版
|
||||
return "http://127.0.0.1:8080/jeecg-boot/"
|
||||
break;
|
||||
default: //未知,默认调用正式版
|
||||
return "http://127.0.0.1:8080/jeecg-boot/"
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
/*网络请求*/
|
||||
import operate from '@/common/operate'
|
||||
// vuex 的使用 详情参考官网 https://uniapp.dcloud.io/vue-vuex
|
||||
import store from '../store/index.js'
|
||||
let token= uni.getStorageSync('token')
|
||||
token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3MDU4ODQ5MDYsInVzZXJuYW1lIjoid2FuZ3hpYW9taW5nIn0.jRSoihlbs08ONDIsrk2U3l3pw8ZQK2Z1Oc2-mQaf7pw'
|
||||
export default class Request {
|
||||
http(param) {
|
||||
// 请求参数
|
||||
var url = param.url,
|
||||
method = param.method,
|
||||
header = {
|
||||
'X-Access-Token':param.token || "",
|
||||
},
|
||||
data = param.data || {},
|
||||
hideLoading = param.hideLoading || false;
|
||||
/*token = param.token || "",*/
|
||||
|
||||
//拼接完整请求地址
|
||||
var requestUrl = operate.api + url;
|
||||
console.log(requestUrl)
|
||||
//拼接完整请求地址(根据环境切换)
|
||||
// var requestUrl = operate.api() + url;
|
||||
|
||||
//请求方式:GET或POST(POST需配置
|
||||
// header: {'content-type' : "application/x-www-form-urlencoded"},)
|
||||
if (method) {
|
||||
method = method.toUpperCase(); //小写改为大写
|
||||
if (method === "POST") {
|
||||
header = {"content-type":'application/json',...header}
|
||||
} else {
|
||||
header = {"content-type":'application/x-www-form-urlencoded',...header}
|
||||
}
|
||||
}
|
||||
|
||||
//加载圈
|
||||
if (!hideLoading) {
|
||||
uni.showLoading({
|
||||
title: '加载中...'
|
||||
});
|
||||
}
|
||||
|
||||
// 返回promise
|
||||
return new Promise((resolve, reject) => {
|
||||
// 请求
|
||||
uni.request({
|
||||
url: requestUrl,
|
||||
data: data,
|
||||
method: method,
|
||||
header: header,
|
||||
success: (res) => {
|
||||
console.log('执行http请求')
|
||||
// 判断 请求api 格式是否正确
|
||||
/*if (res.statusCode && res.statusCode != 200) {
|
||||
uni.showToast({
|
||||
title: "api错误" + res.errMsg,
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}*/
|
||||
// 将结果抛出
|
||||
resolve(res.data)
|
||||
},
|
||||
//请求失败
|
||||
fail: (e) => {
|
||||
uni.showToast({
|
||||
title: "" + e.data.msg,
|
||||
icon: 'none'
|
||||
});
|
||||
resolve(e.data);
|
||||
},
|
||||
//请求完成
|
||||
complete() {
|
||||
//隐藏加载
|
||||
if (!hideLoading) {
|
||||
uni.hideLoading();
|
||||
}
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
get(url,data,options={}){
|
||||
options.method='get';
|
||||
options.data=data;
|
||||
options.url=url;
|
||||
options.token=token;
|
||||
return this.http(options);
|
||||
}
|
||||
get(url,data,headers={},options={}){
|
||||
options.method='get';
|
||||
options.data=data;
|
||||
options.url=url;
|
||||
options.token=token;
|
||||
return this.http(options);
|
||||
}
|
||||
|
||||
post(url,data,options={}){
|
||||
options.method='post';
|
||||
options.data=data;
|
||||
options.url=url;
|
||||
options.token=token;
|
||||
return this.http(options);
|
||||
}
|
||||
|
||||
post(url,data,headers={},options={}){
|
||||
options.method='post';
|
||||
options.data=data;
|
||||
options.url=url;
|
||||
options.token=token;
|
||||
return this.http(options);
|
||||
}
|
||||
|
||||
delete(url,data,options={}){
|
||||
options.method='delete';
|
||||
options.data=data;
|
||||
options.url=url;
|
||||
options.token=token;
|
||||
return this.http(options);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
/* #ifndef APP-PLUS-NVUE */
|
||||
page {
|
||||
min-height: 100%;
|
||||
height: auto;
|
||||
}
|
||||
/* #endif */
|
||||
|
||||
/* 解决头条小程序字体图标不显示问题,因为头条运行时自动插入了span标签,且有全局字体 */
|
||||
/* #ifdef MP-TOUTIAO */
|
||||
/* text :not(view) {
|
||||
font-family: uniicons;
|
||||
} */
|
||||
/* #endif */
|
||||
|
||||
.uni-icon {
|
||||
font-family: uniicons;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.uni-container {
|
||||
padding: 15px;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.uni-header-logo {
|
||||
/* #ifdef H5 */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
padding: 15px 15px;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
|
||||
.uni-header-image {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.uni-hello-text {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.hello-text {
|
||||
color: #7A7E83;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.hello-link {
|
||||
color: #7A7E83;
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.uni-panel {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.uni-panel-h {
|
||||
/* #ifdef H5 */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
background-color: #ffffff;
|
||||
flex-direction: row !important;
|
||||
/* justify-content: space-between !important; */
|
||||
align-items: center !important;
|
||||
padding: 12px;
|
||||
/* #ifdef H5 */
|
||||
cursor: pointer;
|
||||
/* #endif */
|
||||
}
|
||||
/*
|
||||
.uni-panel-h:active {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
*/
|
||||
.uni-panel-h-on {
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
.uni-panel-text {
|
||||
flex: 1;
|
||||
color: #000000;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.uni-panel-icon {
|
||||
margin-left: 15px;
|
||||
color: #999999;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
transform: rotate(0deg);
|
||||
transition-duration: 0s;
|
||||
transition-property: transform;
|
||||
}
|
||||
|
||||
.uni-panel-icon-on {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
|
||||
.uni-navigate-item {
|
||||
/* #ifdef H5 */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
background-color: #FFFFFF;
|
||||
border-top-style: solid;
|
||||
border-top-color: #f0f0f0;
|
||||
border-top-width: 1px;
|
||||
padding: 12px;
|
||||
/* #ifdef H5 */
|
||||
cursor: pointer;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-navigate-item:active {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
|
||||
.uni-navigate-text {
|
||||
flex: 1;
|
||||
color: #000000;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.uni-navigate-icon {
|
||||
margin-left: 15px;
|
||||
color: #999999;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,73 @@
|
|||
function 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(':')
|
||||
}
|
||||
|
||||
function formatLocation(longitude, latitude) {
|
||||
if (typeof longitude === 'string' && typeof latitude === 'string') {
|
||||
longitude = parseFloat(longitude)
|
||||
latitude = parseFloat(latitude)
|
||||
}
|
||||
|
||||
longitude = longitude.toFixed(2)
|
||||
latitude = latitude.toFixed(2)
|
||||
|
||||
return {
|
||||
longitude: longitude.toString().split('.'),
|
||||
latitude: latitude.toString().split('.')
|
||||
}
|
||||
}
|
||||
var dateUtils = {
|
||||
UNITS: {
|
||||
'年': 31557600000,
|
||||
'月': 2629800000,
|
||||
'天': 86400000,
|
||||
'小时': 3600000,
|
||||
'分钟': 60000,
|
||||
'秒': 1000
|
||||
},
|
||||
humanize: function(milliseconds) {
|
||||
var humanize = '';
|
||||
for (var key in this.UNITS) {
|
||||
if (milliseconds >= this.UNITS[key]) {
|
||||
humanize = Math.floor(milliseconds / this.UNITS[key]) + key + '前';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return humanize || '刚刚';
|
||||
},
|
||||
format: function(dateStr) {
|
||||
var date = this.parse(dateStr)
|
||||
var diff = Date.now() - date.getTime();
|
||||
if (diff < this.UNITS['天']) {
|
||||
return this.humanize(diff);
|
||||
}
|
||||
var _format = function(number) {
|
||||
return (number < 10 ? ('0' + number) : number);
|
||||
};
|
||||
return date.getFullYear() + '/' + _format(date.getMonth() + 1) + '/' + _format(date.getDate()) + '-' +
|
||||
_format(date.getHours()) + ':' + _format(date.getMinutes());
|
||||
},
|
||||
parse: function(str) { //将"yyyy-mm-dd HH:MM:ss"格式的字符串,转化为一个Date对象
|
||||
var a = str.split(/[^0-9]/);
|
||||
return new Date(a[0], a[1] - 1, a[2], a[3], a[4], a[5]);
|
||||
}
|
||||
};
|
||||
|
||||
export {
|
||||
formatTime,
|
||||
formatLocation,
|
||||
dateUtils
|
||||
}
|
||||
|
|
@ -0,0 +1,181 @@
|
|||
import amap from '@/components/amap-wx/lib/amap-wx.js';
|
||||
// 地铁颜色图
|
||||
const line = {
|
||||
'1号线': '#C43B33',
|
||||
'2号线': '#016299',
|
||||
'4号线/大兴线': '#008E9C',
|
||||
'5号线': '#A42380',
|
||||
'6号线': '#D09900',
|
||||
'7号线': '#F2C172',
|
||||
'8号线': '#009D6A',
|
||||
'9号线': '#8FC41E',
|
||||
'10号线': '#009DBE',
|
||||
'13号线': '#F9E701',
|
||||
'14号线东段': '#D4A7A2',
|
||||
'14号线西段': '#D4A7A2',
|
||||
'15号线': '#5D2D69',
|
||||
'八通线': '#C33A32',
|
||||
'昌平线': '#DE82B1',
|
||||
'亦庄线': '#E40177',
|
||||
'房山线': '#E66021',
|
||||
'机场线': '#A29BBC',
|
||||
}
|
||||
|
||||
// 150500:地铁站 ,150700:公交站 , 190700:地名地址
|
||||
const typecode = [{
|
||||
id: '150500',
|
||||
icon: 'icon-ditie'
|
||||
}, {
|
||||
id: '150700',
|
||||
icon: 'icon-gongjiao'
|
||||
}, {
|
||||
id: '190700',
|
||||
icon: 'icon-gonglu'
|
||||
}];
|
||||
|
||||
const util = {
|
||||
key:'b526b09b86cd2996e7732be8ab8c4430',
|
||||
/**
|
||||
* 初始化高德地图api
|
||||
*/
|
||||
mapInit() {
|
||||
return new amap.AMapWX({
|
||||
key: this.key
|
||||
});
|
||||
},
|
||||
// 服务状态吗
|
||||
typecode,
|
||||
/**
|
||||
* 获取地图颜色
|
||||
*/
|
||||
lineColor(name) {
|
||||
if (line[name]) {
|
||||
return line[name];
|
||||
} else {
|
||||
return '#ccc';
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 关键字颜色变化
|
||||
*/
|
||||
serachNmme(val, name) {
|
||||
let namestr = new RegExp(val);
|
||||
let nameresult =
|
||||
`<div style="font-size: 14px;color: #333;line-height: 1.5;">
|
||||
${name.replace(namestr, "<span style='color:#66ccff;'>" + val + '</span>')}
|
||||
</div>`
|
||||
.trim();
|
||||
|
||||
return nameresult;
|
||||
},
|
||||
/**
|
||||
* 地址转地铁线路
|
||||
*/
|
||||
addressToLine(address, type) {
|
||||
let addr = address.split(';');
|
||||
let dt = '';
|
||||
addr.forEach(elm => {
|
||||
let color = '#cccccc';
|
||||
if (type === typecode[0].id) {
|
||||
color = this.lineColor(elm)
|
||||
} else if (type === typecode[1].id) {
|
||||
color = '#4075cb'
|
||||
}
|
||||
let style = 'margin:5px 0;margin-right:5px;padding:0 5px;background:' + color +
|
||||
';font-size:12px;color:#fff;border-radius:3px;';
|
||||
dt += `<div style=\'${style}\'>${elm}</div>`;
|
||||
|
||||
});
|
||||
return `<div style="display:flex;flex-wrap: wrap;">${dt}</div>`;
|
||||
},
|
||||
/**
|
||||
* 数据处理
|
||||
*/
|
||||
dataHandle(item, val) {
|
||||
// 改变字体颜色
|
||||
if (val) {
|
||||
item.nameNodes = util.serachNmme(val, item.name);
|
||||
} else {
|
||||
item.nameNodes = `<div style="font-size: 14px;color: #333;line-height: 1.5;">${item.name}</div>`;
|
||||
|
||||
}
|
||||
// 地址解析 地铁
|
||||
if (
|
||||
item.typecode === util.typecode[0].id ||
|
||||
item.typecode === util.typecode[1].id
|
||||
) {
|
||||
item.addressNodes = util.addressToLine(item.address, item.typecode);
|
||||
if (item.typecode === util.typecode[0].id) {
|
||||
item.icon = util.typecode[0].icon;
|
||||
} else if (item.typecode === util.typecode[1].id) {
|
||||
item.icon = util.typecode[1].icon;
|
||||
}
|
||||
} else {
|
||||
item.addressNodes = `<span>${item.district}${
|
||||
item.address.length > 0 ? '·' + item.address : ''
|
||||
}</span>`.trim();
|
||||
item.icon = 'icon-weizhi';
|
||||
}
|
||||
|
||||
if (item.location && item.location.length === 0) {
|
||||
item.icon = 'icon-sousuo';
|
||||
}
|
||||
|
||||
return item;
|
||||
},
|
||||
/**
|
||||
* 存储历史数据
|
||||
* val [string | object]需要存储的内容
|
||||
*/
|
||||
setHistory(val) {
|
||||
let searchHistory = uni.getStorageSync('search:history');
|
||||
if (!searchHistory) searchHistory = [];
|
||||
let serachData = {};
|
||||
if (typeof(val) === 'string') {
|
||||
serachData = {
|
||||
adcode: [],
|
||||
address: [],
|
||||
city: [],
|
||||
district: [],
|
||||
id: [],
|
||||
location: [],
|
||||
name: val,
|
||||
typecode: []
|
||||
};
|
||||
} else {
|
||||
serachData = val
|
||||
}
|
||||
|
||||
// 判断数组是否存在,如果存在,那么将放到最前面
|
||||
for (var i = 0; i < searchHistory.length; i++) {
|
||||
if (searchHistory[i].name === serachData.name) {
|
||||
searchHistory.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
searchHistory.unshift(util.dataHandle(serachData));
|
||||
uni.setStorage({
|
||||
key: 'search:history',
|
||||
data: searchHistory,
|
||||
success: function() {
|
||||
// console.log('success');
|
||||
}
|
||||
});
|
||||
},
|
||||
getHistory() {
|
||||
|
||||
},
|
||||
removeHistory() {
|
||||
uni.removeStorage({
|
||||
key: 'search:history',
|
||||
success: function(res) {
|
||||
console.log('success');
|
||||
}
|
||||
});
|
||||
return []
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default util;
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,156 @@
|
|||
<template>
|
||||
<view class="uni-padding-wrap">
|
||||
<page-head :title="title"></page-head>
|
||||
<button class="button" @click="setTabBarBadge">{{ !hasSetTabBarBadge ? '设置tab徽标' : '移除tab徽标' }}</button>
|
||||
<button class="button" @click="showTabBarRedDot">{{ !hasShownTabBarRedDot ? '显示红点' : '移除红点'}}</button>
|
||||
<button class="button" @click="customStyle">{{ !hasCustomedStyle ? '自定义Tab样式' : '移除自定义样式'}}</button>
|
||||
<button class="button" @click="customItem">{{ !hasCustomedItem ? '自定义Tab信息' : '移除自定义信息' }}</button>
|
||||
<button class="button" @click="hideTabBar">{{ !hasHiddenTabBar ? '隐藏TabBar' : '显示TabBar' }}</button>
|
||||
<view class="btn-area">
|
||||
<button class="button" type="primary" @click="navigateBack">返回上一级</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'tababr',
|
||||
hasSetTabBarBadge: false,
|
||||
hasShownTabBarRedDot: false,
|
||||
hasCustomedStyle: false,
|
||||
hasCustomedItem: false,
|
||||
hasHiddenTabBar: false
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
if (this.hasSetTabBarBadge) {
|
||||
uni.removeTabBarBadge({
|
||||
index: 1
|
||||
})
|
||||
}
|
||||
if (this.hasShownTabBarRedDot) {
|
||||
uni.hideTabBarRedDot({
|
||||
index: 1
|
||||
})
|
||||
}
|
||||
if (this.hasHiddenTabBar) {
|
||||
uni.showTabBar()
|
||||
}
|
||||
if (this.hasCustomedStyle) {
|
||||
uni.setTabBarStyle({
|
||||
color: '#7A7E83',
|
||||
selectedColor: '#007AFF',
|
||||
backgroundColor: '#F8F8F8',
|
||||
borderStyle: 'black'
|
||||
})
|
||||
}
|
||||
|
||||
if (this.hasCustomedItem) {
|
||||
let tabBarOptions = {
|
||||
index: 1,
|
||||
text: '接口',
|
||||
iconPath: '/static/api.png',
|
||||
selectedIconPath: '/static/apiHL.png'
|
||||
}
|
||||
uni.setTabBarItem(tabBarOptions)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
navigateBack() {
|
||||
this.$emit('unmount')
|
||||
},
|
||||
setTabBarBadge() {
|
||||
if(this.hasShownTabBarRedDot){
|
||||
uni.hideTabBarRedDot({
|
||||
index: 1
|
||||
})
|
||||
this.hasShownTabBarRedDot = !this.hasShownTabBarRedDot
|
||||
}
|
||||
if (!this.hasSetTabBarBadge) {
|
||||
uni.setTabBarBadge({
|
||||
index: 1,
|
||||
text: '1'
|
||||
})
|
||||
} else {
|
||||
uni.removeTabBarBadge({
|
||||
index: 1
|
||||
})
|
||||
}
|
||||
this.hasSetTabBarBadge = !this.hasSetTabBarBadge
|
||||
},
|
||||
showTabBarRedDot() {
|
||||
if(this.hasSetTabBarBadge) {
|
||||
uni.removeTabBarBadge({
|
||||
index: 1
|
||||
})
|
||||
this.hasSetTabBarBadge = !this.hasSetTabBarBadge
|
||||
}
|
||||
if (!this.hasShownTabBarRedDot) {
|
||||
uni.showTabBarRedDot({
|
||||
index: 1
|
||||
})
|
||||
} else {
|
||||
uni.hideTabBarRedDot({
|
||||
index: 1
|
||||
})
|
||||
}
|
||||
this.hasShownTabBarRedDot = !this.hasShownTabBarRedDot
|
||||
},
|
||||
hideTabBar() {
|
||||
if (!this.hasHiddenTabBar) {
|
||||
uni.hideTabBar()
|
||||
} else {
|
||||
uni.showTabBar()
|
||||
}
|
||||
this.hasHiddenTabBar = !this.hasHiddenTabBar
|
||||
},
|
||||
customStyle() {
|
||||
if (this.hasCustomedStyle) {
|
||||
uni.setTabBarStyle({
|
||||
color: '#7A7E83',
|
||||
selectedColor: '#007AFF',
|
||||
backgroundColor: '#F8F8F8',
|
||||
borderStyle: 'black'
|
||||
})
|
||||
} else {
|
||||
uni.setTabBarStyle({
|
||||
color: '#FFF',
|
||||
selectedColor: '#007AFF',
|
||||
backgroundColor: '#000000',
|
||||
borderStyle: 'black'
|
||||
})
|
||||
}
|
||||
this.hasCustomedStyle = !this.hasCustomedStyle
|
||||
},
|
||||
customItem() {
|
||||
let tabBarOptions = {
|
||||
index: 1,
|
||||
text: '接口',
|
||||
iconPath: '/static/api.png',
|
||||
selectedIconPath: '/static/apiHL.png'
|
||||
}
|
||||
if (this.hasCustomedItem) {
|
||||
uni.setTabBarItem(tabBarOptions)
|
||||
} else {
|
||||
tabBarOptions.text = 'API'
|
||||
uni.setTabBarItem(tabBarOptions)
|
||||
}
|
||||
this.hasCustomedItem = !this.hasCustomedItem
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.button {
|
||||
margin-top: 30rpx;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.btn-area {
|
||||
padding-top: 30rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1 @@
|
|||
export default './lib/marked'
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,139 @@
|
|||
/* eslint-disable */
|
||||
var provinceData = [{
|
||||
"label": "北京市",
|
||||
"value": "11"
|
||||
},
|
||||
{
|
||||
"label": "天津市",
|
||||
"value": "12"
|
||||
},
|
||||
{
|
||||
"label": "河北省",
|
||||
"value": "13"
|
||||
},
|
||||
{
|
||||
"label": "山西省",
|
||||
"value": "14"
|
||||
},
|
||||
{
|
||||
"label": "内蒙古自治区",
|
||||
"value": "15"
|
||||
},
|
||||
{
|
||||
"label": "辽宁省",
|
||||
"value": "21"
|
||||
},
|
||||
{
|
||||
"label": "吉林省",
|
||||
"value": "22"
|
||||
},
|
||||
{
|
||||
"label": "黑龙江省",
|
||||
"value": "23"
|
||||
},
|
||||
{
|
||||
"label": "上海市",
|
||||
"value": "31"
|
||||
},
|
||||
{
|
||||
"label": "江苏省",
|
||||
"value": "32"
|
||||
},
|
||||
{
|
||||
"label": "浙江省",
|
||||
"value": "33"
|
||||
},
|
||||
{
|
||||
"label": "安徽省",
|
||||
"value": "34"
|
||||
},
|
||||
{
|
||||
"label": "福建省",
|
||||
"value": "35"
|
||||
},
|
||||
{
|
||||
"label": "江西省",
|
||||
"value": "36"
|
||||
},
|
||||
{
|
||||
"label": "山东省",
|
||||
"value": "37"
|
||||
},
|
||||
{
|
||||
"label": "河南省",
|
||||
"value": "41"
|
||||
},
|
||||
{
|
||||
"label": "湖北省",
|
||||
"value": "42"
|
||||
},
|
||||
{
|
||||
"label": "湖南省",
|
||||
"value": "43"
|
||||
},
|
||||
{
|
||||
"label": "广东省",
|
||||
"value": "44"
|
||||
},
|
||||
{
|
||||
"label": "广西壮族自治区",
|
||||
"value": "45"
|
||||
},
|
||||
{
|
||||
"label": "海南省",
|
||||
"value": "46"
|
||||
},
|
||||
{
|
||||
"label": "重庆市",
|
||||
"value": "50"
|
||||
},
|
||||
{
|
||||
"label": "四川省",
|
||||
"value": "51"
|
||||
},
|
||||
{
|
||||
"label": "贵州省",
|
||||
"value": "52"
|
||||
},
|
||||
{
|
||||
"label": "云南省",
|
||||
"value": "53"
|
||||
},
|
||||
{
|
||||
"label": "西藏自治区",
|
||||
"value": "54"
|
||||
},
|
||||
{
|
||||
"label": "陕西省",
|
||||
"value": "61"
|
||||
},
|
||||
{
|
||||
"label": "甘肃省",
|
||||
"value": "62"
|
||||
},
|
||||
{
|
||||
"label": "青海省",
|
||||
"value": "63"
|
||||
},
|
||||
{
|
||||
"label": "宁夏回族自治区",
|
||||
"value": "64"
|
||||
},
|
||||
{
|
||||
"label": "新疆维吾尔自治区",
|
||||
"value": "65"
|
||||
},
|
||||
{
|
||||
"label": "台湾",
|
||||
"value": "66"
|
||||
},
|
||||
{
|
||||
"label": "香港",
|
||||
"value": "67"
|
||||
},
|
||||
{
|
||||
"label": "澳门",
|
||||
"value": "68"
|
||||
}
|
||||
]
|
||||
export default provinceData;
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
<template>
|
||||
<div class="mpvue-picker">
|
||||
<div :class="{'pickerMask':showPicker}" @click="maskClick" catchtouchmove="true"></div>
|
||||
<div class="mpvue-picker-content " :class="{'mpvue-picker-view-show':showPicker}">
|
||||
<div class="mpvue-picker__hd" catchtouchmove="true">
|
||||
<div class="mpvue-picker__action" @click="pickerCancel">取消</div>
|
||||
<div class="mpvue-picker__action" :style="{color:themeColor}" @click="pickerConfirm">确定</div>
|
||||
</div>
|
||||
<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue" @change="pickerChange">
|
||||
<block>
|
||||
<picker-view-column>
|
||||
<div class="picker-item" v-for="(item,index) in provinceDataList" :key="index">{{item.label}}</div>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<div class="picker-item" v-for="(item,index) in cityDataList" :key="index">{{item.label}}</div>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<div class="picker-item" v-for="(item,index) in areaDataList" :key="index">{{item.label}}</div>
|
||||
</picker-view-column>
|
||||
</block>
|
||||
</picker-view>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import provinceData from './city-data/province.js';
|
||||
import cityData from './city-data/city.js';
|
||||
import areaData from './city-data/area.js';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pickerValue: [0, 0, 0],
|
||||
provinceDataList: provinceData,
|
||||
cityDataList: cityData[0],
|
||||
areaDataList: areaData[0][0],
|
||||
/* 是否显示控件 */
|
||||
showPicker: false,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.init()
|
||||
},
|
||||
props: {
|
||||
/* 默认值 */
|
||||
pickerValueDefault: {
|
||||
type: Array,
|
||||
default () {
|
||||
return [0, 0, 0]
|
||||
}
|
||||
},
|
||||
/* 主题色 */
|
||||
themeColor: String
|
||||
},
|
||||
watch: {
|
||||
pickerValueDefault() {
|
||||
this.init();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.handPickValueDefault(); // 对 pickerValueDefault 做兼容处理
|
||||
|
||||
const pickerValueDefault = this.pickerValueDefault
|
||||
|
||||
this.cityDataList = cityData[pickerValueDefault[0]];
|
||||
this.areaDataList = areaData[pickerValueDefault[0]][pickerValueDefault[1]];
|
||||
this.pickerValue = pickerValueDefault;
|
||||
},
|
||||
show() {
|
||||
setTimeout(() => {
|
||||
this.showPicker = true;
|
||||
}, 0);
|
||||
},
|
||||
maskClick() {
|
||||
this.pickerCancel();
|
||||
},
|
||||
pickerCancel() {
|
||||
this.showPicker = false;
|
||||
this._$emit('onCancel');
|
||||
},
|
||||
pickerConfirm(e) {
|
||||
this.showPicker = false;
|
||||
this._$emit('onConfirm');
|
||||
},
|
||||
showPickerView() {
|
||||
this.showPicker = true;
|
||||
},
|
||||
handPickValueDefault() {
|
||||
const pickerValueDefault = this.pickerValueDefault
|
||||
|
||||
let provinceIndex = pickerValueDefault[0]
|
||||
let cityIndex = pickerValueDefault[1]
|
||||
const areaIndex = pickerValueDefault[2]
|
||||
if (
|
||||
provinceIndex !== 0 ||
|
||||
cityIndex !== 0 ||
|
||||
areaIndex !== 0
|
||||
) {
|
||||
if (provinceIndex > provinceData.length - 1) {
|
||||
this.pickerValueDefault[0] = provinceIndex = provinceData.length - 1;
|
||||
}
|
||||
if (cityIndex > cityData[provinceIndex].length - 1) {
|
||||
this.pickerValueDefault[1] = cityIndex = cityData[provinceIndex].length - 1;
|
||||
}
|
||||
if (areaIndex > areaData[provinceIndex][cityIndex].length - 1) {
|
||||
this.pickerValueDefault[2] = areaData[provinceIndex][cityIndex].length - 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
pickerChange(e) {
|
||||
let changePickerValue = e.mp.detail.value;
|
||||
if (this.pickerValue[0] !== changePickerValue[0]) {
|
||||
// 第一级发生滚动
|
||||
this.cityDataList = cityData[changePickerValue[0]];
|
||||
this.areaDataList = areaData[changePickerValue[0]][0];
|
||||
changePickerValue[1] = 0;
|
||||
changePickerValue[2] = 0;
|
||||
} else if (this.pickerValue[1] !== changePickerValue[1]) {
|
||||
// 第二级滚动
|
||||
this.areaDataList =
|
||||
areaData[changePickerValue[0]][changePickerValue[1]];
|
||||
changePickerValue[2] = 0;
|
||||
}
|
||||
this.pickerValue = changePickerValue;
|
||||
this._$emit('onChange');
|
||||
},
|
||||
_$emit(emitName) {
|
||||
let pickObj = {
|
||||
label: this._getLabel(),
|
||||
value: this.pickerValue,
|
||||
cityCode: this._getCityCode()
|
||||
};
|
||||
this.$emit(emitName, pickObj);
|
||||
},
|
||||
_getLabel() {
|
||||
let pcikerLabel =
|
||||
this.provinceDataList[this.pickerValue[0]].label +
|
||||
'-' +
|
||||
this.cityDataList[this.pickerValue[1]].label +
|
||||
'-' +
|
||||
this.areaDataList[this.pickerValue[2]].label;
|
||||
return pcikerLabel;
|
||||
},
|
||||
_getCityCode() {
|
||||
return this.areaDataList[this.pickerValue[2]].value;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.pickerMask {
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
.mpvue-picker-content {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
transition: all 0.3s ease;
|
||||
transform: translateY(100%);
|
||||
z-index: 3000;
|
||||
}
|
||||
|
||||
.mpvue-picker-view-show {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.mpvue-picker__hd {
|
||||
display: flex;
|
||||
padding: 9px 15px;
|
||||
background-color: #fff;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
.mpvue-picker__hd:after {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
color: #e5e5e5;
|
||||
transform-origin: 0 100%;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
|
||||
.mpvue-picker__action {
|
||||
display: block;
|
||||
flex: 1;
|
||||
color: #1aad19;
|
||||
}
|
||||
|
||||
.mpvue-picker__action:first-child {
|
||||
text-align: left;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.mpvue-picker__action:last-child {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.picker-item {
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.mpvue-picker-view {
|
||||
position: relative;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 238px;
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
<template>
|
||||
<canvas v-if="canvasId" class="ec-canvas" :id="canvasId" :canvasId="canvasId" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" @error="error"></canvas>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import WxCanvas from './wx-canvas';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
canvasId: {
|
||||
type: String,
|
||||
default: 'ec-canvas'
|
||||
},
|
||||
lazyLoad: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
disableTouch: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
throttleTouch: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
// #ifdef H5
|
||||
mounted() {
|
||||
if (!this.lazyLoad) this.init();
|
||||
},
|
||||
// #endif
|
||||
// #ifndef H5
|
||||
onReady() {
|
||||
if (!this.lazyLoad) this.init();
|
||||
},
|
||||
// #endif
|
||||
methods: {
|
||||
setChart(chart){
|
||||
this.chart = chart
|
||||
},
|
||||
init() {
|
||||
const { canvasId } = this;
|
||||
this.ctx = wx.createCanvasContext(canvasId, this);
|
||||
|
||||
this.canvas = new WxCanvas(this.ctx, canvasId);
|
||||
|
||||
const query = wx.createSelectorQuery().in(this);
|
||||
query
|
||||
.select(`#${canvasId}`)
|
||||
.boundingClientRect(res => {
|
||||
if (!res) {
|
||||
setTimeout(() => this.init(), 50);
|
||||
return;
|
||||
}
|
||||
this.$emit('onInit', {
|
||||
width: res.width,
|
||||
height: res.height
|
||||
});
|
||||
})
|
||||
.exec();
|
||||
},
|
||||
canvasToTempFilePath(opt) {
|
||||
const { canvasId } = this;
|
||||
this.ctx.draw(true, () => {
|
||||
wx.canvasToTempFilePath({
|
||||
canvasId,
|
||||
...opt
|
||||
});
|
||||
});
|
||||
},
|
||||
touchStart(e) {
|
||||
const { disableTouch, chart } = this;
|
||||
if (disableTouch || !chart || !e.mp.touches.length) return;
|
||||
const touch = e.mp.touches[0];
|
||||
chart._zr.handler.dispatch('mousedown', {
|
||||
zrX: touch.x,
|
||||
zrY: touch.y
|
||||
});
|
||||
chart._zr.handler.dispatch('mousemove', {
|
||||
zrX: touch.x,
|
||||
zrY: touch.y
|
||||
});
|
||||
},
|
||||
touchMove(e) {
|
||||
const { disableTouch, throttleTouch, chart, lastMoveTime } = this;
|
||||
if (disableTouch || !chart || !e.mp.touches.length) return;
|
||||
|
||||
if (throttleTouch) {
|
||||
const currMoveTime = Date.now();
|
||||
if (currMoveTime - lastMoveTime < 240) return;
|
||||
this.lastMoveTime = currMoveTime;
|
||||
}
|
||||
|
||||
const touch = e.mp.touches[0];
|
||||
chart._zr.handler.dispatch('mousemove', {
|
||||
zrX: touch.x,
|
||||
zrY: touch.y
|
||||
});
|
||||
},
|
||||
touchEnd(e) {
|
||||
const { disableTouch, chart } = this;
|
||||
if (disableTouch || !chart) return;
|
||||
const touch = e.mp.changedTouches ? e.mp.changedTouches[0] : {};
|
||||
chart._zr.handler.dispatch('mouseup', {
|
||||
zrX: touch.x,
|
||||
zrY: touch.y
|
||||
});
|
||||
chart._zr.handler.dispatch('click', {
|
||||
zrX: touch.x,
|
||||
zrY: touch.y
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ec-canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
export default class WxCanvas {
|
||||
constructor(ctx, canvasId) {
|
||||
this.ctx = ctx;
|
||||
this.canvasId = canvasId;
|
||||
this.chart = null;
|
||||
|
||||
WxCanvas.initStyle(ctx);
|
||||
this.initEvent();
|
||||
}
|
||||
|
||||
getContext(contextType) {
|
||||
return contextType === '2d' ? this.ctx : null;
|
||||
}
|
||||
|
||||
setChart(chart) {
|
||||
this.chart = chart;
|
||||
}
|
||||
|
||||
attachEvent() {
|
||||
// noop
|
||||
}
|
||||
|
||||
detachEvent() {
|
||||
// noop
|
||||
}
|
||||
|
||||
static initStyle(ctx) {
|
||||
const styles = ['fillStyle', 'strokeStyle', 'globalAlpha',
|
||||
'textAlign', 'textBaseAlign', 'shadow', 'lineWidth',
|
||||
'lineCap', 'lineJoin', 'lineDash', 'miterLimit', 'fontSize'];
|
||||
|
||||
styles.forEach((style) => {
|
||||
Object.defineProperty(ctx, style, {
|
||||
set: (value) => {
|
||||
if ((style !== 'fillStyle' && style !== 'strokeStyle')
|
||||
|| (value !== 'none' && value !== null)
|
||||
) {
|
||||
ctx[`set${style.charAt(0).toUpperCase()}${style.slice(1)}`](value);
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
ctx.createRadialGradient = () => ctx.createCircularGradient(arguments);
|
||||
}
|
||||
|
||||
initEvent() {
|
||||
this.event = {};
|
||||
const eventNames = [{
|
||||
wxName: 'touchStart',
|
||||
ecName: 'mousedown',
|
||||
}, {
|
||||
wxName: 'touchMove',
|
||||
ecName: 'mousemove',
|
||||
}, {
|
||||
wxName: 'touchEnd',
|
||||
ecName: 'mouseup',
|
||||
}, {
|
||||
wxName: 'touchEnd',
|
||||
ecName: 'click',
|
||||
}];
|
||||
|
||||
eventNames.forEach((name) => {
|
||||
this.event[name.wxName] = (e) => {
|
||||
const touch = e.mp.touches[0];
|
||||
this.chart._zr.handler.dispatch(name.ecName, {
|
||||
zrX: name.wxName === 'tap' ? touch.clientX : touch.x,
|
||||
zrY: name.wxName === 'tap' ? touch.clientY : touch.y,
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,484 @@
|
|||
<template>
|
||||
<view class="mpvue-picker">
|
||||
<view :class="{'pickerMask':showPicker}" @click="maskClick" catchtouchmove="true"></view>
|
||||
<view class="mpvue-picker-content " :class="{'mpvue-picker-view-show':showPicker}">
|
||||
<view class="mpvue-picker__hd" catchtouchmove="true">
|
||||
<view class="mpvue-picker__action" @click="pickerCancel">取消</view>
|
||||
<view class="mpvue-picker__action" :style="{color:themeColor}" @click="pickerConfirm">确定</view>
|
||||
</view>
|
||||
<!-- 单列 -->
|
||||
<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue"
|
||||
@change="pickerChange" v-if="mode==='selector' && pickerValueSingleArray.length > 0">
|
||||
<picker-view-column>
|
||||
<view class="picker-item" v-for="(item,index) in pickerValueSingleArray" :key="index">{{item.label}}
|
||||
</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
<!-- 时间选择器 -->
|
||||
<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue"
|
||||
@change="pickerChange" v-if="mode==='timeSelector'">
|
||||
<picker-view-column>
|
||||
<view class="picker-item" v-for="(item,index) in pickerValueHour" :key="index">{{item.label}}</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="picker-item" v-for="(item,index) in pickerValueMinute" :key="index">{{item.label}}
|
||||
</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
<!-- 多列选择 -->
|
||||
<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue"
|
||||
@change="pickerChange" v-if="mode==='multiSelector'">
|
||||
<!-- #ifdef VUE3 -->
|
||||
<template v-for="(n,index) in pickerValueMulArray.length" :key="index">
|
||||
<picker-view-column>
|
||||
<view class="picker-item" v-for="(item,index1) in pickerValueMulArray[n]" :key="index1">
|
||||
{{item.label}}
|
||||
</view>
|
||||
</picker-view-column>
|
||||
</template>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef VUE3 -->
|
||||
<block v-for="(n,index) in pickerValueMulArray.length" :key="index">
|
||||
<picker-view-column>
|
||||
<view class="picker-item" v-for="(item,index1) in pickerValueMulArray[n]" :key="index1">
|
||||
{{item.label}}
|
||||
</view>
|
||||
</picker-view-column>
|
||||
</block>
|
||||
<!-- #endif -->
|
||||
</picker-view>
|
||||
<!-- 二级联动 -->
|
||||
<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue"
|
||||
@change="pickerChangeMul" v-if="mode==='multiLinkageSelector' && deepLength===2">
|
||||
<picker-view-column>
|
||||
<view class="picker-item" v-for="(item,index) in pickerValueMulTwoOne" :key="index">{{item.label}}
|
||||
</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="picker-item" v-for="(item,index) in pickerValueMulTwoTwo" :key="index">{{item.label}}
|
||||
</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
<!-- 三级联动 -->
|
||||
<picker-view indicator-style="height: 40px;" class="mpvue-picker-view" :value="pickerValue"
|
||||
@change="pickerChangeMul" v-if="mode==='multiLinkageSelector' && deepLength===3">
|
||||
<picker-view-column>
|
||||
<view class="picker-item" v-for="(item,index) in pickerValueMulThreeOne" :key="index">{{item.label}}
|
||||
</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="picker-item" v-for="(item,index) in pickerValueMulThreeTwo" :key="index">{{item.label}}
|
||||
</view>
|
||||
</picker-view-column>
|
||||
<picker-view-column>
|
||||
<view class="picker-item" v-for="(item,index) in pickerValueMulThreeThree" :key="index">
|
||||
{{item.label}}
|
||||
</view>
|
||||
</picker-view-column>
|
||||
</picker-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pickerChangeValue: [],
|
||||
pickerValue: [],
|
||||
pickerValueArrayChange: true,
|
||||
modeChange: false,
|
||||
pickerValueSingleArray: [],
|
||||
pickerValueHour: [],
|
||||
pickerValueMinute: [],
|
||||
pickerValueMulArray: [],
|
||||
pickerValueMulTwoOne: [],
|
||||
pickerValueMulTwoTwo: [],
|
||||
pickerValueMulThreeOne: [],
|
||||
pickerValueMulThreeTwo: [],
|
||||
pickerValueMulThreeThree: [],
|
||||
/* 是否显示控件 */
|
||||
showPicker: false,
|
||||
};
|
||||
},
|
||||
props: {
|
||||
/* mode */
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'selector'
|
||||
},
|
||||
/* picker 数值 */
|
||||
pickerValueArray: {
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
/* 默认值 */
|
||||
pickerValueDefault: {
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
/* 几级联动 */
|
||||
deepLength: {
|
||||
type: Number,
|
||||
default: 2
|
||||
},
|
||||
/* 主题色 */
|
||||
themeColor: String
|
||||
},
|
||||
watch: {
|
||||
pickerValueArray(oldVal, newVal) {
|
||||
this.pickerValueArrayChange = true;
|
||||
},
|
||||
mode(oldVal, newVal) {
|
||||
this.modeChange = true;
|
||||
},
|
||||
pickerValueArray(val) {
|
||||
this.initPicker(val);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initPicker(valueArray) {
|
||||
let pickerValueArray = valueArray;
|
||||
this.pickerValue = this.pickerValueDefault;
|
||||
// 初始化多级联动
|
||||
if (this.mode === 'selector') {
|
||||
this.pickerValueSingleArray = valueArray;
|
||||
} else if (this.mode === 'timeSelector') {
|
||||
this.modeChange = false;
|
||||
let hourArray = [];
|
||||
let minuteArray = [];
|
||||
for (let i = 0; i < 24; i++) {
|
||||
hourArray.push({
|
||||
value: i,
|
||||
label: i > 9 ? `${i} 时` : `0${i} 时`
|
||||
});
|
||||
}
|
||||
for (let i = 0; i < 60; i++) {
|
||||
minuteArray.push({
|
||||
value: i,
|
||||
label: i > 9 ? `${i} 分` : `0${i} 分`
|
||||
});
|
||||
}
|
||||
this.pickerValueHour = hourArray;
|
||||
this.pickerValueMinute = minuteArray;
|
||||
} else if (this.mode === 'multiSelector') {
|
||||
this.pickerValueMulArray = valueArray;
|
||||
} else if (this.mode === 'multiLinkageSelector' && this.deepLength === 2) {
|
||||
// 两级联动
|
||||
let pickerValueMulTwoOne = [];
|
||||
let pickerValueMulTwoTwo = [];
|
||||
// 第一列
|
||||
for (let i = 0, length = pickerValueArray.length; i < length; i++) {
|
||||
pickerValueMulTwoOne.push(pickerValueArray[i]);
|
||||
}
|
||||
// 渲染第二列
|
||||
// 如果有设定的默认值
|
||||
if (this.pickerValueDefault.length === 2) {
|
||||
let num = this.pickerValueDefault[0];
|
||||
for (
|
||||
let i = 0, length = pickerValueArray[num].children.length; i < length; i++
|
||||
) {
|
||||
pickerValueMulTwoTwo.push(pickerValueArray[num].children[i]);
|
||||
}
|
||||
} else {
|
||||
for (
|
||||
let i = 0, length = pickerValueArray[0].children.length; i < length; i++
|
||||
) {
|
||||
pickerValueMulTwoTwo.push(pickerValueArray[0].children[i]);
|
||||
}
|
||||
}
|
||||
this.pickerValueMulTwoOne = pickerValueMulTwoOne;
|
||||
this.pickerValueMulTwoTwo = pickerValueMulTwoTwo;
|
||||
} else if (
|
||||
this.mode === 'multiLinkageSelector' &&
|
||||
this.deepLength === 3
|
||||
) {
|
||||
let pickerValueMulThreeOne = [];
|
||||
let pickerValueMulThreeTwo = [];
|
||||
let pickerValueMulThreeThree = [];
|
||||
// 第一列
|
||||
for (let i = 0, length = pickerValueArray.length; i < length; i++) {
|
||||
pickerValueMulThreeOne.push(pickerValueArray[i]);
|
||||
}
|
||||
// 渲染第二列
|
||||
this.pickerValueDefault =
|
||||
this.pickerValueDefault.length === 3 ?
|
||||
this.pickerValueDefault : [0, 0, 0];
|
||||
if (this.pickerValueDefault.length === 3) {
|
||||
let num = this.pickerValueDefault[0];
|
||||
for (
|
||||
let i = 0, length = pickerValueArray[num].children.length; i < length; i++
|
||||
) {
|
||||
pickerValueMulThreeTwo.push(pickerValueArray[num].children[i]);
|
||||
}
|
||||
// 第三列
|
||||
let numSecond = this.pickerValueDefault[1];
|
||||
for (let i = 0, length = pickerValueArray[num].children[numSecond].children.length; i <
|
||||
length; i++) {
|
||||
pickerValueMulThreeThree.push(
|
||||
pickerValueArray[num].children[numSecond].children[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
this.pickerValueMulThreeOne = pickerValueMulThreeOne;
|
||||
this.pickerValueMulThreeTwo = pickerValueMulThreeTwo;
|
||||
this.pickerValueMulThreeThree = pickerValueMulThreeThree;
|
||||
}
|
||||
},
|
||||
show() {
|
||||
setTimeout(() => {
|
||||
if (this.pickerValueArrayChange || this.modeChange) {
|
||||
this.initPicker(this.pickerValueArray);
|
||||
this.showPicker = true;
|
||||
this.pickerValueArrayChange = false;
|
||||
this.modeChange = false;
|
||||
} else {
|
||||
this.showPicker = true;
|
||||
}
|
||||
}, 0);
|
||||
},
|
||||
maskClick() {
|
||||
this.pickerCancel();
|
||||
},
|
||||
pickerCancel() {
|
||||
this.showPicker = false;
|
||||
this._initPickerVale();
|
||||
let pickObj = {
|
||||
index: this.pickerValue,
|
||||
value: this._getPickerLabelAndValue(this.pickerValue, this.mode).value,
|
||||
label: this._getPickerLabelAndValue(this.pickerValue, this.mode).label
|
||||
};
|
||||
this.$emit('onCancel', pickObj);
|
||||
},
|
||||
pickerConfirm(e) {
|
||||
this.showPicker = false;
|
||||
this._initPickerVale();
|
||||
let pickObj = {
|
||||
index: this.pickerValue,
|
||||
value: this._getPickerLabelAndValue(this.pickerValue, this.mode).value,
|
||||
label: this._getPickerLabelAndValue(this.pickerValue, this.mode).label
|
||||
};
|
||||
this.$emit('onConfirm', pickObj);
|
||||
},
|
||||
showPickerView() {
|
||||
this.showPicker = true;
|
||||
},
|
||||
pickerChange(e) {
|
||||
console.log(11111111, e);
|
||||
this.pickerValue = e.detail.value;
|
||||
let pickObj = {
|
||||
index: this.pickerValue,
|
||||
value: this._getPickerLabelAndValue(this.pickerValue, this.mode).value,
|
||||
label: this._getPickerLabelAndValue(this.pickerValue, this.mode).label
|
||||
};
|
||||
this.$emit('onChange', pickObj);
|
||||
},
|
||||
pickerChangeMul(e) {
|
||||
if (this.deepLength === 2) {
|
||||
let pickerValueArray = this.pickerValueArray;
|
||||
let changeValue = e.detail.value;
|
||||
// 处理第一列滚动
|
||||
if (changeValue[0] !== this.pickerValue[0]) {
|
||||
let pickerValueMulTwoTwo = [];
|
||||
// 第一列滚动第二列数据更新
|
||||
for (let i = 0, length = pickerValueArray[changeValue[0]].children.length; i < length; i++) {
|
||||
pickerValueMulTwoTwo.push(pickerValueArray[changeValue[0]].children[i]);
|
||||
}
|
||||
this.pickerValueMulTwoTwo = pickerValueMulTwoTwo;
|
||||
// 第二列初始化为 0
|
||||
changeValue[1] = 0;
|
||||
}
|
||||
this.pickerValue = changeValue;
|
||||
} else if (this.deepLength === 3) {
|
||||
let pickerValueArray = this.pickerValueArray;
|
||||
let changeValue = e.detail.value;
|
||||
let pickerValueMulThreeTwo = [];
|
||||
let pickerValueMulThreeThree = [];
|
||||
// 重新渲染第二列
|
||||
// 如果是第一列滚动
|
||||
if (changeValue[0] !== this.pickerValue[0]) {
|
||||
this.pickerValueMulThreeTwo = [];
|
||||
for (let i = 0, length = pickerValueArray[changeValue[0]].children.length; i < length; i++) {
|
||||
pickerValueMulThreeTwo.push(pickerValueArray[changeValue[0]].children[i]);
|
||||
}
|
||||
// 重新渲染第三列
|
||||
for (let i = 0, length = pickerValueArray[changeValue[0]].children[0].children.length; i <
|
||||
length; i++) {
|
||||
pickerValueMulThreeThree.push(pickerValueArray[changeValue[0]].children[0].children[i]);
|
||||
}
|
||||
changeValue[1] = 0;
|
||||
changeValue[2] = 0;
|
||||
this.pickerValueMulThreeTwo = pickerValueMulThreeTwo;
|
||||
this.pickerValueMulThreeThree = pickerValueMulThreeThree;
|
||||
} else if (changeValue[1] !== this.pickerValue[1]) {
|
||||
// 第二列滚动
|
||||
// 重新渲染第三列
|
||||
this.pickerValueMulThreeThree = [];
|
||||
pickerValueMulThreeTwo = this.pickerValueMulThreeTwo;
|
||||
for (let i = 0, length = pickerValueArray[changeValue[0]].children[changeValue[1]].children
|
||||
.length; i <
|
||||
length; i++) {
|
||||
pickerValueMulThreeThree.push(pickerValueArray[changeValue[0]].children[changeValue[1]]
|
||||
.children[
|
||||
i]);
|
||||
}
|
||||
changeValue[2] = 0;
|
||||
this.pickerValueMulThreeThree = pickerValueMulThreeThree;
|
||||
}
|
||||
this.pickerValue = changeValue;
|
||||
}
|
||||
let pickObj = {
|
||||
index: this.pickerValue,
|
||||
value: this._getPickerLabelAndValue(this.pickerValue, this.mode).value,
|
||||
label: this._getPickerLabelAndValue(this.pickerValue, this.mode).label
|
||||
};
|
||||
this.$emit('onChange', pickObj);
|
||||
},
|
||||
// 获取 pxikerLabel
|
||||
_getPickerLabelAndValue(value, mode) {
|
||||
let pickerLable;
|
||||
let pickerGetValue = [];
|
||||
// selector
|
||||
if (mode === 'selector') {
|
||||
pickerLable = this.pickerValueSingleArray[value].label;
|
||||
pickerGetValue.push(this.pickerValueSingleArray[value].value);
|
||||
} else if (mode === 'timeSelector') {
|
||||
pickerLable = `${this.pickerValueHour[value[0]].label}-${this.pickerValueMinute[value[1]].label}`;
|
||||
pickerGetValue.push(this.pickerValueHour[value[0]].value);
|
||||
pickerGetValue.push(this.pickerValueHour[value[1]].value);
|
||||
} else if (mode === 'multiSelector') {
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
if (i > 0) {
|
||||
pickerLable += this.pickerValueMulArray[i][value[i]].label + (i === value.length - 1 ? '' :
|
||||
'-');
|
||||
} else {
|
||||
pickerLable = this.pickerValueMulArray[i][value[i]].label + '-';
|
||||
}
|
||||
pickerGetValue.push(this.pickerValueMulArray[i][value[i]].value);
|
||||
}
|
||||
} else if (mode === 'multiLinkageSelector') {
|
||||
/* eslint-disable indent */
|
||||
pickerLable =
|
||||
this.deepLength === 2 ?
|
||||
`${this.pickerValueMulTwoOne[value[0]].label}-${this.pickerValueMulTwoTwo[value[1]].label}` :
|
||||
`${this.pickerValueMulThreeOne[value[0]].label}-${this.pickerValueMulThreeTwo[value[1]].label}-${this.pickerValueMulThreeThree[value[2]].label}`;
|
||||
if (this.deepLength === 2) {
|
||||
pickerGetValue.push(this.pickerValueMulTwoOne[value[0]].value);
|
||||
pickerGetValue.push(this.pickerValueMulTwoTwo[value[1]].value);
|
||||
} else {
|
||||
pickerGetValue.push(this.pickerValueMulThreeOne[value[0]].value);
|
||||
pickerGetValue.push(this.pickerValueMulThreeTwo[value[1]].value);
|
||||
pickerGetValue.push(this.pickerValueMulThreeThree[value[2]].value);
|
||||
}
|
||||
/* eslint-enable indent */
|
||||
}
|
||||
return {
|
||||
label: pickerLable,
|
||||
value: pickerGetValue
|
||||
};
|
||||
},
|
||||
// 初始化 pickerValue 默认值
|
||||
_initPickerVale() {
|
||||
if (this.pickerValue.length === 0) {
|
||||
if (this.mode === 'selector') {
|
||||
this.pickerValue = [0];
|
||||
} else if (this.mode === 'multiSelector') {
|
||||
this.pickerValue = new Int8Array(this.pickerValueArray.length);
|
||||
} else if (
|
||||
this.mode === 'multiLinkageSelector' &&
|
||||
this.deepLength === 2
|
||||
) {
|
||||
this.pickerValue = [0, 0];
|
||||
} else if (
|
||||
this.mode === 'multiLinkageSelector' &&
|
||||
this.deepLength === 3
|
||||
) {
|
||||
this.pickerValue = [0, 0, 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.pickerMask {
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
.mpvue-picker-content {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
transition: all 0.3s ease;
|
||||
transform: translateY(100%);
|
||||
z-index: 3000;
|
||||
}
|
||||
|
||||
.mpvue-picker-view-show {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
.mpvue-picker__hd {
|
||||
display: flex;
|
||||
padding: 9px 15px;
|
||||
background-color: #fff;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
.mpvue-picker__hd:after {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: 1px;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
color: #e5e5e5;
|
||||
transform-origin: 0 100%;
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
|
||||
.mpvue-picker__action {
|
||||
display: block;
|
||||
flex: 1;
|
||||
color: #1aad19;
|
||||
}
|
||||
|
||||
.mpvue-picker__action:first-child {
|
||||
text-align: left;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
.mpvue-picker__action:last-child {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.picker-item {
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.mpvue-picker-view {
|
||||
position: relative;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 238px;
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,175 @@
|
|||
class GestureLock {
|
||||
|
||||
constructor(containerWidth, cycleRadius) {
|
||||
this.containerWidth = containerWidth; // 容器宽度
|
||||
this.cycleRadius = cycleRadius; // 圆的半径
|
||||
|
||||
this.circleArray = []; // 全部圆的对象数组
|
||||
this.checkPoints = []; // 选中的圆的对象数组
|
||||
this.lineArray = []; // 已激活锁之间的线段数组
|
||||
this.lastCheckPoint = 0; // 最后一个激活的锁
|
||||
this.offsetX = 0; // 容器的 X 偏移
|
||||
this.offsetY = 0; // 容器的 Y 偏移
|
||||
this.activeLine = {}; // 最后一个激活的锁与当前位置之间的线段
|
||||
|
||||
this.windowWidth = wx.getSystemInfoSync().windowWidth; // 窗口大小(用于rpx 和 px 转换)
|
||||
|
||||
this.initCircleArray();
|
||||
}
|
||||
|
||||
// 初始化 画布上的 9个圆
|
||||
initCircleArray() {
|
||||
const cycleMargin = (this.containerWidth - 6 * this.cycleRadius) / 6;
|
||||
let count = 0;
|
||||
for (let i = 0; i < 3; i++) {
|
||||
for (let j = 0; j < 3; j++) {
|
||||
count++;
|
||||
this.circleArray.push({
|
||||
count: count,
|
||||
x: this.rpxTopx((cycleMargin + this.cycleRadius) * (j * 2 + 1)),
|
||||
y: this.rpxTopx((cycleMargin + this.cycleRadius) * (i * 2 + 1)),
|
||||
radius: this.rpxTopx(this.cycleRadius),
|
||||
check: false,
|
||||
style: {
|
||||
left: (cycleMargin + this.cycleRadius) * (j * 2 + 1) - this.cycleRadius + 'rpx',
|
||||
top: (cycleMargin + this.cycleRadius) * (i * 2 + 1) - this.cycleRadius + 'rpx',
|
||||
width: this.cycleRadius * 2 + 'rpx',
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onTouchStart(e) {
|
||||
this.setOffset(e);
|
||||
this.checkTouch({
|
||||
x: e.touches[0].pageX - this.offsetX,
|
||||
y: e.touches[0].pageY - this.offsetY
|
||||
});
|
||||
}
|
||||
|
||||
onTouchMove(e) {
|
||||
this.moveDraw(e)
|
||||
}
|
||||
|
||||
onTouchEnd(e) {
|
||||
const checkPoints = this.checkPoints;
|
||||
this.reset();
|
||||
return checkPoints;
|
||||
}
|
||||
|
||||
// 初始化 偏移量
|
||||
setOffset(e) {
|
||||
this.offsetX = e.currentTarget.offsetLeft;
|
||||
this.offsetY = e.currentTarget.offsetTop;
|
||||
}
|
||||
|
||||
// 检测当时 触摸位置是否位于 锁上
|
||||
checkTouch({
|
||||
x,
|
||||
y
|
||||
}) {
|
||||
for (let i = 0; i < this.circleArray.length; i++) {
|
||||
let point = this.circleArray[i];
|
||||
if (this.isPointInCycle(x, y, point.x, point.y, point.radius)) {
|
||||
if (!point.check) {
|
||||
this.checkPoints.push(point.count);
|
||||
if (this.lastCheckPoint != 0) {
|
||||
// 已激活锁之间的线段
|
||||
const line = this.drawLine(this.lastCheckPoint, point);
|
||||
this.lineArray.push(line);
|
||||
}
|
||||
this.lastCheckPoint = point;
|
||||
}
|
||||
point.check = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 画线 - 返回 样式 对象
|
||||
drawLine(start, end) {
|
||||
const width = this.getPointDis(start.x, start.y, end.x, end.y);
|
||||
const rotate = this.getAngle(start, end);
|
||||
|
||||
return {
|
||||
activeLeft: start.x + 'px',
|
||||
activeTop: start.y + 'px',
|
||||
activeWidth: width + 'px',
|
||||
activeRotate: rotate + 'deg'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 获取 画线的 角度
|
||||
getAngle(start, end) {
|
||||
var diff_x = end.x - start.x,
|
||||
diff_y = end.y - start.y;
|
||||
if (diff_x >= 0) {
|
||||
return 360 * Math.atan(diff_y / diff_x) / (2 * Math.PI);
|
||||
} else {
|
||||
return 180 + 360 * Math.atan(diff_y / diff_x) / (2 * Math.PI);
|
||||
}
|
||||
}
|
||||
|
||||
// 判断 当前点是否位于 锁内
|
||||
isPointInCycle(x, y, circleX, circleY, radius) {
|
||||
return (this.getPointDis(x, y, circleX, circleY) < radius) ? true : false;
|
||||
}
|
||||
|
||||
// 获取两点之间距离
|
||||
getPointDis(ax, ay, bx, by) {
|
||||
return Math.sqrt(Math.pow(ax - bx, 2) + Math.pow(ay - by, 2));
|
||||
}
|
||||
|
||||
// 移动 绘制
|
||||
moveDraw(e) {
|
||||
// 画经过的圆
|
||||
const x = e.touches[0].pageX - this.offsetX;
|
||||
const y = e.touches[0].pageY - this.offsetY;
|
||||
this.checkTouch({
|
||||
x,
|
||||
y
|
||||
});
|
||||
|
||||
// 画 最后一个激活的锁与当前位置之间的线段
|
||||
this.activeLine = this.drawLine(this.lastCheckPoint, {
|
||||
x,
|
||||
y
|
||||
});
|
||||
}
|
||||
|
||||
// 使 画布 恢复初始状态
|
||||
reset() {
|
||||
this.circleArray.forEach((item) => {
|
||||
item.check = false;
|
||||
});
|
||||
this.checkPoints = [];
|
||||
this.lineArray = [];
|
||||
this.activeLine = {};
|
||||
this.lastCheckPoint = 0;
|
||||
}
|
||||
|
||||
|
||||
// 获取 最后一个激活的锁与当前位置之间的线段
|
||||
getActiveLine() {
|
||||
return this.activeLine;
|
||||
}
|
||||
|
||||
// 获取 圆对象数组
|
||||
getCycleArray() {
|
||||
return this.circleArray;
|
||||
}
|
||||
|
||||
// 获取 已激活锁之间的线段
|
||||
getLineArray() {
|
||||
return this.lineArray;
|
||||
}
|
||||
|
||||
// 将 RPX 转换成 PX
|
||||
rpxTopx(rpx) {
|
||||
return rpx / 750 * this.windowWidth;
|
||||
}
|
||||
}
|
||||
|
||||
export default GestureLock;
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
<template>
|
||||
<view class="gesture-lock" :class="{error:error}" :style="{width: containerWidth +'rpx', height:containerWidth +'rpx'}"
|
||||
@touchstart.stop="onTouchStart" @touchmove.stop="onTouchMove" @touchend.stop="onTouchEnd">
|
||||
<!-- 同级 v-for 的 key 重复会有问题,需要套一层。 -->
|
||||
<!-- 9 个圆 -->
|
||||
<view>
|
||||
<view v-for="(item,i) in circleArray" :key="i" class="cycle" :class="{check:item.check}" :style="{left:item.style.left,top:item.style.top,width:item.style.width,height:item.style.width}">
|
||||
</view>
|
||||
</view>
|
||||
<view>
|
||||
<!-- 已激活锁之间的线段 -->
|
||||
<view v-for="(item,i) in lineArray" :key="i" class="line" :style="{left:item.activeLeft,top:item.activeTop,width:item.activeWidth,'-webkit-transform':'rotate('+item.activeRotate+')',transform:'rotate('+item.activeRotate+')'}">
|
||||
</view>
|
||||
</view>
|
||||
<!-- 最后一个激活的锁与当前位置之间的线段 -->
|
||||
<view class="line" :style="{left:activeLine.activeLeft,top:activeLine.activeTop,width:activeLine.activeWidth,'-webkit-transform':'rotate('+activeLine.activeRotate+')',transform:'rotate('+activeLine.activeRotate+')'}">
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import GestureLock from './gestureLock';
|
||||
|
||||
export default {
|
||||
name: 'index',
|
||||
props: {
|
||||
/**
|
||||
* 容器宽度
|
||||
*/
|
||||
containerWidth: {
|
||||
type: [Number, String],
|
||||
default: 0
|
||||
},
|
||||
/**
|
||||
* 圆的半径
|
||||
*/
|
||||
cycleRadius: {
|
||||
type: [Number, String],
|
||||
default: 0
|
||||
},
|
||||
/**
|
||||
* 已设定的密码
|
||||
*/
|
||||
password: {
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
gestureLock: {}, // 锁对象
|
||||
circleArray: [], // 圆对象数组
|
||||
lineArray: [], // 已激活锁之间的线段
|
||||
activeLine: {}, // 最后一个激活的锁与当前位置之间的线段
|
||||
error: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onTouchStart(e) {
|
||||
this.gestureLock.onTouchStart(e);
|
||||
this.refesh();
|
||||
},
|
||||
|
||||
onTouchMove(e) {
|
||||
this.gestureLock.onTouchMove(e);
|
||||
this.refesh();
|
||||
},
|
||||
|
||||
onTouchEnd(e) {
|
||||
const checkPoints = this.gestureLock.onTouchEnd(e);
|
||||
if (!this.password.length || checkPoints.join('') == this.password.join('')) {
|
||||
this.refesh();
|
||||
this.$emit('end', checkPoints);
|
||||
} else {
|
||||
this.error = true;
|
||||
setTimeout(() => {
|
||||
this.refesh();
|
||||
this.$emit('end', checkPoints);
|
||||
}, 800);
|
||||
}
|
||||
|
||||
},
|
||||
refesh() {
|
||||
this.error = false;
|
||||
this.circleArray = this.gestureLock.getCycleArray();
|
||||
this.lineArray = this.gestureLock.getLineArray();
|
||||
this.activeLine = this.gestureLock.getActiveLine();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.gestureLock = new GestureLock(this.containerWidth, this.cycleRadius);
|
||||
this.refesh();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.gesture-lock {
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.gesture-lock .cycle {
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
border: 2px solid #66aaff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.gesture-lock .cycle.check:after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 32%;
|
||||
height: 32%;
|
||||
border: 2px solid #66aaff;
|
||||
border-radius: 50%;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.gesture-lock .line {
|
||||
height: 0;
|
||||
border-top: 2px solid #66aaff;
|
||||
position: absolute;
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.gesture-lock.error .cycle.check,
|
||||
.gesture-lock.error .cycle.check:after,
|
||||
.gesture-lock.error .line {
|
||||
border-color: #ffa197;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<template name="page-foot">
|
||||
<view class="page-share-title">
|
||||
<text>感谢{{name}}提供本示例,</text>
|
||||
<text class="submit" @click="submit">我也提交</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "page-foot",
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
default: ""
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submit() {
|
||||
uni.showModal({
|
||||
content:"hello uni-app开源地址为https://github.com/dcloudio/uni-app/tree/master/examples,请在这个开源项目上贡献你的代码",
|
||||
showCancel:false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.page-share-title {
|
||||
text-align: center;
|
||||
font-size: 30rpx;
|
||||
color: #BEBEBE;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.submit {
|
||||
border-bottom: 1rpx solid #BEBEBE;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<template name="page-head">
|
||||
<view class="common-page-head">
|
||||
<view class="common-page-head-title">{{title}}</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "page-head",
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ""
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
<template>
|
||||
<view class="product">
|
||||
<image class="product-image" :src="image ? image : 'https://via.placeholder.com/150x200'"></image>
|
||||
<view class="product-title">{{title}}</view>
|
||||
<view class="product-price">
|
||||
<text class="product-price-favour">¥{{originalPrice}}</text>
|
||||
<text class="product-price-original">¥{{favourPrice}}</text>
|
||||
<text class="product-tip">{{tip}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'product',
|
||||
props: ['image', 'title', 'originalPrice', 'favourPrice', 'tip']
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.product {
|
||||
padding: 10rpx 20rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.product-image {
|
||||
height: 330rpx;
|
||||
width: 330rpx;
|
||||
}
|
||||
|
||||
.product-title {
|
||||
width: 300rpx;
|
||||
font-size: 32rpx;
|
||||
word-break: break-all;
|
||||
display: -webkit-box;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
|
||||
.product-price {
|
||||
font-size: 28rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.product-price-original {
|
||||
color: #E80080;
|
||||
}
|
||||
|
||||
.product-price-favour {
|
||||
color: #888888;
|
||||
text-decoration: line-through;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
|
||||
.product-tip {
|
||||
position: absolute;
|
||||
right: 10rpx;
|
||||
background-color: #FF3333;
|
||||
color: #FFFFFF;
|
||||
padding: 0 10rpx;
|
||||
border-radius: 5rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,175 @@
|
|||
<template>
|
||||
<view class="view">
|
||||
<view class="list-cell view" hover-class="uni-list-cell-hover" @click="bindClick">
|
||||
<view class="media-list view" v-if="options.title">
|
||||
<view class="view" :class="{'media-image-right': options.article_type === 2, 'media-image-left': options.article_type === 1}">
|
||||
<text class="media-title" :class="{'media-title2': options.article_type === 1 || options.article_type === 2}">{{options.title}}</text>
|
||||
<view v-if="options.image_list || options.image_url" class="image-section view" :class="{'image-section-right': options.article_type === 2, 'image-section-left': options.article_type === 1}">
|
||||
<image class="image-list1" :class="{'image-list2': options.article_type === 1 || options.article_type === 2}"
|
||||
v-if="options.image_url" :src="options.image_url"></image>
|
||||
<image class="image-list3" v-if="options.image_list" :src="source.url" v-for="(source, i) in options.image_list"
|
||||
:key="i" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="media-foot view">
|
||||
<view class="media-info view">
|
||||
<text class="info-text">{{options.source}}</text>
|
||||
<text class="info-text">{{options.comment_count}}条评论</text>
|
||||
<text class="info-text">{{options.datetime}}</text>
|
||||
</view>
|
||||
<view class="max-close-view view" @click.stop="close">
|
||||
<view class="close-view view"><text class="close">×</text></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
default: function(e) {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
close(e) {
|
||||
this.$emit('close');
|
||||
},
|
||||
bindClick() {
|
||||
this.$emit('click');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.view {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.list-cell {
|
||||
width: 750rpx;
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.uni-list-cell-hover {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
|
||||
.media-list {
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
border-bottom-width: 1rpx;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-color: #c8c7cc;
|
||||
padding: 20rpx 0;
|
||||
}
|
||||
|
||||
.media-image-right {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.media-image-left {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
||||
.media-title {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.media-title {
|
||||
lines: 3;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 32rpx;
|
||||
color: #555555;
|
||||
}
|
||||
|
||||
.media-title2 {
|
||||
flex: 1;
|
||||
margin-top: 6rpx;
|
||||
line-height: 40rpx;
|
||||
}
|
||||
|
||||
.image-section {
|
||||
margin-top: 20rpx;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.image-section-right {
|
||||
margin-top: 0rpx;
|
||||
margin-left: 10rpx;
|
||||
width: 225rpx;
|
||||
height: 146rpx;
|
||||
}
|
||||
|
||||
.image-section-left {
|
||||
margin-top: 0rpx;
|
||||
margin-right: 10rpx;
|
||||
width: 225rpx;
|
||||
height: 146rpx;
|
||||
}
|
||||
|
||||
.image-list1 {
|
||||
width: 690rpx;
|
||||
height: 481rpx;
|
||||
}
|
||||
|
||||
.image-list2 {
|
||||
width: 225rpx;
|
||||
height: 146rpx;
|
||||
}
|
||||
|
||||
.image-list3 {
|
||||
width: 225rpx;
|
||||
height: 146rpx;
|
||||
}
|
||||
|
||||
.media-info {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.info-text {
|
||||
margin-right: 20rpx;
|
||||
color: #999999;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
.media-foot {
|
||||
margin-top: 20rpx;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.max-close-view {
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
flex-direction: row;
|
||||
height: 40rpx;
|
||||
width: 80rpx;
|
||||
}
|
||||
|
||||
.close-view {
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
border-color: #999999;
|
||||
border-radius: 10rpx;
|
||||
justify-content: center;
|
||||
height: 30rpx;
|
||||
width: 40rpx;
|
||||
line-height: 30rpx;
|
||||
}
|
||||
|
||||
.close {
|
||||
text-align: center;
|
||||
color: #999999;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
</style>
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,59 @@
|
|||
<template>
|
||||
<text style="text-decoration:underline" :href="href" @click="openURL" :inWhiteList="inWhiteList">{{text}}</text>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* @description u-link是一个外部网页超链接组件,在小程序内打开内部web-view组件或复制url,在app内打开外部浏览器,在h5端打开新网页
|
||||
* @property {String} href 点击后打开的外部网页url,小程序中必须以https://开头
|
||||
* @property {String} text 显示的文字
|
||||
* @property {Boolean} inWhiteList 是否在小程序白名单中,如果在的话,在小程序端会直接打开内置web-view,否则会只会复制url,提示在外部打开
|
||||
* @example * <u-link href="https://ext.dcloud.net.cn" text="https://ext.dcloud.net.cn" :inWhiteList="true"></u-link>
|
||||
*/
|
||||
export default {
|
||||
name: 'u-link',
|
||||
props: {
|
||||
href: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
inWhiteList: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openURL() {
|
||||
// #ifdef APP-PLUS
|
||||
plus.runtime.openURL(this.href) //这里默认使用外部浏览器打开而不是内部web-view组件打开
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
window.open(this.href)
|
||||
// #endif
|
||||
// #ifdef MP
|
||||
if (this.inWhiteList) { //如果在小程序的网址白名单中,会走内置webview打开,否则会复制网址提示在外部浏览器打开
|
||||
uni.navigateTo({
|
||||
url: '/pages/component/web-view/web-view?url=' + this.href
|
||||
});
|
||||
} else {
|
||||
uni.setClipboardData({
|
||||
data: this.href
|
||||
});
|
||||
uni.showModal({
|
||||
content: '本网址无法直接在小程序内打开。已自动复制网址,请在手机浏览器里粘贴该网址',
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>本地网页</title>
|
||||
<style type="text/css">
|
||||
.btn {
|
||||
display: block;
|
||||
margin: 20px auto;
|
||||
padding: 5px;
|
||||
background-color: #007aff;
|
||||
border: 0;
|
||||
color: #ffffff;
|
||||
height: 40px;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.btn-red {
|
||||
background-color: #dd524d;
|
||||
}
|
||||
|
||||
.btn-yellow {
|
||||
background-color: #f0ad4e;
|
||||
}
|
||||
|
||||
.desc {
|
||||
padding: 10px;
|
||||
color: #999999;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p class="desc">web-view 组件加载本地 html 示例,仅在 App 环境下生效。点击下列按钮,跳转至其它页面。</p>
|
||||
<div class="btn-list">
|
||||
<button class="btn" type="button" data-action="navigateTo">navigateTo</button>
|
||||
<button class="btn" type="button" data-action="redirectTo">redirectTo</button>
|
||||
<button class="btn" type="button" data-action="navigateBack">navigateBack</button>
|
||||
<button class="btn" type="button" data-action="reLaunch">reLaunch</button>
|
||||
<button class="btn" type="button" data-action="switchTab">switchTab</button>
|
||||
</div>
|
||||
<p class="desc">网页向应用发送消息。注意:小程序端应用会在此页面后退时接收到消息。</p>
|
||||
<div class="btn-list">
|
||||
<button class="btn btn-red" type="button" id="postMessage">postMessage</button>
|
||||
</div>
|
||||
<!-- uni 的 SDK -->
|
||||
<script type="text/javascript" src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.1/index.js"></script>
|
||||
<script type="text/javascript">
|
||||
document.addEventListener('UniAppJSBridgeReady', function() {
|
||||
document.querySelector('.btn-list').addEventListener('click', function(evt) {
|
||||
var target = evt.target;
|
||||
if (target.tagName === 'BUTTON') {
|
||||
var action = target.getAttribute('data-action');
|
||||
switch (action) {
|
||||
case 'switchTab':
|
||||
uni.switchTab({
|
||||
url: '/pages/tabBar/API/API'
|
||||
});
|
||||
break;
|
||||
case 'reLaunch':
|
||||
uni.reLaunch({
|
||||
url: '/pages/tabBar/API/API'
|
||||
});
|
||||
break;
|
||||
case 'navigateBack':
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
});
|
||||
break;
|
||||
default:
|
||||
uni[action]({
|
||||
url: '/pages/component/button/button'
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
document.querySelector("#postMessage").addEventListener('click', function() {
|
||||
uni.postMessage({
|
||||
data: {
|
||||
action: 'message'
|
||||
}
|
||||
});
|
||||
})
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<script>
|
||||
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
||||
CSS.supports('top: constant(a)'))
|
||||
document.write(
|
||||
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||
</script>
|
||||
<title></title>
|
||||
<!--preload-links-->
|
||||
<!--app-context-->
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"><!--app-html--></div>
|
||||
<script type="module" src="/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
import App from './App'
|
||||
import store from './store'
|
||||
|
||||
// #ifndef VUE3
|
||||
import Vue from 'vue'
|
||||
Vue.config.productionTip = false
|
||||
Vue.prototype.$store = store
|
||||
Vue.prototype.$adpid = "1111111111"
|
||||
Vue.prototype.$backgroundAudioData = {
|
||||
playing: false,
|
||||
playTime: 0,
|
||||
formatedPlayTime: '00:00:00'
|
||||
}
|
||||
App.mpType = 'app'
|
||||
const app = new Vue({
|
||||
store,
|
||||
...App
|
||||
})
|
||||
app.$mount()
|
||||
// #endif
|
||||
|
||||
// #ifdef VUE3
|
||||
import {
|
||||
createSSRApp
|
||||
} from 'vue'
|
||||
export function createApp() {
|
||||
const app = createSSRApp(App)
|
||||
app.use(store)
|
||||
app.config.globalProperties.$adpid = "1111111111"
|
||||
app.config.globalProperties.$backgroundAudioData = {
|
||||
playing: false,
|
||||
playTime: 0,
|
||||
formatedPlayTime: '00:00:00'
|
||||
}
|
||||
return {
|
||||
app
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
{
|
||||
"name" : "mini-test",
|
||||
"appid" : "__UNI__7850BDB",
|
||||
"description" : "uni-app 框架示例,一套代码,同时发行到iOS、Android、H5、小程序等多个平台,请使用手机扫码快速体验 uni-app 的强大功能",
|
||||
"versionName" : "1.0.0",
|
||||
"versionCode" : "100",
|
||||
"transformPx" : false,
|
||||
"app-plus" : {
|
||||
"usingComponents" : true,
|
||||
"nvueCompiler" : "uni-app",
|
||||
"nvueStyleCompiler" : "uni-app",
|
||||
"compilerVersion" : 3,
|
||||
"nvueLaunchMode" : "fast",
|
||||
"splashscreen" : {
|
||||
"alwaysShowBeforeRender" : true,
|
||||
"waiting" : true,
|
||||
"autoclose" : true,
|
||||
"delay" : 0
|
||||
},
|
||||
"modules" : {
|
||||
"OAuth" : {},
|
||||
"Payment" : {},
|
||||
"Push" : {},
|
||||
"Share" : {},
|
||||
"Speech" : {},
|
||||
"VideoPlayer" : {}
|
||||
},
|
||||
"distribute" : {
|
||||
"android" : {
|
||||
"permissions" : [
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_MOCK_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.CALL_PHONE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_TASKS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.INTERNET\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_SMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.RECEIVE_BOOT_COMPLETED\"/>",
|
||||
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
|
||||
"<uses-permission android:name=\"android.permission.SEND_SMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_SMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.RECEIVE_USER_PRESENT\"/>"
|
||||
]
|
||||
},
|
||||
"ios" : {
|
||||
"UIBackgroundModes" : [ "audio" ],
|
||||
"urlschemewhitelist" : [ "baidumap", "iosamap" ]
|
||||
},
|
||||
"sdkConfigs" : {
|
||||
"speech" : {
|
||||
"ifly" : {}
|
||||
}
|
||||
},
|
||||
"orientation" : [ "portrait-primary" ]
|
||||
},
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"quickapp" : {},
|
||||
"quickapp-native" : {
|
||||
"icon" : "/static/logo.png",
|
||||
"package" : "com.example.demo",
|
||||
"features" : [
|
||||
{
|
||||
"name" : "system.clipboard"
|
||||
}
|
||||
]
|
||||
},
|
||||
"quickapp-webview" : {
|
||||
"icon" : "/static/logo.png",
|
||||
"package" : "com.example.demo",
|
||||
"minPlatformVersion" : 1070,
|
||||
"versionName" : "1.0.0",
|
||||
"versionCode" : 100
|
||||
},
|
||||
"mp-weixin" : {
|
||||
"appid" : "wxdaa0c852bdfa9d24",
|
||||
"setting" : {
|
||||
"urlCheck" : false
|
||||
},
|
||||
"usingComponents" : true,
|
||||
"permission" : {
|
||||
"scope.userLocation" : {
|
||||
"desc" : "演示定位能力"
|
||||
}
|
||||
},
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"mp-alipay" : {
|
||||
"usingComponents" : true,
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"mp-baidu" : {
|
||||
"usingComponents" : true,
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
},
|
||||
"dynamicLib" : {
|
||||
"editorLib" : {
|
||||
"provider" : "swan-editor"
|
||||
}
|
||||
}
|
||||
},
|
||||
"mp-toutiao" : {
|
||||
"usingComponents" : true,
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"mp-jd" : {
|
||||
"usingComponents" : true,
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"h5" : {
|
||||
"template" : "template.h5.html",
|
||||
"router" : {
|
||||
"mode" : "history",
|
||||
"base" : ""
|
||||
},
|
||||
"sdkConfigs" : {
|
||||
"maps" : {
|
||||
"qqmap" : {
|
||||
"key" : "TKUBZ-D24AF-GJ4JY-JDVM2-IBYKK-KEBCU"
|
||||
}
|
||||
}
|
||||
},
|
||||
"async" : {
|
||||
"timeout" : 20000
|
||||
},
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"vueVersion" : "3",
|
||||
"mp-kuaishou" : {
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"mp-lark" : {
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"mp-qq" : {
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"quickapp-webview-huawei" : {
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"quickapp-webview-union" : {
|
||||
"uniStatistics" : {
|
||||
"enable" : true
|
||||
}
|
||||
},
|
||||
"uniStatistics" : {
|
||||
"version" : "2",
|
||||
"enable" : true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
{
|
||||
"id": "hello-uniapp",
|
||||
"name": "hello-uniapp",
|
||||
"displayName": "hello-uniapp 示例工程",
|
||||
"version": "3.4.5",
|
||||
"description": "uni-app 框架示例,一套代码,同时发行到iOS、Android、H5、小程序等多个平台,请使用手机扫码快速体验 uni-app 的强大功能",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"repository": "https://github.com/dcloudio/hello-uniapp.git",
|
||||
"keywords": [
|
||||
"hello-uniapp",
|
||||
"uni-app",
|
||||
"uni-ui",
|
||||
"示例工程"
|
||||
],
|
||||
"author": "",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/dcloudio/hello-uniapp/issues"
|
||||
},
|
||||
"homepage": "https://github.com/dcloudio/hello-uniapp#readme",
|
||||
"dependencies": {},
|
||||
"dcloudext": {
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": "",
|
||||
"type": "uniapp-template-project"
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "y"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "y",
|
||||
"百度": "y",
|
||||
"字节跳动": "y",
|
||||
"QQ": "y",
|
||||
"京东": "y",
|
||||
"钉钉": "y",
|
||||
"快手": "y",
|
||||
"飞书": "y"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "y",
|
||||
"联盟": "y"
|
||||
},
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"uni-app": {
|
||||
"scripts": {
|
||||
"mp-dingtalk": {
|
||||
"title": "钉钉小程序",
|
||||
"env": {
|
||||
"UNI_PLATFORM": "mp-alipay"
|
||||
},
|
||||
"define": {
|
||||
"MP-DINGTALK": true
|
||||
}
|
||||
},
|
||||
"hello-uniapp-demo": {
|
||||
"title": "hello-uniapp 演示网站",
|
||||
"env": {
|
||||
"UNI_PLATFORM": "h5"
|
||||
},
|
||||
"define": {
|
||||
"H5-DEMO": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,60 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-btn-v">
|
||||
<button class="target" type="default" @tap="actionSheetTap">弹出action sheet</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'action-sheet',
|
||||
buttonRect: {}
|
||||
}
|
||||
},
|
||||
// #ifdef H5
|
||||
onReady() {
|
||||
this.getNodeInfo()
|
||||
window.addEventListener('resize', this.getNodeInfo)
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('resize', this.getNodeInfo)
|
||||
},
|
||||
// #endif
|
||||
methods: {
|
||||
actionSheetTap() {
|
||||
const that = this
|
||||
uni.showActionSheet({
|
||||
title: '标题',
|
||||
itemList: ['item1', 'item2', 'item3', 'item4'],
|
||||
popover: {
|
||||
// 104: navbar + topwindow 高度,暂时 fix createSelectorQuery 在 pc 上获取 top 不准确的 bug
|
||||
top: that.buttonRect.top + 104 + that.buttonRect.height,
|
||||
left: that.buttonRect.left + that.buttonRect.width / 2
|
||||
},
|
||||
success: (e) => {
|
||||
console.log(e.tapIndex);
|
||||
uni.showToast({
|
||||
title: "点击了第" + e.tapIndex + "个选项",
|
||||
icon: "none"
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
// #ifdef H5
|
||||
getNodeInfo() {
|
||||
uni.createSelectorQuery().select('.target').boundingClientRect().exec((ret) => {
|
||||
const rect = ret[0]
|
||||
if (rect) {
|
||||
this.buttonRect = rect
|
||||
}
|
||||
});
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-common-mt">
|
||||
<view class="uni-list">
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">名称</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" placeholder="请输入联系人名称" name="name" :value="name" @input="nameChange"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">手机号</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" placeholder="请输入联系人手机号" name="phone" :value="phone" @input="phoneChange"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" class="btn-setstorage" @tap="add">添加联系人</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
// #ifdef APP-PLUS
|
||||
import permision from "@/common/permission.js"
|
||||
// #endif
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'addPhoneContact',
|
||||
name: '',
|
||||
phone: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
nameChange: function(e) {
|
||||
this.name = e.detail.value
|
||||
},
|
||||
phoneChange: function(e) {
|
||||
this.phone = e.detail.value
|
||||
},
|
||||
async add() {
|
||||
// #ifdef APP-PLUS
|
||||
let status = await this.checkPermission();
|
||||
if (status !== 1) {
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
|
||||
uni.addPhoneContact({
|
||||
firstName: this.name,
|
||||
mobilePhoneNumber: this.phone,
|
||||
success: function() {
|
||||
uni.showModal({
|
||||
content: '已成功添加联系人!',
|
||||
showCancel: false
|
||||
})
|
||||
},
|
||||
fail: function() {
|
||||
uni.showModal({
|
||||
content: '添加联系人失败!',
|
||||
showCancel: false
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
// #ifdef APP-PLUS
|
||||
,
|
||||
async checkPermission() {
|
||||
let status = permision.isIOS ? await permision.requestIOS('contact') :
|
||||
await permision.requestAndroid('android.permission.WRITE_CONTACTS');
|
||||
|
||||
if (status === null || status === 1) {
|
||||
status = 1;
|
||||
} else {
|
||||
uni.showModal({
|
||||
content: "需要联系人权限",
|
||||
confirmText: "设置",
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
permision.gotoAppSetting();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
return status;
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="animation-element-wrapper">
|
||||
<view class="animation-element" :animation="animationData"></view>
|
||||
</view>
|
||||
<scroll-view class="animation-buttons" scroll-y="true">
|
||||
<button class="animation-button" @tap="rotate">旋转</button>
|
||||
<button class="animation-button" @tap="scale">缩放</button>
|
||||
<button class="animation-button" @tap="translate">移动</button>
|
||||
<button class="animation-button" @tap="skew">倾斜</button>
|
||||
<button class="animation-button" @tap="rotateAndScale">旋转并缩放</button>
|
||||
<button class="animation-button" @tap="rotateThenScale">旋转后缩放</button>
|
||||
<button class="animation-button" @tap="all">同时展示全部</button>
|
||||
<button class="animation-button" @tap="allInQueue">顺序展示全部</button>
|
||||
<button class="animation-button animation-button-reset" @tap="reset">还原</button>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'createAnimation',
|
||||
animationData: ''
|
||||
}
|
||||
},
|
||||
onUnload(){
|
||||
this.animationData = ''
|
||||
},
|
||||
onLoad() {
|
||||
this.animation = uni.createAnimation()
|
||||
},
|
||||
methods: {
|
||||
rotate: function () {
|
||||
this.animation.rotate(Math.random() * 720 - 360).step()
|
||||
this.animationData = this.animation.export()
|
||||
},
|
||||
scale: function () {
|
||||
this.animation.scale(Math.random() * 2).step()
|
||||
this.animationData = this.animation.export()
|
||||
},
|
||||
translate: function () {
|
||||
this.animation.translate(Math.random() * 100 - 50, Math.random() * 100 - 50).step()
|
||||
this.animationData = this.animation.export()
|
||||
},
|
||||
skew: function () {
|
||||
this.animation.skew(Math.random() * 90, Math.random() * 90).step()
|
||||
this.animationData = this.animation.export()
|
||||
},
|
||||
rotateAndScale: function () {
|
||||
this.animation.rotate(Math.random() * 720 - 360)
|
||||
.scale(Math.random() * 2)
|
||||
.step()
|
||||
this.animationData = this.animation.export()
|
||||
},
|
||||
rotateThenScale: function () {
|
||||
this.animation.rotate(Math.random() * 720 - 360).step()
|
||||
.scale(Math.random() * 2).step()
|
||||
this.animationData = this.animation.export()
|
||||
},
|
||||
all: function () {
|
||||
this.animation.rotate(Math.random() * 720 - 360)
|
||||
.scale(Math.random() * 2)
|
||||
.translate(Math.random() * 100 - 50, Math.random() * 100 - 50)
|
||||
.skew(Math.random() * 90, Math.random() * 90)
|
||||
.step()
|
||||
this.animationData = this.animation.export()
|
||||
},
|
||||
allInQueue: function () {
|
||||
this.animation.rotate(Math.random() * 720 - 360).step()
|
||||
.scale(Math.random() * 2).step()
|
||||
.translate(Math.random() * 100 - 50, Math.random() * 100 - 50).step()
|
||||
.skew(Math.random() * 90, Math.random() * 90).step()
|
||||
this.animationData = this.animation.export()
|
||||
},
|
||||
reset: function () {
|
||||
this.animation.rotate(0, 0)
|
||||
.scale(1)
|
||||
.translate(0, 0)
|
||||
.skew(0, 0)
|
||||
.step({
|
||||
duration: 0
|
||||
})
|
||||
this.animationData = this.animation.export()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.animation-element-wrapper {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding-top: 150rpx;
|
||||
padding-bottom: 150rpx;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.animation-element {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
background-color: #1AAD19;
|
||||
}
|
||||
|
||||
.animation-buttons {
|
||||
padding:30rpx 0;
|
||||
width: 100%;
|
||||
/* height: 360rpx; */
|
||||
}
|
||||
|
||||
.animation-button {
|
||||
float: left;
|
||||
width: 44%;
|
||||
margin: 15rpx 3%;
|
||||
}
|
||||
|
||||
.animation-button-reset {
|
||||
width: 94%;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-center">
|
||||
<text class="time-big">{{formatedPlayTime}}</text>
|
||||
</view>
|
||||
<view class="uni-common-mt">
|
||||
<slider class="slider" min="0" max="21" step="1" :value="playTime" @change="seek"></slider>
|
||||
</view>
|
||||
<view class="play-time">
|
||||
<text>00:00</text>
|
||||
<text>00:21</text>
|
||||
</view>
|
||||
<view class="uni-hello-text">注意:离开当前页面后背景音乐将保持播放,但退出uni-app将停止</view>
|
||||
<view class="page-body-buttons">
|
||||
<block v-if="playing">
|
||||
<view class="page-body-button" @tap="stop">
|
||||
<image src="/static/stop.png"></image>
|
||||
</view>
|
||||
<view class="page-body-button" @tap="pause">
|
||||
<image src="/static/pause.png"></image>
|
||||
</view>
|
||||
</block>
|
||||
<block v-if="!playing">
|
||||
<view class="page-body-button"></view>
|
||||
<view class="page-body-button" @tap="play">
|
||||
<image src="/static/play.png"></image>
|
||||
</view>
|
||||
</block>
|
||||
<view class="page-body-button"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
import * as util from '../../../common/util.js';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'backgroundAudio',
|
||||
bgAudioMannager: null,
|
||||
dataUrl: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-hello-uniapp/2cc220e0-c27a-11ea-9dfb-6da8e309e0d8.mp3',
|
||||
playing: false,
|
||||
playTime: 0,
|
||||
formatedPlayTime: '00:00:00'
|
||||
}
|
||||
},
|
||||
onLoad: function () {
|
||||
this.playing = this.$backgroundAudioData.playing;
|
||||
this.playTime = this.$backgroundAudioData.playTime;
|
||||
this.formatedPlayTime = this.$backgroundAudioData.formatedPlayTime;
|
||||
|
||||
let bgAudioMannager = uni.getBackgroundAudioManager();
|
||||
if(!bgAudioMannager.title){
|
||||
bgAudioMannager.title = '致爱丽丝';
|
||||
}
|
||||
if(!bgAudioMannager.singer) {
|
||||
bgAudioMannager.singer = '暂无';
|
||||
}
|
||||
if(!bgAudioMannager.coverImgUrl){
|
||||
bgAudioMannager.coverImgUrl = 'https://web-assets.dcloud.net.cn/unidoc/zh/Alice.jpeg';
|
||||
}
|
||||
|
||||
bgAudioMannager.onPlay(() => {
|
||||
console.log("开始播放");
|
||||
this.$backgroundAudioData.playing = this.playing = true;
|
||||
})
|
||||
bgAudioMannager.onPause(() => {
|
||||
console.log("暂停播放");
|
||||
this.$backgroundAudioData.playing = this.playing = false;
|
||||
})
|
||||
bgAudioMannager.onEnded(() => {
|
||||
this.playing = false;
|
||||
this.$backgroundAudioData.playing = false;
|
||||
this.$backgroundAudioData.playTime = this.playTime = 0;
|
||||
this.$backgroundAudioData.formatedPlayTime = this.formatedPlayTime = util.formatTime(0);
|
||||
})
|
||||
|
||||
bgAudioMannager.onTimeUpdate((e) => {
|
||||
if (Math.floor(bgAudioMannager.currentTime) > Math.floor(this.playTime)) {
|
||||
this.$backgroundAudioData.formatedPlayTime = this.formatedPlayTime = util.formatTime(Math.floor(bgAudioMannager.currentTime));
|
||||
}
|
||||
this.$backgroundAudioData.playTime = this.playTime = bgAudioMannager.currentTime;
|
||||
})
|
||||
|
||||
this.bgAudioMannager = bgAudioMannager;
|
||||
},
|
||||
methods: {
|
||||
play: function (res) {
|
||||
if (!this.bgAudioMannager.src) {
|
||||
this.bgAudioMannager.startTime = this.playTime;
|
||||
this.bgAudioMannager.src = this.dataUrl;
|
||||
} else {
|
||||
this.bgAudioMannager.seek(this.playTime);
|
||||
this.bgAudioMannager.play();
|
||||
}
|
||||
},
|
||||
seek: function (e) {
|
||||
this.bgAudioMannager.seek(e.detail.value);
|
||||
},
|
||||
pause: function () {
|
||||
this.bgAudioMannager.pause();
|
||||
},
|
||||
stop: function () {
|
||||
this.bgAudioMannager.stop();
|
||||
this.$backgroundAudioData.playing = this.playing = false;
|
||||
this.$backgroundAudioData.playTime = this.playTime = 0;
|
||||
this.$backgroundAudioData.formatedPlayTime = this.formatedPlayTime = util.formatTime(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
image {
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
}
|
||||
|
||||
.page-body-text {
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.page-body-wrapper {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.page-body-info {
|
||||
padding-bottom: 50rpx;
|
||||
}
|
||||
|
||||
.time-big {
|
||||
font-size: 60rpx;
|
||||
margin: 20rpx;
|
||||
}
|
||||
|
||||
.slider {
|
||||
width:630rpx;
|
||||
}
|
||||
|
||||
.play-time {
|
||||
font-size: 28rpx;
|
||||
width:100%;
|
||||
padding: 20rpx 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.page-body-buttons {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
margin-top: 100rpx;
|
||||
}
|
||||
|
||||
.page-body-button {
|
||||
width: 250rpx;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,723 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view>
|
||||
本蓝牙协议只支持低功耗蓝牙协议ble。如果想连接非ble蓝牙设备,请在社区搜索 Native.js 蓝牙。
|
||||
</view>
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" :disabled="disabled[0]" @click="openBluetoothAdapter">
|
||||
初始化蓝牙模块
|
||||
</button>
|
||||
<view v-if="!adapterState.available">
|
||||
{{ '蓝牙适配器不可用,请初始化蓝牙模块' }}
|
||||
</view>
|
||||
<button
|
||||
type="primary"
|
||||
:loading="searchLoad"
|
||||
:disabled="disabled[1]"
|
||||
@click="startBluetoothDevicesDiscovery"
|
||||
>
|
||||
开始搜索蓝牙设备
|
||||
</button>
|
||||
<button
|
||||
type="primary"
|
||||
:disabled="disabled[2]"
|
||||
@click="stopBluetoothDevicesDiscovery(false)"
|
||||
>
|
||||
停止搜索蓝牙设备
|
||||
</button>
|
||||
<button
|
||||
type="primary"
|
||||
:loading="newDeviceLoad"
|
||||
:disabled="disabled[3]"
|
||||
@click="queryDevices"
|
||||
>
|
||||
选择设备
|
||||
</button>
|
||||
<view v-if="equipment.length > 0">
|
||||
{{
|
||||
(connected ? '已连接设备' : '已选择设备') +
|
||||
' : ' +
|
||||
equipment[0].name +
|
||||
' (' +
|
||||
equipment[0].deviceId +
|
||||
')'
|
||||
}}
|
||||
</view>
|
||||
<button type="primary" :disabled="disabled[4]" @click="createBLEConnection">
|
||||
连接蓝牙设备
|
||||
</button>
|
||||
<button type="primary" :disabled="disabled[5]" @click="getBLEDeviceServices">
|
||||
选择设备服务
|
||||
</button>
|
||||
<view v-if="servicesData.length > 0">已选服务uuid:{{ servicesData[0].uuid }}</view>
|
||||
<button type="primary" :disabled="disabled[6]" @click="getBLEDeviceCharacteristics">
|
||||
获取服务的特征值
|
||||
</button>
|
||||
<view v-if="characteristicsData.length > 0">
|
||||
<view class="uni-list_name">uuid:{{ characteristicsData[0].uuid }}</view>
|
||||
<view class="uni-list_item">
|
||||
是否支持 read 操作:{{ characteristicsData[0].properties.read }}
|
||||
</view>
|
||||
<view class="uni-list_item">
|
||||
是否支持 write 操作:{{ characteristicsData[0].properties.write }}
|
||||
</view>
|
||||
<view class="uni-list_item">
|
||||
是否支持 notify 操作:{{ characteristicsData[0].properties.notify }}
|
||||
</view>
|
||||
<view class="uni-list_item">
|
||||
是否支持 indicate 操作:{{ characteristicsData[0].properties.indicate }}
|
||||
</view>
|
||||
</view>
|
||||
<!-- <button type="primary" :disabled="disabled[7]" @click="readBLECharacteristicValue">
|
||||
读取特征值数据
|
||||
</button>
|
||||
<view v-if="valueChangeData.serviceId">
|
||||
<view class="list-name">
|
||||
特征值最新的值:{{ valueChangeData.value || '还没有最新值' }}
|
||||
</view>
|
||||
</view> -->
|
||||
<!-- <button type="primary" :disabled="disabled[8]" @click="w">写入特征值数据</button> -->
|
||||
<button type="primary" :disabled="disabled[9]" @click="closeBLEConnection">
|
||||
断开蓝牙设备
|
||||
</button>
|
||||
<button type="primary" :disabled="disabled[10]" @click="closeBluetoothAdapter">
|
||||
关闭蓝牙模块
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 遮罩 -->
|
||||
<view v-if="maskShow" class="uni-mask" @touchmove.stop.prevent="moveHandle" @click="maskclose">
|
||||
<scroll-view class="uni-scroll_box" scroll-y @touchmove.stop.prevent="moveHandle" @click.stop="moveHandle">
|
||||
<view class="uni-title">
|
||||
已经发现{{ list.length }}{{ showMaskType === 'device' ? '台设备' : '个服务' }}:
|
||||
</view>
|
||||
<view
|
||||
class="uni-list-box"
|
||||
v-for="(item, index) in list"
|
||||
:key="index"
|
||||
@click="tapQuery(item)"
|
||||
>
|
||||
<view v-if="showMaskType === 'device'">
|
||||
<view class="uni-list_name">{{ item.name || item.localName }}</view>
|
||||
<view class="uni-list_item">信号强度:{{ item.RSSI }}dBm</view>
|
||||
<view class="uni-list_item">UUID:{{ item.deviceId }}</view>
|
||||
<!-- <view class="list-item" v-if="showMaskType === 'device'">
|
||||
Service数量:{{ item.advertisServiceUUIDs.length }}
|
||||
</view> -->
|
||||
</view>
|
||||
<view v-if="showMaskType === 'service'">
|
||||
<view class="uni-list_item" style="line-height:2.2;">
|
||||
UUID: {{ item.uuid }}
|
||||
<text v-if="showMaskType === 'service'">
|
||||
{{ item.isPrimary ? '(主服务)' : '' }}
|
||||
</text>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="showMaskType === 'characteristics'">
|
||||
<view class="uni-list_name">uuid:{{ item.uuid }}</view>
|
||||
<view class="uni-list_item">是否支持 read 操作:{{ item.properties.read }}</view>
|
||||
<view class="uni-list_item">
|
||||
是否支持 write 操作:{{ item.properties.write }}
|
||||
</view>
|
||||
<view class="uni-list_item">
|
||||
是否支持 notify 操作:{{ item.properties.notify }}
|
||||
</view>
|
||||
<view class="uni-list_item">
|
||||
是否支持 indicate 操作:{{ item.properties.indicate }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'bluetooth',
|
||||
disabled: [false, true, true, true, true, true, true, true, true, true, true],
|
||||
newDeviceLoad: false,
|
||||
searchLoad: false,
|
||||
maskShow: false,
|
||||
equipment: [],
|
||||
adapterState: {
|
||||
discovering: false,
|
||||
available: false
|
||||
},
|
||||
connected: false,
|
||||
showMaskType: 'device',
|
||||
servicesData: [],
|
||||
characteristicsData: [],
|
||||
valueChangeData: {},
|
||||
isStop:true ,
|
||||
list: []
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.onBLEConnectionStateChange();
|
||||
},
|
||||
methods: {
|
||||
moveHandle() {},
|
||||
/**
|
||||
* 关闭遮罩
|
||||
*/
|
||||
maskclose(){
|
||||
this.maskShow = false;
|
||||
},
|
||||
/**
|
||||
* 选择设备
|
||||
*/
|
||||
queryDevices() {
|
||||
// this.newDeviceLoad = true;
|
||||
this.showMaskType = 'device';
|
||||
this.maskShow = true;
|
||||
},
|
||||
tapQuery(item) {
|
||||
if (this.showMaskType === 'device') {
|
||||
this.$set(this.disabled, 4, false);
|
||||
if (this.equipment.length > 0) {
|
||||
this.equipment[0] = item;
|
||||
} else {
|
||||
this.equipment.push(item);
|
||||
}
|
||||
this.newDeviceLoad = false;
|
||||
}
|
||||
if (this.showMaskType === 'service') {
|
||||
this.$set(this.disabled, 6, false);
|
||||
if (this.servicesData.length > 0) {
|
||||
this.servicesData[0] = item;
|
||||
} else {
|
||||
this.servicesData.push(item);
|
||||
}
|
||||
}
|
||||
if (this.showMaskType === 'characteristics') {
|
||||
this.$set(this.disabled, 7, false);
|
||||
if (this.characteristicsData.length > 0) {
|
||||
this.characteristicsData[0] = item;
|
||||
} else {
|
||||
this.characteristicsData.push(item);
|
||||
}
|
||||
}
|
||||
this.maskShow = false;
|
||||
},
|
||||
/**
|
||||
* 初始化蓝牙设备
|
||||
*/
|
||||
openBluetoothAdapter() {
|
||||
uni.openBluetoothAdapter({
|
||||
success: e => {
|
||||
console.log('初始化蓝牙成功:' + e.errMsg);
|
||||
console.log(JSON.stringify(e));
|
||||
this.isStop = false ;
|
||||
this.$set(this.disabled, 0, true);
|
||||
this.$set(this.disabled, 1, false);
|
||||
this.$set(this.disabled, 10, false);
|
||||
this.getBluetoothAdapterState();
|
||||
},
|
||||
fail: e => {
|
||||
console.log(e)
|
||||
console.log('初始化蓝牙失败,错误码:' + (e.errCode || e.errMsg));
|
||||
if (e.errCode !== 0) {
|
||||
initTypes(e.errCode,e.errMsg);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 开始搜索蓝牙设备
|
||||
*/
|
||||
startBluetoothDevicesDiscovery() {
|
||||
uni.startBluetoothDevicesDiscovery({
|
||||
success: e => {
|
||||
console.log('开始搜索蓝牙设备:' + e.errMsg);
|
||||
this.searchLoad = true;
|
||||
this.$set(this.disabled, 1, true);
|
||||
this.$set(this.disabled, 2, false);
|
||||
this.$set(this.disabled, 3, false);
|
||||
this.onBluetoothDeviceFound();
|
||||
},
|
||||
fail: e => {
|
||||
console.log('搜索蓝牙设备失败,错误码:' + e.errCode);
|
||||
if (e.errCode !== 0) {
|
||||
initTypes(e.errCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 停止搜索蓝牙设备
|
||||
*/
|
||||
stopBluetoothDevicesDiscovery(types) {
|
||||
uni.stopBluetoothDevicesDiscovery({
|
||||
success: e => {
|
||||
console.log('停止搜索蓝牙设备:' + e.errMsg);
|
||||
if (types) {
|
||||
this.$set(this.disabled, 1, true);
|
||||
} else {
|
||||
this.$set(this.disabled, 1, false);
|
||||
}
|
||||
this.$set(this.disabled, 2, true);
|
||||
// this.$set(this.disabled, 3, true);
|
||||
this.searchLoad = false;
|
||||
},
|
||||
fail: e => {
|
||||
console.log('停止搜索蓝牙设备失败,错误码:' + e.errCode);
|
||||
if (e.errCode !== 0) {
|
||||
initTypes(e.errCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 发现外围设备
|
||||
*/
|
||||
onBluetoothDeviceFound() {
|
||||
uni.onBluetoothDeviceFound(devices => {
|
||||
console.log('开始监听寻找到新设备的事件');
|
||||
// this.$set(this.disabled, 3, false);
|
||||
this.getBluetoothDevices();
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取在蓝牙模块生效期间所有已发现的蓝牙设备。包括已经和本机处于连接状态的设备。
|
||||
*/
|
||||
getBluetoothDevices() {
|
||||
uni.getBluetoothDevices({
|
||||
success: res => {
|
||||
this.newDeviceLoad = false;
|
||||
console.log('获取蓝牙设备成功:' + res.errMsg);
|
||||
// console.log(JSON.stringify(res))
|
||||
this.list = res.devices;
|
||||
},
|
||||
fail: e => {
|
||||
console.log('获取蓝牙设备错误,错误码:' + e.errCode);
|
||||
if (e.errCode !== 0) {
|
||||
initTypes(e.errCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取本机蓝牙适配器状态
|
||||
*/
|
||||
getBluetoothAdapterState() {
|
||||
console.log('--->');
|
||||
uni.getBluetoothAdapterState({
|
||||
success: res => {
|
||||
console.log(JSON.stringify(res));
|
||||
this.adapterState = res;
|
||||
},
|
||||
fail: e => {
|
||||
console.log('获取本机蓝牙适配器状态失败,错误码:' + e.errCode);
|
||||
if (e.errCode !== 0) {
|
||||
initTypes(e.errCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 连接低功耗蓝牙
|
||||
*/
|
||||
createBLEConnection() {
|
||||
let deviceId = this.equipment[0].deviceId;
|
||||
uni.showToast({
|
||||
title: '连接蓝牙...',
|
||||
icon: 'loading',
|
||||
duration: 99999
|
||||
});
|
||||
uni.createBLEConnection({
|
||||
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
|
||||
deviceId,
|
||||
success: res => {
|
||||
console.log(res);
|
||||
console.log('连接蓝牙成功:' + res.errMsg);
|
||||
// 连接设备后断开搜索 并且不能搜索设备
|
||||
this.stopBluetoothDevicesDiscovery(true);
|
||||
uni.hideToast();
|
||||
uni.showToast({
|
||||
title: '连接成功',
|
||||
icon: 'success',
|
||||
duration: 2000
|
||||
});
|
||||
this.$set(this.disabled, 3, true);
|
||||
this.$set(this.disabled, 4, true);
|
||||
this.$set(this.disabled, 5, false);
|
||||
this.$set(this.disabled, 9, false);
|
||||
this.connected = true;
|
||||
},
|
||||
fail: e => {
|
||||
console.log('连接低功耗蓝牙失败,错误码:' + e.errCode);
|
||||
if (e.errCode !== 0) {
|
||||
initTypes(e.errCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 断开与低功耗蓝牙设备的连接
|
||||
*/
|
||||
closeBLEConnection() {
|
||||
let deviceId = this.equipment[0].deviceId;
|
||||
uni.closeBLEConnection({
|
||||
deviceId,
|
||||
success: res => {
|
||||
console.log(res);
|
||||
console.log('断开低功耗蓝牙成功:' + res.errMsg);
|
||||
this.$set(this.disabled, 1, false);
|
||||
this.$set(this.disabled, 3, true);
|
||||
this.$set(this.disabled, 4, true);
|
||||
this.$set(this.disabled, 5, true);
|
||||
this.$set(this.disabled, 6, true);
|
||||
this.$set(this.disabled, 7, true);
|
||||
this.$set(this.disabled, 8, true);
|
||||
this.$set(this.disabled, 9, true);
|
||||
this.equipment = [];
|
||||
this.servicesData = [];
|
||||
this.characteristicsData = [];
|
||||
},
|
||||
fail: e => {
|
||||
console.log('断开低功耗蓝牙成功,错误码:' + e.errCode);
|
||||
if (e.errCode !== 0) {
|
||||
initTypes(e.errCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取所有服务
|
||||
*/
|
||||
getBLEDeviceServices() {
|
||||
let deviceId = this.equipment[0].deviceId;
|
||||
console.log('获取所有服务的 uuid:' + deviceId);
|
||||
|
||||
uni.getBLEDeviceServices({
|
||||
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
|
||||
deviceId,
|
||||
success: res => {
|
||||
console.log(JSON.stringify(res.services));
|
||||
console.log('获取设备服务成功:' + res.errMsg);
|
||||
this.$set(this.disabled, 7, true);
|
||||
this.$set(this.disabled, 8, true);
|
||||
this.showMaskType = 'service';
|
||||
this.list = res.services;
|
||||
|
||||
this.characteristicsData = [];
|
||||
if (this.list.length <= 0) {
|
||||
toast('获取服务失败,请重试!');
|
||||
return;
|
||||
}
|
||||
this.maskShow = true;
|
||||
},
|
||||
fail: e => {
|
||||
console.log('获取设备服务失败,错误码:' + e.errCode);
|
||||
if (e.errCode !== 0) {
|
||||
initTypes(e.errCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取某个服务下的所有特征值
|
||||
*/
|
||||
getBLEDeviceCharacteristics() {
|
||||
let deviceId = this.equipment[0].deviceId;
|
||||
let serviceId = this.servicesData[0].uuid;
|
||||
console.log(deviceId);
|
||||
console.log(serviceId);
|
||||
uni.getBLEDeviceCharacteristics({
|
||||
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
|
||||
deviceId,
|
||||
// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
|
||||
serviceId,
|
||||
success: res => {
|
||||
console.log(JSON.stringify(res));
|
||||
console.log('获取特征值成功:' + res.errMsg);
|
||||
this.$set(this.disabled, 7, true);
|
||||
this.valueChangeData = {};
|
||||
this.showMaskType = 'characteristics';
|
||||
this.list = res.characteristics;
|
||||
if (this.list.length <= 0) {
|
||||
toast('获取特征值失败,请重试!');
|
||||
return;
|
||||
}
|
||||
this.maskShow = true;
|
||||
},
|
||||
fail: e => {
|
||||
console.log('获取特征值失败,错误码:' + e.errCode);
|
||||
if (e.errCode !== 0) {
|
||||
initTypes(e.errCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 监听低功耗蓝牙连接状态的改变事件。包括开发者主动连接或断开连接,设备丢失,连接异常断开等等
|
||||
*/
|
||||
onBLEConnectionStateChange() {
|
||||
uni.onBLEConnectionStateChange(res => {
|
||||
// 该方法回调中可以用于处理连接意外断开等异常情况
|
||||
console.log(`蓝牙连接状态 -------------------------->`);
|
||||
console.log(JSON.stringify(res));
|
||||
if (!res.connected) {
|
||||
if(this.isStop) return ;
|
||||
console.log('断开低功耗蓝牙成功:');
|
||||
this.$set(this.disabled, 1, false);
|
||||
this.$set(this.disabled, 3, true);
|
||||
this.$set(this.disabled, 4, true);
|
||||
this.$set(this.disabled, 5, true);
|
||||
this.$set(this.disabled, 6, true);
|
||||
this.$set(this.disabled, 7, true);
|
||||
this.$set(this.disabled, 8, true);
|
||||
this.$set(this.disabled, 9, true);
|
||||
this.searchLoad = false;
|
||||
this.equipment = [];
|
||||
this.servicesData = [];
|
||||
this.characteristicsData = [];
|
||||
this.valueChangeData = {};
|
||||
toast('已经断开当前蓝牙连接');
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 读取低功耗蓝牙设备的特征值的二进制数据值。注意:必须设备的特征值支持 read 才可以成功调用
|
||||
*/
|
||||
readBLECharacteristicValue() {
|
||||
let deviceId = this.equipment[0].deviceId;
|
||||
let serviceId = this.servicesData[0].uuid;
|
||||
let characteristicId = this.characteristicsData[0].uuid;
|
||||
console.log(deviceId);
|
||||
console.log(serviceId);
|
||||
console.log(characteristicId);
|
||||
uni.readBLECharacteristicValue({
|
||||
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
|
||||
deviceId,
|
||||
// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
|
||||
serviceId,
|
||||
// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
|
||||
characteristicId,
|
||||
success: res => {
|
||||
console.log('读取设备数据值成功');
|
||||
console.log(JSON.stringify(res));
|
||||
this.notifyBLECharacteristicValueChange();
|
||||
},
|
||||
fail(e) {
|
||||
console.log('读取设备数据值失败,错误码:' + e.errCode);
|
||||
if (e.errCode !== 0) {
|
||||
initTypes(e.errCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
this.onBLECharacteristicValueChange();
|
||||
},
|
||||
/**
|
||||
* 监听低功耗蓝牙设备的特征值变化事件。必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。
|
||||
*/
|
||||
onBLECharacteristicValueChange() {
|
||||
// 必须在这里的回调才能获取
|
||||
uni.onBLECharacteristicValueChange(characteristic => {
|
||||
console.log('监听低功耗蓝牙设备的特征值变化事件成功');
|
||||
console.log(JSON.stringify(characteristic));
|
||||
this.valueChangeData = characteristic;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 订阅操作成功后需要设备主动更新特征值的 value,才会触发 uni.onBLECharacteristicValueChange 回调。
|
||||
*/
|
||||
notifyBLECharacteristicValueChange() {
|
||||
let deviceId = this.equipment[0].deviceId;
|
||||
let serviceId = this.servicesData[0].uuid;
|
||||
let characteristicId = this.characteristicsData[0].uuid;
|
||||
let notify = this.characteristicsData[0].properties.notify;
|
||||
console.log(deviceId);
|
||||
console.log(serviceId);
|
||||
console.log(characteristicId);
|
||||
console.log(notify);
|
||||
uni.notifyBLECharacteristicValueChange({
|
||||
state: true, // 启用 notify 功能
|
||||
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
|
||||
deviceId,
|
||||
// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
|
||||
serviceId,
|
||||
// 这里的 characteristicId 需要在 getBLEDeviceCharacteristics 接口中获取
|
||||
characteristicId,
|
||||
success(res) {
|
||||
console.log('notifyBLECharacteristicValueChange success:' + res.errMsg);
|
||||
console.log(JSON.stringify(res));
|
||||
}
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 断开蓝牙模块
|
||||
*/
|
||||
closeBluetoothAdapter(OBJECT) {
|
||||
uni.closeBluetoothAdapter({
|
||||
success: res => {
|
||||
console.log('断开蓝牙模块成功');
|
||||
this.isStop = true ;
|
||||
this.$set(this.disabled, 0, false);
|
||||
this.$set(this.disabled, 1, true);
|
||||
this.$set(this.disabled, 2, true);
|
||||
this.$set(this.disabled, 3, true);
|
||||
this.$set(this.disabled, 4, true);
|
||||
this.$set(this.disabled, 5, true);
|
||||
this.$set(this.disabled, 6, true);
|
||||
this.$set(this.disabled, 7, true);
|
||||
this.$set(this.disabled, 8, true);
|
||||
this.$set(this.disabled, 9, true);
|
||||
this.$set(this.disabled, 10, true);
|
||||
this.equipment = [];
|
||||
this.servicesData = [];
|
||||
this.characteristicsData = [];
|
||||
this.valueChangeData = {};
|
||||
this.adapterState = [];
|
||||
this.searchLoad =false;
|
||||
toast('断开蓝牙模块');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 判断初始化蓝牙状态
|
||||
*/
|
||||
function initTypes(code, errMsg) {
|
||||
switch (code) {
|
||||
case 10000:
|
||||
toast('未初始化蓝牙适配器');
|
||||
break;
|
||||
case 10001:
|
||||
toast('未检测到蓝牙,请打开蓝牙重试!');
|
||||
break;
|
||||
case 10002:
|
||||
toast('没有找到指定设备');
|
||||
break;
|
||||
case 10003:
|
||||
toast('连接失败');
|
||||
break;
|
||||
case 10004:
|
||||
toast('没有找到指定服务');
|
||||
break;
|
||||
case 10005:
|
||||
toast('没有找到指定特征值');
|
||||
break;
|
||||
case 10006:
|
||||
toast('当前连接已断开');
|
||||
break;
|
||||
case 10007:
|
||||
toast('当前特征值不支持此操作');
|
||||
break;
|
||||
case 10008:
|
||||
toast('其余所有系统上报的异常');
|
||||
break;
|
||||
case 10009:
|
||||
toast('Android 系统特有,系统版本低于 4.3 不支持 BLE');
|
||||
break;
|
||||
default:
|
||||
toast(errMsg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹出框封装
|
||||
*/
|
||||
function toast(content, showCancel = false) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content,
|
||||
showCancel
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
.uni-title {
|
||||
/* width: 100%; */
|
||||
/* height: 80rpx; */
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.uni-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
padding: 0 30rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.uni-scroll_box {
|
||||
height: 70%;
|
||||
background: #fff;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
.uni-list-box {
|
||||
margin: 0 20rpx;
|
||||
padding: 15rpx 0;
|
||||
border-bottom: 1px #f5f5f5 solid;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.uni-list:last-child {
|
||||
border: none;
|
||||
}
|
||||
.uni-list_name {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
}
|
||||
.uni-list_item {
|
||||
font-size: 24rpx;
|
||||
color: #555;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.uni-success_box {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
min-height: 100rpx;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
box-sizing: border-box;
|
||||
border-top: 1px #eee solid;
|
||||
}
|
||||
.uni-success_sub {
|
||||
/* width: 100%%; */
|
||||
height: 100rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
.uni-close_button {
|
||||
padding: 0 20rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
background: #ce3c39;
|
||||
color: #ffffff;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
.uni-success_content {
|
||||
height: 600rpx;
|
||||
margin: 30rpx;
|
||||
margin-top: 0;
|
||||
border: 1px #eee solid;
|
||||
padding: 30rpx;
|
||||
}
|
||||
.uni-content_list {
|
||||
padding-bottom: 10rpx;
|
||||
border-bottom: 1px #f5f5f5 solid;
|
||||
}
|
||||
.uni-tips {
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<!-- #ifndef MP-TOUTIAO -->
|
||||
<view class="text-box">亮度 : {{ screen }}</view>
|
||||
<view class="uni-slider"><slider :value="screen" @changing="sliderChange" step="1" /></view>
|
||||
<!-- #endif -->
|
||||
<button type="primary" @click="keep">
|
||||
{{ keepScreenOn ? '保持常亮状态' : '关闭常亮状态' }}
|
||||
</button>
|
||||
<view class="tips">
|
||||
保持常亮时,屏幕不会熄灭。仅在当前应用生效,离开应用后设置失效。
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'brightness',
|
||||
screen: 0,
|
||||
keepScreenOn: true
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
uni.getScreenBrightness({
|
||||
success: res => {
|
||||
this.screen = (res.value * 100).toFixed();
|
||||
},
|
||||
fail(e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
sliderChange(e) {
|
||||
let screen = e.detail.value;
|
||||
// 判断是否重复
|
||||
if (this.screen !== screen) {
|
||||
console.log('当前数值:' + e.detail.value);
|
||||
uni.setScreenBrightness({
|
||||
value: screen / 100,
|
||||
success: function() {
|
||||
},
|
||||
fail(e) {
|
||||
console.log(e);
|
||||
}
|
||||
});
|
||||
this.screen = screen;
|
||||
}
|
||||
},
|
||||
keep() {
|
||||
uni.setKeepScreenOn({
|
||||
keepScreenOn: this.keepScreenOn
|
||||
});
|
||||
this.keepScreenOn = !this.keepScreenOn;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.text-box {
|
||||
margin-bottom: 40rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 300rpx;
|
||||
background-color: #ffffff;
|
||||
font-size: 32rpx;
|
||||
color: #353535;
|
||||
}
|
||||
|
||||
.uni-slider {
|
||||
margin: 100rpx 0;
|
||||
}
|
||||
|
||||
.tips {
|
||||
font-size: 26rpx;
|
||||
text-align: center;
|
||||
margin-top: 20rpx;
|
||||
color: #999;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,366 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-common-mt">
|
||||
<canvas class="canvas-element" canvas-id="canvas" id="canvas"></canvas>
|
||||
<scroll-view class="canvas-buttons" scroll-y="true">
|
||||
<block v-for="(name, index) in names" :key="index">
|
||||
<button class="canvas-button" @click="handleCanvasButton(name)">{{name}}</button>
|
||||
</block>
|
||||
<button class="canvas-button" @click="toTempFilePath" type="primary">toTempFilePath</button>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
var context = null;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'createContext',
|
||||
names: ["rotate", "scale", "reset", "translate", "save", "restore", "drawImage", "fillText", "fill",
|
||||
"stroke", "clearRect", "beginPath", "closePath", "moveTo", "lineTo", "rect", "arc",
|
||||
"quadraticCurveTo", "bezierCurveTo", "setFillStyle", "setStrokeStyle", "setGlobalAlpha",
|
||||
"setShadow", "setFontSize", "setLineCap", "setLineJoin", "setLineWidth", "setMiterLimit"
|
||||
]
|
||||
}
|
||||
},
|
||||
onReady: function() {
|
||||
context = uni.createCanvasContext('canvas',this)
|
||||
},
|
||||
methods: {
|
||||
toTempFilePath: function() {
|
||||
uni.canvasToTempFilePath({
|
||||
canvasId: 'canvas',
|
||||
success: function(res) {
|
||||
console.log(res.tempFilePath)
|
||||
},
|
||||
fail: function(err) {
|
||||
console.error(JSON.stringify(err))
|
||||
}
|
||||
})
|
||||
},
|
||||
handleCanvasButton: function(name) {
|
||||
this[name] && this[name]();
|
||||
},
|
||||
rotate: function() {
|
||||
context.beginPath()
|
||||
context.rotate(10 * Math.PI / 180)
|
||||
context.rect(225, 75, 20, 10)
|
||||
context.fill()
|
||||
context.draw()
|
||||
},
|
||||
scale: function() {
|
||||
context.beginPath()
|
||||
context.rect(25, 25, 50, 50)
|
||||
context.stroke()
|
||||
|
||||
context.scale(2, 2)
|
||||
|
||||
context.beginPath()
|
||||
context.rect(25, 25, 50, 50)
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
reset: function() {
|
||||
context.beginPath()
|
||||
|
||||
context.setFillStyle('#000000')
|
||||
context.setStrokeStyle('#000000')
|
||||
context.setFontSize(10)
|
||||
context.setGlobalAlpha(1)
|
||||
context.setShadow(0, 0, 0, 'rgba(0, 0, 0, 0)')
|
||||
|
||||
context.setLineCap('butt')
|
||||
context.setLineJoin('miter')
|
||||
context.setLineWidth(1)
|
||||
context.setMiterLimit(10)
|
||||
context.draw()
|
||||
},
|
||||
translate: function() {
|
||||
context.beginPath()
|
||||
context.rect(10, 10, 100, 50)
|
||||
context.fill()
|
||||
|
||||
context.translate(70, 70)
|
||||
|
||||
context.beginPath()
|
||||
context.fill()
|
||||
context.draw()
|
||||
},
|
||||
save: function() {
|
||||
context.beginPath()
|
||||
context.setStrokeStyle('#00ff00')
|
||||
context.save()
|
||||
|
||||
context.scale(2, 2)
|
||||
context.setStrokeStyle('#ff0000')
|
||||
context.rect(0, 0, 100, 100)
|
||||
context.stroke()
|
||||
context.restore()
|
||||
|
||||
context.rect(0, 0, 50, 50)
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
restore: function() {
|
||||
[3, 2, 1].forEach(function(item) {
|
||||
context.beginPath()
|
||||
context.save()
|
||||
context.scale(item, item)
|
||||
context.rect(10, 10, 100, 100)
|
||||
context.stroke()
|
||||
context.restore()
|
||||
});
|
||||
context.draw()
|
||||
},
|
||||
drawImage: function() {
|
||||
// #ifdef APP-PLUS
|
||||
context.drawImage('../../../static/app-plus/uni@2x.png', 0, 0)
|
||||
// #endif
|
||||
// #ifndef APP-PLUS
|
||||
context.drawImage('../../../static/uni.png', 0, 0)
|
||||
// #endif
|
||||
context.draw()
|
||||
},
|
||||
fillText: function() {
|
||||
context.setStrokeStyle('#ff0000')
|
||||
|
||||
context.beginPath()
|
||||
context.moveTo(0, 10)
|
||||
context.lineTo(300, 10)
|
||||
context.stroke()
|
||||
// context.save()
|
||||
// context.scale(1.5, 1.5)
|
||||
// context.translate(20, 20)
|
||||
context.setFontSize(10)
|
||||
context.fillText('Hello World', 0, 30)
|
||||
context.setFontSize(20)
|
||||
context.fillText('Hello World', 100, 30)
|
||||
|
||||
// context.restore()
|
||||
|
||||
context.beginPath()
|
||||
context.moveTo(0, 30)
|
||||
context.lineTo(300, 30)
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
fill: function() {
|
||||
context.beginPath()
|
||||
context.rect(20, 20, 150, 100)
|
||||
context.setStrokeStyle('#00ff00')
|
||||
context.fill()
|
||||
context.draw()
|
||||
},
|
||||
stroke: function() {
|
||||
context.beginPath()
|
||||
context.moveTo(20, 20)
|
||||
context.lineTo(20, 100)
|
||||
context.lineTo(70, 100)
|
||||
context.setStrokeStyle('#00ff00')
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
clearRect: function() {
|
||||
context.setFillStyle('#ff0000')
|
||||
context.beginPath()
|
||||
context.rect(0, 0, 300, 150)
|
||||
context.fill()
|
||||
context.clearRect(20, 20, 100, 50)
|
||||
context.draw()
|
||||
},
|
||||
beginPath: function() {
|
||||
context.beginPath()
|
||||
context.setLineWidth(5)
|
||||
context.setStrokeStyle('#ff0000')
|
||||
context.moveTo(0, 75)
|
||||
context.lineTo(250, 75)
|
||||
context.stroke()
|
||||
context.beginPath()
|
||||
context.setStrokeStyle('#0000ff')
|
||||
context.moveTo(50, 0)
|
||||
context.lineTo(150, 130)
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
closePath: function() {
|
||||
context.beginPath()
|
||||
context.setLineWidth(1)
|
||||
context.moveTo(20, 20)
|
||||
context.lineTo(20, 100)
|
||||
context.lineTo(70, 100)
|
||||
context.closePath()
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
moveTo: function() {
|
||||
context.beginPath()
|
||||
context.moveTo(0, 0)
|
||||
context.lineTo(300, 150)
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
lineTo: function() {
|
||||
context.beginPath()
|
||||
context.moveTo(20, 20)
|
||||
context.lineTo(20, 100)
|
||||
context.lineTo(70, 100)
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
rect: function() {
|
||||
context.beginPath()
|
||||
context.rect(20, 20, 150, 100)
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
arc: function() {
|
||||
context.beginPath()
|
||||
context.setLineWidth(2)
|
||||
context.arc(75, 75, 50, 0, Math.PI * 2, true)
|
||||
context.moveTo(110, 75)
|
||||
context.arc(75, 75, 35, 0, Math.PI, false)
|
||||
context.moveTo(65, 65)
|
||||
context.arc(60, 65, 5, 0, Math.PI * 2, true)
|
||||
context.moveTo(95, 65)
|
||||
context.arc(90, 65, 5, 0, Math.PI * 2, true)
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
quadraticCurveTo: function() {
|
||||
context.beginPath()
|
||||
context.moveTo(20, 20)
|
||||
context.quadraticCurveTo(20, 100, 200, 20)
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
bezierCurveTo: function() {
|
||||
context.beginPath()
|
||||
context.moveTo(20, 20)
|
||||
context.bezierCurveTo(20, 100, 200, 100, 200, 20)
|
||||
context.stroke()
|
||||
context.draw()
|
||||
},
|
||||
setFillStyle: function() {
|
||||
['#fef957', 'rgb(242,159,63)', 'rgb(242,117,63)', '#e87e51'].forEach(function(item, index) {
|
||||
context.setFillStyle(item)
|
||||
context.beginPath()
|
||||
context.rect(0 + 75 * index, 0, 50, 50)
|
||||
context.fill()
|
||||
})
|
||||
context.draw()
|
||||
},
|
||||
setStrokeStyle: function() {
|
||||
['#fef957', 'rgb(242,159,63)', 'rgb(242,117,63)', '#e87e51'].forEach(function(item, index) {
|
||||
context.setStrokeStyle(item)
|
||||
context.beginPath()
|
||||
context.rect(0 + 75 * index, 0, 50, 50)
|
||||
context.stroke()
|
||||
})
|
||||
context.draw()
|
||||
},
|
||||
setGlobalAlpha: function() {
|
||||
context.setFillStyle('#000000');
|
||||
[1, 0.5, 0.1].forEach(function(item, index) {
|
||||
context.setGlobalAlpha(item)
|
||||
context.beginPath()
|
||||
context.rect(0 + 75 * index, 0, 50, 50)
|
||||
context.fill()
|
||||
})
|
||||
context.draw()
|
||||
context.setGlobalAlpha(1)
|
||||
},
|
||||
setShadow: function() {
|
||||
context.beginPath()
|
||||
context.setShadow(10, 10, 10, 'rgba(0, 0, 0, 199)')
|
||||
context.rect(10, 10, 100, 100)
|
||||
context.fill()
|
||||
context.draw()
|
||||
},
|
||||
setFontSize: function() {
|
||||
[10, 20, 30, 40].forEach(function(item, index) {
|
||||
context.setFontSize(item)
|
||||
context.fillText('Hello, world', 20, 20 + 40 * index)
|
||||
})
|
||||
context.draw()
|
||||
},
|
||||
setLineCap: function() {
|
||||
context.setLineWidth(10);
|
||||
['butt', 'round', 'square'].forEach(function(item, index) {
|
||||
context.beginPath()
|
||||
context.setLineCap(item)
|
||||
context.moveTo(20, 20 + 20 * index)
|
||||
context.lineTo(100, 20 + 20 * index)
|
||||
context.stroke()
|
||||
})
|
||||
context.draw()
|
||||
},
|
||||
setLineJoin: function() {
|
||||
context.setLineWidth(10);
|
||||
['bevel', 'round', 'miter'].forEach(function(item, index) {
|
||||
context.beginPath()
|
||||
context.setLineJoin(item)
|
||||
context.moveTo(20 + 80 * index, 20)
|
||||
context.lineTo(100 + 80 * index, 50)
|
||||
context.lineTo(20 + 80 * index, 100)
|
||||
context.stroke()
|
||||
})
|
||||
context.draw()
|
||||
},
|
||||
setLineWidth: function() {
|
||||
[2, 4, 6, 8, 10].forEach(function(item, index) {
|
||||
context.beginPath()
|
||||
context.setLineWidth(item)
|
||||
context.moveTo(20, 20 + 20 * index)
|
||||
context.lineTo(100, 20 + 20 * index)
|
||||
context.stroke()
|
||||
})
|
||||
context.draw()
|
||||
},
|
||||
setMiterLimit: function() {
|
||||
context.setLineWidth(4);
|
||||
[2, 4, 6, 8, 10].forEach(function(item, index) {
|
||||
context.beginPath()
|
||||
context.setMiterLimit(item)
|
||||
context.moveTo(20 + 80 * index, 20)
|
||||
context.lineTo(100 + 80 * index, 50)
|
||||
context.lineTo(20 + 80 * index, 100)
|
||||
context.stroke()
|
||||
})
|
||||
context.draw()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.canvas-element-wrapper {
|
||||
display: block;
|
||||
margin-bottom: 100rpx;
|
||||
}
|
||||
|
||||
.canvas-element {
|
||||
width: 100%;
|
||||
height: 500rpx;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.canvas-buttons {
|
||||
padding: 30rpx 50rpx 10rpx;
|
||||
width: 100%;
|
||||
height: 360rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.canvas-button {
|
||||
float: left;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 40px;
|
||||
line-height: 1;
|
||||
width: 300rpx;
|
||||
margin: 15rpx 12rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view style="background:#FFFFFF; padding:40rpx;">
|
||||
<view class="uni-hello-text uni-center">当前位置信息</view>
|
||||
<block v-if="hasLocation === false">
|
||||
<view class="uni-h2 uni-center uni-common-mt">未选择位置</view>
|
||||
</block>
|
||||
<block v-if="hasLocation === true">
|
||||
<view class="uni-hello-text uni-center" style="margin-top:10px;">
|
||||
{{locationAddress}}
|
||||
</view>
|
||||
<view class="uni-h2 uni-center uni-common-mt">
|
||||
<text>E: {{location.longitude[0]}}°{{location.longitude[1]}}′</text>
|
||||
<text>\nN: {{location.latitude[0]}}°{{location.latitude[1]}}′</text>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" @tap="chooseLocation">选择位置</button>
|
||||
<button @tap="clear">清空</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import * as util from '../../../common/util.js'
|
||||
var formatLocation = util.formatLocation;
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'chooseLocation',
|
||||
hasLocation: false,
|
||||
location: {},
|
||||
locationAddress: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
chooseLocation: function () {
|
||||
uni.chooseLocation({
|
||||
success: (res) => {
|
||||
this.hasLocation = true,
|
||||
this.location = formatLocation(res.longitude, res.latitude),
|
||||
this.locationAddress = res.address
|
||||
}
|
||||
})
|
||||
},
|
||||
clear: function () {
|
||||
this.hasLocation = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.page-body-info {
|
||||
padding-bottom: 0;
|
||||
height: 440rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-title">请输入剪贴板内容</view>
|
||||
<view class="uni-list">
|
||||
<view class="uni-list-cell">
|
||||
<input class="uni-input" type="text" placeholder="请输入剪贴板内容" :value="data" @input="dataChange"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" @click="setClipboard">存储数据</button>
|
||||
<button @tap="getClipboard">读取数据</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'get/setClipboardData',
|
||||
data: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
dataChange: function (e) {
|
||||
this.data = e.detail.value
|
||||
},
|
||||
getClipboard: function () {
|
||||
uni.getClipboardData({
|
||||
success: (res) => {
|
||||
console.log(res.data);
|
||||
const content = res.data ? '剪贴板内容为:' + res.data : '剪贴板暂无内容';
|
||||
uni.showModal({
|
||||
content,
|
||||
title: '读取剪贴板',
|
||||
showCancel: false
|
||||
})
|
||||
},
|
||||
fail: () => {
|
||||
uni.showModal({
|
||||
content: '读取剪贴板失败!',
|
||||
showCancel: false
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
setClipboard: function () {
|
||||
var data = this.data;
|
||||
if (data.length === 0) {
|
||||
uni.showModal({
|
||||
title: '设置剪贴板失败',
|
||||
content: '内容不能为空',
|
||||
showCancel: false
|
||||
})
|
||||
} else {
|
||||
uni.setClipboardData({
|
||||
data: data,
|
||||
success: () => {
|
||||
// 成功处理
|
||||
// #ifdef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO
|
||||
uni.showToast({
|
||||
title: '设置剪贴板成功',
|
||||
icon: "success",
|
||||
mask: !1
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
fail: () => {
|
||||
// 失败处理
|
||||
// #ifdef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO
|
||||
uni.showToast({
|
||||
title: '储存数据失败!',
|
||||
icon: "none",
|
||||
mask: !1
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view v-if="imageSrc" class="image-container">
|
||||
<image class="img" :src="imageSrc" mode="center" />
|
||||
</view>
|
||||
<block v-else style="margin-top: 50px;">
|
||||
<view class="uni-hello-text">
|
||||
点击按钮下载服务端示例图片(下载网络文件到本地临时目录)
|
||||
</view>
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" @tap="downloadImage">下载</button>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'downloadFile',
|
||||
imageSrc: ''
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
this.imageSrc = '';
|
||||
},
|
||||
methods: {
|
||||
downloadImage: function () {
|
||||
uni.showLoading({
|
||||
title:'下载中'
|
||||
})
|
||||
var self = this
|
||||
uni.downloadFile({
|
||||
url: "https://web-assets.dcloud.net.cn/unidoc/zh/uni-app.png",
|
||||
success: (res) => {
|
||||
console.log('downloadFile success, res is', res)
|
||||
self.imageSrc = res.tempFilePath;
|
||||
uni.hideLoading();
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('downloadFile fail, err is:', err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.img {
|
||||
width: 500rpx;
|
||||
height: 500rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.image-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<block v-if="tempFilePath">
|
||||
<image :src="tempFilePath" class="image" mode="aspectFit"></image>
|
||||
</block>
|
||||
<block v-if="!tempFilePath && savedFilePath">
|
||||
<image :src="savedFilePath" class="image" mode="aspectFit"></image>
|
||||
</block>
|
||||
<block v-if="!tempFilePath && !savedFilePath">
|
||||
<view class="uni-hello-addfile" @click="chooseImage">+ 请选择文件</view>
|
||||
</block>
|
||||
<view class="uni-btn-v">
|
||||
<button class="btn-savefile" @click="saveFile">保存文件</button>
|
||||
<button @click="clear">删除文件</button>
|
||||
</view>
|
||||
<!-- #ifndef MP-ALIPAY || MP-TOUTIAO -->
|
||||
<view class="btn-area">
|
||||
<button @click="openDocument">打开pdf文件</button>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'saveFile',
|
||||
tempFilePath: '',
|
||||
savedFilePath: ''
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.savedFilePath = uni.getStorageSync('savedFilePath');
|
||||
},
|
||||
methods: {
|
||||
chooseImage() {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
success: (res) => {
|
||||
this.tempFilePath = res.tempFilePaths[0];
|
||||
},
|
||||
fail: (err) => {
|
||||
// #ifdef MP
|
||||
uni.getSetting({
|
||||
success: (res) => {
|
||||
let authStatus = res.authSetting['scope.album'] && res.authSetting['scope.camera'];
|
||||
if (!authStatus) {
|
||||
uni.showModal({
|
||||
title: '授权失败',
|
||||
content: 'Hello uni-app需要从您的相机或相册获取图片,请在设置界面打开相关权限',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.openSetting()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
});
|
||||
},
|
||||
saveFile() {
|
||||
if (this.tempFilePath.length > 0) {
|
||||
uni.saveFile({
|
||||
tempFilePath: this.tempFilePath,
|
||||
success: (res) => {
|
||||
this.savedFilePath = res.savedFilePath;
|
||||
uni.setStorageSync('savedFilePath', res.savedFilePath);
|
||||
uni.showModal({
|
||||
title: '保存成功',
|
||||
content: '下次进入页面时,此文件仍可用',
|
||||
showCancel: false
|
||||
});
|
||||
},
|
||||
fail: (res) => {
|
||||
uni.showModal({
|
||||
title: '保存失败',
|
||||
content: '失败原因: ' + JSON.stringify(res),
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.showModal({
|
||||
content: '请选择文件',
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
},
|
||||
clear() {
|
||||
uni.setStorageSync('savedFilePath', '');
|
||||
this.tempFilePath = '';
|
||||
this.savedFilePath = '';
|
||||
},
|
||||
// #ifndef MP-ALIPAY || MP-TOUTIAO
|
||||
openDocument() {
|
||||
uni.downloadFile({
|
||||
url: 'https://web-assets.dcloud.net.cn/unidoc/zh/helloworld.pdf',
|
||||
success: (res) => {
|
||||
uni.openDocument({
|
||||
filePath: res.tempFilePath,
|
||||
success: () => {
|
||||
console.log('打开文档成功');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.image {
|
||||
width: 100%;
|
||||
height: 360rpx;
|
||||
}
|
||||
|
||||
.btn-savefile {
|
||||
background-color: #007aff;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<button :loading="loading" :disabled="loading" type="primary" class="btn" @click="showAd">显示广告</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: '全屏视频广告',
|
||||
loading: false,
|
||||
loadError: false
|
||||
}
|
||||
},
|
||||
onReady() {
|
||||
// #ifdef APP-PLUS
|
||||
this.adOption = {
|
||||
adpid: '1507000611'
|
||||
};
|
||||
// #endif
|
||||
this.createAd();
|
||||
},
|
||||
methods: {
|
||||
createAd() {
|
||||
var _ad = this._ad = uni.createFullScreenVideoAd(this.adOption);
|
||||
_ad.onLoad(() => {
|
||||
this.loading = false;
|
||||
this.loadError = false;
|
||||
_ad.show();
|
||||
console.log('onLoad event')
|
||||
});
|
||||
_ad.onClose((res) => {
|
||||
// 用户点击了【关闭广告】按钮
|
||||
if (res && res.isEnded) {
|
||||
// 正常播放结束
|
||||
console.log("onClose " + res.isEnded);
|
||||
} else {
|
||||
// 播放中途退出
|
||||
console.log("onClose " + res.isEnded);
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
uni.showToast({
|
||||
title: "全屏视频" + (res.isEnded ? "成功" : "未") + "播放完毕",
|
||||
duration: 10000,
|
||||
position: 'bottom'
|
||||
})
|
||||
}, 500)
|
||||
});
|
||||
_ad.onError((err) => {
|
||||
this.loading = false;
|
||||
if (err.code) {
|
||||
this.loadError = true;
|
||||
}
|
||||
console.log('onError event', err)
|
||||
uni.showToast({
|
||||
title: err.errMsg,
|
||||
position: 'bottom'
|
||||
})
|
||||
});
|
||||
},
|
||||
showAd() {
|
||||
this.loading = true;
|
||||
this._ad.load();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.btn {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.ad-tips {
|
||||
color: #999;
|
||||
padding: 30px 0;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view style="background:#FFFFFF; padding:40rpx;">
|
||||
<view class="uni-hello-text uni-center">当前位置经纬度</view>
|
||||
<block v-if="hasLocation === false">
|
||||
<view class="uni-h2 uni-center uni-common-mt">未获取</view>
|
||||
</block>
|
||||
<block v-if="hasLocation === true">
|
||||
<view class="uni-h2 uni-center uni-common-mt">
|
||||
<text>E: {{location.longitude[0]}}°{{location.longitude[1]}}′</text>
|
||||
<text>\nN: {{location.latitude[0]}}°{{location.latitude[1]}}′</text>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" @tap="getLocation">获取位置</button>
|
||||
<button @tap="clear">清空</button>
|
||||
</view>
|
||||
</view>
|
||||
<uni-popup :show="type === 'showpopup'" mode="fixed" @hidePopup="togglePopup('')">
|
||||
<view class="popup-view">
|
||||
<text class="popup-title">需要用户授权位置权限</text>
|
||||
<view class="uni-flex popup-buttons">
|
||||
<button class="uni-flex-item" type="primary" open-type="openSetting" @tap="openSetting">设置</button>
|
||||
<button class="uni-flex-item" @tap="togglePopup('')">取消</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import * as util from '../../../common/util.js'
|
||||
var formatLocation = util.formatLocation;
|
||||
// #ifdef APP-PLUS
|
||||
import permision from "@/common/permission.js"
|
||||
// #endif
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'getLocation',
|
||||
hasLocation: false,
|
||||
location: {},
|
||||
type: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
togglePopup(type) {
|
||||
this.type = type;
|
||||
},
|
||||
showConfirm() {
|
||||
this.type = 'showpopup';
|
||||
},
|
||||
hideConfirm() {
|
||||
this.type = '';
|
||||
},
|
||||
async getLocation() {
|
||||
// #ifdef APP-PLUS
|
||||
let status = await this.checkPermission();
|
||||
if (status !== 1) {
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN || MP-TOUTIAO || MP-QQ
|
||||
let status = await this.getSetting();
|
||||
if (status === 2) {
|
||||
this.showConfirm();
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
|
||||
this.doGetLocation();
|
||||
},
|
||||
doGetLocation() {
|
||||
uni.getLocation({
|
||||
success: (res) => {
|
||||
this.hasLocation = true;
|
||||
this.location = formatLocation(res.longitude, res.latitude);
|
||||
},
|
||||
fail: (err) => {
|
||||
// #ifdef MP-BAIDU
|
||||
if (err.errCode === 202 || err.errCode === 10003) { // 202模拟器 10003真机 user deny
|
||||
this.showConfirm();
|
||||
}
|
||||
// #endif
|
||||
// #ifndef MP-BAIDU
|
||||
if (err.errMsg.indexOf("auth deny") >= 0) {
|
||||
uni.showToast({
|
||||
title: "访问位置被拒绝"
|
||||
})
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: err.errMsg
|
||||
})
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
})
|
||||
},
|
||||
getSetting: function() {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.getSetting({
|
||||
success: (res) => {
|
||||
if (res.authSetting['scope.userLocation'] === undefined) {
|
||||
resolve(0);
|
||||
return;
|
||||
}
|
||||
if (res.authSetting['scope.userLocation']) {
|
||||
resolve(1);
|
||||
} else {
|
||||
resolve(2);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
openSetting: function() {
|
||||
this.hideConfirm();
|
||||
uni.openSetting({
|
||||
success: (res) => {
|
||||
if (res.authSetting && res.authSetting['scope.userLocation']) {
|
||||
this.doGetLocation();
|
||||
}
|
||||
},
|
||||
fail: (err) => {}
|
||||
})
|
||||
},
|
||||
async checkPermission() {
|
||||
let status = permision.isIOS ? await permision.requestIOS('location') :
|
||||
await permision.requestAndroid('android.permission.ACCESS_FINE_LOCATION');
|
||||
|
||||
if (status === null || status === 1) {
|
||||
status = 1;
|
||||
} else if (status === 2) {
|
||||
uni.showModal({
|
||||
content: "系统定位已关闭",
|
||||
confirmText: "确定",
|
||||
showCancel: false,
|
||||
success: function(res) {
|
||||
}
|
||||
})
|
||||
} else if (status.code) {
|
||||
uni.showModal({
|
||||
content: status.message
|
||||
})
|
||||
} else {
|
||||
uni.showModal({
|
||||
content: "需要定位权限",
|
||||
confirmText: "设置",
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
permision.gotoAppSetting();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return status;
|
||||
},
|
||||
clear: function() {
|
||||
this.hasLocation = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.popup-view {
|
||||
width: 500rpx;
|
||||
}
|
||||
|
||||
.popup-title {
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
line-height: 3;
|
||||
margin-bottom: 10px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.popup-buttons button {
|
||||
margin-left: 4px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view style="background:#FFFFFF; padding:40rpx;">
|
||||
<view class="uni-hello-text uni-center">网络状态</view>
|
||||
<block v-if="hasNetworkType === false">
|
||||
<view class="uni-h2 uni-center uni-common-mt">未获取</view>
|
||||
<view class="uni-hello-text uni-center uni-common-mt">请点击下面按钮获取网络状态</view>
|
||||
</block>
|
||||
<block v-if="hasNetworkType === true">
|
||||
<view class="uni-h2 uni-center uni-common-mt">{{networkType}}</view>
|
||||
</block>
|
||||
<view v-if="hasNetworkType === true && networkType === 'wifi'" class="uni-textarea uni-common-mt">
|
||||
<textarea :value="connectedWifi"></textarea>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-btn-v uni-common-mt">
|
||||
<button type="primary" @tap="getNetworkType">获取设备网络状态</button>
|
||||
<!-- #ifdef MP-WEIXIN || MP-JD-->
|
||||
<button v-if="hasNetworkType === true && networkType === 'wifi'" class="uni-common-mt" type="primary" @tap="getConnectedWifi">获取 wifi 信息</button>
|
||||
<!-- #endif -->
|
||||
<button class="uni-common-mt" @tap="clear">清空</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'getNetworkType',
|
||||
hasNetworkType: false,
|
||||
networkType: '',
|
||||
connectedWifi: ''
|
||||
}
|
||||
},
|
||||
onUnload:function(){
|
||||
this.networkType = '',this.hasNetworkType = false;
|
||||
},
|
||||
methods: {
|
||||
getNetworkType: function () {
|
||||
uni.getNetworkType({
|
||||
success: (res) => {
|
||||
console.log(res)
|
||||
this.hasNetworkType = true, this.networkType = res.subtype || res.networkType
|
||||
},
|
||||
fail: () => {
|
||||
uni.showModal({
|
||||
content:'获取失败!',
|
||||
showCancel:false
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
clear: function () {
|
||||
this.hasNetworkType = false,
|
||||
this.networkType = '',
|
||||
this.connectedWifi = ''
|
||||
},
|
||||
// #ifdef MP-WEIXIN || MP-JD
|
||||
getConnectedWifi() {
|
||||
const that = this
|
||||
uni.startWifi({
|
||||
success: function() {
|
||||
uni.getConnectedWifi({
|
||||
success: function(res) {
|
||||
const { wifi } = res
|
||||
that.connectedWifi = JSON.stringify(wifi)
|
||||
},
|
||||
fail: function(res) {
|
||||
}
|
||||
})
|
||||
},
|
||||
fail: function(res) {
|
||||
}
|
||||
})
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="movable block">
|
||||
<!-- #ifndef MP-TOUTIAO -->
|
||||
<movable-area>
|
||||
<movable-view class="target" direction="all" @change="getNodeInfo">Drag</movable-view>
|
||||
</movable-area>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-TOUTIAO -->
|
||||
<view class="target" @click="setPosition" :style="{top:top,left:left}">Click</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<view class="movable">
|
||||
<view class="info">
|
||||
<view v-for="(item,index) in info" :key="index">
|
||||
<text class="b">{{item.key}}</text>
|
||||
<text class="span">{{item.val}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'createSelectorQuery',
|
||||
top: 0,
|
||||
left: '0px',
|
||||
info: []
|
||||
}
|
||||
},
|
||||
onReady() {
|
||||
this.getNodeInfo()
|
||||
},
|
||||
methods: {
|
||||
setPosition() {
|
||||
this.left = Math.random() * uni.upx2px(320) + 'px'
|
||||
this.top = Math.random() * uni.upx2px(320) + 'px'
|
||||
this.getNodeInfo()
|
||||
},
|
||||
getNodeInfo() {
|
||||
uni.createSelectorQuery().select('.target').boundingClientRect().exec((ret) => {
|
||||
const rect = ret[0]
|
||||
if (rect) {
|
||||
const sort = ['left','right','top','bottom','width','height']
|
||||
const info = []
|
||||
for (let i in sort) {
|
||||
let key = sort[i]
|
||||
info.push({
|
||||
'key': key,
|
||||
'val': rect[key]
|
||||
})
|
||||
}
|
||||
this.info = info
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.movable {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.block {
|
||||
height: 400rpx;
|
||||
width: 400rpx;
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #ccc;
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
movable-area {
|
||||
height: 400rpx;
|
||||
width: 400rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.target {
|
||||
height: 80rpx;
|
||||
width: 80rpx;
|
||||
line-height: 80rpx;
|
||||
text-align: center;
|
||||
color: #FFFFFF;
|
||||
background-color: #4cd964;
|
||||
font-size: 28rpx;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.b {
|
||||
font-weight: bold;
|
||||
width: 150rpx;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.span {
|
||||
width: 100rpx;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-common-mt">
|
||||
<view class="uni-list">
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">设备型号</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.model"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">客户端平台</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.platform"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">操作系统版本</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.system"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">语言</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.language"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">版本</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.version"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">屏幕宽度</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.screenWidth"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">屏幕高度</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.screenHeight"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">可使用窗口高度</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.windowHeight"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">可使用窗口的顶部位置</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.windowTop"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">可使用窗口的底部位置</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.windowBottom"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">状态栏的高度</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.statusBarHeight"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">DPI</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.pixelRatio"/>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #ifdef MP -->
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-pd">
|
||||
<view class="uni-label" style="width:180px;">基础库版本</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" placeholder="未获取" :value="systemInfo.SDKVersion"/>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" @tap="getSystemInfo">获取设备系统信息</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'getSystemInfo',
|
||||
systemInfo: {}
|
||||
}
|
||||
},
|
||||
onUnload:function(){
|
||||
this.systemInfo = {};
|
||||
},
|
||||
methods: {
|
||||
getSystemInfo: function () {
|
||||
uni.getSystemInfo({
|
||||
success: (res) => {
|
||||
this.systemInfo = res
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-pd {
|
||||
padding-left: 30rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view style="background:#FFF; padding:40rpx;">
|
||||
<block v-if="hasUserInfo === false">
|
||||
<view class="uni-hello-text uni-center">
|
||||
<text>请点击下方按钮获取用户头像及昵称或手机号</text>
|
||||
</view>
|
||||
</block>
|
||||
<block v-if="hasUserInfo === true">
|
||||
<view class="uni-h4 uni-center uni-common-mt">{{userInfo.nickName || userInfo.nickname || userInfo.gender || userInfo.email || userInfo.phoneNumber}}</view>
|
||||
<view v-if="userInfo.avatarUrl || userInfo.avatar_url " style="padding:30rpx 0; text-align:center;">
|
||||
<image class="userinfo-avatar" :src="userInfo.avatarUrl||userInfo.avatar_url"></image>
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="uni-btn-v">
|
||||
<!-- #ifdef APP-PLUS || MP-ALIPAY || MP-TOUTIAO -->
|
||||
<button type="primary" :loading="btnLoading" @click="getUserInfo">获取用户信息</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP-WEIXIN || MP-BAIDU || MP-QQ || MP-JD -->
|
||||
<button type="primary" open-type="getUserInfo" @getuserinfo="mpGetUserInfo">获取用户信息</button>
|
||||
<!-- #endif -->
|
||||
<button @click="clear">清空</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
mapState,
|
||||
mapMutations,
|
||||
mapActions
|
||||
} from 'vuex'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'getUserInfo',
|
||||
hasUserInfo: false,
|
||||
userInfo: {},
|
||||
btnLoading: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
'loginProvider',
|
||||
'isUniverifyLogin'
|
||||
])
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['getPhoneNumber']),
|
||||
// 获取用户信息 API 在小程序可直接使用,在 5+App 里面需要先登录才能调用
|
||||
getUserInfo() {
|
||||
this.btnLoading = true;
|
||||
if (this.isUniverifyLogin) {
|
||||
// 一键登录
|
||||
this.getPhoneNumber(uni.getStorageSync('univerifyInfo')).then(phoneNumber => {
|
||||
this.hasUserInfo = true;
|
||||
this.userInfo = {
|
||||
phoneNumber
|
||||
};
|
||||
}).catch(err => {
|
||||
console.error('getUserInfo fail:', err);
|
||||
this.hasUserInfo = false;
|
||||
}).finally(() => {
|
||||
this.btnLoading = false;
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
if(this.loginProvider === 'apple'){
|
||||
const nickname = uni.getStorageSync('apple_nickname')
|
||||
if(nickname){
|
||||
this.hasUserInfo = true;
|
||||
this.userInfo = { nickName:nickname }
|
||||
this.btnLoading = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uni.getUserInfo({
|
||||
provider: this.loginProvider,
|
||||
success: (result) => {
|
||||
this.hasUserInfo = true;
|
||||
this.userInfo = result.userInfo;
|
||||
},
|
||||
fail: (error) => {
|
||||
console.log('getUserInfo fail', error);
|
||||
let content = error.errMsg;
|
||||
if (~content.indexOf('uni.login')) {
|
||||
content = '请在登录页面完成登录操作';
|
||||
}
|
||||
// #ifndef APP-PLUS
|
||||
uni.getSetting({
|
||||
success: (res) => {
|
||||
let authStatus = res.authSetting['scope.userInfo'];
|
||||
if (!authStatus) {
|
||||
uni.showModal({
|
||||
title: '授权失败',
|
||||
content: 'Hello uni-app需要获取您的用户信息,请在设置界面打开相关权限',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.openSetting()
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
uni.showModal({
|
||||
title: '获取用户信息失败',
|
||||
content: '错误原因' + content,
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
// #ifdef APP-PLUS
|
||||
uni.showModal({
|
||||
title: '获取用户信息失败',
|
||||
content: '错误原因' + content,
|
||||
showCancel: false
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
complete: () => {
|
||||
this.btnLoading = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
mpGetUserInfo(result) {
|
||||
console.log('mpGetUserInfo', result);
|
||||
if (result.detail.errMsg !== 'getUserInfo:ok') {
|
||||
uni.showModal({
|
||||
title: '获取用户信息失败',
|
||||
content: '错误原因' + result.detail.errMsg,
|
||||
showCancel: false
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.hasUserInfo = true;
|
||||
if(result.detail && result.detail.userInfo){
|
||||
this.userInfo = result.detail.userInfo;
|
||||
}else{
|
||||
// #ifdef MP-JD
|
||||
this.userInfo = result.detail.user_info;
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
clear() {
|
||||
this.hasUserInfo = false;
|
||||
this.userInfo = {};
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.userinfo-avatar {
|
||||
border-radius: 128rpx;
|
||||
width: 128rpx;
|
||||
height: 128rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,300 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" :disabled="isOpen" @click="openBluetoothAdapter">打开蓝牙模块</button>
|
||||
<button type="primary" :disabled="!isOpen" @click="closeBluetoothAdapter">关闭蓝牙模块</button>
|
||||
<button type="primary" :disabled="!isOpen || isStarted" :loading="isStarted" @click="startBeaconDiscovery">开始搜索附近的iBeacon设备</button>
|
||||
<button type="primary" :disabled="!isStarted" @click="stopBeaconDiscovery">停止搜索附近的iBeacon设备</button>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view class="uni-scroll_box">
|
||||
<view class="uni-title" v-if="isStarted || deviceList.length > 0">已经发现 {{ deviceList.length }} 台设备:</view>
|
||||
<view class="uni-list-box" v-for="(item, index) in deviceList" :key="item.uuid">
|
||||
<view>
|
||||
<view class="uni-list_name">UUID: {{ item.uuid }}</view>
|
||||
<view class="uni-list_item">major: {{ item.major }}</view>
|
||||
<view class="uni-list_item">minor: {{ item.minor }}</view>
|
||||
<view class="uni-list_item">rssi: {{ item.rssi }} dBm</view>
|
||||
<view class="uni-list_item">accuracy: {{ item.accuracy }}</view>
|
||||
<view class="uni-list_item">heading: {{ item.heading }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
const DEVICE_UUID_WEICHAT = 'FDA50693-A4E2-4FB1-AFCF-C6EB07647825';
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'iBeacon',
|
||||
isOpen: false,
|
||||
isStarted: false,
|
||||
deviceList: [],
|
||||
isPageOpened: false
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.onBeaconUpdate();
|
||||
},
|
||||
onShow() {
|
||||
this.isPageOpened = true;
|
||||
},
|
||||
methods: {
|
||||
maskclose() {
|
||||
this.maskShow = false;
|
||||
},
|
||||
openBluetoothAdapter() {
|
||||
uni.openBluetoothAdapter({
|
||||
success: (res) => {
|
||||
console.log('初始化蓝牙成功:' + res.errMsg);
|
||||
console.log(res);
|
||||
this.isOpen = true;
|
||||
this.deviceList = [];
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('初始化蓝牙失败,错误码:' + (err.errCode || err.errMsg));
|
||||
if (err.errCode !== 0) {
|
||||
initTypes(err.errCode, err.errMsg);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
closeBluetoothAdapter(OBJECT) {
|
||||
this.stopBeaconDiscovery();
|
||||
wx.closeBluetoothAdapter({
|
||||
success: (res) => {
|
||||
this.isOpen = false;
|
||||
console.log('断开蓝牙模块成功');
|
||||
}
|
||||
});
|
||||
},
|
||||
onBeaconUpdate() {
|
||||
uni.onBeaconUpdate(res => {
|
||||
if (!this.isPageOpened || !this.isOpen || !this.isStarted) {
|
||||
return;
|
||||
}
|
||||
console.log(res);
|
||||
// if (res.code !== 0) {
|
||||
// return;
|
||||
// }
|
||||
if (res.beacons && res.beacons.length > 0) {
|
||||
this.getBeacons();
|
||||
} else if (!res.connected) {
|
||||
this.deviceList = [];
|
||||
}
|
||||
});
|
||||
},
|
||||
startBeaconDiscovery() {
|
||||
uni.startBeaconDiscovery({
|
||||
uuids: this.getUUIDList(),
|
||||
success: (res) => {
|
||||
this.isStarted = true;
|
||||
console.log(res);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error(err);
|
||||
}
|
||||
});
|
||||
},
|
||||
stopBeaconDiscovery(types) {
|
||||
if(this.isStarted) {
|
||||
uni.stopBeaconDiscovery({
|
||||
success: (res) => {
|
||||
this.isStarted = false;
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
getBeacons() {
|
||||
uni.getBeacons({
|
||||
success: (res) => {
|
||||
if (res.beacons && res.beacons.length > 0) {
|
||||
console.log(res.beacons);
|
||||
this.deviceList = res.beacons;
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('获取设备服务失败,错误码:' + err.errCode);
|
||||
if (errCode.errCode !== 0) {
|
||||
initTypes(errCode.errCode);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
getUUIDList() {
|
||||
// #ifdef APP-PLUS
|
||||
const sysInfo = uni.getSystemInfoSync();
|
||||
if (!sysInfo) {
|
||||
return [];
|
||||
}
|
||||
let isIOS = sysInfo.platform ? (sysInfo.platform.toLowerCase() === "ios") : false;
|
||||
if (isIOS) {
|
||||
return [DEVICE_UUID_WEICHAT];
|
||||
}
|
||||
return [];
|
||||
// #endif
|
||||
|
||||
// #ifndef APP-PLUS
|
||||
return [DEVICE_UUID_WEICHAT];
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
this.isPageOpened = false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 判断初始化蓝牙状态
|
||||
*/
|
||||
function initTypes(code, errMsg) {
|
||||
switch (code) {
|
||||
case 10000:
|
||||
toast('未初始化蓝牙适配器');
|
||||
break;
|
||||
case 10001:
|
||||
toast('未检测到蓝牙,请打开蓝牙重试!');
|
||||
break;
|
||||
case 10002:
|
||||
toast('没有找到指定设备');
|
||||
break;
|
||||
case 10003:
|
||||
toast('连接失败');
|
||||
break;
|
||||
case 10004:
|
||||
toast('没有找到指定服务');
|
||||
break;
|
||||
case 10005:
|
||||
toast('没有找到指定特征值');
|
||||
break;
|
||||
case 10006:
|
||||
toast('当前连接已断开');
|
||||
break;
|
||||
case 10007:
|
||||
toast('当前特征值不支持此操作');
|
||||
break;
|
||||
case 10008:
|
||||
toast('其余所有系统上报的异常');
|
||||
break;
|
||||
case 10009:
|
||||
toast('Android 系统特有,系统版本低于 4.3 不支持 BLE');
|
||||
break;
|
||||
default:
|
||||
toast(errMsg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹出框封装
|
||||
*/
|
||||
function toast(content, showCancel = false) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content,
|
||||
showCancel
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-title {
|
||||
/* width: 100%; */
|
||||
/* height: 80rpx; */
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.uni-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
padding: 0 30rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.uni-scroll_box {
|
||||
height: 70%;
|
||||
background: #fff;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
.uni-list-box {
|
||||
margin: 0 20rpx;
|
||||
padding: 15rpx 0;
|
||||
border-bottom: 1px #f5f5f5 solid;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.uni-list:last-child {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.uni-list_name {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.uni-list_item {
|
||||
font-size: 24rpx;
|
||||
color: #555;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.uni-success_box {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
min-height: 100rpx;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
box-sizing: border-box;
|
||||
border-top: 1px #eee solid;
|
||||
}
|
||||
|
||||
.uni-success_sub {
|
||||
/* width: 100%%; */
|
||||
height: 100rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
.uni-close_button {
|
||||
padding: 0 20rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
background: #ce3c39;
|
||||
color: #ffffff;
|
||||
border-radius: 10rpx;
|
||||
}
|
||||
|
||||
.uni-success_content {
|
||||
height: 600rpx;
|
||||
margin: 30rpx;
|
||||
margin-top: 0;
|
||||
border: 1px #eee solid;
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
.uni-content_list {
|
||||
padding-bottom: 10rpx;
|
||||
border-bottom: 1px #f5f5f5 solid;
|
||||
}
|
||||
|
||||
.uni-tips {
|
||||
text-align: center;
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-common-mt">
|
||||
<form>
|
||||
<view class="uni-list">
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">图片来源</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-right">
|
||||
<picker :range="sourceType" @change="sourceTypeChange" :value="sourceTypeIndex" mode="selector">
|
||||
<view class="uni-input">{{sourceType[sourceTypeIndex]}}</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">图片质量</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-right">
|
||||
<picker :range="sizeType" @change="sizeTypeChange" :value="sizeTypeIndex" mode="selector">
|
||||
<view class="uni-input">{{sizeType[sizeTypeIndex]}}</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">数量限制</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-right">
|
||||
<picker :range="count" @change="countChange" mode="selector">
|
||||
<view class="uni-input">{{count[countIndex]}}</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<view class="uni-list list-pd">
|
||||
<view class="uni-list-cell cell-pd">
|
||||
<view class="uni-uploader">
|
||||
<view class="uni-uploader-head">
|
||||
<view class="uni-uploader-title">点击可预览选好的图片</view>
|
||||
<view class="uni-uploader-info">{{imageList.length}}/9</view>
|
||||
</view>
|
||||
<view class="uni-uploader-body">
|
||||
<view class="uni-uploader__files">
|
||||
<block v-for="(image,index) in imageList" :key="index">
|
||||
<view class="uni-uploader__file">
|
||||
<image class="uni-uploader__img" :src="image" :data-src="image" @tap="previewImage"></image>
|
||||
</view>
|
||||
</block>
|
||||
<view class="uni-uploader__input-box">
|
||||
<view class="uni-uploader__input" @tap="chooseImage"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</form>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import permision from "@/common/permission.js"
|
||||
var sourceType = [
|
||||
['camera'],
|
||||
['album'],
|
||||
['camera', 'album']
|
||||
]
|
||||
var sizeType = [
|
||||
['compressed'],
|
||||
['original'],
|
||||
['compressed', 'original']
|
||||
]
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'choose/previewImage',
|
||||
imageList: [],
|
||||
sourceTypeIndex: 2,
|
||||
sourceType: ['拍照', '相册', '拍照或相册'],
|
||||
sizeTypeIndex: 2,
|
||||
sizeType: ['压缩', '原图', '压缩或原图'],
|
||||
countIndex: 8,
|
||||
count: [1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
this.imageList = [],
|
||||
this.sourceTypeIndex = 2,
|
||||
this.sourceType = ['拍照', '相册', '拍照或相册'],
|
||||
this.sizeTypeIndex = 2,
|
||||
this.sizeType = ['压缩', '原图', '压缩或原图'],
|
||||
this.countIndex = 8;
|
||||
},
|
||||
methods: {
|
||||
sourceTypeChange: function(e) {
|
||||
this.sourceTypeIndex = parseInt(e.detail.value)
|
||||
},
|
||||
sizeTypeChange: function(e) {
|
||||
this.sizeTypeIndex = parseInt(e.detail.value)
|
||||
},
|
||||
countChange: function(e) {
|
||||
this.countIndex = e.detail.value;
|
||||
},
|
||||
chooseImage: async function() {
|
||||
// #ifdef APP-PLUS
|
||||
// TODO 选择相机或相册时 需要弹出actionsheet,目前无法获得是相机还是相册,在失败回调中处理
|
||||
if (this.sourceTypeIndex !== 2) {
|
||||
let status = await this.checkPermission();
|
||||
if (status !== 1) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// #endif
|
||||
|
||||
if (this.imageList.length === 9) {
|
||||
let isContinue = await this.isFullImg();
|
||||
console.log("是否继续?", isContinue);
|
||||
if (!isContinue) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
uni.chooseImage({
|
||||
sourceType: sourceType[this.sourceTypeIndex],
|
||||
sizeType: sizeType[this.sizeTypeIndex],
|
||||
count: this.imageList.length + this.count[this.countIndex] > 9 ? 9 - this.imageList.length : this.count[this.countIndex],
|
||||
success: (res) => {
|
||||
this.imageList = this.imageList.concat(res.tempFilePaths);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log("err: ",err);
|
||||
// #ifdef APP-PLUS
|
||||
if (err['code'] && err.code !== 0 && this.sourceTypeIndex === 2) {
|
||||
this.checkPermission(err.code);
|
||||
}
|
||||
// #endif
|
||||
// #ifdef MP
|
||||
if(err.errMsg.indexOf('cancel') !== '-1'){
|
||||
return;
|
||||
}
|
||||
uni.getSetting({
|
||||
success: (res) => {
|
||||
let authStatus = false;
|
||||
switch (this.sourceTypeIndex) {
|
||||
case 0:
|
||||
authStatus = res.authSetting['scope.camera'];
|
||||
break;
|
||||
case 1:
|
||||
authStatus = res.authSetting['scope.album'];
|
||||
break;
|
||||
case 2:
|
||||
authStatus = res.authSetting['scope.album'] && res.authSetting['scope.camera'];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!authStatus) {
|
||||
uni.showModal({
|
||||
title: '授权失败',
|
||||
content: 'Hello uni-app需要从您的相机或相册获取图片,请在设置界面打开相关权限',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.openSetting()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
})
|
||||
},
|
||||
isFullImg: function() {
|
||||
return new Promise((res) => {
|
||||
uni.showModal({
|
||||
content: "已经有9张图片了,是否清空现有图片?",
|
||||
success: (e) => {
|
||||
if (e.confirm) {
|
||||
this.imageList = [];
|
||||
res(true);
|
||||
} else {
|
||||
res(false)
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
res(false)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
previewImage: function(e) {
|
||||
var current = e.target.dataset.src
|
||||
uni.previewImage({
|
||||
current: current,
|
||||
urls: this.imageList
|
||||
})
|
||||
},
|
||||
async checkPermission(code) {
|
||||
let type = code ? code - 1 : this.sourceTypeIndex;
|
||||
let status = permision.isIOS ? await permision.requestIOS(sourceType[type][0]) :
|
||||
await permision.requestAndroid(type === 0 ? 'android.permission.CAMERA' :
|
||||
'android.permission.READ_EXTERNAL_STORAGE');
|
||||
|
||||
if (status === null || status === 1) {
|
||||
status = 1;
|
||||
} else {
|
||||
uni.showModal({
|
||||
content: "没有开启权限",
|
||||
confirmText: "设置",
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
permision.gotoAppSetting();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.cell-pd {
|
||||
padding: 22rpx 30rpx;
|
||||
}
|
||||
|
||||
.list-pd {
|
||||
margin-top: 50rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
<template>
|
||||
<view class="uni-padding-wrap">
|
||||
<page-head title="audio"></page-head>
|
||||
<view class="uni-common-mt">
|
||||
<slider :value="position" :min="0" :max="duration" @changing="onchanging" @change="onchange"></slider>
|
||||
</view>
|
||||
<!-- <view class="uni-common-mt play-time-area">
|
||||
<text class="current-time">{{currentTime}}</text>
|
||||
<text class="duration">{{duration}}</text>
|
||||
</view> -->
|
||||
<view class="play-button-area">
|
||||
<image class="icon-play" :src="playImage" @click="play"></image>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
const audioUrl = 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-hello-uniapp/2cc220e0-c27a-11ea-9dfb-6da8e309e0d8.mp3'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: "innerAudioContext",
|
||||
isPlaying: false,
|
||||
isPlayEnd: false,
|
||||
currentTime: 0,
|
||||
duration: 100
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
position() {
|
||||
return this.isPlayEnd ? 0 : this.currentTime;
|
||||
},
|
||||
playImage() {
|
||||
return this.isPlaying ? "/static/pause.png" : "/static/play.png"
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this._isChanging = false;
|
||||
this._audioContext = null;
|
||||
this.createAudio();
|
||||
},
|
||||
onUnload() {
|
||||
if (this._audioContext != null && this.isPlaying) {
|
||||
this.stop();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
createAudio() {
|
||||
var innerAudioContext = this._audioContext = uni.createInnerAudioContext();
|
||||
innerAudioContext.autoplay = false;
|
||||
innerAudioContext.src = audioUrl;
|
||||
innerAudioContext.onPlay(() => {
|
||||
console.log('开始播放');
|
||||
});
|
||||
innerAudioContext.onTimeUpdate((e) => {
|
||||
if (this._isChanging === true) {
|
||||
return;
|
||||
}
|
||||
this.currentTime = innerAudioContext.currentTime || 0;
|
||||
this.duration = innerAudioContext.duration || 0;
|
||||
});
|
||||
innerAudioContext.onEnded(() => {
|
||||
this.currentTime = 0;
|
||||
this.isPlaying = false;
|
||||
this.isPlayEnd = true;
|
||||
});
|
||||
innerAudioContext.onError((res) => {
|
||||
this.isPlaying = false;
|
||||
console.log(res.errMsg);
|
||||
console.log(res.errCode);
|
||||
});
|
||||
return innerAudioContext;
|
||||
},
|
||||
onchanging() {
|
||||
this._isChanging = true;
|
||||
},
|
||||
onchange(e) {
|
||||
console.log(e.detail.value);
|
||||
console.log(typeof e.detail.value);
|
||||
this._audioContext.seek(e.detail.value);
|
||||
this._isChanging = false;
|
||||
},
|
||||
play() {
|
||||
if (this.isPlaying) {
|
||||
this.pause();
|
||||
return;
|
||||
}
|
||||
this.isPlaying = true;
|
||||
this._audioContext.play();
|
||||
this.isPlayEnd = false;
|
||||
},
|
||||
pause() {
|
||||
this._audioContext.pause();
|
||||
this.isPlaying = false;
|
||||
},
|
||||
stop() {
|
||||
this._audioContext.stop();
|
||||
this.isPlaying = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.play-time-area {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.duration {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.play-button-area {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
margin-top: 50px;
|
||||
}
|
||||
|
||||
.icon-play {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="uni-title uni-common-mt">
|
||||
{{appear ? '小球出现' : '小球消失'}}
|
||||
</view>
|
||||
<scroll-view class="scroll-view" scroll-y>
|
||||
<view class="scroll-area">
|
||||
<text class="notice">向下滚动让小球出现</text>
|
||||
<view class="ball"></view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
let observer = null;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
appear: false,
|
||||
title:'intersectionObserver'
|
||||
}
|
||||
},
|
||||
onReady() {
|
||||
observer = uni.createIntersectionObserver(this);
|
||||
observer.relativeTo('.scroll-view').observe('.ball', (res) => {
|
||||
if (res.intersectionRatio > 0 && !this.appear) {
|
||||
this.appear = true;
|
||||
} else if (!res.intersectionRatio > 0 && this.appear) {
|
||||
this.appear = false;
|
||||
}
|
||||
})
|
||||
},
|
||||
onUnload() {
|
||||
if (observer) {
|
||||
observer.disconnect()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.scroll-view {
|
||||
height: 400rpx;
|
||||
background: #fff;
|
||||
border: 1px solid #ccc;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.scroll-area {
|
||||
height: 1300rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.notice {
|
||||
margin-top: 150rpx;
|
||||
margin: 150rpx 0 400rpx 0;
|
||||
}
|
||||
|
||||
.ball {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
background: #4cd964;
|
||||
border-radius: 50%;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,322 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view style="background:#FFF; padding:40rpx;">
|
||||
<block v-if="hasLogin === true">
|
||||
<view class="uni-h3 uni-center uni-common-mt">已登录
|
||||
<text v-if="isUniverifyLogin" style="font-size: 0.8em;">
|
||||
<i v-if="!phoneNumber.length" class="uni-icon_toast uni-loading"></i>
|
||||
<i v-else>({{phoneNumber}})</i>
|
||||
</text>
|
||||
</view>
|
||||
<view class="uni-hello-text uni-center">
|
||||
<text>每个账号仅需登录 1 次,\n后续每次进入页面即可自动拉取用户信息。</text>
|
||||
</view>
|
||||
</block>
|
||||
<block v-if="hasLogin === false">
|
||||
<view class="uni-h3 uni-center uni-common-mt">未登录</view>
|
||||
<view class="uni-hello-text uni-center">
|
||||
请点击按钮登录
|
||||
</view>
|
||||
</block>
|
||||
</view>
|
||||
<view class="uni-btn-v uni- uni-common-mt">
|
||||
<!-- #ifdef MP-TOUTIAO -->
|
||||
<button type="primary" class="page-body-button" v-for="(value,key) in providerList" @click="tologin(value)" :key="key">
|
||||
登录
|
||||
</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-TOUTIAO -->
|
||||
<button type="primary" class="page-body-button" v-for="(value,key) in providerList" @click="tologin(value)"
|
||||
:loading="value.id === 'univerify' ? univerifyBtnLoading : false" :key="key">{{value.name}}</button>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
mapState,
|
||||
mapMutations,
|
||||
mapActions
|
||||
} from 'vuex'
|
||||
const univerifyInfoKey = 'univerifyInfo';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'login',
|
||||
providerList: [],
|
||||
phoneNumber: '',
|
||||
univerifyBtnLoading: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['hasLogin', 'isUniverifyLogin', 'univerifyErrorMsg'])
|
||||
},
|
||||
onLoad() {
|
||||
uni.getProvider({
|
||||
service: 'oauth',
|
||||
success: (result) => {
|
||||
this.providerList = result.provider.map((value) => {
|
||||
let providerName = '';
|
||||
switch (value) {
|
||||
case 'weixin':
|
||||
providerName = '微信登录'
|
||||
break;
|
||||
case 'qq':
|
||||
providerName = 'QQ登录'
|
||||
break;
|
||||
case 'sinaweibo':
|
||||
providerName = '新浪微博登录'
|
||||
break;
|
||||
case 'xiaomi':
|
||||
providerName = '小米登录'
|
||||
break;
|
||||
case 'alipay':
|
||||
providerName = '支付宝登录'
|
||||
break;
|
||||
case 'baidu':
|
||||
providerName = '百度登录'
|
||||
break;
|
||||
case 'jd':
|
||||
providerName = '京东登录'
|
||||
break;
|
||||
case 'toutiao':
|
||||
providerName = '头条登录'
|
||||
break;
|
||||
case 'apple':
|
||||
providerName = '苹果登录'
|
||||
break;
|
||||
case 'univerify':
|
||||
providerName = '一键登录'
|
||||
break;
|
||||
}
|
||||
return {
|
||||
name: providerName,
|
||||
id: value
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
fail: (error) => {
|
||||
console.log('获取登录通道失败', error);
|
||||
}
|
||||
});
|
||||
|
||||
if (this.hasLogin && this.isUniverifyLogin) {
|
||||
this.getPhoneNumber(uni.getStorageSync(univerifyInfoKey)).then((phoneNumber) => {
|
||||
this.phoneNumber = phoneNumber
|
||||
})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['login', 'setUniverifyLogin']),
|
||||
...mapActions(['getPhoneNumber']),
|
||||
Toast(data, duration = 1000) {
|
||||
uni.showToast(Object.assign({}, data, {
|
||||
duration
|
||||
}))
|
||||
},
|
||||
tologin(provider) {
|
||||
if (provider.id === 'univerify') {
|
||||
this.univerifyBtnLoading = true;
|
||||
}
|
||||
|
||||
// 一键登录已在APP onLaunch的时候进行了预登陆,可以显著提高登录速度。登录成功后,预登陆状态会重置
|
||||
uni.login({
|
||||
provider: provider.id,
|
||||
// #ifdef MP-ALIPAY
|
||||
scopes: 'auth_user', //支付宝小程序需设置授权类型
|
||||
// #endif
|
||||
success: async (res) => {
|
||||
console.log('login success:', res);
|
||||
this.Toast({
|
||||
title: '登录成功'
|
||||
})
|
||||
// 更新保存在 store 中的登录状态
|
||||
this.login(provider.id);
|
||||
|
||||
// #ifdef APP-PLUS
|
||||
this.setUniverifyLogin(provider.id === 'univerify')
|
||||
switch (provider.id) {
|
||||
case 'univerify':
|
||||
this.loginByUniverify(provider.id, res)
|
||||
break;
|
||||
case 'apple':
|
||||
this.loginByApple(provider.id, res)
|
||||
break;
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
console.warn('如需获取openid请参考uni-id: https://uniapp.dcloud.net.cn/uniCloud/uni-id')
|
||||
uni.request({
|
||||
url: 'https://97fca9f2-41f6-449f-a35e-3f135d4c3875.bspapp.com/http/user-center',
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: 'loginByWeixin',
|
||||
params: {
|
||||
code: res.code,
|
||||
platform: 'mp-weixin'
|
||||
}
|
||||
},
|
||||
success(res) {
|
||||
console.log(res);
|
||||
if (res.data.code !== 0) {
|
||||
console.log('获取openid失败:', res.data.errMsg);
|
||||
return
|
||||
}
|
||||
uni.setStorageSync('openid', res.data.openid)
|
||||
},
|
||||
fail(err) {
|
||||
console.log('获取openid失败:', err);
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('login fail:', err);
|
||||
|
||||
// 一键登录点击其他登录方式
|
||||
if (err.code == '30002') {
|
||||
uni.closeAuthView();
|
||||
this.Toast({
|
||||
title: '其他登录方式'
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
// 未开通
|
||||
if (err.code == 1000) {
|
||||
uni.showModal({
|
||||
title: '登录失败',
|
||||
content: `${err.errMsg}\n,错误码:${err.code}`,
|
||||
confirmText: '开通指南',
|
||||
cancelText: '确定',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
setTimeout(() => {
|
||||
plus.runtime.openWeb('https://ask.dcloud.net.cn/article/37965')
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 一键登录预登陆失败
|
||||
if (err.code == '30005') {
|
||||
uni.showModal({
|
||||
showCancel: false,
|
||||
title: '预登录失败',
|
||||
content: this.univerifyErrorMsg || err.errMsg
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 一键登录用户关闭验证界面
|
||||
if (err.code != '30003') {
|
||||
uni.showModal({
|
||||
showCancel: false,
|
||||
title: '登录失败',
|
||||
content: JSON.stringify(err)
|
||||
});
|
||||
}
|
||||
},
|
||||
complete: () => {
|
||||
this.univerifyBtnLoading = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
loginByUniverify(provider, res) {
|
||||
this.setUniverifyLogin(true);
|
||||
uni.closeAuthView();
|
||||
|
||||
const univerifyInfo = {
|
||||
provider,
|
||||
...res.authResult,
|
||||
}
|
||||
|
||||
this.getPhoneNumber(univerifyInfo).then((phoneNumber) => {
|
||||
this.phoneNumber = phoneNumber;
|
||||
uni.setStorageSync(univerifyInfoKey, univerifyInfo)
|
||||
}).catch(err => {
|
||||
uni.showModal({
|
||||
showCancel: false,
|
||||
title: '手机号获取失败',
|
||||
content: `${err.errMsg}\n,错误码:${err.code}`
|
||||
})
|
||||
console.error(res);
|
||||
})
|
||||
},
|
||||
async loginByApple(provider, res) {
|
||||
// 获取用户信息
|
||||
let getUserInfoErr, result
|
||||
// #ifndef VUE3
|
||||
[getUserInfoErr, result] = await uni.getUserInfo({
|
||||
provider
|
||||
});
|
||||
// #endif
|
||||
|
||||
// #ifdef VUE3
|
||||
try {
|
||||
result = await uni.getUserInfo({
|
||||
provider
|
||||
});
|
||||
} catch(e) {
|
||||
getUserInfoErr = e
|
||||
}
|
||||
// #endif
|
||||
|
||||
if (getUserInfoErr) {
|
||||
let content = getUserInfoErr.errMsg;
|
||||
if (~content.indexOf('uni.login')) {
|
||||
content = '请在登录页面完成登录操作';
|
||||
}
|
||||
uni.showModal({
|
||||
title: '获取用户信息失败',
|
||||
content: '错误原因' + content,
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
// uni-id 苹果登录
|
||||
console.warn('此处使用uni-id处理苹果登录,详情参考: https://uniapp.dcloud.net.cn/uniCloud/uni-id')
|
||||
uni.request({
|
||||
url: 'https://97fca9f2-41f6-449f-a35e-3f135d4c3875.bspapp.com/http/user-center',
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: 'loginByApple',
|
||||
params: result.userInfo
|
||||
},
|
||||
success: (res) => {
|
||||
console.log('uniId login success', res);
|
||||
if(res.data.code !== 0){
|
||||
uni.showModal({
|
||||
showCancel: false,
|
||||
content: `苹果登录失败: ${JSON.stringify(res.data.msg)}`,
|
||||
})
|
||||
} else {
|
||||
uni.setStorageSync('openid', res.data.openid)
|
||||
uni.setStorageSync('apple_nickname', res.data.userInfo.nickname)
|
||||
}
|
||||
},
|
||||
fail: (e) => {
|
||||
uni.showModal({
|
||||
content: `苹果登录失败: ${JSON.stringify(e)}`,
|
||||
showCancel: false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
button {
|
||||
background-color: #007aff;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="uni-hello-text uni-center">请在下方输入电话号码</view>
|
||||
<input class="input uni-common-mt" type="number" name="input" @input="bindInput" />
|
||||
<view class="uni-btn-v uni-common-mt">
|
||||
<button @tap="makePhoneCall" type="primary" :disabled="disabled">拨打</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'makePhoneCall',
|
||||
disabled: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
bindInput: function (e) {
|
||||
this.inputValue = e.detail.value
|
||||
if (this.inputValue.length > 0) {
|
||||
this.disabled = false
|
||||
} else {
|
||||
this.disabled = true
|
||||
}
|
||||
},
|
||||
makePhoneCall: function () {
|
||||
uni.makePhoneCall({
|
||||
phoneNumber: this.inputValue,
|
||||
success: () => {
|
||||
console.log("成功拨打电话")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.input {
|
||||
height: 119rpx;
|
||||
line-height: 119rpx;
|
||||
font-size: 78rpx;
|
||||
border-bottom: 1rpx solid #E2E2E2;
|
||||
text-align:center;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
<template>
|
||||
<view class="content">
|
||||
<map class="map" ref="dcmap" :markers="markers" @tap="selectPoint"></map>
|
||||
<scroll-view class="scrollview" scroll-y="true">
|
||||
<button class="button" @click="reverseGeocode">reverseGeocode</button>
|
||||
<button class="button" @click="poiSearchNearBy">poiSearchNearBy</button>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 116.397477,39.908692
|
||||
let mapSearch = weex.requireModule('mapSearch')
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
markers: [{
|
||||
id: '1',
|
||||
latitude: 39.9086920000,
|
||||
longitude: 116.3974770000,
|
||||
title: '天安门',
|
||||
zIndex: '1',
|
||||
iconPath: '/static/gps.png',
|
||||
width: 20,
|
||||
height: 20,
|
||||
anchor: {
|
||||
x: 0.5,
|
||||
y: 1
|
||||
},
|
||||
callout: {
|
||||
content: '首都北京\n天安门',
|
||||
color: '#00BFFF',
|
||||
fontSize: 12,
|
||||
borderRadius: 2,
|
||||
borderWidth: 0,
|
||||
borderColor: '#333300',
|
||||
bgColor: '#CCFF11',
|
||||
padding: '1',
|
||||
display: 'ALWAYS'
|
||||
}
|
||||
}]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
selectPoint(e) {
|
||||
console.log(e);
|
||||
},
|
||||
reverseGeocode() {
|
||||
var point = this.markers[0]
|
||||
mapSearch.reverseGeocode({
|
||||
point: {
|
||||
latitude: point.latitude,
|
||||
longitude: point.longitude
|
||||
}
|
||||
}, ret => {
|
||||
console.log(JSON.stringify(ret));
|
||||
uni.showModal({
|
||||
content: JSON.stringify(ret)
|
||||
})
|
||||
})
|
||||
},
|
||||
poiSearchNearBy() {
|
||||
var point = this.markers[0]
|
||||
mapSearch.poiSearchNearBy({
|
||||
point: {
|
||||
latitude: point.latitude,
|
||||
longitude: point.longitude
|
||||
},
|
||||
key: '停车场',
|
||||
radius: 1000
|
||||
}, ret => {
|
||||
console.log(ret);
|
||||
uni.showModal({
|
||||
content: JSON.stringify(ret)
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.map {
|
||||
width: 750rpx;
|
||||
height: 500rpx;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
.scrollview {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-top: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,447 @@
|
|||
<template>
|
||||
<view class="content">
|
||||
<map class="map" id="map1" ref="map1" :controls="controls" :scale="scale" :longitude="location.longitude"
|
||||
:latitude="location.latitude" :show-location="showLocation" :enable-3D="enable3D" :rotate="rotate" :skew="skew"
|
||||
:show-compass="showCompass" :enable-overlooking="enableOverlooking" :enable-zoom="enableZoom"
|
||||
:enable-scroll="enableScroll" :enable-rotate="enableRotate" :enable-satellite="enableSatellite"
|
||||
:enable-traffic="enableTraffic" :markers="markers" :polyline="polyline" :circles="circles" :polygons="polygons"
|
||||
:include-points="includePoints" @tap="maptap" @controltap="oncontroltap" @markertap="onmarkertap"
|
||||
@callouttap="oncallouttap" @poitap="onpoitap" @updated="onupdated" @regionchange="onregionchange"></map>
|
||||
<scroll-view class="scrollview" scroll-y="true">
|
||||
<!-- <view class="list-item">
|
||||
<text class="list-text">显示3D楼块</text>
|
||||
<switch :checked="enable3D" @change="enableThreeD" />
|
||||
</view>
|
||||
<view class="list-item">
|
||||
<text class="list-text">显示指南针</text>
|
||||
<switch :checked="showCompass" @change="changeShowCompass" />
|
||||
</view>
|
||||
<view class="list-item">
|
||||
<text class="list-text">开启俯视</text>
|
||||
<switch :checked="enableOverlooking" @change="changeEnableOverlooking" />
|
||||
</view>
|
||||
<view class="list-item">
|
||||
<text class="list-text">是否支持缩放</text>
|
||||
<switch :checked="enableZoom" @change="changeEnableZoom" />
|
||||
</view>
|
||||
<view class="list-item">
|
||||
<text class="list-text">是否支持拖动</text>
|
||||
<switch :checked="enableScroll" @change="changeEnableScroll" />
|
||||
</view>
|
||||
<view class="list-item">
|
||||
<text class="list-text">是否支持旋转</text>
|
||||
<switch :checked="enableRotate" @change="changeEnableRotate" />
|
||||
</view>
|
||||
<view class="list-item">
|
||||
<text class="list-text">是否开启卫星图</text>
|
||||
<switch :checked="enableSatellite" @change="changeEnableSatellite" />
|
||||
</view>
|
||||
<view class="list-item">
|
||||
<text class="list-text">是否开启实时路况</text>
|
||||
<switch :checked="enableTraffic" @change="changeEnableTraffic" />
|
||||
</view> -->
|
||||
<!-- #ifndef MP-JD -->
|
||||
<button class="button" @click="changeScale">changeScale</button>
|
||||
<button class="button" @click="changeRotate">changeRotate</button>
|
||||
<button class="button" @click="changeSkew">skew</button>
|
||||
<!-- #endif -->
|
||||
<button class="button" @click="addMarkers">addMarkers</button>
|
||||
<button class="button" @click="addPolyline">addPolyline</button>
|
||||
<!-- #ifndef MP-JD -->
|
||||
<button class="button" @click="addPolygons">addPolygons</button>
|
||||
<!-- #endif -->
|
||||
<button class="button" @click="addCircles">addCircles</button>
|
||||
<button class="button" @click="includePoint">includePoints</button>
|
||||
<button class="button" @click="handleGetCenterLocation">getCenterLocation</button>
|
||||
<button class="button" @click="handleGetRegion">getRegion</button>
|
||||
<!-- #ifndef MP-JD -->
|
||||
<button class="button" @click="handleTranslateMarker">translateMarker</button>
|
||||
<!-- #endif -->
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const testMarkers = [{
|
||||
id: 0,
|
||||
latitude: 39.989631,
|
||||
longitude: 116.481018,
|
||||
title: '方恒国际 阜通东大街6号',
|
||||
zIndex: '1',
|
||||
rotate: 0,
|
||||
width: 20,
|
||||
height: 20,
|
||||
anchor: {
|
||||
x: 0.5,
|
||||
y: 1
|
||||
},
|
||||
callout: {
|
||||
content: '方恒国际 阜通东大街6号',
|
||||
color: '#00BFFF',
|
||||
fontSize: 10,
|
||||
borderRadius: 4,
|
||||
borderWidth: 1,
|
||||
borderColor: '#333300',
|
||||
bgColor: '#CCFF99',
|
||||
padding: '5',
|
||||
display: 'ALWAYS'
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 1,
|
||||
latitude: 39.9086920000,
|
||||
longitude: 116.3974770000,
|
||||
title: '天安门',
|
||||
zIndex: '1',
|
||||
iconPath: '/static/location.png',
|
||||
width: 40,
|
||||
height: 40,
|
||||
anchor: {
|
||||
x: 0.5,
|
||||
y: 1
|
||||
},
|
||||
callout: {
|
||||
content: '首都北京\n天安门',
|
||||
color: '#00BFFF',
|
||||
fontSize: 12,
|
||||
borderRadius: 2,
|
||||
borderWidth: 0,
|
||||
borderColor: '#333300',
|
||||
bgColor: '#CCFF11',
|
||||
padding: '1',
|
||||
display: 'ALWAYS'
|
||||
}
|
||||
}
|
||||
];
|
||||
const testPolyline = [{
|
||||
points: [{
|
||||
latitude: 39.925539,
|
||||
longitude: 116.279037
|
||||
},
|
||||
{
|
||||
latitude: 39.925539,
|
||||
longitude: 116.520285
|
||||
}
|
||||
],
|
||||
color: '#FFCCFF',
|
||||
width: 7,
|
||||
dottedLine: true,
|
||||
arrowLine: true,
|
||||
borderColor: '#000000',
|
||||
borderWidth: 2
|
||||
},
|
||||
{
|
||||
points: [{
|
||||
latitude: 39.938698,
|
||||
longitude: 116.275177
|
||||
},
|
||||
{
|
||||
latitude: 39.966069,
|
||||
longitude: 116.289253
|
||||
},
|
||||
{
|
||||
latitude: 39.944226,
|
||||
longitude: 116.306076
|
||||
},
|
||||
{
|
||||
latitude: 39.966069,
|
||||
longitude: 116.322899
|
||||
},
|
||||
{
|
||||
latitude: 39.938698,
|
||||
longitude: 116.336975
|
||||
}
|
||||
],
|
||||
color: '#CCFFFF',
|
||||
width: 5,
|
||||
dottedLine: true,
|
||||
arrowLine: true,
|
||||
borderColor: '#CC0000',
|
||||
borderWidth: 3
|
||||
}
|
||||
];
|
||||
const testPolygons = [{
|
||||
points: [{
|
||||
latitude: 39.781892,
|
||||
longitude: 116.293413
|
||||
},
|
||||
{
|
||||
latitude: 39.787600,
|
||||
longitude: 116.391842
|
||||
},
|
||||
{
|
||||
latitude: 39.733187,
|
||||
longitude: 116.417932
|
||||
},
|
||||
{
|
||||
latitude: 39.704653,
|
||||
longitude: 116.338255
|
||||
}
|
||||
],
|
||||
fillColor: '#FFCCFF',
|
||||
strokeWidth: 3,
|
||||
strokeColor: '#CC99CC',
|
||||
zIndex: 11
|
||||
},
|
||||
{
|
||||
points: [{
|
||||
latitude: 39.887600,
|
||||
longitude: 116.518932
|
||||
},
|
||||
{
|
||||
latitude: 39.781892,
|
||||
longitude: 116.518932
|
||||
},
|
||||
{
|
||||
latitude: 39.781892,
|
||||
longitude: 116.428932
|
||||
},
|
||||
{
|
||||
latitude: 39.887600,
|
||||
longitude: 116.428932
|
||||
}
|
||||
],
|
||||
fillColor: '#CCFFFF',
|
||||
strokeWidth: 5,
|
||||
strokeColor: '#CC0000',
|
||||
zIndex: 3
|
||||
}
|
||||
];
|
||||
const testCircles = [{
|
||||
latitude: 39.996441,
|
||||
longitude: 116.411146,
|
||||
radius: 15000,
|
||||
strokeWidth: 5,
|
||||
color: '#CCFFFF',
|
||||
fillColor: '#CC0000'
|
||||
},
|
||||
{
|
||||
latitude: 40.096441,
|
||||
longitude: 116.511146,
|
||||
radius: 12000,
|
||||
strokeWidth: 3,
|
||||
color: '#CCFFFF',
|
||||
fillColor: '#FFCCFF'
|
||||
},
|
||||
{
|
||||
latitude: 39.896441,
|
||||
longitude: 116.311146,
|
||||
radius: 9000,
|
||||
strokeWidth: 1,
|
||||
color: '#CCFFFF',
|
||||
fillColor: '#CC0000'
|
||||
}
|
||||
];
|
||||
const testIncludePoints = [{
|
||||
latitude: 39.989631,
|
||||
longitude: 116.481018,
|
||||
},
|
||||
{
|
||||
latitude: 39.9086920000,
|
||||
longitude: 116.3974770000,
|
||||
}
|
||||
];
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
location: {
|
||||
longitude: 116.3974770000,
|
||||
latitude: 39.9086920000
|
||||
},
|
||||
controls: [{
|
||||
id: 1,
|
||||
position: {
|
||||
left: 5,
|
||||
top: 180,
|
||||
width: 30,
|
||||
height: 30
|
||||
},
|
||||
iconPath: '/static/logo.png',
|
||||
clickable: true
|
||||
}],
|
||||
showLocation: false,
|
||||
scale: 13,
|
||||
showCompass: true,
|
||||
enable3D: true,
|
||||
enableOverlooking: true,
|
||||
enableZoom: true,
|
||||
enableScroll: true,
|
||||
enableRotate: true,
|
||||
enableSatellite: false,
|
||||
enableTraffic: false,
|
||||
polyline: [],
|
||||
markers: [],
|
||||
polygons: [],
|
||||
circles: [],
|
||||
includePoints: [],
|
||||
rotate: 0,
|
||||
skew: 0
|
||||
}
|
||||
},
|
||||
onLoad() {},
|
||||
onReady() {
|
||||
this.map = uni.createMapContext("map1", this);
|
||||
},
|
||||
methods: {
|
||||
// #ifndef MP-JD
|
||||
changeScale() {
|
||||
this.scale = this.scale == 9 ? 15 : 9;
|
||||
},
|
||||
changeRotate() {
|
||||
this.rotate = this.rotate == 90 ? 0 : 90;
|
||||
},
|
||||
changeSkew() {
|
||||
this.skew = this.skew == 30 ? 0 : 30;
|
||||
},
|
||||
// #endif
|
||||
enableThreeD(e) {
|
||||
this.enable3D = e.detail.value;
|
||||
},
|
||||
changeShowCompass(e) {
|
||||
this.showCompass = e.detail.value;
|
||||
},
|
||||
changeEnableOverlooking(e) {
|
||||
this.enableOverlooking = e.detail.value;
|
||||
},
|
||||
changeEnableZoom(e) {
|
||||
this.enableZoom = e.detail.value;
|
||||
},
|
||||
changeEnableScroll(e) {
|
||||
this.enableScroll = e.detail.value;
|
||||
},
|
||||
changeEnableRotate(e) {
|
||||
this.enableRotate = e.detail.value;
|
||||
},
|
||||
changeEnableSatellite(e) {
|
||||
this.enableSatellite = e.detail.value;
|
||||
},
|
||||
changeEnableTraffic(e) {
|
||||
this.enableTraffic = e.detail.value;
|
||||
},
|
||||
addMarkers() {
|
||||
this.markers = testMarkers;
|
||||
},
|
||||
addPolyline() {
|
||||
this.polyline = testPolyline;
|
||||
},
|
||||
// #ifndef MP-JD
|
||||
addPolygons() {
|
||||
this.polygons = testPolygons;
|
||||
},
|
||||
// #endif
|
||||
addCircles() {
|
||||
this.circles = testCircles;
|
||||
},
|
||||
includePoint() {
|
||||
this.includePoints = testIncludePoints;
|
||||
},
|
||||
handleGetCenterLocation() {
|
||||
this.map.getCenterLocation({
|
||||
success: ret => {
|
||||
console.log(JSON.stringify(ret));
|
||||
uni.showModal({
|
||||
content: JSON.stringify(ret)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleGetRegion() {
|
||||
this.map.getRegion({
|
||||
success: ret => {
|
||||
console.log(JSON.stringify(ret));
|
||||
uni.showModal({
|
||||
content: JSON.stringify(ret)
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
// #ifndef MP-JD
|
||||
handleTranslateMarker() {
|
||||
this.map.translateMarker({
|
||||
markerId: 1,
|
||||
destination: {
|
||||
latitude: 39.989631,
|
||||
longitude: 116.481018
|
||||
},
|
||||
duration: 2000
|
||||
}, ret => {
|
||||
console.log(JSON.stringify(ret));
|
||||
uni.showModal({
|
||||
content: JSON.stringify(ret)
|
||||
})
|
||||
});
|
||||
},
|
||||
// #endif
|
||||
maptap(e) {
|
||||
uni.showModal({
|
||||
content: JSON.stringify(e)
|
||||
})
|
||||
},
|
||||
onmarkertap(e) {
|
||||
uni.showModal({
|
||||
content: JSON.stringify(e)
|
||||
})
|
||||
},
|
||||
oncontroltap(e) {
|
||||
uni.showModal({
|
||||
content: JSON.stringify(e)
|
||||
})
|
||||
},
|
||||
oncallouttap(e) {
|
||||
uni.showModal({
|
||||
content: JSON.stringify(e)
|
||||
})
|
||||
},
|
||||
onupdated(e) {
|
||||
console.log(JSON.stringify(e))
|
||||
},
|
||||
onregionchange(e) {
|
||||
console.log(JSON.stringify(e));
|
||||
},
|
||||
onpoitap(e) {
|
||||
uni.showModal({
|
||||
content: JSON.stringify(e)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.map {
|
||||
width: 750rpx;
|
||||
/* #ifdef H5 */
|
||||
width: 100%;
|
||||
/* #endif */
|
||||
height: 250px;
|
||||
background-color: #f0f0f0;
|
||||
}
|
||||
|
||||
.scrollview {
|
||||
/* #ifdef H5 */
|
||||
margin-top: 240px;
|
||||
/* #endif */
|
||||
flex: 1;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.list-item {
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
padding: 5px 0px;
|
||||
}
|
||||
|
||||
.list-text {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.button {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="uni-btn-v">
|
||||
<button type="default" @tap="modalTap">有标题的modal</button>
|
||||
<button type="default" @tap="noTitlemodalTap">无标题的modal</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'modal',
|
||||
modalHidden: true,
|
||||
modalHidden2: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
modalTap: function (e) {
|
||||
uni.showModal({
|
||||
title: "弹窗标题",
|
||||
content: "弹窗内容,告知当前状态、信息和解决方法,描述文字尽量控制在三行内",
|
||||
showCancel: false,
|
||||
confirmText: "确定"
|
||||
})
|
||||
},
|
||||
noTitlemodalTap: function (e) {
|
||||
uni.showModal({
|
||||
content: "弹窗内容,告知当前状态、信息和解决方法,描述文字尽量控制在三行内",
|
||||
confirmText: "确定",
|
||||
cancelText: "取消"
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="uni-btn-v">
|
||||
<button @tap="navigateTo">跳转新页面,并传递数据</button>
|
||||
<button @tap="navigateBack">返回上一页</button>
|
||||
<button @tap="redirectTo">在当前页面打开</button>
|
||||
<button @tap="switchTab">切换到模板选项卡</button>
|
||||
<button v-if="!hasLeftWin" @tap="reLaunch">关闭所有页面,打开首页</button>
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<button @tap="customAnimation">使用自定义动画打开页面</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-PLUS || H5 -->
|
||||
<button @tap="preloadPage">预载复杂页面</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<button @tap="unPreloadPage">取消页面预载</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-PLUS || H5 -->
|
||||
<button @tap="navigateToPreloadPage">打开复杂页面</button>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
const preloadPageUrl = '/pages/extUI/calendar/calendar'
|
||||
import { mapState } from 'vuex'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'navigate'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
hasLeftWin: state => !state.noMatchLeftWindow
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
navigateTo() {
|
||||
uni.navigateTo({
|
||||
url: 'new-page/new-vue-page-1?data=Hello'
|
||||
})
|
||||
},
|
||||
navigateBack() {
|
||||
uni.navigateBack();
|
||||
},
|
||||
redirectTo() {
|
||||
uni.redirectTo({
|
||||
url: 'new-page/new-vue-page-1'
|
||||
});
|
||||
},
|
||||
switchTab() {
|
||||
uni.switchTab({
|
||||
url: '/pages/tabBar/template/template'
|
||||
});
|
||||
},
|
||||
reLaunch() {
|
||||
if (this.hasLeftWin) {
|
||||
uni.reLaunch({
|
||||
url: '/pages/component/view/view'
|
||||
});
|
||||
return;
|
||||
}
|
||||
uni.reLaunch({
|
||||
url: '/pages/tabBar/component/component'
|
||||
});
|
||||
},
|
||||
customAnimation(){
|
||||
uni.navigateTo({
|
||||
url: 'new-page/new-vue-page-1?data=使用自定义动画打开页面',
|
||||
animationType: 'slide-in-bottom',
|
||||
animationDuration: 200
|
||||
})
|
||||
},
|
||||
preloadPage(){
|
||||
uni.preloadPage({
|
||||
url: preloadPageUrl,
|
||||
success(){
|
||||
uni.showToast({
|
||||
title:'页面预载成功'
|
||||
})
|
||||
},
|
||||
fail(){
|
||||
uni.showToast({
|
||||
title:'页面预载失败'
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
unPreloadPage(){
|
||||
uni.unPreloadPage({
|
||||
url: preloadPageUrl
|
||||
})
|
||||
},
|
||||
navigateToPreloadPage(){
|
||||
uni.navigateTo({
|
||||
url: preloadPageUrl
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
<template>
|
||||
<view class="root">
|
||||
<view class="page-body">
|
||||
<view class="new-page__color" @click="setColorIndex(colorIndex>1?0:colorIndex+1)" :style="{backgroundColor:currentColor}">
|
||||
<text class="new-page__color-text">点击改变颜色</text>
|
||||
</view>
|
||||
<view class="new-page__text-box">
|
||||
<text class="new-page__text">点击上方色块使用vuex在页面之间进行通讯</text>
|
||||
</view>
|
||||
<view class="new-page__button">
|
||||
<button class="new-page__button-item" @click="navToNvue">跳转NVUE页面</button>
|
||||
<button class="new-page__button-item" @click="navToVue">跳转VUE页面</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState,mapGetters,mapMutations} from 'vuex'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
...mapState(['colorIndex','colorList']),
|
||||
...mapGetters(['currentColor'])
|
||||
},
|
||||
methods:{
|
||||
...mapMutations(['setColorIndex']),
|
||||
navToNvue(){
|
||||
uni.navigateTo({
|
||||
url:'new-nvue-page-2'
|
||||
})
|
||||
},
|
||||
navToVue(){
|
||||
uni.navigateTo({
|
||||
url:'new-vue-page-2'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.new-page__text {
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.root{
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.page-body{
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
.new-page__text-box{
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.new-page__color{
|
||||
width: 200px;
|
||||
height: 100px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.new-page__color-text{
|
||||
font-size: 14px;
|
||||
color: #FFFFFF;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.new-page__button-item{
|
||||
margin-top: 15px;
|
||||
width: 300px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
<template>
|
||||
<view class="root">
|
||||
<view class="page-body">
|
||||
<view class="new-page__color" @click="setColorIndex(colorIndex>1?0:colorIndex+1)" :style="{backgroundColor:currentColor}">
|
||||
<text class="new-page__color-text">点击改变颜色</text>
|
||||
</view>
|
||||
<view class="new-page__text-box">
|
||||
<text class="new-page__text">点击上方色块使用vuex在页面之间进行通讯</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState,mapGetters,mapMutations} from 'vuex'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
...mapState(['colorIndex','colorList']),
|
||||
...mapGetters(['currentColor'])
|
||||
},
|
||||
methods:{
|
||||
...mapMutations(['setColorIndex'])
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.new-page__text {
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.root{
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.page-body{
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
.new-page__text-box{
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.new-page__color{
|
||||
width: 200px;
|
||||
height: 100px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.new-page__color-text{
|
||||
font-size: 14px;
|
||||
color: #FFFFFF;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.new-page__button-item{
|
||||
margin-top: 15px;
|
||||
width: 300px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
<template>
|
||||
<view class="root">
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="page-body">
|
||||
<view class="new-page__text-box">
|
||||
<text class="new-page__text">从上个页面接收到参数:{{data}}</text>
|
||||
</view>
|
||||
<view class="new-page__color" @click="setColorIndex(colorIndex>1?0:colorIndex+1)" :style="{backgroundColor:currentColor}">
|
||||
<text class="new-page__color-text">点击改变颜色</text>
|
||||
</view>
|
||||
<view class="new-page__text-box">
|
||||
<text class="new-page__text">点击上方色块使用vuex在页面之间进行通讯</text>
|
||||
</view>
|
||||
<view class="new-page__button">
|
||||
<!-- #ifndef VUE3-->
|
||||
<button class="new-page__button-item" @click="navToNvue">跳转NVUE页面</button>
|
||||
<!-- #endif -->
|
||||
<button class="new-page__button-item" @click="navToVue">跳转VUE页面</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState,mapGetters,mapMutations} from 'vuex'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: '新页面',
|
||||
data:""
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
...mapState(['colorIndex','colorList']),
|
||||
...mapGetters(['currentColor'])
|
||||
},
|
||||
onLoad(e){
|
||||
if(e.data){
|
||||
this.data = e.data;
|
||||
}
|
||||
uni.$on('postMsg',(res)=>{
|
||||
uni.showModal({
|
||||
content: `收到uni.$emit消息:${res.msg}`,
|
||||
showCancel: false
|
||||
})
|
||||
})
|
||||
},
|
||||
onUnload() {
|
||||
uni.$off('postMsg')
|
||||
},
|
||||
methods:{
|
||||
...mapMutations(['setColorIndex']),
|
||||
navToNvue(){
|
||||
uni.navigateTo({
|
||||
url:'new-nvue-page-1'
|
||||
})
|
||||
},
|
||||
navToVue(){
|
||||
uni.navigateTo({
|
||||
url:'new-vue-page-2'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.new-page__text {
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.root{
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.page-body{
|
||||
/* flex: 1; */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.new-page__text-box{
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.new-page__color{
|
||||
display: flex;
|
||||
width: 200px;
|
||||
height: 100px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.new-page__color-text{
|
||||
font-size: 14px;
|
||||
color: #FFFFFF;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.new-page__button-item{
|
||||
margin-top: 15px;
|
||||
width: 300px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
<template>
|
||||
<view class="root">
|
||||
<view class="page-body">
|
||||
<view class="new-page__color" @click="setColorIndex(colorIndex>1?0:colorIndex+1)" :style="{backgroundColor:currentColor}">
|
||||
<text class="new-page__color-text">点击改变颜色</text>
|
||||
</view>
|
||||
<view class="new-page__text-box">
|
||||
<text class="new-page__text">点击上方色块使用vuex在页面之间进行通讯</text>
|
||||
</view>
|
||||
<view class="new-page__button">
|
||||
<button class="new-page__button-item" @click="emitMsg">向上一页面传递数据</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import {
|
||||
mapState,
|
||||
mapGetters,
|
||||
mapMutations
|
||||
} from 'vuex'
|
||||
export default {
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['colorIndex', 'colorList']),
|
||||
...mapGetters(['currentColor'])
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['setColorIndex']),
|
||||
emitMsg() {
|
||||
uni.$emit('postMsg', {
|
||||
msg: 'From: Vue Page'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.new-page__text {
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.root {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.page-body {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding-top: 50px;
|
||||
}
|
||||
|
||||
.new-page__text-box {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.new-page__color {
|
||||
display: flex;
|
||||
width: 200px;
|
||||
height: 100px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.new-page__color-text {
|
||||
font-size: 14px;
|
||||
color: #FFFFFF;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.new-page__button-item {
|
||||
margin-top: 15px;
|
||||
width: 300px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<view class="uni-btn-v">
|
||||
<button class="shake" @tap="shake">摇一摇</button>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" @tap="watchAcce">监听设备的加速度变化</button>
|
||||
<button type="primary" @tap="stopAcce">停止监听设备的加速度变化</button>
|
||||
</view>
|
||||
<view class="uni-textarea uni-common-mt">
|
||||
<textarea class="acc-show" :value="value" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'onAccelerometerChange',
|
||||
value: ''
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
uni.stopAccelerometer();
|
||||
},
|
||||
methods: {
|
||||
//#ifdef APP-PLUS
|
||||
shake() {
|
||||
uni.navigateTo({
|
||||
url: '/platforms/app-plus/shake/shake'
|
||||
})
|
||||
},
|
||||
//#endif
|
||||
watchAcce() {
|
||||
uni.onAccelerometerChange((res) => {
|
||||
this.value = "监听设备的加速度变化:\n" + "X轴:" + res.x.toFixed(2) + "\nY轴:" + res.y.toFixed(2) +
|
||||
"\nZ轴:" + res.z.toFixed(2);
|
||||
})
|
||||
},
|
||||
stopAcce() {
|
||||
uni.stopAccelerometer()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.shake {
|
||||
background-color: #FFCC33;
|
||||
color: #ffffff;
|
||||
margin-bottom: 50rpx;
|
||||
}
|
||||
.uni-textarea .acc-show{
|
||||
height: 240rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-hello-text uni-center" style="padding-bottom:50rpx;">
|
||||
旋转手机即可获取方位信息
|
||||
</view>
|
||||
<view class="direction">
|
||||
<view class="bg-compass-line"></view>
|
||||
<image class="bg-compass" src="../../../static/compass.png" :style="'transform: rotate('+direction+'deg)'"></image>
|
||||
<view class="direction-value">
|
||||
<text>{{direction}}</text>
|
||||
<text class="direction-degree">o</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'onCompassChange',
|
||||
direction: 0
|
||||
}
|
||||
},
|
||||
onReady: function () {
|
||||
uni.onCompassChange((res) => {
|
||||
this.direction = parseInt(res.direction)
|
||||
})
|
||||
},
|
||||
onUnload() {
|
||||
// #ifndef MP-ALIPAY
|
||||
uni.stopCompass();
|
||||
this.direction = 0;
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-ALIPAY
|
||||
uni.offCompassChange();
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.direction {
|
||||
position: relative;
|
||||
margin-top: 70rpx;
|
||||
display: flex;
|
||||
width: 540rpx;
|
||||
height: 540rpx;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin:0 auto;
|
||||
}
|
||||
|
||||
.direction-value {
|
||||
position: relative;
|
||||
font-size: 200rpx;
|
||||
color: #353535;
|
||||
line-height: 1;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.direction-degree {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -40rpx;
|
||||
font-size: 60rpx;
|
||||
}
|
||||
|
||||
.bg-compass {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 540rpx;
|
||||
height: 540rpx;
|
||||
transition: .1s;
|
||||
}
|
||||
|
||||
.bg-compass-line {
|
||||
position: absolute;
|
||||
left: 267rpx;
|
||||
top: -10rpx;
|
||||
width: 6rpx;
|
||||
height: 56rpx;
|
||||
background-color: #1AAD19;
|
||||
border-radius: 999rpx;
|
||||
z-index: 1;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-common-mt">
|
||||
<form @submit="openLocation">
|
||||
<view class="uni-list">
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">经度</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" value="116.39747" name="longitude"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">纬度</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" value="39.9085" name="latitude"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">位置名称</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" value="天安门" name="name"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">详细位置</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" :disabled="true" value="北京市东城区东长安街" name="address"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-btn-v uni-common-mt">
|
||||
<button type="primary" formType="submit">查看位置</button>
|
||||
</view>
|
||||
</view>
|
||||
</form>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'openLocation'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openLocation: function (e) {
|
||||
console.log(e)
|
||||
var value = e.detail.value
|
||||
uni.openLocation({
|
||||
longitude: Number(value.longitude),
|
||||
latitude: Number(value.latitude),
|
||||
name: value.name,
|
||||
address: value.address
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-list-cell-left {
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view style="font-size: 12px; color: #666;">注:PC 不支持下拉刷新</view>
|
||||
<view class="text" v-for="(num,index) in data" :key="index">list - {{num}}</view>
|
||||
<view class="uni-loadmore" v-if="showLoadMore">{{loadMoreText}}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: '下拉刷新 + 加载更多',
|
||||
data: [],
|
||||
loadMoreText: "加载中...",
|
||||
showLoadMore: false,
|
||||
max: 0
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
this.initData();
|
||||
},
|
||||
onUnload() {
|
||||
this.max = 0,
|
||||
this.data = [],
|
||||
this.loadMoreText = "加载更多",
|
||||
this.showLoadMore = false;
|
||||
},
|
||||
onReachBottom() {
|
||||
console.log("onReachBottom");
|
||||
if (this.max > 40) {
|
||||
this.loadMoreText = "没有更多数据了!"
|
||||
return;
|
||||
}
|
||||
this.showLoadMore = true;
|
||||
setTimeout(() => {
|
||||
this.setListData();
|
||||
}, 300);
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
console.log('onPullDownRefresh');
|
||||
this.initData();
|
||||
},
|
||||
methods: {
|
||||
initData(){
|
||||
setTimeout(() => {
|
||||
this.max = 0;
|
||||
this.data = [];
|
||||
let data = [];
|
||||
this.max += 20;
|
||||
for (var i = this.max - 19; i < this.max + 1; i++) {
|
||||
data.push(i)
|
||||
}
|
||||
this.data = this.data.concat(data);
|
||||
uni.stopPullDownRefresh();
|
||||
}, 300);
|
||||
},
|
||||
setListData() {
|
||||
let data = [];
|
||||
this.max += 10;
|
||||
for (var i = this.max - 9; i < this.max + 1; i++) {
|
||||
data.push(i)
|
||||
}
|
||||
this.data = this.data.concat(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.text {
|
||||
margin: 16rpx 0;
|
||||
width:100%;
|
||||
background-color: #fff;
|
||||
height: 120rpx;
|
||||
line-height: 120rpx;
|
||||
text-align: center;
|
||||
color: #555;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,256 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view style="background:#FFF; padding:50rpx 0;">
|
||||
<view class="uni-hello-text uni-center"><text>支付金额</text></view>
|
||||
<view class="uni-h1 uni-center uni-common-mt">
|
||||
<text class="rmbLogo">¥</text>
|
||||
<input class="price" type="digit" :value="price" maxlength="4" @input="priceChange" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-btn-v uni-common-mt">
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<button type="primary" @click="weixinPay" :loading="loading">微信支付</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<template v-if="providerList.length > 0">
|
||||
<button v-for="(item,index) in providerList" :key="index" @click="requestPayment(item,index)" :loading="item.loading">{{item.name}}支付</button>
|
||||
</template>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'request-payment',
|
||||
loading: false,
|
||||
price: 1,
|
||||
providerList: []
|
||||
}
|
||||
},
|
||||
onLoad: function() {
|
||||
// #ifdef APP-PLUS
|
||||
uni.getProvider({
|
||||
service: "payment",
|
||||
success: (e) => {
|
||||
console.log("payment success:" + JSON.stringify(e));
|
||||
let providerList = [];
|
||||
e.provider.map((value) => {
|
||||
switch (value) {
|
||||
case 'alipay':
|
||||
providerList.push({
|
||||
name: '支付宝',
|
||||
id: value,
|
||||
loading: false
|
||||
});
|
||||
break;
|
||||
case 'wxpay':
|
||||
providerList.push({
|
||||
name: '微信',
|
||||
id: value,
|
||||
loading: false
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
})
|
||||
this.providerList = providerList;
|
||||
},
|
||||
fail: (e) => {
|
||||
console.log("获取支付通道失败:", e);
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
methods: {
|
||||
loginMpWeixin() {
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.login({
|
||||
provider: 'weixin',
|
||||
success(res) {
|
||||
console.warn('此处使用uni-id处理微信小程序登录,详情参考: https://uniapp.dcloud.net.cn/uniCloud/uni-id')
|
||||
uni.request({
|
||||
url: 'https://97fca9f2-41f6-449f-a35e-3f135d4c3875.bspapp.com/http/user-center',
|
||||
method: 'POST',
|
||||
data: {
|
||||
action: 'loginByWeixin',
|
||||
params: {
|
||||
code: res.code,
|
||||
platform: 'mp-weixin'
|
||||
}
|
||||
},
|
||||
success(res) {
|
||||
if (res.data.code !== 0) {
|
||||
reject(new Error('获取openid失败:', res.result.msg))
|
||||
return
|
||||
}
|
||||
uni.setStorageSync('openid', res.data.openid)
|
||||
resolve(res.data.openid)
|
||||
},
|
||||
fail(err) {
|
||||
reject(new Error('获取openid失败:' + err))
|
||||
}
|
||||
})
|
||||
},
|
||||
fail(err) {
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
async weixinPay() {
|
||||
let openid = uni.getStorageSync('openid')
|
||||
console.log("发起支付");
|
||||
this.loading = true;
|
||||
if (!openid) {
|
||||
try {
|
||||
openid = await this.loginMpWeixin()
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
|
||||
if (!openid) {
|
||||
uni.showModal({
|
||||
content: '获取openid失败',
|
||||
showCancel: false
|
||||
})
|
||||
this.loading = false
|
||||
return
|
||||
}
|
||||
}
|
||||
this.openid = openid
|
||||
let orderInfo = await this.getOrderInfo('wxpay')
|
||||
if (!orderInfo) {
|
||||
uni.showModal({
|
||||
content: '获取支付信息失败',
|
||||
showCancel: false
|
||||
})
|
||||
return
|
||||
}
|
||||
uni.requestPayment({
|
||||
...orderInfo,
|
||||
success: (res) => {
|
||||
uni.showToast({
|
||||
title: "感谢您的赞助!"
|
||||
})
|
||||
},
|
||||
fail: (res) => {
|
||||
uni.showModal({
|
||||
content: "支付失败,原因为: " + res
|
||||
.errMsg,
|
||||
showCancel: false
|
||||
})
|
||||
},
|
||||
complete: () => {
|
||||
this.loading = false;
|
||||
}
|
||||
})
|
||||
},
|
||||
async requestPayment(e, index) {
|
||||
this.providerList[index].loading = true;
|
||||
const provider = e.id
|
||||
let orderInfo = await this.getOrderInfo(provider);
|
||||
if (!orderInfo) {
|
||||
uni.showModal({
|
||||
content: '获取支付信息失败',
|
||||
showCancel: false
|
||||
})
|
||||
return
|
||||
}
|
||||
console.log('--------orderInfo--------')
|
||||
console.log(orderInfo);
|
||||
uni.requestPayment({
|
||||
provider,
|
||||
orderInfo: orderInfo,
|
||||
success: (e) => {
|
||||
console.log("success", e);
|
||||
uni.showToast({
|
||||
title: "感谢您的赞助!"
|
||||
})
|
||||
},
|
||||
fail: (e) => {
|
||||
console.log("fail", e);
|
||||
uni.showModal({
|
||||
content: "支付失败,原因为: " + e.errMsg,
|
||||
showCancel: false
|
||||
})
|
||||
},
|
||||
complete: () => {
|
||||
this.providerList[index].loading = false;
|
||||
}
|
||||
})
|
||||
},
|
||||
getOrderInfo(provider) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.price) {
|
||||
reject(new Error('请输入金额'))
|
||||
}
|
||||
console.warn('此处使用uni-pay处理支付,详情参考: https://uniapp.dcloud.io/uniCloud/unipay')
|
||||
uni.request({
|
||||
method: 'POST',
|
||||
url: 'https://97fca9f2-41f6-449f-a35e-3f135d4c3875.bspapp.com/http/pay',
|
||||
data: {
|
||||
provider,
|
||||
openid: this.openid,
|
||||
totalFee: Number(this.price) * 100, // 转为以分为单位
|
||||
// #ifdef APP-PLUS
|
||||
platform: 'app-plus',
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
platform: 'mp-weixin',
|
||||
// #endif
|
||||
},
|
||||
success(res) {
|
||||
if (res.data.code === 0) {
|
||||
resolve(res.data.orderInfo)
|
||||
} else {
|
||||
reject(new Error('获取支付信息失败' + res.data.msg))
|
||||
}
|
||||
},
|
||||
fail(err) {
|
||||
reject(new Error('请求支付接口失败' + err))
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
priceChange(e) {
|
||||
console.log(e.detail.value)
|
||||
this.price = e.detail.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.rmbLogo {
|
||||
font-size: 40rpx;
|
||||
}
|
||||
|
||||
button {
|
||||
background-color: #007aff;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.uni-h1.uni-center {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.price {
|
||||
border-bottom: 1px solid #eee;
|
||||
width: 200rpx;
|
||||
height: 80rpx;
|
||||
padding-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.ipaPayBtn {
|
||||
margin-top: 30rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="uni-hello-text">
|
||||
请点击按钮向服务器发起请求
|
||||
</view>
|
||||
<view class="uni-textarea uni-common-mt">
|
||||
<textarea :value="res"></textarea>
|
||||
</view>
|
||||
<view class="uni-btn-v uni-common-mt">
|
||||
<button type="primary" @click="sendRequest" :loading="loading">发起请求(Callback)</button>
|
||||
<button type="primary" @click="sendRequest('promise')" :loading="loading">发起请求(Promise)</button>
|
||||
<button type="primary" @click="sendRequest('await')" :loading="loading">发起请求(Async/Await)</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
const requestUrl = 'https://unidemo.dcloud.net.cn/ajax/echo/text?name=uni-app'
|
||||
const duration = 2000
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'request',
|
||||
loading: false,
|
||||
res: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
sendRequest(mode) {
|
||||
this.loading = true;
|
||||
switch (mode) {
|
||||
case 'promise':
|
||||
this._requestPromise();
|
||||
break;
|
||||
case 'await':
|
||||
this._requestAwait();
|
||||
break;
|
||||
default:
|
||||
this._request();
|
||||
break;
|
||||
}
|
||||
},
|
||||
_request() {
|
||||
uni.request({
|
||||
url: requestUrl,
|
||||
dataType: 'text',
|
||||
data: {
|
||||
noncestr: Date.now()
|
||||
},
|
||||
success: (res) => {
|
||||
console.log('request success', res)
|
||||
uni.showToast({
|
||||
title: '请求成功',
|
||||
icon: 'success',
|
||||
mask: true,
|
||||
duration: duration
|
||||
});
|
||||
this.res = '请求结果 : ' + JSON.stringify(res);
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('request fail', err);
|
||||
uni.showModal({
|
||||
content: err.errMsg,
|
||||
showCancel: false
|
||||
});
|
||||
},
|
||||
complete: () => {
|
||||
this.loading = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
_requestPromise() {
|
||||
// #ifndef VUE3
|
||||
uni.request({
|
||||
url: requestUrl,
|
||||
dataType: 'text',
|
||||
data: {
|
||||
noncestr: Date.now()
|
||||
}
|
||||
}).then(res => {
|
||||
console.log('request success', res[1]);
|
||||
uni.showToast({
|
||||
title: '请求成功',
|
||||
icon: 'success',
|
||||
mask: true,
|
||||
duration: duration
|
||||
});
|
||||
this.res = '请求结果 : ' + JSON.stringify(res[1]);
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
console.log('request fail', err);
|
||||
uni.showModal({
|
||||
content: err.errMsg,
|
||||
showCancel: false
|
||||
});
|
||||
|
||||
this.loading = false;
|
||||
});
|
||||
// #endif
|
||||
|
||||
// #ifdef VUE3
|
||||
uni.request({
|
||||
url: requestUrl,
|
||||
dataType: 'text',
|
||||
data: {
|
||||
noncestr: Date.now()
|
||||
}
|
||||
}).then(res => {
|
||||
console.log('request success', res);
|
||||
uni.showToast({
|
||||
title: '请求成功',
|
||||
icon: 'success',
|
||||
mask: true,
|
||||
duration: duration
|
||||
});
|
||||
this.res = '请求结果 : ' + JSON.stringify(res);
|
||||
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
console.log('request fail', err);
|
||||
uni.showModal({
|
||||
content: err.errMsg,
|
||||
showCancel: false
|
||||
});
|
||||
|
||||
this.loading = false;
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
async _requestAwait() {
|
||||
let res, err
|
||||
// #ifndef VUE3
|
||||
[err, res] = await uni.request({
|
||||
url: requestUrl,
|
||||
dataType: 'text',
|
||||
data: {
|
||||
noncestr: Date.now()
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
// #ifdef VUE3
|
||||
try {
|
||||
res = await uni.request({
|
||||
url: requestUrl,
|
||||
dataType: 'text',
|
||||
data: {
|
||||
noncestr: Date.now()
|
||||
}
|
||||
});
|
||||
} catch(e){
|
||||
err=e
|
||||
}
|
||||
// #endif
|
||||
if (err) {
|
||||
console.log('request fail', err);
|
||||
uni.showModal({
|
||||
content: err.errMsg,
|
||||
showCancel: false
|
||||
});
|
||||
} else {
|
||||
console.log('request success', res)
|
||||
uni.showToast({
|
||||
title: '请求成功',
|
||||
icon: 'success',
|
||||
mask: true,
|
||||
duration: duration
|
||||
});
|
||||
this.res = '请求结果 : ' + JSON.stringify(res);
|
||||
}
|
||||
this.loading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<button v-if="!loadError" :loading="loading" :disabled="loading" type="primary" class="btn" @click="show">显示广告</button>
|
||||
<button v-if="loadError" :loading="loading" :disabled="loading" type="primary" class="btn" @click="reloadAd">重新加载广告</button>
|
||||
</view>
|
||||
<!-- #ifndef APP-PLUS -->
|
||||
<view class="ad-tips">
|
||||
<text>小程序端的广告ID由小程序平台提供</text>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const ERROR_CODE = [-5001, -5002, -5003, -5004, -5005, -5006];
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: '激励视频广告',
|
||||
loading: false,
|
||||
loadError: false
|
||||
}
|
||||
},
|
||||
onReady() {
|
||||
// #ifdef APP-PLUS
|
||||
this.adOption = {
|
||||
adpid: '1507000689'
|
||||
};
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
this.adOption = {
|
||||
adUnitId: ''
|
||||
};
|
||||
// #endif
|
||||
this.createAd();
|
||||
},
|
||||
methods: {
|
||||
createAd() {
|
||||
var rewardedVideoAd = this.rewardedVideoAd = uni.createRewardedVideoAd(this.adOption);
|
||||
rewardedVideoAd.onLoad(() => {
|
||||
this.loading = false;
|
||||
this.loadError = false;
|
||||
console.log('onLoad event')
|
||||
});
|
||||
rewardedVideoAd.onClose((res) => {
|
||||
this.loading = true;
|
||||
// 用户点击了【关闭广告】按钮
|
||||
if (res && res.isEnded) {
|
||||
// 正常播放结束
|
||||
console.log("onClose " + res.isEnded);
|
||||
} else {
|
||||
// 播放中途退出
|
||||
console.log("onClose " + res.isEnded);
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
uni.showToast({
|
||||
title: "激励视频" + (res.isEnded ? "成功" : "未") + "播放完毕",
|
||||
duration: 10000,
|
||||
position: 'bottom'
|
||||
})
|
||||
}, 500)
|
||||
});
|
||||
rewardedVideoAd.onError((err) => {
|
||||
this.loading = false;
|
||||
if (err.code && ERROR_CODE.indexOf(err.code) !== -1) {
|
||||
this.loadError = true;
|
||||
}
|
||||
console.log('onError event', err)
|
||||
});
|
||||
this.loading = true;
|
||||
},
|
||||
show() {
|
||||
const rewardedVideoAd = this.rewardedVideoAd;
|
||||
rewardedVideoAd.show().catch(() => {
|
||||
rewardedVideoAd.load()
|
||||
.then(() => rewardedVideoAd.show())
|
||||
.catch(err => {
|
||||
console.log('激励视频 广告显示失败', err)
|
||||
uni.showToast({
|
||||
title: err.errMsg || err.message,
|
||||
duration: 5000,
|
||||
position: 'bottom'
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
reloadAd() {
|
||||
this.loading = true;
|
||||
this.rewardedVideoAd.load();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.btn {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.ad-tips {
|
||||
color: #999;
|
||||
padding: 30px 0;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view v-if="imagePath !== ''" class="media-box image">
|
||||
<image class="image" mode="widthFix" :src="imagePath" />
|
||||
</view>
|
||||
<button type="primary" class="uni-button" @click="saveImage">拍摄图片并保存到本地</button>
|
||||
<view v-if="videoPath !== ''" class="media-box">
|
||||
<video
|
||||
id="myVideo"
|
||||
:src="videoPath"
|
||||
@error="videoErrorCallback"
|
||||
enable-danmu
|
||||
danmu-btn
|
||||
controls
|
||||
></video>
|
||||
</view>
|
||||
<button type="primary" class="uni-button" @click="saveVideo">录制视频并保存到本地</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'saveImage/saveVideo',
|
||||
imagePath: '',
|
||||
videoPath: ''
|
||||
};
|
||||
},
|
||||
onLoad() {},
|
||||
methods: {
|
||||
videoErrorCallback: function() {
|
||||
uni.showModal({
|
||||
content: '视频加载失败',
|
||||
showCancel: false
|
||||
});
|
||||
},
|
||||
saveImage() {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sourceType: ['camera'],
|
||||
success: res => {
|
||||
this.imagePath = res.tempFilePaths[0];
|
||||
this.getTempFilePath(res.tempFilePaths[0], 'imageTempPath');
|
||||
},
|
||||
fail: (err) => {
|
||||
// #ifdef MP
|
||||
uni.getSetting({
|
||||
success: (res) => {
|
||||
let authStatus = res.authSetting['scope.camera'];
|
||||
if (!authStatus) {
|
||||
uni.showModal({
|
||||
title: '授权失败',
|
||||
content: 'Hello uni-app需要从您的相机获取图片,请在设置界面打开相关权限',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.openSetting()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
});
|
||||
},
|
||||
saveVideo() {
|
||||
let _this = this;
|
||||
uni.chooseVideo({
|
||||
count: 1,
|
||||
sourceType: ['camera'],
|
||||
success: res => {
|
||||
console.log(res.tempFilePath)
|
||||
this.videoPath = res.tempFilePath;
|
||||
this.getTempFilePath(res.tempFilePath, 'videoTempPath');
|
||||
},
|
||||
fail: (err) => {
|
||||
// #ifdef MP
|
||||
uni.getSetting({
|
||||
success: (res) => {
|
||||
let authStatus = res.authSetting['scope.camera'];
|
||||
if (!authStatus) {
|
||||
uni.showModal({
|
||||
title: '授权失败',
|
||||
content: 'Hello uni-app需要从您的相机获取视频,请在设置界面打开相关权限',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.openSetting()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getTempFilePath(url, types) {
|
||||
// 如果已经下载本地路径,那么直接储存
|
||||
let obj = {
|
||||
filePath: url,
|
||||
success: () => {
|
||||
console.log('save success');
|
||||
uni.showModal({
|
||||
content: '保存成功',
|
||||
showCancel: false
|
||||
});
|
||||
uni.hideLoading();
|
||||
},
|
||||
fail: e => {
|
||||
uni.hideLoading();
|
||||
uni.showModal({
|
||||
content: '保存失败',
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
};
|
||||
uni.showLoading({
|
||||
title: '保存中...'
|
||||
});
|
||||
if (types === 'videoTempPath') {
|
||||
uni.saveVideoToPhotosAlbum(obj);
|
||||
} else {
|
||||
uni.saveImageToPhotosAlbum(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.media-box {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 30rpx 0;
|
||||
width: 100%;
|
||||
}
|
||||
.image {
|
||||
height: 400rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
.image image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
video {
|
||||
width: 100%;
|
||||
}
|
||||
.uni-button {
|
||||
margin: 30rpx 0;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="uni-title">扫码结果:</view>
|
||||
<view class="uni-list" v-if="result">
|
||||
<view class="uni-cell">
|
||||
<view class="scan-result">
|
||||
{{result}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" @click="scan">扫一扫</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
import permision from "@/common/permission.js"
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'scanCode',
|
||||
result: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async scan() {
|
||||
// #ifdef APP-PLUS
|
||||
let status = await this.checkPermission();
|
||||
if (status !== 1) {
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
uni.scanCode({
|
||||
success: (res) => {
|
||||
this.result = res.result
|
||||
},
|
||||
fail: (err) => {
|
||||
// 需要注意的是小程序扫码不需要申请相机权限
|
||||
}
|
||||
});
|
||||
}
|
||||
// #ifdef APP-PLUS
|
||||
,
|
||||
async checkPermission(code) {
|
||||
let status = permision.isIOS ? await permision.requestIOS('camera') :
|
||||
await permision.requestAndroid('android.permission.CAMERA');
|
||||
|
||||
if (status === null || status === 1) {
|
||||
status = 1;
|
||||
} else {
|
||||
uni.showModal({
|
||||
content: "需要相机权限",
|
||||
confirmText: "设置",
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
permision.gotoAppSetting();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
return status;
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.scan-result {
|
||||
min-height: 50rpx;
|
||||
line-height: 50rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
describe('pages/API/set-navigation-bar-title/set-navigation-bar-title.vue', () => {
|
||||
let page
|
||||
beforeAll(async () => {
|
||||
// 重新reLaunch至首页,并获取首页page对象(其中 program 是uni-automator自动注入的全局对象)
|
||||
page = await program.reLaunch('/pages/API/set-navigation-bar-title/set-navigation-bar-title')
|
||||
|
||||
if (process.env.UNI_PLATFORM === "mp-weixin") {
|
||||
await page.waitFor(10000)
|
||||
} else {
|
||||
await page.waitFor(5000)
|
||||
}
|
||||
|
||||
page = await program.currentPage()
|
||||
|
||||
})
|
||||
|
||||
it('set-navigation-bar-title 组件标题', async () => {
|
||||
let view = await page.$('.common-page-head-title')
|
||||
expect(await view.text()).toBe('nav-default')
|
||||
})
|
||||
})
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<template>
|
||||
<view class="page">
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-helllo-text">
|
||||
本页标题栏是uni-app的默认配置,开发者可在pages.json里配置文字内容及标题颜色,也可通过api接口将其改变。
|
||||
</view>
|
||||
<view class="uni-btn-v">
|
||||
<button type="default" @click="setText">改变标题栏文字</button>
|
||||
<button type="primary" @click="setBg">改变标题栏颜色</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'nav-default',
|
||||
hasSetText:false,
|
||||
hasSetBg:false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setText() {
|
||||
this.hasSetText = !this.hasSetText;
|
||||
uni.setNavigationBarTitle({
|
||||
title: this.hasSetText ? "Hello uni-app" : "默认导航栏"
|
||||
})
|
||||
},
|
||||
setBg() {
|
||||
this.hasSetBg = !this.hasSetBg;
|
||||
uni.setNavigationBarColor({
|
||||
frontColor: this.hasSetBg ? "#000000" : "#ffffff",
|
||||
backgroundColor: this.hasSetBg ? "#F8F8F8" : "#007AFF"
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-title">分享内容</view>
|
||||
<view class="uni-textarea">
|
||||
<textarea class="textarea" v-model="shareText" />
|
||||
</view>
|
||||
<view class="uni-title">分享图片:</view>
|
||||
<view class="uni-uploader" style="padding:15rpx; background:#FFF;">
|
||||
<view class="uni-uploader__input-box" v-if="!image" @tap="chooseImage"></view>
|
||||
<image class="uni-uploader__img" v-if="image" :src="image"></image>
|
||||
</view>
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<view class="uni-title">分享类型:</view>
|
||||
<view>
|
||||
<radio-group @change="radioChange">
|
||||
<label class="radio">
|
||||
<radio value="1" checked="true"/>文字
|
||||
</label>
|
||||
<label class="radio">
|
||||
<radio value="2" />图片
|
||||
</label>
|
||||
<label class="radio">
|
||||
<radio value="0" />图文
|
||||
</label>
|
||||
<label class="radio">
|
||||
<radio value="5" />小程序
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
<view class="uni-btn-v uni-common-mt" v-if="providerList.length > 0">
|
||||
<block v-for="(value,index) in providerList" :key="index">
|
||||
<button type="primary" v-if="value" :disabled="isDisableButton(value)" @tap="share(value)">{{value.name}}</button>
|
||||
</block>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef MP || QUICKAPP-WEBVIEW -->
|
||||
<view class="uni-btn-v uni-common-mt">
|
||||
<button type="primary" open-type="share">分享</button>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'share',
|
||||
shareText: 'uni-app可以同时发布成原生App、小程序、H5,邀请你一起体验!',
|
||||
href:"https://uniapp.dcloud.io",
|
||||
image: '',
|
||||
shareType:1,
|
||||
providerList: []
|
||||
}
|
||||
},
|
||||
computed:{
|
||||
isDisableButton() {
|
||||
return function(item) {
|
||||
if(this.shareType === 0 && item.id === 'qq'){
|
||||
return true;
|
||||
}
|
||||
if(this.shareType === 5 && item.name !== '分享到微信好友'){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
},
|
||||
onShareAppMessage() {
|
||||
return {
|
||||
title: this.shareText ? this.shareText : "欢迎体验uni-app",
|
||||
path: '/pages/tabBar/component/component',
|
||||
imageUrl:this.image ? this.image : 'https://web-assets.dcloud.net.cn/unidoc/zh/share-logo@3.png'
|
||||
}
|
||||
},
|
||||
onUnload:function(){
|
||||
this.shareText='uni-app可以同时发布成原生App、小程序、H5,邀请你一起体验!',
|
||||
this.href = 'https://uniapp.dcloud.io',
|
||||
this.image='';
|
||||
},
|
||||
onLoad: function () {
|
||||
uni.getProvider({
|
||||
service: 'share',
|
||||
success: (e) => {
|
||||
console.log('success', e);
|
||||
let data = []
|
||||
for (let i = 0; i < e.provider.length; i++) {
|
||||
switch (e.provider[i]) {
|
||||
case 'weixin':
|
||||
data.push({
|
||||
name: '分享到微信好友',
|
||||
id: 'weixin',
|
||||
sort:0
|
||||
})
|
||||
data.push({
|
||||
name: '分享到微信朋友圈',
|
||||
id: 'weixin',
|
||||
type:'WXSenceTimeline',
|
||||
sort:1
|
||||
})
|
||||
break;
|
||||
case 'sinaweibo':
|
||||
data.push({
|
||||
name: '分享到新浪微博',
|
||||
id: 'sinaweibo',
|
||||
sort:2
|
||||
})
|
||||
break;
|
||||
case 'qq':
|
||||
data.push({
|
||||
name: '分享到QQ',
|
||||
id: 'qq',
|
||||
sort:3
|
||||
})
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.providerList = data.sort((x,y) => {
|
||||
return x.sort - y.sort
|
||||
});
|
||||
},
|
||||
fail: (e) => {
|
||||
console.log('获取分享通道失败', e);
|
||||
uni.showModal({
|
||||
content:'获取分享通道失败',
|
||||
showCancel:false
|
||||
})
|
||||
}
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
async share(e) {
|
||||
console.log('分享通道:'+ e.id +'; 分享类型:' + this.shareType);
|
||||
|
||||
if(!this.shareText && (this.shareType === 1 || this.shareType === 0)){
|
||||
uni.showModal({
|
||||
content:'分享内容不能为空',
|
||||
showCancel:false
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
if(!this.image && (this.shareType === 2 || this.shareType === 0)){
|
||||
uni.showModal({
|
||||
content:'分享图片不能为空',
|
||||
showCancel:false
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
let shareOPtions = {
|
||||
provider: e.id,
|
||||
scene: e.type && e.type === 'WXSceneTimeline' ? 'WXSceneTimeline' : 'WXSceneSession', //WXSceneSession”分享到聊天界面,“WXSceneTimeline”分享到朋友圈,“WXSceneFavorite”分享到微信收藏
|
||||
type: this.shareType,
|
||||
success: (e) => {
|
||||
console.log('success', e);
|
||||
uni.showModal({
|
||||
content: '已分享',
|
||||
showCancel:false
|
||||
})
|
||||
},
|
||||
fail: (e) => {
|
||||
console.log('fail', e)
|
||||
uni.showModal({
|
||||
content: e.errMsg,
|
||||
showCancel:false
|
||||
})
|
||||
},
|
||||
complete:function(){
|
||||
console.log('分享操作结束!')
|
||||
}
|
||||
}
|
||||
|
||||
switch (this.shareType){
|
||||
case 0:
|
||||
shareOPtions.summary = this.shareText;
|
||||
shareOPtions.imageUrl = this.image;
|
||||
shareOPtions.title = '欢迎体验uniapp';
|
||||
shareOPtions.href = 'https://uniapp.dcloud.io';
|
||||
break;
|
||||
case 1:
|
||||
shareOPtions.summary = this.shareText;
|
||||
break;
|
||||
case 2:
|
||||
shareOPtions.imageUrl = this.image;
|
||||
break;
|
||||
case 5:
|
||||
shareOPtions.imageUrl = this.image ? this.image : 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/b6304f00-5168-11eb-bd01-97bc1429a9ff.png'
|
||||
shareOPtions.title = '欢迎体验uniapp';
|
||||
shareOPtions.miniProgram = {
|
||||
id:'gh_33446d7f7a26',
|
||||
path:'/pages/tabBar/component/component',
|
||||
webUrl:'https://uniapp.dcloud.io',
|
||||
type:0
|
||||
};
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if(shareOPtions.type === 0 && plus.os.name === 'iOS'){//如果是图文分享,且是ios平台,则压缩图片
|
||||
shareOPtions.imageUrl = await this.compress();
|
||||
}
|
||||
if(shareOPtions.type === 1 && shareOPtions.provider === 'qq'){//如果是分享文字到qq,则必须加上href和title
|
||||
shareOPtions.href = 'https://uniapp.dcloud.io';
|
||||
shareOPtions.title = '欢迎体验uniapp';
|
||||
}
|
||||
uni.share(shareOPtions);
|
||||
},
|
||||
radioChange(e){
|
||||
console.log('type:' + e.detail.value);
|
||||
this.shareType = parseInt(e.detail.value);
|
||||
},
|
||||
chooseImage() {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sourceType: ['album', 'camera'],
|
||||
sizeType: ['compressed', 'original'],
|
||||
success: (res) => {
|
||||
this.image = res.tempFilePaths[0];
|
||||
},
|
||||
fail: (err) => {
|
||||
// #ifdef MP
|
||||
uni.getSetting({
|
||||
success: (res) => {
|
||||
let authStatus = res.authSetting['scope.album'] && res.authSetting['scope.camera'];
|
||||
if (!authStatus) {
|
||||
uni.showModal({
|
||||
title: '授权失败',
|
||||
content: 'Hello uni-app需要从您的相机或相册获取图片,请在设置界面打开相关权限',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.openSetting()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
})
|
||||
},
|
||||
compress(){//压缩图片 图文分享要求分享图片大小不能超过20Kb
|
||||
console.log('开始压缩');
|
||||
let img = this.image;
|
||||
return new Promise((res) => {
|
||||
var localPath = plus.io.convertAbsoluteFileSystem(img.replace('file://', ''));
|
||||
console.log('after' + localPath);
|
||||
// 压缩size
|
||||
plus.io.resolveLocalFileSystemURL(localPath, (entry) => {
|
||||
entry.file((file) => {// 可通过entry对象操作图片
|
||||
console.log('getFile:' + JSON.stringify(file));
|
||||
if(file.size > 20480) {// 压缩后size 大于20Kb
|
||||
plus.zip.compressImage({
|
||||
src: img,
|
||||
dst: img.replace('.jpg', '2222.jpg').replace('.JPG', '2222.JPG'),
|
||||
width: '10%',
|
||||
height: '10%',
|
||||
quality: 1,
|
||||
overwrite: true
|
||||
}, (event) => {
|
||||
console.log('success zip****' + event.size);
|
||||
let newImg = img.replace('.jpg', '2222.jpg').replace('.JPG', '2222.JPG');
|
||||
res(newImg);
|
||||
}, function(error) {
|
||||
uni.showModal({
|
||||
content:'分享图片太大,需要请重新选择图片!',
|
||||
showCancel:false
|
||||
})
|
||||
});
|
||||
}
|
||||
});
|
||||
}, (e) => {
|
||||
console.log('Resolve file URL failed: ' + e.message);
|
||||
uni.showModal({
|
||||
content:'分享图片太大,需要请重新选择图片!',
|
||||
showCancel:false
|
||||
})
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-btn-v">
|
||||
<button class="btn-load" type="primary" @click="showLoading">显示 loading 提示框</button>
|
||||
<!-- #ifndef MP-ALIPAY -->
|
||||
<button @click="hideLoading">隐藏 loading 提示框</button>
|
||||
<!-- #endif -->
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'loading'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showLoading: function() {
|
||||
uni.showLoading({
|
||||
title: 'loading'
|
||||
});
|
||||
|
||||
// #ifdef MP-ALIPAY
|
||||
this._showTimer && clearTimeout(this._showTimer);
|
||||
this._showTimer = setTimeout(() => {
|
||||
this.hideLoading();
|
||||
}, 3000)
|
||||
// #endif
|
||||
},
|
||||
hideLoading: function() {
|
||||
uni.hideLoading();
|
||||
}
|
||||
}
|
||||
// #ifdef MP-ALIPAY
|
||||
,
|
||||
onUnload() {
|
||||
this._showTimer && clearTimeout(this._showTimer);
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" @click="checkIsSupportSoterAuthentication">检查支持的认证方式</button>
|
||||
<button type="primary" @click="checkIsSoterEnrolledInDeviceFingerPrint">检查是否录入指纹</button>
|
||||
<button type="primary" @click="checkIsSoterEnrolledInDeviceFaceID">检查是否录入FaceID</button>
|
||||
<button type="primary" @click="startSoterAuthenticationFingerPrint">开始指纹认证</button>
|
||||
<button type="primary" @click="startSoterAuthenticationFaceID">开始FaceID认证</button>
|
||||
</view>
|
||||
<view style="width: 100%;text-align: center;">{{ result }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: '生物认证',
|
||||
result: ''
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
|
||||
},
|
||||
methods: {
|
||||
checkIsSupportSoterAuthentication() {
|
||||
uni.checkIsSupportSoterAuthentication({
|
||||
success(res) {
|
||||
uni.showModal({
|
||||
content: '支持的认证方式:' + res.supportMode,
|
||||
showCancel: false
|
||||
})
|
||||
console.log(res);
|
||||
},
|
||||
fail(err) {
|
||||
console.log(err);
|
||||
}
|
||||
})
|
||||
},
|
||||
checkIsSoterEnrolledInDeviceFingerPrint() {
|
||||
uni.checkIsSoterEnrolledInDevice({
|
||||
checkAuthMode: 'fingerPrint',
|
||||
success(res) {
|
||||
if(res.isEnrolled) {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '已录入指纹'
|
||||
})
|
||||
}else {
|
||||
uni.showModal({
|
||||
content: '未录入指纹',
|
||||
showCancel: false
|
||||
})
|
||||
}
|
||||
console.log(res);
|
||||
},
|
||||
fail(err) {
|
||||
uni.showModal({
|
||||
content: '未录入指纹',
|
||||
showCancel: false
|
||||
})
|
||||
console.log(err);
|
||||
}
|
||||
})
|
||||
},
|
||||
checkIsSoterEnrolledInDeviceFaceID() {
|
||||
uni.checkIsSoterEnrolledInDevice({
|
||||
checkAuthMode: 'facial',
|
||||
success(res) {
|
||||
if(res.isEnrolled) {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '已录入FaceID'
|
||||
})
|
||||
}else {
|
||||
uni.showModal({
|
||||
content: '未录入FaceID',
|
||||
showCancel: false
|
||||
})
|
||||
}
|
||||
console.log(res);
|
||||
},
|
||||
fail(err) {
|
||||
uni.showModal({
|
||||
content: '未录入FaceID',
|
||||
showCancel: false
|
||||
})
|
||||
console.log(err);
|
||||
}
|
||||
})
|
||||
},
|
||||
startSoterAuthenticationFingerPrint() {
|
||||
uni.startSoterAuthentication({
|
||||
requestAuthModes: ['fingerPrint'],
|
||||
challenge: '123456',
|
||||
authContent: '请用指纹解锁',
|
||||
success(res) {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '指纹验证成功'
|
||||
})
|
||||
console.log(res);
|
||||
},
|
||||
fail(err) {
|
||||
uni.showModal({
|
||||
content: '指纹验证失败,errCode:' + err.errCode,
|
||||
showCancel: false
|
||||
})
|
||||
console.log(err);
|
||||
}
|
||||
})
|
||||
},
|
||||
startSoterAuthenticationFaceID() {
|
||||
uni.startSoterAuthentication({
|
||||
requestAuthModes: ['facial'],
|
||||
challenge: '123456',
|
||||
authContent: '请用FaceID解锁',
|
||||
success(res) {
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: 'FaceID验证成功'
|
||||
})
|
||||
console.log(res);
|
||||
},
|
||||
fail(err) {
|
||||
uni.showModal({
|
||||
content: 'FaceID验证失败,errCode:' + err.errCode,
|
||||
showCancel: false
|
||||
})
|
||||
console.log(err);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style></style>
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="uni-btn-v"><button type="primary" @click="openDB">打开数据库test.db</button></view>
|
||||
<view class="uni-btn-v"><button type="primary" @click="executeSQL">创建表database及插入数据</button></view>
|
||||
<view class="uni-btn-v"><button type="primary" @click="selectSQL">查询表database的数据</button></view>
|
||||
<view class="uni-btn-v"><button type="primary" @click="droptable">删除表database</button></view>
|
||||
<view class="uni-btn-v"><button type="primary" @click="closeDB">关闭数据库test.db</button></view>
|
||||
<view class="uni-btn-v"><button type="primary" @click="isOpenDB">查询是否打开数据库</button></view>
|
||||
|
||||
|
||||
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'SQLite'
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
openDB: function() {
|
||||
plus.sqlite.openDatabase({
|
||||
name: 'first',
|
||||
path: '_doc/test.db',
|
||||
success: function(e) {
|
||||
plus.nativeUI.alert('打开数据库test.db成功 ');
|
||||
},
|
||||
fail: function(e) {
|
||||
plus.nativeUI.alert('打开数据库test.db失败: ' + JSON.stringify(e));
|
||||
}
|
||||
});
|
||||
},
|
||||
// 执行SQL语句
|
||||
executeSQL: function() {
|
||||
plus.sqlite.executeSql({
|
||||
name: 'first',
|
||||
sql: 'create table if not exists database("name" CHAR(110),"sex" CHAR(10),"age" INT(11))',
|
||||
success: function(e) {
|
||||
plus.sqlite.executeSql({
|
||||
name: 'first',
|
||||
sql: "insert into database values('彦','女','7000')",
|
||||
success: function(e) {
|
||||
plus.nativeUI.alert('创建表table和插入数据成功');
|
||||
},
|
||||
fail: function(e) {
|
||||
plus.nativeUI.alert('创建表table成功但插入数据失败: ' + JSON.stringify(e));
|
||||
}
|
||||
});
|
||||
},
|
||||
fail: function(e) {
|
||||
plus.nativeUI.alert('创建表table失败: ' + JSON.stringify(e));
|
||||
}
|
||||
});
|
||||
},
|
||||
// 查询SQL语句
|
||||
selectSQL: function() {
|
||||
plus.sqlite.selectSql({
|
||||
name: 'first',
|
||||
sql: 'select * from database',
|
||||
success: function(e) {
|
||||
plus.nativeUI.alert('查询SQL语句成功: ' + JSON.stringify(e));
|
||||
},
|
||||
fail: function(e) {
|
||||
plus.nativeUI.alert('查询SQL语句失败: ' + JSON.stringify(e));
|
||||
}
|
||||
});
|
||||
},
|
||||
// 删除表
|
||||
droptable: function() {
|
||||
plus.sqlite.executeSql({
|
||||
name: 'first',
|
||||
sql: 'drop table database',
|
||||
success: function(e) {
|
||||
plus.nativeUI.alert('删除表database成功');
|
||||
},
|
||||
fail: function(e) {
|
||||
plus.nativeUI.alert('删除表database失败: ' + JSON.stringify(e));
|
||||
}
|
||||
});
|
||||
},
|
||||
// 关闭数据库
|
||||
closeDB: function() {
|
||||
plus.sqlite.closeDatabase({
|
||||
name: 'first',
|
||||
success: function(e) {
|
||||
plus.nativeUI.alert('关闭数据库成功');
|
||||
},
|
||||
fail: function(e) {
|
||||
plus.nativeUI.alert('关闭数据库失败: ' + JSON.stringify(e));
|
||||
}
|
||||
});
|
||||
},
|
||||
isOpenDB: function() {
|
||||
if (
|
||||
plus.sqlite.isOpenDatabase({
|
||||
name: 'first',
|
||||
path: '_doc/test.db'
|
||||
})
|
||||
) {
|
||||
plus.nativeUI.alert('Opened!');
|
||||
} else {
|
||||
plus.nativeUI.alert('Unopened!');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-btn-v {
|
||||
margin: 20rpx 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-common-mt">
|
||||
<view class="uni-list">
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">key</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" placeholder="请输入key" name="key" :value="key" @input="keyChange"/>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">value</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-db">
|
||||
<input class="uni-input" type="text" placeholder="请输入value" name="data" :value="data" @input="dataChange"/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-btn-v">
|
||||
<button type="primary" class="btn-setstorage" @tap="setStorage">存储数据</button>
|
||||
<button @tap="getStorage">读取数据</button>
|
||||
<button @tap="clearStorage">清理数据</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'get/set/clearStorage',
|
||||
key: '',
|
||||
data: ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
keyChange: function (e) {
|
||||
this.key = e.detail.value
|
||||
},
|
||||
dataChange: function (e) {
|
||||
this.data = e.detail.value
|
||||
},
|
||||
getStorage: function () {
|
||||
var key = this.key,
|
||||
data = this.data;
|
||||
if (key.length === 0) {
|
||||
uni.showModal({
|
||||
title: '读取数据失败',
|
||||
content: "key 不能为空",
|
||||
showCancel:false
|
||||
})
|
||||
} else {
|
||||
uni.getStorage({
|
||||
key: key,
|
||||
success: (res) => {
|
||||
uni.showModal({
|
||||
title: '读取数据成功',
|
||||
content: "data: '" + res.data + "'",
|
||||
showCancel:false
|
||||
})
|
||||
},
|
||||
fail: () => {
|
||||
uni.showModal({
|
||||
title: '读取数据失败',
|
||||
content: "找不到 key 对应的数据",
|
||||
showCancel:false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
setStorage: function () {
|
||||
var key = this.key
|
||||
var data = this.data
|
||||
if (key.length === 0) {
|
||||
uni.showModal({
|
||||
title: '保存数据失败',
|
||||
content: 'key 不能为空',
|
||||
showCancel:false
|
||||
})
|
||||
} else {
|
||||
uni.setStorage({
|
||||
key: key,
|
||||
data: data,
|
||||
success: (res) => {
|
||||
uni.showModal({
|
||||
title: '存储数据成功',
|
||||
// #ifndef MP-ALIPAY
|
||||
content: JSON.stringify(res.errMsg),
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
content: data,
|
||||
// #endif
|
||||
showCancel:false
|
||||
})
|
||||
},
|
||||
fail: () => {
|
||||
uni.showModal({
|
||||
title: '储存数据失败!',
|
||||
showCancel:false
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
clearStorage: function () {
|
||||
uni.clearStorageSync()
|
||||
this.key = '',
|
||||
this.data = ''
|
||||
uni.showModal({
|
||||
title: '清除数据成功',
|
||||
content: ' ',
|
||||
showCancel:false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.btn-setstorage {
|
||||
background-color: #007aff;
|
||||
color: #ffffff;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
<template>
|
||||
<view class="content">
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="example">
|
||||
<view class="example-title">从左侧滑出</view>
|
||||
<button @click="showDrawer">显示抽屉</button>
|
||||
</view>
|
||||
<view class="example">
|
||||
<view class="example-title">从上侧竖向滑出</view>
|
||||
<button @click="showPopup">显示 弹出层</button>
|
||||
</view>
|
||||
<view style="width: 100%;">
|
||||
<video v-if="showVideo" id="video"
|
||||
@play="playVideo"
|
||||
@pause="closeMask"
|
||||
:controls="false"
|
||||
src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/%E7%AC%AC1%E8%AE%B2%EF%BC%88uni-app%E4%BA%A7%E5%93%81%E4%BB%8B%E7%BB%8D%EF%BC%89-%20DCloud%E5%AE%98%E6%96%B9%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B@20181126-lite.m4v"
|
||||
@error="videoErrorCallback" poster="https://web-assets.dcloud.net.cn/unidoc/zh/poster.png"></video>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'SubNvue',
|
||||
showVideo: false
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.closeMask();
|
||||
|
||||
// 接收 popup 的消息
|
||||
uni.$on('popup-page', (data) => {
|
||||
switch(data.type){
|
||||
case 'interactive':
|
||||
uni.showModal({
|
||||
title: '来自Popup的消息',
|
||||
content: data.info
|
||||
})
|
||||
break;
|
||||
default:
|
||||
uni.showToast({
|
||||
title: data.title,
|
||||
})
|
||||
break;
|
||||
}
|
||||
})
|
||||
// 监听 drawer 消息
|
||||
uni.$on('drawer-page', (data) => {
|
||||
uni.showToast({
|
||||
title: '点击了第' + data + '项',
|
||||
icon:"none"
|
||||
});
|
||||
})
|
||||
},
|
||||
onUnload() {
|
||||
uni.$off('popup-page')
|
||||
uni.$off('drawer-page')
|
||||
},
|
||||
onReady() {
|
||||
this.showVideo = true
|
||||
},
|
||||
methods: {
|
||||
showDrawer() {
|
||||
uni.getSubNVueById('drawer').show('slide-in-left', 200);
|
||||
},
|
||||
showPopup() {
|
||||
// 向 popup 传递消息
|
||||
uni.$emit('page-popup', {
|
||||
title: '请阅读软件内容',
|
||||
content: 'uni-app 是一个使用 Vue.js 开发跨平台应用的前端框架,开发者编写一套代码,可编译到iOS、Android、H5、小程序等多个平台。'
|
||||
});
|
||||
const subNVue = uni.getSubNVueById('popup')
|
||||
subNVue.show('slide-in-top', 250)
|
||||
},
|
||||
videoErrorCallback: function() {
|
||||
uni.showModal({
|
||||
content: '视频加载失败',
|
||||
showCancel: false
|
||||
})
|
||||
},
|
||||
playVideo() {
|
||||
let subNVue = uni.getSubNVueById('video_mask')
|
||||
subNVue.show('fade-in', 200, () => {
|
||||
uni.$emit('play-video', {
|
||||
status: 'open',
|
||||
})
|
||||
})
|
||||
},
|
||||
closeMask() {
|
||||
let subNVue = uni.getSubNVueById('video_mask')
|
||||
uni.$emit('close-video', {
|
||||
status: 'close',
|
||||
})
|
||||
subNVue.hide('fade-out', 200)
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
align-content: center;
|
||||
height: 100%;
|
||||
background-color: #F4F5F6;
|
||||
}
|
||||
.example {
|
||||
padding: 0 10px 10px
|
||||
}
|
||||
.example-title {
|
||||
font-size: 14px;
|
||||
line-height: 14px;
|
||||
color: #777;
|
||||
margin: 40px 2rpx;
|
||||
position: relative
|
||||
}
|
||||
video {
|
||||
position: absolute;
|
||||
bottom: 30px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 200px;
|
||||
}
|
||||
.example .example-title {
|
||||
margin: 40rpx 0
|
||||
}
|
||||
button {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
.title {
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
color: #8f8f94;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
<template>
|
||||
<div class="wrapper">
|
||||
<text class="nav-text">左侧列表</text>
|
||||
<list class="list-wrapper">
|
||||
<cell v-for="item in lists" :key="item.id">
|
||||
<div class="text-wrapper" @click="clickitem(item.id)">
|
||||
<text style="font-size: 30rpx; ">{{item.name}}</text>
|
||||
<text class="icon"></text>
|
||||
</div>
|
||||
</cell>
|
||||
</list>
|
||||
<div style="flex: 1; text-align: center;">
|
||||
<div class="close-drawer" @click="hideDrawer">
|
||||
<text style="font-size: 34rpx; text-align: center;">关闭抽屉</text>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
lists: [],
|
||||
}
|
||||
},
|
||||
beforeCreate() {
|
||||
const domModule = weex.requireModule('dom')
|
||||
domModule.addRule('fontFace', {
|
||||
fontFamily: "unibtn",
|
||||
'src': "url('../../../../static/uni.ttf')"
|
||||
});
|
||||
},
|
||||
created() {
|
||||
for(let i = 0; i < 5; i++){
|
||||
this.lists.push({
|
||||
id: i,
|
||||
name: 'Item' + i,
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
hideDrawer() {
|
||||
uni.getCurrentSubNVue().hide('auto')
|
||||
},
|
||||
clickitem(e) {
|
||||
uni.$emit('drawer-page', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.wrapper {
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
padding: 60rpx 0rpx 0rpx 20rpx;
|
||||
background-color: #F4F5F6;
|
||||
}
|
||||
.nav-text {
|
||||
color: #8f8f94;
|
||||
/* #ifndef APP-PLUS-NVUE */
|
||||
margin-bottom: 40px;
|
||||
/* #endif */
|
||||
/* #ifdef APP-PLUS-NVUE */
|
||||
margin-bottom: 40rpx;
|
||||
/* #endif */
|
||||
}
|
||||
.list-wrapper {
|
||||
/* #ifdef APP-PLUS-NVUE */
|
||||
height: 450rpx;
|
||||
/* #endif */
|
||||
/* #ifndef APP-PLUS-NVUE */
|
||||
height: 450px;
|
||||
/* #endif */
|
||||
}
|
||||
.text-wrapper {
|
||||
justify-content: center;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 1rpx;
|
||||
border-bottom-color: rgba(0,0,0,.2);
|
||||
margin-bottom: 35rpx;
|
||||
padding-bottom: 15rpx;
|
||||
}
|
||||
.close-drawer {
|
||||
background-color: #f8f8f8;
|
||||
width: 300rpx;
|
||||
padding: 15rpx;
|
||||
border-radius: 20rpx;
|
||||
border-style: solid;
|
||||
border-width: 1rpx;
|
||||
border-color: rgba(0,0,0,.2);
|
||||
}
|
||||
.icon {
|
||||
position: absolute;
|
||||
right: 10rpx;
|
||||
color: #000000;
|
||||
font-family: unibtn;
|
||||
font-size: 30rpx;
|
||||
font-weight: 400;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
<template>
|
||||
<div class="wrapper">
|
||||
<text class="title">{{title}}</text>
|
||||
<scroller class="scroller">
|
||||
<div>
|
||||
<text class="content">{{content}}</text>
|
||||
</div>
|
||||
<div>
|
||||
<text style="color: red; font-size: 30rpx;">以下为 Popup 内部滚动示例:</text>
|
||||
</div>
|
||||
<div class="cell" v-for="(item, index) in lists" @click="handle(item)" :key="index">
|
||||
<text class="text">{{item}}</text>
|
||||
</div>
|
||||
</scroller>
|
||||
<div class="message-wrapper">
|
||||
<text class="send-message" @click="sendMessage">向页面发送消息</text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: '',
|
||||
content: '',
|
||||
lists: [],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const vm = this;
|
||||
for (let i = 1; i < 20; i++) {
|
||||
this.lists.push('item' + i);
|
||||
}
|
||||
uni.$on('page-popup', (data) => {
|
||||
vm.title = data.title;
|
||||
vm.content = data.content;
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
uni.$off('drawer-page')
|
||||
},
|
||||
methods: {
|
||||
sendMessage() {
|
||||
const subNVue = uni.getCurrentSubNVue()
|
||||
uni.$emit('popup-page', {
|
||||
title: '已读完!',
|
||||
})
|
||||
},
|
||||
handle(item, index) {
|
||||
const subNVue = uni.getCurrentSubNVue()
|
||||
uni.$emit('popup-page', {
|
||||
type: 'interactive',
|
||||
info: item + ' 该元素被点击了!',
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.wrapper {
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
padding: 10rpx 15rpx;
|
||||
background-color: #F4F5F6;
|
||||
border-radius: 4rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
height: 100rpx;
|
||||
line-height: 100rpx;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 1rpx;
|
||||
border-bottom-color: #CBCBCB;
|
||||
flex: 0;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.scroller {
|
||||
height: 400rpx;
|
||||
padding: 8rpx 15rpx;
|
||||
}
|
||||
|
||||
.content {
|
||||
color: #555555;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.message-wrapper {
|
||||
flex: 0;
|
||||
border-top-style: solid;
|
||||
border-top-width: 1rpx;
|
||||
border-top-color: #CBCBCB;
|
||||
height: 80rpx;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.send-message {
|
||||
font-size: 30rpx;
|
||||
line-height: 80rpx;
|
||||
color: #00CE47;
|
||||
margin-left: 20rpx;
|
||||
}
|
||||
|
||||
.cell {
|
||||
margin: 10rpx;
|
||||
padding: 20rpx 0;
|
||||
top: 10rpx;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 10rpx;
|
||||
background-color: #5989B9;
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 30rpx;
|
||||
text-align: center;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
<template>
|
||||
<div class="wrapper">
|
||||
<list class="list">
|
||||
<cell v-for="(item, index) in lists" :key="index" :ref="'item' + index" class="cell">
|
||||
<text class="name">{{item.name}}:</text>
|
||||
<text class="content">{{item.content}}</text>
|
||||
</cell>
|
||||
</list>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
lists: [],
|
||||
interval: null,
|
||||
yourTexts: [
|
||||
{
|
||||
name: '学员A',
|
||||
content: '老师讲的真好',
|
||||
}, {
|
||||
name: '学员B',
|
||||
content: 'uni-app值得学习',
|
||||
}, {
|
||||
name: '学员C',
|
||||
content: '老师,还有实战例子吗?',
|
||||
}, {
|
||||
name: '学员D',
|
||||
content: '老师,请问是不是要先学会vue才能学uni-app?',
|
||||
}, {
|
||||
name: '学员E',
|
||||
content: '受教了,uni-app太牛了',
|
||||
}
|
||||
],
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const vm = this;
|
||||
uni.$on('play-video', (data) => {
|
||||
if(data.status === 'open'){
|
||||
this.addItem();
|
||||
}else{
|
||||
this.closeItem();
|
||||
}
|
||||
})
|
||||
},
|
||||
beforeDestroy(){
|
||||
uni.$off('play-video')
|
||||
this.closeItem()
|
||||
},
|
||||
methods: {
|
||||
addItem() {
|
||||
const vm = this;
|
||||
vm.lists = [{
|
||||
name: '学员E',
|
||||
content: '受教了,uni-app太牛了',
|
||||
}];
|
||||
const dom = weex.requireModule('dom')
|
||||
vm.interval = setInterval(() => {
|
||||
if(vm.lists.length > 15) {
|
||||
vm.lists.unshift();
|
||||
}
|
||||
vm.lists.push({
|
||||
name: vm.yourTexts[vm.lists.length%4].name,
|
||||
content: vm.yourTexts[vm.lists.length%4].content
|
||||
});
|
||||
if(vm.lists.length > 5) {
|
||||
vm.$nextTick(() => {
|
||||
if(vm.$refs['item' + (vm.lists.length - 1)]){
|
||||
dom.scrollToElement(vm.$refs['item' + (vm.lists.length - 1)][0]);
|
||||
}
|
||||
});
|
||||
}
|
||||
}, 3500);
|
||||
},
|
||||
closeItem() {
|
||||
if(this.interval) clearInterval(this.interval);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.wrapper {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
background-color: transparent;
|
||||
}
|
||||
.list {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
.cell {
|
||||
padding: 10rpx 0;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
.name {
|
||||
flex: 0;
|
||||
font-size: 20rpx;
|
||||
margin-right: 20rpx;
|
||||
color: #FF5A5F;
|
||||
}
|
||||
.content {
|
||||
flex: 1;
|
||||
font-size: 20rpx;
|
||||
color: #F4F5F6;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-btn-v">
|
||||
<button type="default" @tap="toast1Tap">点击弹出默认toast</button>
|
||||
<button type="default" @tap="toast2Tap">点击弹出设置duration的toast</button>
|
||||
<button type="default" @tap="toast3Tap">点击弹出显示loading的toast</button>
|
||||
<!-- #ifndef MP-ALIPAY -->
|
||||
<button type="default" @tap="toast4Tap">点击弹出显示自定义图片的toast</button>
|
||||
<!-- #endif -->
|
||||
<!-- #ifdef APP-PLUS -->
|
||||
<button type="default" @tap="toast5Tap">点击显示无图标的居底toast</button>
|
||||
<!-- #endif -->
|
||||
<button type="default" @tap="hideToast">点击隐藏toast</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'toast'
|
||||
}
|
||||
},
|
||||
// #ifdef MP-ALIPAY
|
||||
onUnload() {
|
||||
this._showTimer && clearTimeout(this._showTimer);
|
||||
},
|
||||
// #endif
|
||||
methods: {
|
||||
toast1Tap: function () {
|
||||
uni.showToast({
|
||||
title: "默认"
|
||||
})
|
||||
},
|
||||
toast2Tap: function () {
|
||||
uni.showToast({
|
||||
title: "duration 3000",
|
||||
duration: 3000
|
||||
})
|
||||
},
|
||||
toast3Tap: function () {
|
||||
uni.showToast({
|
||||
title: "loading",
|
||||
icon: "loading",
|
||||
duration: 5000
|
||||
})
|
||||
// #ifdef MP-ALIPAY
|
||||
this._showTimer = setTimeout(() => {
|
||||
// icon 是 loading 时,showToast 实际执行的是 showLoading
|
||||
my.hideLoading()
|
||||
// 执行完所有代码再清除定时器
|
||||
clearTimeout(this._showTimer);
|
||||
}, 3000)
|
||||
// #endif
|
||||
|
||||
},
|
||||
toast4Tap: function () {
|
||||
uni.showToast({
|
||||
title: "logo",
|
||||
image: "../../../static/uni.png"
|
||||
})
|
||||
},
|
||||
// #ifdef APP-PLUS
|
||||
toast5Tap: function () {
|
||||
uni.showToast({
|
||||
title: "显示一段轻提示",
|
||||
position:'bottom'
|
||||
})
|
||||
},
|
||||
// #endif
|
||||
hideToast: function () {
|
||||
uni.hideToast()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap uni-common-mt">
|
||||
<view class="demo">
|
||||
<block v-if="imageSrc">
|
||||
<image :src="imageSrc" class="image" mode="widthFix"></image>
|
||||
</block>
|
||||
<block v-else>
|
||||
<view class="uni-hello-addfile" @click="chooseImage">+ 选择图片</view>
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'uploadFile',
|
||||
imageSrc: ''
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
this.imageSrc = '';
|
||||
},
|
||||
methods: {
|
||||
chooseImage: function() {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sizeType: ['compressed'],
|
||||
sourceType: ['album'],
|
||||
success: (res) => {
|
||||
console.log('chooseImage success, temp path is', res.tempFilePaths[0])
|
||||
var imageSrc = res.tempFilePaths[0]
|
||||
uni.uploadFile({
|
||||
url: 'https://unidemo.dcloud.net.cn/upload',
|
||||
filePath: imageSrc,
|
||||
fileType: 'image',
|
||||
name: 'data',
|
||||
success: (res) => {
|
||||
console.log('uploadImage success, res is:', res)
|
||||
uni.showToast({
|
||||
title: '上传成功',
|
||||
icon: 'success',
|
||||
duration: 1000
|
||||
})
|
||||
this.imageSrc = imageSrc
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('uploadImage fail', err);
|
||||
uni.showModal({
|
||||
content: err.errMsg,
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('chooseImage fail', err)
|
||||
// #ifdef MP
|
||||
uni.getSetting({
|
||||
success: (res) => {
|
||||
let authStatus = res.authSetting['scope.album'];
|
||||
if (!authStatus) {
|
||||
uni.showModal({
|
||||
title: '授权失败',
|
||||
content: 'Hello uni-app需要从您的相册获取图片,请在设置界面打开相关权限',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.openSetting()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.image {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.demo {
|
||||
background: #FFF;
|
||||
padding: 50rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<button class="uni-button" type="primary" @click="longshock">长震动</button>
|
||||
<button class="uni-button" @click="shortshock">短震动</button>
|
||||
|
||||
<view class="uni-tips">
|
||||
<view>Tips</view>
|
||||
<view class="uni-tips-text">iOS上只有长震动,没有短震动</view>
|
||||
<view class="uni-tips-text">iOS上需要手机设置“打开响铃时震动”或“静音时震动”,否则无法震动</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'vibrateLong/vibrateShort'
|
||||
};
|
||||
},
|
||||
onLoad() {},
|
||||
methods: {
|
||||
longshock() {
|
||||
uni.vibrateLong({
|
||||
success: function() {
|
||||
console.log('success');
|
||||
}
|
||||
});
|
||||
},
|
||||
shortshock() {
|
||||
uni.vibrateShort({
|
||||
success: function() {
|
||||
console.log('success');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-padding-wrap {
|
||||
margin-top: 50rpx 0;
|
||||
}
|
||||
.uni-button {
|
||||
margin: 30rpx 0;
|
||||
}
|
||||
.uni-tips {
|
||||
color: #666;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
.uni-tips-text {
|
||||
margin-top: 15rpx;
|
||||
line-height: 1.2;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<view class="uni-common-mt">
|
||||
<view class="uni-list">
|
||||
<view class="uni-list-cell">
|
||||
<view class="uni-list-cell-left">
|
||||
<view class="uni-label">视频来源</view>
|
||||
</view>
|
||||
<view class="uni-list-cell-right">
|
||||
<picker :range="sourceType" @change="sourceTypeChange" :value="sourceTypeIndex">
|
||||
<view class="uni-input">{{sourceType[sourceTypeIndex]}}</view>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #ifdef APP-PLUS || MP-WEIXIN -->
|
||||
<view class="uni-title uni-common-mt uni-common-pl">摄像头位置</view>
|
||||
<view class="uni-hello-text camera-tips">注意:部分 Android 手机下由于系统 ROM 不支持无法生效,打开拍摄界面后可操作切换</view>
|
||||
<view class="uni-list">
|
||||
<radio-group @change="radioChange">
|
||||
<label class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in cameraList" :key="item.value">
|
||||
<radio :value="item.value" :checked="index === cameraIndex">{{item.name}}</radio>
|
||||
</label>
|
||||
</radio-group>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<template v-if="!src">
|
||||
<view class="uni-hello-addfile" @tap="chooseVideo">+ 添加视频</view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<video :src="src" class="video"></video>
|
||||
</template>
|
||||
</view>
|
||||
</template>
|
||||
<script>
|
||||
var sourceType = [
|
||||
['camera'],
|
||||
['album'],
|
||||
['camera', 'album']
|
||||
]
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'chooseVideo',
|
||||
sourceTypeIndex: 2,
|
||||
sourceType: ['拍摄', '相册', '拍摄或相册'],
|
||||
src: '',
|
||||
cameraList: [{
|
||||
value: 'back',
|
||||
name: '后置摄像头',
|
||||
checked: 'true'
|
||||
},
|
||||
{
|
||||
value: 'front',
|
||||
name: '前置摄像头'
|
||||
},
|
||||
],
|
||||
cameraIndex: 0
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
this.src = '',
|
||||
this.sourceTypeIndex = 2,
|
||||
this.sourceType = ['拍摄', '相册', '拍摄或相册'];
|
||||
},
|
||||
methods: {
|
||||
radioChange(evt) {
|
||||
for (let i = 0; i < this.cameraList.length; i++) {
|
||||
if (this.cameraList[i].value === evt.detail.value) {
|
||||
this.cameraIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
sourceTypeChange: function(e) {
|
||||
this.sourceTypeIndex = parseInt(e.detail.value)
|
||||
},
|
||||
chooseVideo: function() {
|
||||
uni.chooseVideo({
|
||||
camera: this.cameraList[this.cameraIndex].value,
|
||||
sourceType: sourceType[this.sourceTypeIndex],
|
||||
success: (res) => {
|
||||
this.src = res.tempFilePath
|
||||
},
|
||||
fail: (err) => {
|
||||
// #ifdef MP
|
||||
uni.getSetting({
|
||||
success: (res) => {
|
||||
let authStatus = false;
|
||||
switch (this.sourceTypeIndex) {
|
||||
case 0:
|
||||
authStatus = res.authSetting['scope.camera'];
|
||||
break;
|
||||
case 1:
|
||||
authStatus = res.authSetting['scope.album'];
|
||||
break;
|
||||
case 2:
|
||||
authStatus = res.authSetting['scope.album'] && res.authSetting['scope.camera'];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (!authStatus) {
|
||||
uni.showModal({
|
||||
title: '授权失败',
|
||||
content: 'Hello uni-app需要从您的相机或相册获取视频,请在设置界面打开相关权限',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.openSetting()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
// #endif
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.video {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.camera-tips {
|
||||
padding: 10rpx 30rpx;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,243 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head :title="title"></page-head>
|
||||
<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"></view>
|
||||
<view class="page-body-button" @click="startRecord">
|
||||
<image src="../../../static/record.png"></image>
|
||||
</view>
|
||||
<view class="page-body-button"></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"></view>
|
||||
<view class="page-body-button" @click="stopRecord">
|
||||
<view class="button-stop-record"></view>
|
||||
</view>
|
||||
<view class="page-body-button"></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
|
||||
import * as util from '../../../common/util.js'
|
||||
var playTimeInterval = null;
|
||||
var recordTimeInterval = null;
|
||||
var recorderManager = null;
|
||||
var music = null;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
title: 'start/stopRecord、play/stopVoice',
|
||||
recording: false, //录音中
|
||||
playing: false, //播放中
|
||||
hasRecord: false, //是否有了一个
|
||||
tempFilePath: '',
|
||||
recordTime: 0,
|
||||
playTime: 0,
|
||||
formatedRecordTime: '00:00:00', //录音的总时间
|
||||
formatedPlayTime: '00:00:00' //播放录音的当前时间
|
||||
}
|
||||
},
|
||||
onUnload: function() {
|
||||
this.end();
|
||||
},
|
||||
onLoad: function() {
|
||||
music = uni.createInnerAudioContext();
|
||||
music.onEnded(() => {
|
||||
clearInterval(playTimeInterval)
|
||||
var playTime = 0
|
||||
console.log('play voice finished')
|
||||
this.playing = false;
|
||||
this.formatedPlayTime = util.formatTime(playTime);
|
||||
this.playTime = playTime;
|
||||
});
|
||||
recorderManager = uni.getRecorderManager();
|
||||
recorderManager.onStart(() => {
|
||||
console.log('recorder start');
|
||||
|
||||
this.recording = true;
|
||||
recordTimeInterval = setInterval(() => {
|
||||
this.recordTime += 1;
|
||||
this.formatedRecordTime = util.formatTime(this.recordTime);
|
||||
}, 1000)
|
||||
});
|
||||
recorderManager.onStop((res) => {
|
||||
console.log('on stop');
|
||||
music.src = res.tempFilePath;
|
||||
|
||||
this.hasRecord = true;
|
||||
this.recording = false;
|
||||
});
|
||||
recorderManager.onError(() => {
|
||||
console.log('recorder onError');
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
async startRecord() { //开始录音
|
||||
// #ifdef APP-PLUS
|
||||
let status = await this.checkPermission();
|
||||
if (status !== 1) {
|
||||
return;
|
||||
}
|
||||
// #endif
|
||||
|
||||
// TODO ios 在没有请求过权限之前无法得知是否有相关权限,这种状态下需要直接调用录音,但没有状态或回调判断用户拒绝
|
||||
recorderManager.start({
|
||||
format: 'mp3'
|
||||
});
|
||||
},
|
||||
stopRecord() { //停止录音
|
||||
recorderManager.stop();
|
||||
clearInterval(recordTimeInterval);
|
||||
},
|
||||
playVoice() {
|
||||
console.log('play voice');
|
||||
this.playing = true;
|
||||
playTimeInterval = setInterval(() => {
|
||||
this.playTime += 1;
|
||||
this.formatedPlayTime = util.formatTime(this.playTime);
|
||||
}, 1000)
|
||||
music.play();
|
||||
},
|
||||
stopVoice() {
|
||||
clearInterval(playTimeInterval)
|
||||
this.playing = false;
|
||||
this.formatedPlayTime = util.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>
|
||||
image {
|
||||
width: 150rpx;
|
||||
height: 150rpx;
|
||||
}
|
||||
|
||||
.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: 60rpx;
|
||||
margin: 20rpx;
|
||||
}
|
||||
|
||||
.time-small {
|
||||
font-size: 30rpx;
|
||||
}
|
||||
|
||||
.page-body-buttons {
|
||||
margin-top: 60rpx;
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.page-body-button {
|
||||
width: 250rpx;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.button-stop-record {
|
||||
width: 110rpx;
|
||||
height: 110rpx;
|
||||
border: 20rpx solid #fff;
|
||||
background-color: #f55c23;
|
||||
border-radius: 130rpx;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head title="websocket通讯示例"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-btn-v">
|
||||
<view class="websocket-msg">{{showMsg}}</view>
|
||||
<button type="primary" @click="connect">连接websocket服务</button>
|
||||
<button v-show="connected" type="primary" @click="send">发送一条消息</button>
|
||||
<button type="primary" @click="close">断开websocket服务</button>
|
||||
<view class="websocket-tips">发送消息后会收到一条服务器返回的消息(与发送的消息内容一致)</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
let platform = uni.getSystemInfoSync().platform
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
connected: false,
|
||||
connecting: false,
|
||||
msg: false,
|
||||
roomId: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
showMsg() {
|
||||
if (this.connected) {
|
||||
if (this.msg) {
|
||||
return '收到消息:' + this.msg
|
||||
} else {
|
||||
return '等待接收消息'
|
||||
}
|
||||
} else {
|
||||
return '尚未连接'
|
||||
}
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
uni.closeSocket()
|
||||
uni.hideLoading()
|
||||
},
|
||||
methods: {
|
||||
connect() {
|
||||
if (this.connected || this.connecting) {
|
||||
uni.showModal({
|
||||
content: '正在连接或者已经连接,请勿重复连接',
|
||||
showCancel: false
|
||||
})
|
||||
return false
|
||||
}
|
||||
this.connecting = true
|
||||
uni.showLoading({
|
||||
title: '连接中...'
|
||||
})
|
||||
uni.connectSocket({
|
||||
url: 'wss://echo.websocket.org',
|
||||
data() {
|
||||
return {
|
||||
msg: 'Hello'
|
||||
}
|
||||
},
|
||||
// #ifdef MP
|
||||
header: {
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
method: 'GET',
|
||||
// #endif
|
||||
success(res) {
|
||||
// 这里是接口调用成功的回调,不是连接成功的回调,请注意
|
||||
},
|
||||
fail(err) {
|
||||
// 这里是接口调用失败的回调,不是连接失败的回调,请注意
|
||||
}
|
||||
})
|
||||
uni.onSocketOpen((res) => {
|
||||
this.connecting = false
|
||||
this.connected = true
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '连接成功'
|
||||
})
|
||||
console.log('onOpen', res);
|
||||
})
|
||||
uni.onSocketError((err) => {
|
||||
this.connecting = false
|
||||
this.connected = false
|
||||
uni.hideLoading()
|
||||
uni.showModal({
|
||||
content: '连接失败,可能是websocket服务不可用,请稍后再试',
|
||||
showCancel: false
|
||||
})
|
||||
console.log('onError', err);
|
||||
})
|
||||
uni.onSocketMessage((res) => {
|
||||
this.msg = res.data
|
||||
console.log('onMessage', res)
|
||||
})
|
||||
uni.onSocketClose((res) => {
|
||||
this.connected = false
|
||||
this.startRecive = false
|
||||
this.msg = false
|
||||
console.log('onClose', res)
|
||||
})
|
||||
},
|
||||
send() {
|
||||
uni.sendSocketMessage({
|
||||
data: 'from ' + platform + ' : ' + parseInt(Math.random() * 10000).toString(),
|
||||
success(res) {
|
||||
console.log(res);
|
||||
},
|
||||
fail(err) {
|
||||
console.log(err);
|
||||
}
|
||||
})
|
||||
},
|
||||
close() {
|
||||
uni.closeSocket()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.uni-btn-v {
|
||||
padding: 10rpx 0;
|
||||
}
|
||||
|
||||
.uni-btn-v button {
|
||||
margin: 20rpx 0;
|
||||
}
|
||||
|
||||
.websocket-room {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
border-bottom: solid 1px #DDDDDD;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.websocket-msg {
|
||||
padding: 40px 0px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
line-height: 40px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.websocket-tips{
|
||||
padding: 40px 0px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
color: #666666;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,160 @@
|
|||
<template>
|
||||
<view>
|
||||
<page-head title="websocket通讯示例"></page-head>
|
||||
<view class="uni-padding-wrap">
|
||||
<view class="uni-btn-v">
|
||||
<view class="websocket-msg">{{showMsg}}</view>
|
||||
<button type="primary" @click="connect">连接websocket服务</button>
|
||||
<button v-show="connected" type="primary" @click="send">发送一条消息</button>
|
||||
<button type="primary" @click="close">断开websocket服务</button>
|
||||
<view class="websocket-tips">发送消息后会收到一条服务器返回的消息(与发送的消息内容一致)</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
let platform = uni.getSystemInfoSync().platform
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
connected: false,
|
||||
connecting: false,
|
||||
socketTask: false,
|
||||
msg: false,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
showMsg() {
|
||||
if (this.connected) {
|
||||
if (this.msg) {
|
||||
return '收到消息:' + this.msg
|
||||
} else {
|
||||
return '等待接收消息'
|
||||
}
|
||||
} else {
|
||||
return '尚未连接'
|
||||
}
|
||||
}
|
||||
},
|
||||
onUnload() {
|
||||
uni.hideLoading()
|
||||
if (this.socketTask && this.socketTask.close) {
|
||||
this.socketTask.close()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
connect() {
|
||||
if (this.connected || this.connecting) {
|
||||
uni.showModal({
|
||||
content: '正在连接或者已经连接,请勿重复连接',
|
||||
showCancel: false
|
||||
})
|
||||
return false
|
||||
}
|
||||
this.connecting = true
|
||||
uni.showLoading({
|
||||
title: '连接中...'
|
||||
})
|
||||
this.socketTask = uni.connectSocket({
|
||||
url: 'wss://echo.websocket.org',
|
||||
data() {
|
||||
return {
|
||||
msg: 'Hello'
|
||||
}
|
||||
},
|
||||
// #ifdef MP
|
||||
header: {
|
||||
'content-type': 'application/json'
|
||||
},
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
method: 'GET',
|
||||
// #endif
|
||||
success(res) {
|
||||
// 这里是接口调用成功的回调,不是连接成功的回调,请注意
|
||||
},
|
||||
fail(err) {
|
||||
// 这里是接口调用失败的回调,不是连接失败的回调,请注意
|
||||
}
|
||||
})
|
||||
console.log(this.socketTask);
|
||||
this.socketTask.onOpen((res) => {
|
||||
this.connecting = false
|
||||
this.connected = true
|
||||
uni.hideLoading()
|
||||
uni.showToast({
|
||||
icon: 'none',
|
||||
title: '连接成功'
|
||||
})
|
||||
console.log('onOpen', res);
|
||||
})
|
||||
this.socketTask.onError((err) => {
|
||||
this.connecting = false
|
||||
this.connected = false
|
||||
uni.hideLoading()
|
||||
uni.showModal({
|
||||
content: '连接失败,可能是websocket服务不可用,请稍后再试',
|
||||
showCancel: false
|
||||
})
|
||||
console.log('onError', err);
|
||||
})
|
||||
this.socketTask.onMessage((res) => {
|
||||
this.msg = res.data
|
||||
console.log('onMessage', res)
|
||||
})
|
||||
this.socketTask.onClose((res) => {
|
||||
this.connected = false
|
||||
this.startRecive = false
|
||||
this.socketTask = false
|
||||
this.msg = false
|
||||
console.log('onClose', res)
|
||||
})
|
||||
console.log('task', this.socketTask)
|
||||
},
|
||||
send() {
|
||||
this.socketTask.send({
|
||||
data: 'from ' + platform + ' : ' + parseInt(Math.random() * 10000).toString(),
|
||||
success(res) {
|
||||
console.log(res);
|
||||
},
|
||||
fail(err) {
|
||||
console.log(err);
|
||||
}
|
||||
})
|
||||
},
|
||||
close() {
|
||||
if (this.socketTask && this.socketTask.close) {
|
||||
this.socketTask.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
.uni-btn-v {
|
||||
padding: 10rpx 0;
|
||||
}
|
||||
|
||||
.uni-btn-v button {
|
||||
margin: 20rpx 0;
|
||||
}
|
||||
|
||||
.websocket-msg {
|
||||
padding: 40px 0px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
line-height: 40px;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.websocket-tips{
|
||||
padding: 40px 0px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
color: #666666;
|
||||
}
|
||||
</style>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue