Commit 8d31ed1d by 莫晓莉

残联二期项目APP页面

parents
<script>
import {
mapState,
mapMutations
} from 'vuex'
export default {
onLaunch: function() {
let uniIdToken = uni.getStorageSync('uniIdToken')
if (uniIdToken) {
this.login(uni.getStorageSync('username'))
}
console.log('App Launch');
},
onShow: function() {
console.log('App Show');
},
onHide: function() {
console.log('App Hide');
},
methods: {
...mapMutations(['login']),
}
}
</script>
<style>
@import './common/common.css';
/* 头条小程序需要把 iconfont 样式放到组件外 */
@import "components/m-icon/m-icon.css";
/*每个页面公共css */
page {
min-height: 100%;
display: flex;
font-size: 16px;
}
/* #ifdef MP-BAIDU */
page {
width: 100%;
height: 100%;
display: block;
}
swan-template {
width: 100%;
min-height: 100%;
display: flex;
}
/* 原生组件模式下需要注意组件外部样式 */
custom-component {
width: 100%;
min-height: 100%;
display: flex;
}
/* #endif */
/* #ifdef MP-ALIPAY */
page {
min-height: 100vh;
}
/* #endif */
/* 原生组件模式下需要注意组件外部样式 */
m-input {
width: 100%;
/* min-height: 100%; */
display: flex;
flex: 1;
}
.content {
display: flex;
flex: 1;
flex-direction: column;
background-color: #efeff4;
padding: 10px;
}
.input-group {
background-color: #ffffff;
margin-top: 20px;
position: relative;
}
.input-group::before {
position: absolute;
right: 0;
top: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.input-group::after {
position: absolute;
right: 0;
bottom: 0;
left: 0;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.input-row {
display: flex;
flex-direction: row;
position: relative;
font-size: 18px;
line-height: 40px;
}
.input-row .title {
width: 100px;
padding-left: 15px;
}
.input-row.border::after {
position: absolute;
right: 0;
bottom: 0;
left: 8px;
height: 1px;
content: '';
-webkit-transform: scaleY(.5);
transform: scaleY(.5);
background-color: #c8c7cc;
}
.btn-row {
margin-top: 25px;
padding: 10px;
}
button.primary {
background-color: #0faeff;
}
</style>
MIT License
Copyright (c) 2018 DCloud
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
# uni-template-login
基于 uni-app & uniCloud 的前后一体登录模板
![](https://img-cdn-qiniu.dcloud.net.cn/7E6B79E2-B469-4CF3-8F4D-7502E72C4CB8.png?imageView2/0/w/375)
![](https://img-cdn-qiniu.dcloud.net.cn/659AE293-95F8-46E1-AC1F-D62FE3B080DB.png?imageView2/0/w/375)
## 快速体验
手机扫码体验:
![](https://img.cdn.aliyun.dcloud.net.cn/uni-app/uni-template-login-qr.png)
## 本地运行
1. 将项目拖入[HBuilderX](http://www.dcloud.io/hbuilderx.html)
2. 创建服务空间,详情参考[uniCloud 快速上手](https://uniapp.dcloud.net.cn/uniCloud/quickstart)
3. 上传 common 下的公用模块、在云函数 user-center 内安装 uni-id 模块并上传,[公用模块参考文档](https://uniapp.dcloud.io/uniCloud/cf-common)
4. 在 cloudfunctions 目录下的`db_init.json`右键初始化云数据库
5. 运行到 HBuilderX 内置浏览器体验
6. 如果运行到小程序,注意在小程序后台配置域名白名单,[详见](https://uniapp.dcloud.net.cn/uniCloud/quickstart?id=%e5%b0%8f%e7%a8%8b%e5%ba%8f%e4%b8%ad%e4%bd%bf%e7%94%a8unicloud%e7%9a%84%e7%99%bd%e5%90%8d%e5%8d%95%e9%85%8d%e7%bd%ae)
## 特点
- 前端基于uni-app实现,支持所有平台
- 服务端基于 uniCloud 实现,用户管理基于 [uni-id](https://uniapp.dcloud.net.cn/uniCloud/uni-id) 实现
- 使用 vuex 管理登录状态
- 支持账号密码、手机号验证等多种登录模式
{
"passwordSecret": "passwordSecret-demo",
"tokenSecret": "tokenSecret-demo",
"tokenExpiresIn": 7200,
"passwordErrorLimit": 6,
"bindTokenToDevice": true,
"passwordErrorRetryTime": 3600,
"app-plus": {
"tokenExpiresIn": 2592000,
"oauth" : {
"weixin" : {
"appid" : "weixin appid",
"appsecret" : "weixin appsecret"
}
}
},
"mp-weixin": {
"oauth" : {
"weixin" : {
"appid" : "weixin appid",
"appsecret" : "weixin appsecret"
}
}
},
"mp-alipay": {
"oauth" : {
"alipay" : {
"appid" : "alipay appid",
"privateKey" : "alipay privateKey"
}
}
},
"service": {
"sms": {
"name": "your app name",
"codeExpiresIn": 180,
"smsKey": "your sms key",
"smsSecret": "your sms secret"
}
}
}
{
"name": "uni-id",
"version": "1.1.1",
"description": "uni-id for uniCloud",
"main": "index.js",
"scripts": {},
"keywords": [],
"author": "",
"license": "Apache-2.0"
}
// 在本文件中可配置云数据库初始化,数据格式见:https://uniapp.dcloud.io/uniCloud/cf-database?id=db_init
// 编写完毕后对本文件点右键,可按配置规则创建表和添加数据
{
"uni-id-users": {
"data": [],
"index": [{
"IndexName": "username",
"MgoKeySchema": {
"MgoIndexKeys": [{
"Name": "username",
"Direction": "1"
}],
"MgoIsUnique": false
}
}, {
"IndexName": "mobile",
"MgoKeySchema": {
"MgoIndexKeys": [{
"Name": "mobile",
"Direction": "1"
}],
"MgoIsUnique": false
}
}, {
"IndexName": "email",
"MgoKeySchema": {
"MgoIndexKeys": [{
"Name": "email",
"Direction": "1"
}],
"MgoIsUnique": false
}
}]
},
"uni-verify": {
"data": [],
"index": [{
"IndexName": "mobile",
"MgoKeySchema": {
"MgoIndexKeys": [{
"Name": "mobile",
"Direction": "1"
}],
"MgoIsUnique": false
}
}, {
"IndexName": "email",
"MgoKeySchema": {
"MgoIndexKeys": [{
"Name": "email",
"Direction": "1"
}],
"MgoIsUnique": false
}
}]
}
}
'use strict';
const uniID = require('uni-id')
const db = uniCloud.database()
const dbCmd = db.command
exports.main = async (event, context) => {
//event为客户端上传的参数
console.log('event : ' + event)
let params = event.params
let res = {}
let payload = {}
switch (event.action) {
case 'register':
res = uniID.register(params);
break;
case 'login':
res = uniID.login(params);
break;
case 'checkToken':
res = uniID.checkToken(event.uniIdToken);
break;
case 'logout':
res = await uniID.logout(event.uniIdToken)
break;
case 'sendSmsCode':
// 简单限制一下客户端调用频率
const ipLimit = await db.collection('uni-verify').where({
ip: context.CLIENTIP,
created_at: dbCmd.gt(Date.now() - 60000)
}).get()
if(ipLimit.data.length > 0) {
return {
code: 429,
msg: '请求过于频繁'
}
}
const randomStr = '00000' + Math.floor(Math.random() * 1000000)
const code = randomStr.substring(randomStr.length - 6)
res = await uniID.sendSmsCode({
mobile: params.mobile,
code,
type: 'login'
})
break;
case 'loginBySms':
res = await uniID.loginBySms(params)
break;
default:
res = {
code: 403,
msg: '非法访问'
}
break;
}
//返回数据给客户端
return res
};
../../common/uni-id
\ No newline at end of file
{
"name": "user-center",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"uni-id": {
"version": "file:../common/uni-id"
}
}
}
{
"name": "user-center",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"uni-id": "file:../common/uni-id"
}
}
// 本文件中的json内容将在云函数【运行】时作为参数传给云函数。
// 配置教程参考:https://uniapp.dcloud.net.cn/uniCloud/quickstart?id=runparam
{
"action": "sendSmsCode",
"params": {
"mobile": "18810505803"
}
}
\ No newline at end of file
page{
display: flex;
flex-direction: column;
width:100%;
}
.flex{
/*display: flex;兼容写法开始*/
display: -webkit-box; /* 老版本语法: Safari, iOS, Android browser, older WebKit browsers. */
display: -moz-box; /* 老版本语法: Firefox (buggy) */
display: -ms-flexbox; /* 混合版本语法: IE 10 */
display: -webkit-flex; /* 新版本语法: Chrome 21+ */
display: flex; /* 新版本语法: Opera 12.1, Firefox 22+ */
/*display: flex;兼容写法结束*/
}
.flex-ac{
/*align-items兼容写法开始*/
-webkit-align-items:center;
-ms-flex-align:center;
align-items:center;
-webkit-box-align:center;
/*align-items兼容写法开始*/
}
.flex-jc{
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
}
.flex-dc{
-webkit-box-orient: vertical;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
}
.flex-jb{
/*justify-content:space-between;兼容写法开始*/
-webkit-box-pack:justify;
-webkit-justify-content:space-between;
-ms-flex-pack:justify;
justify-content:space-between;
/*align-items兼容写法开始*/
}
.flex-col-b{
/*display: flex;兼容写法开始*/
display: -webkit-box; /* 老版本语法: Safari, iOS, Android browser, older WebKit browsers. */
display: -moz-box; /* 老版本语法: Firefox (buggy) */
display: -ms-flexbox; /* 混合版本语法: IE 10 */
display: -webkit-flex; /* 新版本语法: Chrome 21+ */
display: flex; /* 新版本语法: Opera 12.1, Firefox 22+ */
/*display: flex;兼容写法结束*/
-webkit-box-orient: vertical;
-webkit-flex-direction: column;
-ms-flex-direction: column;
flex-direction: column;
/*justify-content:space-between;兼容写法开始*/
-webkit-box-pack:justify;
-webkit-justify-content:space-between;
-ms-flex-pack:justify;
justify-content:space-between;
/*align-items兼容写法开始*/
}
.flex-a-c{
/*display: flex;兼容写法开始*/
display: -webkit-box; /* 老版本语法: Safari, iOS, Android browser, older WebKit browsers. */
display: -moz-box; /* 老版本语法: Firefox (buggy) */
display: -ms-flexbox; /* 混合版本语法: IE 10 */
display: -webkit-flex; /* 新版本语法: Chrome 21+ */
display: flex; /* 新版本语法: Opera 12.1, Firefox 22+ */
/*display: flex;兼容写法结束*/
/*align-items兼容写法开始*/
-webkit-align-items:center;
-ms-flex-align:center;
align-items:center;
-webkit-box-align:center;
/*align-items兼容写法开始*/
}
.flex-ac-jc{
/*display: flex;兼容写法开始*/
display: -webkit-box; /* 老版本语法: Safari, iOS, Android browser, older WebKit browsers. */
display: -moz-box; /* 老版本语法: Firefox (buggy) */
display: -ms-flexbox; /* 混合版本语法: IE 10 */
display: -webkit-flex; /* 新版本语法: Chrome 21+ */
display: flex; /* 新版本语法: Opera 12.1, Firefox 22+ */
/*display: flex;兼容写法结束*/
/*align-items兼容写法开始*/
-webkit-align-items:center;
-ms-flex-align:center;
align-items:center;
-webkit-box-align:center;
/*align-items兼容写法开始*/
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
}
.flex-ac-jb{
/*display: flex;兼容写法开始*/
display: -webkit-box; /* 老版本语法: Safari, iOS, Android browser, older WebKit browsers. */
display: -moz-box; /* 老版本语法: Firefox (buggy) */
display: -ms-flexbox; /* 混合版本语法: IE 10 */
display: -webkit-flex; /* 新版本语法: Chrome 21+ */
display: flex; /* 新版本语法: Opera 12.1, Firefox 22+ */
/*display: flex;兼容写法结束*/
/*align-items兼容写法开始*/
-webkit-align-items:center;
-ms-flex-align:center;
align-items:center;
-webkit-box-align:center;
/*align-items兼容写法开始*/
/*justify-content:space-between;兼容写法开始*/
-webkit-box-pack:justify;
-webkit-justify-content:space-between;
-ms-flex-pack:justify;
justify-content:space-between;
/*align-items兼容
写法开始*/
}
.flex1{
-prefix-box-flex: 1;
-webkit-box-flex: 1;
-webkit-flex: 1;
-moz-box-flex: 1;
-ms-flex: 1;
flex: 1;
}
.ellipsis2{
display:-webkit-box;
-webkit-box-orient:vertical;
-webkit-line-clamp:2;
overflow:hidden;
}
.flex-wrap{
-webkit-flex-wrap: wrap;
-moz-flex-wrap: wrap;
-ms-flex-wrap: wrap;
-o-flex-wrap: wrap;
flex-wrap: wrap;
}
checkbox .wx-checkbox-input {
width: 35rpx;
height: 35rpx;
}
checkbox .wx-checkbox-input.wx-checkbox-input-checked {
border: none;
background: #38B0A5;
}
checkbox .wx-checkbox-input.wx-checkbox-input-checked::before {
border-radius: 50%;
width: 40rpx;
height: 40rpx;
line-height: 40rpx;
text-align: center;
font-size: 30rpx;
color: #fff;
}
button{
border:none;
border-radius:0;
}
button::after{
border: none;
border-radius: 0;
}
.flex-bt{
/*display: flex;兼容写法开始*/
display: -webkit-box; /* 老版本语法: Safari, iOS, Android browser, older WebKit browsers. */
display: -moz-box; /* 老版本语法: Firefox (buggy) */
display: -ms-flexbox; /* 混合版本语法: IE 10 */
display: -webkit-flex; /* 新版本语法: Chrome 21+ */
display: flex; /* 新版本语法: Opera 12.1, Firefox 22+ */
/*display: flex;兼容写法结束*/
/*justify-content:space-between;兼容写法开始*/
-webkit-box-pack:justify;
-webkit-justify-content:space-between;
-ms-flex-pack:justify;
justify-content:space-between;
/*align-items兼容*/
}
checkbox .wx-checkbox-input {
border-radius: 50%;
width: 40rpx;
height: 40rpx;
}
\ No newline at end of file
@font-face {
font-family: uniicons;
font-weight: normal;
font-style: normal;
src: url('https://img-cdn-qiniu.dcloud.net.cn/fonts/uni.ttf?t=1536565627510') format('truetype');
}
.m-icon {
font-family: uniicons;
font-size: 24px;
font-weight: normal;
font-style: normal;
line-height: 1;
display: inline-block;
text-decoration: none;
-webkit-font-smoothing: antialiased;
}
.m-icon.uni-active {
color: #007aff;
}
.m-icon-contact:before {
content: '\e100';
}
.m-icon-person:before {
content: '\e101';
}
.m-icon-personadd:before {
content: '\e102';
}
.m-icon-contact-filled:before {
content: '\e130';
}
.m-icon-person-filled:before {
content: '\e131';
}
.m-icon-personadd-filled:before {
content: '\e132';
}
.m-icon-phone:before {
content: '\e200';
}
.m-icon-email:before {
content: '\e201';
}
.m-icon-chatbubble:before {
content: '\e202';
}
.m-icon-chatboxes:before {
content: '\e203';
}
.m-icon-phone-filled:before {
content: '\e230';
}
.m-icon-email-filled:before {
content: '\e231';
}
.m-icon-chatbubble-filled:before {
content: '\e232';
}
.m-icon-chatboxes-filled:before {
content: '\e233';
}
.m-icon-weibo:before {
content: '\e260';
}
.m-icon-weixin:before {
content: '\e261';
}
.m-icon-pengyouquan:before {
content: '\e262';
}
.m-icon-chat:before {
content: '\e263';
}
.m-icon-qq:before {
content: '\e264';
}
.m-icon-videocam:before {
content: '\e300';
}
.m-icon-camera:before {
content: '\e301';
}
.m-icon-mic:before {
content: '\e302';
}
.m-icon-location:before {
content: '\e303';
}
.m-icon-mic-filled:before,
.m-icon-speech:before {
content: '\e332';
}
.m-icon-location-filled:before {
content: '\e333';
}
.m-icon-micoff:before {
content: '\e360';
}
.m-icon-image:before {
content: '\e363';
}
.m-icon-map:before {
content: '\e364';
}
.m-icon-compose:before {
content: '\e400';
}
.m-icon-trash:before {
content: '\e401';
}
.m-icon-upload:before {
content: '\e402';
}
.m-icon-download:before {
content: '\e403';
}
.m-icon-close:before {
content: '\e404';
}
.m-icon-redo:before {
content: '\e405';
}
.m-icon-undo:before {
content: '\e406';
}
.m-icon-refresh:before {
content: '\e407';
}
.m-icon-star:before {
content: '\e408';
}
.m-icon-plus:before {
content: '\e409';
}
.m-icon-minus:before {
content: '\e410';
}
.m-icon-circle:before,
.m-icon-checkbox:before {
content: '\e411';
}
.m-icon-close-filled:before,
.m-icon-clear:before {
content: '\e434';
}
.m-icon-refresh-filled:before {
content: '\e437';
}
.m-icon-star-filled:before {
content: '\e438';
}
.m-icon-plus-filled:before {
content: '\e439';
}
.m-icon-minus-filled:before {
content: '\e440';
}
.m-icon-circle-filled:before {
content: '\e441';
}
.m-icon-checkbox-filled:before {
content: '\e442';
}
.m-icon-closeempty:before {
content: '\e460';
}
.m-icon-refreshempty:before {
content: '\e461';
}
.m-icon-reload:before {
content: '\e462';
}
.m-icon-starhalf:before {
content: '\e463';
}
.m-icon-spinner:before {
content: '\e464';
}
.m-icon-spinner-cycle:before {
content: '\e465';
}
.m-icon-search:before {
content: '\e466';
}
.m-icon-plusempty:before {
content: '\e468';
}
.m-icon-forward:before {
content: '\e470';
}
.m-icon-back:before,
.m-icon-left-nav:before {
content: '\e471';
}
.m-icon-checkmarkempty:before {
content: '\e472';
}
.m-icon-home:before {
content: '\e500';
}
.m-icon-navigate:before {
content: '\e501';
}
.m-icon-gear:before {
content: '\e502';
}
.m-icon-paperplane:before {
content: '\e503';
}
.m-icon-info:before {
content: '\e504';
}
.m-icon-help:before {
content: '\e505';
}
.m-icon-locked:before {
content: '\e506';
}
.m-icon-more:before {
content: '\e507';
}
.m-icon-flag:before {
content: '\e508';
}
.m-icon-home-filled:before {
content: '\e530';
}
.m-icon-gear-filled:before {
content: '\e532';
}
.m-icon-info-filled:before {
content: '\e534';
}
.m-icon-help-filled:before {
content: '\e535';
}
.m-icon-more-filled:before {
content: '\e537';
}
.m-icon-settings:before {
content: '\e560';
}
.m-icon-list:before {
content: '\e562';
}
.m-icon-bars:before {
content: '\e563';
}
.m-icon-loop:before {
content: '\e565';
}
.m-icon-paperclip:before {
content: '\e567';
}
.m-icon-eye:before {
content: '\e568';
}
.m-icon-arrowup:before {
content: '\e580';
}
.m-icon-arrowdown:before {
content: '\e581';
}
.m-icon-arrowleft:before {
content: '\e582';
}
.m-icon-arrowright:before {
content: '\e583';
}
.m-icon-arrowthinup:before {
content: '\e584';
}
.m-icon-arrowthindown:before {
content: '\e585';
}
.m-icon-arrowthinleft:before {
content: '\e586';
}
.m-icon-arrowthinright:before {
content: '\e587';
}
.m-icon-pulldown:before {
content: '\e588';
}
.m-icon-scan:before {
content: "\e612";
}
<template>
<view class="m-icon" :class="['m-icon-'+type]" @click="onClick()"></view>
</template>
<script>
export default {
props: {
/**
* 图标类型
*/
type: String
},
methods: {
onClick() {
this.$emit('click')
}
}
}
</script>
<style>
@import "./m-icon.css";
</style>
<template>
<view class="m-input-view">
<input :focus="focus" :type="inputType" :value="value" @input="onInput" class="m-input-input" :placeholder="placeholder"
:password="type==='password'&&!showPassword" @focus="onFocus" @blur="onBlur" />
<!-- 优先显示密码可见按钮 -->
<view v-if="clearable&&!displayable&&value.length" class="m-input-icon">
<m-icon color="#666666" type="clear" @click="clear"></m-icon>
</view>
<view v-if="displayable" class="m-input-icon">
<m-icon :style="{color:showPassword?'#666666':'#cccccc'}" type="eye" @click="display"></m-icon>
</view>
</view>
</template>
<script>
import mIcon from './m-icon/m-icon.vue'
export default {
components: {
mIcon
},
props: {
/**
* 输入类型
*/
type: String,
/**
* 值
*/
value: String,
/**
* 占位符
*/
placeholder: String,
/**
* 是否显示清除按钮
*/
clearable: {
type: [Boolean, String],
default: false
},
/**
* 是否显示密码可见按钮
*/
displayable: {
type: [Boolean, String],
default: false
},
/**
* 自动获取焦点
*/
focus: {
type: [Boolean, String],
default: false
}
},
model: {
prop: 'value',
event: 'input'
},
data() {
return {
/**
* 显示密码明文
*/
showPassword: false,
/**
* 是否获取焦点
*/
isFocus: false
}
},
computed: {
inputType() {
const type = this.type
return type === 'password' ? 'text' : type
}
},
methods: {
clear() {
this.$emit('input', '')
},
display() {
this.showPassword = !this.showPassword
},
onFocus() {
this.isFocus = true
},
onBlur() {
this.$nextTick(() => {
this.isFocus = false
})
},
onInput(e) {
this.$emit('input', e.detail.value)
}
}
}
</script>
<style>
.m-input-view {
display: inline-flex;
flex-direction: row;
align-items: center;
/* width: 100%; */
flex: 1;
padding: 0 10px;
}
.m-input-input {
flex: 1;
width: 100%;
height: 20px;
line-height: 20px;
background-color: rgba(0, 0, 0, 0);
}
.m-input-icon {
width: 20px;
font-size: 20px;
line-height: 20px;
color: #666666;
}
</style>
import Vue from 'vue'
import App from './App'
import store from './store'
Vue.config.productionTip = false
Vue.prototype.$store = store
App.mpType = 'app'
const app = new Vue({
store,
...App
})
app.$mount()
{
"name" : "comment_login",
"appid" : "",
"description" : "登录模板",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App特有相关 */
"app-plus" : {
"usingComponents" : true,
"compilerVersion" : 3,
/* 模块配置 */
"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" : "",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"h5" : {
"router" : {
"base" : ""
}
}
}
{
"pages": [ //pages数组中第一项表示应用启动页,
{
"path": "pages/main/main",
"style": {
"navigationBarTitleText": "登录模板"
}
}, {
"path": "pages/login/login",
"style": {
"navigationBarTitleText": "登录"
}
}, {
"path": "pages/reg/reg",
"style": {
"navigationBarTitleText": "注册"
}
}, {
"path": "pages/pwd/pwd",
"style": {
"navigationBarTitleText": "找回密码"
}
}, {
"path": "pages/user/user",
"style": {
"navigationBarTitleText": "我的"
}
}
,{
"path" : "pages/evaluate/evaluate",
"style" : {
"navigationBarTitleText": "满意度评价"
}
}
,{
"path" : "pages/evaluate-history/evaluate-history",
"style" : {
"navigationBarTitleText": "历史评价"
}
}
,{
"path" : "pages/service-apl/service-apl",
"style" : {
"navigationBarTitleText": "申请服务"
}
}
,{
"path" : "pages/service-apl-history/service-apl-history",
"style" : {
"navigationBarTitleText": "审批记录 "
}
}
],
"tabBar": {
"color": "#7a7e83",
"selectedColor": "#d81e06",
"backgroundColor": "#ffffff",
"list": [{
"pagePath": "pages/main/main",
"text": "首页",
"iconPath": "static/bottombar/home.png",
"selectedIconPath": "static/bottombar/selhome.png"
}, {
"pagePath": "pages/user/user",
"text": "我的",
"iconPath": "static/bottombar/my.png",
"selectedIconPath": "./static/bottombar/selmy.png"
}]
},
"globalStyle": {
"navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#CA0000",
"backgroundColor": "#fbf9fe"
}
}
.m-list{
padding:25upx 10upx;
border-bottom:1upx solid #eee;
}
.ser-name{
width:350upx;margin-right:15rpx;
}
.time{
padding-top:15upx;
color:#ccc;
font-size:30upx;
}
.head-img{
flex-shrink: 0;
margin-right:15upx;
width:100upx;
height:100upx;
border-radius:50%;
}
.img-area{
margin-top:15upx;
}
.img-area .upload-img{
width:150upx;
height:150upx;
margin:5upx 10upx;
}
<template>
<view style="padding:0 35rpx;">
<view class="flex m-list" style="">
<image class="head-img" style="" src="../../static/img/app-icon.png"></image>
<view>
<view class="flex">
<view class="ser-name ellipsis2" style="">服务名称</view>
<view class="time">2020.9.10</view>
</view>
<view>
<text></text>
<text></text>
<text></text>
<text></text>
</view>
<view style="color:#ccc;">
服务好,非常满意
</view>
<view class="img-area" style="margin-top:25upx;">
<image class="upload-img" src="../../static/img/app-icon.png"></image>
<image class="upload-img" src="../../static/img/app-icon.png"></image>
<image class="upload-img" src="../../static/img/app-icon.png"></image>
<image class="upload-img" src="../../static/img/app-icon.png"></image>
</view>
</view>
</view>
<view class="flex m-list" style="">
<image class="head-img" style="" src="../../static/img/app-icon.png"></image>
<view>
<view class="flex">
<view class="ser-name ellipsis2" style="">服务名称官方价格封建割据金凤凰过节费过节费监管局房管局发几个</view>
<view class="time">2020.9.10</view>
</view>
<view>
<text></text>
<text></text>
<text></text>
<text></text>
</view>
<view style="color:#ccc;">
服务好,非常满意寄过来交流交流归根结底开花结果开花结果开花结果看黄金矿工会更好规范化
</view>
<view class="img-area" style="margin-top:25upx;">
<image class="upload-img" src="../../static/img/app-icon.png"></image>
<image class="upload-img" src="../../static/img/app-icon.png"></image>
<image class="upload-img" src="../../static/img/app-icon.png"></image>
<image class="upload-img" src="../../static/img/app-icon.png"></image>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style>
@import url("evaluate-history.css");
</style>
.category-title {
font-size: 31upx;
font-weight: bold;
padding: 15upx 0;
}
.cate-box {
padding: 15upx 0;
display: flex;
align-items: center;
}
.category-area {
white-space: nowrap;
position: relative;
background-color: #fff;
z-index: 2;
}
.cate-item {
display: inline-block;
/* padding: 8upx 25upx; */
width: 164upx;
height: 74upx;
line-height: 70upx;
text-align: center;
border: 1upx solid #eee;
font-size: 28upx;
border-radius: 10upx;
background-color: #f4f7f8;
color: #2ac096;
margin-right: 30upx;
}
.cate-item .name {
display: inline-block;
vertical-align: middle;
}
.z-cate {
background: linear-gradient(#27c599, #3a9f84); /* 标准的语法 */
color: white;
}
.g-bd {
padding: 35upx 25upx;
font-size: 30upx;
flex:1;
}
.suggest-area {
margin-top: 25upx;
border: 1upx solid #ccc;
padding: 15upx;
font-size: 25upx;
width: 100%;
box-sizing: border-box;
}
.box-title {
margin-top: 25upx;
font-size: 32upx;
}
.title-intro {
color: #999;
font-size: 22upx;
font-weight: normal;
}
.imgs-area {
padding: 25upx 0;
display: flex;
flex-direction:row;
flex-wrap:wrap;
/* border-bottom: 5upx solid #eee; */
}
.imgs-area .img-box {
display: inline-block;
position: relative;
width: 200upx;
height: 200upx;
/* margin-right: 25upx;
margin-bottom: 15upx; */
margin:10upx;
}
.imgs-area .add-box {
/* vertical-align: top; */
box-sizing: border-box;
font-size: 25upx;
/* padding-top: 30upx; */
/* border: 1upx solid #ccc; */
background: #F4F7F8;
width: 200upx;
height: 200upx;
/* display: inline-block; */
text-align: center;
margin:10upx;
}
.imgs-area .img-box .pic {
display: block;
width: 100%;
height: 100%;
}
.imgs-area .img-box .delete-icon {
position: absolute;
top: -15upx;
right: -15upx;
z-index: 2upx;
width: 40upx;
height: 40upx;
}
.imgs-area .add-btn {
display: inline-block;
width: 80upx;
height: 80upx;
}
.btns-area {
display:flex;
position:fixed;
width:100%;
bottom:0;
padding:50upx 0;
left:0;
}
.send-btn {
position: relative;
padding: 0!important;
width: 250upx!important;
height: 74upx;
line-height: 74upx;
text-align: center;
background:#CA0000; /* 标准的语法 */
color: white;
font-size: 25upx;
border-radius:50upx;
}
.right-icon {
position: absolute;
right: 35upx;
top: 13upx;
}
.cancel-btn {
border: 1upx solid #ccc;
background-color: white;
padding: 0;
width: 250upx!important;
height: 74upx;
line-height: 74upx;
text-align: center;
font-size: 25upx;
border-radius:50upx;
}
/*产品缩略 */
.goodsInfo {
display: flex;
align-items: center;
}
.goodsInfo image {
width: 100upx;
height: 100upx;
border-radius: 8upx;
border: 2upx solid #ccc
}
.goodsInfo view {
margin-left: 30upx;
flex: 1;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
/* 服务完成评价星星******************************** */
/* .star-rating {
unicode-bidi: bidi-override;
color: #ddd;
font-size: 30upx;
padding: 0;
}
.star-rating-shop {
color: #ddd;
font-size: 30upx;
height: 150upx;
}
.star-rating text {
padding: 5px;
font-size: 20px;
}
.star-rating-shop text {
padding: 5px;
font-size: 20px;
}
.star-rating-top {
color: #ffd700;
padding: 0;
position: absolute;
z-index: 1;
display: block;
top: 0;
left: 0;
overflow: hidden;
white-space: nowrap;
}
.star-rating-bottom {
padding: 0;
display: block;
z-index: 0;
} */
.v-o-p-img {
display: inline;
position: relative;
top: 35upx;
margin-right: 50upx;
}
.v-o-p-img image{
width:100upx;
height:100upx;
background:white;
}
.v-o-l-face{
color:#eee;
/* display:inline-block; */
margin-left:60upx;
/* position: relative; */
top:18upx;
}
.v-o-l-face image{
width:70upx;
height:70upx;
}
.v-o-l-text{
display:inline-block;
margin-left:20upx;
color:#ccc;
font-size:30rpx;
}
.star{
display: inline-block;
margin:20upx;
font-size:55upx;
}
/***************************************** */
<template>
<view class="g-bd">
<!-- <view class="type-box" >
<view class="category-title">xx信息<text style="color:red;">*</text></view>
<view class="goodsInfo" >
<image src=""></image>
<view>xx</view>
</view>
</view> -->
<view class="type-box">
<view class="category-title">
星级评价 <text style="color:red;">*</text>
</view>
<view class="cate-box">
<!-- <scroll-view scroll-x="true" class="category-area">
<block wx:for="{{ suggestInfo.typeList }}" wx:key="index">
<view bindtap="selectTypeTap" class="cate-item ">
<text class="name" >xx</text>
</view>
</block>
</scroll-view> -->
<view class="star" v-for="(item,index) in starsList" :key="item.id" v-bind:style="{ color: [item.selected ?'red':'#ccc']}"
:data-current="index" @tap="selStar">{{ item.content }}</view>
<view class='flex-a-c v-o-l-face'>
<image :src="starLevel[cur_starLevel].face" />
<view class='v-o-l-text'>{{starLevel[cur_starLevel].name}}</view>
</view>
</view>
</view>
<view class="category-title">
评价内容<text style="color:red;">*</text>
</view>
<textarea class="suggest-area" placeholder="请输入60字以内问题或建议" name="content" maxlength="60"></textarea>
<view class="category-title">
上传图片
<text class="title-intro" style="">(如无图片,可以忽略,最多6张图)</text>
</view>
<view class="imgs-area">
<view class="img-box" v-for="(item,index) in imageList" :key="index">
<image class="pic" :src="item" @tap="previewPictures(item)"/>
<image @click="del(index)" class="delete-icon" src="../../static/comment/delete.png" />
</view>
<view class="flex-ac-jc add-box" @click="uploadPictures">
<image class="add-btn" style='' src='../../static/comment/add-icon.png'></image>
</view>
</view>
<view>
<view class="btns-area">
<button class="send-btn flex-ac-jc">确 定</button>
<button class="cancel-btn flex-ac-jc">取 消</button>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
imageList: [],
starsList: [{
id: 1,
content: "★",
selected: true
}, {
id: 2,
content: "★",
selected: false
},
{
id: 3,
content: "★",
selected: false
}, {
id: 4,
content: "★",
selected: false
},
{
id: 5,
content: "★",
selected: false
}
],
// orderList: [{
// id: 1,
// content: "★",
// selected: false
// }, {
// id: 2,
// content: "★",
// selected: false
// },
// {
// id: 3,
// content: "★",
// selected: false
// }, {
// id: 4,
// content: "★",
// selected: false
// },
// {
// id: 5,
// content: "★",
// selected: false
// }
// ],
starLevel: [
{
level:1,
name: "不满意",
face: "../../static/comment/level1.png"
},
{
level:2,
name: "较不满意",
face: "../../static/comment/level2.png"
},
{
level:3,
name: "一般",
face: "../../static/comment/level3.png"
},
{
level:4,
name: "较满意",
face: "../../static/comment/level4.png"
},
{
level:5,
name: "很满意",
face: "../../static/comment/praise.png"
},
],
cur_starLevel:0
}
},
methods: {
uploadPictures() {
uni.chooseImage({
count: 6, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album'], //从相册选择
success: res => {
console.log(res)
// 将选择的本地图片赋值给data中定义的images变量
this.imageList =this.imageList.concat(res.tempFilePaths);
console.log(this.imageList)
}
})
},
/*
图片预览
*/
previewPictures(item) {
uni.previewImage({
current: item,
urls: this.imageList
})
},
del(index){
this.imageList.splice(index, 1)
},
selStar(e) {
let idx = e.target.dataset.current || e.currentTarget.dataset.current; //获取下标值
idx++;
var list = this.starsList;
for (var i in list) {
list[i].selected = i < idx ? true : false;
}
// for (var i in starLevel) {
// starLevel[i].level = idx?this.star_level=idx:this.star_level=1;
// }
this.starsList = list;
this.cur_starLevel=idx-1;
},
chooseImg() {
uni.chooseImage({
count: 6, //默认9
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album'], //从相册选择
success: function(res) {
// 预览图片
// uni.previewImage({
// urls: res.tempFilePaths,
// longPressActions: {
// itemList: ['发送给朋友', '保存图片', '收藏'],
// success: function(data) {
// console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');
// },
// fail: function(err) {
// console.log(err.errMsg);
// }
// }
// });
// console.log(JSON.stringify(res.tempFilePaths));
// this.imageList = res.tempFilePaths
this.imageList = res.tempFilePaths;
}
});
},
}
}
</script>
<style>
@import url('evaluate.css');
</style>
.head-icon{
display:block;
margin:50upx auto;
width:150upx;
height:150upx;
border-radius:50%;
}
.login-area{
background-color:#fff;
width:95%;
margin:0 auto;
border:1upx solid #eee;
border-radius:15upx;
}
.login-item{
/* background-color:#fff; */
display: flex;
align-items: center;
/* border-radius:15upx; */
}
.login-icon{
width:50upx;
height:50upx;
margin:0 30upx;
}
.login-item-input{
flex:1;
height:120upx;
line-height:120upx;
font-size:30upx;
}
.bt{
border-bottom:1upx solid #eee;
}
.code-btn{
font-size:25rpx;
border:1upx solid #ccc;
padding:15upx;
border-radius:15upx;
margin:0 25upx;
}
.btn-login{
background-color: #CA0000;border-radius:15upx;
}
.mt25{
margin-top:25upx;
}
\ No newline at end of file
<template>
<view class="content">
<view v-if="hasLogin" class="hello">
<view class="title">
您好 {{userName}},您已成功登录。
</view>
<view class="ul">
<view>这是 uni-app 带登录模板的示例App首页。</view>
<view>在 “我的” 中点击 “退出” 可以 “注销当前账户”</view>
</view>
</view>
<view v-if="!hasLogin" class="hello">
<view class="title">
您好 游客。
</view>
<view class="ul">
<view>这是 uni-app 带登录模板的示例App首页。</view>
<view>在 “我的” 中点击 “登录” 可以 “登录您的账户”</view>
</view>
</view>
</view>
</template>
<script>
import {
mapState,
mapMutations
} from 'vuex'
export default {
computed: mapState(['forcedLogin', 'hasLogin', 'userName']),
onLoad() {
const loginType = uni.getStorageSync('login_type')
if (loginType === 'local') {
this.login(uni.getStorageSync('username'))
return
}
let uniIdToken = uni.getStorageSync('uniIdToken')
if (uniIdToken) {
this.login(uni.getStorageSync('username'))
uniCloud.callFunction({
name: 'user-center',
data: {
action: 'checkToken',
},
success: (e) => {
console.log('checkToken success', e);
if (e.result.code > 0) {
//token过期或token不合法,重新登录
if (this.forcedLogin) {
uni.reLaunch({
url: '../login/login'
});
} else {
uni.navigateTo({
url: '../login/login'
});
}
}
},
fail(e) {
uni.showModal({
content: JSON.stringify(e),
showCancel: false
})
}
})
} else {
this.guideToLogin()
}
},
methods: {
...mapMutations(['login']),
guideToLogin() {
uni.showModal({
title: '未登录',
content: '您未登录,需要登录后才能继续',
/**
* 如果需要强制登录,不显示取消按钮
*/
showCancel: !this.forcedLogin,
success: (res) => {
if (res.confirm) {
/**
* 如果需要强制登录,使用reLaunch方式
*/
if (this.forcedLogin) {
uni.reLaunch({
url: '../login/login'
});
} else {
uni.navigateTo({
url: '../login/login'
});
}
}
}
});
}
}
}
</script>
<style>
.hello {
display: flex;
flex: 1;
flex-direction: column;
}
.title {
color: #8f8f94;
margin-top: 25px;
}
.ul {
font-size: 15px;
color: #8f8f94;
margin-top: 25px;
}
.ul>view {
line-height: 25px;
}
</style>
<template>
<view class="content">
<view class="input-group">
<view class="input-row">
<text class="title">邮箱:</text>
<m-input type="text" focus clearable v-model="email" placeholder="请输入邮箱"></m-input>
</view>
</view>
<view class="btn-row">
<button type="primary" class="primary" @tap="findPassword">提交</button>
</view>
</view>
</template>
<script>
import service from '../../service.js';
import mInput from '../../components/m-input.vue';
export default {
components: {
mInput
},
data() {
return {
email: ''
}
},
methods: {
findPassword() {
/**
* 仅做示例
*/
if (this.email.length < 3 || !~this.email.indexOf('@')) {
uni.showToast({
icon: 'none',
title: '邮箱地址不合法',
});
return;
}
uni.showToast({
icon: 'none',
title: '已发送重置邮件至注册邮箱,请注意查收。',
duration: 3000
});
}
}
}
</script>
<style>
</style>
.head-icon{
display:block;
margin:50upx auto;
width:150upx;
height:150upx;
border-radius:50%;
}
.login-area{
/* background-color:#fff; */
width:95%;
margin:0 auto;
border:1upx solid #eee;
/* border-radius:15upx; */
}
.login-item{
background-color:#fff;
display: flex;
align-items: center;
border-radius:15upx;
}
.login-icon{
width:50upx;
height:50upx;
margin:0 30upx;
}
.login-item-input{
flex:1;
height:90upx;
line-height:90upx;
font-size:30upx;
}
.bt{
border-bottom:1upx solid #eee;
}
.code-btn{
font-size:25rpx;
border:1upx solid #ccc;
padding:15upx;
border-radius:15upx;
margin:0 25upx;
}
.btn-login{
background-color: #CA0000;
border-radius:15upx;
}
.mt25{
margin-top:25upx;
}
.uni-list-cell{
margin:0 50upx;
}
.radio-v{
padding:25upx 30upx;
font-size:30upx;
}
/* .uni-radio-input {
background-color: red!important;
border-color: red!important;
}
.uni-radio-input-checked{
background-color: red!important;
border-color: red!important;
} */
\ No newline at end of file
<template>
<view class="content">
<!-- <view class="input-group">
<view class="input-row border">
<text class="title">账号:</text>
<m-input type="text" focus clearable v-model="username" placeholder="请输入账号"></m-input>
</view>
<view class="input-row border">
<text class="title">密码:</text>
<m-input type="password" displayable v-model="password" placeholder="请输入密码"></m-input>
</view>
<view class="input-row">
<text class="title">确认密码:</text>
<m-input type="password" displayable v-model="confirmPassword" placeholder="请确认密码"></m-input>
</view>
</view> -->
<!-- 登录新样式start -->
<view style="text-align: center;color:#CA0000;font-size:45upx;padding:50upx;">
<!-- <image class="head-icon" style="" src="../../static/login/personal.png"></image> -->
欢迎注册!
</view>
<view class="login-area">
<view class="login-item">
<image class="login-icon" src="../../static/login/mine.png"></image>
<input class="login-item-input" placeholder="请输入身份证号" />
</view>
<view class="login-item radio-v mt25" style="">
<view>是否持证</view>
<radio-group class="flex uni-list" @change="radioChange">
<view class="flex uni-list-cell uni-list-cell-pd" v-for="(item,index) in radioItems" :key="index">
<view>
<radio :id="item.name" :value="item.name" :checked="item.checked"></radio>
</view>
<label class="label-2-text" :for="item.name">
<text>{{item.value}}</text>
</label>
</view>
</radio-group>
</view>
<view class="login-item mt25">
<image class="login-icon" src="../../static/login/phone.png"></image>
<input class="login-item-input" placeholder="请输入手机号码" />
</view>
<view class="login-item mt25">
<image class="login-icon" src="../../static/login/code.png"></image>
<input class="login-item-input" placeholder="请输入验证码" />
<view class="code-btn" style="">获取验证码</view>
</view>
<view class="login-item mt25">
<image class="login-icon" src="../../static/login/password.png"></image>
<input class="login-item-input" placeholder="请输入登录密码" />
</view>
<view class="login-item mt25">
<image class="login-icon" src="../../static/login/password.png"></image>
<input class="login-item-input" placeholder="请再次输入登录密码" />
</view>
</view>
<!-- 登录新样式end -->
<view class="btn-row">
<button type="primary" class="primary btn-login" @tap="register">注册</button>
</view>
</view>
</template>
<script>
import service from '../../service.js';
import mInput from '../../components/m-input.vue';
export default {
components: {
mInput
},
data() {
return {
username: '',
password: '',
confirmPassword: '',
radioItems: [{
name: 'USA',
value: '是'
},
{
name: 'CHN',
value: '否',
checked: 'true'
}
],
}
},
methods: {
register() {
/**
* 客户端对账号信息进行一些必要的校验。
* 实际开发中,根据业务需要进行处理,这里仅做示例。
*/
if (this.username.length < 3) {
uni.showToast({
icon: 'none',
title: '账号最短为 3 个字符'
});
return;
}
if (this.password.length < 6) {
uni.showToast({
icon: 'none',
title: '密码最短为 6 个字符'
});
return;
}
if (this.password !== this.confirmPassword) {
uni.showToast({
icon: 'none',
title: '两次密码输入不一致'
});
return;
}
const data = {
username: this.username,
password: this.password
}
uniCloud.callFunction({
name: 'user-center',
data: {
action: 'register',
params: data
},
success(e) {
console.log("注册成功", e);
if (e.result.code === 0) {
uni.showToast({
title: '注册成功'
});
uni.setStorageSync('uniIdToken', e.result.token)
uni.setStorageSync('username', e.result.username)
uni.reLaunch({
url: '../main/main',
});
} else {
uni.showModal({
content: JSON.stringify(e.result),
showCancel: false
})
}
},
fail(e) {
uni.showModal({
content: JSON.stringify(e),
showCancel: false
})
}
})
}
}
}
</script>
<style>
@import url("reg.css");
</style>
.menu-bar{
text-align: center;
}
.tybe-tab{
display: inline-block;
width:33%;
height:90upx;
line-height:90upx;
text-align: center;
font-size:30upx;
font-weight:bold;
}
.z-active{
/* border-bottom:2upx solid red; */
color:red;
position: relative;
}
.z-active::before{
position: absolute;
bottom:0;
left:30%;
content: '';
height:2upx;
width:100upx;
background-color: red;;
}
.list-area{
padding:0 35upx;
}
.m-his-list{
padding:35upx 0;
border-bottom:1upx solid #eee;
}
.his-item{
font-size:28upx;
color: #ccc;
}
.his-item-result{
font-size:28upx;
color: #ccc;
color:red;
}
.mt10{
margin-top:10upx;
}
\ No newline at end of file
<template>
<view>
<view class="menu-bar">
<block v-for="(tab,index) in StatusList" :key="tab.id">
<view :data-current="index" @click="ontabtap" class="tybe-tab" :class="statusIndex==index ? 'z-active' : ''">{{tab.name}}</view>
</block>
<!-- <view class="tybe-tab">已审批</view>
<view class="tybe-tab">待审批</view> -->
</view>
<block v-if="statusIndex==0">
<view class="list-area">
<view class="m-his-list" style="">
<view class="his-item">申请人:张三</view>
<view class="his-item mt10">伤残等级:一级</view>
<view class="his-item mt10">伤残类别:意外</view>
<view class="his-item mt10">服务类型:特殊服务</view>
<view class="his-item mt10">申请时间:2020.10.1</view>
<view class="his-item-result mt10">审批结果:待审批</view>
</view>
<view class="m-his-list" style="">
<view class="his-item">申请人:张三</view>
<view class="his-item mt10">伤残等级:一级</view>
<view class="his-item mt10">伤残类别:意外</view>
<view class="his-item mt10">服务类型:特殊服务</view>
<view class="his-item mt10">申请时间:2020.10.1</view>
<view class="his-item-result mt10">审批结果:拒绝</view>
<view class="his-item-result mt10">拒绝理由:个叽里呱啦</view>
</view>
</view>
</block>
</view>
</template>
<script>
export default {
data() {
return {
statusIndex:0,
StatusList:[
{
name:'全部'
},
{
name:'已审批'
},
{
name:'待审批'
}
]
}
},
methods: {
ontabtap(e){
let index = e.target.dataset.current || e.currentTarget.dataset.current;
var curIndex=this.statusIndex
if(curIndex==index){
return
}else{
this.statusIndex=index
}
}
}
}
</script>
<style>
@import url("service-apl-history.css");
</style>
page{
padding-bottom:150upx;
background:#F7F7F7;
}
.set-info-title{
font-size:28upx;
color:#999;
background:#F7F7F7;
height:80upx;
line-height:80upx;
padding:0 35upx;
}
.set-info-item {
padding: 0 35upx;
border-bottom: 1upx solid #eee;
}
.set-info-item .item-name {
position: relative;
font-size: 30upx;
margin-right: 25upx;
padding-right: 25upx;
white-space: nowrap;
flex-shrink: 0;
}
.set-info-item .item-name .remind-icon {
position: absolute;
right: -5upx;
top: 5upx;
width: 16upx;
height: 16upx;
}
.set-info-item .item-iput {
font-size: 30upx;
height: 90upx;
line-height: 90upx;
padding: 0 25upx;
}
.set-info-pad {
padding-top: 25upx;
padding-bottom: 25upx;
}
.set-intro-item {
padding: 25upx 35upx;
}
.set-intro-item .item-name {
position: relative;
font-size: 30upx;
margin-right: 25upx;
padding-right: 25upx;
white-space: nowrap;
flex-shrink: 0;
}
.set-intro-item .item-name .remind-icon {
position: absolute;
right: -5upx;
top: 5upx;
width: 16upx;
height: 16upx;
}
.set-intro-item .intro-holder {
font-size: 30upx;
color: #999;
text-align: right;
padding: 0 25upx;
}
.into-num {
font-size: 25upx;
color: #999;
text-align: center;
}
.area-view {
padding: 15upx 35upx;
border-bottom: 1upx solid #eee;
}
.intro-area {
width: 100%;
height: 200upx;
font-size: 30upx;
}
.intro-img {
width: 200upx;
height: 200upx;
background: #ccc;
margin: 0 auto;
}
.img-box {
display: block;
position: relative;
width: 200upx;
height: 200upx;
margin: 0 auto;
}
.add-box {
display: block;
box-sizing: border-box;
font-size: 25upx;
padding-top: 30upx;
border: 1upx solid #ccc;
width: 200upx;
height: 200upx;
text-align: center;
margin: 0 auto;
color:#ccc;
}
.img-box .pic {
display: block;
width: 100%;
height: 100%;
}
.img-box .delete-icon {
position: absolute;
top: 0upx;
right: 0upx;
z-index: 2upx;
width: 40upx;
height: 40upx;
}
.add-btn {
display: inline-block;
width: 80upx;
height: 80upx;
}
.picker-content {
height: 90upx;
line-height: 90upx;
padding: 0 25upx;
font-size: 30upx;
text-align: right;
}
.save-btn {
position: fixed;
width: 100%;
bottom: 0;
left: 0;
height: 100upx;
line-height: 100upx;
text-align: center;
font-size: 32upx;
background-color: #03A9F4;
color:white;
}
/* 提示信息 */
.msg-remind-input{
height:85upx;line-height:85upx;font-size:28upx;
}
.msg-remind-btn{
width:150upx;height:60upx;line-height:60upx;text-align:center;font-size:26upx;border:1upx solid #eee;border-radius:10upx;
}
.trangle{
display:inline-block;
border-top: 15upx solid;
border-right: 8upx solid;
border-left: 8upx solid;
border-color: black transparent transparent transparent;
}
\ No newline at end of file
<template>
<view>
<view style="background:white;">
<!-- <view class="set-info-title">小程序名称设置</view> -->
<view class="flex-a-c set-info-item">
<view class="item-name">
<text>姓名</text>
<text style="color:red;">*</text>
<!-- <image class="remind-icon" mode="aspectFit" style="" src=""></image> -->
</view>
<view class="flex1">
<input name="nickName" value="" class="item-iput"
placeholder="请输入姓名"></input>
</view>
</view>
<view class="flex-a-c set-info-item">
<view class="item-name">
<text>地址</text>
<text style="color:red;">*</text>
<!-- <image class="remind-icon" mode="aspectFit" style="" src=""></image> -->
</view>
<view class="flex1">
<input name="nickName" value="" class="item-iput"
placeholder="请输入居住地址"></input>
</view>
</view>
<view class="flex-a-c set-info-item">
<view class="item-name">
<text>伤残等级</text>
<text style="color:red;">*</text>
<!-- <image class="remind-icon" mode="aspectFit" style="" src=""></image> -->
</view>
<view class="flex1">
<picker @change="bindPickerChange" :value="index" :range="arrayHurt" range-key="name">
<view class="flex-a-c" style="justify-content:flex-end;">
<view class="picker-content" style=''>{{arrayHurt[index].name}}</view>
<view class="trangle"></view>
</view>
</picker>
</view>
</view>
<view class="flex-a-c set-info-item">
<view class="item-name">
<text>伤残类别</text>
<text style="color:red;">*</text>
<!-- <image class="remind-icon" mode="aspectFit" style="" src=""></image> -->
</view>
<view class="flex1">
<picker bindchange="cat1Change" value="" range="" range-key="name">
<view class="flex-a-c" style="justify-content:flex-end;">
<view class="picker-content" style=''>意外</view>
<view class="trangle"></view>
</view>
</picker>
</view>
</view>
<view class="flex-a-c set-info-item">
<view class="item-name">
<text>项目类型</text>
<text style="color:red;">*</text>
<!-- <image class="remind-icon" mode="aspectFit" style="" src=""></image> -->
</view>
<view class="flex1">
<picker bindchange="cat1Change" value="" range="" range-key="name">
<view class="flex-a-c" style="justify-content:flex-end;">
<view class="picker-content" style=''>公益服务</view>
<view class="trangle"></view>
</view>
</picker>
</view>
</view>
<!-- <view class="flex set-info-item set-info-pad">
<view class="item-name">
<text>上传附件</text>
<text style="color:red;">*</text>
</view>
<view class="flex1">
<view class="img-box" style=''>
<image class="pic" style='' src='../../../images/test/banner1.jpg'></image>
<image class="delete-icon" style='' src='../../../images/total/delete.png'></image>
</view>
<block wx:if="{{licImage!=null}}">
<view class="img-box" style=''>
<image class="pic" style='' src=''></image>
<image bindtap='deleteImage' class="delete-icon" style='' src=''></image>
</view>
</block>
<view class="add-box">
<image class="add-btn" style='' src=''></image>
<view>添加</view>
</view>
</view>
</view> -->
<!-- 设置名称 -->
<!-- <view class="flex-a-c" style="padding:0 35rpx;">
<input class="flex1 msg-remind-input" disabled="true" placeholder="小程序名称未设置"></input>
<view class="msg-remind-btn" style="">设置名称</view>
</view>
<view class="set-info-title">小程序介绍设置</view>
<view class="flex set-intro-item">
<view class="item-name">
<text>小程序介绍\n</text>
<text class="into-num">不超过120个字符</text>
<image class="remind-icon" mode="aspectFit" style="" src=""></image>
</view>
<view class="flex1">
<view class="intro-holder">请输入小程序介绍</view>
</view>
</view> -->
<!-- <view class="area-view" style="">
<textarea name="signature" maxlength="120" class="intro-area" placeholder="请输入小程序介绍,不超过120个字符"></textarea>
</view>
<view class="flex-a-c" style="padding:0 35rpx;">
<input class="flex1 msg-remind-input" disabled="true" placeholder="小程序介绍未设置"></input>
<view class="msg-remind-btn" style="">设置介绍</view>
</view> -->
<!-- <view class="set-info-title">小程序图标设置</view>
<view class="flex set-info-item set-info-pad">
<view class="item-name">
<text>小程序图标\n</text>
<text class="into-num">144px*144px</text>
<image class="remind-icon" mode="aspectFit" style="" src=""></image>
</view>
<view class="flex1">
<view class="img-box" style=''>
<image class="pic" style='' src='../../../images/test/banner1.jpg'></image>
<image class="delete-icon" style='' src='../../../images/total/delete.png'></image>
</view>
<view class="add-box">
<image class="add-btn" style='' src=''></image>
<view>添加</view>
</view>
</view>
</view>
<view class="flex-a-c" style="padding:0 35rpx;">
<input class="flex1 msg-remind-input" disabled="true" placeholder="小程序图标未设置"></input>
<view class="msg-remind-btn" style="">设置图标</view>
</view> -->
<!-- <view class="set-info-title">小程序类目设置</view>
<view class="flex-a-c set-info-item">
<view class="item-name">
<text>选择一级类目</text>
<image class="remind-icon" mode="aspectFit" style="" src=""></image>
</view>
<view class="flex1">
<picker bindchange="cat1Change" value="" range="" range-key="name">
<view class="flex-a-c" style="justify-content:flex-end;">
<view class="picker-content" style=''>ggg</view>
<view class="trangle"></view>
</view>
</picker>
</view>
</view>
<view class="flex-a-c set-info-item">
<view class="item-name">
<text>选择二级类目</text>
<image class="remind-icon" mode="aspectFit" style="" src=""></image>
</view>
<view class="flex1">
<picker class="" style='' bindchange="cat2Change" value="" range="" range-key="name">
<view class="flex-a-c" style="justify-content:flex-end;">
<view class="picker-content" style=''>bb</view>
<view class="trangle"></view>
</view>
</picker>
</view>
</view>
<view class="flex-a-c" style="padding:0 35rpx;">
<input class="flex1 msg-remind-input" disabled="true" placeholder="小程序类目未设置"></input>
<view class="msg-remind-btn" style="">设置类目</view>
</view> -->
<!-- <view class="flex set-info-item set-info-pad">
<view class="item-name">
<text>营业执照\n</text>
<text class="into-num">小程序申请单位的营业执照</text>
<image class="remind-icon" mode="aspectFit" style="" src="../../../images/total/star.png"></image>
</view>
<view class="flex1">
<block wx:if="{{licImage!=null}}">
<view class="img-box" style=''>
<image class="pic" style='' src='{{licImage}}'></image>
<image bindtap='deleteImage' class="delete-icon" style='' src='../../../images/total/delete.png'></image>
</view>
</block>
<view class="add-box">
<image bindtap="uploadLic" class="add-btn" style='' src='../../../images/total/add.png'></image>
<view >选择图片</view>
</view>
</view>
</view> -->
<button style="background-color: #CA0000;" class="save-btn">确定</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
arrayHurt: [{name:'一级'},{name: '二级'}, {name:'三级'}, {name:'四级'}],
index: 0,
}
},
methods: {
bindPickerChange: function(e) {
console.log('picker发送选择改变,携带值为:' + e.detail.value)
this.index = e.detail.value
},
}
}
</script>
<style>
@import url("service-apl.css");
</style>
<template>
<view class="">
<view class="center">
<view class="logo" @click="bindLogin" :hover-class="!hasLogin ? 'logo-hover' : ''">
<image class="logo-img" :src="avatarUrl"></image>
<view class="logo-title">
<text class="uer-name">Hi,{{hasLogin ? userName : '您未登录'}}</text>
<text class="go-login navigat-arrow" v-if="!hasLogin">&#xe65e;</text>
</view>
</view>
<view class="center-list" v-for="item in navList" :key="item.id">
<view class="center-list-item border-bottom" v-for="item2 in item.barList" :key="item2.id" @click="goDetailPage(item2)">
<text class="list-icon">&#xe60b;</text>
<text class="list-text">{{item2.name}}</text>
<text class="navigat-arrow">&#xe65e;</text>
</view>
<!-- <view class="center-list-item">
<text class="list-icon">&#xe65f;</text>
<text class="list-text">申请服务</text>
<text class="navigat-arrow">&#xe65e;</text>
</view> -->
</view>
<!-- <view class="center-list">
<view class="center-list-item border-bottom">
<text class="list-icon">&#xe60f;</text>
<text class="list-text">帐号管理</text>
<text class="navigat-arrow">&#xe65e;</text>
</view>
<view class="center-list-item">
<text class="list-icon">&#xe639;</text>
<text class="list-text">新消息通知</text>
<text class="navigat-arrow">&#xe65e;</text>
</view>
</view>
<view class="center-list">
<view class="center-list-item border-bottom">
<text class="list-icon">&#xe60b;</text>
<text class="list-text">帮助与反馈</text>
<text class="navigat-arrow">&#xe65e;</text>
</view>
<view class="center-list-item">
<text class="list-icon">&#xe65f;</text>
<text class="list-text">服务条款及隐私</text>
<text class="navigat-arrow">&#xe65e;</text>
</view>
</view>
<view class="center-list">
<view class="center-list-item">
<text class="list-icon">&#xe614;</text>
<text class="list-text">关于应用</text>
<text class="navigat-arrow">&#xe65e;</text>
</view>
</view> -->
<view class="btn-row">
<button v-if="hasLogin" class="primary" type="primary" @tap="bindLogout">退出登录</button>
</view>
</view>
</view>
</template>
<script>
import {
mapState,
mapMutations
} from 'vuex'
export default {
data() {
return {
avatarUrl: "../../static/img/logo.png",
navList: [
{
id: 1,
barList: [{
id: 1,
name: '满意度评价',
url: '/pages/evaluate/evaluate'
},
{
id: 2,
name: '申请服务',
url: '/pages/service-apl/service-apl'
}
],
},
{
id: 2,
barList: [{
id: 3,
name: '历史评价',
url: '/pages/evaluate-history/evaluate-history'
},
{
id: 4,
name: '服务申请记录',
url: '/pages/service-apl-history/service-apl-history'
}
],
},
]
}
},
computed: {
...mapState(['hasLogin', 'forcedLogin', 'userName'])
},
methods: {
...mapMutations(['logout']),
bindLogin() {
uni.navigateTo({
url: '../login/login',
});
},
bindLogout() {
const loginType = uni.getStorageSync('login_type')
if (loginType === 'local') {
this.logout();
if (this.forcedLogin) {
uni.reLaunch({
url: '../login/login',
});
}
return
}
uniCloud.callFunction({
name: 'user-center',
data: {
action: 'logout'
},
success: (e) => {
console.log('logout success', e);
if (e.result.code == 0) {
this.logout();
uni.removeStorageSync('uniIdToken')
uni.removeStorageSync('username')
/**
* 如果需要强制登录跳转回登录页面
*/
if (this.forcedLogin) {
uni.reLaunch({
url: '../login/login',
});
}
} else {
uni.showModal({
content: e.result.msg,
showCancel: false
})
console.log('登出失败', e);
}
},
fail(e) {
uni.showModal({
content: JSON.stringify(e),
showCancel: false
})
}
})
},
// 路径跳转start
goDetailPage(e) {
let path = e.url;
// let url ='/pages/'+path+'/'+path;
uni.navigateTo({
url: path
});
}
// 路径跳转end
}
}
</script>
<style>
@font-face {
font-family: texticons;
font-weight: normal;
font-style: normal;
src: url('https://at.alicdn.com/t/font_984210_5cs13ndgqsn.ttf') format('truetype');
}
page,
view {
display: flex;
}
page {
background-color: #f8f8f8;
}
button {
width: 100%;
}
.center {
flex-direction: column;
}
.logo {
width: 750rpx;
height: 240rpx;
padding: 20rpx;
box-sizing: border-box;
background-color: #CA0000;
flex-direction: row;
align-items: center;
}
.logo-hover {
opacity: 0.8;
}
.logo-img {
width: 150rpx;
height: 150rpx;
border-radius: 150rpx;
}
.logo-title {
height: 150rpx;
flex: 1;
align-items: center;
justify-content: space-between;
flex-direction: row;
margin-left: 20rpx;
}
.uer-name {
height: 60rpx;
line-height: 60rpx;
font-size: 38rpx;
color: #FFFFFF;
}
.go-login.navigat-arrow {
font-size: 38rpx;
color: #FFFFFF;
}
.login-title {
height: 150rpx;
align-items: self-start;
justify-content: center;
flex-direction: column;
margin-left: 20rpx;
}
.center-list {
background-color: #FFFFFF;
margin-top: 20rpx;
width: 750rpx;
flex-direction: column;
}
.center-list-item {
height: 90rpx;
width: 750rpx;
box-sizing: border-box;
flex-direction: row;
padding: 0rpx 20rpx;
}
.border-bottom {
border-bottom-width: 1rpx;
border-color: #c8c7cc;
border-bottom-style: solid;
}
.list-icon {
width: 40rpx;
height: 90rpx;
line-height: 90rpx;
font-size: 34rpx;
color: red;
text-align: center;
font-family: texticons;
margin-right: 20rpx;
}
.list-text {
height: 90rpx;
line-height: 90rpx;
font-size: 34rpx;
color: #555;
flex: 1;
text-align: left;
}
.navigat-arrow {
height: 90rpx;
width: 40rpx;
line-height: 90rpx;
font-size: 34rpx;
color: #555;
text-align: right;
font-family: texticons;
}
.myicon{
/* height: 90rpx;
width: 40rpx;
line-height: 90rpx; */
font-size: 34rpx;
color:red;
/* text-align: right; */
font-family: myicons;
}
</style>
// 管理账号信息
const USERS_KEY = 'USERS_KEY';
const STATE_KEY = 'STATE_KEY';
const getUsers = function() {
let ret = '';
ret = uni.getStorageSync(USERS_KEY);
if (!ret) {
ret = '[]';
}
return JSON.parse(ret);
}
const addUser = function(userInfo) {
let users = getUsers();
users.push({
account: userInfo.account,
password: userInfo.password
});
uni.setStorageSync(USERS_KEY, JSON.stringify(users));
}
export default {
getUsers,
addUser
}
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
/**
* 是否需要强制登录
*/
forcedLogin: false,
hasLogin: false,
userName: ""
},
mutations: {
login(state, userName) {
state.userName = userName || '新用户';
state.hasLogin = true;
},
logout(state) {
state.userName = "";
state.hasLogin = false;
}
}
})
export default store
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment