mirror of
https://github.com/sunniejs/vue-h5-template.git
synced 2025-04-06 03:57:50 +08:00
微信公众号,授权,券
This commit is contained in:
parent
6014f11ee4
commit
ca44e7447a
12
.babelrc
Normal file
12
.babelrc
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"presets": [
|
||||
[ "@babel/preset-env", {
|
||||
"targets": {
|
||||
"browsers": [ "last 1 version", "ie >= 11" ]
|
||||
}
|
||||
}]
|
||||
],
|
||||
"plugins": [
|
||||
"@babel/plugin-transform-runtime"
|
||||
]
|
||||
}
|
@ -4,6 +4,7 @@ VUE_APP_ENV = 'staging'
|
||||
#base url
|
||||
BASE_URL = https://www.top1buyer.com/
|
||||
#appid
|
||||
|
||||
VUE_APP_WECHAT_APPID='wx6bb2125514b4c1ff'
|
||||
# base api
|
||||
VUE_APP_BASE_API = '/stage-api'
|
||||
|
@ -1,5 +1,6 @@
|
||||
process.env.VUE_CLI_BABEL_TRANSPILE_MODULES = true
|
||||
module.exports = {
|
||||
presets: ['@vue/app'],
|
||||
presets: [['@vue/app', { useBuiltIns: 'entry' }]],
|
||||
plugins: [
|
||||
[
|
||||
'import',
|
||||
|
@ -3,7 +3,7 @@ const chalk = require('chalk')
|
||||
// const config = require('../vue.config.js')
|
||||
const rawArgv = process.argv.slice(2)
|
||||
const args = rawArgv.join(' ')
|
||||
|
||||
// npm run preview -- --report
|
||||
if (process.env.npm_config_preview || rawArgv.includes('--preview')) {
|
||||
const report = rawArgv.includes('--report')
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
"scripts": {
|
||||
"dev": "vue-cli-service serve",
|
||||
"build:prod": "vue-cli-service build",
|
||||
"build:stage": "vue-cli-service build --mode staging",
|
||||
"build:sit": "vue-cli-service build --mode staging",
|
||||
"preview": "node build/index.js --preview",
|
||||
"lint": "eslint --ext .js,.vue src",
|
||||
"test:unit": "jest --clearCache && vue-cli-service test:unit",
|
||||
@ -15,8 +15,10 @@
|
||||
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/polyfill": "^7.4.4",
|
||||
"@chenfengyuan/vue-qrcode": "^1.0.0",
|
||||
"axios": "0.18.0",
|
||||
"core-js": "^2.6.9",
|
||||
"crypto-js": "^3.1.9-1",
|
||||
"good-storage": "^1.1.0",
|
||||
"js-cookie": "^2.2.0",
|
||||
@ -52,6 +54,7 @@
|
||||
"script-loader": "0.7.2",
|
||||
"serve-static": "^1.13.2",
|
||||
"svgo": "1.2.2",
|
||||
"vconsole": "^2.5.2",
|
||||
"vue-template-compiler": "2.6.10"
|
||||
},
|
||||
"engines": {
|
||||
|
27
public/index.1.html
Normal file
27
public/index.1.html
Normal file
@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<% for (var i in
|
||||
htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.css) { %>
|
||||
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="preload" as="style" />
|
||||
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet" />
|
||||
<% } %>
|
||||
<title><%= webpackConfig.name %></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- 使用CDN加速的JS文件,配置在vue.config.js下 -->
|
||||
<% for (var i in
|
||||
htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %>
|
||||
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
|
||||
<% } %>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
@ -5,11 +5,6 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<% for (var i in
|
||||
htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.css) { %>
|
||||
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="preload" as="style" />
|
||||
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet" />
|
||||
<% } %>
|
||||
<title><%= webpackConfig.name %></title>
|
||||
</head>
|
||||
<body>
|
||||
@ -18,10 +13,6 @@
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- 使用CDN加速的JS文件,配置在vue.config.js下 -->
|
||||
<% for (var i in
|
||||
htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %>
|
||||
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
|
||||
<% } %>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
|
15
src/api/coupon.js
Normal file
15
src/api/coupon.js
Normal file
@ -0,0 +1,15 @@
|
||||
import qs from 'qs'
|
||||
import request from '@/utils/request'
|
||||
import { api } from '@/config'
|
||||
// 签名
|
||||
import _bale from '@/utils/package'
|
||||
// api
|
||||
|
||||
// 查询我的优惠券
|
||||
export function getCouponList(params) {
|
||||
return request({
|
||||
url: '/coupon/selectMyCoupon',
|
||||
method: 'post',
|
||||
data: qs.stringify(_bale('selectMyCoupon', params))
|
||||
})
|
||||
}
|
@ -4,12 +4,10 @@ import { api } from '@/config'
|
||||
// 签名
|
||||
import _bale from '@/utils/package'
|
||||
// api
|
||||
const { common_api } = api
|
||||
|
||||
// 登录
|
||||
export function login(params) {
|
||||
return request({
|
||||
url: common_api + '/wechat/login.do',
|
||||
url: '/wechat/login.do',
|
||||
method: 'post',
|
||||
data: qs.stringify(_bale('login', params))
|
||||
})
|
||||
@ -17,16 +15,10 @@ export function login(params) {
|
||||
/**
|
||||
* 登录接口请求token与userinfo
|
||||
* @param params
|
||||
* 入参 code:"021gj0OV1om5PU0k9VNV1VMQNV1gj0OK"
|
||||
* 返回 {
|
||||
* accessToken:'xxx',
|
||||
* refreshToken:'xxx',
|
||||
* userInfo:{}
|
||||
* }
|
||||
*/
|
||||
export function loginByCode(params) {
|
||||
return request({
|
||||
url: common_api + '/wechat/auth2',
|
||||
url: '/wechat/auth2',
|
||||
method: 'post',
|
||||
data: qs.stringify(_bale('auth2', params))
|
||||
})
|
||||
@ -37,7 +29,7 @@ export function loginByCode(params) {
|
||||
*/
|
||||
export function getUserInfo(params) {
|
||||
return request({
|
||||
url: common_api + '/user/get_user',
|
||||
url: '/user/get_user',
|
||||
method: 'post',
|
||||
data: qs.stringify(_bale('get_user', params))
|
||||
})
|
||||
@ -49,7 +41,7 @@ export function getUserInfo(params) {
|
||||
*/
|
||||
export function getAccountInfo(params) {
|
||||
return request({
|
||||
url: common_api + '/wechat/selectVipUserInfo',
|
||||
url: '/wechat/selectVipUserInfo',
|
||||
method: 'post',
|
||||
data: qs.stringify(_bale('selectVipUserInfo', params))
|
||||
})
|
||||
@ -61,7 +53,7 @@ export function getAccountInfo(params) {
|
||||
*/
|
||||
export function sendCode(params) {
|
||||
return request({
|
||||
url: common_api + '/wechat/send_phone_code',
|
||||
url: '/wechat/send_phone_code',
|
||||
method: 'post',
|
||||
data: qs.stringify(_bale('send_phone_code', params))
|
||||
})
|
||||
@ -73,7 +65,7 @@ export function sendCode(params) {
|
||||
*/
|
||||
export function bindPhoneNumber(params) {
|
||||
return request({
|
||||
url: common_api + '/wechat/addPhoneNumber',
|
||||
url: '/wechat/addPhoneNumber',
|
||||
method: 'post',
|
||||
data: qs.stringify(_bale('addPhoneNumber', params))
|
||||
})
|
||||
|
@ -118,7 +118,7 @@ div:focus {
|
||||
.app-container {
|
||||
}
|
||||
.van-hairline--top-bottom::after {
|
||||
border-width: 0!important;
|
||||
border-width: 0 !important;
|
||||
}
|
||||
.van-cell {
|
||||
line-height: 30px !important;
|
||||
@ -143,3 +143,26 @@ div:focus {
|
||||
max-width: 10rem;
|
||||
min-width: 10rem;
|
||||
}
|
||||
.my-header {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
background: #fff;
|
||||
border-bottom:1px solid #E9E9E9;
|
||||
.back-icon {
|
||||
position: absolute;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
box-sizing: border-box;
|
||||
background: url('../../assets/images/arrow-left.png') no-repeat center
|
||||
center;
|
||||
background-size: 70% 70%;
|
||||
}
|
||||
.header-title {
|
||||
font-size: 17px;
|
||||
font-weight: 600;
|
||||
height: 44px;
|
||||
line-height: 44px;
|
||||
text-align: center;
|
||||
|
||||
}
|
||||
}
|
||||
|
BIN
src/assets/images/arrow-left.png
Normal file
BIN
src/assets/images/arrow-left.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 838 B |
BIN
src/assets/images/coupon/s-coupon-detail-down@2x.png
Normal file
BIN
src/assets/images/coupon/s-coupon-detail-down@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 389 B |
BIN
src/assets/images/coupon/s-coupon-detail-up@2x.png
Normal file
BIN
src/assets/images/coupon/s-coupon-detail-up@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 378 B |
BIN
src/assets/images/coupon/s-coupon-empty@2x.png
Normal file
BIN
src/assets/images/coupon/s-coupon-empty@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
35
src/components/ListEmpty.vue
Normal file
35
src/components/ListEmpty.vue
Normal file
@ -0,0 +1,35 @@
|
||||
<!-- ListEmpty.vue -->
|
||||
<template>
|
||||
<div class="list-empty">
|
||||
<slot name='emptyImg'></slot>
|
||||
<div class="empty-tips">{{tips}}</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'ListEmpty',
|
||||
props: {
|
||||
tips: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
</script>
|
||||
<style lang='scss' scoped>
|
||||
.list-empty {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 55px;
|
||||
|
||||
.empty-tips {
|
||||
color: #999999;
|
||||
font-size: 17px;
|
||||
line-height: 24px;
|
||||
padding-top: 35px;
|
||||
}
|
||||
}
|
||||
</style>
|
134
src/components/QrCodePopup.vue
Normal file
134
src/components/QrCodePopup.vue
Normal file
@ -0,0 +1,134 @@
|
||||
<!-- verificationCode.vue -->
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!-- 二维码大图 -->
|
||||
<van-popup v-model="visible" class="modal-popup">
|
||||
<div class="qrcode-popup-container">
|
||||
<div class="qrcode-close" @click="closePopup">
|
||||
取消
|
||||
</div>
|
||||
<div class="qrcode-top">
|
||||
{{title}}
|
||||
</div>
|
||||
<div class="qrcode-bottom">
|
||||
<img class="qrcode-img" :src="src" alt="">
|
||||
<div class="qrcode-tips" v-html="tips">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</van-popup>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Popup, Toast } from 'vant'
|
||||
import * as Validate from '@/utils/validate'
|
||||
import { bindPhoneNumber, sendCode } from '@/api/user'
|
||||
export default {
|
||||
name: 'QrCodePopup',
|
||||
components: {
|
||||
'van-popup': Popup
|
||||
},
|
||||
props: {
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
src: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
tips: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
closePopup () {
|
||||
this.$emit('close')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<style lang='scss' scoped>
|
||||
.modal-popup {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #d43f36;
|
||||
.qrcode-popup-container {
|
||||
position: relative;
|
||||
margin: 25px 27px;
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
.qrcode-close {
|
||||
color: #d43f36;
|
||||
font-size: 16px;
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
padding: 20px;
|
||||
z-index: 100;
|
||||
}
|
||||
.qrcode-top {
|
||||
position: relative;
|
||||
height: 115px;
|
||||
border-bottom: 2px dotted #dbdbdb;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #333333;
|
||||
font-size: 24px;
|
||||
font-weight: 500;
|
||||
&::before {
|
||||
content: "";
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: #d43f36;
|
||||
position: absolute;
|
||||
bottom: -16px;
|
||||
right: -16px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
&::after {
|
||||
content: "";
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background: #d43f36;
|
||||
position: absolute;
|
||||
bottom: -16px;
|
||||
left: -16px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
.qrcode-bottom {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 25px 0 41px 0;
|
||||
.qrcode-img {
|
||||
height: 190px;
|
||||
width: 190px;
|
||||
}
|
||||
.qrcode-tips {
|
||||
font-size: 15px;
|
||||
color: #666666;
|
||||
width: 210px;
|
||||
text-align: center;
|
||||
margin-top: 17px;
|
||||
line-height: 21px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -7,12 +7,12 @@
|
||||
<div class="cell-title">绑定手机号</div>
|
||||
<div class="cell-item">
|
||||
<div class="item-left">+86</div>
|
||||
<input v-model="verifyCodeForm.account" type="tel" placeholder="请输入手机号">
|
||||
<input v-reset-page v-model="verifyCodeForm.account" type="tel" placeholder="请输入手机号">
|
||||
</div>
|
||||
<div class="cell-item">
|
||||
<div class="item-left"> 验证码</div>
|
||||
<div class="code-cell-warp">
|
||||
<input v-model="verifyCodeForm.code" type="tel" placeholder="请输入验证码">
|
||||
<input v-reset-page v-model="verifyCodeForm.code" type="tel" placeholder="请输入验证码">
|
||||
<div :class="['registered-get-code',codeCountdown?'disabled-btn':'']" :disabled="codeCountdown" @click="sendMsgCode">
|
||||
{{ codeCountdown ? `${codeCountdown}后重新发送` : '发送验证码' }}
|
||||
</div>
|
||||
@ -66,7 +66,10 @@ export default {
|
||||
// 绑定手机
|
||||
bindPhoneNumber(this.verifyCodeForm).then(res => {
|
||||
// 绑定成功后关闭弹窗
|
||||
this.visible = false
|
||||
Toast({
|
||||
message: '绑定成功'
|
||||
})
|
||||
this.$emit('close')
|
||||
}).catch(() => {
|
||||
})
|
||||
},
|
||||
|
@ -3,7 +3,7 @@ module.exports = {
|
||||
baseUrl: 'https://test.top1buyer.com',
|
||||
api: {
|
||||
base_api: 'https://test.top1buyer.com/wx',
|
||||
common_api: 'https://xxx.xxx.com/common'
|
||||
common_api: 'https://test.top1buyer.com/wx'
|
||||
},
|
||||
// package appid,appSecret
|
||||
APPID: 'Pc690487e95992c395633866b',
|
||||
|
@ -1,5 +1,42 @@
|
||||
/**
|
||||
*格式化时间
|
||||
*yyyy-MM-dd hh:mm:ss
|
||||
*/
|
||||
export function formatDate(time, fmt) {
|
||||
if (time === undefined || '') {
|
||||
return
|
||||
}
|
||||
const date = new Date(time)
|
||||
if (/(y+)/.test(fmt)) {
|
||||
fmt = fmt.replace(
|
||||
RegExp.$1,
|
||||
(date.getFullYear() + '').substr(4 - RegExp.$1.length)
|
||||
)
|
||||
}
|
||||
const o = {
|
||||
'M+': date.getMonth() + 1,
|
||||
'd+': date.getDate(),
|
||||
'h+': date.getHours(),
|
||||
'm+': date.getMinutes(),
|
||||
's+': date.getSeconds()
|
||||
}
|
||||
for (const k in o) {
|
||||
if (new RegExp(`(${k})`).test(fmt)) {
|
||||
const str = o[k] + ''
|
||||
fmt = fmt.replace(
|
||||
RegExp.$1,
|
||||
RegExp.$1.length === 1 ? str : padLeftZero(str)
|
||||
)
|
||||
}
|
||||
}
|
||||
return fmt
|
||||
}
|
||||
|
||||
function padLeftZero(str) {
|
||||
return ('00' + str).substr(str.length)
|
||||
}
|
||||
// 转为unicode 编码
|
||||
exports.encodeUnicode = str => {
|
||||
export function encodeUnicode(str) {
|
||||
var res = []
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
res[i] = ('00' + str.charCodeAt(i).toString(16)).slice(-4)
|
||||
@ -8,7 +45,7 @@ exports.encodeUnicode = str => {
|
||||
}
|
||||
|
||||
// 解码
|
||||
exports.decodeUnicode = str => {
|
||||
export function decodeUnicode(str) {
|
||||
if (str === undefined || '') {
|
||||
return
|
||||
}
|
||||
@ -18,17 +55,26 @@ exports.decodeUnicode = str => {
|
||||
/*
|
||||
* 格式化金钱
|
||||
*/
|
||||
exports.formatMoney = value => {
|
||||
export function formatMoney(value) {
|
||||
return Number(value).toFixed(2)
|
||||
}
|
||||
exports.formatCentMoney = value => {
|
||||
export function formatCentMoney(value) {
|
||||
if (value === undefined || '') {
|
||||
return
|
||||
}
|
||||
return Number(value / 100).toFixed(2)
|
||||
}
|
||||
// 昵称解码
|
||||
exports.formatName = nickname => {
|
||||
export function formatName(nickname) {
|
||||
if (!nickname) return ''
|
||||
return decodeURIComponent(nickname)
|
||||
}
|
||||
// 折扣转换
|
||||
export function formatPercent(percent_off) {
|
||||
if (!percent_off) return ''
|
||||
if (percent_off == 1) {
|
||||
return '原价'
|
||||
}
|
||||
// 解决精度丢失问题
|
||||
return Math.round(percent_off * 100) / 10
|
||||
}
|
||||
|
@ -1,10 +1,12 @@
|
||||
import Vue from 'vue'
|
||||
import filter from './filter'
|
||||
import * as filter from './filter'
|
||||
|
||||
Object.keys(filter).forEach(k => Vue.filter(k, filter[k]))
|
||||
|
||||
Vue.prototype.$formatDate = Vue.filter('formatDate')
|
||||
Vue.prototype.$encodeUnicode = Vue.filter('encodeUnicode')
|
||||
Vue.prototype.$decodeUnicode = Vue.filter('decodeUnicode')
|
||||
Vue.prototype.$formatMoney = Vue.filter('formatMoney')
|
||||
Vue.prototype.$formatCentMoney = Vue.filter('formatCentMoney')
|
||||
Vue.prototype.$formatName = Vue.filter('formatName')
|
||||
Vue.prototype.$formatPercent = Vue.filter('formatPercent')
|
||||
|
@ -1,5 +1,5 @@
|
||||
import Vue from 'vue'
|
||||
|
||||
import '@babel/polyfill'
|
||||
import 'normalize.css/normalize.css' // A modern alternative to CSS resets
|
||||
import '@/assets/css/index.scss' // global css
|
||||
// 移动端适配
|
||||
@ -8,11 +8,14 @@ import App from './App'
|
||||
import store from './store'
|
||||
import router from './router'
|
||||
import '@/filters' // filters
|
||||
import '@/utils/directives' // directives
|
||||
import '@/permission' // permission control
|
||||
import wechatAuth from './plugins/wechatAuth' // 微信登录插件
|
||||
Vue.use(wechatAuth, {
|
||||
appid: process.env.VUE_APP_WECHAT_APPID
|
||||
})
|
||||
import VCconsole from 'vconsole'
|
||||
Vue.use(VCconsole)
|
||||
Vue.config.productionTip = false
|
||||
|
||||
new Vue({
|
||||
|
@ -5,9 +5,14 @@ import wechatAuth from './plugins/wechatAuth' // 微信登录插件
|
||||
const qs = require('qs')
|
||||
router.beforeEach((to, from, next) => {
|
||||
// next()
|
||||
console.log(store.getters.loginStatus)
|
||||
// store.dispatch('user/fedLogOut').then(() => {
|
||||
// // location.reload()
|
||||
// })
|
||||
// store.dispatch('user/setLoginStatus', 0)
|
||||
// alert(store.getters.loginStatus)
|
||||
// return false
|
||||
// alert(store.getters.loginStatus)
|
||||
const loginStatus = Number(store.getters.loginStatus)
|
||||
// console.log(loginStatus === 1)
|
||||
document.title = getPageTitle(to.meta.title)
|
||||
if (loginStatus === 0) {
|
||||
// 微信未授权登录跳转到授权登录页面
|
||||
@ -22,7 +27,9 @@ router.beforeEach((to, from, next) => {
|
||||
} else {
|
||||
loginUrl = url
|
||||
}
|
||||
// alert(loginUrl)
|
||||
wechatAuth.redirect_uri = loginUrl
|
||||
// 无论拒绝还是授权都设置成1
|
||||
store.dispatch('user/setLoginStatus', 1)
|
||||
window.location.href = wechatAuth.authUrl
|
||||
} else if (loginStatus === 1) {
|
||||
@ -31,27 +38,32 @@ router.beforeEach((to, from, next) => {
|
||||
wechatAuth.returnFromWechat(to.fullPath)
|
||||
} catch (err) {
|
||||
store.dispatch('user/setLoginStatus', 0)
|
||||
next()
|
||||
location.reload()
|
||||
// next()
|
||||
}
|
||||
// 同意授权 to.fullPath 携带code参数,拒绝授权没有code参数
|
||||
// alert(to.fullPath)
|
||||
// 重新赋值,不然获取不到code
|
||||
const code = wechatAuth.code
|
||||
store
|
||||
.dispatch('user/loginWechatAuth', code)
|
||||
.then(res => {
|
||||
console.log(res)
|
||||
if (res.status === 200) {
|
||||
// alert(code)
|
||||
if (code) {
|
||||
store
|
||||
.dispatch('user/loginWechatAuth', code)
|
||||
.then(res => {
|
||||
store.dispatch('user/setLoginStatus', 2)
|
||||
} else {
|
||||
next()
|
||||
})
|
||||
.catch(() => {
|
||||
store.dispatch('user/setLoginStatus', 0)
|
||||
}
|
||||
next()
|
||||
})
|
||||
.catch(() => {
|
||||
store.dispatch('user/setLoginStatus', 0)
|
||||
next()
|
||||
})
|
||||
location.reload()
|
||||
})
|
||||
} else {
|
||||
store.dispatch('user/setLoginStatus', 0)
|
||||
location.reload()
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// alert(to.fullPath)
|
||||
|
||||
next()
|
||||
}
|
||||
})
|
||||
|
@ -38,7 +38,7 @@ export const constantRoutes = [
|
||||
const createRouter = () =>
|
||||
new Router({
|
||||
mode: 'history', // require service support
|
||||
base: '/',
|
||||
base: '/antpublic',
|
||||
scrollBehavior: () => ({ y: 0 }),
|
||||
routes: constantRoutes
|
||||
})
|
||||
|
@ -71,6 +71,12 @@ const actions = {
|
||||
// 保存用户个人信息
|
||||
setUserInfo({ commit, state }, query) {
|
||||
commit('SET_USERINFO', saveUserInfo(query))
|
||||
},
|
||||
// 登出
|
||||
fedLogOut({ commit, state }, query) {
|
||||
removeToken()
|
||||
removeUserInfo()
|
||||
commit('SET_LOGIN_STATUS', saveLoginStatus(0))
|
||||
}
|
||||
}
|
||||
|
||||
|
33
src/utils/directives.js
Normal file
33
src/utils/directives.js
Normal file
@ -0,0 +1,33 @@
|
||||
import Vue from 'vue'
|
||||
|
||||
Vue.directive('focus', {
|
||||
inserted: function(el) {
|
||||
// 获取焦点
|
||||
el.focus()
|
||||
}
|
||||
})
|
||||
|
||||
Vue.directive('numberOnly', {
|
||||
inserted: function(el) {
|
||||
// 获取焦点
|
||||
el.handler = function() {
|
||||
el.value = el.value.replace(/[^\d]/g, '')
|
||||
}
|
||||
el.addEventListener('input', el.handler)
|
||||
}
|
||||
})
|
||||
Vue.directive('resetPage', {
|
||||
inserted: function(el) {
|
||||
// 监听键盘收起事件
|
||||
document.body.addEventListener('focusout', () => {
|
||||
if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) {
|
||||
// 软键盘收起的事件处理
|
||||
setTimeout(() => {
|
||||
const scrollHeight =
|
||||
document.documentElement.scrollTop || document.body.scrollTop || 0
|
||||
window.scrollTo(0, Math.max(scrollHeight - 1, 0))
|
||||
}, 100)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
@ -35,10 +35,14 @@ service.interceptors.response.use(
|
||||
response => {
|
||||
Toast.clear()
|
||||
const res = response.data
|
||||
|
||||
if (res.status && res.status !== 200) {
|
||||
Toast({
|
||||
message: res.info
|
||||
})
|
||||
// 登录超时,重新登录
|
||||
if (res.status === 401) {
|
||||
store.dispatch('FedLogOut').then(() => {
|
||||
store.dispatch('user/fedLogOut').then(() => {
|
||||
location.reload()
|
||||
})
|
||||
}
|
||||
|
@ -1,129 +1,211 @@
|
||||
<!-- coupon.vue -->
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<van-nav-bar title="我的优惠券" left-arrow @click-left="()=>{this.$router.push('/account')}" />
|
||||
<van-tabs v-model="tabActive" class="coupon-tabs" :line-width="44" :line-height="1" color="#333333">
|
||||
<van-tab title="未使用"></van-tab>
|
||||
<van-tab title="已使用"></van-tab>
|
||||
<van-tab title="已失效"></van-tab>
|
||||
</van-tabs>
|
||||
<div class="fixed">
|
||||
<div class="my-header">
|
||||
<div class="back-icon" @click="()=>{this.$router.push('/account')}"></div>
|
||||
<div class="header-title">我的优惠券</div>
|
||||
</div>
|
||||
<van-tabs v-model="tabActive" @click="tabClick(tabActive)" class="coupon-tabs" :line-width="44" :line-height="1" color="#333333">
|
||||
<van-tab title="未使用"></van-tab>
|
||||
<van-tab title="已使用"></van-tab>
|
||||
<van-tab title="已失效"></van-tab>
|
||||
</van-tabs>
|
||||
</div>
|
||||
<div class="coupon-list-warpper">
|
||||
<div class="coupon-item">
|
||||
<div class="coupon-amount-warp">
|
||||
<div class="coupon-amount-number">
|
||||
<span class="rmb">¥</span>
|
||||
<span>50</span>
|
||||
<!-- foreach -->
|
||||
<div v-for="(item,index) in couponList" :key="index" class="coupon-item">
|
||||
<div class="coupon-main">
|
||||
<div class="coupon-left">
|
||||
<div class="coupon-amount-number">
|
||||
<template v-if="item.couponType===3">
|
||||
<span>{{ item.percentOff|formatPercent }}</span><span class="rmb">折</span>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span class="rmb">¥</span><span>{{ item.couponAmount|formatCentMoney }}</span>
|
||||
</template>
|
||||
</div>
|
||||
<div>
|
||||
<span v-if="item.couponType===1">无门槛</span>
|
||||
<span v-if="item.couponType===2">满¥{{ item.availableAmount|formatCentMoney }}可用</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="coupon-right">
|
||||
<div class="coupon-info">
|
||||
<div class="coupon-title">{{ item.couponName }}</div>
|
||||
<div v-if="item.endType === 0" class="coupon-off-date">无使用期限</div>
|
||||
<div v-else class="coupon-off-date"> {{ item.couponStart|formatDate("yyyy.MM.dd hh:mm:ss") }}-{{ item.couponEnd|formatDate("yyyy.MM.dd hh:mm:ss") }}</div>
|
||||
</div>
|
||||
<div class="coupon-detail" @click="showExpain(index)">
|
||||
<span>详细信息</span>
|
||||
<span :class="item.explainVisible?'coupon-arrow-up':'coupon-arrow-down'"></span>
|
||||
</div>
|
||||
</div>
|
||||
<p><span>满¥199可用</span></p>
|
||||
</div>
|
||||
<div class="coupon-info-warp">
|
||||
<div class="coupon-info">
|
||||
<div class="coupon-title">全场限时优惠</div>
|
||||
<div class="off-date">2018.12.18 10:00:00</div>
|
||||
</div>
|
||||
<div class="coupon-detail">详细信息<span></span></div>
|
||||
<div v-if="item.explainVisible" class="coupon-info-explain">
|
||||
{{ item.couponExplain }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="coupon-item">
|
||||
<div class="coupon-amount-warp">
|
||||
<div class="coupon-amount-number">
|
||||
<span class="rmb">¥</span>
|
||||
<span>50</span>
|
||||
</div>
|
||||
<p><span>满¥199可用</span></p>
|
||||
<!-- foreach end-->
|
||||
<!-- empty -->
|
||||
<list-empty v-if="couponList.length===0" tips="您没有可用的优惠券哦">
|
||||
<div slot="emptyImg" class="coupon_empty">
|
||||
</div>
|
||||
<div class="coupon-info-warp">
|
||||
<div class="coupon-info">
|
||||
<div class="coupon-title">全场限时优惠</div>
|
||||
<div class="off-date">2018.12.18 10:00:00</div>
|
||||
</div>
|
||||
<div class="coupon-detail">详细信息<span></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</list-empty>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { NavBar, Tab, Tabs } from 'vant'
|
||||
import { Tab, Tabs } from 'vant'
|
||||
import { getCouponList } from '@/api/coupon'
|
||||
import ListEmpty from '@/components/ListEmpty'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
'van-nav-bar': NavBar,
|
||||
'van-tabs': Tabs,
|
||||
'van-tab': Tab
|
||||
'van-tab': Tab,
|
||||
'list-empty': ListEmpty
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
tabActive: 0
|
||||
tabActive: 0,
|
||||
couponList: [],
|
||||
params: {
|
||||
couponStatus: 0 // 0未使用,1已使用,2已失效
|
||||
},
|
||||
explainShow: false
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
mounted () { },
|
||||
methods: {}
|
||||
mounted () {
|
||||
this.fetchData()
|
||||
},
|
||||
methods: {
|
||||
fetchData () {
|
||||
getCouponList(this.params).then(res => {
|
||||
this.couponList = res.data.couponList
|
||||
})
|
||||
},
|
||||
// 显示优惠券解释说明
|
||||
showExpain (index) {
|
||||
if (this.couponList[index].explainVisible) {
|
||||
this.couponList[index].explainVisible = !this.couponList[index].explainVisible
|
||||
} else {
|
||||
this.$set(this.couponList[index], 'explainVisible', true)
|
||||
}
|
||||
},
|
||||
// 切换tab
|
||||
tabClick (index) {
|
||||
this.params.couponStatus = index
|
||||
// 重新请求数据
|
||||
this.fetchData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
<style lang='scss'>
|
||||
.coupon-tabs {
|
||||
.van-tab {
|
||||
font-size: 17px !important;
|
||||
font-weight: 500 !important;
|
||||
.fixed {
|
||||
position: fixed;
|
||||
z-index: 9999;
|
||||
width: 100%;
|
||||
.coupon-tabs {
|
||||
.van-tab {
|
||||
font-size: 17px !important;
|
||||
font-weight: 500 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.coupon-list-warpper {
|
||||
padding: 12px;
|
||||
padding: 98px 12px 0 12px;
|
||||
height: 100vh;
|
||||
overflow-y: scroll;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
.coupon-item {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
margin-bottom: 12px;
|
||||
.coupon-amount-warp {
|
||||
width: 118px;
|
||||
.coupon-main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: url("../../assets/images/coupon/s-coupon-item@2x.png")
|
||||
no-repeat center center;
|
||||
background-size: contain;
|
||||
color: #fff;
|
||||
.coupon-amount-number {
|
||||
font-size: 30px;
|
||||
.rmb {
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.coupon-info-warp {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: #fff;
|
||||
flex: 1;
|
||||
.coupon-info {
|
||||
width: 100%;
|
||||
.coupon-left {
|
||||
width: 118px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
padding: 12px 11px 9px 11px;
|
||||
height: 70px;
|
||||
border-bottom: 2px dotted #ddd;
|
||||
.coupon-title {
|
||||
font-size: 16px;
|
||||
line-height: 23px;
|
||||
color: #333333;
|
||||
}
|
||||
.off-date {
|
||||
font-size: 10px;
|
||||
line-height: 14px;
|
||||
color: #999999;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: url("../../assets/images/coupon/s-coupon-item@2x.png")
|
||||
no-repeat center center;
|
||||
background-size: contain;
|
||||
color: #fff;
|
||||
.coupon-amount-number {
|
||||
font-size: 30px;
|
||||
line-height: 42px;
|
||||
.rmb {
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.coupon-detail {
|
||||
color: #666666;
|
||||
line-height: 30px;
|
||||
padding-left: 11px;
|
||||
.coupon-right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: #fff;
|
||||
flex: 1;
|
||||
.coupon-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
padding: 12px 11px 9px 11px;
|
||||
height: 70px;
|
||||
border-bottom: 2px dotted #ddd;
|
||||
.coupon-title {
|
||||
font-size: 16px;
|
||||
line-height: 23px;
|
||||
color: #333333;
|
||||
}
|
||||
.coupon-off-date {
|
||||
font-size: 10px;
|
||||
line-height: 14px;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
.coupon-detail {
|
||||
color: #666666;
|
||||
line-height: 30px;
|
||||
padding: 0 11px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.coupon-arrow-down {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
background: url("../../assets/images/coupon/s-coupon-detail-down@2x.png")
|
||||
no-repeat center center;
|
||||
background-size: contain;
|
||||
}
|
||||
.coupon-arrow-up {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
background: url("../../assets/images/coupon/s-coupon-detail-up@2x.png")
|
||||
no-repeat center center;
|
||||
background-size: contain;
|
||||
}
|
||||
}
|
||||
}
|
||||
.coupon-info-explain {
|
||||
background: #ffffff;
|
||||
margin-top: 1px;
|
||||
padding: 8px 12px;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
}
|
||||
.coupon_empty {
|
||||
width: 140px;
|
||||
height: 105px;
|
||||
background: url("../../assets/images/coupon/s-coupon-empty@2x.png") no-repeat
|
||||
center center;
|
||||
background-size: cover;
|
||||
}
|
||||
</style>
|
||||
|
@ -9,8 +9,8 @@
|
||||
<div class="user-name">{{ vipInfo.nickName|formatName }}<span class="user-level"></span></div>
|
||||
<div class="user-code">代购编号:{{ vipInfo.userCode }}</div>
|
||||
</div>
|
||||
<div class="qrcode-warp" @click="showQrcode($event)">
|
||||
<qrcode :value="vipInfo.userCode" tag="img" :options="{ width: 45,margin:0 }"></qrcode>
|
||||
<div class="qrcode-warp" @click="showUserQrcode($event)">
|
||||
<qrcode v-if="vipInfo.userPhone!==''" :value="vipInfo.userPhone" tag="img" :options="{ width: 145,margin:0 }"></qrcode>
|
||||
</div>
|
||||
</div>
|
||||
<div class="account-info">
|
||||
@ -42,49 +42,60 @@
|
||||
</van-cell-group>
|
||||
</div>
|
||||
<!-- 绑定手机 -->
|
||||
<msg-code :visible="codeVisible"></msg-code>
|
||||
<!-- 二维码大图 -->
|
||||
<van-popup v-model="qrcodeVisible" style="padding:10px;border-radius:10px">
|
||||
<div class="popup-container">
|
||||
<img :src="qrSrc" alt="">
|
||||
</div>
|
||||
</van-popup>
|
||||
<msg-code :visible="codeVisible" @close="()=>{ codeVisible = false }"></msg-code>
|
||||
<!-- 二维码 -->
|
||||
<qrcode-popup :visible="qrcodeVisible" :src="qrSrc" :title="qrTitle" :tips="qrTips" @close="()=>{ qrcodeVisible = false }">
|
||||
</qrcode-popup>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import VueQrcode from '@chenfengyuan/vue-qrcode'
|
||||
import { Popup, Cell, CellGroup } from 'vant'
|
||||
import { Cell, CellGroup } from 'vant'
|
||||
import VerificationCode from '@/components/VerificationCode'
|
||||
import QrCodePopup from '@/components/QrCodePopup'
|
||||
import { getAccountInfo } from '@/api/user'
|
||||
export default {
|
||||
components: {
|
||||
'van-cell-group': CellGroup,
|
||||
'van-cell': Cell,
|
||||
'msg-code': VerificationCode,
|
||||
'qrcode': VueQrcode,
|
||||
'van-popup': Popup
|
||||
'qrcode-popup': QrCodePopup,
|
||||
'qrcode': VueQrcode
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
qrcodeVisible: false,
|
||||
codeVisible: false,
|
||||
vipInfo: {},
|
||||
qrSrc: ''
|
||||
qrSrc: '',
|
||||
qrTitle: '',
|
||||
qrTips: ''
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
created () {
|
||||
computed: {
|
||||
},
|
||||
mounted () {
|
||||
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
// 获取初始数据
|
||||
async init () {
|
||||
init () {
|
||||
|
||||
// 获取全部的会员信息
|
||||
const { data } = await getAccountInfo()
|
||||
this.vipInfo = data.vipUserInfo
|
||||
getAccountInfo().then(res => {
|
||||
this.vipInfo = res.data.vipUserInfo
|
||||
// 手机号为空的时候绑定
|
||||
if (this.vipInfo && this.vipInfo.userPhone === '') {
|
||||
this.codeVisible = true
|
||||
}
|
||||
})
|
||||
},
|
||||
showQrcode (event) {
|
||||
// 展示会员二维码
|
||||
showUserQrcode (event) {
|
||||
this.qrSrc = event.target.currentSrc
|
||||
this.qrTitle = '小蚁货仓会员码'
|
||||
this.qrTips = '<p>会员码用于会员储值及支付</p> <p>请勿随意泄漏给</p>'
|
||||
this.qrcodeVisible = true
|
||||
}
|
||||
}
|
||||
@ -135,9 +146,13 @@ h1 {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
.qr-code {
|
||||
.qrcode-warp {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.account-info {
|
||||
|
@ -1,17 +1,15 @@
|
||||
'use strict'
|
||||
const path = require('path')
|
||||
const defaultSettings = require('./src/config/index.js')
|
||||
function resolve(dir) {
|
||||
return path.join(__dirname, dir)
|
||||
}
|
||||
|
||||
const name = defaultSettings.title || 'vue mobile template' // page title
|
||||
const port = 9018 // dev port
|
||||
const externals = {
|
||||
vue: 'Vue',
|
||||
'vue-router': 'VueRouter',
|
||||
vuex: 'Vuex',
|
||||
'mint-ui': 'MINT',
|
||||
vant: 'vant',
|
||||
axios: 'axios',
|
||||
'crypto-js': 'CryptoJS'
|
||||
}
|
||||
@ -26,6 +24,7 @@ const cdn = {
|
||||
build: {
|
||||
css: ['https://cdn.jsdelivr.net/npm/vant@beta/lib/index.css'],
|
||||
js: [
|
||||
// 'https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.4.4/polyfill.min.js',
|
||||
'https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js',
|
||||
'https://cdnjs.cloudflare.com/ajax/libs/vue-router/3.0.6/vue-router.min.js',
|
||||
'https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js',
|
||||
@ -36,7 +35,7 @@ const cdn = {
|
||||
}
|
||||
}
|
||||
module.exports = {
|
||||
publicPath: '/',
|
||||
publicPath: process.env.NODE_ENV === 'production' ? '/antpublic/' : '/',
|
||||
outputDir: 'dist',
|
||||
assetsDir: 'static',
|
||||
lintOnSave: process.env.NODE_ENV === 'development',
|
||||
@ -50,29 +49,22 @@ module.exports = {
|
||||
},
|
||||
disableHostCheck: true
|
||||
},
|
||||
configureWebpack: config => {
|
||||
// 为生产环境修改配置...
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
// externals里的模块不打包
|
||||
Object.assign(config, {
|
||||
externals: externals
|
||||
})
|
||||
}
|
||||
// 为开发环境修改配置...
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
}
|
||||
},
|
||||
// configureWebpack: {
|
||||
// name: name,
|
||||
// resolve: {
|
||||
// alias: {
|
||||
// '@': resolve('src')
|
||||
// }
|
||||
// configureWebpack: config => {
|
||||
// // 为生产环境修改配置...
|
||||
// if (process.env.NODE_ENV === 'production') {
|
||||
// // externals里的模块不打包
|
||||
// Object.assign(config, {
|
||||
// externals: externals
|
||||
// })
|
||||
// }
|
||||
// // 为开发环境修改配置...
|
||||
// if (process.env.NODE_ENV === 'development') {
|
||||
// }
|
||||
// },
|
||||
chainWebpack(config) {
|
||||
config.plugins.delete('preload') // TODO: need test
|
||||
config.plugins.delete('prefetch') // TODO: need test
|
||||
config
|
||||
// alias
|
||||
config.resolve.alias
|
||||
.set('@', resolve('src'))
|
||||
@ -82,16 +74,16 @@ module.exports = {
|
||||
/**
|
||||
* 添加CDN参数到htmlWebpackPlugin配置中, 详见public/index.html 修改
|
||||
*/
|
||||
config.plugin('html').tap(args => {
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
args[0].cdn = cdn.build
|
||||
}
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
args[0].cdn = cdn.dev
|
||||
}
|
||||
console.log(args)
|
||||
return args
|
||||
})
|
||||
// config.plugin('html').tap(args => {
|
||||
// if (process.env.NODE_ENV === 'production') {
|
||||
// args[0].cdn = cdn.build
|
||||
// }
|
||||
// if (process.env.NODE_ENV === 'development') {
|
||||
// args[0].cdn = cdn.dev
|
||||
// }
|
||||
// console.log(args)
|
||||
// return args
|
||||
// })
|
||||
|
||||
// set preserveWhitespace
|
||||
config.module
|
||||
|
Loading…
x
Reference in New Issue
Block a user