Commit f31000f9 authored by FE-安焕焕's avatar FE-安焕焕 👣

商城首页开发

parent c3371c4c
import request from '@/service/httpDecorator'; import request from '@/service/httpDecorator';
import config from '@/config'; import config from '@/config';
const { talosApi } = config; const { talosHost } = config;
const queryPayInfo = function(data) { const queryPayInfo = function(data) {
return request.post(`${talosApi}/open/checkout`, data); return request.post(`${talosHost}/open/checkout`, data);
}; };
const prepay = function(data) { const prepay = function(data) {
console.log('prepay-param', data); console.log('prepay-param', data);
return request.post(`${talosApi}/open/checkout/prepay`, data); return request.post(`${talosHost}/open/checkout/prepay`, data);
}; };
const pay = function(data) { const pay = function(data) {
return request.post(`${talosApi}/open/checkout/pay`, data, { return request.post(`${talosHost}/open/checkout/pay`, data, {
needScDeviceId: true needScDeviceId: true
}); });
}; };
const queryPayStatus = function(data) { const queryPayStatus = function(data) {
return request.post(`${talosApi}/open/checkout/pay_status/query`, data); return request.post(`${talosHost}/open/checkout/pay_status/query`, data);
}; };
const sendSms = function(data) { const sendSms = function(data) {
return request.post(`${talosApi}/open/checkout/send_sms`, data); return request.post(`${talosHost}/open/checkout/send_sms`, data);
}; };
const desSalt = function() { const desSalt = function() {
return request.get(`${talosApi}/vcc/account/salt`); return request.get(`${talosHost}/vcc/account/salt`);
}; };
const h5AppyUrl = function() { const h5AppyUrl = function() {
return request.get(`${talosApi}/vcc/xyqb_mall/app_url`); return request.get(`${talosHost}/vcc/xyqb_mall/app_url`);
}; };
const getCoupon = function(params) { const getCoupon = function(params) {
return request.post(`${talosApi}/open/checkout/pay_coupon_list`, params); return request.post(`${talosHost}/open/checkout/pay_coupon_list`, params);
}; };
const ocrFaceId = function(params) { const ocrFaceId = function(params) {
return request.post(`${talosApi}open/checkout/ocr_faceId`, params); return request.post(`${talosHost}open/checkout/ocr_faceId`, params);
}; };
export { export {
......
...@@ -8,11 +8,13 @@ export default { ...@@ -8,11 +8,13 @@ export default {
return http.get(talosHost + '/api/kdsp/virtual/recharge-center/config'); return http.get(talosHost + '/api/kdsp/virtual/recharge-center/config');
}, },
// VIP充值中心SKU列表 // VIP充值中心SKU列表
getSkuList() { getSkuList(spuNos, type) {
return http.get(talosHost + '/api/kdsp/virtual/recharge-center/recharge-list'); return http.get(
`${talosHost}/api/kdsp/virtual/recharge-center/recharge-list?spuNos=${spuNos}&type=${type}`
);
}, },
// 查询归属地 // 查询归属地
getPhoneHome() { getPhoneHome(phoneNo) {
return http.get(talosHost + '/api/kdsp/virtual/recharge-center/phone-home'); return http.get(`${talosHost}/api/kdsp/virtual/recharge-center/phone-home?phoneNo=${phoneNo}`);
} }
}; };
src/assets/images/addicon.png

1.06 KB | W: | H:

src/assets/images/addicon.png

465 Bytes | W: | H:

src/assets/images/addicon.png
src/assets/images/addicon.png
src/assets/images/addicon.png
src/assets/images/addicon.png
  • 2-up
  • Swipe
  • Onion skin
src/assets/images/paying.png

4.36 KB | W: | H:

src/assets/images/paying.png

1.13 KB | W: | H:

src/assets/images/paying.png
src/assets/images/paying.png
src/assets/images/paying.png
src/assets/images/paying.png
  • 2-up
  • Swipe
  • Onion skin
