commit
1fe04ebefa
91 changed files with 12008 additions and 0 deletions
@ -0,0 +1,23 @@ |
|||
/* |
|||
* Copyright (c) 2019. |
|||
* author: wally |
|||
* email: 18603454788@163.com |
|||
*/ |
|||
|
|||
module.exports = { |
|||
root: true, |
|||
|
|||
env: { browser: true, node: true }, |
|||
extends: ['plugin:vue/recommended', 'plugin:vue/essential', '@vue/prettier'], |
|||
rules: { |
|||
'vue/html-self-closing': 'off', |
|||
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', |
|||
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', |
|||
'no-param-reassign': ['error', { props: true, ignorePropertyModificationsFor: ['state'] }], |
|||
'max-len': ['error', { code: 120, tabWidth: 2 }], |
|||
'object-curly-newline': ['error', { multiline: true }], |
|||
'arrow-parens': ['error', 'as-needed'], |
|||
}, |
|||
|
|||
parserOptions: { parser: 'babel-eslint' }, |
|||
}; |
@ -0,0 +1,17 @@ |
|||
.DS_Store |
|||
node_modules/ |
|||
dist/ |
|||
unpackage/ |
|||
unpackage/* |
|||
|
|||
npm-debug.log* |
|||
yarn-debug.log* |
|||
yarn-error.log* |
|||
|
|||
# Editor directories and files |
|||
.idea |
|||
.vscode |
|||
*.suo |
|||
*.ntvs* |
|||
*.njsproj |
|||
*.sln |
@ -0,0 +1,12 @@ |
|||
{ |
|||
"printWidth": 100, |
|||
"singleQuote": true, |
|||
"semi": true, |
|||
"trailingComma": "all", |
|||
"arrowParens": "avoid", |
|||
"tabWidth": 2, |
|||
"useTabs": false, |
|||
"bracketSpacing": true, |
|||
"jsxBracketSameLine": false, |
|||
"proseWrap": "always" |
|||
} |
@ -0,0 +1,31 @@ |
|||
<script> |
|||
import { mapState, mapMutations, mapActions } from 'vuex'; |
|||
|
|||
export default { |
|||
async onLaunch(options) { |
|||
|
|||
}, |
|||
created () { |
|||
//在页面加载时读取sessionStorage里的状态信息 |
|||
if (sessionStorage.getItem("store") ) { |
|||
this.$store.replaceState(Object.assign({}, this.$store.state,JSON.parse(sessionStorage.getItem("store")))) |
|||
} |
|||
//在页面刷新时将vuex里的信息保存到sessionStorage里 |
|||
window.addEventListener("beforeunload",()=>{ |
|||
sessionStorage.setItem("store",JSON.stringify(this.$store.state)) |
|||
}) |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
@import 'colorui/main.scss'; |
|||
@import 'colorui/icon.scss'; |
|||
@import 'colorui/animation.scss'; |
|||
@import 'common/style/global'; |
|||
@import 'common/style/iconfont'; |
|||
body{ |
|||
background: $white; |
|||
padding-bottom: 100px; |
|||
} |
|||
</style> |
@ -0,0 +1,111 @@ |
|||
# uni-templete使用说明 |
|||
|
|||
## 环境准备 |
|||
|
|||
+ 使用HbuilderX作为构建开发环境, 主要使用HX的编译环境, 也可以使用vscode编码 + HX编译的搭配 |
|||
+ HX需要安装插件 |
|||
+ es6编译 |
|||
+ Eslint-js |
|||
+ Eslint-plugin-vue |
|||
+ git |
|||
+ prettier |
|||
+ **Scss/sass编译** |
|||
+ 微信小程序开发工具 |
|||
+ appId申请 |
|||
|
|||
## 目录说明 |
|||
|
|||
+ **api** |
|||
|
|||
+ api接口统一管理文件夹,不允许在组件中直接定义api地址,必须在api文件夹下进行统一管理 |
|||
+ 不同的模块,分成不同的js文件进行管理 |
|||
+ 采用`export const signin = params => http.post('/api/xxx', params);`格式,封装请求方法及请求地址,方便统一管理 |
|||
|
|||
+ **colorui** colorui样式库引入,如果不需要直接删除,注意删除app.vue里的引用 |
|||
|
|||
+ **common** 存放公用的css js font等文件,工具类js建议封装到utils文件里 |
|||
|
|||
+ **components** |
|||
|
|||
+ 组件存放文件夹 |
|||
+ 统一格式 `组件/组件.vue ` 文件夹与组件同名,在页面或组件中引入就不用再`import`和在`components`注册了 |
|||
+ 如果是某个组件特用的子组件,确定不公用的情况下,建议封装到 `组件/components`文件夹里 |
|||
|
|||
+ **config** 配置信息文件,一些复杂对象或复杂数组的配置信息,不要在组件内直接定义,公用的建议提到config文件夹下(分模块管理),确定非公用的直接写到组件的文件夹内部即可 |
|||
|
|||
+ **pages** 页面存放目录 |
|||
|
|||
+ **plugins** 插件,request插件是封装的类似axios请求处理插件,跟axios用法一致,**注意返回值**:成功的返回对象是res.data.data,失败的返回值是res.data.msg,可根据后台接口对应修改。请求做了header里的token处理 |
|||
|
|||
+ **static** 存放静态文件 |
|||
|
|||
+ **store** vuex文件,注意分模块处理,参考模板中的user,组件中使用store文件时,优先使用mapState等解构方法 |
|||
|
|||
+ **utils** 公用工具类,注意分模块,如:`ui.js` `time.js` ` query.js`等 |
|||
|
|||
+ **.eslintrc.js** eslint代码格式检测配置文件 |
|||
|
|||
+ **.gitignore** 上传git仓库忽略的文件 |
|||
|
|||
+ **.prettierrc** prettier自动格式化代码风格的插件配置文件 |
|||
|
|||
+ App.vue 入口文件 |
|||
|
|||
+ Main.js 入口文件 |
|||
|
|||
+ **Manifest.json** 项目配置文件 |
|||
|
|||
+ **package.json** 项目中有使用到npm包,初始时先运行`npm i` |
|||
|
|||
+ **uni.scss** scss样式遍历定义文件,在组件中可直接使用其变量而不需要导入 |
|||
|
|||
+ **Vue.config.js** vue配置文件,定义了常用的alias,使用时尽量使用alias的绝对路径代替相对路径,如:`api/user.js`代替`./api/user.js` |
|||
|
|||
```js |
|||
'~': __dirname, |
|||
config: resolve('config'), |
|||
api: resolve('api'), |
|||
store: resolve('store'), |
|||
components: resolve('components'), |
|||
pages: resolve('pages'), |
|||
common: resolve('common'), |
|||
plugins: resolve('plugins'), |
|||
utils: resolve('utils'), |
|||
``` |
|||
|
|||
|
|||
|
|||
## scss |
|||
|
|||
+ 使用scss代替css样式 |
|||
+ HX必须要安装`scss插件` |
|||
+ 项目开发前应该先定义好uni.scss里的变量,统一引用这里的变量,有利用界面风格统一及后期维护 |
|||
|
|||
[官方文档uni.scss](https://uniapp.dcloud.io/collocation/uni-scss) |
|||
|
|||
## 约定 |
|||
|
|||
+ Package.json里内置了时间处理插件`moment.js`,统一使用`moment.js`进行时间处理 |
|||
|
|||
+ 使用scss进行样式开发 |
|||
|
|||
+ 样式变量(颜色,字体大小,间距等)统一定义到`uni.scss`文件里 |
|||
|
|||
+ 尽量使用alias定义的绝对路径代替相对路径,如:`api/user.js`代替`./api/user.js` |
|||
|
|||
+ 保持代码风格统一,建议使用vscode + prettier插件,自动格式化代码 |
|||
|
|||
+ 代码提交前,进行lint检测,不允许有eslint未通过提交的情况 |
|||
|
|||
+ `components`里的组件统一格式 `组件/组件.vue ` 文件夹与组件同名,在页面或组件中引入就不用再`import`和在`components`注册了 |
|||
|
|||
+ 页面及组件中分割出来的子组件,确定不公用的情况下,建议封装到 `组件/components`文件夹里 |
|||
|
|||
+ 一些复杂对象或复杂数组的配置信息,不要在组件内直接定义,公用的建议提到config文件夹下(分模块管理),确定非公用的直接写到组件的文件夹内部即可 |
|||
|
|||
+ api 参考上文目录说明中的api项 |
|||
|
|||
+ git提交规范参考前端规范里的代码提交规范 |
|||
|
|||
https://kdocs.cn/l/saAjmwvzT?f=130 |
|||
[文档] 1-前端技术规范-v1.0-20200618.docx |
@ -0,0 +1,6 @@ |
|||
// api基础地质
|
|||
// export const BASE_URL = 'https://www.sxwikionline.com/gateway';
|
|||
export const BASE_URL = '/gateway'; |
|||
|
|||
// 错误码
|
|||
export const ERR_CODE = 200; |
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/mt'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 查看教练/领队 信息详情
|
|||
export const coachInfo = params => http.post(`${proxyUrl}/province/coachInfo`, params); |
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/mt'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 查看比赛届数
|
|||
export const competeTime = params => http.post(`${proxyUrl}/compete/competeTime`, params); |
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/mt'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 删除教练/领队信息
|
|||
export const deletecoach = params => http.post(`${proxyUrl}/province/delete/coach`, params); |
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/mt'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 删除参赛人员
|
|||
export const delplayer = params => http.post(`${proxyUrl}/province/del/player`, params); |
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/mt'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 根据比赛届数查询一级目录
|
|||
export const firstproject = params => http.post(`${proxyUrl}/province/first/project`, params); |
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/tall/v1.0'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 验证码图片及id获取
|
|||
export const getbase = params => http.get(`${proxyUrl}/users/code`, params); |
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/tall/v1.0'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 获取验证码
|
|||
export const getcode = params => http.get(`${proxyUrl}/users/smscode`, params); |
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/mt'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 根据比赛届数查询用户参赛单户基本信息
|
|||
export const getcompany = params => http.post(`${proxyUrl}/province/get/company`, params); |
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/mt'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 查询比赛的所有组别
|
|||
export const group = params => http.post(`${proxyUrl}/compete/group`, params); |
@ -0,0 +1,6 @@ |
|||
const proxyUrl = '/mt'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 查询本单位所有注册的选手
|
|||
export const groupplayer = params => http.post(`${proxyUrl}/province/group/player`, params); |
|||
|
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/mt'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 选手报名/取消报名
|
|||
export const join = params => http.post(`${proxyUrl}/province/join`, params); |
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/tall/v1.0'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 登录接口
|
|||
export const login = params => http.post(`${proxyUrl}/users/signin`, params); |
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/mt'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 根据比赛id查询当前用户填写的信息概览
|
|||
export const overview = params => http.post(`${proxyUrl}/province/overview`, params); |
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/tall/v1.0'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 修改密码接口
|
|||
export const password = params => http.post(`${proxyUrl}/users/password`, params); |
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/tall/v1.0'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 检查是否被注册过
|
|||
export const phone = params => http.get(`${proxyUrl}/users/phone`, params); |
@ -0,0 +1,4 @@ |
|||
const proxyUrl = '/mt'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
export const photoBase64 = params => http.post(`${proxyUrl}/file/upload/photoBase64`, params); |
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/mt'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 参赛选手详细信息
|
|||
export const playerInfo = params => http.post(`${proxyUrl}/province/playerInfo`, params); |
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/mt'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 查看教练/领队 信息列表
|
|||
export const querycoach = params => http.post(`${proxyUrl}/province/query/coach`, params); |
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/tall/v1.0'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 注册接口
|
|||
export const register = params => http.post(`${proxyUrl}/users/signup`, params); |
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/mt'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 添加教练/领队信息
|
|||
export const savecoach = params => http.post(`${proxyUrl}/province/save/coach`, params); |
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/mt'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 添加/修改单位基本信息
|
|||
export const savecompany = params => http.post(`${proxyUrl}/province/save/company`, params); |
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/mt'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 添加/修改参赛人员
|
|||
export const saveplayer = params => http.post(`${proxyUrl}/province/save/player`, params); |
@ -0,0 +1,6 @@ |
|||
|
|||
const proxyUrl = '/mt'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 根据一级项目id查询二级项目
|
|||
export const secondproject = params => http.post(`${proxyUrl}/province/second/project`, params); |
@ -0,0 +1,4 @@ |
|||
const proxyUrl = '/mt'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
export const upload = params => http.post(`${proxyUrl}/file/upload/photo`, params, {header:{'Content-Type' : 'multipart/form-data'}}); |
@ -0,0 +1,5 @@ |
|||
const proxyUrl = '/tall/v1.0'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
// 请求统一使用如下格式
|
|||
// export const signin = params => http.post('/api/xxx', params);
|
@ -0,0 +1,184 @@ |
|||
/* |
|||
Animation 微动画 |
|||
基于ColorUI组建库的动画模块 by 文晓港 2019年3月26日19:52:28 |
|||
*/ |
|||
|
|||
/* css 滤镜 控制黑白底色gif的 */ |
|||
.gif-black{ |
|||
mix-blend-mode: screen; |
|||
} |
|||
.gif-white{ |
|||
mix-blend-mode: multiply; |
|||
} |
|||
|
|||
|
|||
/* Animation css */ |
|||
[class*=animation-] { |
|||
animation-duration: .5s; |
|||
animation-timing-function: ease-out; |
|||
animation-fill-mode: both |
|||
} |
|||
|
|||
.animation-fade { |
|||
animation-name: fade; |
|||
animation-duration: .8s; |
|||
animation-timing-function: linear |
|||
} |
|||
|
|||
.animation-scale-up { |
|||
animation-name: scale-up |
|||
} |
|||
|
|||
.animation-scale-down { |
|||
animation-name: scale-down |
|||
} |
|||
|
|||
.animation-slide-top { |
|||
animation-name: slide-top |
|||
} |
|||
|
|||
.animation-slide-bottom { |
|||
animation-name: slide-bottom |
|||
} |
|||
|
|||
.animation-slide-left { |
|||
animation-name: slide-left |
|||
} |
|||
|
|||
.animation-slide-right { |
|||
animation-name: slide-right |
|||
} |
|||
|
|||
.animation-shake { |
|||
animation-name: shake |
|||
} |
|||
|
|||
.animation-reverse { |
|||
animation-direction: reverse |
|||
} |
|||
|
|||
@keyframes fade { |
|||
0% { |
|||
opacity: 0 |
|||
} |
|||
|
|||
100% { |
|||
opacity: 1 |
|||
} |
|||
} |
|||
|
|||
@keyframes scale-up { |
|||
0% { |
|||
opacity: 0; |
|||
transform: scale(.2) |
|||
} |
|||
|
|||
100% { |
|||
opacity: 1; |
|||
transform: scale(1) |
|||
} |
|||
} |
|||
|
|||
@keyframes scale-down { |
|||
0% { |
|||
opacity: 0; |
|||
transform: scale(1.8) |
|||
} |
|||
|
|||
100% { |
|||
opacity: 1; |
|||
transform: scale(1) |
|||
} |
|||
} |
|||
|
|||
@keyframes slide-top { |
|||
0% { |
|||
opacity: 0; |
|||
transform: translateY(-100%) |
|||
} |
|||
|
|||
100% { |
|||
opacity: 1; |
|||
transform: translateY(0) |
|||
} |
|||
} |
|||
|
|||
@keyframes slide-bottom { |
|||
0% { |
|||
opacity: 0; |
|||
transform: translateY(100%) |
|||
} |
|||
|
|||
100% { |
|||
opacity: 1; |
|||
transform: translateY(0) |
|||
} |
|||
} |
|||
|
|||
@keyframes shake { |
|||
|
|||
0%, |
|||
100% { |
|||
transform: translateX(0) |
|||
} |
|||
|
|||
10% { |
|||
transform: translateX(-9px) |
|||
} |
|||
|
|||
20% { |
|||
transform: translateX(8px) |
|||
} |
|||
|
|||
30% { |
|||
transform: translateX(-7px) |
|||
} |
|||
|
|||
40% { |
|||
transform: translateX(6px) |
|||
} |
|||
|
|||
50% { |
|||
transform: translateX(-5px) |
|||
} |
|||
|
|||
60% { |
|||
transform: translateX(4px) |
|||
} |
|||
|
|||
70% { |
|||
transform: translateX(-3px) |
|||
} |
|||
|
|||
80% { |
|||
transform: translateX(2px) |
|||
} |
|||
|
|||
90% { |
|||
transform: translateX(-1px) |
|||
} |
|||
} |
|||
|
|||
@keyframes slide-left { |
|||
0% { |
|||
opacity: 0; |
|||
transform: translateX(-100%) |
|||
} |
|||
|
|||
100% { |
|||
opacity: 1; |
|||
transform: translateX(0) |
|||
} |
|||
} |
|||
|
|||
@keyframes slide-right { |
|||
0% { |
|||
opacity: 0; |
|||
transform: translateX(100%) |
|||
} |
|||
|
|||
100% { |
|||
opacity: 1; |
|||
transform: translateX(0) |
|||
} |
|||
} |
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
@ -0,0 +1,34 @@ |
|||
.cc-active { |
|||
transform: translate3d(1rpx, 1rpx, 0); |
|||
} |
|||
|
|||
.card { |
|||
margin-bottom: 60rpx; |
|||
.card-head { |
|||
display: flex; |
|||
align-items: center; |
|||
height: 120rpx; |
|||
padding: 0 32rpx; |
|||
|
|||
.card-head-avatar { |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
width: 56rpx; |
|||
height: 56rpx; |
|||
border-radius: 50%; |
|||
} |
|||
|
|||
.card-head-title { |
|||
flex: 1; |
|||
margin: 0 20rpx; |
|||
font-size: 16px; |
|||
color: $black; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.card-head-action { |
|||
font-size: 14px; |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,17 @@ |
|||
## 简介 |
|||
|
|||
|
|||
|
|||
## 更新日志 |
|||
**2019.12.30** |
|||
优化: |
|||
定位下拉内容 |
|||
待实现:只同时展示一个下拉内容 |
|||
**2019.12.27** |
|||
bug修复 |
|||
支持H5、微信小程序 |
|||
**2019.12.20** |
|||
第一次发布 |
|||
支持H5下拉,暂不支持小程序。 |
|||
原因:一些适配H5的方法是用vue来写的,小程序不支持。 |
|||
`this.$slots.`在小程序中不能用 |
@ -0,0 +1,213 @@ |
|||
<template> |
|||
<div class="dropdown-item"> |
|||
<!-- selected --> |
|||
<view class="dropdown-item__selected" |
|||
@click="changePopup"> |
|||
<slot name="title" v-if="$slots.title"></slot> |
|||
<block v-else> |
|||
<view class="selected__name">{{title ? title : selectItem.text}}</view> |
|||
<view class="selected__icon" |
|||
:class="showClass === 'show'? 'up' : 'down'" |
|||
> |
|||
<span class="iconfont"></span> |
|||
</view> |
|||
</block> |
|||
</view> |
|||
<view class="dropdown-item__content" :style="{top: contentTop + 'px'}" v-if="showList"> |
|||
<!-- dropdown --> |
|||
<view :class="['list', showClass]"> |
|||
<slot v-if="$slots.default"></slot> |
|||
<block v-else> |
|||
<view class="list__option" |
|||
v-for="(item, index) in list" |
|||
:key="index" |
|||
@click="choose(item)"> |
|||
<view>{{item.text}}</view> |
|||
<icon v-if="item.value === value" type="success_no_circle" size="26"/> |
|||
</view> |
|||
</block> |
|||
</view> |
|||
<!-- dropdown-mask --> |
|||
<view :class="['dropdown-mask', showClass]" v-if="showList" @click="closePopup"></view> |
|||
</view> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
components: { |
|||
}, |
|||
props: { |
|||
value: [Number, String, Object], |
|||
list: { |
|||
type: Array, |
|||
default: ()=> { |
|||
return [] |
|||
} |
|||
}, |
|||
title: [Number, String] |
|||
}, |
|||
data() { |
|||
return { |
|||
showList: "", |
|||
showClass: '', |
|||
selectItem: {}, |
|||
contentTop: 0 |
|||
} |
|||
}, |
|||
watch: { |
|||
}, |
|||
mounted() { |
|||
this.showList = this.active; |
|||
this.selectItem = this.list[this.value]; |
|||
// document.addEventListener('click', e => { |
|||
// //this.$el 可以获取当前组件的容器节点 |
|||
// if (!this.$el.contains(e.target)) { |
|||
// console.log('change'); |
|||
// this.close() |
|||
// } |
|||
// }); |
|||
}, |
|||
methods: { |
|||
choose(item) { |
|||
this.selectItem = item |
|||
this.$emit('input', item.value) |
|||
this.closePopup() |
|||
}, |
|||
changePopup() { |
|||
if(this.showList) { |
|||
this.closePopup() |
|||
} else { |
|||
this.openPopup() |
|||
} |
|||
}, |
|||
openPopup() { |
|||
// this.$parent -> dropdown-menu |
|||
this.$parent.$emit('close') |
|||
this.showList = true |
|||
this.$nextTick(() => { |
|||
this.getElementData('.dropdown-item__selected', (data)=>{ |
|||
this.contentTop = data[0].bottom |
|||
this.showClass = 'show' |
|||
}) |
|||
}) |
|||
}, |
|||
closePopup() { |
|||
this.showClass = '' |
|||
setTimeout(() => { |
|||
this.showList = false |
|||
}, 300) |
|||
}, |
|||
close() { |
|||
this.showClass = '' |
|||
this.showList = false |
|||
}, |
|||
getElementData(el, callback){ |
|||
uni.createSelectorQuery().in(this).selectAll(el).boundingClientRect().exec((data) => { |
|||
callback(data[0]); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
@font-face { |
|||
font-family: 'iconfont'; /* project id 1564327 */ |
|||
src: url('https://at.alicdn.com/t/font_1564327_fcszez4n5i.eot'); |
|||
src: url('https://at.alicdn.com/t/font_1564327_fcszez4n5i.eot?#iefix') format('embedded-opentype'), |
|||
url('https://at.alicdn.com/t/font_1564327_fcszez4n5i.woff2') format('woff2'), |
|||
url('https://at.alicdn.com/t/font_1564327_fcszez4n5i.woff') format('woff'), |
|||
url('https://at.alicdn.com/t/font_1564327_fcszez4n5i.ttf') format('truetype'), |
|||
url('https://at.alicdn.com/t/font_1564327_fcszez4n5i.svg#iconfont') format('svg'); |
|||
} |
|||
.iconfont{ |
|||
font-family:"iconfont" !important; |
|||
font-size:28rpx; |
|||
font-style:normal; |
|||
-webkit-font-smoothing: antialiased; |
|||
-webkit-text-stroke-width: 0.2px; |
|||
-moz-osx-font-smoothing: grayscale; |
|||
} |
|||
.dropdown-item { |
|||
width: 100%; |
|||
flex:1; |
|||
position: relative; |
|||
&__selected { |
|||
position: relative; |
|||
display: flex; |
|||
align-items: center; |
|||
background: #fff; |
|||
padding: 30rpx; |
|||
box-sizing: border-box; |
|||
justify-content: center; |
|||
.selected__name { |
|||
font-size: 32rpx; |
|||
} |
|||
.selected__icon { |
|||
margin-left: 20rpx; |
|||
&.down { |
|||
transition: transform .3s; |
|||
transform: rotateZ(0); |
|||
} |
|||
&.up { |
|||
transition: transform .3s; |
|||
transform: rotateZ(-180deg); |
|||
} |
|||
} |
|||
} |
|||
&__content { |
|||
position: fixed; |
|||
left: 0; |
|||
right: 0; |
|||
overflow: hidden; |
|||
top: 0; |
|||
bottom: 0; |
|||
z-index: 1; |
|||
.list { |
|||
max-height: 400px; |
|||
overflow-y: auto; |
|||
position: absolute; |
|||
left: 0; |
|||
right: 0; |
|||
z-index: 3; |
|||
background: #fff; |
|||
transform: translateY(-100%); |
|||
transition: all .3s; |
|||
&.show { |
|||
transform: translateY(0); |
|||
} |
|||
&__option { |
|||
font-size:32rpx; |
|||
padding: 26rpx 28rpx; |
|||
display: flex; |
|||
justify-content: space-between; |
|||
&:not(:last-child) { |
|||
border-bottom: 1rpx solid #DDDDDD; |
|||
} |
|||
} |
|||
} |
|||
.dropdown-mask { |
|||
position: absolute; |
|||
left: 0; |
|||
right: 0; |
|||
top: 0; |
|||
bottom: 0; |
|||
transition: all .3s; |
|||
z-index: 2; |
|||
&.show { |
|||
background:rgba(0,0,0,0.5); |
|||
} |
|||
} |
|||
} |
|||
&:not(:last-child):after { |
|||
content: ' '; |
|||
position: absolute; |
|||
width: 2rpx; |
|||
top: 36rpx; |
|||
bottom: 36rpx; |
|||
right: 0; |
|||
background: $uni-border-color; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,35 @@ |
|||
<template> |
|||
<div class="dropdown-menu"> |
|||
<slot></slot> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.$on('close', this.closeDropdown) |
|||
}, |
|||
methods: { |
|||
closeDropdown() { |
|||
this.$children.forEach(item =>{ |
|||
item.close(); |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
.dropdown-menu { |
|||
display: flex; |
|||
overflow: auto; |
|||
white-space: nowrap; |
|||
} |
|||
dropdown-item { |
|||
flex: 1; |
|||
} |
|||
</style> |
@ -0,0 +1,19 @@ |
|||
<template> |
|||
<view> |
|||
test组件 |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
|
|||
}; |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
|
|||
</style> |
@ -0,0 +1 @@ |
|||
export const ERR_CODE = 200; |
@ -0,0 +1,20 @@ |
|||
/* |
|||
* Copyright (c) 2020. |
|||
* author: wally |
|||
* email: 18603454788@163.com |
|||
*/ |
|||
|
|||
// 用户登录client
|
|||
export const SIGN_IN_CLIENTS = { mp: 0, h5: 1, android: 2, ios: 3, wx_work: 4 }; |
|||
|
|||
// 用户登录类型
|
|||
export const SIGN_IN_TYPES = { |
|||
mp: 0, |
|||
phone: 1, |
|||
email: 2, |
|||
username: 3, |
|||
wx: 4, |
|||
wx_web: 5, |
|||
wb: 6, |
|||
wx_work: 7, |
|||
}; |
@ -0,0 +1,64 @@ |
|||
import Vue from 'vue'; |
|||
import moment from 'moment'; |
|||
import { http } from 'plugins/request/index'; |
|||
import App from './App'; |
|||
import store from './store'; |
|||
import axios from 'axios' |
|||
Vue.prototype.$axios = axios |
|||
|
|||
import Fingerprint from 'fingerprintjs' |
|||
|
|||
// 白名单页面
|
|||
const whitePathList = [ |
|||
'basic-info', |
|||
'statistics', |
|||
'user-code', |
|||
'sign', |
|||
'my-signs', |
|||
'my-code', |
|||
'my-trips', |
|||
]; |
|||
/** |
|||
* 检查url是否在是否在白名单内 |
|||
* @param {string} url path+query |
|||
*/ |
|||
const checkWhitePath = url => { |
|||
let str = url.slice(7).split('/')[0]; |
|||
return whitePathList.includes(str); |
|||
}; |
|||
|
|||
// var fingerprint = new Fingerprint().get();
|
|||
// store.state.user.fingerprint = fingerprint
|
|||
// console.log(store.state.user.fingerprint)
|
|||
|
|||
|
|||
Vue.config.productionTip = false; |
|||
Vue.prototype.$http = http; |
|||
Vue.prototype.$moment = moment; |
|||
|
|||
moment.locale('zh-cn'); |
|||
|
|||
Vue.prototype.goHome = () => { |
|||
uni.reLaunch({ |
|||
url: '/pages/index/index', |
|||
}); |
|||
}; |
|||
|
|||
Vue.prototype.openPage = function(path, query = '') { |
|||
let url = query ? `${path}?${query}` : path; |
|||
store.commit('user/setPagePath', url); |
|||
const isWhite = checkWhitePath(url); |
|||
if ((!store.state.user.userInfo || !store.state.user.userInfo.id) && !isWhite) { |
|||
url = '/pages/basic-info/basic-info'; |
|||
} |
|||
|
|||
uni.navigateTo({ url }); |
|||
}; |
|||
|
|||
App.mpType = 'app'; |
|||
|
|||
const app = new Vue({ |
|||
store, |
|||
...App, |
|||
}); |
|||
app.$mount(); |
@ -0,0 +1,116 @@ |
|||
{ |
|||
"name" : "Loading...", |
|||
"appid" : "__UNI__4CABB72", |
|||
"description" : "", |
|||
"versionName" : "1.0.0", |
|||
"versionCode" : "100", |
|||
"transformPx" : false, |
|||
"networkTimeout" : { |
|||
"uploadFile" : 20000, |
|||
"request" : 20000 |
|||
}, |
|||
/* 5+App特有相关 */ |
|||
"app-plus" : { |
|||
"usingComponents" : true, |
|||
"nvueCompiler" : "uni-app", |
|||
"compilerVersion" : 3, |
|||
"splashscreen" : { |
|||
"alwaysShowBeforeRender" : true, |
|||
"waiting" : true, |
|||
"autoclose" : true, |
|||
"delay" : 0 |
|||
}, |
|||
/* 模块配置 */ |
|||
"modules" : {}, |
|||
/* 应用发布信息 */ |
|||
"distribute" : { |
|||
/* android打包配置 */ |
|||
"android" : { |
|||
"permissions" : [ |
|||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>", |
|||
"<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>", |
|||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>", |
|||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>", |
|||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>", |
|||
"<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>", |
|||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.CAMERA\"/>", |
|||
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>", |
|||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>", |
|||
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>", |
|||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>", |
|||
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>", |
|||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>", |
|||
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>", |
|||
"<uses-feature android:name=\"android.hardware.camera\"/>", |
|||
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>", |
|||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>" |
|||
] |
|||
}, |
|||
/* ios打包配置 */ |
|||
"ios" : {}, |
|||
/* SDK配置 */ |
|||
"sdkConfigs" : {} |
|||
} |
|||
}, |
|||
/* 快应用特有相关 */ |
|||
"quickapp" : {}, |
|||
/* 小程序特有相关 */ |
|||
"mp-weixin" : { |
|||
"appid" : "wx2f9ef33e08053bbf", |
|||
"setting" : { |
|||
"urlCheck" : false, |
|||
"es6" : true, |
|||
"postcss" : true, |
|||
"minified" : true |
|||
}, |
|||
"permission" : { |
|||
"scope.userLocation" : { |
|||
"desc" : "你的位置信息将用于获取地理位置及地图展示" |
|||
} |
|||
}, |
|||
"usingComponents" : true, |
|||
"navigateToMiniProgramAppIdList" : [ "wx5b97b0686831c076" ] |
|||
}, |
|||
"mp-alipay" : { |
|||
"usingComponents" : true |
|||
}, |
|||
"mp-baidu" : { |
|||
"usingComponents" : true |
|||
}, |
|||
"mp-toutiao" : { |
|||
"usingComponents" : true |
|||
}, |
|||
"h5" : { |
|||
"devServer" : { |
|||
"proxy" : { |
|||
"/gateway" : { |
|||
"target" : "https://test.tall.wiki/gateway", |
|||
"changeOrigin" : true, |
|||
"secure" : true, |
|||
"pathRewrite" : { |
|||
"^/gateway" : "" |
|||
} |
|||
} |
|||
}, |
|||
"https" : false, |
|||
"port" : "" |
|||
}, |
|||
"router" : { |
|||
"base" : "" |
|||
}, |
|||
"domain" : "https//:www.tall.wiki", |
|||
"async" : { |
|||
//页面js异步加载配置 |
|||
"loading" : "AsyncLoading", //页面js加载时使用的组件(需注册为全局组件) |
|||
"error" : "AsyncError", //页面js加载失败时使用的组件(需注册为全局组件) |
|||
"delay" : 500, //展示 loading 加载组件的延时时间(页面 js 若在 delay 时间内加载完成,则不会显示 loading 组件) |
|||
"timeout" : 1000 //页面js加载超时时间(超时后展示 error 对应的组件) |
|||
}, |
|||
"title" : "2020年山西省学生跳绳比赛报名系统" |
|||
} |
|||
} |
@ -0,0 +1,36 @@ |
|||
{ |
|||
"name": "uniTemplete", |
|||
"version": "1.0.0", |
|||
"lockfileVersion": 1, |
|||
"requires": true, |
|||
"dependencies": { |
|||
"axios": { |
|||
"version": "0.21.0", |
|||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.0.tgz", |
|||
"integrity": "sha512-fmkJBknJKoZwem3/IKSSLpkdNXZeBu5Q7GA/aRsr2btgrptmSCxi2oFjZHqGdK9DoTil9PIHlPIZw2EcRJXRvw==", |
|||
"requires": { |
|||
"follow-redirects": "^1.10.0" |
|||
} |
|||
}, |
|||
"fingerprintjs": { |
|||
"version": "0.5.3", |
|||
"resolved": "https://registry.npmjs.org/fingerprintjs/-/fingerprintjs-0.5.3.tgz", |
|||
"integrity": "sha1-ACZCL64asQA2keE2wUPhm3UnslU=" |
|||
}, |
|||
"fingerprintjs2": { |
|||
"version": "2.1.2", |
|||
"resolved": "https://registry.npmjs.org/fingerprintjs2/-/fingerprintjs2-2.1.2.tgz", |
|||
"integrity": "sha512-ZPsLgjziFRbUb5tXWpEMtWp4XFnzSah8SiNfl3aoURDZ+2zi2tuIOYUULqDBV+Cb6paN+raWT+Q2qpOaCbX/Yw==" |
|||
}, |
|||
"follow-redirects": { |
|||
"version": "1.13.0", |
|||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz", |
|||
"integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==" |
|||
}, |
|||
"moment": { |
|||
"version": "2.29.1", |
|||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", |
|||
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,34 @@ |
|||
{ |
|||
"name": "uniTemplete", |
|||
"version": "1.0.0", |
|||
"description": "", |
|||
"main": "main.js", |
|||
"scripts": { |
|||
"test": "echo \"Error: no test specified\" && exit 1" |
|||
}, |
|||
"uni-app": { |
|||
"scripts": { |
|||
"mp-dingtalk": { |
|||
"title": "钉钉小程序", |
|||
"env": { |
|||
"UNI_PLATFORM": "mp-alipay" |
|||
}, |
|||
"define": { |
|||
"MP-DINGTALK": true |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
"repository": { |
|||
"type": "git", |
|||
"url": "" |
|||
}, |
|||
"author": "wally", |
|||
"license": "ISC", |
|||
"dependencies": { |
|||
"axios": "^0.21.0", |
|||
"fingerprintjs": "^0.5.3", |
|||
"fingerprintjs2": "^2.1.2", |
|||
"moment": "^2.29.1" |
|||
} |
|||
} |
@ -0,0 +1,129 @@ |
|||
{ |
|||
"pages": [ |
|||
{ |
|||
"path" : "pages/Login/Login", |
|||
"style" : {} |
|||
}, |
|||
{ |
|||
"path" : "pages/First/First", |
|||
"style" : {} |
|||
} |
|||
,{ |
|||
"path" : "pages/Leader/Leader", |
|||
"style" : { |
|||
"navigationBarTitleText": "添加领队", |
|||
"navigationBarTextStyle": "black", |
|||
"navigationBarBackgroundColor": "#f8f8f8" |
|||
} |
|||
} |
|||
,{ |
|||
"path" : "pages/Coach/Coach", |
|||
"style" : { |
|||
"navigationBarTitleText": "添加教练", |
|||
"navigationBarTextStyle": "black", |
|||
"navigationBarBackgroundColor": "#f8f8f8" |
|||
} |
|||
} |
|||
,{ |
|||
"path" : "pages/Choice/Choice", |
|||
"style" : { |
|||
"navigationBarTitleText": "教练及领队信息", |
|||
"navigationBarTextStyle": "black", |
|||
"navigationBarBackgroundColor": "#f8f8f8" |
|||
} |
|||
} |
|||
,{ |
|||
"path" : "pages/Basics/Basics", |
|||
"style" : { |
|||
"navigationBarTitleText": "基础信息填写", |
|||
"navigationBarTextStyle": "black", |
|||
"navigationBarBackgroundColor": "#f8f8f8" |
|||
} |
|||
} |
|||
,{ |
|||
"path" : "pages/Athletes/Athletes", |
|||
"style" : { |
|||
"navigationBarTitleText": "添加运动员", |
|||
"navigationBarTextStyle": "black", |
|||
"navigationBarBackgroundColor": "#f8f8f8" |
|||
} |
|||
} |
|||
,{ |
|||
"path" : "pages/Athletes/AthAdd", |
|||
"style" : { |
|||
"navigationBarTitleText": "添加运动员", |
|||
"navigationBarTextStyle": "black", |
|||
"navigationBarBackgroundColor": "#f8f8f8" |
|||
} |
|||
} |
|||
,{ |
|||
"path" : "pages/Project/Project", |
|||
"style" : { |
|||
"navigationBarTitleText": "参赛项目", |
|||
"navigationBarTextStyle": "black", |
|||
"navigationBarBackgroundColor": "#f8f8f8" |
|||
} |
|||
} |
|||
,{ |
|||
"path" : "pages/Project/NumMatch", |
|||
"style" : { |
|||
"navigationBarTitleText": "计数赛项目", |
|||
"navigationBarTextStyle": "black", |
|||
"navigationBarBackgroundColor": "#f8f8f8" |
|||
} |
|||
} |
|||
,{ |
|||
"path" : "pages/Project/MatchDetail/MatchDetail", |
|||
"style" : { |
|||
"navigationBarTitleText": "队员添加", |
|||
"navigationBarTextStyle": "black", |
|||
"navigationBarBackgroundColor": "#f8f8f8" |
|||
} |
|||
} |
|||
,{ |
|||
"path" : "pages/Login/Register", |
|||
"style" : {} |
|||
} |
|||
,{ |
|||
"path" : "pages/read/read", |
|||
"style" : { |
|||
"navigationBarTitleText": "安全责任书", |
|||
"navigationBarTextStyle": "black", |
|||
"navigationBarBackgroundColor": "#f8f8f8" |
|||
} |
|||
} |
|||
,{ |
|||
"path" : "pages/read/Privacy", |
|||
"style" : { |
|||
"navigationBarTitleText": "隐私协议", |
|||
"navigationBarTextStyle": "black", |
|||
"navigationBarBackgroundColor": "#f8f8f8" |
|||
} |
|||
} |
|||
,{ |
|||
"path" : "pages/Project/PatternMatch", |
|||
"style" : {} |
|||
} |
|||
,{ |
|||
"path" : "pages/Login/Retrieve", |
|||
"style" : {} |
|||
} |
|||
,{ |
|||
"path" : "pages/Project/MatchDetail/TeamMatch", |
|||
"style" : {} |
|||
} |
|||
,{ |
|||
"path" : "pages/Project/MatchDetail/TeamDetail", |
|||
"style" : {} |
|||
} |
|||
], |
|||
"globalStyle": { |
|||
"navigationBarTextStyle": "white", |
|||
"navigationBarTitleText": "2020年山西省学生跳绳比赛报名系统", |
|||
"navigationBarBackgroundColor": "#6D99F2", |
|||
"backgroundColor": "#0a97c6" |
|||
}, |
|||
"easycom": { |
|||
"autoscan": true |
|||
} |
|||
} |
@ -0,0 +1,632 @@ |
|||
<template> |
|||
<view class="body-box"> |
|||
<view class="infor-box" v-for="(item,index) in list" :key="index"> |
|||
<view class="infor-title">{{ item.title }}<text class="fbt">*</text></view> |
|||
<input v-if="item.type === 0" placeholder="请输入" name="input" v-model.trim="item.content"></input> |
|||
<view class="drop-box"> |
|||
<view v-show="showview === 1" class="mask" @click="showBox"> |
|||
|
|||
</view> |
|||
<input v-if="item.type === 3" placeholder="请选择" name="input" disabled @click="showBox" v-model.trim="item.content"/> |
|||
<view v-if="item.type === 3" class="group-box" v-show="showview === 1"> |
|||
<view v-for="(item,index) in groupList" :key="index" @click="choice(index)"> |
|||
{{ item }} |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<radio-group v-if="item.type === 1" name="" @change="radioChange"> |
|||
<label class="w100"> |
|||
<radio value="0" :checked="che===0?true:false" /></radio><text>女</text> |
|||
<radio value="1" :checked="che===1?true:false" /></radio><text>男</text> |
|||
</label> |
|||
</radio-group> |
|||
|
|||
<!-- 身份证明 --> |
|||
<view v-if="item.type === 4" class="cu-form-group"> |
|||
<view class="grid col-4 grid-square flex-sub"> |
|||
<view class="solids"> |
|||
<view class="mask-box" @click="jump(item.content1)"> |
|||
|
|||
</view> |
|||
<text class='cuIcon-cameraadd'></text> |
|||
<image class="img-box" :src="idCardFront" mode="aspectFill"></image> |
|||
<icon v-show="idCardFront !== ''" type="icon" class="cuIcon-roundclosefill close-icon" @click="delimg(0)"></icon> |
|||
</view> |
|||
<view class="solids"> |
|||
<view class="mask-box" @click="jump(item.content2)"> |
|||
|
|||
</view> |
|||
<text class='cuIcon-cameraadd'></text> |
|||
<image class="img-box" :src="idCardBack"></image> |
|||
<icon v-show="idCardBack !== ''" type="icon" class="cuIcon-roundclosefill close-icon" @click="delimg(1)"></icon> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<!-- 一寸证件照 --> |
|||
<view v-if="item.type === 5" class="cu-form-group"> |
|||
<view class="grid col-4 grid-square flex-sub"> |
|||
<view class="solids" @click="jump(item.content)"> |
|||
<text class='cuIcon-cameraadd'></text> |
|||
<image class="img-box" :src="idPhone"></image> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<!-- 学籍证明/俱乐部证明 --> |
|||
<view v-if="item.type === 6" class="cu-form-group"> |
|||
<view class="grid col-4 grid-square flex-sub"> |
|||
<view class="solids" @click="jump(item.content)"> |
|||
<text class='cuIcon-cameraadd'></text> |
|||
<image class="img-box" :src="studentRecord"></image> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<!-- 体检证明 --> |
|||
<view v-if="item.type === 7" class="cu-form-group"> |
|||
<view class="grid col-4 grid-square flex-sub"> |
|||
<view class="solids" @click="jump(item.content)"> |
|||
<text class='cuIcon-cameraadd'></text> |
|||
<image class="img-box" :src="healthRecord"></image> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<!-- 人身意外保险 --> |
|||
<view v-if="item.type === 8" class="cu-form-group"> |
|||
<view class="grid col-4 grid-square flex-sub"> |
|||
<view class="solids" @click="jump(item.content)"> |
|||
<text class='cuIcon-cameraadd'></text> |
|||
<image class="img-box" :src="insuranceRecord"></image> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<text v-if="item.tips !== ''" class="tips">{{ item.tips }}</text> |
|||
</view> |
|||
<button v-show="isId-0===0" class="btn cu-btn bg-green margin-tb-sm lg" @tap="submit">提交</button> |
|||
<button v-show="isId-0===1" class="btn cu-btn bg-blue margin-tb-sm lg" @click="change">修改</button> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { upload } from 'api/upload' |
|||
import { saveplayer } from 'api/saveplayer' |
|||
import { playerInfo } from 'api/playerInfo' |
|||
import { group } from 'api/group' |
|||
// import { photoBase64 } from 'api/photoBase64' |
|||
export default { |
|||
async onLoad(option) { |
|||
const that = this |
|||
const params1 = { |
|||
param: { |
|||
type: 0 |
|||
} |
|||
} |
|||
const data1 = await group(params1) |
|||
// that.groupList = data1 |
|||
if(option.id) { |
|||
// console.log(option) |
|||
try{ |
|||
const params = { |
|||
param: { |
|||
playerId: option.id |
|||
} |
|||
} |
|||
const data = await playerInfo(params) |
|||
// console.log(data) |
|||
that.list[0].content = data.playerName |
|||
that.che = data.gender |
|||
that.groupRemark = data.groupRemark |
|||
that.list[3].content = data.idCard |
|||
that.isId = 1 |
|||
that.playerId = data.playerId |
|||
that.idCardFront = data.idCardFront |
|||
that.idCardFrontId = data.idCardFrontId |
|||
that.idCardBack = data.idCardBack |
|||
that.idCardBackId = data.idCardBackId |
|||
that.idPhone = data.idPhone |
|||
that.idPhoneId = data.idPhoneId |
|||
that.studentRecord = data.studentRecord |
|||
that.studentRecordId = data.studentRecordId |
|||
that.healthRecord = data.healthRecord |
|||
that.healthRecordId = data.healthRecordId |
|||
that.insuranceRecord = data.insuranceRecord |
|||
that.insuranceRecordId = data.insuranceRecordId |
|||
|
|||
// for( var i=0; i<data1.length; i++){ |
|||
// if(data1[i].groupId - 0 === data.groupId - 0) { |
|||
var num = data.groupRemark - 0 - 1 |
|||
that.list[2].content = that.groupList[`${num}`] |
|||
// console.log(data1[i].groupName) |
|||
// } |
|||
// } |
|||
|
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
} |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
list: [{ |
|||
title:'姓名', |
|||
type: 0, // 0是输入框,1是单选框,2是图片选择,3是下拉列表 |
|||
tips: '', |
|||
content: '' |
|||
}, { |
|||
title:'性别', |
|||
type: 1, |
|||
tips: '', |
|||
content: '' |
|||
}, { |
|||
title:'组别', |
|||
type: 3, |
|||
tips: '', |
|||
content: '' |
|||
}, { |
|||
title:'身份证号', |
|||
type: 0, |
|||
tips: '', |
|||
content: '' |
|||
}, { |
|||
title:'身份证明(图片大小不得大于2M)', |
|||
type: 4, |
|||
tips: '身份证、户口本、出生证等,身份证需上传正反面,户口本需上传运动员本人页', |
|||
content1: 'idCardFront', |
|||
content2: 'idCardBack' |
|||
}, { |
|||
title:'一寸证件照(图片大小不得大于2M)', |
|||
type: 5, |
|||
tips: '用于生成参赛证及比赛证书', |
|||
content: 'idPhone' |
|||
}, { |
|||
title:'学籍证明/俱乐部证明(图片大小不得大于2M)', |
|||
type: 6, |
|||
tips: '', |
|||
content: 'studentRecord' |
|||
}, { |
|||
title:'体检证明(图片大小不得大于2M)', |
|||
type: 7, |
|||
tips: '', |
|||
content: 'healthRecord' |
|||
}, { |
|||
title:'人身意外保险(图片大小不得大于2M)', |
|||
type: 8, |
|||
tips: '', |
|||
content: 'insuranceRecord' |
|||
}], |
|||
idCardFront: '', //身份证正面照片 或户口本照片 (文件类型) |
|||
idCardFrontId: '', //身份证正面照片 或户口本照片 (文件类型) |
|||
idCardBack: '', //身份证反面照片(文件类型) |
|||
idCardBackId: '', //身份证反面照片(文件类型) |
|||
idPhone: '', //一寸证件照(文件类型) |
|||
idPhoneId: '', //一寸证件照(文件类型) |
|||
studentRecord: '', //学籍证明(文件类型) |
|||
studentRecordId: '', //学籍证明(文件类型) |
|||
healthRecord: '', //体检证明(文件类型) |
|||
healthRecordId: '', //体检证明(文件类型) |
|||
insuranceRecord: '', //保险证明(文件类型) |
|||
insuranceRecordId: '', //保险证明(文件类型) |
|||
che: 0, |
|||
isId: 0, |
|||
playerId: 0, |
|||
groupList: ['小学','中学','高职院校','本科院校','俱乐部'], |
|||
groupRemark: 0, |
|||
showview: 0 |
|||
} |
|||
}, |
|||
methods: { |
|||
delimg(index) { |
|||
const that = this |
|||
if (index - 0 === 0) { |
|||
uni.showModal({ |
|||
title: '删除', |
|||
content: '确定要删除这张图片么?', |
|||
success: (res) => { |
|||
if (res.confirm) { |
|||
that.idCardFront = '' |
|||
that.idCardFrontId = '' |
|||
} |
|||
} |
|||
}) |
|||
} else if (index - 0 === 1) { |
|||
uni.showModal({ |
|||
title: '删除', |
|||
content: '确定要删除这张图片么?', |
|||
success: (res) => { |
|||
if (res.confirm) { |
|||
that.idCardBack = '' |
|||
that.idCardBackId = '' |
|||
} |
|||
}, |
|||
}) |
|||
} |
|||
}, |
|||
radioChange(e) { |
|||
const that = this |
|||
that.che = e.detail.value - 0 |
|||
// console.log(that.che) |
|||
}, |
|||
jump(type) { |
|||
const that = this |
|||
uni.chooseImage({ |
|||
count:1, |
|||
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有 |
|||
sourceType: ['album'], //从相册选择 |
|||
success: function (res) { |
|||
// console.log(res) |
|||
if (res.tempFiles[0].size > 2*1024*1024) { |
|||
uni.showToast({ |
|||
title: '图片超过2M,请重新选择', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else { |
|||
const tempFilePaths = res.tempFilePaths[0] |
|||
if(type === 'idCardBack' && that.idCardFront === ''){ |
|||
that.idCardFront = tempFilePaths |
|||
} else { |
|||
that[`${type}`] = tempFilePaths |
|||
} |
|||
// that[`${type}Id`] = jsondata.data.id |
|||
// that.urlTobase64(res.tempFilePaths[0],type); |
|||
|
|||
uni.uploadFile({ |
|||
url: '//www.tall.wiki/gateway/mt/file/upload/photo', |
|||
filePath: tempFilePaths, |
|||
header:{ |
|||
"Authorization" : "Bearer " + that.$store.state.user.user.token |
|||
}, |
|||
name: 'file', |
|||
success: (res) => { |
|||
// console.log(JSON.stringify()); |
|||
const jsondata = JSON.parse(res.data) |
|||
if (jsondata.code === 200) { |
|||
console.log(jsondata) |
|||
if(type === 'idCardBack' && that.idCardFrontId === ''){ |
|||
that.idCardFront = jsondata.data.visitUrl |
|||
that.idCardFrontId = jsondata.data.id |
|||
} else { |
|||
that[`${type}`] = jsondata.data.visitUrl |
|||
that[`${type}Id`] = jsondata.data.id |
|||
} |
|||
} else { |
|||
uni.showToast({ |
|||
title: `图片上传失败,请重新上传`, |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
}) |
|||
}, |
|||
// urlTobase64(url,type){ |
|||
// const that = this |
|||
// uni.request({ |
|||
// url: url, |
|||
// method: 'GET', |
|||
// responseType: 'arraybuffer', |
|||
// success: async res => { |
|||
// let base64 = wx.arrayBufferToBase64(res.data); //把arraybuffer转成base64 |
|||
// base64 = 'data:image/jpeg;base64,' + base64; //不加上这串字符,在页面无法显示 |
|||
// // console.log(base64); |
|||
|
|||
// try{ |
|||
// const params = { |
|||
// fileBase64: base64 |
|||
// } |
|||
// const data = await photoBase64(params) |
|||
// // console.log(data) |
|||
|
|||
// // console.log(that[`${type}Id`]) |
|||
// // console.log(that.idCardFrontId) |
|||
// // console.log(`${type}Id`) |
|||
// }catch(e){ |
|||
// //TODO handle the exception |
|||
// // console.log(e) |
|||
// } |
|||
// } |
|||
// }); |
|||
// }, |
|||
showBox() { |
|||
const that = this |
|||
if (that.showview === 0) { |
|||
that.showview = 1 |
|||
} else { |
|||
that.showview = 0 |
|||
} |
|||
}, |
|||
choice(index) { |
|||
const that = this |
|||
that.list[2].content = that.groupList[`${index}`] |
|||
that.groupRemark = index - 0 + 1 |
|||
that.showview = 0 |
|||
}, |
|||
async submit() { |
|||
const that = this |
|||
if (that.list[0].content === '') { |
|||
uni.showToast({ |
|||
title: '姓名不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.groupRemark - 0 === 0) { |
|||
uni.showToast({ |
|||
title: '请选择组别', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
}else if (that.list[2].content === '') { |
|||
uni.showToast({ |
|||
title: '组别不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.list[3].content === '') { |
|||
uni.showToast({ |
|||
title: '身份证号不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.idCardFrontId === '') { |
|||
uni.showToast({ |
|||
title: '请上传身份证明', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.idPhoneId === '') { |
|||
uni.showToast({ |
|||
title: '请上传一寸证件照', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.studentRecordId === '') { |
|||
uni.showToast({ |
|||
title: '请上传学籍证明', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.healthRecordId === '') { |
|||
uni.showToast({ |
|||
title: '请上传体检证明', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.insuranceRecordId === '') { |
|||
uni.showToast({ |
|||
title: '请上传保险证明', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else { |
|||
try{ |
|||
const params = { |
|||
param: { |
|||
competeId: that.$store.state.project.companyId, |
|||
groupRemark: that.groupRemark,//组别id |
|||
playerName: that.list[0].content,//选手姓名 |
|||
gender: that.che,//性别 |
|||
idCard: that.list[3].content,//身份证号 |
|||
idCardFront: that.idCardFrontId,//身份证正面照片 或户口本照片 (文件类型) |
|||
idCardBack: that.idCardBackId,//身份证反面照片(文件类型) |
|||
idPhone: that.idPhoneId,//一寸证件照(文件类型) |
|||
studentRecord: that.studentRecordId,//学籍证明(文件类型) |
|||
healthRecord: that.healthRecordId,//体检证明(文件类型) |
|||
insuranceRecord: that.insuranceRecordId//保险证明(文件类型) |
|||
} |
|||
} |
|||
const data = await saveplayer(params) |
|||
uni.showToast({ |
|||
title: '添加成功', |
|||
icon: 'success', |
|||
duration: 1500 |
|||
}) |
|||
that.$store.state.project.num++ |
|||
setTimeout(function(){ |
|||
uni.navigateBack() |
|||
},1000) |
|||
// console.log(that.$store.state.project.num) |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
uni.showToast({ |
|||
title: e, |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} |
|||
} |
|||
}, |
|||
async change() { |
|||
const that = this |
|||
if (that.list[0].content === '') { |
|||
uni.showToast({ |
|||
title: '姓名不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.groupRemark - 0 === 0) { |
|||
uni.showToast({ |
|||
title: '请选择组别', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.list[2].content === '') { |
|||
uni.showToast({ |
|||
title: '组别不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.list[3].content === '') { |
|||
uni.showToast({ |
|||
title: '身份证号不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.idCardFrontId === '') { |
|||
uni.showToast({ |
|||
title: '请上传身份证正面照', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.idCardBackId === '') { |
|||
uni.showToast({ |
|||
title: '请上传身份证反面照', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.idPhoneId === '') { |
|||
uni.showToast({ |
|||
title: '请上传一寸证件照', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.studentRecordId === '') { |
|||
uni.showToast({ |
|||
title: '请上传学籍证明', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.healthRecordId === '') { |
|||
uni.showToast({ |
|||
title: '请上传体检证明', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.insuranceRecordId === '') { |
|||
uni.showToast({ |
|||
title: '请上传保险证明', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
}else { |
|||
try{ |
|||
const params = { |
|||
param: { |
|||
playerId: that.playerId, |
|||
competeId: that.$store.state.project.companyId, |
|||
groupRemark: that.groupRemark,//组别id |
|||
playerName: that.list[0].content,//选手姓名 |
|||
gender: that.che,//性别 |
|||
idCard: that.list[3].content,//身份证号 |
|||
idCardFront: that.idCardFrontId,//身份证正面照片 或户口本照片 (文件类型) |
|||
idCardBack: that.idCardBackId,//身份证反面照片(文件类型) |
|||
idPhone: that.idPhoneId,//一寸证件照(文件类型) |
|||
studentRecord: that.studentRecordId,//学籍证明(文件类型) |
|||
healthRecord: that.healthRecordId,//体检证明(文件类型) |
|||
insuranceRecord: that.insuranceRecordId//保险证明(文件类型) |
|||
} |
|||
} |
|||
const data = await saveplayer(params) |
|||
uni.showToast({ |
|||
title: '修改成功', |
|||
icon: 'success', |
|||
duration: 1500 |
|||
}) |
|||
that.$store.state.project.num++ |
|||
setTimeout(function(){ |
|||
uni.navigateBack() |
|||
},1000) |
|||
// console.log(that.$store.state.project.num) |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.body-box { |
|||
padding-bottom: 100px; |
|||
} |
|||
.infor-box { |
|||
width: 680rpx; |
|||
margin-left: 35rpx; |
|||
margin-top: 25px; |
|||
border-bottom: 1px solid #eee; |
|||
} |
|||
.infor-title { |
|||
font-size: 16px; |
|||
color: #505050; |
|||
margin-bottom: 10px; |
|||
} |
|||
.w100 { |
|||
width: 680rpx; |
|||
display: flex; |
|||
radio { |
|||
margin-right: 50rpx; |
|||
} |
|||
text { |
|||
flex: 1; |
|||
} |
|||
} |
|||
.btn { |
|||
width: 600rpx; |
|||
margin: 50px 0 0 75rpx; |
|||
} |
|||
.tips { |
|||
color: $gray; |
|||
font-size: 14px; |
|||
} |
|||
.drop-box { |
|||
position: relative; |
|||
} |
|||
.fbt { |
|||
color: $red; |
|||
} |
|||
.group-box { |
|||
position: absolute; |
|||
background: white; |
|||
z-index: 10; |
|||
height: 200px; |
|||
overflow-y: auto; |
|||
border-radius: 0 0 10px 10px; |
|||
box-sizing: border-box !important; |
|||
// border: 2rpx solid $grey; |
|||
box-shadow: 0 0 5px $grey; |
|||
width: 680rpx; |
|||
z-index: 1000; |
|||
|
|||
view { |
|||
box-sizing: border-box !important; |
|||
left: 0; |
|||
height: 40px; |
|||
padding: 0 0 10px 20px; |
|||
line-height: 40px; |
|||
font-size: 14px; |
|||
width: 100%; |
|||
border-bottom: 1rpx solid #eee; |
|||
} |
|||
} |
|||
.mask { |
|||
position: fixed; |
|||
width: 750rpx; |
|||
height: 100%; |
|||
background: rgba(0,0,0,0); |
|||
left: 0; |
|||
top: 0; |
|||
z-index: 10; |
|||
} |
|||
.img-box { |
|||
width: 150rpx; |
|||
height: 150rpx; |
|||
} |
|||
.close-icon { |
|||
position: absolute; |
|||
right: 0; |
|||
top: 0; |
|||
font-size: 22px; |
|||
z-index: 100; |
|||
color: $red; |
|||
} |
|||
.mask-box { |
|||
height: 100%; |
|||
width: 100%; |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
z-index: 100; |
|||
background: rgba(0,0,0,0); |
|||
} |
|||
</style> |
@ -0,0 +1,200 @@ |
|||
<template> |
|||
<view> |
|||
<button v-show="cha !== 2" class="change" @click="change" :class="cha - 0 === 1 ? 'delsure' : ''"> |
|||
<text v-show="cha === 0">编辑</text> |
|||
<text v-show="cha === 1">确定</text> |
|||
</button> |
|||
<view class="img-B" v-show="cha - 0 === 2" > |
|||
<img src="static/item.png" class="img-box" /> |
|||
<view> |
|||
暂无运动员信息 |
|||
</view> |
|||
</view> |
|||
<view class="member-box" v-for="(item,index) in list" :key="index"> |
|||
<view class="member-title">{{ item.groupName }}</view> |
|||
<view class="member-con" v-for="(a,b) in item.playerList" :key="b" > |
|||
<view class="click-box" @click="details(a.playerId)"> |
|||
{{ a.playerName }} |
|||
</view> |
|||
<icon v-show="cha === 1" type="icon" class="cuIcon-roundclosefill del" @click="Del(a.playerId)"></icon> |
|||
</view> |
|||
</view> |
|||
<view class="choice" @tap="jump"> |
|||
添加 |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { groupplayer } from 'api/groupplayer' |
|||
import { delplayer } from 'api/delplayer' |
|||
export default { |
|||
async onLoad () { |
|||
this.add() |
|||
}, |
|||
data() { |
|||
return { |
|||
list: [], |
|||
cha: 2 |
|||
} |
|||
}, |
|||
methods: { |
|||
async add() { |
|||
const that = this |
|||
try{ |
|||
const params = { |
|||
param: { |
|||
companyId: that.$store.state.project.companyId |
|||
} |
|||
} |
|||
const data = await groupplayer(params) |
|||
// console.log(data) |
|||
that.list = data |
|||
if (that.list[0]) { |
|||
that.cha = 0 |
|||
} else { |
|||
that.cha = 2 |
|||
uni.navigateTo({ |
|||
url: './AthAdd' |
|||
}) |
|||
} |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
that.cha = 2 |
|||
} |
|||
}, |
|||
jump() { |
|||
uni.navigateTo({ |
|||
url:`./AthAdd` |
|||
}) |
|||
}, |
|||
async Del(num) { |
|||
const that = this |
|||
uni.showModal({ |
|||
title: '提示', |
|||
content: '确认要删除吗?', |
|||
success:async function (res) { |
|||
if (res.confirm) { |
|||
try{ |
|||
const params = { |
|||
param: { |
|||
playerId: num |
|||
} |
|||
} |
|||
const data = await delplayer(params) |
|||
that.add() |
|||
uni.showToast({ |
|||
title: '删除成功', |
|||
icon: 'success', |
|||
duration: 1500 |
|||
}) |
|||
that.$store.state.project.num++ |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
} |
|||
} |
|||
} |
|||
}) |
|||
}, |
|||
change() { |
|||
const that = this |
|||
if (that.cha - 0 === 0) { |
|||
that.cha = 1 |
|||
} else { |
|||
that.cha = 0 |
|||
} |
|||
}, |
|||
details(id) { |
|||
uni.navigateTo({ |
|||
url: `./AthAdd?id=${id}` |
|||
}) |
|||
} |
|||
}, |
|||
watch:{ |
|||
'$store.state.project.num'(val) { |
|||
const that = this |
|||
that.add() |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.member-box { |
|||
margin-left: 35rpx; |
|||
width: 680rpx; |
|||
} |
|||
.member-title { |
|||
height: 40px; |
|||
line-height: 40px; |
|||
font-size: 16px; |
|||
margin-top: 10px; |
|||
border-bottom: 1px solid $grey; |
|||
} |
|||
.member-con { |
|||
position: relative; |
|||
height: 60px; |
|||
margin-top: 10px; |
|||
line-height: 60px; |
|||
border-radius: 10px; |
|||
text-align: center; |
|||
box-shadow: 0 0 5px $gray; |
|||
} |
|||
.active { |
|||
box-shadow: 0 0 4px $green !important; |
|||
} |
|||
.choice { |
|||
position: fixed; |
|||
width: 150rpx; |
|||
height: 150rpx; |
|||
background: #709AFC; |
|||
box-shadow: 0 0 20px #709AFC; |
|||
border-radius: 50%; |
|||
color: $white; |
|||
right: 10px; |
|||
bottom: 100px; |
|||
text-align: center; |
|||
line-height: 150rpx; |
|||
font-size: 18px; |
|||
} |
|||
.man-num { |
|||
margin-left: 20px; |
|||
font-size: 14px; |
|||
color: $gray; |
|||
} |
|||
.del { |
|||
font-size: 28px; |
|||
position: absolute; |
|||
right: 10px; |
|||
top: 0; |
|||
font-weight: 700; |
|||
color: $red; |
|||
} |
|||
.change { |
|||
position: absolute; |
|||
top: 5px; |
|||
height: 30px; |
|||
line-height: 30px; |
|||
background: #eee; |
|||
font-size: 14px; |
|||
right: 40rpx; |
|||
} |
|||
.delsure { |
|||
background: $green; |
|||
color: $white; |
|||
} |
|||
.click-box { |
|||
margin: 0 50px; |
|||
} |
|||
.img-box { |
|||
width: 70%; |
|||
height: 70%; |
|||
} |
|||
.img-B { |
|||
width: 100%; |
|||
margin-top: 100px; |
|||
height: 450rpx; |
|||
text-align: center; |
|||
color: #aaa; |
|||
} |
|||
</style> |
@ -0,0 +1,225 @@ |
|||
<template> |
|||
<view> |
|||
<button v-show="!sub" type="default" class="change" @click="changeData">编辑</button> |
|||
<view class="infor-box" v-for="(item,index) in list" :key="index"> |
|||
<view v-if="item.type === 0" class="infor-title">{{ item.title }}<text class="fbt">*</text></view> |
|||
<input :class="sub? 'iptactive' : ''" :disabled="!sub" v-if="item.type === 0" placeholder="请输入" name="input" v-model.trim="item.content"></input> |
|||
<view v-show="sub" class="safe-box"> |
|||
<radio-group v-if="item.type === 1" name="sex"> |
|||
<label class="w100"> |
|||
<radio value="0" :checked="che" @click="radioChange"/></radio> |
|||
</label> |
|||
</radio-group> |
|||
<text v-if="item.type === 1" class="asfe-title" @click="jump">{{ item.title }}</text> |
|||
</view> |
|||
</view> |
|||
<button v-show="sub" class="btn cu-btn bg-green margin-tb-sm lg" @click="submit"> |
|||
<text v-if="!chan">确定提交</text> |
|||
<text v-else>确定修改</text> |
|||
</button> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { getcompany } from 'api/getcompany' |
|||
import { savecompany } from 'api/savecompany' |
|||
export default { |
|||
async onLoad (options) { |
|||
const that = this |
|||
console.log(options) |
|||
that.projectId = options.id - 0 |
|||
that.companyId = options.companyId - 0 |
|||
try{ |
|||
const params = { |
|||
param : { |
|||
competeTimeId: options.id |
|||
} |
|||
} |
|||
const data = await getcompany(params) |
|||
if (options.companyId - 0 === 0) { |
|||
that.list[2].content = that.$store.state.user.user.phone |
|||
} else { |
|||
that.list[0].content = data.companyName |
|||
that.list[1].content = data.contactsName |
|||
that.list[2].content = data.contactsPhone |
|||
that.che = true |
|||
that.sub = false |
|||
that.chan = true |
|||
that.companyId = options.companyId |
|||
} |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
list: [{ |
|||
title:'参赛队伍名称', |
|||
type: 0, // 0是输入框,1是单选框,2是图片选择 |
|||
content: '' |
|||
}, { |
|||
title:'主要联系人', |
|||
type: 0, |
|||
content: '' |
|||
}, { |
|||
title:'联系方式', |
|||
type: 0, |
|||
content: '' |
|||
}, { |
|||
title:'阅读并同意《安全责任书》', |
|||
type: 1, |
|||
content: '' |
|||
}], |
|||
projectId: 0, |
|||
che: false, |
|||
companyId: '', |
|||
sub: true, |
|||
chan: false |
|||
// imgList: [] |
|||
} |
|||
}, |
|||
methods: { |
|||
radioChange() { |
|||
const that = this |
|||
if (that.che) { |
|||
that.che = false |
|||
} else { |
|||
that.che = true |
|||
} |
|||
}, |
|||
async submit() { |
|||
const that = this |
|||
if (that.list[0].content === '') { |
|||
uni.showToast({ |
|||
title: '参赛队伍名称不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
}else if (that.list[1].content === '') { |
|||
uni.showToast({ |
|||
title: '主要联系人不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
}else if (that.list[2].content === '') { |
|||
uni.showToast({ |
|||
title: '联系方式不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (!/^1([3-9])[0-9]{9}$/.test(that.list[2].content)) { |
|||
uni.showToast({ |
|||
title: '请输入正确的手机号', |
|||
icon: 'none', |
|||
duration: 2000 |
|||
}) |
|||
}else if (that.che === false) { |
|||
uni.showToast({ |
|||
title: '请同意《安全责任书》', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
}else { |
|||
try{ |
|||
if (that.$store.state.project.companyId - 0 === 0) { |
|||
that.companyId = '' |
|||
} else { |
|||
that.companyId = that.$store.state.project.companyId |
|||
} |
|||
const params = { |
|||
param: { |
|||
companyId: that.companyId, |
|||
companyName: that.list[0].content, |
|||
competeTimeId: that.projectId - 0, |
|||
contactsName: that.list[1].content, |
|||
contactsPhone: that.list[2].content, |
|||
authorization: 1, |
|||
} |
|||
} |
|||
const data = await savecompany(params) |
|||
that.$store.state.project.companyId = data.companyId |
|||
uni.showToast({ |
|||
title: '提交成功', |
|||
icon: 'success', |
|||
duration: 1500 |
|||
}) |
|||
that.sub = false |
|||
that.chan = true |
|||
that.$store.state.project.num++ |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
uni.showToast({ |
|||
title: e, |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} |
|||
} |
|||
}, |
|||
jump() { |
|||
// 跳转到 安全责任书 界面 |
|||
uni.navigateTo({ |
|||
url: './../read/read' |
|||
}) |
|||
}, |
|||
changeData() { |
|||
const that = this |
|||
that.sub = true |
|||
that.chan = true |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.infor-box { |
|||
width: 680rpx; |
|||
margin-left: 35rpx; |
|||
margin-top: 25px; |
|||
border-bottom: 1px solid #eee; |
|||
} |
|||
.infor-box:last-of-type{ |
|||
border: none; |
|||
} |
|||
.infor-title { |
|||
font-size: 16px; |
|||
color: #505050; |
|||
margin-bottom: 10px; |
|||
} |
|||
.w100 { |
|||
radio { |
|||
margin-right: 20rpx; |
|||
} |
|||
} |
|||
.btn { |
|||
width: 680rpx; |
|||
margin: 50px 0 0 35rpx; |
|||
} |
|||
.asfe-title { |
|||
font-size: 14px; |
|||
} |
|||
.safe-box { |
|||
display: flex; |
|||
} |
|||
input { |
|||
height: 30px; |
|||
font-size: 14px; |
|||
border-radius: 5px; |
|||
} |
|||
.iptactive { |
|||
border: 1px solid $gray; |
|||
padding-left: 3%; |
|||
} |
|||
.change { |
|||
position: absolute; |
|||
top: -20px; |
|||
height: 30px; |
|||
line-height: 30px; |
|||
background: #eee; |
|||
font-size: 14px; |
|||
right: 40rpx; |
|||
} |
|||
.fbt { |
|||
color: $red; |
|||
} |
|||
</style> |
@ -0,0 +1,270 @@ |
|||
<template> |
|||
<view> |
|||
<view class="fixed-box"> |
|||
<scroll-view scroll-x class="bg-white nav text-center"> |
|||
<view class="cu-item" :class="index==TabCur?'bor':''" v-for="(item,index) in list" :key="index" @tap="tabSelect" :data-id="index"> |
|||
{{ item }} |
|||
</view> |
|||
</scroll-view> |
|||
<view class="num-box"> |
|||
<text v-if="TabCur === 0">已填 {{ competeCompanyCoachList.length }} / 2 人</text> |
|||
<text v-if="TabCur === 1">已填 {{ competeCompanyLeadersList.length }} / 3 人</text> |
|||
</view> |
|||
<button v-show="TabCur === 0 && cha1 !== 2" class="change" :class="cha === 1 ? 'delsure' : ''" @click="change1"> |
|||
<text v-show="cha1 === 0">编辑</text> |
|||
<text v-show="cha1 === 1">确定</text> |
|||
</button> |
|||
<button v-show="TabCur === 1 && cha !== 2" class="change" :class="cha === 1 ? 'delsure' : ''" @click="change"> |
|||
<text v-show="cha === 0">编辑</text> |
|||
<text v-show="cha === 1">确定</text> |
|||
</button> |
|||
</view> |
|||
<view class="content-box"> |
|||
<view v-show="TabCur === 0"> |
|||
<view class="infor-box" v-for="(item,index) in competeCompanyCoachList" :key="index"> |
|||
<view class="click-box" @click="details(item.coachId)"> |
|||
<view class="infor-content"><text>姓名:</text><text class="con">{{ item.coachName }}</text></view> |
|||
<view class="infor-content" v-if="item.gender === 0"><text>性别:</text><text class="con">女</text></view> |
|||
<view class="infor-content" v-else-if="item.gender === 1"><text>性别:</text><text class="con">男</text></view> |
|||
<view class="infor-content"><text>联系电话:</text><text class="con">{{ item.phone }}</text></view> |
|||
</view> |
|||
<icon v-show="cha1 === 1" type="icon" class="cuIcon-roundclosefill del" @click="del(item.coachId)"></icon> |
|||
</view> |
|||
</view> |
|||
<view v-show="TabCur === 1"> |
|||
<view class="infor-box" v-for="(item,index) in competeCompanyLeadersList" :key="index"> |
|||
<view class="click-box" @click="details1(item.guideId)"> |
|||
<view class="infor-content"><text>姓名:</text><text class="con">{{ item.guideName }}</text></view> |
|||
<view class="infor-content" v-if="item.gender === 0"><text>性别:</text><text class="con">女</text></view> |
|||
<view class="infor-content" v-else-if="item.gender === 1"><text>性别:</text><text class="con">男</text></view> |
|||
<view class="infor-content"><text>联系电话:</text><text class="con">{{ item.phone }}</text></view> |
|||
</view> |
|||
<icon v-show="cha === 1" type="icon" class="cuIcon-roundclosefill del" @click="del(item.guideId)"></icon> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<view v-show="TabCur === 0 && competeCompanyCoachList.length < 2" class="choice" @tap="jump"> |
|||
+添加领队 |
|||
</view> |
|||
<view v-show="TabCur === 1 && competeCompanyLeadersList.length < 3" class="choice" @tap="jump"> |
|||
+添加教练 |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { querycoach } from 'api/querycoach' |
|||
import { deletecoach } from 'api/deletecoach' |
|||
export default { |
|||
onLoad () { |
|||
this.query() |
|||
}, |
|||
data() { |
|||
return { |
|||
list: ['领队', '教练'], |
|||
TabCur: 0, |
|||
competeCompanyCoachList: [], |
|||
competeCompanyLeadersList: [], |
|||
cha: 2, |
|||
cha1: 2 |
|||
} |
|||
}, |
|||
methods: { |
|||
tabSelect(e) { |
|||
this.TabCur = e.currentTarget.dataset.id - 0; |
|||
this.scrollLeft = (e.currentTarget.dataset.id - 1) * 60 |
|||
console.log(this.TabCur,this.cha,this.cha1) |
|||
}, |
|||
async del(num) { |
|||
console.log(num) |
|||
const that = this |
|||
uni.showModal({ |
|||
title: '提示', |
|||
content: '确认要删除吗?', |
|||
success: async function (res) { |
|||
if (res.confirm) { |
|||
try{ |
|||
const params = { |
|||
param: { |
|||
coachId: num |
|||
} |
|||
} |
|||
const data = await deletecoach(params) |
|||
uni.showToast({ |
|||
title: '删除成功', |
|||
icon: 'success', |
|||
duration: 1500 |
|||
}) |
|||
that.$store.state.project.num++ |
|||
that.query() |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
} |
|||
} |
|||
} |
|||
}) |
|||
}, |
|||
change() { |
|||
const that = this |
|||
if(that.cha - 0 === 0) { |
|||
that.cha = 1 |
|||
} else { |
|||
that.cha = 0 |
|||
} |
|||
}, |
|||
change1() { |
|||
const that = this |
|||
if(that.cha1 - 0 === 0) { |
|||
that.cha1 = 1 |
|||
} else { |
|||
that.cha1 = 0 |
|||
} |
|||
}, |
|||
jump() { |
|||
const that = this |
|||
if (that.TabCur === 1) { |
|||
uni.navigateTo({ |
|||
url:`../Coach/Coach` |
|||
}) |
|||
} else if (that.TabCur === 0) { |
|||
uni.navigateTo({ |
|||
url:`../Leader/Leader` |
|||
}) |
|||
} |
|||
}, |
|||
async query() { |
|||
const that = this |
|||
try{ |
|||
const params = { |
|||
param: { |
|||
companyId: that.$store.state.project.companyId |
|||
} |
|||
} |
|||
const data = await querycoach(params) |
|||
if (data.competeCompanyCoachList[0]) { |
|||
that.competeCompanyCoachList = data.competeCompanyCoachList |
|||
that.cha1 = 0 |
|||
} else { |
|||
that.cha1 = 2 |
|||
that.competeCompanyCoachList = [] |
|||
} |
|||
if (data.competeCompanyLeadersList[0]) { |
|||
that.competeCompanyLeadersList = data.competeCompanyLeadersList |
|||
that.cha = 0 |
|||
} else { |
|||
that.cha = 2 |
|||
that.competeCompanyLeadersList = [] |
|||
} |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
that.cha = 2 |
|||
} |
|||
}, |
|||
details(id) { |
|||
uni.navigateTo({ |
|||
url:`../Leader/Leader?id=${id}` |
|||
}) |
|||
}, |
|||
details1(id) { |
|||
uni.navigateTo({ |
|||
url:`../Coach/Coach?id=${id}` |
|||
}) |
|||
} |
|||
}, |
|||
watch:{ |
|||
'$store.state.project.num'(val) { |
|||
const that = this |
|||
that.query()() |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.nav{ |
|||
display: flex !important; |
|||
} |
|||
.cu-item { |
|||
width: 325rpx; |
|||
} |
|||
.bor { |
|||
border-bottom: 4px solid #709AFC; |
|||
color: #709AFC; |
|||
} |
|||
.infor-box { |
|||
position: relative; |
|||
box-shadow: 0px 0px 5px $grey; |
|||
background: #fff; |
|||
margin-top: 10px; |
|||
width: 670rpx; |
|||
margin-left: 40rpx; |
|||
border-radius: 10px; |
|||
padding-left: 75rpx; |
|||
} |
|||
.infor-content { |
|||
// margin-top: 10px; |
|||
padding: 10px 0 10px 0; |
|||
// margin-bottom: 20px; |
|||
} |
|||
.con { |
|||
position: absolute; |
|||
left: 350rpx; |
|||
} |
|||
.choice { |
|||
width: 300rpx; |
|||
margin: 20px auto; |
|||
background: $white; |
|||
box-shadow: 0 0 5px $grey; |
|||
border-radius: 5px; |
|||
color: $gray; |
|||
text-align: center; |
|||
height: 40px; |
|||
line-height: 40px; |
|||
font-size: 14px; |
|||
} |
|||
.num-box { |
|||
position: relative; |
|||
width: auto; |
|||
text-align: left; |
|||
height: 30px; |
|||
line-height: 40px; |
|||
font-size: 14px; |
|||
color: $gray; |
|||
margin-left: 35rpx; |
|||
} |
|||
.del { |
|||
font-size: 22px; |
|||
position: absolute; |
|||
right: 10px; |
|||
z-index: 10; |
|||
top: 10px; |
|||
font-weight: 700; |
|||
color: $red; |
|||
} |
|||
.change { |
|||
position: absolute; |
|||
margin-top: -30px; |
|||
height: 30px; |
|||
line-height: 30px; |
|||
background: #eee; |
|||
font-size: 14px; |
|||
right: 40rpx; |
|||
} |
|||
.delsure { |
|||
background: $green; |
|||
color: $white; |
|||
} |
|||
.click-box { |
|||
margin-right: 50px; |
|||
} |
|||
.fixed-box { |
|||
position: fixed; |
|||
z-index: 100; |
|||
background-color: $white; |
|||
top: 44px; |
|||
width: 100%; |
|||
} |
|||
.content-box { |
|||
margin-top: 90px; |
|||
} |
|||
</style> |
@ -0,0 +1,346 @@ |
|||
<template> |
|||
<view> |
|||
<view class="infor-box" v-for="(item,index) in list" :key="index"> |
|||
<view class="infor-title">{{ item.title }}<text v-if="item.type !== 21" class="fbt">*</text></view> |
|||
<input v-if="item.type === 0" placeholder="请输入" name="input" v-model.trim="item.content"></input> |
|||
<radio-group v-if="item.type === 1" name="" @change="radioChange"> |
|||
<label class="w100"> |
|||
<radio value="0" :checked="che===0?true:false" /></radio><text>女</text> |
|||
<radio value="1" :checked="che===1?true:false" /></radio><text>男</text> |
|||
</label> |
|||
</radio-group> |
|||
|
|||
<view v-if="item.type === 20" class="cu-form-group"> |
|||
<view class="grid col-4 grid-square flex-sub"> |
|||
<view class="solids" @click="jump(item.content)"> |
|||
<text class='cuIcon-cameraadd'></text> |
|||
<image class="img-box" :src="idPhotoUrl"></image> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<view v-if="item.type === 21" class="cu-form-group"> |
|||
<view class="grid col-4 grid-square flex-sub"> |
|||
<view class="solids" @click="jump(item.content)"> |
|||
<text class='cuIcon-cameraadd'></text> |
|||
<image class="img-box" :src="coachCertificateUrl"></image> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
<text v-if="item.type === 20" class="tips">用于生成参赛证及比赛证书</text> |
|||
</view> |
|||
<button v-show="isId-0===0" class="btn cu-btn bg-green margin-tb-sm lg" @tap="submit">提交</button> |
|||
<button v-show="isId-0===1" class="btn cu-btn bg-blue margin-tb-sm lg" @click="change">修改</button> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { savecoach } from 'api/savecoach' |
|||
import { coachInfo } from 'api/coachInfo' |
|||
import { photoBase64 } from 'api/photoBase64' |
|||
export default { |
|||
async onLoad(option) { |
|||
const that = this |
|||
if(option.id) { |
|||
console.log(option) |
|||
try{ |
|||
const params = { |
|||
param: { |
|||
coachId: option.id |
|||
} |
|||
} |
|||
const data = await coachInfo(params) |
|||
console.log(data) |
|||
that.list[0].content = data.name |
|||
that.che = data.gender |
|||
that.list[2].content = data.phone |
|||
that.list[3].content = data.idCard |
|||
that.isId = 1 |
|||
that.guideId = data.coachId |
|||
that.idPhoto = data.idPhotoId |
|||
that.idPhotoUrl = data.idPhoto |
|||
that.coachCertificate = data.coachCertificateId |
|||
that.coachCertificateUrl = data.coachCertificate |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
} |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
list: [{ |
|||
title:'姓名', |
|||
type: 0,// 0是输入框,1是单选框,2是图片选择 |
|||
content: '' |
|||
}, { |
|||
title:'性别', |
|||
type: 1, |
|||
content: '' |
|||
}, { |
|||
title:'联系方式', |
|||
type: 0, |
|||
content: '' |
|||
}, { |
|||
title:'身份证号', |
|||
type: 0, |
|||
content: '' |
|||
}, { |
|||
title:'一寸证件照(图片大小不得大于2M)', |
|||
type: 20, |
|||
content: 'idPhoto' |
|||
}, { |
|||
title:'教练证(图片大小不得大于2M)', |
|||
type: 21, |
|||
content: 'coachCertificate' |
|||
}], |
|||
che: 0, |
|||
isId: 0, |
|||
idPhoto: 0, |
|||
idPhotoUrl: '', |
|||
coachCertificate: '', |
|||
coachCertificateUrl: '', |
|||
guideId: 0 |
|||
} |
|||
}, |
|||
methods: { |
|||
radioChange(e) { |
|||
const that = this |
|||
that.che = e.detail.value - 0 |
|||
console.log(that.che) |
|||
}, |
|||
jump(type) { |
|||
const that = this |
|||
uni.chooseImage({ |
|||
count:1, |
|||
sizeType: ['compressed'], //可以指定是原图还是压缩图,默认二者都有 |
|||
sourceType: ['album', 'camera'], //从相册选择 |
|||
success: function (res) { |
|||
if (res.tempFiles[0].size > 2*1024*1024) { |
|||
uni.showToast({ |
|||
title: '图片超过2M,请重新选择', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else { |
|||
const tempFilePaths = res.tempFilePaths[0] |
|||
that[`${type}`] = tempFilePaths |
|||
uni.uploadFile({ |
|||
url: '//www.tall.wiki/gateway/mt/file/upload/photo', |
|||
filePath: tempFilePaths, |
|||
header:{ |
|||
"Authorization" : "Bearer " + that.$store.state.user.user.token |
|||
}, |
|||
name: 'file', |
|||
success: (res) => { |
|||
// console.log(JSON.stringify()); |
|||
const jsondata = JSON.parse(res.data) |
|||
console.log(jsondata) |
|||
that[`${type}Url`] = jsondata.data.visitUrl |
|||
that[`${type}`] = jsondata.data.id |
|||
} |
|||
}); |
|||
} |
|||
// that.urlTobase64(res.tempFilePaths[0],type); |
|||
} |
|||
}) |
|||
}, |
|||
// urlTobase64(url,type){ |
|||
// const that = this |
|||
// uni.request({ |
|||
// url: url, |
|||
// method: 'GET', |
|||
// responseType: 'arraybuffer', |
|||
// success: async res => { |
|||
// let base64 = wx.arrayBufferToBase64(res.data); //把arraybuffer转成base64 |
|||
// base64 = 'data:image/jpeg;base64,' + base64; //不加上这串字符,在页面无法显示 |
|||
// // console.log(base64); |
|||
|
|||
// try{ |
|||
// const params = { |
|||
// fileBase64: base64 |
|||
// } |
|||
// const data = await photoBase64(params) |
|||
// that[`${type}Url`] = data.visitUrl |
|||
// that[`${type}`] = data.id |
|||
// }catch(e){ |
|||
// } |
|||
// } |
|||
// }); |
|||
// }, |
|||
async submit() { |
|||
const that = this |
|||
// console.log('提交事件') |
|||
if (that.list[0].content === '') { |
|||
uni.showToast({ |
|||
title: '姓名不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.list[2].content === '') { |
|||
uni.showToast({ |
|||
title: '联系方式不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (!/^1([3-9])[0-9]{9}$/.test(that.list[2].content)) { |
|||
uni.showToast({ |
|||
title: '请输入正确的手机号', |
|||
icon: 'none', |
|||
duration: 2000 |
|||
}) |
|||
}else if (that.list[3].content === '') { |
|||
uni.showToast({ |
|||
title: '身份证号不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.idPhoto - 0 === 0) { |
|||
uni.showToast({ |
|||
title: '请上传一寸证件照', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else { |
|||
try{ |
|||
const params = { |
|||
param: { |
|||
companyId: that.$store.state.project.companyId, |
|||
identity: 1, |
|||
name: that.list[0].content, |
|||
gender: that.che, |
|||
phone: that.list[2].content, |
|||
idCard: that.list[3].content, |
|||
idPhoto: that.idPhoto, |
|||
coachCertificate: that.coachCertificate |
|||
} |
|||
} |
|||
const data = await savecoach(params) |
|||
uni.showToast({ |
|||
title: '添加成功', |
|||
icon: 'success', |
|||
duration: 1500 |
|||
}) |
|||
that.$store.state.project.num++ |
|||
setTimeout(function(){ |
|||
uni.navigateBack() |
|||
},1000) |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
uni.showToast({ |
|||
title: e, |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} |
|||
} |
|||
}, |
|||
async change() { |
|||
const that = this |
|||
if (that.list[0].content === '') { |
|||
uni.showToast({ |
|||
title: '姓名不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.list[2].content === '') { |
|||
uni.showToast({ |
|||
title: '联系方式不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (!/^1([3-9])[0-9]{9}$/.test(that.list[2].content)) { |
|||
uni.showToast({ |
|||
title: '请输入正确的手机号', |
|||
icon: 'none', |
|||
duration: 2000 |
|||
}) |
|||
}else if (that.list[3].content === '') { |
|||
uni.showToast({ |
|||
title: '身份证号不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.idPhoto - 0 === 0) { |
|||
uni.showToast({ |
|||
title: '请上传一寸证件照', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else { |
|||
try{ |
|||
const params = { |
|||
param: { |
|||
coachId: that.guideId, |
|||
companyId: that.$store.state.project.companyId, |
|||
identity: 1, |
|||
name: that.list[0].content, |
|||
gender: that.che, |
|||
phone: that.list[2].content, |
|||
idCard: that.list[3].content, |
|||
idPhoto: that.idPhoto, |
|||
coachCertificate: that.coachCertificate |
|||
} |
|||
} |
|||
const data = await savecoach(params) |
|||
uni.showToast({ |
|||
title: '修改成功', |
|||
icon: 'success', |
|||
duration: 1500 |
|||
}) |
|||
that.$store.state.project.num++ |
|||
setTimeout(function(){ |
|||
uni.navigateBack() |
|||
},1000) |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
uni.showToast({ |
|||
title: e, |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.infor-box { |
|||
width: 680rpx; |
|||
margin-left: 35rpx; |
|||
margin-top: 25px; |
|||
border-bottom: 1px solid #eee; |
|||
} |
|||
.infor-title { |
|||
font-size: 16px; |
|||
color: #505050; |
|||
margin-bottom: 10px; |
|||
} |
|||
.w100 { |
|||
width: 680rpx; |
|||
display: flex; |
|||
radio { |
|||
margin-right: 50rpx; |
|||
} |
|||
text { |
|||
flex: 1; |
|||
} |
|||
} |
|||
.btn { |
|||
width: 600rpx; |
|||
margin: 50px 0 0 75rpx; |
|||
} |
|||
.tips { |
|||
color: $gray; |
|||
font-size: 14px; |
|||
} |
|||
.fbt { |
|||
color: $red; |
|||
} |
|||
.img-box { |
|||
width: 150rpx; |
|||
height: 150rpx; |
|||
} |
|||
</style> |
@ -0,0 +1,214 @@ |
|||
<template> |
|||
<view> |
|||
<swiper class="screen-swiper" :class="dotStyle?'square-dot':'round-dot'" :indicator-dots="true" :circular="true" |
|||
:autoplay="true" interval="3000" duration="500"> |
|||
<swiper-item v-for="(item,index) in swiperList" :key="index"> |
|||
<img class="img" :src="item.url" mode="aspectFill" v-if="item.type=='img'"></img> |
|||
</swiper-item> |
|||
</swiper> |
|||
<view class="item-box" v-for="(item,index) in list" :key="index" @click="jump(index)"> |
|||
<view class="item-num">{{ index + 1 }}</view> |
|||
<text class="item-content">{{ item.title }}</text> |
|||
<view v-show="item.complete + 1" class="item-infor"> |
|||
<text v-if="datalist.companyId === null">未填写</text> |
|||
<text v-else>已填写</text> |
|||
</view> |
|||
<view v-show="item.leader + 1" class="item-infor"> |
|||
<text>领队{{ datalist.guideNum }}人,教练{{ datalist.coachNum }}人</text> |
|||
</view> |
|||
<view v-show="item.athletes + 1" class="item-infor"> |
|||
<text>运动员{{ datalist.playerNum }}人</text> |
|||
</view> |
|||
<view v-show="item.project + 1" class="item-infor"> |
|||
<text>参赛项目{{ datalist.projectNum }}项</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { competeTime } from 'api/competeTime' |
|||
import { overview } from 'api/overview' |
|||
export default { |
|||
onLoad () { |
|||
this.query() |
|||
}, |
|||
data() { |
|||
return { |
|||
list: [{ |
|||
title:'基础信息', |
|||
complete: 1 |
|||
}, { |
|||
title:'领队及教练信息', |
|||
leader: 2, |
|||
coach: 0 |
|||
}, { |
|||
title:'运动员注册', |
|||
athletes: 4 |
|||
}, { |
|||
title:'参赛项目', |
|||
project: 0 |
|||
}], |
|||
projectId: 0, |
|||
companyId: 0, |
|||
datalist: {}, |
|||
dotStyle: true, |
|||
swiperList: [{ |
|||
id: 0, |
|||
type: 'img', |
|||
url: 'static/title.png' |
|||
}, { |
|||
id: 1, |
|||
type: 'img', |
|||
url: 'static/item01.png', |
|||
}, { |
|||
id: 2, |
|||
type: 'img', |
|||
url: 'static/item02.png' |
|||
}] |
|||
} |
|||
}, |
|||
methods: { |
|||
async query () { |
|||
const that = this |
|||
try{ |
|||
const params = { |
|||
param: { |
|||
type: 0 |
|||
} |
|||
} |
|||
const data = await competeTime(params) |
|||
that.projectId = data.id |
|||
that.$store.state.project.data = data |
|||
console.log(that.$store.state.project.data) |
|||
if (data.id) { |
|||
const params = { |
|||
param : { |
|||
competeTimeId: data.id |
|||
} |
|||
} |
|||
const datalist = await overview(params) |
|||
if (datalist.companyId) { |
|||
that.companyId = datalist.companyId |
|||
} |
|||
console.log(datalist.companyId) |
|||
that.datalist = datalist |
|||
that.$store.state.project.companyId = datalist.companyId |
|||
console.log(that.$store.state.project.companyId) |
|||
} |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
uni.showToast({ |
|||
title: e, |
|||
icon: 'none' |
|||
}) |
|||
} |
|||
}, |
|||
jump (num) { |
|||
const that = this |
|||
if (that.$store.state.project.companyId) { |
|||
if (num === 0) { |
|||
uni.navigateTo({ |
|||
url:`../Basics/Basics?id=${that.projectId}&companyId=${that.companyId}` |
|||
}) |
|||
} else if (num + 1 === 2) { |
|||
uni.navigateTo({ |
|||
url:`../Choice/Choice` |
|||
}) |
|||
} else if (num + 1 === 3) { |
|||
uni.navigateTo({ |
|||
url:`../Athletes/Athletes` |
|||
}) |
|||
} else if (num + 1 === 4) { |
|||
if (that.datalist.playerNum) { |
|||
uni.navigateTo({ |
|||
url:`../Project/Project` |
|||
}) |
|||
} else { |
|||
uni.showToast({ |
|||
title: '请先注册运动员', |
|||
icon:'none', |
|||
duration: 1500 |
|||
}) |
|||
} |
|||
} |
|||
} else { |
|||
if (num === 0) { |
|||
uni.navigateTo({ |
|||
url:`../Basics/Basics?id=${that.projectId}&companyId=${that.companyId}` |
|||
}) |
|||
} else { |
|||
uni.showToast({ |
|||
title: '请先填写基础信息', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
}, |
|||
watch: { |
|||
'$store.state.project.num'(val) { |
|||
const that = this |
|||
that.query() |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
<style lang="scss" scoped> |
|||
.item-box { |
|||
margin-top: 24px; |
|||
height: 80px; |
|||
line-height: 80px; |
|||
font-size: 18px; |
|||
width: 670rpx; |
|||
margin-left: 40rpx; |
|||
padding-left: 56rpx; |
|||
position: relative; |
|||
box-shadow: 0px 2px 5px $grey; |
|||
border-radius: 10px; |
|||
} |
|||
.item-num { |
|||
position: relative; |
|||
width: 40px; |
|||
height: 40px; |
|||
border-radius: 50%; |
|||
top: 20px; |
|||
text-align: center; |
|||
line-height: 40px; |
|||
background-color: #709AFC; |
|||
color: #fff; |
|||
} |
|||
.item-content { |
|||
position: absolute; |
|||
left: 180rpx; |
|||
top: -10px; |
|||
font-size: 16px; |
|||
} |
|||
.item-infor { |
|||
position: absolute; |
|||
left: 180rpx; |
|||
font-size: 12px; |
|||
color: $gray; |
|||
top: 15px; |
|||
} |
|||
.bingo { |
|||
font-size: 30px; |
|||
position: absolute; |
|||
top: 0; |
|||
right: 100rpx; |
|||
|
|||
} |
|||
.active { |
|||
color: $green; |
|||
} |
|||
.noactive { |
|||
color: $grey; |
|||
} |
|||
.img { |
|||
width: 750rpx; |
|||
top: 0; |
|||
height: 100%; |
|||
z-index: 1000; |
|||
} |
|||
</style> |
@ -0,0 +1,227 @@ |
|||
<template> |
|||
<view> |
|||
<view class="infor-box" v-for="(item,index) in list" :key="index"> |
|||
<view class="infor-title">{{ item.title }}<text class="fbt">*</text></view> |
|||
<input v-if="item.type === 0" placeholder="请输入" name="input" v-model.trim="item.content"></input> |
|||
<radio-group v-if="item.type === 1" name="sex" @change="radioChange"> |
|||
<label class="w100"> |
|||
<radio value="0" :checked="che===0?true:false" /></radio><text>女</text> |
|||
<radio value="1" :checked="che===1?true:false" /></radio><text>男</text> |
|||
</label> |
|||
</radio-group> |
|||
</view> |
|||
<button v-show="isId-0===0" class="btn cu-btn bg-green margin-tb-sm lg" @click="submit">提交</button> |
|||
<button v-show="isId-0===1" class="btn cu-btn bg-blue margin-tb-sm lg" @click="change">修改</button> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { savecoach } from 'api/savecoach' |
|||
import { coachInfo } from 'api/coachInfo' |
|||
export default { |
|||
async onLoad(option) { |
|||
const that = this |
|||
if(option.id) { |
|||
console.log(option) |
|||
try{ |
|||
const params = { |
|||
param: { |
|||
coachId: option.id |
|||
} |
|||
} |
|||
const data = await coachInfo(params) |
|||
console.log(data) |
|||
that.list[0].content = data.name |
|||
that.che = data.gender |
|||
that.list[2].content = data.phone |
|||
that.list[3].content = data.idCard |
|||
that.isId = 1 |
|||
that.coachId = data.coachId |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
} |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
list: [{ |
|||
title:'姓名', |
|||
type: 0 ,// 0是输入框,1是单选框,2是图片选择 |
|||
content: '' |
|||
}, { |
|||
title:'性别', |
|||
type: 1, |
|||
content: '' |
|||
}, { |
|||
title:'联系方式', |
|||
type: 0, |
|||
content: '' |
|||
}, { |
|||
title:'身份证号', |
|||
type: 0, |
|||
content: '' |
|||
}], |
|||
che: 0, |
|||
isId: 0, |
|||
coachId: 0 |
|||
// imgList: [] |
|||
} |
|||
}, |
|||
methods: { |
|||
radioChange(e) { |
|||
const that = this |
|||
that.che = e.detail.value - 0 |
|||
console.log(that.che) |
|||
}, |
|||
async submit() { |
|||
const that = this |
|||
if (that.list[0].content === '') { |
|||
uni.showToast({ |
|||
title: '姓名不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.list[2].content === '') { |
|||
uni.showToast({ |
|||
title: '联系方式不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (!/^1([3-9])[0-9]{9}$/.test(that.list[2].content)) { |
|||
uni.showToast({ |
|||
title: '请输入正确的手机号', |
|||
icon: 'none', |
|||
duration: 2000 |
|||
}) |
|||
}else if (that.list[3].content === '') { |
|||
uni.showToast({ |
|||
title: '身份证号不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else { |
|||
try{ |
|||
const params = { |
|||
param: { |
|||
companyId: that.$store.state.project.companyId, |
|||
identity: 0, |
|||
name: that.list[0].content, |
|||
gender: that.che, |
|||
phone: that.list[2].content, |
|||
idCard: that.list[3].content |
|||
} |
|||
} |
|||
const data = await savecoach(params) |
|||
uni.showToast({ |
|||
title: '添加成功', |
|||
icon: 'success', |
|||
duration: 1500 |
|||
}) |
|||
that.$store.state.project.num++ |
|||
setTimeout(function(){ |
|||
uni.navigateBack() |
|||
},1000) |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
uni.showToast({ |
|||
title: e, |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} |
|||
} |
|||
// console.log('提交事件') |
|||
}, |
|||
async change() { |
|||
const that = this |
|||
if (that.list[0].content === '') { |
|||
uni.showToast({ |
|||
title: '姓名不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.list[2].content === '') { |
|||
uni.showToast({ |
|||
title: '联系方式不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (!/^1([3-9])[0-9]{9}$/.test(that.list[2].content)) { |
|||
uni.showToast({ |
|||
title: '请输入正确的手机号', |
|||
icon: 'none', |
|||
duration: 2000 |
|||
}) |
|||
}else if (that.list[3].content === '') { |
|||
uni.showToast({ |
|||
title: '身份证号不能为空', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else { |
|||
try{ |
|||
const params = { |
|||
param: { |
|||
coachId: that.coachId, |
|||
companyId: that.$store.state.project.companyId, |
|||
identity: 0, |
|||
name: that.list[0].content, |
|||
gender: that.che, |
|||
phone: that.list[2].content, |
|||
idCard: that.list[3].content |
|||
} |
|||
} |
|||
const data = await savecoach(params) |
|||
uni.showToast({ |
|||
title: '修改成功', |
|||
icon: 'success', |
|||
duration: 1500 |
|||
}) |
|||
that.$store.state.project.num++ |
|||
setTimeout(function(){ |
|||
uni.navigateBack() |
|||
},1000) |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
uni.showToast({ |
|||
title: e, |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.infor-box { |
|||
width: 680rpx; |
|||
margin-left: 35rpx; |
|||
margin-top: 25px; |
|||
border-bottom: 1px solid #eee; |
|||
} |
|||
.infor-title { |
|||
font-size: 16px; |
|||
color: #505050; |
|||
margin-bottom: 10px; |
|||
} |
|||
.fbt { |
|||
color: $red; |
|||
} |
|||
.w100 { |
|||
width: 680rpx; |
|||
display: flex; |
|||
radio { |
|||
margin-right: 50rpx; |
|||
} |
|||
text { |
|||
flex: 1; |
|||
} |
|||
} |
|||
.btn { |
|||
width: 600rpx; |
|||
margin: 50px 0 0 75rpx; |
|||
} |
|||
</style> |
@ -0,0 +1,220 @@ |
|||
<template> |
|||
<view class="box"> |
|||
<swiper class="screen-swiper" :class="dotStyle?'square-dot':'round-dot'" :indicator-dots="true" :circular="true" |
|||
:autoplay="true" interval="3000" duration="500"> |
|||
<swiper-item v-for="(item,index) in swiperList" :key="index"> |
|||
<img class="img" :src="item.url" mode="aspectFill" v-if="item.type=='img'"></img> |
|||
</swiper-item> |
|||
</swiper> |
|||
<view class="title"> |
|||
登录 |
|||
</view> |
|||
<view class="ipt-infor"> |
|||
<view class="ipt-username"> |
|||
<view> |
|||
<text class="justleft">手机号</text>: |
|||
</view> |
|||
<input type="text" v-model.trim="userphone" placeholder="请输入"/> |
|||
</view> |
|||
<view class="ipt-password"> |
|||
<view> |
|||
<text class="justleft">密码</text>: |
|||
</view> |
|||
<input type="password" v-model.trim="password" placeholder="请输入"/> |
|||
</view> |
|||
</view> |
|||
<button type="default" class="btn cu-btn bg-green margin-tb-sm lg" @click="login">登录</button> |
|||
|
|||
<view class="go-register" @click="jump">注册</view> |
|||
<view class="go-password" @click="jump1">忘记密码</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { mapState, mapMutations, mapActions } from 'vuex'; |
|||
import { login } from 'api/login' |
|||
export default { |
|||
data() { |
|||
return { |
|||
userphone:'', |
|||
password:'', |
|||
dotStyle: true, |
|||
swiperList: [{ |
|||
id: 0, |
|||
type: 'img', |
|||
url: 'static/title.png' |
|||
}, { |
|||
id: 1, |
|||
type: 'img', |
|||
url: 'static/item01.png', |
|||
}, { |
|||
id: 2, |
|||
type: 'img', |
|||
url: 'static/item02.png' |
|||
}] |
|||
} |
|||
}, |
|||
methods: { |
|||
...mapMutations('user', ['setToken', 'setUser']), |
|||
jump() { |
|||
uni.navigateTo({ |
|||
url:`./Register`, |
|||
|
|||
}) |
|||
}, |
|||
jump1() { |
|||
uni.navigateTo({ |
|||
url:`./Retrieve`, |
|||
|
|||
}) |
|||
}, |
|||
async login () { |
|||
const that = this |
|||
if (that.userphone === '') { |
|||
uni.showToast({ |
|||
title: '请输入用户名', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.password === '') { |
|||
uni.showToast({ |
|||
title: '请输入密码', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else { |
|||
try { |
|||
const params = { |
|||
client: 1, |
|||
data: { |
|||
identifier: that.userphone, |
|||
credential: that.password, |
|||
}, |
|||
type: 3 |
|||
} |
|||
const data = await login(params) |
|||
console.log(data) |
|||
that.cacheData(data) |
|||
uni.navigateTo({ |
|||
url:`../First/First` |
|||
}) |
|||
} catch(e){ |
|||
//TODO handle the exception |
|||
console.log(e) |
|||
uni.showToast({ |
|||
title:e, |
|||
icon: "none", |
|||
duration: 2000 |
|||
}) |
|||
} |
|||
} |
|||
}, |
|||
cacheData(data) { |
|||
const { token } = data; |
|||
this.setToken(token); |
|||
this.setUser(data); |
|||
// console.log(this.$store.state.user) |
|||
} |
|||
// , |
|||
// replace(e){ |
|||
// const that = this |
|||
// that.userphone=e.detail.value.replace(/\s/g,"") |
|||
// }, |
|||
// replace1(e){ |
|||
// const that = this |
|||
// that.password=e.detail.value.replace(/\s/g,"") |
|||
// } |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.box { |
|||
position: relative; |
|||
} |
|||
.title { |
|||
font-size: 20px; |
|||
width: 150rpx; |
|||
height: 30px; |
|||
line-height: 30px; |
|||
margin-top: 30px; |
|||
border-bottom: 2px solid $blue; |
|||
margin-left: 300rpx; |
|||
text-align: center; |
|||
} |
|||
.ipt-infor { |
|||
margin-left: 50rpx; |
|||
width: 650rpx; |
|||
margin-top: 50px; |
|||
view{ |
|||
position: relative; |
|||
padding-left: 30px; |
|||
} |
|||
} |
|||
.justleft { |
|||
position: absolute; |
|||
left: -25px; |
|||
width: 50px; |
|||
text-align: justify !important; |
|||
text-align-last: justify; |
|||
} |
|||
.ipt-username { |
|||
position: relative; |
|||
height: 60px; |
|||
line-height: 60px; |
|||
border-bottom: 1px solid $grey; |
|||
|
|||
input { |
|||
position: absolute; |
|||
top: 20px; |
|||
left: 90px; |
|||
font-size: 14px; |
|||
} |
|||
} |
|||
.ipt-password { |
|||
position: relative; |
|||
height: 60px; |
|||
line-height: 60px; |
|||
border-bottom: 1px solid $grey; |
|||
|
|||
input { |
|||
position: absolute; |
|||
top: 20px; |
|||
left: 90px; |
|||
height: 20px; |
|||
line-height: 20px; |
|||
font-size: 14px; |
|||
} |
|||
} |
|||
.go-password { |
|||
color: $blue; |
|||
position: absolute; |
|||
left: 50rpx; |
|||
margin-top: 20px; |
|||
} |
|||
.btn { |
|||
width: 650rpx; |
|||
margin-left: 50rpx; |
|||
background: $blue; |
|||
color: $white; |
|||
margin-top: 50px; |
|||
} |
|||
.go-register { |
|||
color: $blue; |
|||
position: absolute; |
|||
right: 50rpx; |
|||
margin-top: 20px; |
|||
} |
|||
// .information { |
|||
// height: 30px; |
|||
// line-height: 30px; |
|||
// text-align: center; |
|||
// color: ; |
|||
// } |
|||
.img { |
|||
width: 750rpx; |
|||
height: 100%; |
|||
top: 0; |
|||
z-index: 1000; |
|||
} |
|||
</style> |
@ -0,0 +1,806 @@ |
|||
<template> |
|||
<view> |
|||
<swiper class="screen-swiper" :class="dotStyle?'square-dot':'round-dot'" :indicator-dots="true" :circular="true" |
|||
:autoplay="true" interval="3000" duration="500"> |
|||
<swiper-item v-for="(item,index) in swiperList" :key="index"> |
|||
<img class="img" :src="item.url" mode="aspectFill" v-if="item.type=='img'"></img> |
|||
</swiper-item> |
|||
</swiper> |
|||
<view class="title"> |
|||
注册 |
|||
</view> |
|||
<view class="ipt-infor"> |
|||
<view class="ipt-username"> |
|||
<text class="just-box">手机号</text>:<input type="text" v-model.trim="username" placeholder="请输入"/> |
|||
<text class="just-tips" v-show="tips === 1"> |
|||
该手机号已被注册,请直接登录 |
|||
</text> |
|||
</view> |
|||
<view class="ipt-username"> |
|||
<text class="just-box">验证码</text>:<input type="text" v-model.trim="code" placeholder="请输入"/> |
|||
<button type="default" class="btn-code" :class="cooling? 'active' : ''" @click="cooling? get() : ''">{{ content }}</button> |
|||
</view> |
|||
<view class="ipt-password"> |
|||
<text class="just-box">密码</text>:<input type="password" v-model.trim="password" placeholder="请输入"/> |
|||
</view> |
|||
</view> |
|||
<view class="img-box" v-show="imgbox"> |
|||
<image :src="imgsrc" mode=""></image> |
|||
<input type="text" placeholder="请输入验证码" v-model.trim="codeinput"/> |
|||
<view class="btn-box"> |
|||
<button type="default" @click="imgbox = false">关闭</button> |
|||
<button type="default" class="success" @click="submit">确定</button> |
|||
</view> |
|||
</view> |
|||
<button v-show="tips !== 1" type="default" class="btn cu-btn bg-green margin-tb-sm lg" @click="showBox">注册</button> |
|||
<view class="go-register" @click="jump">登录</view> |
|||
<view class="" v-show="safe === 1"> |
|||
<view class="box111" @click="mask"> |
|||
|
|||
</view> |
|||
<view class="safe-box"> |
|||
<view class="safe-title"> |
|||
隐私条款 |
|||
</view> |
|||
<view class="safe-content"> |
|||
<view class="fs12"> |
|||
山西传控电子科技有限公司(以下统称“传控科技”或“我们”)一向庄严承诺保护使用传控科技所有产品服务(以下统称“传控服务”)之用户(以下统称“用户”或“您”)的隐私。您在使用传控服务时,我们可能会收集和使用您的相关信息。 |
|||
</view> |
|||
<view class="fs12">
本隐私条款为传控服务声明的一部分,并适用于我们提供的一切传控服务,其包括传控科技所有产品服务的PC端、App端、H5手机网站以及提供基础服务的微信公众号、微信小程序。另外,若您通过使用第三方产品和/或服务(如第三方账号)来使用传控服务,您的信息还应当适用该第三方的隐私政策。 |
|||
</view> |
|||
<view class="fs12">
传控科技将通过本隐私条款向您说明传控科技会如何收集、保存、使用、共享以及保护您的信息,本隐私条款与您使用我们的服务关系密切,在使用传控服务前,请您务必仔细阅读并透彻理解本政策,在确认充分理解并同意后使用相关产品服务。一旦您使用或在我们更新本隐私条款后(我们会及时提示您更新的情况)继续使用我们的产品或服务,即意味着您已充分理解并同意本隐私条款(含更新版本)内容,授权并接受我们按照本隐私条款的规定收集、保存、使用、共享、披露您的信息。如您不同意协议中的任何条款,您应立即停止使用传控科技相关服务。
</view> |
|||
<view class="fs12"> |
|||
您可以通过以下目录阅读相应章节,进一步了解本条款的具体内容 |
|||
</view> |
|||
<view class="fs12"> |
|||
1. 我们收集的信息类型 |
|||
</view> |
|||
<view class="fs12"> |
|||
2. 我们如何使用所收集的信息 |
|||
</view> |
|||
<view class="fs12"> |
|||
3. 我们可能共享、转让、公开披露信息 |
|||
</view> |
|||
<view class="fs12"> |
|||
4. 您的权利 |
|||
</view> |
|||
<view class="fs12"> |
|||
5. 第三方网站 |
|||
</view> |
|||
<view class="fs12"> |
|||
6. 我们如何保存和保护您的信息 |
|||
</view> |
|||
<view class="fs12"> |
|||
7. 未成年人保护 |
|||
</view> |
|||
<view class="fs12"> |
|||
8. 本《隐私条款》的变更 |
|||
</view> |
|||
<view class="fs12"> |
|||
9. 联系我们 |
|||
</view> |
|||
<view class="fs16"> |
|||
1 我们收集的信息类型 |
|||
</view> |
|||
<view class="fs14"> |
|||
1.1 您向我们提供的信息 |
|||
</view> |
|||
<view class="fs14"> |
|||
1.1.1 使用传控服务的必要信息 |
|||
</view> |
|||
<view class="fs12"> |
|||
当您使用传控服务时,我们要求您提供并收集以下您的个人信息。此等信息对于充分履行您和我们之间的约定的服务很有必要,并使得我们能够遵守我们的法律义务。没有此等信息,我们可能无法向您提供您所要求的全部服务。 |
|||
</view> |
|||
<view class="fs12"> |
|||
账号信息。在您使用传控科技提供的服务时,可以在不注册账号或不登录的情形下浏览传控科技网站,但您在注册之后可以享受更全面和优质的服务。在您注册传控科技账号时,我们需要收集您的手机号码或个人邮箱,我们将通过发送短信验证码的方式来验证您的手机号码是否真实有效,通过发送邮件的方式来验证您的邮箱是否真实有效。您也可以使用微博、微信和QQ的第三方账号关联登录,为保存登录信息并在不同设备登录时能同步数据,我们需要您授予我们从第三方账号获得某些信息的权限,如使用者第三方关联登录的唯一标识、头像、昵称。有关您在这些第三方账号中所有的隐私控制、选项及具体的隐私规定,请参阅他们的隐私政策。我们将在您首次运行App和您注册时提供隐私条款并获取您的同意。 |
|||
</view> |
|||
<view class="fs14"> |
|||
1.1.2 您选择向我们提供的信息 |
|||
</view> |
|||
<view class="fs12"> |
|||
您可以选择向我们提供额外的个人信息,以便在使用传控服务时获得更好的用户体验。此等额外信息将基于您的自愿同意而处理。 |
|||
</view> |
|||
<view class="fs12"> |
|||
个性化信息。如果您选择我们为您提供的个性化产品或服务,我们会根据相关服务的具体需求,要求您提供更多个性化信息。例如,当您使用我们的比赛服务时,根据比赛主办方的具体需求,比赛报名还会要求您提供身份证号、证件照等信息,用于登记、报到、检录等环节。 |
|||
</view> |
|||
<view class="fs12"> |
|||
授权信息。在您使用传控科技的部分功能和/或服务时可能需要您自行开启以下权限。您决定开启这些权限即代表您授权我们可以收集和使用这些信息来实现相关功能。不开启或关闭这些权限即代表您取消了这些授权,则我们将不再继续收集和使用您的这些个人信息,也无法为您继续提供与这些权限相对应的功能。您关闭权限的决定不会影响此前基于您的授权所进行的个人信息处理。这些权限包括但不限于: |
|||
</view> |
|||
<view class="fs12"> |
|||
(1)文件存储和访问权限:开启文件存储和访问权限,方便为您提供保存图片、缓存播放视频功能。 |
|||
</view> |
|||
<view class="fs12"> |
|||
(2)访问位置信息权限:开启访问位置信息权限,我们可能会收集您的精确或大致位置信息,此等信息通过您的IP地址或移动设备的GPS数据来确定,以便为您提供更好的用户体验。即使当您不使用应用时,如果您的设置或设备权限允许此等连接开启,我们仍可能会收集此等信息。 |
|||
</view> |
|||
<view class="fs12"> |
|||
(3)相机权限:开启相机权限,方便您直接拍摄图片上传和使用视频会议等功能。 |
|||
</view> |
|||
<view class="fs12"> |
|||
(4)访问和修改日历权限:开启访问和修改日历权限,方便您将比赛、会议日期加入您的日历提醒中,防止遗忘。 |
|||
</view> |
|||
<view class="fs12"> |
|||
(5)麦克风权限:开启麦克风权限,方便您正常使用在线会议、语音聊天等功能。 |
|||
</view> |
|||
<view class="fs14"> |
|||
1.2 您使用传控服务时,我们自动收集的信息 |
|||
</view> |
|||
<view class="fs12"> |
|||
在您使用传控科技提供的相关服务时,我们会自动收集关于您所使用的服务以及如何使用相关服务的信息,包括个人信息。 |
|||
</view> |
|||
<view class="fs14"> |
|||
1.2.1 使用信息 |
|||
</view> |
|||
<view class="fs12"> |
|||
我们会收集您与传控科技相关产品和服务的互动信息,如您查看的页面或其他内容、您搜索的服务项目以及您在传控科技平台上参与的其他活动,这些活动包括但不限于: |
|||
</view> |
|||
<view class="fs12"> |
|||
线上支付:在您选择购买我们的服务时,我们会根据法律规定记录、保存在传控科技上的服务信息、交易信息。您可以选择第三方支付机构所提供的支付服务,根据您的选择,您需要提供开户行、账户、银行账户或者您选择的第三方支付时必要信息。如果需要发票,您还需要提交纳税人识别号,支付功能本身并不收集您的信息,但我们需要将您的订单号与交易金额信息与支付机构共享以实现其确认您的支付指令并完成支付。 |
|||
</view> |
|||
<view class="fs12"> |
|||
关注并使用传控科技微信公众号、小程序:当您关注、使用我们的微信公众号时,我们会收集您的微信昵称、头像;当您使用该微信小程序时,我们可能会收集您的微信UnionID、OpenID、UserID、微信昵称、微信头像、登录记录信息。当您使用微信账号或微信小程序的特定功能或服务时,您可能需要注册、登录传控科技账号或使用微信账号授权登录,当您选择后者时,我们可能会收集您的手机号码,对于此类消息,我们将按照微信公众号和微信小程序的个人信息收集规则,根据相应提示获取您的同意。当您参加线上课程等活动时,我们将收集您主动填写的个人信息,且仅用于该次活动的开展和统计工作。 |
|||
</view> |
|||
<view class="fs14"> |
|||
1.2.2 登录数据和设备信息 |
|||
</view> |
|||
<view class="fs12"> |
|||
为了保障您使用传控科技服务时的人身、财产安全,更好地预防求职诈骗财产风险、人身安全风险,以及更准确地识别违反法律法规及传控科技相关协议、规则的行为,我们会记录、整合、使用您的常用设备信息、网络标识信息,以及我们关联公司、合作第三方取得您授权或依法共享的信息。即使您未创建或登录传控科技账户,当您访问并使用传控科技网站时,我们也会自动收集登录数据和设备信息。此等信息包括:您使用传控科技服务(包括指向第三方应用的链接)的详细信息、IP地址、访问日期和次数、硬件和软件信息、设备信息,设备事件信息、唯一识别符、崩溃数据、cookie数据以及您在使用传控科技服务前后查看或接触过的页面。收集此等信息用于判断您的账号风险、进行身份验证、检测我们认为存在风险的行为以及防范平台安全时间,并采取必要的记录、审计、分析、处置措施。 |
|||
</view> |
|||
<view class="fs14"> |
|||
1.2.3 Cookie及类似技术 |
|||
</view> |
|||
<view class="fs12"> |
|||
我们使用Cookie及类似技术,如网络信标、像素及移动标识符。借助于 Cookie,网站能够存储您的偏好等数据。我们不会将 Cookie 用于本政策所述目的之外的任何用途,您可根据自己的偏好管理或删除 Cookie。 |
|||
</view> |
|||
<view class="fs12"> |
|||
您有权选择接受或拒绝接受Cookie。在您未拒绝接受Cookie的情况下,www.ccsens.com会在您的计算机上设定或取用Cookie,以便您能登录或使用依赖于Cookie的www.ccsens.com平台服务或功能。同时,www.ccsens.com将自动接收并记录您的浏览器端数据,包括但不限于IP地址、网站Cookie中的资料及您要求取用的网页记录; |
|||
</view> |
|||
<view class="fs12"> |
|||
您可以通过修改浏览器设置的方式拒绝接受Cookie。但如果您选择拒绝接受Cookie,则您可能无法登录或使用依赖于Cookie的www.ccsens.com平台服务或功能; |
|||
</view> |
|||
<view class="fs12"> |
|||
通过www.ccsens.com所设Cookie所取得的有关信息,将适用本政策。 |
|||
</view> |
|||
<view class="fs14"> |
|||
1.3 我们通过第三方收集的信息 |
|||
</view> |
|||
<view class="fs12"> |
|||
传控科技可能会收集其他方在使用传控科技服务时提供的关于您的信息(包括个人信息),或从其他渠道获取信息,并与我们通过传控科技服务收集的信息整合。我们不会控制、监督或回应提供您的信息的第三方如何处理您的个人数据,任何发给我们的关于披露您的个人信息的信息请求应直接发送给此类第三方。 |
|||
</view> |
|||
<view class="fs12"> |
|||
第三方服务。我们提供部分功能和/或服务时需要使用第三方SDK技术,这些第三方SDK在配合我们向您提供更全面的服务的同时,可能会收集或使用您的个人信息,我们会以弹窗提示等方式明确告知您,在您授权同意后再获取相关信息,相关隐私实践请详见该第三方的隐私政策。如未取得您的授权,我们将不会收集和使用相关信息,也不会再反复弹窗向您获取授权。目前这些SDK包括: |
|||
</view> |
|||
<view class="fs12"> |
|||
第三方登录(新浪微博SDK、微信SDK、QQ登录SDK):如果您将您的传控科技账户与第三方服务相关联或使用第三方服务登录您的传控科技账户,相关第三方服务可能会向我们发送您在该服务中的注册信息和个人资料信息。信息因服务而异,由相关服务控制或由您通过相关服务的隐私设置授权。使用第三方登录功能和一键快速登录功能时,在您授权同意后,新浪微博登录SDK、微信SDK、QQ登录SDK可能获取访问您的读写入外部存储、WiFi权限、网络状态、电话状态、检索正在运行的应用,用于保证对应功能的正常使用。 |
|||
</view> |
|||
<view class="fs12"> |
|||
支付(支付宝、微信SDK):为实现用户在线支付购买增值服务产品,在您授权同意后,微信、支付宝SDK可能获取访问您的网络状态、读取电话状态、Wi-Fi状态,确保您在服务中正常使用在线支付的功能。您可选择关闭相应的授权,但可能造成您无法购买我们的增值产品或服务。 |
|||
</view> |
|||
<view class="fs12"> |
|||
定位(腾讯地图SDK):在您授权同意后,腾讯地图SDK可能获取访问您所在的城市、地区以及位置信息、网络状态、读写外部存储权限、Wi-Fi状态。您可选择关闭相应的授权,但可能造成您无法接收附近的职位信息。 |
|||
</view> |
|||
<view class="fs12"> |
|||
分享(微信、QQ、新浪微博SDK):为了实现分享到第三方的功能,在您授权同意后,微信SDK、QQSDK、新浪微博SDK可能获取访问您的读写入外部存储、WiFi权限、网络状态、电话状态,用于保证对应功能的正常使用。 |
|||
</view> |
|||
<view class="fs12"> |
|||
其他来源。在适用法律允许的情况下,我们可以从第三方服务提供商和/或合作伙伴处获得您的额外信息,并将此类信息与我们所拥有的您的信息整合。我们可以通过合作伙伴获得您的信息以及您在传控科技内外的活动信息,或您在合作伙伴广告网络的体验与互动信息。 |
|||
</view> |
|||
<view class="fs16"> |
|||
2 我们如何使用所收集的信息 |
|||
</view> |
|||
<view class="fs12"> |
|||
我们遵循“合法、正当、必要”的原则使用、存储和处理您的信息(包括个人信息),以提供、了解、改进和发展传控科技,创建和维护一个受到信任的、更安全的环境,并遵守我们的法律义务。其中,如涉及您的个人化信息,我们将通过技术手段对数据进行去标识化处理,去标识化处理的信息将无法识别主体。我们有权使用已经去标识化的信息;并在不透露您个人信息的前提下,对用户数据库进行分析、利用。 |
|||
</view> |
|||
<view class="fs16"> |
|||
3 我们可能共享、转让、公开披露信息 |
|||
</view> |
|||
<view class="fs12"> |
|||
获得您的明确同意后,我们会与其他方共享您的个人信息。 |
|||
</view> |
|||
<view class="fs12"> |
|||
为便于我们基于关联账号共同向您提供服务,推荐您可能感兴趣的信息或保护传控科技关联公司或其他用户或公众的人身财产安全免遭侵害,您的个人信息可能会与我们的关联公司共享。 |
|||
</view> |
|||
<view class="fs12"> |
|||
仅为实现本隐私权政策中声明的目的,我们的某些服务将由我们和授权合作伙伴共同提供。我们仅会出于合法、正当、必要、特定、明确的目的共享您的个人信息,并且只会共享提供服务所必要的个人信息,以提供更好的客户服务和用户体验。我们的合作伙伴必须遵守我们的数据隐私和安全要求,并且无权将共享的个人信息用于与产品或服务无关的其他用途。 |
|||
</view> |
|||
在传控科技服务提供者发生合并、收购或破产清算情形,或其他涉及合并、收购或破产清算情形时,如涉及到个人信息转让,我们会要求新的持有您个人信息的公司、组织继续受本政策的约束,否则我们将要求该公司、组织和个人重新向您征求授权同意。 |
|||
<view class="fs12"> |
|||
尤其注意:以下情形中,共享、转让、公开披露您的个人信息无需事先征得您的授权同意: |
|||
</view> |
|||
<view class="fs12"> |
|||
依照法律、法规、法院命令、监管机构命令的要求,或根据政府行为、监管要求或请求; |
|||
</view> |
|||
<view class="fs12"> |
|||
为执行相关服务协议或本政策、维护社会公共利益,为保护使用者、我们的客户、我们或我们的关联公司、其他用户或雇员的人身财产安全或其他合法权益合理且必要的用途; |
|||
</view> |
|||
<view class="fs12"> |
|||
为提供和优化我们的服务,我们的服务中内嵌了第三方的SDK,比如:您需要确定比赛或会议的地理位置,可以调用腾讯地图的定位和导航功能。在您调用相关功能时,第三方SDK可能与我们收集您的个人常用设备信息(硬件序列号、设备MAC地址、唯一设备识别码)、网络身份标识信息和其他可识别的信息,上述所有信息将去标识化传输。 |
|||
</view> |
|||
<view class="fs16"> |
|||
4 您的权利 |
|||
</view> |
|||
<view class="fs14"> |
|||
4.1 管理您的信息 |
|||
</view> |
|||
<view class="fs12"> |
|||
除法律规定外,您有权访问和管理您的信息。我们鼓励您更新和修改您的信息以使其更准确有效。 |
|||
</view> |
|||
<view class="fs14"> |
|||
4.2 更正不准确或不完整的信息 |
|||
</view> |
|||
<view class="fs12"> |
|||
您在账户内可修改您的原有个人信息设置。当您发现我们处理的关于您的个人信息有错误且您无法在账户内自行修改时,您有权通过“联系我们“要求我们更正您的不准确或不完整的个人信息。 |
|||
</view> |
|||
<view class="fs14"> |
|||
4.3 数据保留与删除 |
|||
</view> |
|||
<view class="fs12"> |
|||
通常,我们只在履行您与我们之间的约定的服务并遵守我们的法律义务的必要时间段内保留您的不可识别个人信息。如果您不再希望我们使用您的信息来为您提供服务,您可以通过“联系我们“要求我们删除您的个人信息。 |
|||
</view> |
|||
<view class="fs14"> |
|||
4.4 撤销同意和处理限制 |
|||
</view> |
|||
<view class="fs12"> |
|||
当您撤销同意或授权后,我们将不再处理相应的信息,但请您理解,当您撤销同意或授权后,我们无法继续为您提供撤销同意或授权所对应的全部或部分功能和服务。您也可以通过“联系我们“向传控科技发送消息来撤销您的同意,同时说明您要撤销哪一项同意。请注意,撤销您的同意不会影响任何在此撤销之前依据此类同意的处理活动的合法性。 |
|||
</view> |
|||
<view class="fs12"> |
|||
请您理解,在您访问、修改和删除相关信息时,我们可能会要求您进行身份验证,以保障账号的安全。同时,由于技术所限、法律或监管要求,我们可能无法满足您的所有要求,原则上我们会在15个工作日内答复您的请求。 |
|||
</view> |
|||
<view class="fs14"> |
|||
4.5 注销权 |
|||
</view> |
|||
<view class="fs12"> |
|||
一般情况下,您可以通过网上自助或联系客服方式,注销您此前注册的账号,我们将尽快删除该账号。账户注销可能会导致清除您的所有用户数据和账户信息且不可恢复;但在特定的情形下,如合理必要地履行我们的法律义务、解决争议、防止欺诈和滥用,我们将在您的账号注销后保留不可识别个人的信息。 |
|||
</view> |
|||
<view class="fs12"> |
|||
您可根据以下“联系我们”部分所列的方式与我们联络,以行使上述权利;或者对于通过传控科技网站和传控科技App收集的个人信息,您可通过传控科技网站或App中的帮助与反馈功能提交相关权利要求。当您请求行使上述权利,或进行其他申诉时,原则上我们将于15个工作日内回复处理意见或结果。 |
|||
</view> |
|||
<view class="fs14"> |
|||
4.6 例外情况 |
|||
</view> |
|||
<view class="fs12"> |
|||
依据相关法律法规及国家相关标准,在以下情形中,我们可能无法响应您的请求: |
|||
</view> |
|||
<view class="fs12"> |
|||
(1)与国家安全、国防安全直接相关的; |
|||
</view> |
|||
<view class="fs12"> |
|||
(2)与公共安全、公共卫生、重大公共利益直接相关的; |
|||
</view> |
|||
<view class="fs12"> |
|||
(3)与犯罪侦查、起诉、审判和执行判决等直接相关的; |
|||
</view> |
|||
<view class="fs12"> |
|||
(4)有充分证据表明您存在主观恶意或滥用权利的; |
|||
</view> |
|||
<view class="fs12"> |
|||
(5)响应您的请求将导致其他个人、组织的合法权益受到严重损害的; |
|||
</view> |
|||
<view class="fs12"> |
|||
(6)涉及商业秘密的。 |
|||
</view> |
|||
<view class="fs16"> |
|||
5 第三方网站 |
|||
</view> |
|||
<view class="fs12"> |
|||
我们的网站中可能包含第三方运营网站的链接。对于与传控科技网站链接或传控科技网站包含的第三方运营网站的相关产品或服务,需受他们的隐私政策约束,但这并不意味着传控科技认可或负责该第三方运营网站的隐私政策。此外,我们的网站中还存在网络110报警服务,以响应您的紧急安全请求。 |
|||
</view> |
|||
<view class="fs16"> |
|||
6 我们如何保存和保护您的信息 |
|||
</view> |
|||
<view class="fs12"> |
|||
我们高度重视您的信息安全,我们将严格遵守相关法律法规规定,采取业内认可的合理可行的措施,保存和保护您的信息。防止信息遭到未经授权的访问、披露、使用、修改,避免信息损坏或丢失。 |
|||
</view> |
|||
<view class="fs14"> |
|||
6.1 保存期限 |
|||
</view> |
|||
<view class="fs12"> |
|||
我们仅为实现本隐私条款的目的所需的期限和法律法规及监管规定的最短时限内,保留您的信息,超出上述期限后,我们将删除您的个人信息或对您的个人信息进行匿名化处理。但如出现下列情况下,我们将更改信息的存储时间: |
|||
</view> |
|||
<view class="fs12"> |
|||
(1)法律法规等有关规定的要求; |
|||
</view> |
|||
<view class="fs12"> |
|||
(2)法院判决、裁定或其他法律程序规定的要求; |
|||
</view> |
|||
<view class="fs12"> |
|||
(3)相关行政机关的强制要求; |
|||
</view> |
|||
<view class="fs12"> |
|||
(4)我们有理由确信需要遵守法律法规等有关规定; |
|||
</view> |
|||
<view class="fs12"> |
|||
(5)为执行相关服务协议或本隐私条款、维护社会公共利益,为保护们的客户、我们或我们的关联公司、其他用户或雇员的人身财产安全或其他合法权益所合理必需的用途; |
|||
</view> |
|||
<view class="fs12"> |
|||
(6)当我们的产品或服务发生停止运营的情形时,我们将采取例如邮件、信函、电话、推送通知、公告等形式通知您,并在合理的期限内删除或匿名化处理您的信息。 |
|||
</view> |
|||
<view class="fs14"> |
|||
6.2 保存地域 |
|||
</view> |
|||
<view class="fs12"> |
|||
我们在中华人民共和国境内运营中收集和产生的个人信息,存储在中国境内,以下情形除外: |
|||
</view> |
|||
<view class="fs12"> |
|||
(1)法律法规有明确规定; |
|||
</view> |
|||
<view class="fs12"> |
|||
(2)获得您的明确授权; |
|||
</view> |
|||
<view class="fs12"> |
|||
针对以上情形,我们会确保依据本隐私条款对您的个人信息提供足够的保护。 |
|||
</view> |
|||
vi<view class="fs14"> |
|||
6.3 技术措施与数据安全措施 |
|||
</view> |
|||
<view class="fs12"> |
|||
(1)我们努力采取各种合理可行的措施来保护您的信息安全。我们积极建立数据分类分级制度、数据安全管理规范、数据安全开发规范来管理规范信息的存储和使用,确保未收集与我们提供的服务无关的信息。 |
|||
</view> |
|||
<view class="fs12"> |
|||
(2)我们通过与信息接触者签署保密协议、监控和审计机制来对数据进行全面安全控制。防止您的信息遭到未经授权的访问、公开披露、使用、修改、损坏或丢失。 |
|||
</view> |
|||
<view class="fs12"> |
|||
(3)我们已使用符合业界标准的安全防护措施保护您提供的信息,防止数据遭到未经授权的访问、公开披露、使用、修改,防止数据发生损坏或丢失。我们会采取一切合理可行的措施,保护您的信息。例如,在您的浏览器与服务之间交换数据时受SSL加密保护;我们同时对传控科技网站提供https安全浏览方式;我们会使用加密技术确保数据的保密性;我们会使用受信赖的保护机制防止数据遭到恶意攻击;我们会部署访问控制机制,确保只有授权人员才可以访问信息;以及我们会举办安全和隐私保护培训课程,加强员工对于保护信息重要性的认识。 |
|||
</view> |
|||
<view class="fs14"> |
|||
6.4 安全事件通知 |
|||
</view> |
|||
<view class="fs12"> |
|||
我们会制定网络安全事件应急预案,及时处置系统漏洞、计算机病毒、网络攻击、网络侵入等安全风险,在发生危害网络安全的事件时,我们会立即启动应急预案,采取相应的补救措施,并按照适用法律及法规向有关主管部门报告。 |
|||
</view> |
|||
<view class="fs12"> |
|||
在发生安全事件后,我们将按照法律法规的要求,及时向您告知安全事件的基本情况和可能的影响、我们已采取或将要采取的处理措施、您可自主防范和降低的风险的建议、对您的补救措施等。我们将及时将事件相关情况以短信通知、电话、邮件等您预留的联系方式告知您,难以逐一告知时我们会采取合理、有效的方式发布公告。 |
|||
</view>
<view class="fs16"> |
|||
7 未成年人保护 |
|||
</view> |
|||
<view class="fs12"> |
|||
除了适用法律要求外,我们不会在明知的情况下收集未成年人(未满十八周岁)的个人信息。我们将在信息收集的相关功能中对年龄进行限定,不再提供十八周岁以下的年龄区间选项。十六周岁至十八周岁的未成年人使用传控科技服务,应当由监护人仔细阅读本隐私条款、注册账户和填写相关信息,并应确保已征得其监护人同意的前提下使用我们的产品和服务并向我们提供您的信息。如未经其监护人同意,未成年人请勿向我们提供个人信息。如您的监护人不同意您按照本隐私条款使用我们的产品和服务并向我们提供信息,请您立即终止使用我们的服务并及时通知我们,以便我们采取相应的措施。如果监护人发现我们对您所监护的未成年人的信息处理有任何疑问,请通过本隐私条款公布的联系方式及时联系我们。我们将根据国家相关法律法规及本隐私条款的规定重点保护未成年人信息的保密性及安全性。 |
|||
</view> |
|||
<view class="fs16"> |
|||
8 本《隐私条款》的变更 |
|||
</view> |
|||
<view class="fs12"> |
|||
传控科技保留随时根据本条规定修改本《隐私条款》的权利。如果我们对本《隐私条款》做出变更,我们将发布变更后的《隐私条款》,并更新《隐私条款》顶端的“最后更新”日期。如本政策发生更新,我们将以移动端推送通知或者在传控科技官方网站发布公告的方式来通知您。为了您能及时接收到通知,建议您在联系方式更新时及时通知我们。如果您不同意变更后的《隐私条款》,您可以注销您的账户。如果您未在变更后的《隐私条款》生效前注销您的账户,您对传控科技的继续访问或使用将受变更后的《隐私条款》的约束。 |
|||
</view> |
|||
<view class="fs16"> |
|||
9 联系我们 |
|||
</view> |
|||
<view class="fs12"> |
|||
公司名称:山西传控电子科技有限公司 |
|||
</view> |
|||
<view class="fs12"> |
|||
注册地址:山西综改示范区太原学府园区发展路15号中绿大厦2-5层创时代孵化器508室 |
|||
</view> |
|||
<view class="fs12"> |
|||
联系方式:如果您对本《隐私条款》或传控科技的信息处理方法有任何疑问、意见、建议以及申诉,您可以通过产品的帮助与反馈功能或如下方式同我们联系: |
|||
</view> |
|||
<view class="fs12"> |
|||
电话:(010)88850886-803(工作日 9:30-18:00) |
|||
</view> |
|||
<view class="fs12"> |
|||
官网:www.ccsens.com |
|||
</view> |
|||
<view class="fs12"> |
|||
邮箱:who@ccsens.com |
|||
</view> |
|||
<view class="fs12"> |
|||
为了核查您的问题并及时向您反馈,我们可能需要您提交身份证明、有效联系方式和书面请求及相关证据。我们会妥善处理并及时反馈您的疑问、意见、建议以及申诉,一般情况下,我们会在15个工作日内对您的请求予以答复。 |
|||
</view> |
|||
</view> |
|||
<view class="safe-sure"> |
|||
<icon type="icon" class="cuIcon-roundcheckfill green-icon safe-icon" :class="active === 1 ? 'active111' : ''" @click="changeSafe"></icon> |
|||
<text @click="changeSafe">同意</text> |
|||
<button class="safe-btn" type="default" @click="register">确认</button> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
|
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { register } from 'api/register' |
|||
import { getbase } from 'api/getbase' |
|||
import { getcode } from 'api/getcode' |
|||
import { phone } from 'api/phone' |
|||
export default { |
|||
data() { |
|||
return { |
|||
username:'', |
|||
password:'', |
|||
code: '', |
|||
cooling: true, |
|||
content: '获取验证码', |
|||
imgbox: false, |
|||
imgsrc: '', |
|||
codeId: '', |
|||
codeinput: '', |
|||
safe: 0, |
|||
active: 0, |
|||
tips: 0, |
|||
dotStyle: true, |
|||
swiperList: [{ |
|||
id: 0, |
|||
type: 'img', |
|||
url: 'static/title.png' |
|||
}, { |
|||
id: 1, |
|||
type: 'img', |
|||
url: 'static/item01.png', |
|||
}, { |
|||
id: 2, |
|||
type: 'img', |
|||
url: 'static/item02.png' |
|||
}] |
|||
} |
|||
}, |
|||
methods: { |
|||
jump() { |
|||
uni.navigateTo({ |
|||
url:`./Login` |
|||
}) |
|||
}, |
|||
changeSafe() { |
|||
const that = this |
|||
if (that.active === 0) { |
|||
that.active = 1 |
|||
} else { |
|||
that.active = 0 |
|||
} |
|||
}, |
|||
async get() { |
|||
const that = this |
|||
if (!/^1([3-9])[0-9]{9}$/.test(that.username)) { |
|||
uni.showToast({ |
|||
title: '请输入正确的手机号', |
|||
icon: 'loading', |
|||
duration: 2000 |
|||
}) |
|||
} else { |
|||
const params = { |
|||
|
|||
} |
|||
const data = await getbase(params) |
|||
console.log(data) |
|||
that.imgsrc = data.imageBase64 |
|||
that.codeId = data.verificationCodeId |
|||
that.imgbox = true |
|||
} |
|||
}, |
|||
async register() { |
|||
const that = this |
|||
if (that.active === 0) { |
|||
uni.showToast({ |
|||
title: '请先同意', |
|||
icon: 'none', |
|||
duration:1500 |
|||
}) |
|||
} else if (that.active === 1) { |
|||
try{ |
|||
const params = { |
|||
account: that.username, |
|||
phone: that.username, |
|||
password: that.password, |
|||
smsCode: that.code, |
|||
source: 1 |
|||
} |
|||
const data = await register(params) |
|||
console.log(data) |
|||
if (!data || !data.token) { |
|||
uni.showToast({ |
|||
title: '注册失败', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
}else if (data.account) { |
|||
uni.showToast({ |
|||
title: '注册成功,自动跳转到登录界面', |
|||
icon: 'success', |
|||
duration: 1500 |
|||
}) |
|||
setTimeout(function () { |
|||
uni.navigateTo({ |
|||
url:`./Login` |
|||
}) |
|||
},1500) |
|||
} |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
uni.showToast({ |
|||
title: e, |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
that.safe = 0 |
|||
} |
|||
} |
|||
}, |
|||
showBox() { |
|||
const that = this |
|||
if (that.username === '') { |
|||
uni.showToast({ |
|||
title: '请输入手机号', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.password === '') { |
|||
uni.showToast({ |
|||
title: '请输入密码', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.code === '') { |
|||
uni.showToast({ |
|||
title: '请输入验证码', |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else { |
|||
that.safe = 1 |
|||
} |
|||
}, |
|||
mask() { |
|||
const that = this |
|||
that.safe = 0 |
|||
}, |
|||
async submit() { |
|||
const that = this |
|||
try{ |
|||
const params = { |
|||
params: { |
|||
phone: that.username, |
|||
verificationCodeId: that.codeId, |
|||
verificationCodeValue: that.codeinput |
|||
} |
|||
} |
|||
const data = await getcode(params) |
|||
console.log(data) |
|||
if (data.expiredInSeconds) { |
|||
that.imgbox = false |
|||
uni.showToast({ |
|||
title: '正在获取', |
|||
icon: 'success', |
|||
duration: 3000 |
|||
}) |
|||
if (that.cooling) { |
|||
that.cooling = false |
|||
var a = 60 |
|||
that.content = a + 's' |
|||
var aaa = setInterval(function () { |
|||
a -= 1 |
|||
that.content = a + 's' |
|||
if (a - 0 === 0) { |
|||
that.cooling = true |
|||
that.content = '获取验证码' |
|||
clearInterval(aaa) |
|||
} |
|||
},1000) |
|||
} |
|||
} |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
uni.showToast({ |
|||
title: e, |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} |
|||
} |
|||
}, |
|||
watch:{ |
|||
async username(val){ |
|||
const that = this |
|||
that.tips = 0 |
|||
if (that.username.length - 0 === 11) { |
|||
const params = { |
|||
params: { |
|||
phone : that.username |
|||
} |
|||
} |
|||
const data = await phone(params) |
|||
if (data) { |
|||
that.tips = 1 |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.title { |
|||
font-size: 20px; |
|||
width: 150rpx; |
|||
height: 30px; |
|||
line-height: 30px; |
|||
margin-top: 30px; |
|||
border-bottom: 2px solid $blue; |
|||
margin-left: 300rpx; |
|||
text-align: center; |
|||
} |
|||
.ipt-infor { |
|||
margin-left: 50rpx; |
|||
width: 650rpx; |
|||
margin-top: 50px; |
|||
view{ |
|||
padding-left: 75px; |
|||
} |
|||
} |
|||
.ipt-username { |
|||
position: relative; |
|||
height: 60px; |
|||
line-height: 60px; |
|||
border-bottom: 1px solid $grey; |
|||
|
|||
input { |
|||
position: absolute; |
|||
top: 20px; |
|||
left: 90px; |
|||
font-size: 14px; |
|||
} |
|||
} |
|||
.ipt-password { |
|||
position: relative; |
|||
height: 60px; |
|||
line-height: 60px; |
|||
border-bottom: 1px solid $grey; |
|||
|
|||
input { |
|||
position: absolute; |
|||
top: 20px; |
|||
left: 90px; |
|||
height: 20px; |
|||
line-height: 20px; |
|||
font-size: 14px; |
|||
} |
|||
} |
|||
.btn { |
|||
width: 650rpx; |
|||
margin-left: 50rpx; |
|||
background: $blue; |
|||
color: $white; |
|||
margin-top: 50px; |
|||
} |
|||
.go-register { |
|||
color: $blue; |
|||
position: absolute; |
|||
right: 50rpx; |
|||
margin-top: 20px; |
|||
} |
|||
|
|||
.btn-code { |
|||
width: 100px; |
|||
height: 30px; |
|||
line-height: 30px; |
|||
font-size: 12px; |
|||
position: absolute; |
|||
right: 0; |
|||
top: 15px; |
|||
} |
|||
.active { |
|||
background: $green; |
|||
color: $white; |
|||
} |
|||
.img-box { |
|||
height: 650rpx; |
|||
width: 650rpx; |
|||
background: white; |
|||
border: 1px solid $gray; |
|||
border-radius: 10px; |
|||
position: fixed; |
|||
padding: 25rpx; |
|||
top: 0; |
|||
left: 50rpx; |
|||
margin-top: 45%; |
|||
z-index: 1; |
|||
image { |
|||
width: 500rpx; |
|||
height: 390rpx; |
|||
margin-left: 50rpx; |
|||
background-color: red; |
|||
} |
|||
input { |
|||
border: 1px solid $blue; |
|||
width: 500rpx; |
|||
margin-left: 50rpx; |
|||
margin-top: 40rpx; |
|||
height: 80rpx; |
|||
font-size: 18px; |
|||
padding-left: 5%; |
|||
border-radius: 10px; |
|||
} |
|||
} |
|||
.btn-box { |
|||
display: flex; |
|||
position: absolute; |
|||
bottom: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 80rpx; |
|||
button { |
|||
// flex: 1; |
|||
width: 40%; |
|||
height: 80rpx; |
|||
line-height: 80rpx; |
|||
} |
|||
.success { |
|||
background: $green; |
|||
color: $white; |
|||
} |
|||
} |
|||
.img { |
|||
width: 750rpx; |
|||
top: 0; |
|||
height: 100%; |
|||
z-index: 1000; |
|||
} |
|||
.safe-box { |
|||
position: absolute; |
|||
width: 680rpx; |
|||
padding: 20px; |
|||
border-radius: 10px; |
|||
height: 680rpx; |
|||
top: 20%; |
|||
z-index: 10; |
|||
background: white; |
|||
left: 35rpx; |
|||
} |
|||
.safe-sure { |
|||
font-size: 14px; |
|||
padding-top: 5px; |
|||
} |
|||
.active111 { |
|||
color: $green !important; |
|||
} |
|||
.green-icon { |
|||
font-size: 16px !important; |
|||
color: $gray; |
|||
} |
|||
.box111 { |
|||
position: fixed; |
|||
height: 100%; |
|||
width: 100%; |
|||
top: 0; |
|||
left: 0; |
|||
background: rgba(0,0,0,0.5); |
|||
} |
|||
.safe-title { |
|||
text-align: center; |
|||
font-size: 16px; |
|||
} |
|||
.safe-content { |
|||
height: 70%; |
|||
overflow: auto; |
|||
} |
|||
.safe-btn { |
|||
margin-top: 5px; |
|||
} |
|||
.just-box{ |
|||
position: absolute; |
|||
width: 50px; |
|||
font-size: 14px; |
|||
left: 20px; |
|||
text-align: center; |
|||
text-align: justify !important; |
|||
text-align-last: justify; |
|||
} |
|||
.just-tips { |
|||
position: absolute; |
|||
bottom: 0; |
|||
color: $red; |
|||
height: 14px; |
|||
line-height: 14px; |
|||
font-size: 14px; |
|||
left: 90px; |
|||
} |
|||
.fs16{ |
|||
font-size: 16px; |
|||
} |
|||
.fs14{ |
|||
font-size: 14px; |
|||
text-indent: 1em; |
|||
} |
|||
.fs12{ |
|||
font-size: 12px; |
|||
text-indent: 2em; |
|||
} |
|||
</style> |
@ -0,0 +1,282 @@ |
|||
<template> |
|||
<view> |
|||
<swiper class="screen-swiper" :class="dotStyle?'square-dot':'round-dot'" :indicator-dots="true" :circular="true" |
|||
:autoplay="true" interval="3000" duration="500"> |
|||
<swiper-item v-for="(item,index) in swiperList" :key="index"> |
|||
<img class="img" :src="item.url" mode="aspectFill" v-if="item.type=='img'"></img> |
|||
</swiper-item> |
|||
</swiper> |
|||
<view class="title"> |
|||
找回密码 |
|||
</view> |
|||
<view class="ipt-infor"> |
|||
<view class="ipt-username"> |
|||
<text>手机号:</text><input type="text" v-model.trim="username" placeholder="请输入"/> |
|||
</view> |
|||
<view class="ipt-username"> |
|||
<text>验证码:</text><input type="text" v-model.trim="code" placeholder="请输入"/> |
|||
<button type="default" class="btn-code" :class="cooling? 'active' : ''" @click="get">{{ content }}</button> |
|||
</view> |
|||
<view class="ipt-password"> |
|||
<text>新密码:</text><input type="password" v-model.trim="password" placeholder="请输入"/> |
|||
</view> |
|||
</view> |
|||
<view class="img-box" v-show="imgbox"> |
|||
<image :src="imgsrc" mode=""></image> |
|||
<input type="text" placeholder="请输入验证码" v-model.trim="codeinput"/> |
|||
<view class="btn-box"> |
|||
<button type="default" @click="imgbox = false">关闭</button> |
|||
<button type="default" class="success" @click="submit">确定</button> |
|||
</view> |
|||
</view> |
|||
<button type="default" class="btn cu-btn bg-green margin-tb-sm lg" @click="register">确定修改</button> |
|||
<view class="go-register" @click="jump">登录</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { password } from 'api/password' |
|||
import { getbase } from 'api/getbase' |
|||
import { getcode } from 'api/getcode' |
|||
export default { |
|||
data() { |
|||
return { |
|||
username:'', |
|||
password:'', |
|||
code: '', |
|||
cooling: true, |
|||
content: '获取验证码', |
|||
imgbox: false, |
|||
imgsrc: '', |
|||
codeId: '', |
|||
codeinput: '', |
|||
dotStyle: true, |
|||
swiperList: [{ |
|||
id: 0, |
|||
type: 'img', |
|||
url: 'static/title.png' |
|||
}, { |
|||
id: 1, |
|||
type: 'img', |
|||
url: 'static/item01.png', |
|||
}, { |
|||
id: 2, |
|||
type: 'img', |
|||
url: 'static/item02.png' |
|||
}] |
|||
} |
|||
}, |
|||
methods: { |
|||
jump() { |
|||
uni.navigateTo({ |
|||
url:`./Login` |
|||
}) |
|||
}, |
|||
async get() { |
|||
const that = this |
|||
const params = { |
|||
|
|||
} |
|||
const data = await getbase(params) |
|||
console.log(data) |
|||
that.imgsrc = data.imageBase64 |
|||
that.codeId = data.verificationCodeId |
|||
that.imgbox = true |
|||
|
|||
}, |
|||
async register() { |
|||
const that = this |
|||
try{ |
|||
const params = { |
|||
phone: that.username, |
|||
password: that.password, |
|||
code: that.code |
|||
} |
|||
const data = await password(params) |
|||
console.log(data) |
|||
if (!data || !data.token) { |
|||
uni.showToast({ |
|||
title: '修改成功', |
|||
icon: 'success', |
|||
duration: 1500 |
|||
}) |
|||
} |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
uni.showToast({ |
|||
title: e, |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} |
|||
}, |
|||
async submit() { |
|||
const that = this |
|||
try{ |
|||
const params = { |
|||
params: { |
|||
phone: that.username, |
|||
verificationCodeId: that.codeId, |
|||
verificationCodeValue: that.codeinput |
|||
} |
|||
} |
|||
const data = await getcode(params) |
|||
console.log(data) |
|||
if (data.expiredInSeconds) { |
|||
that.imgbox = false |
|||
uni.showToast({ |
|||
title: '正在获取', |
|||
icon: 'success', |
|||
duration: 3000 |
|||
}) |
|||
if (that.cooling) { |
|||
that.cooling = false |
|||
var a = 60 |
|||
that.content = a + 's' |
|||
var aaa = setInterval(function () { |
|||
a -= 1 |
|||
that.content = a + 's' |
|||
if (a - 0 === 0) { |
|||
that.cooling = true |
|||
that.content = '获取验证码' |
|||
clearInterval(aaa) |
|||
} |
|||
},1000) |
|||
} |
|||
} |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.title { |
|||
font-size: 20px; |
|||
width: 200rpx; |
|||
height: 30px; |
|||
line-height: 30px; |
|||
margin-top: 30px; |
|||
border-bottom: 2px solid $blue; |
|||
margin-left: 275rpx; |
|||
text-align: center; |
|||
} |
|||
.ipt-infor { |
|||
margin-left: 50rpx; |
|||
width: 650rpx; |
|||
margin-top: 50px; |
|||
view{ |
|||
padding-left: 50rpx; |
|||
} |
|||
} |
|||
.ipt-username { |
|||
position: relative; |
|||
height: 60px; |
|||
line-height: 60px; |
|||
border-bottom: 1px solid $grey; |
|||
|
|||
input { |
|||
position: absolute; |
|||
top: 20px; |
|||
left: 90px; |
|||
font-size: 14px; |
|||
} |
|||
} |
|||
.ipt-password { |
|||
position: relative; |
|||
height: 60px; |
|||
line-height: 60px; |
|||
border-bottom: 1px solid $grey; |
|||
|
|||
input { |
|||
position: absolute; |
|||
top: 20px; |
|||
left: 90px; |
|||
height: 20px; |
|||
line-height: 20px; |
|||
font-size: 14px; |
|||
} |
|||
} |
|||
.btn { |
|||
width: 650rpx; |
|||
margin-left: 50rpx; |
|||
background: $blue; |
|||
color: $white; |
|||
margin-top: 50px; |
|||
} |
|||
.go-register { |
|||
color: $blue; |
|||
position: absolute; |
|||
right: 50rpx; |
|||
margin-top: 20px; |
|||
} |
|||
|
|||
.btn-code { |
|||
width: 100px; |
|||
height: 30px; |
|||
line-height: 30px; |
|||
font-size: 12px; |
|||
position: absolute; |
|||
right: 0; |
|||
top: 15px; |
|||
} |
|||
.active { |
|||
background: $green; |
|||
color: $white; |
|||
} |
|||
.img-box { |
|||
height: 650rpx; |
|||
width: 650rpx; |
|||
background: white; |
|||
border: 1px solid $gray; |
|||
border-radius: 10px; |
|||
position: fixed; |
|||
padding: 25rpx; |
|||
top: 0; |
|||
left: 50rpx; |
|||
margin-top: 45%; |
|||
z-index: 1; |
|||
image { |
|||
width: 500rpx; |
|||
height: 390rpx; |
|||
margin-left: 50rpx; |
|||
background-color: red; |
|||
} |
|||
input { |
|||
border: 1px solid $blue; |
|||
width: 500rpx; |
|||
margin-left: 50rpx; |
|||
margin-top: 40rpx; |
|||
height: 80rpx; |
|||
font-size: 18px; |
|||
padding-left: 5%; |
|||
border-radius: 10px; |
|||
} |
|||
} |
|||
.btn-box { |
|||
display: flex; |
|||
position: absolute; |
|||
bottom: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 80rpx; |
|||
button { |
|||
// flex: 1; |
|||
width: 40%; |
|||
height: 80rpx; |
|||
line-height: 80rpx; |
|||
} |
|||
.success { |
|||
background: $green; |
|||
color: $white; |
|||
} |
|||
} |
|||
.img { |
|||
width: 750rpx; |
|||
top: 0; |
|||
height: 100%; |
|||
z-index: 1000; |
|||
} |
|||
</style> |
@ -0,0 +1,209 @@ |
|||
<template> |
|||
<view> |
|||
<view class="sign-up" v-show="submit === 0" @click="changeSub"> |
|||
添加报名 |
|||
</view> |
|||
<!-- <view class="sign-up" v-show="submit === 0" @click="changeSub"> |
|||
已报名{{}}/{{ objdata.memberMax }}人 |
|||
</view> --> |
|||
<view class="member-box" v-for="(item,index) in list" :key="index"> |
|||
<view class="member-title">{{ item.groupName }}</view> |
|||
<view class="member-con" v-for="(a,b) in item.playerList" :key="b" :class="a.joinProject ? 'active' : ''" v-show="(a.joinProject === 1||submit === 1)? true : false" @click="submit === 1? change(index,b) : ''"> |
|||
<icon v-show="submit === 1" type="icon" class="cuIcon-roundcheckfill back" :class="a.joinProject ? 'backactive' : ''"></icon>{{ a.playerName }} |
|||
</view> |
|||
</view> |
|||
<button @click="trans" v-show="submit === 1" type="default" class="btn cu-btn bg-green margin-tb-sm lg">提交</button> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { groupplayer } from 'api/groupplayer' |
|||
import { join } from 'api/join' |
|||
export default { |
|||
onLoad(option) { |
|||
const obj = JSON.parse(option.obj) |
|||
const that = this |
|||
that.objdata = obj |
|||
that.query() |
|||
}, |
|||
data() { |
|||
return { |
|||
list: [], |
|||
objdata: {}, |
|||
submit: 2, |
|||
changeList: [], |
|||
originalList: [] |
|||
} |
|||
}, |
|||
methods: { |
|||
async query () { |
|||
const that = this |
|||
try{ |
|||
const params = { |
|||
param: { |
|||
companyId: that.$store.state.project.companyId, |
|||
projectId: that.objdata.id |
|||
} |
|||
} |
|||
const data = await groupplayer(params) |
|||
// console.log(data) |
|||
that.list = data |
|||
if (that.list[0]) { |
|||
that.submit = 0 |
|||
} else { |
|||
that.submit = 2 |
|||
} |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
} |
|||
}, |
|||
change (a,b) { |
|||
const that = this |
|||
// console.log(that.list[a].playerList[b]) // 本次点击的队员 |
|||
var obj = {} |
|||
if (that.originalList.length === 0) { |
|||
obj.playerId = that.list[a].playerList[b].playerId |
|||
obj.joinProject = that.list[a].playerList[b].joinProject |
|||
obj.playerName = that.list[a].playerList[b].playerName |
|||
that.originalList.push(obj) |
|||
} else { |
|||
// console.log('数组长度大于0了') |
|||
for (var i=0; i<that.originalList.length; i++) { |
|||
// console.log(i) |
|||
if (that.originalList[i].playerId === that.list[a].playerList[b].playerId) { |
|||
// console.log('一样,不添加') |
|||
break |
|||
} |
|||
if (i + 1 === that.originalList.length) { |
|||
// console.log('已经循环到最后了,添加并且跳出for循环吧') |
|||
obj.playerId = that.list[a].playerList[b].playerId |
|||
obj.joinProject = that.list[a].playerList[b].joinProject |
|||
obj.playerName = that.list[a].playerList[b].playerName |
|||
that.originalList.push(obj) |
|||
break |
|||
} |
|||
} |
|||
} |
|||
|
|||
if (that.list[a].playerList[b].joinProject - 0 === 0) { |
|||
that.list[a].playerList[b].joinProject = 1 |
|||
} else { |
|||
that.list[a].playerList[b].joinProject = 0 |
|||
} |
|||
|
|||
if (that.changeList.length === 0) { |
|||
that.changeList.push(that.list[a].playerList[b]) |
|||
} else { |
|||
for (var i=0; i<that.changeList.length; i++) { |
|||
if (that.changeList[i].playerId === that.list[a].playerList[b].playerId) { |
|||
that.changeList[i].joinProject = that.list[a].playerList[b].joinProject |
|||
break |
|||
} |
|||
if (i + 1 === that.changeList.length) { |
|||
that.changeList.push(that.list[a].playerList[b]) |
|||
break |
|||
} |
|||
} |
|||
} |
|||
|
|||
for (var i=0; i<that.originalList.length; i++) { |
|||
for (var j=0; j<that.changeList.length; j++) { |
|||
if (that.originalList[i].playerId === that.changeList[j].playerId) { |
|||
if (that.originalList[i].joinProject === that.changeList[j].joinProject) { |
|||
that.changeList.splice(j,1) |
|||
break |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
console.log(that.changeList) |
|||
}, |
|||
changeSub() { |
|||
const that = this |
|||
that.submit = 1 |
|||
}, |
|||
async trans() { |
|||
const that = this |
|||
try{ |
|||
const params = { |
|||
param: { |
|||
companyId: that.$store.state.project.companyId, |
|||
competeTimeId: that.$store.state.project.data.id, |
|||
players: that.changeList, |
|||
projectId: that.objdata.id |
|||
} |
|||
} |
|||
const data = await join(params) |
|||
uni.showToast({ |
|||
title: '报名成功', |
|||
icon: 'success', |
|||
duration: 1500 |
|||
}) |
|||
that.changeList = [] |
|||
that.originalList = [] |
|||
that.query() |
|||
that.$store.state.project.num++ |
|||
that.submit = 0 |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
that.submit = 1 |
|||
uni.showToast({ |
|||
title: e, |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.member-box { |
|||
margin-left: 35rpx; |
|||
width: 680rpx; |
|||
} |
|||
.member-title { |
|||
height: 40px; |
|||
line-height: 40px; |
|||
font-size: 18px; |
|||
margin-top: 10px; |
|||
border-bottom: 1px solid $grey; |
|||
} |
|||
.member-con { |
|||
position: relative; |
|||
height: 60px; |
|||
margin-top: 10px; |
|||
line-height: 60px; |
|||
border-radius: 10px; |
|||
padding-left: 50%; |
|||
box-shadow: 0 0 4px $gray; |
|||
} |
|||
.active { |
|||
box-shadow: 0 0 4px #709AFC !important; |
|||
} |
|||
.btn { |
|||
width: 680rpx; |
|||
margin-left: 35rpx; |
|||
margin-top: 30px; |
|||
background: #709AFC; |
|||
color: $white; |
|||
} |
|||
.back { |
|||
position: absolute; |
|||
color: $grey; |
|||
font-size: 30px; |
|||
left: 20px; |
|||
} |
|||
.backactive { |
|||
color: #709AFC !important; |
|||
} |
|||
.sign-up { |
|||
position: absolute; |
|||
right: 35rpx; |
|||
padding: 5px 10px; |
|||
border-radius: 5px; |
|||
box-shadow: 0 0 5px $gray; |
|||
} |
|||
</style> |
@ -0,0 +1,225 @@ |
|||
<template> |
|||
<view> |
|||
<ms-dropdown-menu class="select"> |
|||
<ms-dropdown-item v-model="value" :list="list"></ms-dropdown-item> |
|||
<ms-dropdown-item v-model="value1" :list="list1"></ms-dropdown-item> |
|||
</ms-dropdown-menu> |
|||
<!-- <button type="default" @click="btn">123</button> --> |
|||
<view class="player-box"> |
|||
<view class="player" :class="item.isjoin?'player-active':''" v-show="item.isjoin || edit - 0 === 1" v-for="(item,index) in list2" :key="index" @click="choice(index)"> |
|||
<icon type="icon" :class="item.isjoin?'backactive':''" class="cuIcon-roundcheckfill back"></icon> |
|||
{{ item.name }} |
|||
</view> |
|||
</view> |
|||
<button class="modify" type="default" @click="editData" :class="edit - 0 === 1?'mit':''"> |
|||
<text v-if="edit - 0 === 0">编辑</text> |
|||
<text v-else-if="edit - 0 === 1">提交</text> |
|||
</button> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import msDropdownMenu from '@/components/ms-dropdown/dropdown-menu.vue' |
|||
import msDropdownItem from '@/components/ms-dropdown/dropdown-item.vue' |
|||
export default { |
|||
components: { |
|||
msDropdownMenu, |
|||
msDropdownItem |
|||
}, |
|||
onLoad(option) { |
|||
const that = this |
|||
that.obj = JSON.parse(option.obj) |
|||
console.log(that.obj) |
|||
}, |
|||
data() { |
|||
return { |
|||
obj:{}, |
|||
list: [ |
|||
{ |
|||
text: '小学', |
|||
value: 0 |
|||
}, |
|||
{ |
|||
text: '中学', |
|||
value: 1 |
|||
}, |
|||
{ |
|||
text: '高职院校', |
|||
value: 2 |
|||
}, |
|||
{ |
|||
text: '本科院校', |
|||
value: 3 |
|||
}, |
|||
{ |
|||
text: '俱乐部', |
|||
value: 4 |
|||
} |
|||
], |
|||
list1: [ |
|||
{ |
|||
text: '男子组', |
|||
value: 0 |
|||
}, |
|||
{ |
|||
text: '女子组', |
|||
value: 1 |
|||
}, |
|||
{ |
|||
text: '混合组', |
|||
value: 2 |
|||
} |
|||
], |
|||
list2: [ |
|||
{ |
|||
name: '男子组', |
|||
isjoin: 0 |
|||
}, |
|||
{ |
|||
name: '女子组', |
|||
isjoin: 0 |
|||
}, |
|||
{ |
|||
name: '混合组', |
|||
isjoin: 0 |
|||
}, |
|||
{ |
|||
name: '女子组', |
|||
isjoin: 0 |
|||
}, |
|||
{ |
|||
name: '混合组', |
|||
isjoin: 0 |
|||
}, |
|||
{ |
|||
name: '女子组', |
|||
isjoin: 0 |
|||
}, |
|||
{ |
|||
name: '混合组', |
|||
isjoin: 0 |
|||
}, |
|||
{ |
|||
name: '女子组', |
|||
isjoin: 0 |
|||
}, |
|||
{ |
|||
name: '混合组', |
|||
isjoin: 0 |
|||
}, |
|||
{ |
|||
name: '女子组', |
|||
isjoin: 0 |
|||
}, |
|||
{ |
|||
name: '混合组', |
|||
isjoin: 0 |
|||
} |
|||
], |
|||
value: 0, |
|||
value1: 0, |
|||
edit: 0, |
|||
joinNum:0 |
|||
} |
|||
}, |
|||
methods: { |
|||
choose() { |
|||
const that = this |
|||
let obj = { |
|||
value: 'test' |
|||
} |
|||
this.$refs.dropdownItem.choose(obj) |
|||
}, |
|||
close() { |
|||
this.$refs.dropdownItem.closePopup() |
|||
}, |
|||
editData() { |
|||
const that = this |
|||
if(that.edit - 0 === 0) { |
|||
that.edit = 1 |
|||
} else { |
|||
if (that.joinNum - 0 === 0) { |
|||
that.edit = 0 |
|||
} else if (that.joinNum < that.obj.memberMin) { |
|||
uni.showToast({ |
|||
title:`小于最少人数${that.obj.memberMin}人`, |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else if (that.joinNum > that.obj.memberMax) { |
|||
uni.showToast({ |
|||
title:`大于最多人数${that.obj.memberMin}人`, |
|||
icon: 'none', |
|||
duration: 1500 |
|||
}) |
|||
} else { |
|||
that.edit = 0 |
|||
} |
|||
} |
|||
}, |
|||
choice(index) { |
|||
const that = this |
|||
that.joinNum = 0 |
|||
if(that.list2[`${index}`].isjoin - 0 === 0) { |
|||
that.list2[`${index}`].isjoin = 1 |
|||
} else { |
|||
that.list2[`${index}`].isjoin = 0 |
|||
} |
|||
for(var i=0; i<that.list2.length;i++) { |
|||
if(that.list2[i].isjoin - 0 === 1) { |
|||
that.joinNum++ |
|||
} |
|||
} |
|||
console.log(that.joinNum) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.select { |
|||
position: fixed; |
|||
z-index: 10; |
|||
top: 44px; |
|||
width: 750rpx !important; |
|||
box-shadow: 0 2px 10px #aaa; |
|||
margin-bottom: 20px; |
|||
} |
|||
.player-box { |
|||
width: 670rpx; |
|||
margin-top: 70px; |
|||
margin-left: 35rpx; |
|||
} |
|||
.player { |
|||
position: relative; |
|||
height: 60px; |
|||
margin-top: 10px; |
|||
line-height: 60px; |
|||
border-radius: 10px; |
|||
text-align: center; |
|||
box-shadow: 0 0 5px $gray; |
|||
} |
|||
.player-active{ |
|||
box-shadow: 0 0 4px #709AFC !important; |
|||
} |
|||
.back { |
|||
position: absolute; |
|||
color: $grey; |
|||
font-size: 30px; |
|||
left: 20px; |
|||
} |
|||
.backactive { |
|||
color: #709AFC !important; |
|||
} |
|||
.modify { |
|||
width: 670rpx; |
|||
margin-left: 35rpx; |
|||
margin-top: 50px; |
|||
box-shadow: 2px 2px 5px #C0C0C0; |
|||
margin-bottom: 100px; |
|||
} |
|||
.mit { |
|||
background: $blue; |
|||
color: $white; |
|||
} |
|||
</style> |
@ -0,0 +1,181 @@ |
|||
<template> |
|||
<view> |
|||
<view class="match-name"> |
|||
{{ obj.name }} |
|||
</view> |
|||
<view class="match-Name"></view> |
|||
<view v-if="list[0]"> |
|||
<view class="match-team" v-for="(item,index) in list" :key="index"> |
|||
<view class="team-name"> |
|||
{{ item.name }} |
|||
<icon type="icon" class="cuIcon-close icon" @click="del"></icon> |
|||
</view> |
|||
<view class="team-player"> |
|||
<view class="team-man" v-for="(a,b) in item.player" :key="b"> |
|||
{{ a }} |
|||
</view> |
|||
</view> |
|||
<button type="default" class="change" @click="edit">编辑</button> |
|||
</view> |
|||
</view> |
|||
<view class="img-B" v-else> |
|||
<img src="static/item.png" class="img-box" /> |
|||
<view> |
|||
暂无运动员信息 |
|||
</view> |
|||
</view> |
|||
<view class="add" @click="addTeam">添加</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
onLoad(option) { |
|||
const that = this |
|||
var OBJ = JSON.parse(option.obj) |
|||
console.log(option.TypeNum,OBJ) |
|||
that.obj = OBJ |
|||
}, |
|||
data() { |
|||
return { |
|||
obj: {}, |
|||
list: [{ |
|||
name:'小学女子组', |
|||
player: ['王旺旺','王旺旺','王旺旺','王旺旺','王旺旺','王旺旺','王旺旺','王旺旺','王旺旺','王旺旺','王旺旺'] |
|||
},{ |
|||
name:'小学男子组', |
|||
player: ['王旺旺','王旺旺','王旺旺','王旺旺','王旺旺','王旺旺','王旺旺','王旺旺'] |
|||
},{ |
|||
name:'小学混合组', |
|||
player: ['王旺旺','王旺旺','王旺旺'] |
|||
}] |
|||
} |
|||
}, |
|||
methods: { |
|||
del() { |
|||
uni.showModal({ |
|||
title: '提示', |
|||
content: '确定要删除整组么?', |
|||
success: (res) => { |
|||
if (res.confirm) { |
|||
console.log('确定删除') |
|||
} |
|||
if (res.cancel) { |
|||
console.log('取消') |
|||
} |
|||
} |
|||
}) |
|||
}, |
|||
edit() { |
|||
const that = this |
|||
const obj = that.obj |
|||
uni.navigateTo({ |
|||
url: `./TeamDetail?obj=${JSON.stringify(obj)}` |
|||
}) |
|||
}, |
|||
addTeam() { |
|||
const that = this |
|||
const obj = that.obj |
|||
uni.navigateTo({ |
|||
url: `./TeamDetail?obj=${JSON.stringify(obj)}` |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.match-name { |
|||
position: fixed; |
|||
text-align: center; |
|||
width: 100%; |
|||
top: 44px; |
|||
height: 40px; |
|||
line-height: 40px; |
|||
background: $white; |
|||
z-index: 10; |
|||
font-size: 20px; |
|||
} |
|||
.match-Name { |
|||
height: 40px; |
|||
} |
|||
.match-team { |
|||
// background: $yellowLight; |
|||
box-shadow: 0 0 10px #C0C0C0; |
|||
width: 670rpx; |
|||
padding-bottom: 30px; |
|||
margin-left: 35rpx; |
|||
height: auto; |
|||
max-height: 240px; |
|||
margin-top: 20px; |
|||
border-radius: 25px; |
|||
position: relative; |
|||
} |
|||
.team-name { |
|||
height: 40px; |
|||
line-height: 40px; |
|||
width: 100%; |
|||
text-align: center; |
|||
font-size: 16px; |
|||
font-weight: 600; |
|||
border-bottom: 1px solid $blueShadow; |
|||
} |
|||
.change { |
|||
width: 60px; |
|||
height: 30px; |
|||
font-size: 14px; |
|||
line-height: 30px; |
|||
position: absolute; |
|||
right: 10px; |
|||
bottom: 6px; |
|||
} |
|||
.team-player { |
|||
width: 100%; |
|||
max-height: 160px; |
|||
padding: 10px; |
|||
overflow: auto; |
|||
} |
|||
.team-man { |
|||
padding: 2px 10px; |
|||
float: left; |
|||
height: 40px; |
|||
margin-right: 10px; |
|||
margin-bottom: 10px; |
|||
line-height: 40px; |
|||
font-size: 12px; |
|||
border-radius: 10px; |
|||
box-shadow: 0 0 5px $blue; |
|||
} |
|||
.icon { |
|||
position: absolute; |
|||
top: 0; |
|||
right: 10px; |
|||
font-size: 24px; |
|||
color: #C0C0C0; |
|||
} |
|||
.add { |
|||
position: fixed; |
|||
width: 150rpx; |
|||
height: 150rpx; |
|||
background: #709AFC; |
|||
box-shadow: 0 0 20px #709AFC; |
|||
border-radius: 50%; |
|||
color: $white; |
|||
right: 10px; |
|||
bottom: 100px; |
|||
text-align: center; |
|||
line-height: 150rpx; |
|||
font-size: 18px; |
|||
} |
|||
.img-box { |
|||
width: 70%; |
|||
height: 70%; |
|||
} |
|||
.img-B { |
|||
width: 100%; |
|||
margin-top: 100px; |
|||
height: 450rpx; |
|||
text-align: center; |
|||
color: #aaa; |
|||
} |
|||
</style> |
@ -0,0 +1,86 @@ |
|||
<template> |
|||
<view> |
|||
<view class="item-box" v-for="(item,index) in list" :key="index" @click="jump(index,item)"> |
|||
<view class="item-num">{{ index + 1 }}</view> |
|||
<text class="item-content">{{ item.name }}</text> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { secondproject } from 'api/secondproject' |
|||
export default { |
|||
async onLoad (options) { |
|||
const that = this |
|||
try{ |
|||
const params = { |
|||
param: { |
|||
firstProjectId: options.id |
|||
} |
|||
} |
|||
const data = await secondproject(params) |
|||
that.list = data |
|||
console.log(data) |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
list: [], |
|||
} |
|||
}, |
|||
methods: { |
|||
jump (num,obj) { |
|||
if (obj.team - 0 === 0) { |
|||
uni.navigateTo({ |
|||
url:`./MatchDetail/MatchDetail?TypeNum=${num}&obj=${JSON.stringify(obj)}` |
|||
}) |
|||
} else { |
|||
uni.navigateTo({ |
|||
url:`./MatchDetail/TeamMatch?TypeNum=${num}&obj=${JSON.stringify(obj)}` |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.title { |
|||
text-align: center; |
|||
font-size: 12px; |
|||
color: $red; |
|||
overflow: auto; |
|||
} |
|||
.item-box { |
|||
margin-top: 24px; |
|||
height: 80px; |
|||
line-height: 80px; |
|||
font-size: 18px; |
|||
width: 670rpx; |
|||
margin-left: 40rpx; |
|||
padding-left: 56rpx; |
|||
position: relative; |
|||
box-shadow: 0px 2px 5px $grey; |
|||
border-radius: 10px; |
|||
} |
|||
.item-num { |
|||
position: relative; |
|||
width: 20px; |
|||
height: 20px; |
|||
border-radius: 5px; |
|||
top: 30px; |
|||
font-size: 12px; |
|||
text-align: center; |
|||
line-height: 20px; |
|||
background-color: #709AFC; |
|||
color: #fff; |
|||
} |
|||
.item-content { |
|||
position: absolute; |
|||
left: 150rpx; |
|||
font-size: 16px; |
|||
top: 0; |
|||
} |
|||
</style> |
@ -0,0 +1,89 @@ |
|||
<template> |
|||
<view class="box"> |
|||
<view class="item-box" v-for="(item,index) in list" :key="index" @click="jump(index,item)"> |
|||
<view class="item-num">{{ index + 1 }}</view> |
|||
<text class="item-content">{{ item.name }}</text> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { secondproject } from 'api/secondproject' |
|||
export default { |
|||
async onLoad (options) { |
|||
const that = this |
|||
try{ |
|||
const params = { |
|||
param: { |
|||
firstProjectId: options.id |
|||
} |
|||
} |
|||
const data = await secondproject(params) |
|||
that.list = data |
|||
console.log(data) |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
list: [], |
|||
} |
|||
}, |
|||
methods: { |
|||
jump (num,obj) { |
|||
if (obj.team - 0 === 0) { |
|||
uni.navigateTo({ |
|||
url:`./MatchDetail/MatchDetail?TypeNum=${num}&obj=${JSON.stringify(obj)}` |
|||
}) |
|||
} else { |
|||
uni.navigateTo({ |
|||
url:`./MatchDetail/TeamMatch?TypeNum=${num}&obj=${JSON.stringify(obj)}` |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.box { |
|||
padding-bottom: 100px; |
|||
} |
|||
.title { |
|||
text-align: center; |
|||
font-size: 12px; |
|||
color: $red; |
|||
overflow: auto; |
|||
} |
|||
.item-box { |
|||
margin-top: 24px; |
|||
height: 80px; |
|||
line-height: 80px; |
|||
font-size: 18px; |
|||
width: 670rpx; |
|||
margin-left: 40rpx; |
|||
padding-left: 56rpx; |
|||
position: relative; |
|||
box-shadow: 0px 2px 5px $grey; |
|||
border-radius: 10px; |
|||
} |
|||
.item-num { |
|||
position: relative; |
|||
width: 20px; |
|||
height: 20px; |
|||
border-radius: 5px; |
|||
top: 30px; |
|||
font-size: 12px; |
|||
text-align: center; |
|||
line-height: 20px; |
|||
background-color: #709AFC; |
|||
color: #fff; |
|||
} |
|||
.item-content { |
|||
position: absolute; |
|||
left: 150rpx; |
|||
font-size: 16px; |
|||
top: 0; |
|||
} |
|||
</style> |
@ -0,0 +1,97 @@ |
|||
<template> |
|||
<view> |
|||
<view class="title"> |
|||
<text v-for="(item,index) in tips" :key="index" class="flex flex-direction"> |
|||
{{ item }} |
|||
</text> |
|||
</view> |
|||
<view class="item-box" v-for="(item,index) in list" :key="index" @click="jump(index,item.projectId)"> |
|||
<view class="item-num">{{ index + 1 }}</view> |
|||
<text class="item-content">{{ item.projectName }}</text> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { firstproject } from 'api/firstproject' |
|||
export default { |
|||
async onLoad () { |
|||
const that = this |
|||
try{ |
|||
const params = { |
|||
param: { |
|||
competeTimeId: that.$store.state.project.data.id |
|||
} |
|||
} |
|||
const data = await firstproject(params) |
|||
that.list = data |
|||
console.log(data) |
|||
}catch(e){ |
|||
//TODO handle the exception |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
tips: ['参赛项目(各项各组报名不满3人 / 队)', '取消该组该项比赛'], |
|||
list: [{ |
|||
projectId: "2001", |
|||
projectName: "计数赛" |
|||
}, { |
|||
projectId: "2002", |
|||
projectName: "花样赛" |
|||
}], |
|||
} |
|||
}, |
|||
methods: { |
|||
jump (num,id) { |
|||
if (num === 0) { |
|||
uni.navigateTo({ |
|||
url:`./NumMatch?id=${id}` |
|||
}) |
|||
} else if (num === 1) { |
|||
uni.navigateTo({ |
|||
url:`./PatternMatch?id=${id}` |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.title { |
|||
text-align: center; |
|||
font-size: 12px; |
|||
color: $red; |
|||
overflow: auto; |
|||
} |
|||
.item-box { |
|||
margin-top: 24px; |
|||
height: 80px; |
|||
line-height: 80px; |
|||
font-size: 18px; |
|||
width: 670rpx; |
|||
margin-left: 40rpx; |
|||
padding-left: 56rpx; |
|||
position: relative; |
|||
box-shadow: 0px 2px 5px $grey; |
|||
border-radius: 10px; |
|||
} |
|||
.item-num { |
|||
position: relative; |
|||
width: 40px; |
|||
height: 40px; |
|||
border-radius: 50%; |
|||
top: 20px; |
|||
text-align: center; |
|||
line-height: 40px; |
|||
background-color: #709AFC; |
|||
color: #fff; |
|||
} |
|||
.item-content { |
|||
position: absolute; |
|||
left: 180rpx; |
|||
font-size: 16px; |
|||
top: 0; |
|||
} |
|||
</style> |
@ -0,0 +1,17 @@ |
|||
<template> |
|||
<view class="container"> |
|||
|
|||
<!-- 测试组件 不需要引入 注册 --> |
|||
<test /> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
|
|||
}; |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
|
|||
</style> |
@ -0,0 +1,29 @@ |
|||
<template> |
|||
<view> |
|||
<web-view :src="src"></web-view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
onLoad(option) { |
|||
const that = this |
|||
that.type = option.type |
|||
that.token = that.$store.state.user.user.token |
|||
that.src = `http://test.tall.wiki/compete/index/index.html?type=` + option.type + `&token=` + that.token |
|||
}, |
|||
data() { |
|||
return { |
|||
type: '', |
|||
token: '' |
|||
} |
|||
}, |
|||
methods: { |
|||
|
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style> |
|||
|
|||
</style> |
@ -0,0 +1,67 @@ |
|||
<template> |
|||
<view class="box"> |
|||
<view class="title"> |
|||
2020年山西省学生跳绳比赛 |
|||
</view> |
|||
<view class="title-safe"> |
|||
《安全责任书》 |
|||
</view> |
|||
<view class="content"> |
|||
一、本人(队)自愿报名参加2020年山西省学生跳绳比赛并签署本责任书。 |
|||
</view> |
|||
<view class="content"> |
|||
二、本人(队)已全面了解并同意遵守大会所制订的各项竞赛规程、规则、要求及采取的安全措施。 |
|||
</view> |
|||
<view class="content"> |
|||
三、本人已完全了解自己的身体状况,确认自己身体健康状况良好,具备参赛条件,已为参赛做好充分准备,并在比赛前购买了“人身意外伤害保险”;监护人经审慎评估,确认被监护人身体状况符合参赛条件,并自愿承担相应风险。 |
|||
</view> |
|||
<view class="content"> |
|||
四、本人(队)充分了解本次比赛可能出现的风险,且已准备必要的防范措施,以对自己(学生)安全负责的态度参赛。 |
|||
</view> |
|||
<view class="content"> |
|||
五、本人(队)愿意承担比赛期间发生的自身意外风险责任,且同意对于非大会原因造成的伤害等任何形式的损失大会不承担任何形式的赔偿。 |
|||
</view> |
|||
<view class="content"> |
|||
六、本人(队)同意接受大会在比赛期间提供的现场急救性质的医务治疗,但在离开现场后,在医院救治等发生的相关费用由本队(人)负担。 |
|||
</view> |
|||
<view class="content"> |
|||
七、本人(队)承诺以自己的名义参赛,决不冒名顶替,否则自愿承担全部法律责任。 |
|||
</view> |
|||
<view class="content"> |
|||
八、本人(队)及家长(监护人)已认真阅读并全面理解以上内容,且对上述所有内容予以确认并承担相应的法律责任。 |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
data() { |
|||
return { |
|||
|
|||
} |
|||
}, |
|||
methods: { |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.box { |
|||
padding: 20px 35rpx 35px 35rpx; |
|||
} |
|||
.title { |
|||
font-size: 18px; |
|||
text-align: center; |
|||
} |
|||
.title-safe { |
|||
font-size: 16px; |
|||
text-align: center; |
|||
margin-top: 10px; |
|||
margin-bottom: 10px; |
|||
} |
|||
.content { |
|||
margin-bottom: 10px; |
|||
font-size: 14px; |
|||
text-indent: 2em; |
|||
} |
|||
</style> |
@ -0,0 +1,112 @@ |
|||
import { BASE_URL, ERR_CODE } from 'api/base'; |
|||
import Request from './request'; |
|||
import Fingerprint from 'fingerprintjs' |
|||
|
|||
const test = new Request(); |
|||
|
|||
/** |
|||
* 获取token |
|||
* @return {string} 本地保存的token |
|||
*/ |
|||
export const getToken = () => uni.getStorageSync('token'); |
|||
|
|||
test.setConfig(config => { |
|||
/* 设置全局配置 */ |
|||
config.baseUrl = BASE_URL; |
|||
config.header = { |
|||
...config.header, |
|||
}; |
|||
return config; |
|||
}); |
|||
|
|||
test.interceptor.request((config, cancel) => { |
|||
/* 请求之前拦截器 */ |
|||
config.header = { |
|||
...config.header, |
|||
|
|||
}; |
|||
/* |
|||
if (!token) { // 如果token不存在,调用cancel 会取消本次请求,但是该函数的catch() 仍会执行
|
|||
cancel('token 不存在') // 接收一个参数,会传给catch((err) => {}) err.errMsg === 'token 不存在'
|
|||
} |
|||
*/ |
|||
return config; |
|||
}); |
|||
|
|||
/** |
|||
* 自定义验证器,如果返回true 则进入响应拦截器的响应成功函数(resolve),否则进入响应拦截器的响应错误函数(reject) |
|||
* @param { Number } statusCode - 请求响应体statusCode(只读) |
|||
* @return { Boolean } 如果为true,则 resolve, 否则 reject |
|||
*/ |
|||
test.validateStatus = statusCode => { |
|||
return statusCode === ERR_CODE; |
|||
}; |
|||
|
|||
test.interceptor.response( |
|||
response => { |
|||
/* 请求之后拦截器 */ |
|||
return response; |
|||
}, |
|||
response => { |
|||
// 请求错误做点什么
|
|||
return response; |
|||
}, |
|||
); |
|||
|
|||
const http = new Request(); |
|||
|
|||
http.setConfig(config => { |
|||
// 设置全局配置
|
|||
config.baseUrl = BASE_URL; // 根域名不同
|
|||
|
|||
config.header = { |
|||
...config.header, |
|||
}; |
|||
return config; |
|||
}); |
|||
|
|||
/** |
|||
* 自定义验证器,如果返回true 则进入响应拦截器的响应成功函数(resolve),否则进入响应拦截器的响应错误函数(reject) |
|||
* @param { Number } statusCode - 请求响应体statusCode(只读) |
|||
* @return { Boolean } 如果为true,则 resolve, 否则 reject |
|||
*/ |
|||
http.validateStatus = statusCode => { |
|||
return statusCode === ERR_CODE; |
|||
}; |
|||
|
|||
|
|||
// console.log(fingerprint)
|
|||
|
|||
http.interceptor.request((config, cancel) => { |
|||
/* 请求之前拦截器 */ |
|||
const token = getToken() ? { Authorization: `Bearer ${getToken()}` } : {}; |
|||
const fingerprint = { fingerprint: new Fingerprint().get() }; |
|||
config.header = { |
|||
...config.header, |
|||
...token, |
|||
...fingerprint, |
|||
}; |
|||
/* |
|||
if (!token) { // 如果token不存在,调用cancel 会取消本次请求,但是该函数的catch() 仍会执行
|
|||
cancel('token 不存在') // 接收一个参数,会传给catch((err) => {}) err.errMsg === 'token 不存在'
|
|||
} |
|||
*/ |
|||
return config; |
|||
}); |
|||
|
|||
http.interceptor.response( |
|||
response => { |
|||
/* 请求之后拦截器 */ |
|||
if (response.data.code !== ERR_CODE) { |
|||
// 服务端返回的状态码不等于200,则reject()
|
|||
return Promise.reject(response.data.msg); |
|||
} |
|||
return response.data.data; |
|||
}, |
|||
response => { |
|||
// 请求错误做点什么
|
|||
return response; |
|||
}, |
|||
); |
|||
|
|||
export { http, test }; |
@ -0,0 +1,273 @@ |
|||
**插件使用说明** |
|||
|
|||
- 基于 Promise 对象实现更简单的 request 使用方式,支持请求和响应拦截 |
|||
- 支持全局挂载 |
|||
- 支持多个全局配置实例 |
|||
- 支持自定义验证器 |
|||
- 支持文件上传(如不使用可以删除class里upload 方法) |
|||
- 支持` typescript `、` javascript ` 版本(如果不使用ts版本,则可以把luch-request-ts 文件夹删除) |
|||
- 下载后把 http-request 文件夹放到项目 utils/ 目录下 |
|||
|
|||
|
|||
**Example** |
|||
--- |
|||
创建实例 |
|||
|
|||
``` javascript |
|||
const http = new Request(); |
|||
``` |
|||
|
|||
执行` GET `请求 |
|||
|
|||
``` javascript |
|||
http.get('/user/login', {params: {userName: 'name', password: '123456'}}).then(res => { |
|||
|
|||
}).catch(err => { |
|||
|
|||
}) |
|||
// 局部修改配置,局部配置优先级高于全局配置 |
|||
http.get('/user/login', { |
|||
params: {userName: 'name', password: '123456'}, /* 会加在url上 */ |
|||
header: {}, /* 会覆盖全局header */ |
|||
dataType: 'json', |
|||
responseType: 'text' |
|||
}).then(res => { |
|||
|
|||
}).catch(err => { |
|||
|
|||
}) |
|||
``` |
|||
执行` POST `请求 |
|||
|
|||
``` javascript |
|||
http.post('/user/login', {userName: 'name', password: '123456'} ).then(res => { |
|||
|
|||
}).catch(err => { |
|||
|
|||
}) |
|||
// 局部修改配置,局部配置优先级高于全局配置 |
|||
http.post('/user/login', {userName: 'name', password: '123456'}, { |
|||
params: {}, /* 会加在url上 */ |
|||
header: {}, /* 会覆盖全局header */ |
|||
dataType: 'json', |
|||
responseType: 'text' |
|||
}).then(res => { |
|||
|
|||
}).catch(err => { |
|||
|
|||
}) |
|||
``` |
|||
执行` upload `请求 |
|||
|
|||
``` javascript |
|||
http.upload('api/upload/img', { |
|||
files: [], // 仅5+App支持 |
|||
fileType:'image/video/audio', // 仅支付宝小程序,且必填。 |
|||
filePath: '', // 要上传文件资源的路径。 |
|||
name: 'file', // 文件对应的 key , 开发者在服务器端通过这个 key 可以获取到文件二进制内容 |
|||
header: {}, |
|||
formData: {}, // HTTP 请求中其他额外的 form data |
|||
}).then(res => { |
|||
|
|||
}).catch(err => { |
|||
|
|||
}) |
|||
``` |
|||
**luch-request API** |
|||
-- |
|||
``` javascript |
|||
http.request({ |
|||
method: 'POST', // 请求方法必须大写 |
|||
url: '/user/12345', |
|||
data: { |
|||
firstName: 'Fred', |
|||
lastName: 'Flintstone' |
|||
}, |
|||
params: { // 会拼接到url上 |
|||
token: '1111' |
|||
} |
|||
}) |
|||
|
|||
具体参数说明:[uni.uploadFile](https://uniapp.dcloud.io/api/request/network-file) |
|||
http.upload('api/upload/img', { |
|||
files: [], // 仅5+App支持 |
|||
fileType:'image/video/audio', // 仅支付宝小程序,且必填。 |
|||
filePath: '', // 要上传文件资源的路径。 |
|||
name: 'file', // 文件对应的 key , 开发者在服务器端通过这个 key 可以获取到文件二进制内容 |
|||
header: {}, // 如填写,会覆盖全局header |
|||
formData: {}, // HTTP 请求中其他额外的 form data |
|||
}) |
|||
``` |
|||
|
|||
|
|||
请求方法别名 / 实例方法 |
|||
|
|||
``` javascript |
|||
http.request(config) |
|||
http.get(url[, config]) |
|||
http.upload(url[, config]) |
|||
http.delete(url[, data[, config]]) |
|||
http.head(url[, data[, config]]) |
|||
http.post(url[, data[, config]]) |
|||
http.put(url[, data[, config]]) |
|||
http.connect(url[, data[, config]]) |
|||
http.options(url[, data[, config]]) |
|||
http.trace(url[, data[, config]]) |
|||
``` |
|||
|
|||
**全局请求配置** |
|||
-- |
|||
``` javascript |
|||
{ |
|||
baseUrl: '', /* 全局根路径,需要注意,如果请求的路径为绝对路径,则不会应用baseUrl */ |
|||
header: { |
|||
'Content-Type': 'application/json;charset=UTF-8' |
|||
}, |
|||
method: 'GET', |
|||
dataType: 'json', |
|||
responseType: 'text' |
|||
} |
|||
``` |
|||
|
|||
|
|||
全局配置修改` setConfig ` |
|||
|
|||
``` javascript |
|||
/** |
|||
* @description 修改全局默认配置 |
|||
* @param {Function} |
|||
*/ |
|||
http.setConfig((config) => { /* config 为默认全局配置*/ |
|||
config.baseUrl = 'http://www.bbb.cn'; /* 根域名 */ |
|||
config.header = { |
|||
a: 1, |
|||
b: 2 |
|||
} |
|||
return config |
|||
}) |
|||
``` |
|||
|
|||
自定义验证器` validateStatus ` |
|||
|
|||
``` javascript |
|||
/** |
|||
* 自定义验证器,如果返回true 则进入响应拦截器的响应成功函数(resolve),否则进入响应拦截器的响应错误函数(reject) |
|||
* @param { Number } statusCode - 请求响应体statusCode(只读) |
|||
* @return { Boolean } 如果为true,则 resolve, 否则 reject |
|||
*/ |
|||
http.validateStatus = (statusCode) => { // 默认 |
|||
return statusCode === 200 |
|||
} |
|||
|
|||
// 举个栗子 |
|||
http.validateStatus = (statusCode) => { |
|||
return statusCode >= 200 && statusCode < 300 |
|||
} |
|||
``` |
|||
|
|||
**拦截器** |
|||
-- |
|||
|
|||
在请求之前拦截 |
|||
|
|||
``` javascript |
|||
/** |
|||
* @param { Function} cancel - 取消请求,调用cancel 会取消本次请求,但是该函数的catch() 仍会执行; 不会进入响应拦截器 |
|||
* |
|||
* @param {String} text ['handle cancel'| any] - catch((err) => {}) err.errMsg === 'handle cancel'。非必传,默认'handle cancel' |
|||
* @cancel {Object} config - catch((err) => {}) err.config === config; 非必传,默认为request拦截器修改之前的config |
|||
* function cancel(text, config) {} |
|||
*/ |
|||
http.interceptor.request((config, cancel) => { /* cancel 为函数,如果调用会取消本次请求。需要注意:调用cancel,本次请求的catch仍会执行。必须return config */ |
|||
config.header = { |
|||
...config.header, |
|||
a: 1 |
|||
} |
|||
/* |
|||
if (!token) { // 如果token不存在,调用cancel 会取消本次请求,但是该函数的catch() 仍会执行 |
|||
cancel('token 不存在', config) // 把修改后的config传入,之后响应就可以拿到修改后的config。 如果调用了cancel但是不传修改后的config,则catch((err) => {}) err.config 为request拦截器修改之前的config |
|||
} |
|||
*/ |
|||
return config; |
|||
}) |
|||
``` |
|||
|
|||
在请求之后拦截 |
|||
|
|||
``` javascript |
|||
http.interceptor.response((response) => { /* 对响应成功做点什么 (statusCode === 200),必须return response*/ |
|||
// if (response.data.code !== 200) { // 服务端返回的状态码不等于200,则reject() |
|||
// return Promise.reject(response) |
|||
// } |
|||
console.log(response) |
|||
return response |
|||
}, (response) => { /* 对响应错误做点什么 (statusCode !== 200),必须return response*/ |
|||
console.log(response) |
|||
return response |
|||
}) |
|||
``` |
|||
|
|||
**typescript使用** |
|||
-- |
|||
在` request.ts `里还暴露了五个接口 |
|||
```javascript |
|||
{ |
|||
options, // request 方法配置参数 |
|||
handleOptions, // get/post 方法配置参数 |
|||
config, // init 全局config接口(setConfig 参数接口) |
|||
requestConfig, // 请求之前参数配置项 |
|||
response // 响应体 |
|||
} |
|||
``` |
|||
|
|||
**常见问题** |
|||
-- |
|||
1. 为什么会请求两次? |
|||
- 总有些小白问这些很那啥的问题,有两种可能,一种是‘post三次握手’(不知道的请先给个五星好评,然后打自己一巴掌,并问自己,为什么这都不知道),还有一种可能是`本地访问接口时跨域请求,所以浏览器会先发一个option 去预测能否成功,然后再发一个真正的请求`(没有自己观察请求头,Request Method,就跑来问的,请再打自己一巴掌,并问自己,为什么这都不知道,不知道也行,为什么不百度)。 |
|||
2. 如何跨域? |
|||
- 问的人不少,可以先百度了解一下。<a href="https://ask.dcloud.net.cn/article/35267" target="_blank">如何跨域</a> |
|||
3. post 怎么传不了数组的参数啊? |
|||
- <a href="https://uniapp.dcloud.io/api/request/request">uni-request</a> <br> |
|||
可以点击看一下uni-request 的api 文档,data支持的文件类型只有<code>Object/String/ArrayBuffer</code>这个真跟我没啥关系 0.0 |
|||
4. 'Content-Type' 为什么要小写? |
|||
- hbuilderX 更新至‘2.3.0.20190919’ 后,uni.request post请求,如果 ‘Content-Type’ 大写,就会在后面自动拼接‘ application/json’,请求头变成 |
|||
`Content-Type: application/json;charset=UTF-8 application/json`,导致后端无法解析类型,`Status Code 415`,post 请求失败。但是小写就不会出现这个问题。至于为什么我也没有深究,我现在也不清楚这是他们的bug,还是以后就这样规范了。我能做的只有立马兼容,至于后边uni官方会不会继续变动也不清楚。 |
|||
|
|||
|
|||
**tip** |
|||
-- |
|||
- 不想使用upload 可把class 里的upload 删除 |
|||
|
|||
|
|||
**issue** |
|||
-- |
|||
有任何问题或者建议可以=> <a href="https://ask.dcloud.net.cn/question/74922" target="_blank">issue提交</a>,先给个五星好评QAQ!! |
|||
|
|||
|
|||
**作者想说** |
|||
-- |
|||
- 主体代码3kb |
|||
- 目前该插件已经上项目,遇到任何问题请先检查自己的代码(排除新版本发布的情况)。最近新上了` typescript ` 版本,因为本人没使用过ts,所以写的不好的地方,还请见谅~ |
|||
- 写代码很容易,为了让你们看懂写文档真的很lei 0.0 |
|||
- 最近发现有插件与我雷同,当初接触uni-app 就发现插件市场虽然有封装的不错的request库,但是都没有对多全局配置做处理,都是通过修改源码的方式配置。我首先推出通过class类,并仿照axios的api实现request请求库,并起名‘仿axios封装request网络请求库,支持拦截器全局配置’。他们虽然修改了部分代码,但是功能与性能并没有优化,反而使代码很冗余。希望能推出新的功能,和性能更加强悍的请求库。 |
|||
- 任何形式的‘参考’、‘借鉴’,请标明作者 |
|||
```javascript |
|||
<a href="https://ext.dcloud.net.cn/plugin?id=392">luch-request</a> |
|||
``` |
|||
- 关于问问题 |
|||
1. 首先请善于利用搜索引擎,不管百度,还是Google,遇到问题请先自己尝试解决。自己尝试过无法解决,再问。 |
|||
2. 不要问类似为什么我的xx无法使用这种问题。请仔细阅读文档,检查代码,或者说明运行环境,把相关代码贴至评论或者发送至我的邮箱,还可以点击上面的issue提交,在里面提问,可能我在里面已经回答了。 |
|||
3. 我的代码如果真的出现bug,或者你有好的建议、需求,可以提issue,我看到后会立即解决 |
|||
4. 不要问一些弱智问题!!! |
|||
- 如何问问题 |
|||
1. 仔细阅读文档,检查代码 |
|||
2. 说明运行环境,比如:app端 ios、android 版本号、手机机型、普遍现象还是个别现象(越详细越好) |
|||
3. 发出代码片段或者截图至邮箱(很重要) |
|||
4. 或者可以在上方的'issue提交' 里发出详细的问题描述 |
|||
5. 以上都觉得解决不了你的问题,可以加QQ:`370306150` |
|||
|
|||
**土豪赞赏** |
|||
-- |
|||
<img src="https://img-cdn-qiniu.dcloud.net.cn/uploads/answer/20191014/0d9fff1e6a57a83024787224593b39c1.png" width="150"> |
|||
|
|||
####创作不易,五星好评你懂得! |
@ -0,0 +1,316 @@ |
|||
/** |
|||
* Request 1.0.2 |
|||
* @Class Request |
|||
* @description luch-request 1.0.2 http请求插件 |
|||
* @Author lu-ch |
|||
* @Date 2019-10-14 |
|||
* @Email webwork.s@qq.com |
|||
* http://ext.dcloud.net.cn/plugin?id=392
|
|||
*/ |
|||
export default class Request { |
|||
config = { |
|||
baseUrl: '', |
|||
header: { |
|||
'content-type': 'application/json;charset=UTF-8' |
|||
}, |
|||
method: 'GET', |
|||
dataType: 'json', |
|||
responseType: 'text' |
|||
} |
|||
|
|||
static posUrl (url) { /* 判断url是否为绝对路径 */ |
|||
return /(http|https):\/\/([\w.]+\/?)\S*/.test(url) |
|||
} |
|||
|
|||
static addQueryString (params) { |
|||
let paramsData = '' |
|||
Object.keys(params).forEach(function (key) { |
|||
paramsData += key + '=' + params[key] + '&' |
|||
}) |
|||
return paramsData.substring(0, paramsData.length - 1) |
|||
} |
|||
|
|||
/** |
|||
* @property {Function} request 请求拦截器 |
|||
* @property {Function} response 响应拦截器 |
|||
* @type {{request: Request.interceptor.request, response: Request.interceptor.response}} |
|||
*/ |
|||
interceptor = { |
|||
/** |
|||
* @param {Request~requestCallback} cb - 请求之前拦截,接收一个函数(config, cancel)=> {return config}。第一个参数为全局config,第二个参数为函数,调用则取消本次请求。 |
|||
*/ |
|||
request: (cb) => { |
|||
if (cb) { |
|||
this.requestBeforeFun = cb |
|||
} |
|||
}, |
|||
/** |
|||
* @param {Request~responseCallback} cb 响应拦截器,对响应数据做点什么 |
|||
* @param {Request~responseErrCallback} ecb 响应拦截器,对响应错误做点什么 |
|||
*/ |
|||
response: (cb, ecb) => { |
|||
if (cb && ecb) { |
|||
this.requestComFun = cb |
|||
this.requestComFail = ecb |
|||
} |
|||
} |
|||
} |
|||
|
|||
requestBeforeFun (config) { |
|||
return config |
|||
} |
|||
|
|||
requestComFun (response) { |
|||
return response |
|||
} |
|||
|
|||
requestComFail (response) { |
|||
return response |
|||
} |
|||
|
|||
/** |
|||
* 自定义验证器,如果返回true 则进入响应拦截器的响应成功函数(resolve),否则进入响应拦截器的响应错误函数(reject) |
|||
* @param { Number } statusCode - 请求响应体statusCode(只读) |
|||
* @return { Boolean } 如果为true,则 resolve, 否则 reject |
|||
*/ |
|||
validateStatus (statusCode) { |
|||
return statusCode === 200 |
|||
} |
|||
|
|||
/** |
|||
* @Function |
|||
* @param {Request~setConfigCallback} f - 设置全局默认配置 |
|||
*/ |
|||
setConfig (f) { |
|||
this.config = f(this.config) |
|||
} |
|||
|
|||
/** |
|||
* @Function |
|||
* @param {Object} options - 请求配置项 |
|||
* @prop {String} options.url - 请求路径 |
|||
* @prop {Object} options.data - 请求参数 |
|||
* @prop {Object} [options.responseType = config.responseType] [text|arraybuffer] - 响应的数据类型 |
|||
* @prop {Object} [options.dataType = config.dataType] - 如果设为 json,会尝试对返回的数据做一次 JSON.parse |
|||
* @prop {Object} [options.header = config.header] - 请求header |
|||
* @prop {Object} [options.method = config.method] - 请求方法 |
|||
* @returns {Promise<unknown>} |
|||
*/ |
|||
async request (options = {}) { |
|||
options.baseUrl = this.config.baseUrl |
|||
options.dataType = options.dataType || this.config.dataType |
|||
options.responseType = options.responseType || this.config.responseType |
|||
options.url = options.url || '' |
|||
options.data = options.data || {} |
|||
options.params = options.params || {} |
|||
options.header = options.header || this.config.header |
|||
options.method = options.method || this.config.method |
|||
return new Promise((resolve, reject) => { |
|||
let next = true |
|||
|
|||
let handleRe = {} |
|||
options.complete = (response) => { |
|||
response.config = handleRe |
|||
if (this.validateStatus(response.statusCode)) { // 成功
|
|||
response = this.requestComFun(response) |
|||
resolve(response) |
|||
} else { |
|||
response = this.requestComFail(response) |
|||
reject(response) |
|||
} |
|||
} |
|||
const cancel = (t = 'handle cancel', config = options) => { |
|||
const err = { |
|||
errMsg: t, |
|||
config: config |
|||
} |
|||
reject(err) |
|||
next = false |
|||
} |
|||
|
|||
handleRe = { ...this.requestBeforeFun(options, cancel) } |
|||
const _config = { ...handleRe } |
|||
if (!next) return |
|||
|
|||
let mergeUrl = Request.posUrl(options.url) ? options.url : (options.baseUrl + options.url) |
|||
if (JSON.stringify(options.params) !== '{}') { |
|||
const paramsH = Request.addQueryString(options.params) |
|||
mergeUrl += mergeUrl.indexOf('?') === -1 ? `?${paramsH}` : `&${paramsH}` |
|||
} |
|||
_config.url = mergeUrl |
|||
uni.request(_config) |
|||
}) |
|||
} |
|||
|
|||
get (url, options = {}) { |
|||
return this.request({ |
|||
url, |
|||
method: 'GET', |
|||
...options |
|||
}) |
|||
} |
|||
|
|||
post (url, data, options = {}) { |
|||
return this.request({ |
|||
url, |
|||
data, |
|||
method: 'POST', |
|||
...options |
|||
}) |
|||
} |
|||
|
|||
// #ifndef MP-ALIPAY
|
|||
put (url, data, options = {}) { |
|||
return this.request({ |
|||
url, |
|||
data, |
|||
method: 'PUT', |
|||
...options |
|||
}) |
|||
} |
|||
|
|||
// #endif
|
|||
|
|||
// #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
|
|||
delete (url, data, options = {}) { |
|||
return this.request({ |
|||
url, |
|||
data, |
|||
method: 'DELETE', |
|||
...options |
|||
}) |
|||
} |
|||
|
|||
// #endif
|
|||
|
|||
// #ifdef APP-PLUS || H5 || MP-WEIXIN
|
|||
connect (url, data, options = {}) { |
|||
return this.request({ |
|||
url, |
|||
data, |
|||
method: 'CONNECT', |
|||
...options |
|||
}) |
|||
} |
|||
|
|||
// #endif
|
|||
|
|||
// #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
|
|||
head (url, data, options = {}) { |
|||
return this.request({ |
|||
url, |
|||
data, |
|||
method: 'HEAD', |
|||
...options |
|||
}) |
|||
} |
|||
|
|||
// #endif
|
|||
|
|||
// #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
|
|||
options (url, data, options = {}) { |
|||
return this.request({ |
|||
url, |
|||
data, |
|||
method: 'OPTIONS', |
|||
...options |
|||
}) |
|||
} |
|||
|
|||
// #endif
|
|||
|
|||
// #ifdef APP-PLUS || H5 || MP-WEIXIN
|
|||
trace (url, data, options = {}) { |
|||
return this.request({ |
|||
url, |
|||
data, |
|||
method: 'TRACE', |
|||
...options |
|||
}) |
|||
} |
|||
|
|||
// #endif
|
|||
|
|||
upload (url, { |
|||
// #ifdef APP-PLUS
|
|||
files, |
|||
// #endif
|
|||
// #ifdef MP-ALIPAY
|
|||
fileType, |
|||
// #endif
|
|||
filePath, |
|||
name, |
|||
header, |
|||
formData |
|||
}) { |
|||
return new Promise((resolve, reject) => { |
|||
let next = true |
|||
let handleRe = {} |
|||
const pubConfig = { |
|||
baseUrl: this.config.baseUrl, |
|||
url, |
|||
// #ifdef APP-PLUS
|
|||
files, |
|||
// #endif
|
|||
// #ifdef MP-ALIPAY
|
|||
fileType, |
|||
// #endif
|
|||
filePath, |
|||
method: 'UPLOAD', |
|||
name, |
|||
header: header || this.config.header, |
|||
formData, |
|||
complete: (response) => { |
|||
response.config = handleRe |
|||
if (response.statusCode === 200) { // 成功
|
|||
response = this.requestComFun(response) |
|||
resolve(response) |
|||
} else { |
|||
response = this.requestComFail(response) |
|||
reject(response) |
|||
} |
|||
} |
|||
} |
|||
const cancel = (t = 'handle cancel', config = pubConfig) => { |
|||
const err = { |
|||
errMsg: t, |
|||
config: config |
|||
} |
|||
reject(err) |
|||
next = false |
|||
} |
|||
|
|||
handleRe = { ...this.requestBeforeFun(pubConfig, cancel) } |
|||
const _config = { ...handleRe } |
|||
if (!next) return |
|||
_config.url = Request.posUrl(url) ? url : (this.config.baseUrl + url) |
|||
uni.uploadFile(_config) |
|||
}) |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* setConfig回调 |
|||
* @return {Object} - 返回操作后的config |
|||
* @callback Request~setConfigCallback |
|||
* @param {Object} config - 全局默认config |
|||
*/ |
|||
/** |
|||
* 请求拦截器回调 |
|||
* @return {Object} - 返回操作后的config |
|||
* @callback Request~requestCallback |
|||
* @param {Object} config - 全局config |
|||
* @param {Function} [cancel] - 取消请求钩子,调用会取消本次请求 |
|||
*/ |
|||
/** |
|||
* 响应拦截器回调 |
|||
* @return {Object} - 返回操作后的response |
|||
* @callback Request~responseCallback |
|||
* @param {Object} response - 请求结果 response |
|||
*/ |
|||
/** |
|||
* 响应错误拦截器回调 |
|||
* @return {Object} - 返回操作后的response |
|||
* @callback Request~responseErrCallback |
|||
* @param {Object} response - 请求结果 response |
|||
*/ |
@ -0,0 +1,11 @@ |
|||
<!DOCTYPE html> |
|||
<html> |
|||
<head> |
|||
<meta charset="utf-8" /> |
|||
<meta name="viewport" content="width=device-width, initial-scale=1"> |
|||
<title></title> |
|||
</head> |
|||
<body> |
|||
这是html界面 |
|||
</body> |
|||
</html> |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 598 KiB |
After Width: | Height: | Size: 618 KiB |
After Width: | Height: | Size: 770 B |
After Width: | Height: | Size: 75 KiB |
@ -0,0 +1,13 @@ |
|||
import Vue from 'vue'; |
|||
import Vuex from 'vuex'; |
|||
import user from './modules/user/index'; |
|||
import project from './modules/project/index'; |
|||
|
|||
|
|||
Vue.use(Vuex); |
|||
const store = new Vuex.Store({ |
|||
// modules:sessionStorage.getItem('state') ? JSON.parse(sessionStorage.getItem('state')): { user, project }
|
|||
modules: { user, project }, |
|||
}); |
|||
|
|||
export default store; |
@ -0,0 +1,9 @@ |
|||
import { showLoading, hideLoading, showModal, showToast } from 'utils/ui'; |
|||
import { mpLogin, signIn, ddLogin } from 'utils/user'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
const actions = { |
|||
|
|||
}; |
|||
|
|||
export default actions; |
@ -0,0 +1,5 @@ |
|||
import state from './state'; |
|||
import mutations from './mutations'; |
|||
import actions from './actions.js'; |
|||
|
|||
export default { namespaced: true, state, actions, mutations }; |
@ -0,0 +1,5 @@ |
|||
const mutations = { |
|||
|
|||
}; |
|||
|
|||
export default mutations; |
@ -0,0 +1,7 @@ |
|||
const state = { |
|||
data: null, |
|||
companyId: 0, |
|||
num: 0 |
|||
}; |
|||
|
|||
export default state; |
@ -0,0 +1,9 @@ |
|||
import { showLoading, hideLoading, showModal, showToast } from 'utils/ui'; |
|||
import { mpLogin, signIn, ddLogin } from 'utils/user'; |
|||
import { http } from 'plugins/request/index'; |
|||
|
|||
const actions = { |
|||
|
|||
}; |
|||
|
|||
export default actions; |
@ -0,0 +1,5 @@ |
|||
import state from './state'; |
|||
import mutations from './mutations'; |
|||
import actions from './actions.js'; |
|||
|
|||
export default { namespaced: true, state, actions, mutations }; |
@ -0,0 +1,26 @@ |
|||
const mutations = { |
|||
/** |
|||
* 设置存储token |
|||
* @param {object} state |
|||
* @param {string} token |
|||
*/ |
|||
setToken(state, token) { |
|||
if (!token) return; |
|||
state.token = token; |
|||
uni.setStorageSync('token', token); |
|||
}, |
|||
|
|||
/** |
|||
* 设置user数据 |
|||
* @param {object} state |
|||
* @param {object} user |
|||
*/ |
|||
setUser(state, user) { |
|||
if (!user) return; |
|||
state.user = { ...user }; |
|||
uni.setStorageSync('user', JSON.stringify(user)); |
|||
}, |
|||
|
|||
}; |
|||
|
|||
export default mutations; |
@ -0,0 +1,7 @@ |
|||
const state = { |
|||
token: '', |
|||
user: null, |
|||
fingerprint: 0 |
|||
}; |
|||
|
|||
export default state; |
@ -0,0 +1,133 @@ |
|||
/* 颜色变量 */ |
|||
/* Color 可以自定义相关配色 */ |
|||
/* 标准色 */ |
|||
$red: #F26A1B; |
|||
$orange: #f37b1d; |
|||
$yellow: #fbbd08; |
|||
$olive: #76AC96; |
|||
$green: #11A20D; // 健康打卡 绿 |
|||
$cyan: #0897C7; // 按钮蓝 |
|||
$blue: #6D99F2; |
|||
$darkBlue: #0076FF; |
|||
$purple: #677DBF; // 校园打卡 青 |
|||
$mauve: #9c26b0; |
|||
$pink: #e03997; |
|||
$brown: #a5673f; |
|||
$grey: #CDCDCD; |
|||
$black: #333333; |
|||
$darkGray: #666666; |
|||
$gray: #808080; |
|||
$ghostWhite: #f1f1f1; |
|||
$white: #ffffff; |
|||
|
|||
/* 浅色 */ |
|||
$redLight: #fadbd9; |
|||
$orangeLight: #fde6d2; |
|||
$yellowLight: #fef2ce; |
|||
$oliveLight: #e8f4d9; |
|||
$greenLight: #d7f0db; |
|||
$cyanLight: #d2f1f0; |
|||
$blueLight: #cce6ff; |
|||
$purpleLight: #e1d7f0; |
|||
$mauveLight: #ebd4ef; |
|||
$pinkLight: #f9d7ea; |
|||
$brownLight: #ede1d9; |
|||
$greyLight: #F5f5f5; |
|||
|
|||
/* 渐变色 */ |
|||
$gradualRed: linear-gradient(45deg, #f43f3b, #ec008c); |
|||
$gradualOrange: linear-gradient(45deg, #ff9700, #ed1c24); |
|||
$gradualGreen: linear-gradient(45deg, #39b54a, #8dc63f); |
|||
$gradualPurple: linear-gradient(45deg, #ec008c, #5e00ff); |
|||
$gradualPink: linear-gradient(45deg, #ec008c, #6739b6); |
|||
$gradualBlue: linear-gradient(45deg, #0081ff, #1cbbb4); |
|||
|
|||
/* 阴影透明色 */ |
|||
$ShadowSize: 6rpx 6rpx 8rpx; |
|||
$redShadow: rgba(204, 69, 59, 0.2); |
|||
$orangeShadow: rgba(217, 109, 26, 0.2); |
|||
$yellowShadow: rgba(224, 170, 7, 0.2); |
|||
$oliveShadow: rgba(124, 173, 55, 0.2); |
|||
$greenShadow: rgba(48, 156, 63, 0.2); |
|||
$cyanShadow: rgba(28, 187, 180, 0.2); |
|||
$blueShadow: rgba(0, 102, 204, 0.2); |
|||
$purpleShadow: rgba(88, 48, 156, 0.2); |
|||
$mauveShadow: rgba(133, 33, 150, 0.2); |
|||
$pinkShadow: rgba(199, 50, 134, 0.2); |
|||
$brownShadow: rgba(140, 88, 53, 0.2); |
|||
$greyShadow: rgba(114, 130, 138, 0.2); |
|||
$grayShadow: rgba(114, 130, 138, 0.2); |
|||
$blackShadow: rgba(26, 26, 26, 0.2); |
|||
$whiteShadow: rgba(255, 255, 255, 0.2); |
|||
|
|||
/* 行为相关颜色 */ |
|||
$uni-color-primary: #007aff; |
|||
$uni-color-success: #4cd964; |
|||
$uni-color-warning: #f0ad4e; |
|||
$uni-color-error: #dd524d; |
|||
|
|||
/* 首页四个配色 */ |
|||
$iconGreen: #62D4A6; |
|||
$iconCyan: #9376F5; |
|||
$iconBlue: #58C9D1; |
|||
$iconPurple: #CF7FE6; |
|||
|
|||
/* 文字基本颜色 */ |
|||
$uni-text-color: #101010; //基本色 |
|||
$uni-text-color-inverse: #fff; //反色 |
|||
$uni-text-color-grey: #747474; //辅助灰色,如加载更多的提示信息 |
|||
$uni-text-color-placeholder: #808080; |
|||
$uni-text-color-disable: #c0c0c0; |
|||
|
|||
/* 背景颜色 */ |
|||
$uni-bg-color: #ffffff; |
|||
$uni-bg-color-grey: #f8f8f8; |
|||
$uni-bg-color-hover: #f1f1f1; //点击状态颜色 |
|||
$uni-bg-color-mask: rgba(0, 0, 0, 0.4); //遮罩颜色 |
|||
|
|||
/* 边框颜色 */ |
|||
$uni-border-color: #c8c7cc; |
|||
|
|||
/* 尺寸变量 */ |
|||
|
|||
/* 文字尺寸 */ |
|||
$uni-font-size: 20rpx; |
|||
$uni-font-size-sm: 24rpx; |
|||
$uni-font-size-base: 28rpx; |
|||
$uni-font-size-lg: 32rpx; |
|||
$uni-font-size-xl: 36rpx; |
|||
$uni-font-size-xxl: 44rpx; |
|||
$uni-font-size-sl: 80rpx; |
|||
$uni-font-size-xsl: 120rpx; |
|||
|
|||
/* 图片尺寸 */ |
|||
$uni-img-size-sm: 40rpx; |
|||
$uni-img-size-base: 52rpx; |
|||
$uni-img-size-lg: 80rpx; |
|||
|
|||
/* Border Radius */ |
|||
$uni-border-radius-sm: 4rpx; |
|||
$uni-border-radius-base: 6rpx; |
|||
$uni-border-radius-lg: 12rpx; |
|||
$uni-border-radius-circle: 50%; |
|||
|
|||
/* 水平间距 */ |
|||
$uni-spacing-row-sm: 10px; |
|||
$uni-spacing-row-base: 20rpx; |
|||
$uni-spacing-row-lg: 30rpx; |
|||
|
|||
/* 垂直间距 */ |
|||
$uni-spacing-col-sm: 8rpx; |
|||
$uni-spacing-col-base: 16rpx; |
|||
$uni-spacing-col-lg: 24rpx; |
|||
|
|||
/* 透明度 */ |
|||
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度 |
|||
|
|||
/* 文章场景相关 */ |
|||
$uni-color-title: #2c405a; // 文章标题颜色 |
|||
$uni-font-size-title: 40rpx; |
|||
$uni-color-subtitle: #555555; // 二级标题颜色 |
|||
$uni-font-size-subtitle: 36rpx; |
|||
$uni-color-paragraph: #3f536e; // 文章段落颜色 |
|||
$uni-font-size-paragraph: 30rpx; |
@ -0,0 +1,31 @@ |
|||
/** |
|||
* 显示模态框 |
|||
* @param {string} msg |
|||
* @param {boolean} showCancel |
|||
* @param {string} confirmText |
|||
*/ |
|||
export const showModal = (msg, showCancel = false, confirmText = '知道了') => |
|||
uni.showModal({ |
|||
title: '提示', |
|||
content: msg, |
|||
showCancel, |
|||
confirmText, |
|||
confirmColor: '#1890ff', |
|||
}); |
|||
|
|||
/** |
|||
* 显示toast |
|||
* @param {string} msg |
|||
*/ |
|||
export const showToast = msg => |
|||
uni.showToast({ |
|||
title: msg, |
|||
icon: 'none', |
|||
duration: 3000, |
|||
}); |
|||
|
|||
// 显示加载动画
|
|||
export const showLoading = (msg = '努力加载中...') => uni.showLoading({ title: msg }); |
|||
|
|||
// 隐藏加载动画
|
|||
export const hideLoading = () => uni.hideLoading(); |
@ -0,0 +1,132 @@ |
|||
import { SIGN_IN } from 'api/user'; |
|||
import { ERR_CODE } from 'config/config.default'; |
|||
import { http as axios } from 'plugins/request/index'; |
|||
import { SIGN_IN_CLIENTS, SIGN_IN_TYPES } from 'config/config.user'; |
|||
|
|||
/** |
|||
* 保存token |
|||
* @param {string} token 服务端返回的token数据 |
|||
*/ |
|||
export const setToken = token => { |
|||
uni.setStorageSync('token', token); |
|||
}; |
|||
|
|||
/** |
|||
* 获取token |
|||
* @return {string} 本地保存的token |
|||
*/ |
|||
export const getToken = () => uni.getStorageSync('token'); |
|||
|
|||
/** |
|||
* 提交登录信息 |
|||
* @param {object} params 提交的参数 |
|||
*/ |
|||
export const signIn = params => { |
|||
return new Promise((resolve, reject) => { |
|||
axios |
|||
.post(SIGN_IN, params) |
|||
.then(res => { |
|||
const { success, code, data, msg } = res.data; |
|||
if (success && code === ERR_CODE) { |
|||
if (!data || !data.token) { |
|||
reject('服务端返回数据不正确'); |
|||
} else { |
|||
resolve(data); |
|||
} |
|||
} else { |
|||
reject(`登录请求失败 ${msg}`); |
|||
} |
|||
}) |
|||
.catch(err => { |
|||
reject(err); |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
// 微信登录
|
|||
export const wxLogin = () => { |
|||
return new Promise((resolve, reject) => { |
|||
uni.login({ |
|||
provider: 'weixin', |
|||
success(response) { |
|||
if (response.code) { |
|||
const params = { |
|||
client: SIGN_IN_CLIENTS['mp'], |
|||
type: SIGN_IN_TYPES['mp'], |
|||
data: { identifier: response.code, credential: 'health' }, |
|||
// redirect: 'https://test.tall.wiki/gateway/health/initMsg',
|
|||
redirect: 'https://www.tall.wiki/gateway/health/initMsg', |
|||
}; |
|||
resolve(params); |
|||
} else { |
|||
reject(response.errMsg); |
|||
} |
|||
}, |
|||
fail() { |
|||
console.log('fail'); |
|||
reject('微信登录失败'); |
|||
}, |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
// 企业微信登录
|
|||
export const wxWorkLogin = () => { |
|||
return new Promise((resolve, reject) => { |
|||
wx.qy.login({ |
|||
provider: 'weixin', |
|||
success(response) { |
|||
if (response.code) { |
|||
const params = { |
|||
client: SIGN_IN_CLIENTS['wx_work'], |
|||
type: SIGN_IN_TYPES['wx_work'], |
|||
data: { identifier: response.code, credential: 'health' }, |
|||
// redirect: 'https://test.tall.wiki/gateway/health/initMsg',
|
|||
redirect: 'https://www.tall.wiki/gateway/health/initMsg', |
|||
}; |
|||
resolve(params); |
|||
} else { |
|||
reject(response.errMsg); |
|||
} |
|||
}, |
|||
fail() { |
|||
console.log('fail'); |
|||
reject('微信登录失败'); |
|||
}, |
|||
}); |
|||
}); |
|||
}; |
|||
|
|||
// 小程序登录
|
|||
export const mpLogin = () => { |
|||
try { |
|||
const res = uni.getSystemInfoSync(); |
|||
if (res.environment === 'wxwork') { |
|||
return wxWorkLogin(); |
|||
} else { |
|||
return wxLogin(); |
|||
} |
|||
} catch (err) { |
|||
console.log('err: ', err); |
|||
} |
|||
}; |
|||
|
|||
// 钉钉登录
|
|||
export const ddLogin = () => { |
|||
console.log('dingtalk login.........'); |
|||
try { |
|||
dd.getAuthCode({ |
|||
success(res) { |
|||
console.log('res: ', res); |
|||
/*{ |
|||
authCode: 'hYLK98jkf0m' // string authCode
|
|||
}*/ |
|||
}, |
|||
fail: function(err) { |
|||
console.log('err: ', err); |
|||
}, |
|||
}); |
|||
} catch (error) { |
|||
console.log('error: ', error); |
|||
} |
|||
}; |
@ -0,0 +1,20 @@ |
|||
/** |
|||
* 格式化 querystring |
|||
* taskId=3&scene=1011 -> |
|||
* {taskId:3,scene:1011} |
|||
*/ |
|||
export const formatQuery = str => { |
|||
if (!str) return; |
|||
const result = {}; |
|||
if (str.includes('&')) { |
|||
const arr = str.split('&'); |
|||
arr.forEach(item => { |
|||
const arr1 = item.split('='); |
|||
result[arr1[0]] = arr1[1]; |
|||
}); |
|||
} else { |
|||
const arr = str.split('='); |
|||
result[arr[0]] = arr[1]; |
|||
} |
|||
return result; |
|||
}; |
@ -0,0 +1,21 @@ |
|||
const path = require('path'); |
|||
const resolve = dir => path.join(__dirname, dir); |
|||
|
|||
module.exports = { |
|||
lintOnSave: true, |
|||
configureWebpack: { |
|||
resolve: { |
|||
alias: { |
|||
'~': __dirname, |
|||
config: resolve('config'), |
|||
api: resolve('api'), |
|||
store: resolve('store'), |
|||
components: resolve('components'), |
|||
pages: resolve('pages'), |
|||
common: resolve('common'), |
|||
plugins: resolve('plugins'), |
|||
utils: resolve('utils'), |
|||
}, |
|||
}, |
|||
}, |
|||
}; |
@ -0,0 +1,8 @@ |
|||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. |
|||
# yarn lockfile v1 |
|||
|
|||
|
|||
moment@^2.24.0: |
|||
version "2.24.0" |
|||
resolved "https://registry.npm.taobao.org/moment/download/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" |
|||
integrity sha1-DQVdU/UFKqZTyfbraLtdEr9cK1s= |
Loading…
Reference in new issue