Commit af43e5d9 authored by June's avatar June

feature

parent c047352c
<script>
import { mapActions } from 'vuex'
import { checkLoginStatus } from '@/apis/user.js'
import { login_wx } from '@/utils/modules/login.js'
export default {
onLaunch: function() {
this.checkUpdate()
this.setSystemInfo()
this.setLocation()
this.setMenuButtonInfo()
onLaunch: async function() {
this.setSystemInfo() // 获取系统信息
this.setLocation() // 获取经纬度
this.setMenuButtonInfo() // 获取胶囊信息
this.checkUpdate() // 检查更新
// await login_wx()
checkLoginStatus() // 检查登录状态
.then(res => {
console.log(res)
if(res.status) {
this.setLoginStatus(true)
this.setCount()
} else {
this.setLoginStatus(false)
}
})
.catch(err => console.log(err))
},
methods: {
...mapActions('systemInfo', ['setSystemInfo', 'setMenuButtonInfo']),
...mapActions('user', ['setLocation']),
...mapActions('user', ['setLocation', 'setLoginStatus']),
...mapActions('cart', ['setCount']),
// 检查更新
checkUpdate() {
if (wx.canIUse('getUpdateManager')) {
......@@ -34,7 +48,8 @@ export default {
this.$toast({title: "更新失败,请检查您的网络是否正常"})
})
}
}
}
}
}
......
......@@ -2,6 +2,16 @@
import { request } from "@/lib/service"
import { baseUrl } from '@/config'
/**
* @desc 获取购物车数量
*/
export function cartCount() {
return request({
url: `${baseUrl}/wxxcx/cartCount.htm`,
method: 'post'
})
}
/**
* @desc 获取购物车列表
*/
......
......@@ -38,3 +38,18 @@ export function goodDetail(params) {
})
}
/**
* @desc 商品规格选择接口
* goods_id
* shop_id
* sale_type
*/
export function goodsSku(goods_id, shop_id, sale_type = 0) {
return request({
url: `${baseUrl}/wxxcx/goodsSku.htm`,
method: 'post',
data: {
goods_id, shop_id, sale_type
}
})
}
......@@ -3,23 +3,47 @@ import { request } from "@/lib/service"
import { baseUrl } from '@/config' // 将请求的baseUrl写这里,为了开发时调试请求地址
const RSA = require('@/utils/wx_rsa.js')
import { publicKey } from '@/config/index.js'
/**
* @desc 检查登录态
*/
export function checkLogin() {
export function checkLoginStatus() {
return request({
url: `${baseUrl}/wxxcx/isLogin.htm`,
method: 'post',
needMask: true
})
}
/**
* 检查服务器时间
*/
export function checkLoginTime() {
return request({
url: `${baseUrl}/wxxcx/getFwqTime.htm`,
method: 'post'
})
}
/**
* @desc 微信登录 wx.login 获取openid unionid等信息
* @param { String } code
*/
export function wxLogin(code) {
return request({
url: `${baseUrl}/wxxcx/getInfo.htm`,
data: {
js_code: code
}
})
}
/**
* @desc 静默登录
* @param { Number } userPhone
* @param { String } time
*/
export function slelentLogin(userPhone, time) {
console.log(userPhone, time)
const encrypt_rsa = RSA.KEYUTIL.getKey(publicKey)
return request({
url: `${baseUrl}/wxxcx/silentLogin.htm`,
......@@ -32,23 +56,39 @@ export function slelentLogin(userPhone, time) {
}
/**
* @desc 登录
* @desc 退出登录
*/
export function login() {
export function logout() {
return request({
url: `${baseUrl}/a`
url: `${baseUrl}/wxxcx/loginOut.htm`,
method: 'post',
needMask: true
})
}
/**
* @desc 注册
* @param {Object} params
*
* lgtype 必填 登录方式:1微信登录 2短信验证码登录 3账号密码登录
* user 用户名(lgtype!=1时必填)
* pwd 登录密码(lgtype=3时必填)
* yzm 登录验证码(lgtype=2时必填
* encryptedData 加密信息(lgtype=1时必填)
* iv 加密算法的初始向量(lgtype=1时必填)
* session_key 会话密钥(lgtype=1时必填)
*/
export function register() {
export function register(params) {
return request({
url:`${baseUrl}/a`
url: `${baseUrl}/wxxcx/login.htm`,
method: 'post',
data: params
})
}
/**
* @desc 获取手机验证码
*/
......
<template>
<uni-popup ref="goodsPopup" type="bottom">
<view class="wrapper p-2 w-100">
<view v-if="!showSku">
<image style="width: 180rpx;height: 180rpx;" src="../../static/images/common/loading.gif" mode="widthFix"></image>
</view>
<view v-else>1111</view>
</view>
</uni-popup>
</template>
<script>
import uniPopup from '@/components/uni-popup/index.vue'
import { goodsSku } from '@/apis/goods.js'
export default {
name: 'goods-popup',
props: {
goods_id: {
type: Number | String,
default: 0
}
},
data() {
return {
showSku: false,
detail: null
}
},
components: {
uniPopup
},
methods: {
async show(e) {
try{
console.log(e)
const res = await goodsSku(e.goods_id, e.shop_id)
console.log(res)
setTimeout(() => {
this.showSku = true
}, 2000)
this.$refs.goodsPopup.open()
}catch(e){
console.log(e)
this.$toast({title: e.msg || '程序错误'})
}
},
hide() {
this.$refs.goodsPopup.close()
this.showSku = false
this.detail = null
}
}
}
</script>
<style lang="scss" scoped>
.wrapper {
background-color: #fff;
}
</style>
......@@ -2,7 +2,8 @@ import Toast from "../toast/index.js"
import { isObeject, isFunction } from "@/utils/types.js"
import Validator from "@/utils/validate.js"
import { login_slilen } from '@/utils/modules/login.js'
import store from '@/store/index.js'
import store from '@/store/index.js'
/**
* @desc 请求 所有的状态码都在这里处理
* @param { Object } options 参考uni.request参数说明
......@@ -30,57 +31,75 @@ export function request (options) {
...options,
header: {
'content-type': 'application/x-www-form-urlencoded',
'cookie': 'JSESSIONID=aaaH_PdwNLO-Oan2L7QNx; path=/'
'cookie': store.state.user.cookieKey
},
success: res => {
const statusCode = res.statusCode
// console.log(statusCode)
switch(statusCode) {
case 200:
options.successCb && typeof options.successCb === 'function' && options.successCb()
// 处理某些接口返回String类型的数据
const data = (res.data && typeof res.data === 'string') ? JSON.parse(res.data) : res.data
const status = data.code
switch(status) {
case 10:
resolve({
status: true,
data: res.data.list || res.data.data,
res: res.data,
msg: data.rep_msg
})
break;
case -3:
login_slilen()
// return Toast({title: 'login', cb: () => {
// uni.navigateTo({
// url: '/pages/login/index.vue'
// })
// }})
break;
default:
Toast({title: data.rep_msg})
resolve({
status: false,
code: status, // 正常不返回为了好找 后端调试 -1 => 业务错误(一般失败情况返回此项);-2 => 系统异常; -3 => 请先登录; -4 => 请求失败; -10 => 签名失败
data: data.list,
res: res.data.list || res.data.data,
msg: data.rep_msg
})
break;
}
break;
case 404:
return Toast({title: '请求路径不存在'})
break;
case 500:
return Toast({title: '服务器错误'})
break; // 这里的break可以不写,不会执行到。return直接退出函数了
default:
Toast({title: '网络请求失败'})
return
break;
success: async res => {
try{
const statusCode = res.statusCode
// console.log(statusCode)
switch(statusCode) {
case 200:
options.successCb && typeof options.successCb === 'function' && options.successCb()
// 处理某些接口返回String类型的数据
const data = (res.data && typeof res.data === 'string') ? JSON.parse(res.data) : res.data
const status = data.code
switch(status) {
case 10:
resolve({
status: true,
data: res.data.list || res.data.data,
res: res.data,
msg: data.rep_msg
})
break;
case -1:
resolve({
status: true,
data: res.data.list || res.data.data,
res: res.data,
msg: data.rep_msg
})
break;
case -3:
const loginRes = await login_slilen()
console.log('刷新登录 重新执行上一次请求=======')
if(loginRes) { // 重新执行上一次的操作
const againRes = await request(options)
resolve({
status: true,
data: againRes.list || againRes.data,
res: againRes.res,
msg: againRes.msg
})
}
break;
default:
Toast({title: data.rep_msg})
resolve({
status: false,
code: status, // 正常不返回为了好找 后端调试 -1 => 业务错误(一般失败情况返回此项);-2 => 系统异常; -3 => 请先登录; -4 => 请求失败; -10 => 签名失败
data: data.list,
res: res.data.list || res.data.data,
msg: data.rep_msg
})
break;
}
break;
case 404:
return Toast({title: '请求路径不存在'})
break;
case 500:
return Toast({title: '服务器错误'})
break; // 这里的break可以不写,不会执行到。return直接退出函数了
default:
Toast({title: '网络请求失败'})
return
break;
}
}catch(e){
console.log(e)
Toast({title: e.msg || '程序请求错误'})
}
},
fail: err => {
......
......@@ -6,7 +6,9 @@ import "@/utils/vue_extend.js" // 常用方法
// 全局组件
import emptyView from '@/components/empty-view/index.vue'
import uniPopup from '@/components/uni-popup/index.vue'
Vue.component('empty-view', emptyView)
Vue.component('uni-popup', uniPopup)
Vue.config.productionTip = false
......
......@@ -50,7 +50,7 @@
"quickapp" : {},
/* 小程序特有相关 */
"mp-weixin" : {
"appid" : "wx445b225e03ee51aa",
"appid" : "wxd170058f4ad8fecd",
"setting" : {
"urlCheck" : false,
"es6" : true,
......
......@@ -4,10 +4,35 @@
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"charenc": {
"version": "0.0.2",
"resolved": "https://registry.npm.taobao.org/charenc/download/charenc-0.0.2.tgz",
"integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc="
},
"crypt": {
"version": "0.0.2",
"resolved": "https://registry.nlark.com/crypt/download/crypt-0.0.2.tgz",
"integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs="
},
"dayjs": {
"version": "1.10.5",
"resolved": "https://registry.nlark.com/dayjs/download/dayjs-1.10.5.tgz?cache=0&sync_timestamp=1622012259636&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fdayjs%2Fdownload%2Fdayjs-1.10.5.tgz",
"integrity": "sha1-VgDfRUj8JFOz8WPrsqu+llzPuYY="
},
"is-buffer": {
"version": "1.1.6",
"resolved": "https://registry.npm.taobao.org/is-buffer/download/is-buffer-1.1.6.tgz?cache=0&sync_timestamp=1604429452232&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fis-buffer%2Fdownload%2Fis-buffer-1.1.6.tgz",
"integrity": "sha1-76ouqdqg16suoTqXsritUf776L4="
},
"md5": {
"version": "2.3.0",
"resolved": "https://registry.npm.taobao.org/md5/download/md5-2.3.0.tgz",
"integrity": "sha1-w9qaaq46MLRreww0m4exENw72k8=",
"requires": {
"charenc": "0.0.2",
"crypt": "0.0.2",
"is-buffer": "~1.1.6"
}
}
}
}
......@@ -16,6 +16,7 @@
"author": "",
"license": "ISC",
"dependencies": {
"dayjs": "^1.10.5"
"dayjs": "^1.10.5",
"md5": "^2.3.0"
}
}
......@@ -66,17 +66,17 @@
"root": "subPages",
"pages": [
{
"path": "test/index",
"path": "userManage/index",
"style": {
"navigationBarTitleText": "test"
"navigationBarTitleText": "账号管理"
}
}
]
}],
"preloadRule": {
"subPages/test/index": {
"pages/home/index": {
"network": "all",
"packages": ["__APP__"]
"packages": ["subPages"]
}
},
"globalStyle": {
......
<template>
<view class="cart-wrap">
<template v-if="cartList.length === 0">
<empty-view
iconSrc="../../static/images/common/icon_nothing.png"
text="购物车为空"
/>
</template>
<template v-else>
<view class="list-wrap W-100">
<view
class="list-item"
v-for="(item, index) in cartList"
:key="index"
@click="handleCartItem(index, item)"
>
<view>
<text>{{item.checked ? '选中' : '未选中'}}</text> <text>{{item.price}}</text>
</view>
<view style="width: 240rpx;height: 64rpx;">
<input-number
:index="index"
:value="item.counts"
@change="numberChange"
/>
<view v-if="!isLogin">
<button type="default" @click="handleLogin">登录</button>
</view>
<view v-else>
<template v-if="cartList.length === 0">
<empty-view
iconSrc="../../static/images/common/icon_nothing.png"
text="购物车为空"
/>
</template>
<template v-else>
<view class="list-wrap W-100">
<view
class="list-item"
v-for="(item, index) in cartList"
:key="index"
@click="handleCartItem(index, item)"
>
<view>
<text>{{item.checked ? '选中' : '未选中'}}</text> <text>{{item.price}}</text>
</view>
<view style="width: 240rpx;height: 64rpx;">
<input-number
:index="index"
:value="item.counts"
@change="numberChange"
/>
</view>
</view>
</view>
</view>
</template>
<view>总价:{{totalPrice}}</view>
</template>
<view>总价:{{totalPrice}}</view>
</view>
</view>
</template>
<script>
import inputNumber from '@/components/inputNumber/index.vue'
import { mapState } from 'vuex'
export default {
data() {
return {
......@@ -70,6 +77,9 @@ export default {
},
computed: {
...mapState({
isLogin: state => state.user.isLogin
}),
// 总价
totalPrice() {
return this.cartList.filter(item => item.checked).reduce((pre, cur) => {
......@@ -79,6 +89,12 @@ export default {
},
methods: {
handleLogin() {
uni.navigateTo({
url: '/pages/login/index'
})
},
handleCartItem(index, item) {
item.checked = !item.checked
this.$set(this.cartList, index, item)
......
......@@ -30,6 +30,7 @@
<script>
import leftMenuButton from './components/left-menuButton.vue'
import uParse from '@/components/parse/parse.vue'
import { goodDetail } from '@/apis/goods.js'
import { imgUrl } from '@/config/index.js'
......
......@@ -10,7 +10,7 @@
>
<image class="goods_cover w-100" :src="arr[item]" mode="aspectFit"></image>
<view>
<view @click.stop="purchase(index)">购物ICON</view>
<view @click.stop="purchase(item)">购物ICON</view>
</view>
</view>
</view>
......@@ -18,6 +18,7 @@
</template>
<script>
export default {
props: {
title: {
......@@ -40,8 +41,13 @@ export default {
url: `/pages/goods/detail?goods_id=9192&shop_id=101120&agent_id=0`
})
},
purchase(e) {
// this.$me
purchase(item) {
console.log(item)
this.$emit('purchase', {
goods_id: 7344,
sale_type: 0,
shop_id: 100737
})
}
}
}
......
......@@ -9,6 +9,9 @@
</view>
</view>
<button type="default" @click="handleLogout">退出登录</button>
<button type="default" @click="handleCart">购物车请求</button>
<!-- content -->
<template v-if="isOverdue">
<view class="w-100 content-wrap flex flex-column j-center a-center">
......@@ -44,16 +47,18 @@
</view>
<view>
<goods-module title="热销111" :list="module1" />
<goods-module title="热销111" :list="module1" @purchase="purchase" />
</view>
</view>
</template>
<!-- <view class="test" @click="login">登录</view>
<!-- <city-picker @confirmCity="confirmCity"></city-picker> -->
<!-- <navigator url="/pages/goods/detail">详情页</navigator> -->
<uni-popup type="bottom">
<view>{{select_goods.test}}</view>
</uni-popup>
<goods-popup ref="goodsPopup"></goods-popup>
<button type="default" open-type="share" id="share"></button>
</view>
</template>
......@@ -61,12 +66,15 @@
<script>
import searchBar from '@/components/search-bar/index.vue'
import goodsModule from './components/goods-module.vue'
import uniPopup from '@/components/uni-popup/index.vue'
import goodsPopup from '@/components/goods-popup/index.vue'
import cityPicker from '@/components/city-picker/index.vue'
import { mapState } from 'vuex'
import { mapState, mapActions } from 'vuex'
import { checkLogin } from '@/utils/common.js'
import { logout } from '@/apis/user.js'
export default {
data() {
return {
......@@ -77,7 +85,8 @@ export default {
components: {
searchBar,
goodsModule,
uniPopup,
goodsPopup,
cityPicker
},
......@@ -92,12 +101,9 @@ export default {
uni.setNavigationBarTitle({
title: '测试店铺'
})
uni.$on('purchase', e => {
console.log(e)
})
this.$once('hook:beforeDe')
},
onShareAppMessage() {
return {
title: '分享title'
......@@ -105,7 +111,20 @@ export default {
},
methods: {
...mapActions('cart', ['setCount']),
handleLogout() {
logout()
.then(res => console.log(res))
},
handleCart() {
this.setCount()
},
purchase(e) {
this.$refs.goodsPopup.show(e)
},
handleMenu(type) {
checkLogin(() => {
switch(type) {
......
import Validator from "@/utils/validate.js"
import { register } from '@/apis/user.js'
function smsValidate() {
const smsValidator = new Validator()
......@@ -17,7 +17,17 @@ function accoutValidate() {
return smsValidator.validate()
}
async function registerCommon(params) {
try{
const res = await register(params)
console.log(res)
}catch(e){
this.$toast({title: e.msg || '程序错误'})
}
}
export default {
smsValidate,
accoutValidate
accoutValidate,
registerCommon
}
\ No newline at end of file
......@@ -9,7 +9,7 @@
/>
</view>
<view v-show="login_type === 'smsLogin'">
<view v-show="form.lgtype === 2">
<input
type="text"
placeholder="请输入验证码"
......@@ -19,7 +19,7 @@
<view>SMS</view>
</view>
<view v-show="login_type === 'accoutLogin'">
<view v-show="form.lgtype === 3">
<input
type="password"
placeholder="请输入密码"
......@@ -29,9 +29,9 @@
</view>
<view>
<button type="default" @click="handleLogin('smsLogin')">短信验证码注册登录</button>
<button type="default" @click="handleLogin(2)">短信验证码注册登录</button>
<button open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">微信快捷登录</button>
<button type="default" @click="handleLogin('accoutLogin')">密码登录</button>
<button type="default" @click="handleLogin(3)">密码登录</button>
</view>
......@@ -40,20 +40,26 @@
<script>
import loginCommon from './common.js'
// import uniPopup from '@/components/uni-popup/index.vue'
import { timerFn } from '@/utils/common.js'
import { mapState } from 'vuex'
export default {
data() {
return {
login_type: "smsLogin", // smsLogin wxLogin accoutLogin
form: {
lgtype: 2, // 1微信登录 2短信验证码登录 3账号密码登录
phone: null,
smsCode: null,
password: null
}
}
},
computed: {
...mapState({
session_key: state => state.user.session_key
})
},
// components: {
// uniPopup
// },
......@@ -66,8 +72,7 @@ export default {
},
handleLogin(type) {
if(type !== this.login_type) return this.login_type = type
console.log('-----------------------')
if(type !== this.form.lgtype) return this.$set(this.form, 'lgtype', type)
switch (type) {
case 'smsLogin':
const smsValidaErr = this.smsValidate()
......@@ -88,9 +93,15 @@ export default {
getPhoneNumber (e) {
console.log(e.detail.errMsg)
console.log(e.detail.iv)
console.log(e.detail.encryptedData)
if(e.detail.errMsg === 'getPhoneNumber:fail user deny') return
const { iv, encryptedData } = e.detail
console.log(iv, encryptedData)
this.registerCommon({
lgtype: 1,
encryptedData,
iv,
session_key: this.session_key
})
},
......
<template>
<view class="w-100">
<!-- userInfo -->
<view class="user-wrap flex j-start a-center w-100">
<template v-if="token">
<view class="user-wrap flex j-start a-center w-100" @click="handleAvatar">
<template v-if="isLogin">
<open-data class="avatar mr-2" type="userAvatarUrl"></open-data>
<open-data type="userNickName" lang="zh_CN"></open-data>
</template>
......@@ -76,7 +76,7 @@ export default {
},
computed: {
...mapState({
token: state => state.user.token
isLogin: state => state.user.isLogin
})
},
methods: {
......@@ -99,6 +99,18 @@ export default {
})
},
handleAvatar() {
if(this.isLogin) {
uni.navigateTo({
url: '/subPages/userManage/index'
})
} else {
uni.navigateTo({
url: '/pages/login/index'
})
}
},
// 拨打电话
phoneCall() {
checkLogin(() => {
......
import { cartCount } from "@/apis/carts.js"
const state = {
cart_count: 0
}
const mutations = {
SETCOUNT(state, count) {
state.cart_count = count
}
}
const actions = {
setCount: async ({ commit }) => {
const res = await cartCount()
const count = res.res.count
console.log('vuex actions success ==========================================')
if(res.status && count > 0) {
commit('SETCOUNT', count)
uni.setTabBarBadge({
index: 2,
text: count > 99 ? '99+' : JSON.stringify(count)
})
} else {
wx.removeTabBarBadge({index: 2})
}
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
\ No newline at end of file
......@@ -2,13 +2,20 @@ import { getStorage, setStorage, removeStorage } from '@/lib/storage'
// import store from '@/store/index.js'
const state = {
token: '111',
isLogin: true,
openid: null,
unionid: null,
session_key: '',
cookieKey: 'JSESSIONID=aaaD4X0GrEplMbVRPm5Nx; path=/',
isOverdue: false, // 服务是否过期
userInfo: null,
location: {}
}
const mutations = {
SETLOGINSTATUS(state, status) {
state.isLogin = status
},
SETTOKEN(state, token){
state.token = token
},
......@@ -22,6 +29,9 @@ const mutations = {
}
const actions = {
setLoginStatus: ({commit}, status) => {
commit('SETLOGINSTATUS', status)
},
setToken: ({commit}, token) => {
commit('SETTOKEN', token)
setStorage('token',token)
......
<template>
<view class="w-100">
<view class="w-100 flex j-between a-center">
<view>头像</view>
<image
class="avatar"
src="../../static/images/common/icon_nothing.png"
mode="aspectFit"
@click="changeAvatar"
/>
</view>
<view @click="handleLogout">退出登录</view>
</view>
</template>
<script>
export default {
methods: {
changeAvatar(e) {
uni.chooseImage({
count: 1,
success: res => console.log(res)
})
}
}
}
</script>
<style lang="scss" scoped>
.avatar {
width: 180rpx;
height: 180rpx;
}
</style>
import { checkLogin, slelentLogin } from '@/apis/user.js'
import { checkLoginTime, slelentLogin, wxLogin } from '@/apis/user.js'
import store from '@/store/index.js'
export async function login_slilen() {
checkLogin()
.then(checkRes => {
console.log(checkRes)
if(checkRes.status) {
slelentLogin('13143340532', checkRes.res.time)
.then(res => {
store.state.user.userInfo = res.userInfo
})
export async function login_slilen(cb) {
const checkRes = await checkLoginTime()
if(checkRes.status) {
const res = await slelentLogin('13143340532', checkRes.res.time)
store.state.user.userInfo = res.userInfo
return true
} else {
return false
}
}
export async function login_wx() {
return new Promise(()=> {
uni.login({
success: async res => {
const loginRes = await wxLogin(res.code)
console.log(store)
if(loginRes.status) {
store.state.user.openid = loginRes.res.openid
store.state.user.unionid = loginRes.res.unionid
store.state.user.session_key = loginRes.res.session_key
}
}
})
})
}
\ No newline at end of file
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