...@@ -14,11 +14,6 @@ let protocol = window.location.protocol; ...@@ -14,11 +14,6 @@ let protocol = window.location.protocol;
let payHost = protocol + '//mapi-qa.liangkebang.net/pay'; let payHost = protocol + '//mapi-qa.liangkebang.net/pay';
let shenceHost = 'https://bn.xyqb.com/sa?project=default'; // 测试地址 let shenceHost = 'https://bn.xyqb.com/sa?project=default'; // 测试地址
<<<<<<< HEAD
let talosHost = 'http://yapi.quantgroups.com/mock/351'; // 电商分期测试环境服务地址 let talosHost = 'http://yapi.quantgroups.com/mock/351'; // 电商分期测试环境服务地址
// let talosHost = 'https://talos-vcc2.liangkebang.net'; // 电商分期测试环境服务地址
=======
let talosApi = 'http://yapi.quantgroups.com/mock/410'; // 电商分期测试环境服务地址
>>>>>>> 支付开发
let operatorHost = 'https://operator.liangkebang.com'; let operatorHost = 'https://operator.liangkebang.com';
export default { talosApi, operatorHost, payHost, shenceHost, test: true }; export default { talosHost, operatorHost, payHost, shenceHost, test: true };
export default [ export default [
{ {
path: '/', path: '/',
redirect: '/pay' redirect: '/home'
},
{
path: '/home',
name: 'home',
meta: {
title: '充值中心'
},
component: () => import('../views/home')
}, },
{ {
path: '/pay', path: '/pay',
...@@ -9,7 +17,7 @@ export default [ ...@@ -9,7 +17,7 @@ export default [
meta: { meta: {
title: '收银台' title: '收银台'
}, },
component: () => import('../pay') component: () => import('../views/pay')
}, },
{ {
path: '/payFail', path: '/payFail',
...@@ -18,7 +26,7 @@ export default [ ...@@ -18,7 +26,7 @@ export default [
meta: { meta: {
title: '支付失败' title: '支付失败'
}, },
component: () => import('../pay/payResult') component: () => import('../views/pay/payResult')
}, },
{ {
path: '/paySuccess', path: '/paySuccess',
...@@ -28,7 +36,7 @@ export default [ ...@@ -28,7 +36,7 @@ export default [
title: '支付成功', title: '支付成功',
success: true success: true
}, },
component: () => import('../pay/payResult') component: () => import('../views/pay/payResult')
}, },
{ {
path: '/vipLife', path: '/vipLife',
...@@ -53,28 +61,15 @@ export default [ ...@@ -53,28 +61,15 @@ export default [
title: '订单详情' title: '订单详情'
}, },
component: () => import('../views/orderDetail') component: () => import('../views/orderDetail')
},{ },
{
path: '/payWaiting', path: '/payWaiting',
name: 'payWaiting', name: 'payWaiting',
meta: { meta: {
title: '支付中', title: '支付中',
success: true success: true
}, },
component: () => import('../pay/payWaiting') component: () => import('../views/pay/payWaiting')
},
{
path: '/demo',
alias: ['/demo-page'],
name: 'demo-page',
back: false,
meta: {
title: 'DEMO',
has: {
header: true,
footer: true
}
},
component: () => import('../views/demo')
}, },
{ {
path: '/error', path: '/error',
......
...@@ -27,14 +27,11 @@ import { ...@@ -27,14 +27,11 @@ import {
Sticky, Sticky,
Tab, Tab,
Tabs, Tabs,
<<<<<<< HEAD Empty,
Empty
=======
CountDown, CountDown,
PwdField, PwdField,
AuthcodeField, AuthcodeField,
CouponList CouponList
>>>>>>> 支付开发
} from '@qg/cherry-ui'; } from '@qg/cherry-ui';
import DialogFn from '@qg/cherry-ui/src/dialog/func'; import DialogFn from '@qg/cherry-ui/src/dialog/func';
// import "@qg/cherry-ui/dist/cherry.css"; // import "@qg/cherry-ui/dist/cherry.css";
...@@ -64,14 +61,11 @@ Vue.use(Loading); ...@@ -64,14 +61,11 @@ Vue.use(Loading);
Vue.use(List); Vue.use(List);
Vue.use(Tab); Vue.use(Tab);
Vue.use(Tabs); Vue.use(Tabs);
<<<<<<< HEAD
Vue.use(Empty); Vue.use(Empty);
=======
Vue.use(CountDown); Vue.use(CountDown);
Vue.use(PwdField); Vue.use(PwdField);
Vue.use(AuthcodeField); Vue.use(AuthcodeField);
Vue.use(CouponList); Vue.use(CouponList);
>>>>>>> 支付开发
// const _proto = Vue.prototype; // const _proto = Vue.prototype;
// const proto = Object.create(_proto); // const proto = Object.create(_proto);
......
import HttpRequest from '@qg/ui-request'; import HttpRequest from '@qg/ui-request';
import { Toast } from '@qg/cherry-ui'; import { Toast } from '@qg/cherry-ui';
import store from '@/store'; import store from '@/store';
console.log(HttpRequest);
const http = new HttpRequest( const http = new HttpRequest(
{}, {},
{}, {},
...@@ -10,6 +11,5 @@ const http = new HttpRequest( ...@@ -10,6 +11,5 @@ const http = new HttpRequest(
function(loadingState) { function(loadingState) {
store.dispatch('change_loading', loadingState); store.dispatch('change_loading', loadingState);
} }
).getInstance(); );
export default http; export default http;
...@@ -314,12 +314,31 @@ export function idNoFormat(value) { ...@@ -314,12 +314,31 @@ export function idNoFormat(value) {
export function dateFormat(value) { export function dateFormat(value) {
return value.replace(/(\d{4})(\d{2})(\d{2})/, '$1.$2.$3'); return value.replace(/(\d{4})(\d{2})(\d{2})/, '$1.$2.$3');
} }
<<<<<<< HEAD
export function phoneFormat(value) { export function phoneFormat(mobile) {
return value.replace(/(\d{3})(\d{4})(\d{4})/, '$1 $2 $3'); /* 将手机号格式化 */
======= if (!mobile) return;
let value = mobile.replace(/\D/g, '').substr(0, 11); // 不允许输入非数字字符,超过11位数字截取前11位
let len = value.length;
if (len > 3 && len < 8) {
value = value.replace(/^(\d{3})/g, '$1 ');
} else if (len >= 8) {
value = value.replace(/^(\d{3})(\d{4})/g, '$1 $2 ');
}
return value;
}
export function checkPhoneFormat(mobile) {
/* 校验手机号格式 */
if (!mobile) return;
const reg = /^1(3[0-9]|4[5,7]|5[0,1,2,3,5,6,7,8,9]|6[2,5,6,7]|7[0,1,7,8]|8[0-9]|9[1,8,9])\d{8}$/;
return reg.test(mobile);
}
export function phoneTrim(mobile) {
if (!mobile) return;
return mobile.replace(/\s/g, '');
}
export function isObject(value) { export function isObject(value) {
return Object.prototype.toString.call(value) === '[object Object]'; return Object.prototype.toString.call(value) === '[object Object]';
>>>>>>> 支付开发
} }
<template>
<div class="center">
<cr-tabs
v-model="rechargeType"
background="#ffffff"
class="center-recharge"
@change="changeRechargeType"
>
<cr-tab title="话费充值" :title-style="tabItemStyle" name="recharge">
<PhoneRechargeList
:list="rechargeList.recharge"
:info="selectedRechargeInfo"
:three-col="true"
/>
</cr-tab>
<cr-tab title="话费慢冲" :title-style="tabItemStyle" name="slowRecharge">
<PhoneRechargeList
:list="rechargeList.slowRecharge"
:info="selectedRechargeInfo"
:three-col="true"
/></cr-tab>
</cr-tabs>
</div>
</template>
<script>
import api from '@/api/recharge.api';
import PhoneRechargeList from '../vipLife/components/SkuList.vue';
const { getSpuList, getSkuList } = api;
export default {
components: {
PhoneRechargeList
},
props: { info: Object },
data() {
return {
tabItemStyle: {
width: '75px',
flex: 'none'
},
rechargeList: {
recharge: [],
slowRecharge: []
},
rechargeTel: 'recharge',
selectedRechargeInfo: {}
};
},
async mounted() {
const [data] = await getSpuList();
if (data) {
this.vipLife = data.vipLife || [];
this.phoneRecharge = data.phoneRecharge || {};
this.userPhoneInfo = data.userPhoneInfo || {};
this.changeTelFormat(this.userPhoneInfo.phoneNo);
this.phoneNoHome = this.userPhoneInfo.phoneNoHome;
this.changeRechargeType('recharge');
}
},
methods: {
async changeRechargeType(name) {
const [data] = await getSkuList(
this.phoneRecharge[`${name}SpuNo`],
this.phoneRecharge[`${name}Type`]
);
this.rechargeList[name] = data.rechargeList || [];
},
handleSkuSelected(item) {
this.selectedRechargeInfo = item;
this.$emit('selectedRecherge', item);
}
}
};
</script>
<style lang="less">
@import './index';
</style>
.center {
height: 100%;
.top {
width: 100%;
height: 132px;
padding: 10px;
box-sizing: border-box;
background: url('../../assets/images/ellipse.png');
background-size: 100%;
background-repeat: no-repeat;
&-link {
text-align: right;
&-title {
.text-14();
width: 64px;
padding: 0 @padding-xs;
color: @white;
&-first {
border-right: 1px solid @white;
}
}
}
&-tabs {
position: relative;
height: 108px;
width: 351px;
box-sizing: border-box;
overflow: hidden;
margin: auto;
border-radius: 8px;
background: @white;
padding: @padding-xs @padding-sm;
top: 16px;
&-title {
.text-14();
font-weight: bold;
color: @black;
}
&-recharge {
display: flex;
margin-top: 10px;
overflow-x: auto;
overflow-y: hidden;
justify-content: space-between;
}
}
}
.recharge {
width: 55px;
height: 55px;
text-align: center;
&-name {
.text-12();
color: @gray-5;
}
}
.center {
width: 351px;
height: 451px;
box-sizing: border-box;
background: @white;
border-radius: 8px;
padding: 14px;
margin: auto;
margin-top: 50px;
&-phone {
border-bottom: 1px solid #dcdcdc;
.cr-cell__title {
display: none;
}
.cr-cell {
padding: @padding-xs 0;
font-size: 24px;
color: @black;
}
&-location {
.text-12();
color: @gray-5;
}
}
&-recharge {
height: 300px;
margin-top: @padding-xs;
margin-bottom: @padding-xs;
}
.button{
.text-18();
}
}
}
\ No newline at end of file
<template>
<div class="center">
<div class="top">
<div class="top-link">
<a href="#" class="top-link-title top-link-title-first" @click="goOrderList">充值订单</a>
<a href="#" class="top-link-title" @click="goHelper">联系客服</a>
</div>
<div class="top-tabs">
<p class="top-tabs-title">娱乐生活</p>
<div class="top-tabs-recharge">
<div v-for="life in vipLife" :key="life.type" class="recharge" @click="goVipLife(life)">
<cr-image width="34px" height="34px" :src="life.icon" />
<p class="recharge-name">{{ life.name }}</p>
</div>
</div>
</div>
</div>
<div class="center">
<p class="center-phone">
<span v-if="rechargeTel" class="center-phone-location"
>{{ isDefaultphone ? '默认号码' : '未知号码'
}}{{ phoneNoHome ? `(${phoneNoHome})` : '' }}</span
>
<cr-field
v-model="rechargeTel"
type="tel"
@input="changeTelFormat"
@blur="searchPhoneNoHome"
/>
</p>
<!-- <PhoneRecharge :info="phoneRecharge" /> -->
<cr-tabs
v-model="rechargeType"
background="#ffffff"
class="center-recharge"
@change="changeRechargeType"
>
<cr-tab title="话费充值" :title-style="tabItemStyle" name="recharge">
<PhoneRechargeList
:list="rechargeList.recharge"
:info="selectedRechargeInfo"
:three-col="true"
/>
</cr-tab>
<cr-tab title="话费慢冲" :title-style="tabItemStyle" name="slowRecharge">
<PhoneRechargeList
:list="rechargeList.slowRecharge"
:info="selectedRechargeInfo"
:three-col="true"
/></cr-tab>
</cr-tabs>
<cr-button
type="primary"
block
shape="circle"
:disabled="!disabled"
class="button"
@click="goOrder"
>
{{ selectedRechargeInfo.salePrice ? `¥${selectedRechargeInfo.salePrice}` : '' }}立即充值
</cr-button>
</div>
</div>
</template>
<script>
import { phoneFormat, phoneTrim, checkPhoneFormat } from '@/service/utils.service';
import api from '@/api/recharge.api';
import PhoneRechargeList from '../vipLife/components/SkuList.vue';
const { getSpuList, getPhoneHome, getSkuList } = api;
// 组件抽离
// 下订单
export default {
components: {
PhoneRechargeList
},
data() {
return {
vipLife: [],
phoneNoHome: '',
rechargeType: null,
rechargeAmount: 0,
tabItemStyle: {
width: '75px',
flex: 'none'
},
phoneRecharge: {},
userPhoneInfo: {},
rechargeList: {
recharge: [],
slowRecharge: []
},
rechargeTel: 'recharge',
selectedRechargeInfo: {}
};
},
computed: {
disabled: function() {
return (
this.rechargeTel &&
phoneTrim(this.rechargeTel).length === 11 &&
checkPhoneFormat(this.phoneNo) &&
this.selectedRechargeInfo.salePrice
);
},
isDefaultphone: function() {
return phoneTrim(this.rechargeTel) === this.userPhoneInfo.phoneNo;
},
phoneNo: function() {
return phoneTrim(this.rechargeTel);
}
},
created() {},
async mounted() {
const [data] = await getSpuList();
if (data) {
this.vipLife = data.vipLife || [];
this.phoneRecharge = data.phoneRecharge || {};
this.userPhoneInfo = data.userPhoneInfo || {};
this.changeTelFormat(this.userPhoneInfo.phoneNo);
this.phoneNoHome = this.userPhoneInfo.phoneNoHome;
this.changeRechargeType('recharge');
}
},
methods: {
changeTelFormat(phone) {
this.rechargeTel = phoneFormat(phone);
},
async searchPhoneNoHome() {
if (!this.phoneNo) return;
if (!checkPhoneFormat(this.phoneNo)) {
this.$toast.fail('请您输入正确的手机号');
}
const [data] = await getPhoneHome(this.phoneNo);
this.phoneNoHome = data.phoneNoHome;
},
async changeRechargeType(name) {
const [data] = await getSkuList(
this.phoneRecharge[`${name}SpuNo`],
this.phoneRecharge[`${name}Type`]
);
this.rechargeList[name] = data.rechargeList || [];
},
handleSkuSelected(item) {
this.selectedRechargeInfo = item;
},
goOrder() {},
goOrderList() {
this.$router.push({ name: 'orderList' });
},
goHelper() {},
goVipLife(spu) {
this.$router.push({
name: 'vipLife',
query: {
spuType: spu.type
}
});
}
}
};
</script>
<style lang="less">
@import './index';
</style>
...@@ -132,7 +132,7 @@ export default { ...@@ -132,7 +132,7 @@ export default {
margin-top: -12px; margin-top: -12px;
left: 50%; left: 50%;
margin-left: -12px; margin-left: -12px;
background: url('../../assets/images/addicon.png') no-repeat; background: url('../../../assets/images/addicon.png') no-repeat;
background-size: 100%; background-size: 100%;
} }
} }
......
<template> <template>
<div class="card"> <div class="card">
<div class="info"> <div class="info">
<cr-image width="63px" height="63px" class="info__image" src="../assets/images/paying.png" /> <cr-image
width="63px"
height="63px"
class="info__image"
src="../../assets/images/paying.png"
/>
<div class="info__desc"> <div class="info__desc">
<p class="info__text">{{ time }}s)支付中...</p> <p class="info__text">{{ time }}s)支付中...</p>
</div> </div>
...@@ -19,7 +24,7 @@ ...@@ -19,7 +24,7 @@
</template> </template>
<script> <script>
import { registeredEvents } from '@/service/sa.service'; import { registeredEvents } from '@/service/sa.service';
import { queryPayStatus } from '../api/pay.api'; import { queryPayStatus } from '@/api/pay.api';
export default { export default {
components: {}, components: {},
data() { data() {
......
...@@ -6,12 +6,13 @@ ...@@ -6,12 +6,13 @@
class="Vl__sku-item" class="Vl__sku-item"
:class="{ :class="{
cheap: item.price - item.salePrice > 0, cheap: item.price - item.salePrice > 0,
active: props.info.skuNo === item.skuNo active: props.info.skuNo === item.skuNo,
nohhird: (index + 1) % 3 !== 0
}" }"
@click="parent.handleSkuSelected(item, index)" @click="parent.handleSkuSelected(item, index)"
> >
<div class="Vl__sku-name">{{ item.skuName }}</div> <div class="Vl__sku-name">{{ props.threeCol ? item.salePrice : item.skuName }}</div>
<div class="Vl__sku-price">{{ item.salePrice }}</div> <div class="Vl__sku-price">售价{{ props.threeCol ? item.price : item.salePrice }}</div>
<div class="Vl__sku-tag">优惠</div> <div class="Vl__sku-tag">优惠</div>
</div> </div>
</div> </div>
...@@ -39,6 +40,7 @@ export default { ...@@ -39,6 +40,7 @@ export default {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: space-between; justify-content: space-between;
align-content: flex-start;
position: relative; position: relative;
z-index: 1; z-index: 1;
&.disabled::before { &.disabled::before {
...@@ -53,6 +55,12 @@ export default { ...@@ -53,6 +55,12 @@ export default {
background: rgba(255, 255, 255, 0.6); background: rgba(255, 255, 255, 0.6);
} }
&.three-col { &.three-col {
height: 250px;
justify-content: flex-start;
overflow: auto;
.nohhird {
margin-right: 4px;
}
.Vl__sku-item { .Vl__sku-item {
width: 103px; width: 103px;
} }
......
<template> <template>
<div class="page page__nopad"> <div class="page page__nopad">
<cr-tabs v-model="currentTab" @change="handleTabChange"> <cr-tabs v-model="currentTab" @change="handleTabChange">
<cr-tab v-for="(item, index) in spuData" :key="index" :title="item.name" :name="index" /> <cr-tab v-for="(item, index) in spuData" :key="index" :title="item.name" :name="+item.type" />
</cr-tabs> </cr-tabs>
<spu-list :list="spuList" :info="spuInfo" /> <spu-list :list="spuList" :info="spuInfo" />
<div class="Vl__panel"> <div class="Vl__panel">
...@@ -50,7 +50,7 @@ export default { ...@@ -50,7 +50,7 @@ export default {
return this.spuInfo.rechargeAccountType !== 2 && !this.account; return this.spuInfo.rechargeAccountType !== 2 && !this.account;
}, },
spuList() { spuList() {
return this.spuData[this.currentTab] ? this.spuData[this.currentTab].itemList : []; return this.spuData[this.currentTab - 1] ? this.spuData[this.currentTab - 1].itemList : [];
}, },
tips() { tips() {
return tipsData[this.spuInfo.spuNo]; return tipsData[this.spuInfo.spuNo];
...@@ -58,6 +58,7 @@ export default { ...@@ -58,6 +58,7 @@ export default {
}, },
mounted() { mounted() {
this.currentTab = +this.$route.query.spuType || 0; this.currentTab = +this.$route.query.spuType || 0;
console.log(this.currentTab);
this.$nextTick(() => { this.$nextTick(() => {
this.getList(); this.getList();
}); });
......
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