完成师傅注册登录、部分基础功能
This commit is contained in:
parent
bedeacc239
commit
9917390e9b
59
src/App.vue
59
src/App.vue
|
@ -1,7 +1,25 @@
|
|||
<script>
|
||||
export default {
|
||||
onLaunch: function () {
|
||||
this.$store.dispatch("system/initConfig");
|
||||
globalData: {
|
||||
pageConfig: {},
|
||||
},
|
||||
onLaunch: async function () {
|
||||
let pageConfig = this.$storage.get("system_config");
|
||||
if (!pageConfig) {
|
||||
const { windowWidth, windowHeight, statusBarHeight, safeAreaInsets } = uni.getSystemInfoSync();
|
||||
// #ifndef H5
|
||||
const { height, top } = uni.getMenuButtonBoundingClientRect();
|
||||
const headerHeight = height + (top - statusBarHeight) * 2;
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
const headerHeight = 40; // 乘2再使用rpx2px转px使用
|
||||
// #endif
|
||||
pageConfig = { windowWidth, windowHeight, statusBarHeight, headerHeight, safeAreaInsets };
|
||||
this.$storage.set("system_config", pageConfig);
|
||||
}
|
||||
this.globalData.pageConfig = pageConfig;
|
||||
// 初始化用户
|
||||
this.$models.user.initUser();
|
||||
},
|
||||
onShow: function () {},
|
||||
onHide: function () {},
|
||||
|
@ -160,4 +178,41 @@ export default {
|
|||
justify-content: space-between;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
// 输入表单
|
||||
.common-form-container {
|
||||
width: 710rpx;
|
||||
background-color: #fff;
|
||||
margin: 20rpx auto 0 auto;
|
||||
.input-item {
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
height: 105rpx;
|
||||
border-bottom: 2rpx solid #e8e7e7;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 30rpx;
|
||||
line-height: 30rpx;
|
||||
// input
|
||||
.input-box {
|
||||
width: 500rpx;
|
||||
position: relative;
|
||||
padding: 25rpx 0;
|
||||
}
|
||||
.input {
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.title-box {
|
||||
width: 150rpx;
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
line-height: 30rpx;
|
||||
color: #2d2d2d;
|
||||
}
|
||||
.desc {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
<template>
|
||||
<view class="auth-login-box">
|
||||
<widget-modal v-show="showLoginModal" title="该操作需要登录" @close="closeModal" :showClose="false">
|
||||
<view class="login-box">
|
||||
<view class="btn" @click="toLogin">去登录</view>
|
||||
</view>
|
||||
</widget-modal>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import WidgetModal from "@/components/widgets/modal";
|
||||
import { mapState } from "vuex";
|
||||
export default {
|
||||
name: "auth-login-box",
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
components: {
|
||||
WidgetModal,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
showLoginModal: (state) => state.user.showLoginModal,
|
||||
}),
|
||||
},
|
||||
created() {},
|
||||
mounted() {},
|
||||
destroyed() {},
|
||||
methods: {
|
||||
/**
|
||||
* 关闭弹窗
|
||||
* 如果在tabBar页面则relaunch,否则返回
|
||||
*/
|
||||
closeModal() {
|
||||
this.$store.commit("user/showLoginModal", false);
|
||||
if (getCurrentPages().length <= 1) {
|
||||
this.$utils.toPage("/pages/index/index", {}, "relaunch");
|
||||
} else {
|
||||
this.$utils.toPage("", {}, "back");
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 登录页面
|
||||
*/
|
||||
toLogin() {
|
||||
this.$store.commit("user/showLoginModal", false);
|
||||
this.$utils.toPage("/pages/auth/auth");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.auth-login-box {
|
||||
.login-box {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
.btn {
|
||||
width: 100%;
|
||||
background: #7286f1;
|
||||
// border-radius: 50rpx;
|
||||
padding: 20rpx 100rpx;
|
||||
color: #ffffff;
|
||||
font-size: 28rpx;
|
||||
line-height: 28rpx;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -29,11 +29,14 @@
|
|||
<slot></slot>
|
||||
</view>
|
||||
<view class="page-footer"></view>
|
||||
<!-- 组件 -->
|
||||
<auth-login-box />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from "vuex";
|
||||
import AuthLoginBox from "@/components/auth/login-box";
|
||||
import { mapGetters, mapState } from "vuex";
|
||||
export default {
|
||||
name: "component-layout",
|
||||
data() {
|
||||
|
@ -43,7 +46,9 @@ export default {
|
|||
bodyPaddingTop: 0,
|
||||
};
|
||||
},
|
||||
components: {},
|
||||
components: {
|
||||
AuthLoginBox,
|
||||
},
|
||||
props: {
|
||||
minHeight: {
|
||||
type: String,
|
||||
|
@ -79,12 +84,12 @@ export default {
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
config: (state) => state.system.config,
|
||||
...mapGetters({
|
||||
isLogin: "user/isLogin",
|
||||
}),
|
||||
},
|
||||
mounted() {
|
||||
const { statusBarHeight, headerHeight } = this.config;
|
||||
const { statusBarHeight, headerHeight } = getApp().globalData.pageConfig;
|
||||
// #ifndef H5
|
||||
this.statusBarHeight = statusBarHeight;
|
||||
this.headerHeight = headerHeight;
|
||||
|
@ -98,6 +103,9 @@ export default {
|
|||
if (this.showHeader) {
|
||||
this.bodyPaddingTop = safePaddingTop;
|
||||
}
|
||||
if (this.isLogin) {
|
||||
this.$store.dispatch("user/info");
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onClick() {
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<text class="title">
|
||||
{{ title }}
|
||||
</text>
|
||||
<text class="iconfont icon-guanbi close" @click="close"></text>
|
||||
<text class="iconfont icon-guanbi close" v-if="showClose" @click="close"></text>
|
||||
</view>
|
||||
<view class="content-box">
|
||||
<slot></slot>
|
||||
|
@ -30,6 +30,10 @@ export default {
|
|||
type: String,
|
||||
default: "650rpx",
|
||||
},
|
||||
showClose: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
components: {},
|
||||
created() {},
|
||||
|
@ -52,7 +56,7 @@ export default {
|
|||
right: 0;
|
||||
max-width: 750px;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
@ -94,7 +98,7 @@ export default {
|
|||
}
|
||||
}
|
||||
.content-box {
|
||||
// padding-top: 15rpx;
|
||||
padding-top: 15rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,7 +1,24 @@
|
|||
const apis = {
|
||||
member: {
|
||||
info: "/member/info"
|
||||
}
|
||||
user: {
|
||||
sendCode: {
|
||||
url: "/wxapp/public/send",
|
||||
},
|
||||
openId: {
|
||||
url: "/wxapp/public/getopenid",
|
||||
},
|
||||
register: {
|
||||
url: "/wxapp/public/registerb",
|
||||
},
|
||||
login: {
|
||||
url: "/wxapp/public/loginb",
|
||||
},
|
||||
resetPassword: {
|
||||
url: "/wxapp/public/passwordReset",
|
||||
},
|
||||
info: {
|
||||
url: "/user/workerinfo/getuserinfo",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
export default apis
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
const config = {
|
||||
name: "熊熊安装",
|
||||
root: "http://127.0.0.1/api.php"
|
||||
storagePrefix: "worker_",
|
||||
appId: "wx2401c65b68a6c9b5",
|
||||
root: "http://xiongxiong.vipwjf.com/api.php"
|
||||
}
|
||||
|
||||
export default config
|
|
@ -1,17 +0,0 @@
|
|||
const request = async (args) => {
|
||||
const header = {
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'content-type': 'application/x-www-form-urlencoded',
|
||||
};
|
||||
|
||||
const [error, response] = await uni.request({
|
||||
url: args.url,
|
||||
method: args.method || 'get',
|
||||
data: args.data,
|
||||
header: header
|
||||
});
|
||||
|
||||
return Promise.resolve(response);
|
||||
};
|
||||
|
||||
export default request
|
|
@ -1,3 +1,5 @@
|
|||
import $storage from '@/core/storage'
|
||||
|
||||
function time() {
|
||||
return parseInt(Math.round(new Date() / 1000));
|
||||
};
|
||||
|
@ -143,29 +145,68 @@ function debounce(func, wait = 500, immediate = false) {
|
|||
}
|
||||
|
||||
function px2rpx(px) {
|
||||
let { windowWidth } = uni.getStorageSync('system_config');
|
||||
let { windowWidth } = $storage.get('system_config');
|
||||
windowWidth = (windowWidth > 750) ? 750 : windowWidth;
|
||||
return 750 * (px / windowWidth);
|
||||
}
|
||||
|
||||
function rpx2px(rpx) {
|
||||
let { windowWidth } = uni.getStorageSync('system_config');
|
||||
let { windowWidth } = $storage.get('system_config');
|
||||
windowWidth = (windowWidth > 750) ? 750 : windowWidth;
|
||||
return (rpx / 750) * windowWidth;
|
||||
}
|
||||
|
||||
function toPage(url, options) {
|
||||
uni.navigateTo({
|
||||
function toPage(url, options, type) {
|
||||
if (typeof type === "undefined") {
|
||||
type = "navigate";
|
||||
}
|
||||
let params = {
|
||||
...{ url: url, },
|
||||
...options
|
||||
});
|
||||
};
|
||||
switch (type) {
|
||||
case "reload":
|
||||
let pages = getCurrentPages();
|
||||
currentPage = pages[pages.length - 1];
|
||||
currentPage.onShow(currentPage.options);
|
||||
break;
|
||||
case "back":
|
||||
uni.navigateBack({ ...{ delta: 1 }, ...options });
|
||||
break;
|
||||
case "relaunch":
|
||||
uni.reLaunch(params);
|
||||
break;
|
||||
case "redirect":
|
||||
uni.redirectTo(params);
|
||||
break;
|
||||
case "switch":
|
||||
uni.switchTab(params);
|
||||
break;
|
||||
case "navigate":
|
||||
default:
|
||||
uni.navigateTo(params);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
let toastTimer;
|
||||
function toast(title, options) {
|
||||
if (typeof options === "undefined") {
|
||||
options = {};
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!options.duration) {
|
||||
options.duration = 1500;
|
||||
}
|
||||
uni.showToast({
|
||||
...{ title: title, icon: "none" },
|
||||
...options
|
||||
});
|
||||
clearTimeout(toastTimer);
|
||||
toastTimer = setTimeout(() => {
|
||||
resolve();
|
||||
}, options.duration);
|
||||
})
|
||||
}
|
||||
|
||||
function formatNumber(num, limit) {
|
||||
|
@ -176,7 +217,7 @@ function formatNumber(num, limit) {
|
|||
|
||||
function serviceActions() {
|
||||
uni.showActionSheet({
|
||||
itemList: ['电话客服', '微信客服', '微信客服二'],
|
||||
itemList: ['电话客服', '微信客服'],
|
||||
success(res) {
|
||||
console.log('选中了第' + (res.tapIndex + 1) + '个按钮');
|
||||
},
|
||||
|
@ -186,6 +227,47 @@ function serviceActions() {
|
|||
});
|
||||
}
|
||||
|
||||
function chooseImage(count) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let tempFiles = [];
|
||||
// #ifdef H5
|
||||
uni.chooseImage({
|
||||
count: count,
|
||||
success(r) {
|
||||
r.tempFiles.forEach((item, index) => {
|
||||
tempFiles.push({
|
||||
path: r.tempFilePaths[index],
|
||||
size: item.size,
|
||||
});
|
||||
});
|
||||
resolve(tempFiles);
|
||||
},
|
||||
fail(e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
uni.chooseMedia({
|
||||
count: count,
|
||||
mediaType: ["image"],
|
||||
success(r) {
|
||||
r.tempFiles.forEach(item => {
|
||||
tempFiles.push({
|
||||
path: item.tempFilePath,
|
||||
size: item.size,
|
||||
});
|
||||
});
|
||||
resolve(tempFiles);
|
||||
},
|
||||
fail(e) {
|
||||
reject(e);
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
});
|
||||
}
|
||||
|
||||
export default {
|
||||
time,
|
||||
datetime,
|
||||
|
@ -200,4 +282,5 @@ export default {
|
|||
toast,
|
||||
formatNumber,
|
||||
serviceActions,
|
||||
chooseImage,
|
||||
}
|
|
@ -1,60 +1,187 @@
|
|||
import $store from "@/store/index"
|
||||
import Vue from "vue"
|
||||
let prototype = Vue.prototype;
|
||||
|
||||
export default {
|
||||
/**
|
||||
* 获取平台用户信息
|
||||
* 登录平台
|
||||
*/
|
||||
platformInfo() {
|
||||
platformLogin() {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 获取用户信息
|
||||
uni.getUserProfile({
|
||||
provider: 'weixin',
|
||||
desc: "获取用户信息",
|
||||
success: function (info) {
|
||||
console.log(info);
|
||||
// #ifdef MP-WEIXIN
|
||||
uni.login({
|
||||
provider: "weixin",
|
||||
success: (result) => {
|
||||
resolve({
|
||||
code: result.code,
|
||||
userInfo: {
|
||||
avatarUrl: info.userInfo.avatarUrl,
|
||||
city: info.userInfo.city,
|
||||
country: info.userInfo.country,
|
||||
gender: info.userInfo.gender,
|
||||
language: info.userInfo.language,
|
||||
nickName: info.userInfo.nickName,
|
||||
province: info.userInfo.province
|
||||
success(result) {
|
||||
prototype.$request({
|
||||
api: 'user.openId',
|
||||
data: {
|
||||
code: result.code
|
||||
}
|
||||
// encryptedData: info.encryptedData,
|
||||
// iv: info.iv,
|
||||
});
|
||||
},
|
||||
fail: e => {
|
||||
reject(e);
|
||||
},
|
||||
});
|
||||
},
|
||||
fail: e => {
|
||||
reject(e);
|
||||
},
|
||||
});
|
||||
});
|
||||
},
|
||||
register() {
|
||||
this.platformInfo().then(platfromUser => {
|
||||
console.log(platfromUser);
|
||||
}).then((response) => {
|
||||
this.$storage.set("open_id", response.data.openid);
|
||||
return resolve(response.data);
|
||||
}).catch(e => { });
|
||||
},
|
||||
login() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/auth/login'
|
||||
}
|
||||
});
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
return resolve({
|
||||
openid: "mobile_000000000000000000"
|
||||
});
|
||||
// #endif
|
||||
});
|
||||
},
|
||||
getInfo() {
|
||||
/**
|
||||
* 初始化用户
|
||||
*/
|
||||
async initUser() {
|
||||
// openid
|
||||
let openId = prototype.$storage.get("open_id");
|
||||
if (!openId) {
|
||||
await this.platformLogin().then((response) => {
|
||||
openId = response.openid;
|
||||
});
|
||||
}
|
||||
$store.commit("user/openId", openId);
|
||||
// token
|
||||
let token = prototype.$storage.get("user_access_token");
|
||||
$store.commit('user/token', token);
|
||||
},
|
||||
/**
|
||||
* 发送验证码
|
||||
*/
|
||||
sendVerificationCode(mobile) {
|
||||
return new Promise((resolve, reject) => {
|
||||
resolve({
|
||||
id: 123,
|
||||
name: '李四'
|
||||
if (!prototype.$test.mobile(mobile)) {
|
||||
return reject('请输入正确的手机号码');
|
||||
}
|
||||
prototype.$request({
|
||||
api: 'user.sendCode',
|
||||
data: {
|
||||
username: mobile,
|
||||
},
|
||||
}).then((res) => {
|
||||
if (res.code == 1) {
|
||||
return resolve();
|
||||
} else {
|
||||
return reject(response.msg);
|
||||
}
|
||||
}).catch(e => { });
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取信息
|
||||
*/
|
||||
info(refresh) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (refresh === true) {
|
||||
prototype.$storage.remove('userinfo');
|
||||
}
|
||||
let cacheUser = prototype.$storage.get('userinfo');
|
||||
if (cacheUser) {
|
||||
return resolve(cacheUser);
|
||||
}
|
||||
prototype.$request({
|
||||
api: 'user.info',
|
||||
}).then(response => {
|
||||
if (response.code == 1) {
|
||||
let user = {
|
||||
id: response.data.id,
|
||||
avatar: response.data.avatar,
|
||||
nickname: response.data.user_nickname,
|
||||
openid: response.data.openid,
|
||||
mobile: response.data.mobile,
|
||||
createTime: response.data.create_time,
|
||||
finishInfo: response.data.worker != null,
|
||||
};
|
||||
prototype.$storage.set('userinfo', user);
|
||||
return resolve(user);
|
||||
} else {
|
||||
return reject(response.msg);
|
||||
}
|
||||
}).catch(e => { });
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 用户注册
|
||||
*/
|
||||
register(user, verificationCode) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!prototype.$test.mobile(user.mobile)) {
|
||||
return reject('请输入正确的手机号码');
|
||||
}
|
||||
if (user.password.length < 6 || user.password.length > 16) {
|
||||
return reject('密码在6至16位字符之间');
|
||||
}
|
||||
if (!user.openId) {
|
||||
return reject('缺少OpenId,请重启应用');
|
||||
}
|
||||
prototype.$request({
|
||||
api: 'user.register',
|
||||
data: {
|
||||
username: user.mobile,
|
||||
password: user.password,
|
||||
openid: user.openId,
|
||||
verification_code: verificationCode,
|
||||
types: 2,
|
||||
}
|
||||
}).then((response) => {
|
||||
if (response.code == 1) {
|
||||
return resolve(response);
|
||||
} else {
|
||||
return reject(response.msg);
|
||||
}
|
||||
}).catch(e => { });
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 登录用户
|
||||
*/
|
||||
login(user) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!prototype.$test.mobile(user.mobile)) {
|
||||
return reject('请输入正确的手机号码');
|
||||
}
|
||||
if (user.password.length < 6 || user.password.length > 16) {
|
||||
return reject('密码在6至16位字符之间');
|
||||
}
|
||||
prototype.$request({
|
||||
api: 'user.login',
|
||||
data: {
|
||||
username: user.mobile,
|
||||
password: user.password,
|
||||
}
|
||||
}).then(async response => {
|
||||
if (response.code == 1) {
|
||||
prototype.$storage.set('user_access_token', response.data.token);
|
||||
// 提交token到store
|
||||
await this.initUser();
|
||||
return resolve(response);
|
||||
} else {
|
||||
return reject(response.msg);
|
||||
}
|
||||
}).catch(e => { });
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 找回密码
|
||||
*/
|
||||
resetPassword(data, verificationCode) {
|
||||
return new Promise((resolve, reject) => {
|
||||
prototype.$request({
|
||||
api: "user.resetPassword",
|
||||
data: {
|
||||
username: data.username,
|
||||
password: data.password,
|
||||
verification_code: verificationCode,
|
||||
types: 2,
|
||||
},
|
||||
}).then(response => {
|
||||
if (response.code == 1) {
|
||||
return resolve(response.msg);
|
||||
}
|
||||
return reject(response.msg);
|
||||
}).catch(e => { });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
import $store from "@/store/index";
|
||||
import Vue from "vue"
|
||||
let prototype = Vue.prototype;
|
||||
|
||||
function findApi(name) {
|
||||
let pos = name.indexOf('.');
|
||||
if (pos > 0) {
|
||||
let temp, arr = name.split('.');
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (i == 0) {
|
||||
temp = prototype.$apis[arr[i]] || {};
|
||||
} else {
|
||||
temp = temp[arr[i]] || {};
|
||||
}
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
const request = async (args) => {
|
||||
const rule = findApi(args.api || '');
|
||||
if (JSON.stringify(rule) === "{}") {
|
||||
throw "找不到API:" + args.api;
|
||||
}
|
||||
|
||||
const query = (args.query) ? '?' + args.query : '';
|
||||
|
||||
if (typeof rule.auth !== "undefined" && rule.auth === true && !$store.state.user.token) {
|
||||
$store.commit("user/showLoginModal", true);
|
||||
throw "登录态失效";
|
||||
}
|
||||
|
||||
(rule.showLoading) && uni.showLoading({
|
||||
title: "加载中"
|
||||
});
|
||||
|
||||
const contentType = (args.contentType) ? args.contentType : 'application/json';
|
||||
|
||||
const [error, response] = await uni.request({
|
||||
url: prototype.$config.root + rule.url + query,
|
||||
method: rule.method || 'post',
|
||||
data: args.data,
|
||||
header: {
|
||||
"XX-Wxapp-AppId": prototype.$config.appId,
|
||||
'XX-Token': $store.state.user.token,
|
||||
'XX-Device-Type': 'wxapp',
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
'content-type': contentType,
|
||||
}
|
||||
});
|
||||
|
||||
(rule.showLoading) && uni.hideLoading();
|
||||
|
||||
if (error) {
|
||||
prototype.$utils.toast('网络错误');
|
||||
throw "网络错误";
|
||||
}
|
||||
|
||||
if (response.data.code == 10001) {
|
||||
$store.dispatch("user/logout");
|
||||
$store.commit("user/showLoginModal", true);
|
||||
throw "登录态失效";
|
||||
}
|
||||
|
||||
return Promise.resolve(response.data);
|
||||
};
|
||||
|
||||
export default request
|
|
@ -0,0 +1,17 @@
|
|||
import config from '@/core/config';
|
||||
|
||||
export default {
|
||||
prefix: config.storagePrefix,
|
||||
set(key, value) {
|
||||
uni.setStorageSync(this.prefix + key, value);
|
||||
},
|
||||
get(key) {
|
||||
return uni.getStorageSync(this.prefix + key);
|
||||
},
|
||||
remove(key) {
|
||||
uni.removeStorageSync(this.prefix + key);
|
||||
},
|
||||
clear(key, value) {
|
||||
uni.clearStorageSync();
|
||||
}
|
||||
}
|
|
@ -2,9 +2,11 @@ import Vue from 'vue'
|
|||
import App from './App'
|
||||
|
||||
import store from "./store/index"
|
||||
import request from './core/libs/request'
|
||||
import storage from './core/storage'
|
||||
import request from './core/request'
|
||||
import test from './core/libs/test'
|
||||
import event from './core/libs/event'
|
||||
import utils from './core/utils'
|
||||
import utils from './core/libs/utils'
|
||||
import config from './core/config'
|
||||
import apis from './core/apis'
|
||||
import models from './core/models'
|
||||
|
@ -12,7 +14,9 @@ import './static/iconfont/iconfont.css'
|
|||
|
||||
Vue.use({
|
||||
install(Vue, options) {
|
||||
Vue.prototype.$storage = storage
|
||||
Vue.prototype.$request = request
|
||||
Vue.prototype.$test = test
|
||||
Vue.prototype.$event = event
|
||||
Vue.prototype.$utils = utils
|
||||
Vue.prototype.$config = config
|
||||
|
|
|
@ -13,12 +13,11 @@
|
|||
"autoclose": true,
|
||||
"delay": 0
|
||||
},
|
||||
"modules": { /* 模块配置 */
|
||||
|
||||
},
|
||||
"modules": { /* 模块配置 */},
|
||||
"distribute": { /* 应用发布信息 */
|
||||
"android": { /* android打包配置 */
|
||||
"permissions": ["<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"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\"/>",
|
||||
|
@ -42,19 +41,13 @@
|
|||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||
]
|
||||
},
|
||||
"ios": { /* ios打包配置 */
|
||||
|
||||
},
|
||||
"sdkConfigs": { /* SDK配置 */
|
||||
|
||||
}
|
||||
"ios": { /* ios打包配置 */},
|
||||
"sdkConfigs": { /* SDK配置 */}
|
||||
}
|
||||
},
|
||||
"quickapp": { /* 快应用特有相关 */
|
||||
|
||||
},
|
||||
"quickapp": { /* 快应用特有相关 */},
|
||||
"mp-weixin": { /* 微信小程序特有相关 */
|
||||
"appid": "wx239055764f21ba10",
|
||||
"appid": "wx2401c65b68a6c9b5",
|
||||
"setting": {
|
||||
"urlCheck": false,
|
||||
"es6": true,
|
||||
|
|
|
@ -12,6 +12,12 @@
|
|||
"navigationBarTitleText": "登录"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/auth/find-password",
|
||||
"style": {
|
||||
"navigationBarTitleText": "找回密码"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/member/service-info",
|
||||
"style": {
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
<input
|
||||
class="input"
|
||||
type="number"
|
||||
v-model="mobile"
|
||||
v-model="verificationCode"
|
||||
placeholder="请输入验证码"
|
||||
placeholder-class="placeholder-style-3"
|
||||
/>
|
||||
|
@ -102,6 +102,7 @@
|
|||
<script>
|
||||
import AppLayout from "@/components/layout/layout";
|
||||
import AppAgreement from "@/components/auth/agreement";
|
||||
import { mapState } from "vuex";
|
||||
export default {
|
||||
name: "auth",
|
||||
data() {
|
||||
|
@ -115,6 +116,7 @@ export default {
|
|||
tabIndex: 0,
|
||||
mobile: "",
|
||||
password: "",
|
||||
verificationCode: "",
|
||||
isAgree: false,
|
||||
};
|
||||
},
|
||||
|
@ -122,43 +124,113 @@ export default {
|
|||
AppLayout,
|
||||
AppAgreement,
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
openId: (state) => state.user.openId,
|
||||
}),
|
||||
},
|
||||
onLoad() {},
|
||||
onShow() {},
|
||||
onReady() {},
|
||||
onReachBottom() {},
|
||||
onPullDownRefresh() {},
|
||||
methods: {
|
||||
/**
|
||||
* 忘记密码
|
||||
*/
|
||||
forgetPassword() {
|
||||
this.$utils.toast("正在开发中");
|
||||
this.$utils.toPage("/pages/auth/find-password");
|
||||
},
|
||||
/**
|
||||
* 获取验证码
|
||||
*/
|
||||
getVerifyCode() {
|
||||
if (this.canUse) {
|
||||
if (true) {
|
||||
this.parseTime(10);
|
||||
}
|
||||
this.$models.user
|
||||
.sendVerificationCode(this.mobile)
|
||||
.then((response) => {
|
||||
this.parseTime(60);
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$utils.toast(e);
|
||||
});
|
||||
} else {
|
||||
this.$utils.toast("请稍后再试");
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 倒计时
|
||||
*/
|
||||
parseTime(sec) {
|
||||
const that = this;
|
||||
this.canUse = false;
|
||||
this.sec = sec;
|
||||
that.timeTask = setInterval(() => {
|
||||
clearInterval(this.timeTask);
|
||||
this.timeTask = setInterval(() => {
|
||||
that.sec -= 1;
|
||||
if (that.sec <= 0) {
|
||||
that.canUse = true;
|
||||
that.sec = 0;
|
||||
clearInterval(that.timeTask);
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
login() {},
|
||||
/**
|
||||
* 登录
|
||||
*/
|
||||
login() {
|
||||
this.$models.user
|
||||
.login({
|
||||
mobile: this.mobile,
|
||||
password: this.password,
|
||||
})
|
||||
.then((response) => {
|
||||
this.$store.dispatch("user/info");
|
||||
this.$utils.toPage(
|
||||
"",
|
||||
{
|
||||
complete() {
|
||||
let pages = getCurrentPages();
|
||||
let refer = pages[pages.length - 2];
|
||||
if (typeof refer !== "undefined") {
|
||||
if (typeof refer.initPage !== "undefined") {
|
||||
refer.initPage(refer.options);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
"back"
|
||||
);
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$utils.toast(e);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 注册
|
||||
*/
|
||||
register() {
|
||||
const that = this;
|
||||
if (!this.isAgree) {
|
||||
this.$utils.toast("请先阅读并同意《服务协议》《隐私政策》");
|
||||
return;
|
||||
}
|
||||
this.$models.user
|
||||
.register(
|
||||
{
|
||||
mobile: this.mobile,
|
||||
password: this.password,
|
||||
openId: this.openId,
|
||||
},
|
||||
this.verificationCode
|
||||
)
|
||||
.then((response) => {
|
||||
this.$utils.toast(response.msg).then(() => {
|
||||
this.tabIndex = 0;
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$utils.toast(e);
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -206,6 +278,7 @@ export default {
|
|||
margin-top: 45rpx;
|
||||
border-bottom: 2rpx solid #d2d1d1;
|
||||
.input {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
font-size: 32rpx;
|
||||
color: #666666;
|
||||
|
@ -235,6 +308,7 @@ export default {
|
|||
}
|
||||
}
|
||||
.get-code {
|
||||
z-index: 10;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
|
|
|
@ -0,0 +1,148 @@
|
|||
<template>
|
||||
<app-layout title="找回密码">
|
||||
<view class="common-form-container">
|
||||
<view class="input-item">
|
||||
<view class="title-box">
|
||||
<text>手机号</text>
|
||||
</view>
|
||||
<view class="input-box">
|
||||
<input class="input" v-model="mobile" placeholder="请输入手机号码" placeholder-class="placeholder-style-3" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="input-item">
|
||||
<view class="title-box">
|
||||
<text>验证码</text>
|
||||
</view>
|
||||
<view class="input-box">
|
||||
<input
|
||||
class="input"
|
||||
v-model="verificationCode"
|
||||
placeholder="请输入验证码"
|
||||
placeholder-class="placeholder-style-3"
|
||||
/>
|
||||
<view class="get-code" @click="getVerifyCode">
|
||||
<text class="text active" v-if="canUse">获取验证码</text>
|
||||
<text class="text" v-else>{{ sec }}s后重新获取</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="input-item">
|
||||
<view class="title-box">
|
||||
<text>新密码</text>
|
||||
</view>
|
||||
<view class="input-box">
|
||||
<input class="input" v-model="password" placeholder="请输入新密码" placeholder-class="placeholder-style-3" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="common-save-form-btn">
|
||||
<view class="btn" @click="submit">立即找回</view>
|
||||
</view>
|
||||
</app-layout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AppLayout from "@/components/layout/layout";
|
||||
export default {
|
||||
name: "member-password",
|
||||
data() {
|
||||
return {
|
||||
timeTask: null,
|
||||
canUse: true,
|
||||
sec: 0,
|
||||
mobile: "",
|
||||
password: "",
|
||||
verificationCode: "",
|
||||
};
|
||||
},
|
||||
components: {
|
||||
AppLayout,
|
||||
},
|
||||
onLoad() {},
|
||||
onShow() {},
|
||||
onReady() {},
|
||||
onReachBottom() {},
|
||||
onPullDownRefresh() {},
|
||||
methods: {
|
||||
/**
|
||||
* 获取验证码
|
||||
*/
|
||||
getVerifyCode() {
|
||||
if (this.canUse) {
|
||||
this.$models.user
|
||||
.sendVerificationCode(this.mobile)
|
||||
.then((response) => {
|
||||
this.parseTime(60);
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$utils.toast(e);
|
||||
});
|
||||
} else {
|
||||
this.$utils.toast("请稍后再试");
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 倒计时
|
||||
*/
|
||||
parseTime(sec) {
|
||||
const that = this;
|
||||
this.canUse = false;
|
||||
this.sec = sec;
|
||||
clearInterval(this.timeTask);
|
||||
this.timeTask = setInterval(() => {
|
||||
that.sec -= 1;
|
||||
if (that.sec <= 0) {
|
||||
that.canUse = true;
|
||||
that.sec = 0;
|
||||
}
|
||||
}, 1000);
|
||||
},
|
||||
/**
|
||||
* 找回密码
|
||||
*/
|
||||
submit() {
|
||||
this.$models.user
|
||||
.resetPassword(
|
||||
{
|
||||
username: this.mobile,
|
||||
password: this.password,
|
||||
},
|
||||
this.verificationCode
|
||||
)
|
||||
.then((message) => {
|
||||
this.$utils.toast(message).then(() => {
|
||||
this.$utils.toPage("/pages/auth/auth");
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
this.$utils.toast(e);
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.common-form-container {
|
||||
.input-item {
|
||||
position: relative;
|
||||
}
|
||||
.get-code {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
display: inline-block;
|
||||
padding: 24rpx 0;
|
||||
.text {
|
||||
font-size: 28rpx;
|
||||
color: #999999;
|
||||
}
|
||||
.text.active {
|
||||
color: #ffa800;
|
||||
}
|
||||
}
|
||||
.title-box {
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -6,18 +6,21 @@
|
|||
</view>
|
||||
<view class="immerse-main" :style="{ paddingTop: safePt + utils.rpx2px(20) + 'px' }">
|
||||
<view class="head">
|
||||
<block v-if="isLogin">
|
||||
<view class="headimg">
|
||||
<image class="image" :src="userInfo.headimg" mode="aspectFill" />
|
||||
<image class="image" :src="userInfo.avatar" mode="aspectFill" />
|
||||
</view>
|
||||
<view class="detail">
|
||||
<view class="name">
|
||||
<text>{{ userInfo.username }}</text>
|
||||
<text class="type" :style="{ color: models.worker.getWorkerTypeTextColor(userInfo.type) }">{{
|
||||
models.worker.getWorkerTypeText(userInfo.type)
|
||||
}}</text>
|
||||
<text
|
||||
class="type"
|
||||
:style="{ color: models.worker.getWorkerTypeTextColor(userInfo.workerType) }"
|
||||
>{{ models.worker.getWorkerTypeText(userInfo.workerType) }}</text
|
||||
>
|
||||
</view>
|
||||
<view class="line id">ID:{{ userInfo.id }}</view>
|
||||
<view class="line">注册时间:{{ userInfo.registerAt }}</view>
|
||||
<view class="line">注册时间:{{ userInfo.createTime }}</view>
|
||||
</view>
|
||||
<view class="accept-switch">
|
||||
<widget-switch
|
||||
|
@ -28,8 +31,15 @@
|
|||
/>
|
||||
<text class="current-state">{{ acceptOrderState ? "正在" : "暂停" }}接单</text>
|
||||
</view>
|
||||
</block>
|
||||
<block v-else>
|
||||
<view class="login-tips" @click="utils.toPage('/pages/auth/auth')">
|
||||
<view class="title"> 立即登录 </view>
|
||||
<view class="desc">需要登录后操作</view>
|
||||
</view>
|
||||
<view class="order-desc">
|
||||
</block>
|
||||
</view>
|
||||
<view v-if="isLogin" class="order-desc">
|
||||
<view class="service-data">
|
||||
<view class="section-text">
|
||||
<text>服务:</text>
|
||||
|
@ -58,7 +68,7 @@
|
|||
</view>
|
||||
</view>
|
||||
<view class="common-form-widget-group">
|
||||
<view class="widget-item" @click="utils.toPage('/pages/member/cash-withdraw')">
|
||||
<view class="widget-item" @click="toPage('/pages/member/cash-withdraw')">
|
||||
<text class="title limit-line clamp-1">我要提现</text>
|
||||
<text class="iconfont icon-jinru"></text>
|
||||
</view>
|
||||
|
@ -76,7 +86,7 @@
|
|||
</view>
|
||||
</view>
|
||||
<view class="common-form-widget-group">
|
||||
<view class="widget-item" @click="utils.toPage('/pages/member/service-info')">
|
||||
<view class="widget-item" @click="toPage('/pages/member/service-info')">
|
||||
<text class="title limit-line clamp-1">设置服务信息</text>
|
||||
<text class="iconfont icon-jinru"></text>
|
||||
</view>
|
||||
|
@ -84,11 +94,11 @@
|
|||
<text class="title limit-line clamp-1">我的评价</text>
|
||||
<text class="iconfont icon-jinru"></text>
|
||||
</view>
|
||||
<view class="widget-item">
|
||||
<view class="widget-item" @click="utils.serviceActions()">
|
||||
<text class="title limit-line clamp-1">在线客服</text>
|
||||
<text class="iconfont icon-jinru"></text>
|
||||
</view>
|
||||
<view class="widget-item" @click="utils.toPage('/pages/member/setting')">
|
||||
<view class="widget-item" @click="toPage('/pages/member/setting')">
|
||||
<text class="title limit-line clamp-1">设置</text>
|
||||
<text class="iconfont icon-jinru"></text>
|
||||
</view>
|
||||
|
@ -101,6 +111,7 @@
|
|||
<script>
|
||||
import AppLayout from "@/components/layout/layout";
|
||||
import WidgetSwitch from "@/components/widgets/switch";
|
||||
import { mapGetters, mapState } from "vuex";
|
||||
export default {
|
||||
name: "member",
|
||||
data() {
|
||||
|
@ -109,13 +120,6 @@ export default {
|
|||
models: this.$models,
|
||||
safePt: 0,
|
||||
backgroundImage: require("@/static/temp/1.png"),
|
||||
userInfo: {
|
||||
headimg: require("@/static/temp/member/2.png"),
|
||||
username: "李师傅",
|
||||
id: "212121212",
|
||||
registerAt: "2022-11-1",
|
||||
type: 2,
|
||||
},
|
||||
acceptOrderState: false,
|
||||
};
|
||||
},
|
||||
|
@ -123,12 +127,32 @@ export default {
|
|||
AppLayout,
|
||||
WidgetSwitch,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
isLogin: "user/isLogin",
|
||||
finishInfo: "user/finishInfo",
|
||||
}),
|
||||
...mapState({
|
||||
userInfo: (state) => state.user.info,
|
||||
}),
|
||||
},
|
||||
onLoad() {},
|
||||
onShow() {},
|
||||
onShow() {
|
||||
if (this.isLogin && !this.finishInfo) {
|
||||
this.$utils.toPage("/pages/member/service-info");
|
||||
}
|
||||
},
|
||||
onReady() {},
|
||||
onReachBottom() {},
|
||||
onPullDownRefresh() {},
|
||||
methods: {},
|
||||
methods: {
|
||||
toPage(url) {
|
||||
if (!this.isLogin) {
|
||||
return this.$store.commit("user/showLoginModal", true);
|
||||
}
|
||||
this.$utils.toPage(url);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -139,6 +163,20 @@ export default {
|
|||
.member-container {
|
||||
width: 100%;
|
||||
}
|
||||
.login-tips {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
color: #ffffff;
|
||||
margin-bottom: 50rpx;
|
||||
.title {
|
||||
font-size: 40rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
.desc {
|
||||
margin-top: 20rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
}
|
||||
.head {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
|
|
@ -1,34 +1,7 @@
|
|||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
config: {},
|
||||
},
|
||||
getters: {
|
||||
config(state) {
|
||||
return state.config;
|
||||
},
|
||||
},
|
||||
mutations: {
|
||||
setConfig(state, data) {
|
||||
state.config = { ...state.config, ...data };
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
initConfig(context) {
|
||||
let config = uni.getStorageSync('system_config');
|
||||
if (!config) {
|
||||
const { windowWidth, windowHeight, statusBarHeight, safeAreaInsets } = uni.getSystemInfoSync();
|
||||
// #ifndef H5
|
||||
const { height, top } = uni.getMenuButtonBoundingClientRect();
|
||||
const headerHeight = height + ((top - statusBarHeight) * 2);
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
const headerHeight = 40; // 乘2再使用rpx2px转px使用
|
||||
// #endif
|
||||
config = { windowWidth, windowHeight, statusBarHeight, headerHeight, safeAreaInsets };
|
||||
uni.setStorageSync('system_config', config);
|
||||
}
|
||||
context.commit('setConfig', config);
|
||||
}
|
||||
}
|
||||
state: {},
|
||||
getters: {},
|
||||
mutations: {},
|
||||
actions: {}
|
||||
}
|
||||
|
|
|
@ -1,35 +1,50 @@
|
|||
import user from '@/core/models/user'
|
||||
|
||||
import user from "@/core/models/user";
|
||||
export default {
|
||||
namespaced: true,
|
||||
state: {
|
||||
showLoginModal: false,
|
||||
userInfo: null,
|
||||
openId: "",
|
||||
token: "",
|
||||
info: {
|
||||
id: 0,
|
||||
avatar: "",
|
||||
nickname: "",
|
||||
openid: "",
|
||||
mobile: "",
|
||||
createTime: 0,
|
||||
finishInfo: false,
|
||||
},
|
||||
},
|
||||
getters: {
|
||||
showLoginModal(state) {
|
||||
return state.showLoginModal;
|
||||
},
|
||||
userInfo(state) {
|
||||
return state.userInfo;
|
||||
isLogin(state) {
|
||||
return state.token.length > 0;
|
||||
},
|
||||
finishInfo(state) {
|
||||
return state.info.finishInfo;
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
showLoginModal(state, data) {
|
||||
state.showLoginModal = data;
|
||||
},
|
||||
userInfo(state, data) {
|
||||
state.userInfo = data;
|
||||
openId(state, data) {
|
||||
state.openId = data;
|
||||
},
|
||||
token(state, data) {
|
||||
state.token = data;
|
||||
},
|
||||
info(state, data) {
|
||||
state.info = data;
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
logout(context) {
|
||||
context.commit('userInfo', null);
|
||||
},
|
||||
userInfo(context) {
|
||||
user.getInfo().then(info => {
|
||||
context.commit('userInfo', info);
|
||||
info(context) {
|
||||
user.info().then(info => {
|
||||
context.commit('info', info);
|
||||
});
|
||||
}
|
||||
},
|
||||
logout(context) {
|
||||
context.commit('info', null);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue