初始上传
This commit is contained in:
256
addon/pc/source/os/pages/auth/find.vue
Executable file
256
addon/pc/source/os/pages/auth/find.vue
Executable file
@@ -0,0 +1,256 @@
|
||||
<template>
|
||||
<div class="el-row-wrap find-pass">
|
||||
<ul>
|
||||
<li>
|
||||
<div>
|
||||
<p class="ns-bg-color">1</p>
|
||||
<p class="ns-text-color">输入手机号</p>
|
||||
</div>
|
||||
<span class="line-2 ns-border-color"></span>
|
||||
</li>
|
||||
<li id="current2">
|
||||
<span class="line-1" :class="step >= 2 ? 'ns-border-color' : 'ns-border-color-gray'"></span>
|
||||
<div>
|
||||
<p :class="step >= 2 ? 'ns-bg-color' : 'ns-bg-color-gray'">2</p>
|
||||
<p :class="step >= 2 ? 'ns-text-color' : 'ns-text-color-gray'">验证身份</p>
|
||||
</div>
|
||||
<span class="line-2" :class="step >= 2 ? 'ns-border-color' : 'ns-border-color-gray'"></span>
|
||||
</li>
|
||||
<li id="current3">
|
||||
<span class="line-1" :class="step >= 3 ? 'ns-border-color' : 'ns-border-color-gray'"></span>
|
||||
<div>
|
||||
<p :class="step >= 3 ? 'ns-bg-color' : 'ns-bg-color-gray'">3</p>
|
||||
<p :class="step >= 3 ? 'ns-text-color' : 'ns-text-color-gray'">重置密码</p>
|
||||
</div>
|
||||
<span class="line-2" :class="step >= 3 ? 'ns-border-color' : 'ns-border-color-gray'"></span>
|
||||
</li>
|
||||
<li id="current4">
|
||||
<span class="line-1" :class="step >= 4 ? 'ns-border-color' : 'ns-border-color-gray'"></span>
|
||||
<div>
|
||||
<p :class="step >= 4 ? 'ns-bg-color' : 'ns-bg-color-gray'">4</p>
|
||||
<p :class="step >= 4 ? 'ns-text-color' : 'ns-text-color-gray'">完成</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<el-row>
|
||||
<el-col :span="12" :offset="6">
|
||||
<div class="grid-content bg-purple">
|
||||
<el-form :model="formData" :rules="rules" ref="ruleForm" class="ns-forget-pass-form">
|
||||
<div class="ns-forget-pass">
|
||||
<template v-if="step == 1">
|
||||
<el-form-item prop="mobile" key="1">
|
||||
<el-input v-model="formData.mobile" placeholder="请输入注册手机号">
|
||||
<template slot="prepend">
|
||||
<i class="el-icon-mobile-phone"></i>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="nextStep('ruleForm')">下一步</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template v-else-if="step == 2">
|
||||
<el-form-item prop="vercode" key="2">
|
||||
<el-input v-model="formData.vercode" autocomplete="off" placeholder="请输入验证码" maxlength="4">
|
||||
<template slot="prepend">
|
||||
<i class="el-icon-picture-outline"></i>
|
||||
</template>
|
||||
<template slot="append">
|
||||
<img :src="captcha.img" mode class="captcha" @click="getCaptcha" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="dynacode" key="3">
|
||||
<el-input v-model="formData.dynacode" maxlength="4" autocomplete="off" placeholder="请输入短信动态码">
|
||||
<template slot="prepend">
|
||||
<i class="el-icon-mobile"></i>
|
||||
</template>
|
||||
<template slot="append">
|
||||
<div class="dynacode" :class="dynacodeData.seconds == 120 ? 'ns-text-color' : 'ns-text-color-gray'" @click="sendMobileCode('ruleForm')">
|
||||
{{ dynacodeData.codeText }}
|
||||
</div>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="nextStepToSetPass('ruleForm')">下一步</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template v-else-if="step == 3">
|
||||
<el-form-item prop="pass" key="4">
|
||||
<el-input v-model.trim="formData.pass" type="password" autocomplete="off" placeholder="请输入新的登录密码">
|
||||
<template slot="prepend">
|
||||
<i class="el-icon-lock"></i>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="repass" key="5">
|
||||
<el-input v-model.trim="formData.repass" type="password" autocomplete="off" placeholder="请再次输入新密码">
|
||||
<template slot="prepend">
|
||||
<i class="el-icon-lock"></i>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="resetPass('ruleForm')">重置密码</el-button>
|
||||
</el-form-item>
|
||||
</template>
|
||||
|
||||
<template v-else-if="step == 4">
|
||||
<span class="ns-reset-success">重置密码成功</span>
|
||||
<el-form-item>
|
||||
<router-link to="/auth/login">
|
||||
<el-button type="primary">重新登录</el-button>
|
||||
</router-link>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import find from '~/assets/js/auth/find.js';
|
||||
|
||||
export default {
|
||||
name: 'find_pass',
|
||||
layout: 'login',
|
||||
mixins: [find]
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.el-row-wrap {
|
||||
width: $width;
|
||||
margin: 0 auto;
|
||||
border: 1px solid #e5e5e5;
|
||||
|
||||
ul {
|
||||
margin: 50px auto 0;
|
||||
width: 1032px;
|
||||
height: 51px;
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
float: left;
|
||||
width: 258px;
|
||||
height: 51px;
|
||||
text-align: center;
|
||||
|
||||
div p:first-child {
|
||||
display: inline-block;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
color: #fff;
|
||||
border-radius: 28px;
|
||||
}
|
||||
|
||||
div p:nth-child(2) {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.line-1 {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 14px;
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
border-top: solid 2px;
|
||||
}
|
||||
|
||||
.line-2 {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 14px;
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
border-top: solid 2px;
|
||||
}
|
||||
|
||||
.ns-bg-color-gray {
|
||||
background-color: #b7b7b7;
|
||||
}
|
||||
|
||||
.ns-text-color-gray {
|
||||
color: #898989;
|
||||
}
|
||||
|
||||
.ns-border-color-gray {
|
||||
border-color: #e5e5e5 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-form {
|
||||
box-sizing: border-box;
|
||||
padding: 80px 0 50px;
|
||||
|
||||
.captcha {
|
||||
vertical-align: top;
|
||||
max-width: inherit;
|
||||
max-height: 38px;
|
||||
line-height: 38px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dynacode {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
[class*=' el-icon-'],
|
||||
[class^='el-icon-'] {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.ns-forget-pass {
|
||||
width: 60%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ns-reset-success {
|
||||
display: inline-block;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="scss">
|
||||
.find-pass {
|
||||
.ns-forget-pass-form {
|
||||
.el-form-item__error {
|
||||
/* 错误提示信息 */
|
||||
padding-left: 57px;
|
||||
}
|
||||
|
||||
.el-tabs__active-bar,
|
||||
.el-tabs__nav-wrap::after {
|
||||
/* 清除tab标签底部横线 */
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/* 立即注册 */
|
||||
.el-form-item__content {
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
403
addon/pc/source/os/pages/auth/login.vue
Executable file
403
addon/pc/source/os/pages/auth/login.vue
Executable file
@@ -0,0 +1,403 @@
|
||||
<template>
|
||||
<div class="ns-login-wrap" :style="{ background: backgroundColor }" v-loading="loadingAd" @keypress="keypress">
|
||||
<div class="el-row-wrap el-row-wrap-login">
|
||||
<el-row>
|
||||
<el-col :span="13">
|
||||
<el-carousel height="460px" class="ns-login-bg" @change="handleChange" v-if="adList.length">
|
||||
<el-carousel-item v-for="item in adList" :key="item.adv_id">
|
||||
<el-image :src="$img(item.adv_image)" fit="cover" @click="$util.pushToTab(item.adv_url.url)" />
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</el-col>
|
||||
<el-col :span="11" class="ns-login-form" style="float:right;margin-right:70px">
|
||||
<div class="grid-content bg-purple">
|
||||
<el-tabs v-model="activeName" @tab-click="handleClick">
|
||||
<el-tab-pane label="账号登录" name="first" v-if="registerConfig.login.indexOf('username') != -1">
|
||||
<el-form v-if="activeName == 'first'" :model="formData" :rules="accountRules" ref="ruleForm">
|
||||
<el-form-item prop="account">
|
||||
<el-input v-model="formData.account" placeholder="请输入账号">
|
||||
<template slot="prepend">
|
||||
<i class="iconfont icon-zhanghao"></i>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input type="password" v-model="formData.password" autocomplete="off" placeholder="请输入登录密码">
|
||||
<template slot="prepend">
|
||||
<i class="iconfont icon-mima"></i>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="vercode">
|
||||
<el-input v-model="formData.vercode" autocomplete="off" placeholder="请输入验证码" maxlength="4">
|
||||
<template slot="prepend">
|
||||
<i class="iconfont icon-yanzhengma"></i>
|
||||
</template>
|
||||
<template slot="append">
|
||||
<img :src="captcha.img" mode class="captcha" @click="getCaptcha" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-checkbox v-model="formData.checked">七天自动登录</el-checkbox>
|
||||
</el-col>
|
||||
<el-col :span="12" class="ns-forget-pass">
|
||||
<router-link to="/auth/find" class>忘记密码</router-link>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
<el-form-item style="margin-bottom: 18px;">
|
||||
<el-button type="primary" @click="accountLogin('ruleForm')">登录</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<div class="bg-purple-light" style="padding: 0 0 10px 0;" :style="wechatConfigStatus ? 'border-bottom: 1px solid #ebebeb' : ''">
|
||||
没有账号?
|
||||
<router-link to="/auth/register"><p style="color: #fd274a;">立即注册</p></router-link>
|
||||
<!-- <i class="iconfont icon-arrow-right"></i> -->
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-col :span="18" v-if="wechatConfigStatus">
|
||||
<div style="margin-left: 100px; margin-top: 20px; position: relative;" class="go-wx-login iconfont icon-weixin-copy" @click="weixinLogin()">
|
||||
<p style="font-size: 14px; text-indent: 10px; position: absolute;top: 1px;">使用微信扫码登录</p>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="手机动态码登录" name="second" v-if="registerConfig.login.indexOf('mobile') != -1">
|
||||
<el-form v-if="activeName == 'second'" :model="formData" :rules="mobileRules" ref="mobileRuleForm" class="ns-login-mobile">
|
||||
<el-form-item prop="mobile">
|
||||
<el-input v-model="formData.mobile" placeholder="请输入手机号">
|
||||
<template slot="prepend">
|
||||
<i class="iconfont icon-shouji-copy"></i>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="vercode">
|
||||
<el-input v-model="formData.vercode" autocomplete="off" placeholder="请输入验证码" maxlength="4">
|
||||
<template slot="prepend">
|
||||
<i class="iconfont icon-yanzhengma"></i>
|
||||
</template>
|
||||
<template slot="append">
|
||||
<img :src="captcha.img" mode class="captcha" @click="getCaptcha" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="dynacode">
|
||||
<el-input v-model="formData.dynacode" maxlength="4" placeholder="请输入短信动态码">
|
||||
<template slot="prepend">
|
||||
<i class="iconfont icon-dongtaima"></i>
|
||||
</template>
|
||||
<template slot="append">
|
||||
<div class="dynacode" :class="dynacodeData.seconds == 120 ? 'ns-text-color' : 'ns-text-color-gray'" @click="sendMobileCode('mobileRuleForm')">
|
||||
{{ dynacodeData.codeText }}
|
||||
</div>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="mobileLogin('mobileRuleForm')">登录</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-row>
|
||||
<el-col :span="24">
|
||||
<div class="bg-purple-light" style="padding: 0 0 10px 0;" :style="wechatConfigStatus ? 'border-bottom: 1px solid #ebebeb' : ''">
|
||||
<router-link to="/auth/register">立即注册</router-link>
|
||||
<i class="iconfont icon-arrow-right"></i>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-col :span="18" v-if="wechatConfigStatus">
|
||||
<div style="margin-left: 100px; margin-top: 20px; position: relative;" class="go-wx-login iconfont icon-weixin-copy" @click="weixinLogin()">
|
||||
<p style="font-size: 14px; text-indent: 10px; position: absolute;top: 1px;">使用微信扫码登录</p>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</el-col>
|
||||
<div class="wx-login" :class="ischecked == true ? 'wx-login-display' : ''">
|
||||
<p class="wx-login-title">微信扫码登录</p>
|
||||
<div class="qrcode"><img :src="img" /></div>
|
||||
<div style="display: flex;">
|
||||
<p class="iconfont icon-arrowLeft" @click="closeWx()"></p>
|
||||
<p class="wx-login-footer" @click="closeWx()">使用账号密码登录</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wx-login1" :class="ischecked1 == true ? 'wx-login-display1' : ''">
|
||||
<p class="wx-login-title1">扫码成功</p>
|
||||
|
||||
<el-col :span="11" class="ns-login-form ns-login-form2">
|
||||
<div class="grid-content bg-purple">
|
||||
<el-form :model="formData" :rules="wechatRules" ref="wechatRuleForm">
|
||||
<el-form-item prop="mobile">
|
||||
<el-input v-model="formData.mobile" placeholder="请输入手机号">
|
||||
<template slot="prepend">
|
||||
<i class="iconfont icon-shouji-copy"></i>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="vercode">
|
||||
<el-input v-model="formData.vercode" autocomplete="off" placeholder="请输入验证码" maxlength="4">
|
||||
<template slot="prepend">
|
||||
<i class="iconfont icon-yanzhengma"></i>
|
||||
</template>
|
||||
<template slot="append">
|
||||
<img :src="captcha.img" mode class="captcha" @click="getCaptcha" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="dynacode">
|
||||
<el-input v-model="formData.dynacode" maxlength="4" placeholder="请输入短信动态码">
|
||||
<template slot="prepend">
|
||||
<i class="iconfont icon-dongtaima"></i>
|
||||
</template>
|
||||
<template slot="append">
|
||||
<div class="dynacode" :class="dynacodeData.seconds == 120 ? 'ns-text-color' : 'ns-text-color-gray'" @click="sendWechatMobileCode('wechatRuleForm')">
|
||||
{{ dynacodeData.codeText }}
|
||||
</div>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="wechatLogin('wechatRuleForm')">确定</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<div class="go-wx-login iconfont" @click="closeWx1()">
|
||||
<p>使用其他方式登录</p>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<div class="bg-purple-light">
|
||||
<router-link to="/auth/register">立即注册</router-link>
|
||||
<i class="iconfont icon-arrow-right"></i>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-col>
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import login from '~/assets/js/auth/login.js';
|
||||
|
||||
export default {
|
||||
name: 'login',
|
||||
layout: 'login',
|
||||
mixins: [login]
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.icon-arrowLeft {
|
||||
line-height: 55px;
|
||||
font-size: 30px;
|
||||
margin-right: 10px;
|
||||
margin-left: 130px;
|
||||
}
|
||||
|
||||
.ns-login-wrap {
|
||||
width: 100%;
|
||||
height: 500px;
|
||||
min-width: $width;
|
||||
|
||||
.el-row-wrap-login {
|
||||
width: 1200px;
|
||||
margin: 0 auto;
|
||||
|
||||
.ns-login-bg {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.ns-login-form {
|
||||
width: 400px;
|
||||
margin-left: 50px;
|
||||
background: #ffffff;
|
||||
margin-top: 25px;
|
||||
|
||||
.el-form {
|
||||
.captcha {
|
||||
vertical-align: top;
|
||||
max-width: inherit;
|
||||
max-height: 38px;
|
||||
line-height: 38px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dynacode {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
[class*=' el-icon-'],
|
||||
[class^='el-icon-'] {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.grid-content {
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
.el-form-item__error {
|
||||
padding-left: 50px;
|
||||
}
|
||||
|
||||
button {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ns-forget-pass {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.bg-purple-light {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
|
||||
i {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
background-color: $base-color;
|
||||
color: #ffffff;
|
||||
font-size: 12px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ns-login-form2 {
|
||||
margin-left: 9px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon-weixin-copy {
|
||||
color: #09bb07;
|
||||
font-size: 26px;
|
||||
|
||||
p {
|
||||
font-size: 16px;
|
||||
color: #000;
|
||||
display: inline-block;
|
||||
padding-right: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.go-wx-login {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.wx-login-display {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.wx-login {
|
||||
width: 410px;
|
||||
height: 460px;
|
||||
background: #fff;
|
||||
position: absolute;
|
||||
top: 22px;
|
||||
right: 90px;
|
||||
z-index: 10;
|
||||
display: none;
|
||||
|
||||
.wx-login-title {
|
||||
text-align: center;
|
||||
margin-top: 30px;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
color: #fc183e;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 200px;
|
||||
margin: 45px 105px;
|
||||
}
|
||||
|
||||
.wx-login-footer {
|
||||
margin-top: 15px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.wx-login-display1 {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
.wx-login1 {
|
||||
width: 410px;
|
||||
height: 460px;
|
||||
background: #fff;
|
||||
position: absolute;
|
||||
top: 22px;
|
||||
right: 90px;
|
||||
z-index: 11;
|
||||
display: none;
|
||||
|
||||
.wx-login-title1 {
|
||||
text-align: center;
|
||||
margin-top: 30px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.wx-login-footer1 {
|
||||
margin-top: 15px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.ns-login-form {
|
||||
.el-form-item__error {
|
||||
/* 错误提示信息 */
|
||||
padding-left: 57px;
|
||||
}
|
||||
|
||||
.el-tabs__active-bar,
|
||||
.el-tabs__nav-wrap::after {
|
||||
/* 清除tab标签底部横线 */
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/* 立即注册 */
|
||||
.el-form-item__content {
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
787
addon/pc/source/os/pages/auth/register.vue
Executable file
787
addon/pc/source/os/pages/auth/register.vue
Executable file
@@ -0,0 +1,787 @@
|
||||
<template>
|
||||
<div class="register">
|
||||
<div class="box-card">
|
||||
<el-tabs v-model="activeName" @tab-click="handleClick">
|
||||
<el-tab-pane label="用户注册" name="first" v-if="registerConfig.register.indexOf('username') != -1">
|
||||
<el-form v-if="activeName == 'first'" :model="registerForm" :rules="registerRules" ref="registerRef" label-width="80px" label-position="right" show-message>
|
||||
<el-form-item label="用户名" prop="username">
|
||||
<el-input v-model="registerForm.username" placeholder="请输入用户名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="密码" prop="password">
|
||||
<el-input v-model="registerForm.password" placeholder="请输入密码" type="password"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码" prop="checkPass">
|
||||
<el-input v-model="registerForm.checkPass" placeholder="请输入确认密码" type="password"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="验证码" prop="code">
|
||||
<el-input v-model="registerForm.code" placeholder="请输入验证码" maxlength="4">
|
||||
<template slot="append">
|
||||
<img :src="captcha.img" mode class="captcha" @click="getCode" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="xy" @click="check">
|
||||
<div class="xy-wrap">
|
||||
<div class="iconfont" :class="ischecked ? 'icon-xuanze-duoxuan' : 'icon-xuanze'"></div>
|
||||
<div class="content">
|
||||
阅读并同意
|
||||
<b @click.stop="getAggrement">《服务协议》</b>
|
||||
</div>
|
||||
</div>
|
||||
<div class="toLogin" @click="toLogin">已有账号,立即登录</div>
|
||||
</div>
|
||||
<el-button @click="register">立即注册</el-button>
|
||||
</el-tab-pane>
|
||||
|
||||
<el-tab-pane label="手机动态码注册" name="second" v-if="registerConfig.register.indexOf('mobile') != -1">
|
||||
<el-form v-if="activeName == 'second'" :model="registerForm" :rules="mobileRules" ref="mobileRuleForm">
|
||||
<el-form-item prop="mobile">
|
||||
<el-input v-model="registerForm.mobile" placeholder="请输入手机号">
|
||||
<template slot="prepend">
|
||||
<i class="iconfont icon-shouji-copy"></i>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="vercode">
|
||||
<el-input v-model="registerForm.vercode" autocomplete="off" placeholder="请输入验证码" maxlength="4">
|
||||
<template slot="prepend">
|
||||
<i class="iconfont icon-yanzhengma"></i>
|
||||
</template>
|
||||
<template slot="append">
|
||||
<img :src="captcha.img" mode class="captcha" @click="getCode" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item prop="dynacode">
|
||||
<el-input v-model="registerForm.dynacode" maxlength="4" placeholder="请输入短信动态码">
|
||||
<template slot="prepend">
|
||||
<i class="iconfont icon-dongtaima"></i>
|
||||
</template>
|
||||
<template slot="append">
|
||||
<div class="dynacode" :class="dynacodeData.seconds == 120 ? 'ns-text-color' : 'ns-text-color-gray'" @click="sendMobileCode('mobileRuleForm')">
|
||||
{{ dynacodeData.codeText }}
|
||||
</div>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="xy" @click="check">
|
||||
<div class="xy-wrap">
|
||||
<div class="iconfont" :class="ischecked ? 'icon-xuanze-duoxuan' : 'icon-xuanze'"></div>
|
||||
<div class="content">
|
||||
阅读并同意
|
||||
<b @click.stop="getAggrement">《服务协议》</b>
|
||||
</div>
|
||||
</div>
|
||||
<div class="toLogin" @click="toLogin">已有账号,立即登录</div>
|
||||
</div>
|
||||
|
||||
<el-button @click="registerMobile">立即注册</el-button>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<el-dialog :title="agreement.title" :visible.sync="aggrementVisible" width="60%" :before-close="aggrementClose" :lock-scroll="false" center>
|
||||
<div v-html="agreement.content" class="xyContent"></div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
<!-- 浮层区 -->
|
||||
<div class="floatLayer-wrap" v-show="is_show && reward" :style="{ width: bgWidth, height: bgHeight }">
|
||||
<div class="reward-wrap">
|
||||
<img :src="$util.img('public/uniapp/register_reward/register_reward_img.png')" mode="widthFix" class="bg-img-head" />
|
||||
<img :src="$util.img('public/uniapp/register_reward/register_reward_money.png')" mode="widthFix" class="bg-img-money" />
|
||||
<img :src="$util.img('public/uniapp/register_reward/register_reward_head.png')" mode="widthFix" class="bg-img" />
|
||||
<div class="wrap">
|
||||
<div>
|
||||
<div class="reward-content">
|
||||
<div class="reward-item" v-if="reward && reward.point > 0">
|
||||
<div class="head">积分奖励</div>
|
||||
<div class="content">
|
||||
<div class="info">
|
||||
<div>
|
||||
<span class="num">{{ reward.point }}</span>
|
||||
<span class="type">积分</span>
|
||||
</div>
|
||||
<div class="desc">用于下单时抵现或兑换商品等</div>
|
||||
</div>
|
||||
<div class="tip" @click="closeRewardPopup('point')">立即查看</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="reward-item" v-if="reward && reward.growth > 0">
|
||||
<div class="head">成长值</div>
|
||||
<div class="content">
|
||||
<div class="info">
|
||||
<div>
|
||||
<span class="num">{{ reward.growth }}</span>
|
||||
<span class="type">成长值</span>
|
||||
</div>
|
||||
<div class="desc">用于提升会员等级</div>
|
||||
</div>
|
||||
<div class="tip" @click="closeRewardPopup('growth')">立即查看</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="reward-item" v-if="reward && reward.balance > 0">
|
||||
<div class="head">红包奖励</div>
|
||||
<div class="content">
|
||||
<div class="info">
|
||||
<div>
|
||||
<span class="num">{{ reward.balance }}</span>
|
||||
<span class="type">元</span>
|
||||
</div>
|
||||
<div class="desc">不可提现下单时可用</div>
|
||||
</div>
|
||||
<div class="tip" @click="closeRewardPopup('balance')">立即查看</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="reward-item" v-if="reward && reward.coupon_list.length > 0">
|
||||
<div class="head">优惠券奖励</div>
|
||||
<div class="content" v-for="(item, index) in reward.coupon_list" :key="index">
|
||||
<div class="info">
|
||||
<div>
|
||||
<span class="num coupon-name">{{ item.coupon_name }}</span>
|
||||
</div>
|
||||
<div class="desc" v-if="item.at_least > 0">满{{ item.at_least }}{{ item.type == 'discount' ? '打' + item.discount + '折' : '减' + item.money }}</div>
|
||||
<div class="desc" v-else>无门槛,{{ item.type == 'discount' ? '打' + item.discount + '折' : '减' + item.money }}</div>
|
||||
</div>
|
||||
<div class="tip" @click="closeRewardPopup('coupon')">立即查看</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="close-btn" @click="closeRewardPopup()"><i class="iconfont icon-guanbi"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {getRegisterAgreement, registerConfig, registerMobileCode, getRegisterReward} from '@/api/auth/register';
|
||||
import {captcha} from '@/api/website';
|
||||
|
||||
export default {
|
||||
name: 'register',
|
||||
layout: 'login',
|
||||
components: {},
|
||||
data() {
|
||||
var checkPassValidata = (rule, value, callback) => {
|
||||
if (value === '') {
|
||||
callback(new Error('请再次输入密码'));
|
||||
} else if (value !== this.registerForm.password) {
|
||||
callback(new Error('两次输入密码不一致!'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
let self = this;
|
||||
var passwordValidata = function (rule, value, callback) {
|
||||
let regConfig = self.registerConfig;
|
||||
if (!value) {
|
||||
return callback(new Error('请输入密码'));
|
||||
} else {
|
||||
if (regConfig.pwd_len > 0) {
|
||||
if (value.length < regConfig.pwd_len) {
|
||||
return callback(new Error('密码长度不能小于' + regConfig.pwd_len + '位'));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
if (regConfig.pwd_complexity != '') {
|
||||
let passwordErrorMsg = '密码需包含',
|
||||
reg = '';
|
||||
if (regConfig.pwd_complexity.indexOf('number') != -1) {
|
||||
reg += '(?=.*?[0-9])';
|
||||
passwordErrorMsg += '数字';
|
||||
} else if (regConfig.pwd_complexity.indexOf('letter') != -1) {
|
||||
reg += '(?=.*?[a-z])';
|
||||
passwordErrorMsg += '、小写字母';
|
||||
} else if (regConfig.pwd_complexity.indexOf('upper_case') != -1) {
|
||||
reg += '(?=.*?[A-Z])';
|
||||
passwordErrorMsg += '、大写字母';
|
||||
} else if (regConfig.pwd_complexity.indexOf('symbol') != -1) {
|
||||
reg += '(?=.*?[#?!@$%^&*-])';
|
||||
passwordErrorMsg += '、特殊字符';
|
||||
} else {
|
||||
reg += '';
|
||||
passwordErrorMsg += '';
|
||||
}
|
||||
reg = new RegExp(reg);
|
||||
if (reg.test(value)) {
|
||||
return callback(new Error(passwordErrorMsg));
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
var isMobile = (rule, value, callback) => {
|
||||
if (!value) {
|
||||
return callback(new Error('手机号不能为空'));
|
||||
} else {
|
||||
|
||||
if (/^\d{11}$/.test(value)) {
|
||||
callback();
|
||||
} else {
|
||||
callback(new Error('请输入正确的手机号'));
|
||||
}
|
||||
}
|
||||
};
|
||||
return {
|
||||
registerForm: {
|
||||
username: '',
|
||||
password: '',
|
||||
checkPass: '',
|
||||
code: '',
|
||||
mobile: '',
|
||||
vercode: '',
|
||||
dynacode: '',
|
||||
key: ''
|
||||
},
|
||||
registerRules: {
|
||||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入用户名',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
password: [
|
||||
{
|
||||
required: true,
|
||||
validator: passwordValidata,
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
checkPass: [
|
||||
{
|
||||
required: true,
|
||||
validator: checkPassValidata,
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
code: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入验证码',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
},
|
||||
mobileRules: {
|
||||
mobile: [
|
||||
{
|
||||
required: true,
|
||||
validator: isMobile,
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
vercode: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入验证码',
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
dynacode: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入短信动态码',
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
},
|
||||
dynacodeData: {
|
||||
seconds: 120,
|
||||
timer: null,
|
||||
codeText: '获取动态码',
|
||||
isSend: false
|
||||
}, // 动态码
|
||||
ischecked: false,
|
||||
agreement: '',
|
||||
aggrementVisible: false,
|
||||
captcha: {
|
||||
// 验证码
|
||||
id: '',
|
||||
img: ''
|
||||
},
|
||||
registerConfig: {
|
||||
register: ''
|
||||
},
|
||||
activeName: 'first', // tab切换
|
||||
reward: null,
|
||||
is_show: false,
|
||||
bgWidth: '',
|
||||
bgHeight: ''
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getCode();
|
||||
this.registerAggrement();
|
||||
this.getRegisterConfig();
|
||||
this.getRegisterReward();
|
||||
if (process.client) {
|
||||
this.bgWidth = document.documentElement.clientWidth + 'px';
|
||||
this.bgHeight = document.documentElement.clientHeight + 'px';
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: '注册-' + this.$store.state.site.siteInfo.site_name
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
closeRewardPopup(type) {
|
||||
this.is_show = false;
|
||||
|
||||
switch (type) {
|
||||
case 'point':
|
||||
this.$router.push('/member/my_point');
|
||||
break;
|
||||
case 'balance':
|
||||
this.$router.push('/member/account');
|
||||
break;
|
||||
case 'growth':
|
||||
this.$router.push('/member');
|
||||
break;
|
||||
case 'coupon':
|
||||
this.$router.push('/member/coupon');
|
||||
break;
|
||||
default:
|
||||
this.$router.push('/member');
|
||||
this.is_show = false;
|
||||
}
|
||||
},
|
||||
getRegisterReward() {
|
||||
getRegisterReward()
|
||||
.then(res => {
|
||||
if (res.code >= 0) {
|
||||
let data = res.data;
|
||||
if (data.is_use == 1 && (data.value.point > 0 || data.value.balance > 0 || data.value.growth > 0 || data.value.coupon_list.length > 0)) {
|
||||
this.reward = data.value;
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
sendMobileCode(formName) {
|
||||
if (this.dynacodeData.seconds != 120) return;
|
||||
this.$refs[formName].clearValidate('dynacode');
|
||||
|
||||
this.$refs[formName].validateField('mobile', valid => {
|
||||
if (valid) {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
this.$refs[formName].validateField('vercode', valid => {
|
||||
if (!valid) {
|
||||
registerMobileCode({
|
||||
mobile: this.registerForm.mobile,
|
||||
captcha_id: this.captcha.id,
|
||||
captcha_code: this.registerForm.vercode
|
||||
})
|
||||
.then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.registerForm.key = res.data.key;
|
||||
if (this.dynacodeData.seconds == 120 && this.dynacodeData.timer == null) {
|
||||
this.dynacodeData.timer = setInterval(() => {
|
||||
this.dynacodeData.seconds--;
|
||||
this.dynacodeData.codeText = this.dynacodeData.seconds + 's后可重新获取';
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
handleClick(tab, event) {
|
||||
},
|
||||
check() {
|
||||
this.ischecked = !this.ischecked;
|
||||
},
|
||||
toLogin() {
|
||||
this.$router.push('/auth/login');
|
||||
},
|
||||
// 获取注册配置
|
||||
getRegisterConfig() {
|
||||
registerConfig().then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.registerConfig = res.data.value;
|
||||
if (this.registerConfig.register == '') {
|
||||
this.$message({
|
||||
message: '平台未启用注册',
|
||||
type: 'warning',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({name: 'login', params: {third_party: true}});
|
||||
}
|
||||
});
|
||||
} else if (this.registerConfig.register.indexOf('username') != -1) {
|
||||
this.activeName = 'first';
|
||||
} else {
|
||||
this.activeName = 'second';
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
// 账号密码注册
|
||||
register() {
|
||||
this.$refs.registerRef.validate(valid => {
|
||||
if (valid) {
|
||||
if (!this.ischecked) {
|
||||
return this.$message({
|
||||
message: '请先阅读协议并勾选',
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
|
||||
var data = {
|
||||
username: this.registerForm.username.trim(),
|
||||
password: this.registerForm.password
|
||||
};
|
||||
|
||||
var user_test = /^[A-Za-z0-9]+$/;
|
||||
if (!user_test.test(data.username)) {
|
||||
return this.$message({
|
||||
message: '用户名只能输入数字跟英文',
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
|
||||
if (this.captcha.id != '') {
|
||||
data.captcha_id = this.captcha.id;
|
||||
data.captcha_code = this.registerForm.code;
|
||||
}
|
||||
this.$store
|
||||
.dispatch('member/register_token', data)
|
||||
.then(res => {
|
||||
if (res.code >= 0) {
|
||||
if (this.reward) {
|
||||
this.is_show = true;
|
||||
} else {
|
||||
this.$router.push('/member');
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
this.$message.error(err.message);
|
||||
this.getCode();
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
// 手机号注册
|
||||
registerMobile() {
|
||||
this.$refs.mobileRuleForm.validate(valid => {
|
||||
if (valid) {
|
||||
if (!this.ischecked) {
|
||||
return this.$message({
|
||||
message: '请先阅读协议并勾选',
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
var data = {
|
||||
mobile: this.registerForm.mobile,
|
||||
key: this.registerForm.key,
|
||||
code: this.registerForm.dynacode
|
||||
};
|
||||
if (this.captcha.id != '') {
|
||||
data.captcha_id = this.captcha.id;
|
||||
data.captcha_code = this.registerForm.code;
|
||||
}
|
||||
this.$store
|
||||
.dispatch('member/registerMobile_token', data)
|
||||
.then(res => {
|
||||
if (res.code >= 0) {
|
||||
if (this.reward) {
|
||||
this.is_show = true;
|
||||
} else {
|
||||
this.$router.push('/member');
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
this.$message.error(err.message);
|
||||
this.getCode();
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
aggrementClose() {
|
||||
this.aggrementVisible = false;
|
||||
},
|
||||
// 获取协议
|
||||
registerAggrement() {
|
||||
getRegisterAgreement().then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.agreement = res.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
getAggrement() {
|
||||
this.aggrementVisible = true;
|
||||
},
|
||||
// 获取验证码
|
||||
getCode() {
|
||||
captcha({
|
||||
captcha_id: 'this.captcha.id'
|
||||
})
|
||||
.then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.captcha = res.data;
|
||||
this.captcha.img = this.captcha.img.replace(/\r\n/g, '');
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.register {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.box-card {
|
||||
width: 500px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
background-color: #ffffff;
|
||||
padding: 0 30px 30px 30px;
|
||||
flex-direction: column;
|
||||
padding-bottom: 256px;
|
||||
|
||||
.register-title {
|
||||
border-bottom: 1px solid #f1f1f1;
|
||||
text-align: left;
|
||||
margin-bottom: 20px;
|
||||
font-size: 16px;
|
||||
color: $base-color;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.register-account {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.code {
|
||||
width: 80%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.el-form {
|
||||
margin: 0 30px;
|
||||
|
||||
.captcha {
|
||||
vertical-align: top;
|
||||
max-width: inherit;
|
||||
max-height: 38px;
|
||||
line-height: 38px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.xyContent {
|
||||
height: 600px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.xy {
|
||||
margin-left: 110px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
text-align: left;
|
||||
margin-right: 30px;
|
||||
|
||||
.toLogin {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.xy-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: $ns-font-size-base;
|
||||
cursor: pointer;
|
||||
|
||||
.iconfont {
|
||||
display: flex;
|
||||
align-content: center;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin-left: 3px;
|
||||
|
||||
b {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.icon-xuanze-duoxuan {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
|
||||
.el-button {
|
||||
margin: 20px 0 0 25px;
|
||||
background-color: $base-color;
|
||||
color: #ffffff;
|
||||
width: calc(100% - 60px);
|
||||
}
|
||||
}
|
||||
|
||||
.floatLayer-wrap {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: 999;
|
||||
position: absolute;
|
||||
|
||||
.reward-wrap {
|
||||
width: 400px;
|
||||
height: auto;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
.bg-img {
|
||||
width: 100%;
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.bg-img-head {
|
||||
position: absolute;
|
||||
top: -90px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.bg-img-money {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
left: -20px;
|
||||
top: 80px;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.wrap {
|
||||
width: calc(100% - 1px);
|
||||
height: 100%;
|
||||
background-color: #ef3030;
|
||||
margin-top: -40px;
|
||||
padding-bottom: 30px;
|
||||
border-bottom-left-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
|
||||
& > div {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
.reward-content {
|
||||
margin: 0 25px 0 25px;
|
||||
}
|
||||
|
||||
.reward-item {
|
||||
.head {
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
line-height: 1;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
padding: 8px 13px;
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
margin-bottom: 5px;
|
||||
width: auto;
|
||||
|
||||
.info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.tip {
|
||||
color: #ff222d;
|
||||
padding: 5px 0 5px 15px;
|
||||
width: 70px;
|
||||
letter-spacing: 1px;
|
||||
border-left: 1px dashed #e5e5e5;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.num {
|
||||
font-size: 26px;
|
||||
color: #ff222d;
|
||||
font-weight: bolder;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.coupon-name {
|
||||
font-size: 19px;
|
||||
}
|
||||
|
||||
.type {
|
||||
font-size: $ns-font-size-base;
|
||||
margin-left: 5px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.desc {
|
||||
margin-top: 4px;
|
||||
color: $base-color;
|
||||
font-size: $ns-font-size-base;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
position: absolute;
|
||||
width: calc(100% - 50px);
|
||||
bottom: 20px;
|
||||
left: 25px;
|
||||
|
||||
.btn-img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
|
||||
.iconfont {
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.clear {
|
||||
content: '';
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
</style>
|
||||
44
addon/pc/source/os/pages/close.vue
Executable file
44
addon/pc/source/os/pages/close.vue
Executable file
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<div class="error-wrap">
|
||||
<img src="@/assets/images/index/closed.png" />
|
||||
<!-- <i class="iconfont icon404"></i> -->
|
||||
<h2>{{ '网站已关闭' }}</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getSiteStatus } from '@/api/website';
|
||||
|
||||
export default {
|
||||
name: "close",
|
||||
created() {
|
||||
this.getSiteStatus();
|
||||
},
|
||||
layout: 'empty',
|
||||
methods:{
|
||||
getSiteStatus(){
|
||||
getSiteStatus().then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.$router.push('/');
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.error-wrap {
|
||||
text-align: center;
|
||||
padding: 40px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
i {
|
||||
font-size: 60px;
|
||||
}
|
||||
h2 {
|
||||
margin: 0 0 30px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
129
addon/pc/source/os/pages/cms/article/detail.vue
Executable file
129
addon/pc/source/os/pages/cms/article/detail.vue
Executable file
@@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<div class="article-wrap">
|
||||
<el-breadcrumb separator="/" class="path">
|
||||
<el-breadcrumb-item :to="{ path: '/' }" class="path-home">首页</el-breadcrumb-item>
|
||||
<el-breadcrumb-item :to="{ path: '/cms/article/list' }">文章列表</el-breadcrumb-item>
|
||||
<el-breadcrumb-item class="path-help">文章详情</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="article-detil" v-loading="loading">
|
||||
<div class="article-info">
|
||||
<div class="title">{{ info.article_title }}</div>
|
||||
<div class="flex-wrap">
|
||||
<div class="time">{{ $util.timeStampTurnTime(info.create_time) }}</div>
|
||||
<div class="num-wrap" v-if="info.is_show_read_num == 1">
|
||||
<img :src="$img('public/static/img/read.png')" />
|
||||
{{ info.initial_read_num + info.read_num }}
|
||||
</div>
|
||||
<div class="num-wrap" v-if="info.is_show_dianzan_num == 1">
|
||||
<img :src="$img('public/static/img/dianzan.png')" />
|
||||
<span>{{ info.initial_dianzan_num + info.dianzan_num }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content" v-html="info.article_content"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from 'vuex';
|
||||
import {articleDetail} from '@/api/cms/article';
|
||||
|
||||
export default {
|
||||
name: 'article_detail',
|
||||
data: () => {
|
||||
return {
|
||||
info: {},
|
||||
loading: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.id = this.$route.query.id;
|
||||
this.getDetail();
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['siteInfo'])
|
||||
},
|
||||
watch: {
|
||||
$route(curr) {
|
||||
this.id = curr.query.id;
|
||||
this.getDetail();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getDetail() {
|
||||
articleDetail({
|
||||
article_id: this.id
|
||||
}).then(res => {
|
||||
if (res.data) {
|
||||
this.info = res.data;
|
||||
this.loading = false;
|
||||
window.document.title = `${this.info.article_title} - ${this.siteInfo.site_name}`;
|
||||
} else {
|
||||
this.$router.push({
|
||||
path: '/cms/article/list'
|
||||
});
|
||||
}
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.article-wrap {
|
||||
width: $width;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
.article-detil {
|
||||
background-color: #ffffff;
|
||||
min-height: 300px;
|
||||
margin: 20px 0;
|
||||
padding: 10px;
|
||||
|
||||
.title {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.flex-wrap {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
|
||||
.time {
|
||||
text-align: center;
|
||||
color: #838383;
|
||||
}
|
||||
|
||||
.num-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #999;
|
||||
|
||||
img {
|
||||
margin-left: 25px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 3px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.article-info {
|
||||
margin: 0 43px;
|
||||
border-bottom: 1px dotted #e9e9e9;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding-top: 10px;
|
||||
margin: 0 65px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
275
addon/pc/source/os/pages/cms/article/list.vue
Executable file
275
addon/pc/source/os/pages/cms/article/list.vue
Executable file
@@ -0,0 +1,275 @@
|
||||
<template>
|
||||
<div class="article-wrap">
|
||||
<el-breadcrumb separator="/" class="path">
|
||||
<el-breadcrumb-item :to="{ path: '/' }" class="path-home">首页</el-breadcrumb-item>
|
||||
<el-breadcrumb-item class="path-help">文章</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="article" v-loading="loading">
|
||||
<div class="category-wrap">
|
||||
<div class="item" :class="{ 'ns-text-color': queryinfo.category_id == 0 }" @click="search(0)">全部</div>
|
||||
<div class="item" :class="{ 'ns-text-color': queryinfo.category_id == item.category_id }" v-for="item in categoryList" :key="item.category_id" @click="search(item.category_id)">{{ item.category_name }}</div>
|
||||
</div>
|
||||
<div class="list-wrap">
|
||||
<template v-if="articleList.length">
|
||||
<div class="item" v-for="(item, index) in articleList" :key="item.article_id" @click="toDetail(item.article_id)">
|
||||
<div class="info">
|
||||
<div class="title">{{ item.article_title }}</div>
|
||||
<div class="desc">{{ item.article_abstract }}</div>
|
||||
<div class="bottom-wrap">
|
||||
<div class="left" v-if="item.is_show_release_time == 1">
|
||||
<span>{{ $util.timeStampTurnTime(item.create_time) }}</span>
|
||||
</div>
|
||||
<div class="right">
|
||||
<div v-if="item.is_show_read_num == 1">
|
||||
<img :src="$img('public/static/img/read.png')" />
|
||||
{{ item.initial_read_num + item.read_num }}
|
||||
</div>
|
||||
<div v-if="item.is_show_dianzan_num == 1">
|
||||
<img :src="$img('public/static/img/dianzan.png')" />
|
||||
<span>{{ item.initial_dianzan_num + item.dianzan_num }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="img-wrap" v-if="item.cover_img">
|
||||
<img :src="$img(item.cover_img)" @error="imageError(index)" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="empty">暂无文章</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page">
|
||||
<el-pagination
|
||||
background
|
||||
:pager-count="5"
|
||||
:total="total"
|
||||
prev-text="上一页"
|
||||
next-text="下一页"
|
||||
:current-page.sync="queryinfo.page"
|
||||
:page-size.sync="queryinfo.page_size"
|
||||
@size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange"
|
||||
hide-on-single-page
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from 'vuex';
|
||||
import {articleCategoryList, getArticleList} from '@/api/cms/article';
|
||||
|
||||
export default {
|
||||
name: 'article',
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
queryinfo: {
|
||||
page: 1,
|
||||
page_size: 10,
|
||||
category_id: 0
|
||||
},
|
||||
categoryList: [],
|
||||
articleList: [],
|
||||
total: 0,
|
||||
loading: true
|
||||
};
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: '文章列表-' + this.$store.state.site.siteInfo.site_name
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getCategoryList();
|
||||
this.getList();
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultArticleImage'])
|
||||
},
|
||||
methods: {
|
||||
toDetail(id) {
|
||||
this.$router.push({
|
||||
path: '/cms/article/detail',
|
||||
query: {id: id}
|
||||
});
|
||||
},
|
||||
getCategoryList() {
|
||||
articleCategoryList().then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.categoryList = res.data;
|
||||
}
|
||||
});
|
||||
},
|
||||
search(category_id) {
|
||||
this.queryinfo.category_id = category_id;
|
||||
this.getList();
|
||||
},
|
||||
getList() {
|
||||
getArticleList(this.queryinfo).then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.articleList = res.data.list;
|
||||
this.total = res.data.count;
|
||||
}
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
},
|
||||
handlePageSizeChange(newsize) {
|
||||
this.queryinfo.page_size = newsize;
|
||||
this.getList();
|
||||
},
|
||||
handleCurrentPageChange(newnum) {
|
||||
this.queryinfo.page = newnum;
|
||||
this.getList();
|
||||
},
|
||||
imageError(index) {
|
||||
this.articleList[index].cover_img = '';
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.article-wrap {
|
||||
width: $width;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
.article {
|
||||
padding: 20px 0;
|
||||
min-height: 300px;
|
||||
display: flex;
|
||||
|
||||
.category-wrap {
|
||||
width: 210px;
|
||||
min-height: 300px;
|
||||
background: #ffffff;
|
||||
flex-shrink: 0;
|
||||
padding-left: 25px;
|
||||
padding-right: 10px;
|
||||
|
||||
.item {
|
||||
font-size: 15px;
|
||||
cursor: pointer;
|
||||
line-height: 40px;
|
||||
border-top: 1px solid #f1f1f1;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
height: 40px;
|
||||
background: #ffffff;
|
||||
|
||||
&:hover {
|
||||
color: $base-color;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-top: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-wrap {
|
||||
padding: 0 20px;
|
||||
margin-left: 20px;
|
||||
background-color: #fff;
|
||||
flex: 1;
|
||||
|
||||
.item {
|
||||
background: #fff;
|
||||
padding: 20px 0;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.info {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-weight: 600;
|
||||
font-size: 20px;
|
||||
word-break: break-all;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
|
||||
&:hover {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
|
||||
.desc {
|
||||
line-height: 29px;
|
||||
font-size: 16px;
|
||||
word-break: break-all;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
margin-top: 5px;
|
||||
color: #666;
|
||||
height: 55px;
|
||||
}
|
||||
|
||||
.bottom-wrap {
|
||||
display: flex;
|
||||
margin-top: 15px;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #eee;
|
||||
margin-right: 10px;
|
||||
|
||||
span {
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
& > div {
|
||||
margin-left: 25px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 3px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.img-wrap {
|
||||
display: flex;
|
||||
margin-left: 15px;
|
||||
|
||||
img {
|
||||
width: 256px;
|
||||
height: 160px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty {
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
line-height: 300px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
118
addon/pc/source/os/pages/cms/help/detail.vue
Executable file
118
addon/pc/source/os/pages/cms/help/detail.vue
Executable file
@@ -0,0 +1,118 @@
|
||||
<template>
|
||||
<div class="detail-wrap">
|
||||
<el-breadcrumb separator="/" class="path">
|
||||
<el-breadcrumb-item :to="{ path: '/' }" class="path-home">首页</el-breadcrumb-item>
|
||||
<el-breadcrumb-item :to="{ path: '/cms/help/list' }">帮助列表</el-breadcrumb-item>
|
||||
<el-breadcrumb-item class="path-help">帮助详情</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="help-detail" v-loading="loading">
|
||||
<div class="title" @click="toLink">{{ detail.title }}</div>
|
||||
<div class="info">
|
||||
<div class="time">{{ $util.timeStampTurnTime(detail.create_time) }}</div>
|
||||
</div>
|
||||
<div class="content" v-html="detail.content"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapGetters
|
||||
} from 'vuex';
|
||||
import {
|
||||
helpDetail
|
||||
} from '@/api/cms/help';
|
||||
|
||||
export default {
|
||||
name: 'help_detail',
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
detail: [],
|
||||
loading: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.id = this.$route.query.id;
|
||||
this.getDetail();
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['siteInfo'])
|
||||
},
|
||||
watch: {
|
||||
$route(curr) {
|
||||
this.id = curr.query.id;
|
||||
this.getDetail();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getDetail() {
|
||||
helpDetail({
|
||||
id: this.id
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
if (res.data) {
|
||||
this.loading = false;
|
||||
this.detail = res.data;
|
||||
|
||||
window.document.title = `${this.detail.title} - ${this.siteInfo.site_name}`;
|
||||
} else {
|
||||
this.$router.push({
|
||||
path: '/cms/help/list'
|
||||
});
|
||||
}
|
||||
}
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
},
|
||||
toLink() {
|
||||
if (this.detail.link_address) {
|
||||
window.open(this.detail.link_address);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.detail-wrap {
|
||||
width: 1210px;
|
||||
margin: 20px auto;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.path {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.help-detail {
|
||||
background-color: #ffffff;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
margin: 10px 0;
|
||||
|
||||
.title {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
margin: 10px 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.info {
|
||||
// margin: 0 43px;
|
||||
border-bottom: 1px dotted #e9e9e9;
|
||||
|
||||
.time {
|
||||
text-align: center;
|
||||
color: #838383;
|
||||
margin-bottom: 17px;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
padding-top: 10px;
|
||||
// margin: 0 65px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
195
addon/pc/source/os/pages/cms/help/list.vue
Executable file
195
addon/pc/source/os/pages/cms/help/list.vue
Executable file
@@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<div class="help-wrap">
|
||||
<el-breadcrumb separator="/" class="path">
|
||||
<el-breadcrumb-item :to="{ path: '/' }" class="path-home">首页</el-breadcrumb-item>
|
||||
<el-breadcrumb-item class="path-help">帮助</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="help" v-loading="loading">
|
||||
<div class="menu">
|
||||
<div class="title">帮助列表</div>
|
||||
<div class="item" v-for="(item, index) in helpList" :key="index">
|
||||
<div :class="currentId == item.class_id ? 'active item-name' : 'item-name'" @click="menuOther(item.class_id)">{{ item.class_name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-other">
|
||||
<div class="item-info">
|
||||
<div class="item" v-for="(item, index) in helpOther.list" :key="index" @click="detail(item.id)">
|
||||
<div class="item-title">{{ item.title }}</div>
|
||||
<div class="info">
|
||||
<div class="time">{{ $util.timeStampTurnTime(item.create_time) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
helpList,
|
||||
helpOther
|
||||
} from '@/api/cms/help';
|
||||
|
||||
export default {
|
||||
name: 'help',
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
helpList: [],
|
||||
helpOther: [],
|
||||
currentId: 0,
|
||||
loading: true
|
||||
};
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: '帮助列表-' + this.$store.state.site.siteInfo.site_name
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getInfo();
|
||||
},
|
||||
methods: {
|
||||
menuOther(id) {
|
||||
this.currentId = id;
|
||||
this.getHelpOtherInfo();
|
||||
},
|
||||
getInfo() {
|
||||
helpList().then(res => {
|
||||
if (res.code == 0 && res.data.length > 0) {
|
||||
this.currentId = res.data[0].class_id;
|
||||
this.helpList = res.data;
|
||||
this.getHelpOtherInfo();
|
||||
}
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
},
|
||||
getHelpOtherInfo() {
|
||||
helpOther({
|
||||
class_id: this.currentId
|
||||
}).then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.helpOther = res.data;
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
},
|
||||
detail(id) {
|
||||
this.$router.push({
|
||||
path: '/cms/help/detail',
|
||||
query: {
|
||||
id: id
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.help-wrap {
|
||||
background: #ffffff;
|
||||
width: 1210px;
|
||||
margin: 20px auto;
|
||||
|
||||
.path {
|
||||
padding: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.help {
|
||||
display: flex;
|
||||
padding-bottom: 20px;
|
||||
|
||||
.menu {
|
||||
width: 210px;
|
||||
min-height: 300px;
|
||||
background: #ffffff;
|
||||
border: 1px solid #f1f1ff;
|
||||
flex-shrink: 0;
|
||||
|
||||
.title {
|
||||
padding-left: 16px;
|
||||
background: #f8f8f8;
|
||||
font-size: $ns-font-size-base;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
cursor: pointer;
|
||||
color: #666666;
|
||||
}
|
||||
|
||||
.item-name {
|
||||
font-size: $ns-font-size-base;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
line-height: 40px;
|
||||
border-top: 1px solid #f1f1f1;
|
||||
padding-left: 25px;
|
||||
padding-right: 10px;
|
||||
height: 40px;
|
||||
background: #ffffff;
|
||||
color: #666666;
|
||||
|
||||
&:hover {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
|
||||
.active {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list-other {
|
||||
margin-left: 20px;
|
||||
width: 80%;
|
||||
|
||||
.item-info {
|
||||
padding: 10px;
|
||||
background-color: #ffffff;
|
||||
height: 300px;
|
||||
// border: 1px solid #e9e9e9;
|
||||
|
||||
.item {
|
||||
border-bottom: 1px #f1f1f1 solid;
|
||||
padding: 10px 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
padding-top: 0px;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
font-size: $ns-font-size-base;
|
||||
color: #333333;
|
||||
display: inline-block;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
padding-left: 5px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
104
addon/pc/source/os/pages/cms/notice/detail.vue
Executable file
104
addon/pc/source/os/pages/cms/notice/detail.vue
Executable file
@@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<div class="notice-wrap">
|
||||
<el-breadcrumb separator="/" class="path">
|
||||
<el-breadcrumb-item :to="{ path: '/' }" class="path-home">首页</el-breadcrumb-item>
|
||||
<el-breadcrumb-item :to="{ path: '/cms/notice/list' }">公告列表</el-breadcrumb-item>
|
||||
<el-breadcrumb-item class="path-help">公告详情</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="notice-detil" v-loading="loading">
|
||||
<div class="notice-info">
|
||||
<div class="title">{{ info.title }}</div>
|
||||
<div class="time">{{ $util.timeStampTurnTime(info.create_time) }}</div>
|
||||
</div>
|
||||
<div class="content" v-html="info.content"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from 'vuex';
|
||||
import {noticeDetail} from '@/api/cms/notice';
|
||||
|
||||
export default {
|
||||
name: 'notice_detail',
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
info: {},
|
||||
loading: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.id = this.$route.query.id;
|
||||
this.getDetail();
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['siteInfo'])
|
||||
},
|
||||
watch: {
|
||||
$route(curr) {
|
||||
this.id = curr.query.id;
|
||||
this.getDetail();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getDetail() {
|
||||
noticeDetail({
|
||||
id: this.id
|
||||
}).then(res => {
|
||||
if (res.data) {
|
||||
this.info = res.data;
|
||||
this.loading = false;
|
||||
window.document.title = `${this.info.title} - ${this.siteInfo.site_name}`;
|
||||
} else {
|
||||
this.$router.push({
|
||||
path: '/cms/notice/list'
|
||||
});
|
||||
}
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.notice-wrap {
|
||||
width: $width;
|
||||
margin: 0 auto 45px;
|
||||
}
|
||||
|
||||
.notice-detil {
|
||||
background-color: #ffffff;
|
||||
min-height: 300px;
|
||||
margin: 10px 0;
|
||||
padding: 10px;
|
||||
|
||||
.title {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
.time {
|
||||
text-align: center;
|
||||
color: #838383;
|
||||
margin-bottom: 17px;
|
||||
}
|
||||
|
||||
.notice-info {
|
||||
margin: 0 43px;
|
||||
border-bottom: 1px dotted #e9e9e9;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding-top: 10px;
|
||||
margin: 0 65px;
|
||||
}
|
||||
}
|
||||
|
||||
.path {
|
||||
padding: 15px 0;
|
||||
}
|
||||
</style>
|
||||
210
addon/pc/source/os/pages/cms/notice/list.vue
Executable file
210
addon/pc/source/os/pages/cms/notice/list.vue
Executable file
@@ -0,0 +1,210 @@
|
||||
<template>
|
||||
<div class="notice-wrap">
|
||||
<el-breadcrumb separator="/" class="path">
|
||||
<el-breadcrumb-item :to="{ path: '/' }" class="path-home">首页</el-breadcrumb-item>
|
||||
<el-breadcrumb-item class="path-help">公告</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
<div class="notice" v-loading="loading">
|
||||
<div class="menu">
|
||||
<div class="title">最新公告</div>
|
||||
<div class="item" v-for="item in noticeList" :key="item.id" @click="toDetail(item.id)">
|
||||
<div class="item-name">{{ item.title }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-wrap">
|
||||
<div class="notice-title">商城公告</div>
|
||||
<div class="list" v-for="item in noticeList" :key="item.id" @click="toDetail(item.id)">
|
||||
<div class="item">{{ item.title }}</div>
|
||||
<div class="info">
|
||||
<div class="time">{{ $util.timeStampTurnTime(item.create_time) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pager">
|
||||
<el-pagination
|
||||
background
|
||||
:pager-count="5"
|
||||
:total="total"
|
||||
prev-text="上一页"
|
||||
next-text="下一页"
|
||||
:current-page.sync="queryInfo.page"
|
||||
:page-size.sync="queryInfo.page_size"
|
||||
@size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange"
|
||||
hide-on-single-page
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {noticesList} from '@/api/cms/notice';
|
||||
|
||||
export default {
|
||||
name: 'notice',
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
queryInfo: {
|
||||
page: 1,
|
||||
page_size: 10,
|
||||
receiving_type: 'web'
|
||||
},
|
||||
noticeList: [],
|
||||
total: 0,
|
||||
loading: true
|
||||
};
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: '公告列表-' + this.$store.state.site.siteInfo.site_name
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getList();
|
||||
},
|
||||
methods: {
|
||||
toDetail(id) {
|
||||
this.$router.push({
|
||||
path: '/cms/notice/detail',
|
||||
query: {id: id}
|
||||
});
|
||||
},
|
||||
getList() {
|
||||
noticesList(this.queryInfo).then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.noticeList = res.data.list;
|
||||
this.total = res.data.count;
|
||||
}
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
},
|
||||
handlePageSizeChange(newsize) {
|
||||
this.queryInfo.page_size = newsize;
|
||||
this.getList();
|
||||
},
|
||||
handleCurrentPageChange(newnum) {
|
||||
this.queryInfo.page = newnum;
|
||||
this.getList();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.notice-wrap {
|
||||
width: $width;
|
||||
margin: 20px auto;
|
||||
|
||||
.path {
|
||||
padding: 15px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.notice {
|
||||
padding: 20px 0 45px;
|
||||
min-height: 300px;
|
||||
position: relative;
|
||||
display: flex;
|
||||
|
||||
.menu {
|
||||
width: 210px;
|
||||
min-height: 300px;
|
||||
background: #ffffff;
|
||||
border: 1px solid #f1f1ff;
|
||||
flex-shrink: 0;
|
||||
|
||||
.title {
|
||||
padding-left: 16px;
|
||||
background: #f8f8f8;
|
||||
font-size: $ns-font-size-base;
|
||||
height: 40px;
|
||||
cursor: pointer;
|
||||
color: #666666;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.item-name {
|
||||
font-size: $ns-font-size-base;
|
||||
cursor: pointer;
|
||||
line-height: 40px;
|
||||
border-top: 1px solid #f1f1f1;
|
||||
padding-left: 25px;
|
||||
padding-right: 10px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
height: 40px;
|
||||
background: #ffffff;
|
||||
color: #666666;
|
||||
|
||||
&:hover {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
|
||||
.active {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
|
||||
.list-wrap {
|
||||
padding: 0 40px;
|
||||
margin-left: 27px;
|
||||
border: 1px solid #f1f1f1;
|
||||
width: 100%;
|
||||
margin-bottom: 10px;
|
||||
background-color: #fff;
|
||||
|
||||
.notice-title {
|
||||
padding: 37px 0 20px 0;
|
||||
font-size: 18px;
|
||||
border-bottom: 1px dotted #e9e9e9;
|
||||
}
|
||||
|
||||
.list {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
&:last-of-type {
|
||||
border-bottom: initial;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.item {
|
||||
font-size: $ns-font-size-base;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
cursor: pointer;
|
||||
padding: 3px 0;
|
||||
|
||||
&:hover {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
font-size: $ns-font-size-base;
|
||||
|
||||
.time {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.page {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
213
addon/pc/source/os/pages/goods/brand.vue
Executable file
213
addon/pc/source/os/pages/goods/brand.vue
Executable file
@@ -0,0 +1,213 @@
|
||||
<template>
|
||||
<div class="ns-brand">
|
||||
<el-carousel height="400px" v-loading="loadingAd">
|
||||
<el-carousel-item v-for="item in adList" :key="item.adv_id">
|
||||
<el-image :src="$img(item.adv_image)" fit="cover" @click="$util.pushToTab(item.adv_url.url)" />
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
|
||||
<!-- 品牌列表 -->
|
||||
<div class="ns-brand-box" v-loading="loading">
|
||||
<div>
|
||||
<div class="ns-brand-title-wrap ns-text-align">
|
||||
<p class="ns-brand-title">品牌专区</p>
|
||||
<img src="@/assets/images/goods/split.png" alt="" />
|
||||
<p class="ns-brand-en">Brand zone</p>
|
||||
</div>
|
||||
|
||||
<div class="ns-brand-list" v-if="brandList.length > 0">
|
||||
<div class="ns-brand-li" v-for="(item, index) in brandList" :key="index" @click="$router.push({ path: '/goods/list', query: { brand_id: item.brand_id } })">
|
||||
<div class="ns-brand-wrap">
|
||||
<el-image fit="scale-down" :src="$img(item.image_url)" lazy @error="imageError(index)" />
|
||||
<p :title="item.brand_name">{{ item.brand_name }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="empty-wrap" v-if="brandList.length <= 0">
|
||||
<div class="ns-text-align">暂无更多品牌,去首页看看吧</div>
|
||||
</div>
|
||||
|
||||
<div class="pager">
|
||||
<el-pagination
|
||||
background
|
||||
:pager-count="5"
|
||||
:total="total"
|
||||
prev-text="上一页"
|
||||
next-text="下一页"
|
||||
:current-page.sync="currentPage"
|
||||
:page-size.sync="pageSize"
|
||||
@size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange"
|
||||
hide-on-single-page
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {brandPage} from '@/api/goods/goods';
|
||||
import {mapGetters} from 'vuex';
|
||||
import {adList} from '@/api/website';
|
||||
|
||||
export default {
|
||||
name: 'brand',
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 20,
|
||||
brandList: [],
|
||||
siteId: 0,
|
||||
loading: true,
|
||||
loadingAd: true,
|
||||
adList: []
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getAdList();
|
||||
this.getBrandList();
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultBrandImage', 'siteInfo'])
|
||||
},
|
||||
methods: {
|
||||
handlePageSizeChange(size) {
|
||||
this.pageSize = size;
|
||||
this.refresh();
|
||||
},
|
||||
handleCurrentPageChange(page) {
|
||||
this.currentPage = page;
|
||||
this.refresh();
|
||||
},
|
||||
refresh() {
|
||||
this.loading = true;
|
||||
this.getBrandList();
|
||||
},
|
||||
getBrandList() {
|
||||
brandPage({
|
||||
page_size: this.pageSize,
|
||||
page: this.currentPage,
|
||||
site_id: this.siteId
|
||||
}).then(res => {
|
||||
this.brandList = res.data.list;
|
||||
this.total = res.data.count;
|
||||
this.loading = false;
|
||||
window.document.title = `品牌专区 - ${this.siteInfo.site_name}`;
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 图片加载失败
|
||||
*/
|
||||
imageError(index) {
|
||||
this.brandList[index].image_url = this.defaultBrandImage;
|
||||
},
|
||||
getAdList() {
|
||||
adList({keyword: 'NS_PC_BRAND'}).then(res => {
|
||||
this.adList = res.data.adv_list;
|
||||
for (let i = 0; i < this.adList.length; i++) {
|
||||
if (this.adList[i].adv_url) this.adList[i].adv_url = JSON.parse(this.adList[i].adv_url);
|
||||
}
|
||||
this.loadingAd = false;
|
||||
}).catch(err => {
|
||||
this.loadingAd = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.ns-text-align {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.ns-brand-box {
|
||||
width: 100%;
|
||||
background: #ffffff;
|
||||
|
||||
> div {
|
||||
width: $width;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.ns-brand-title-wrap {
|
||||
padding-top: 54px;
|
||||
|
||||
.ns-brand-title {
|
||||
font-size: 26px;
|
||||
font-weight: 600;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.ns-brand-en {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
color: #383838;
|
||||
opacity: 0.2;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 5px;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.ns-brand-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding-top: 30px;
|
||||
|
||||
.ns-brand-li {
|
||||
width: 20%;
|
||||
padding: 8px 6px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.ns-brand-wrap {
|
||||
width: 100%;
|
||||
border: 1px solid #f1f1f1;
|
||||
overflow: hidden;
|
||||
color: #303133;
|
||||
padding: 15px;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
|
||||
.el-image {
|
||||
width: 100%;
|
||||
height: 120px;
|
||||
line-height: 120px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 22px;
|
||||
color: #383838;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty-wrap {
|
||||
margin-top: 30px;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss">
|
||||
.ns-brand {
|
||||
.el-carousel {
|
||||
.el-image__inner {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.el-carousel__arrow--right {
|
||||
right: 60px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
133
addon/pc/source/os/pages/goods/cart.vue
Executable file
133
addon/pc/source/os/pages/goods/cart.vue
Executable file
@@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<div class="cart" v-loading="loading">
|
||||
<template v-if="cartList.length || invalidGoods.length">
|
||||
<nav>
|
||||
<li>
|
||||
<el-checkbox v-model="checkAll" @change="allElection"></el-checkbox>
|
||||
</li>
|
||||
<li>商品信息</li>
|
||||
<li>价格</li>
|
||||
<li>数量</li>
|
||||
<li>小计</li>
|
||||
<li>操作</li>
|
||||
</nav>
|
||||
<div class="list" v-for="(siteItem, siteIndex) in cartList" :key="siteIndex">
|
||||
<div class="item">
|
||||
<!-- <div class="head">
|
||||
<el-checkbox v-model="siteItem.checked" @change="siteAllElection(siteIndex)"></el-checkbox>
|
||||
<router-link to="/shop" target="_blank">{{ siteItem.siteName }}</router-link>
|
||||
<el-tag size="small" v-if="siteItem.cartList[0].is_own == 1">自营</el-tag>
|
||||
</div> -->
|
||||
<ul v-for="(item, cartIndex) in siteItem.cartList" :key="cartIndex">
|
||||
<li>
|
||||
<el-checkbox v-model="item.checked" @change="singleElection(siteIndex, cartIndex)"></el-checkbox>
|
||||
</li>
|
||||
<li class="goods-info-wrap" @click="$util.pushToTab({ path: '/sku/' + item.sku_id })">
|
||||
<div class="img-wrap">
|
||||
<img class="img-thumbnail" :src="$img(item.sku_image, { size: 'mid' })" @error="imageError(siteIndex, cartIndex)" />
|
||||
</div>
|
||||
<div class="info-wrap">
|
||||
<h5>{{ item.sku_name }}</h5>
|
||||
<template v-if="item.sku_spec_format">
|
||||
<span v-for="(x, i) in item.sku_spec_format" :key="i">
|
||||
{{ x.spec_name }}:{{ x.spec_value_name }} {{ i < item.sku_spec_format.length - 1 ? ';' : '' }}
|
||||
</span>
|
||||
</template>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<span>¥{{ item.discount_price }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<el-input-number v-model="item.num" :step="modifyNum" size="mini" :min="item.min_buy>0 ? item.min_buy :1"
|
||||
:max="item.max_buy > 0 && item.max_buy < item.stock ? item.max_buy : item.stock"
|
||||
@change="cartNumChange($event, { siteIndex, cartIndex })"/>
|
||||
</li>
|
||||
<li>
|
||||
<strong class="subtotal ns-text-color" v-if="item.discount_price * item.num">¥{{ $util.filterPrice(item.discount_price * item.num) }}</strong>
|
||||
<strong class="subtotal ns-text-color" v-else>¥0</strong>
|
||||
</li>
|
||||
<li>
|
||||
<el-button type="text" @click="deleteCart(siteIndex, cartIndex)">删除</el-button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="lose-list" v-if="invalidGoods.length">
|
||||
<div class="head">
|
||||
失效商品
|
||||
<span class="ns-text-color">{{ invalidGoods.length }}</span>
|
||||
件
|
||||
</div>
|
||||
<ul v-for="(goodsItem, goodsIndex) in invalidGoods" :key="goodsIndex">
|
||||
<li>
|
||||
<el-tag size="small" type="info">失效</el-tag>
|
||||
</li>
|
||||
<li class="goods-info-wrap">
|
||||
<div class="img-wrap">
|
||||
<img class="img-thumbnail" :src="$img(goodsItem.sku_image, { size: 'mid' })" @error="imageErrorInvalid(goodsIndex)" />
|
||||
</div>
|
||||
<div class="info-wrap">
|
||||
<h5>{{ goodsItem.sku_name }}</h5>
|
||||
<template v-if="goodsItem.sku_spec_format">
|
||||
<span v-for="(x, i) in goodsItem.sku_spec_format" :key="i">
|
||||
{{ x.spec_name }}:{{ x.spec_value_name }}{{ i < goodsItem.sku_spec_format.length - 1 ? ';' : '' }}
|
||||
</span>
|
||||
</template>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<span>¥{{ goodsItem.discount_price }}</span>
|
||||
</li>
|
||||
<li>{{ goodsItem.num }}</li>
|
||||
<li>
|
||||
<strong class="subtotal">¥{{ $util.filterPrice(goodsItem.discount_price * goodsItem.num) }}</strong>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<el-checkbox v-model="checkAll" @change="allElection">全选</el-checkbox>
|
||||
<ul class="operation">
|
||||
<li>
|
||||
<el-button type="text" @click="deleteCartSelected">删除</el-button>
|
||||
</li>
|
||||
<li>
|
||||
<el-button type="text" @click="clearInvalidGoods" v-if="invalidGoods.length!=0">清除失效宝贝</el-button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="sum-wrap">
|
||||
<div class="selected-sum">
|
||||
<span>已选商品</span>
|
||||
<em class="total-count">{{ totalCount }}</em>
|
||||
<span>件</span>
|
||||
</div>
|
||||
<div class="price-wrap">
|
||||
<span>合计(不含运费):</span>
|
||||
<strong class="ns-text-color">¥{{ totalPrice }}</strong>
|
||||
</div>
|
||||
|
||||
<el-button type="primary" v-if="totalCount != 0" @click="settlement">结算</el-button>
|
||||
<el-button type="info" v-else disabled @click="settlement">结算</el-button>
|
||||
</div>
|
||||
</footer>
|
||||
</template>
|
||||
<div class="empty-wrap" v-else-if="!loading && (!cartList.length || !invalidGoods.length)">
|
||||
<img src="~assets/images/goods_empty.png">
|
||||
<router-link to="/">您的购物车是空的,赶快去逛逛,挑选商品吧!</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import cart from '@/assets/js/goods/cart';
|
||||
|
||||
export default {
|
||||
name: 'cart',
|
||||
mixins: [cart]
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/css/goods/cart.scss';
|
||||
</style>
|
||||
226
addon/pc/source/os/pages/goods/category.vue
Executable file
226
addon/pc/source/os/pages/goods/category.vue
Executable file
@@ -0,0 +1,226 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="newCategory" v-loading="loading">
|
||||
<div class="categoryLink">
|
||||
<ul id="categoryUl" :class="categoryFixed == true ? 'category-fixed' : ''">
|
||||
<li v-for="(item, index) in goodsCategory" :key="index" :class="index == clickIndex ? 'selected' : ''" @click="changeCate(index, '#category' + index)">
|
||||
<a>
|
||||
<span>{{ item.category_name }}</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="categoryCon">
|
||||
<div :id="'category' + index" :ref="'category' + index" class="items" :class="'items-' + index" v-for="(cate1, index) in goodsCategory" :key="index">
|
||||
<h2>
|
||||
<router-link :to="{ path: '/goods/list', query: { category_id: cate1.category_id, level: cate1.level } }" target="_blank">{{ cate1.category_name }}</router-link>
|
||||
</h2>
|
||||
|
||||
<dl v-for="(cate2, index) in cate1.child_list" :key="index">
|
||||
<dt>
|
||||
<router-link :to="{ path: '/goods/list', query: { category_id: cate2.category_id, level: cate2.level } }" target="_blank">{{ cate2.category_name }}</router-link>
|
||||
</dt>
|
||||
<dd>
|
||||
<router-link v-for="(cate3, index) in cate2.child_list" :key="index" :to="{ path: '/goods/list', query: { category_id: cate3.category_id, level: cate3.level } }" target="_blank">{{ cate3.category_name }}</router-link>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="empty-wrap" v-if="goodsCategory.length <= 0">
|
||||
<div class="ns-text-align">暂无商品分类</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {tree} from '@/api/goods/goodscategory';
|
||||
|
||||
export default {
|
||||
name: 'category',
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
goodsCategory: [],
|
||||
categoryFixed: false,
|
||||
clickIndex: 0,
|
||||
loading: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getGoodsCategory();
|
||||
},
|
||||
mounted() {
|
||||
window.addEventListener('scroll', this.handleScroll);
|
||||
},
|
||||
methods: {
|
||||
// 分类列表
|
||||
getGoodsCategory() {
|
||||
tree({
|
||||
level: 3,
|
||||
template: 2
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.goodsCategory = res.data;
|
||||
}
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message);
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
// 监听滚动条
|
||||
handleScroll() {
|
||||
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
|
||||
var offsetTop = document.querySelector('.newCategory').offsetTop;
|
||||
|
||||
if (scrollTop > offsetTop) {
|
||||
this.categoryFixed = true;
|
||||
} else {
|
||||
this.categoryFixed = false;
|
||||
}
|
||||
|
||||
var divTopArr = [];
|
||||
for (let i = 0; i < this.goodsCategory.length; i++) {
|
||||
var _top = this.$refs['category' + i][0].offsetTop;
|
||||
|
||||
divTopArr.push(_top);
|
||||
var _offset = scrollTop - offsetTop;
|
||||
if (_offset < divTopArr[divTopArr.length - 1]) {
|
||||
if (_offset >= divTopArr[i] && _offset < divTopArr[i + 1]) {
|
||||
this.clickIndex = i;
|
||||
}
|
||||
} else {
|
||||
this.clickIndex = divTopArr.length - 1;
|
||||
}
|
||||
}
|
||||
},
|
||||
// 点击左侧分类
|
||||
changeCate(index, obj) {
|
||||
this.clickIndex = index;
|
||||
document.querySelector(obj).scrollIntoView(true);
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
// 离开该页面需要移除这个监听的事件,不然会报错
|
||||
window.removeEventListener('scroll', this.handleScroll);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.newCategory {
|
||||
width: $width;
|
||||
margin: 0 auto;
|
||||
overflow: hidden;
|
||||
background-color: #fff;
|
||||
|
||||
.categoryLink {
|
||||
padding-top: 10px;
|
||||
float: left;
|
||||
position: relative;
|
||||
width: 210px;
|
||||
|
||||
ul {
|
||||
width: 210px;
|
||||
padding-top: 20px;
|
||||
background-color: #ffffff;
|
||||
|
||||
li {
|
||||
width: 200px;
|
||||
height: 30px;
|
||||
text-align: left;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 30px;
|
||||
color: #333;
|
||||
line-height: 30px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
margin: 0 auto 15px;
|
||||
|
||||
&.selected {
|
||||
background-color: $base-color;
|
||||
background: -moz-linear-gradient(45deg, $base-color 0%, #ffffff 100%);
|
||||
background: -webkit-gradient(45deg, color-stop(0%, $base-color), color-stop(100%, #ffffff));
|
||||
background: -webkit-linear-gradient(45deg, $base-color 0%, #ffffff 100%);
|
||||
background: -o-linear-gradient(45deg, $base-color 0%, #ffffff 100%);
|
||||
background: -ms-linear-gradient(45deg, $base-color 0%, #ffffff 100%);
|
||||
background: linear-gradient(45deg, $base-color 0%, #ffffff 100%);
|
||||
|
||||
a {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
display: block;
|
||||
margin-left: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.category-fixed {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
.categoryCon {
|
||||
float: left;
|
||||
padding: 0px 0 60px;
|
||||
overflow: hidden;
|
||||
width: 990px;
|
||||
position: relative;
|
||||
|
||||
.items {
|
||||
padding-left: 40px;
|
||||
|
||||
h2 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
line-height: 40px;
|
||||
margin-top: 30px;
|
||||
border-bottom: 1px solid transparent;
|
||||
}
|
||||
|
||||
dl {
|
||||
padding: 15px 0 5px;
|
||||
border-bottom: 1px solid #efefef;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
|
||||
dt {
|
||||
padding-right: 10px;
|
||||
width: 100px;
|
||||
position: relative;
|
||||
background: #fff;
|
||||
float: left;
|
||||
|
||||
a {
|
||||
float: left;
|
||||
max-width: 120px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
dd {
|
||||
a {
|
||||
color: #666;
|
||||
float: left;
|
||||
padding: 0 12px;
|
||||
margin: 0 0 10px -1px;
|
||||
border-left: 1px solid #e0e0e0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
518
addon/pc/source/os/pages/goods/coupon.vue
Executable file
518
addon/pc/source/os/pages/goods/coupon.vue
Executable file
@@ -0,0 +1,518 @@
|
||||
<template>
|
||||
<div class="ns-coupon">
|
||||
<div class="ns-coupon-info" v-if="adList.length">
|
||||
<div class="ns-coupon-wrap">
|
||||
<div class="coupon-name">
|
||||
<span class="ns-text-color">优惠券中心</span>
|
||||
<span class="ns-text-color-gray text12">省钱更多,领券更多</span>
|
||||
</div>
|
||||
<ul class="coupon-type clear-float">
|
||||
<li>
|
||||
<i></i>
|
||||
<span>限时抢券</span>
|
||||
</li>
|
||||
<li>
|
||||
<i></i>
|
||||
<span>叠加使用</span>
|
||||
</li>
|
||||
<li>
|
||||
<i></i>
|
||||
<span>种类多样</span>
|
||||
</li>
|
||||
</ul>
|
||||
<el-button @click="myCoupon">我的优惠券</el-button>
|
||||
</div>
|
||||
<div class="ns-coupon-img" v-loading="loadingAd">
|
||||
<el-carousel height="406px">
|
||||
<el-carousel-item v-for="item in adList" :key="item.adv_id">
|
||||
<el-image :src="$img(item.adv_image)" fit="cover" @click="$util.pushToTab(item.adv_url.url)" />
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</div>
|
||||
</div>
|
||||
<el-tabs>
|
||||
<div v-loading="loading">
|
||||
<ul class="ns-coupon-list">
|
||||
<li class="ns-bg-color ns-coupon-li" v-for="(item, index) in couponList" :key="index" :class="item.useState == 2 ? 'no-coupon' : '' ">
|
||||
<div class="describe">
|
||||
<template>
|
||||
<span v-if="!item.discount || item.discount == '0.00'">¥{{ item.money }}</span>
|
||||
<span v-else>{{ item.discount }}折</span>
|
||||
</template>
|
||||
<span>{{ activeName == 'first' ? item.coupon_name : item.platformcoupon_name }}</span>
|
||||
<span v-if="activeName == 'first'">
|
||||
{{item.goods_type_name}}
|
||||
</span>
|
||||
<template>
|
||||
<span v-if="item.at_least == '0.00'">无门槛优惠券</span>
|
||||
<span v-else>满{{ item.at_least }}可使用</span>
|
||||
</template>
|
||||
|
||||
<template>
|
||||
<span class="coupon-wrap-time" v-if="item.validity_type == 0">领取之日起{{ item.fixed_term }}日内有效</span>
|
||||
<span class="coupon-wrap-time" v-else-if="item.validity_type == 1">有效期至{{ $timeStampTurnTime(item.end_time) }}</span>
|
||||
<span class="coupon-wrap-time" v-else>长期有效</span>
|
||||
</template>
|
||||
</div>
|
||||
<div class="receive">
|
||||
<!-- 如果限领数为0 或者 领取数小于最大领取数 -->
|
||||
<a v-if="item.useState == 0" class="ns-text-color" @click="couponTap(item, index)">
|
||||
<span>立即领取</span>
|
||||
</a>
|
||||
<a v-if="item.useState == 1" class="ns-text-color" @click="couponTap(item, index)">
|
||||
<span>去使用</span>
|
||||
</a>
|
||||
<a v-if="!item.received_type && item.useState == 2" class="ns-text-color">
|
||||
<span>已抢光</span>
|
||||
</a>
|
||||
<a v-if="item.received_type == 'out'" class="ns-text-color">
|
||||
<span>已抢光</span>
|
||||
</a>
|
||||
<a v-if="item.received_type == 'expire'" class="ns-text-color">
|
||||
<span>已过期</span>
|
||||
</a>
|
||||
<a v-if="item.received_type == 'limit'" class="ns-text-color">
|
||||
<span>已达上限</span>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div class="empty-wrap" v-if="couponList.length <= 0">
|
||||
<div class="ns-text-align">暂无优惠券</div>
|
||||
</div>
|
||||
|
||||
<div class="pager">
|
||||
<el-pagination background :pager-count="5" :total="total" prev-text="上一页" next-text="下一页"
|
||||
:current-page.sync="currentPage" :page-size.sync="pageSize" @size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange" hide-on-single-page></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
couponTypeList,
|
||||
couponReceive
|
||||
} from '@/api/coupon';
|
||||
import {
|
||||
mapGetters
|
||||
} from 'vuex';
|
||||
import {
|
||||
adList
|
||||
} from '@/api/website';
|
||||
|
||||
export default {
|
||||
name: 'coupon',
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
couponList: [],
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 9,
|
||||
couponBtnSwitch: false,
|
||||
activeName: 'first',
|
||||
loading: true,
|
||||
loadingAd: true,
|
||||
adList: []
|
||||
};
|
||||
},
|
||||
created() {
|
||||
if (this.addonIsExit && this.addonIsExit.coupon != 1) {
|
||||
this.$message({
|
||||
message: '优惠券插件未安装',
|
||||
type: 'warning',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$route.push('/');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.getAdList();
|
||||
this.getCanReceiveCouponQuery();
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['addonIsExit'])
|
||||
},
|
||||
watch: {
|
||||
addonIsExit() {
|
||||
if (this.addonIsExit.coupon != 1) {
|
||||
this.$message({
|
||||
message: '优惠券插件未安装',
|
||||
type: 'warning',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$route.push('/');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: '领券专区-' + this.$store.state.site.siteInfo.site_name,
|
||||
meta: [{
|
||||
name: 'description',
|
||||
content: this.$store.state.site.siteInfo.seo_description
|
||||
}, {
|
||||
name: 'keyword',
|
||||
content: this.$store.state.site.siteInfo.seo_keywords
|
||||
}]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getAdList() {
|
||||
adList({
|
||||
keyword: 'NS_PC_COUPON'
|
||||
}).then(res => {
|
||||
this.adList = res.data.adv_list;
|
||||
for (let i = 0; i < this.adList.length; i++) {
|
||||
if (this.adList[i].adv_url) this.adList[i].adv_url = JSON.parse(this.adList[i].adv_url);
|
||||
}
|
||||
this.loadingAd = false;
|
||||
}).catch(err => {
|
||||
this.loadingAd = false;
|
||||
});
|
||||
},
|
||||
handleClick(tab, event) {
|
||||
this.loading = true;
|
||||
// (this.currentPage = 1), this.getCanReceiveCouponQuery();
|
||||
},
|
||||
/**
|
||||
* 我的优惠券
|
||||
*/
|
||||
myCoupon() {
|
||||
this.$util.pushToTab('/member/coupon');
|
||||
},
|
||||
/**
|
||||
* 获取优惠券列表
|
||||
*/
|
||||
getCanReceiveCouponQuery() {
|
||||
couponTypeList({
|
||||
page: this.currentPage,
|
||||
page_size: this.pageSize,
|
||||
activeName: this.activeName
|
||||
}).then(res => {
|
||||
this.couponList = res.data.list;
|
||||
this.total = res.data.count;
|
||||
this.couponList.forEach(v => {
|
||||
if (v.count == v.lead_count) v.useState = 2;
|
||||
else if (v.max_fetch != 0 && v.member_coupon_num && v.member_coupon_num >= v.max_fetch) v.useState = 1;
|
||||
else v.useState = 0;
|
||||
|
||||
if(v.received_type && v.received_type == 'expire'){
|
||||
v.useState = 2;
|
||||
}
|
||||
});
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
},
|
||||
handlePageSizeChange(size) {
|
||||
this.pageSize = size;
|
||||
this.loading = true;
|
||||
this.getCanReceiveCouponQuery();
|
||||
},
|
||||
handleCurrentPageChange(page) {
|
||||
this.currentPage = page;
|
||||
this.loading = true;
|
||||
this.getCanReceiveCouponQuery();
|
||||
},
|
||||
/**
|
||||
* 点击优惠券
|
||||
*/
|
||||
couponTap(item, index) {
|
||||
if (item.useState == 0) this.receiveCoupon(item, index);
|
||||
else this.toGoodsList(item);
|
||||
},
|
||||
/**
|
||||
* 领取优惠券
|
||||
*/
|
||||
receiveCoupon(item, index) {
|
||||
if (this.couponBtnSwitch) return;
|
||||
this.couponBtnSwitch = true;
|
||||
|
||||
var data = {
|
||||
site_id: item.site_id,
|
||||
activeName: this.activeName
|
||||
};
|
||||
data.coupon_type_id = item.coupon_type_id;
|
||||
|
||||
couponReceive(data).then(res => {
|
||||
var data = res.data;
|
||||
let msg = res.message;
|
||||
if (res.code == 0) {
|
||||
msg = '领取成功';
|
||||
this.$message({
|
||||
message: msg,
|
||||
type: 'success'
|
||||
});
|
||||
} else {
|
||||
this.$message({
|
||||
message: msg,
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
let list = this.couponList;
|
||||
if (res.data.is_exist == 1) {
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
if (this.activeName == 'first') {
|
||||
if (list[i].coupon_type_id == item.coupon_type_id) {
|
||||
list[i].useState = 1;
|
||||
}
|
||||
} else {
|
||||
if (list[i].platformcoupon_type_id == item.platformcoupon_type_id) {
|
||||
list[i].useState = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
if (this.activeName == 'first') {
|
||||
if (list[i].coupon_type_id == item.coupon_type_id) {
|
||||
list[i].received_type = res.data.type;
|
||||
list[i].useState = 2;
|
||||
}
|
||||
} else {
|
||||
if (list[i].platformcoupon_type_id == item.platformcoupon_type_id) {
|
||||
list[i].useState = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.couponBtnSwitch = false;
|
||||
this.$forceUpdate();
|
||||
}).catch(err => {
|
||||
if (err.message == '您尚未登录,请先进行登录') {
|
||||
this.$router.push('/auth/login');
|
||||
} else {
|
||||
this.$message.error(err.message)
|
||||
}
|
||||
this.couponBtnSwitch = false;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 去购买
|
||||
*/
|
||||
toGoodsList(item) {
|
||||
if (this.activeName == 'first') {
|
||||
if (item.goods_type != 1) {
|
||||
this.$router.push({
|
||||
path: '/goods/list',
|
||||
query: {
|
||||
coupon: item.coupon_type_id
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.$router.push({
|
||||
path: '/goods/list',
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.$router.push('/goods/list');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.empty-wrap {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.ns-coupon {
|
||||
width: $width;
|
||||
padding: 20px 0;
|
||||
margin: 0 auto;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.ns-coupon-info {
|
||||
background: url(../../assets/images/coupon-bg.png) no-repeat;
|
||||
background-size: cover;
|
||||
width: 100%;
|
||||
height: 450px;
|
||||
display: flex;
|
||||
|
||||
.ns-coupon-wrap {
|
||||
width: 320px;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
|
||||
.coupon-name {
|
||||
margin: 45px 0 50px;
|
||||
|
||||
span:nth-child(1) {
|
||||
display: block;
|
||||
line-height: 45px;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.ns-text-color-gray {
|
||||
color: #898989 !important;
|
||||
}
|
||||
|
||||
.text12 {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.coupon-type {
|
||||
margin-left: 20px;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
width: 80px;
|
||||
height: 100px;
|
||||
|
||||
i {
|
||||
display: block;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin: 8px auto;
|
||||
}
|
||||
|
||||
&:nth-child(1) i {
|
||||
background: url(../../assets/images/limited_time.png) no-repeat center;
|
||||
}
|
||||
|
||||
&:nth-child(2) i {
|
||||
background: url(../../assets/images/superposition.png) no-repeat center;
|
||||
}
|
||||
|
||||
&:nth-child(3) i {
|
||||
background: url(../../assets/images/coupon_type.png) no-repeat center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-button {
|
||||
width: 200px;
|
||||
background-color: $base-color;
|
||||
color: #fff;
|
||||
margin-top: 70px;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.ns-coupon-img {
|
||||
width: 850px;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.el-carousel__item:nth-child(2n) {
|
||||
background-color: #99a9bf;
|
||||
}
|
||||
|
||||
.el-carousel__item:nth-child(2n + 1) {
|
||||
background-color: #d3dce6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-tabs {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.ns-coupon-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
padding: 0 20px;
|
||||
|
||||
.ns-coupon-li {
|
||||
background: url(../../assets/images/list_bj.png) no-repeat;
|
||||
width: 32%;
|
||||
height: 169px;
|
||||
margin-bottom: 20px;
|
||||
margin-right: 2%;
|
||||
background-size: cover;
|
||||
|
||||
&.no-coupon {
|
||||
|
||||
background: url(../../assets/images/no_coupon.png) no-repeat !important;
|
||||
background-color: #e6e6e6 !important;
|
||||
|
||||
.describe {
|
||||
color: #999 !important;
|
||||
}
|
||||
|
||||
.receive {
|
||||
.ns-text-color {
|
||||
color: #999 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.describe {
|
||||
float: left;
|
||||
width: 250px;
|
||||
height: inherit;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
|
||||
span {
|
||||
display: block;
|
||||
}
|
||||
|
||||
span:nth-child(1) {
|
||||
font-size: 40px;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 3px;
|
||||
line-height: 50px;
|
||||
}
|
||||
|
||||
span:nth-child(3),
|
||||
span:nth-child(4),
|
||||
span:nth-child(5) {
|
||||
font-size: 12px;
|
||||
margin-left: 15px;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.receive {
|
||||
float: right;
|
||||
width: 95px;
|
||||
height: inherit;
|
||||
text-align: center;
|
||||
|
||||
a {
|
||||
display: inline-block;
|
||||
width: 30px;
|
||||
height: 120px;
|
||||
line-height: 120px;
|
||||
padding: 0 5px;
|
||||
margin-top: 25px;
|
||||
background-color: #fff;
|
||||
border-radius: 15px;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
line-height: 20px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(3n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
704
addon/pc/source/os/pages/goods/list.vue
Executable file
704
addon/pc/source/os/pages/goods/list.vue
Executable file
@@ -0,0 +1,704 @@
|
||||
<template>
|
||||
<div class="goods-container">
|
||||
<div class="goods-list" v-loading="loading">
|
||||
<!-- 搜索关键字 -->
|
||||
<div class="goods-nav" v-if="keyword">
|
||||
<router-link to="/">首页</router-link>
|
||||
<span>/</span>
|
||||
<span class="keyword">{{ keyword }}</span>
|
||||
</div>
|
||||
<div class="goods-nav" v-else-if="catewords">
|
||||
<router-link to="/">首页</router-link>
|
||||
<span>/</span>
|
||||
<router-link :to="{ path: '/goods/list', query: $util.handleLink({ category_id: first_index, level: 1, brand_id: filters.brand_id }) }">{{ catewords.split('$_SPLIT_$')[0] }}</router-link>
|
||||
<span v-if="(filters.category_level == 2 || filters.category_level == 3) && catewords.split('$_SPLIT_$')[1]">/</span>
|
||||
<span v-if="(filters.category_level == 2 || filters.category_level == 3) && catewords.split('$_SPLIT_$')[1]" class="keyword">{{ catewords.split('$_SPLIT_$')[1] }}</span></div>
|
||||
|
||||
<!-- 品牌过滤记录区 -->
|
||||
<div class="attr_filter" v-if="choosedBrand">
|
||||
<el-tag type="info" closable @close="closeBrand" effect="plain">
|
||||
<span v-if="choosedBrand" class="title">品牌:</span>
|
||||
{{ choosedBrand.brand_name }}
|
||||
</el-tag>
|
||||
</div>
|
||||
<div class="goods-screen-wrap">
|
||||
<div v-if="!keyword" class="goods-screen-item classify-info">
|
||||
<span class="screen-item-name">分类:</span>
|
||||
<ul class="screen-item-content">
|
||||
<li :class="{ active: categoryAll.isAllow && (categoryAll.id == 0 || categoryAll.id == filters.category_id) }">
|
||||
<router-link :to="{ path: '/goods/list', query: $util.handleLink({ category_id: categoryAll.id, level: categoryAll.level, brand_id: filters.brand_id }) }">全部</router-link>
|
||||
</li>
|
||||
<li v-for="item in categoryList" :class="{ active: item.category_id == selectCategoryId }">
|
||||
<router-link :to="{ path: '/goods/list', query: $util.handleLink({ category_id: item.category_id, level: item.level, brand_id: filters.brand_id }) }">{{ item.category_name }}</router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- 品牌 -->
|
||||
<div class="brand" v-if="brandList.length > 0">
|
||||
<div class="table_head">品牌:</div>
|
||||
<div class="table_body" :class="{ 'more' : isShowMoreBrand }">
|
||||
<!-- <div class="initial">
|
||||
<span type="info" effect="plain" hit @mouseover="handleChangeInitial('')">所有品牌</span>
|
||||
<span type="info" effect="plain" hit v-for="item in brandInitialList" :key="item" @mouseover="handleChangeInitial(item)">{{ (item || '').toUpperCase() }}</span>
|
||||
</div> -->
|
||||
<el-card v-for="item in brandList" :key="item.id" body-style="padding: 0;height: 100%;" shadow="hover" v-show="currentInitial === '' || item.brand_initial === currentInitial" class="brand-item">
|
||||
<el-image :src="$img(item.image_url || defaultGoodsImage)" :alt="item.brand_name" :title="item.brand_name" fit="contain" @click="onChooseBrand(item)" />
|
||||
</el-card>
|
||||
</div>
|
||||
<div class="more-wrap" v-if="brandList.length>14" @click="isShowMoreBrand=!isShowMoreBrand">
|
||||
{{ isShowMoreBrand ? '收起' : '更多' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="goods-screen-item other-screen-info">
|
||||
<span class="screen-item-name">筛选:</span>
|
||||
<div class="screen-item-content">
|
||||
<div class="item" @click="changeSort('')">
|
||||
<div class="item-name">综合</div>
|
||||
</div>
|
||||
<div :class="['item', 'search-arrow', salesArrowDirection]" @click="changeSort('sale_num')">销量</div>
|
||||
<div :class="['item', 'search-arrow', priceArrowDirection]" @click="changeSort('discount_price')">价格</div>
|
||||
<div class="item-other">
|
||||
<el-checkbox label="包邮" v-model="is_free_shipping"></el-checkbox>
|
||||
</div>
|
||||
<div class="input-wrap">
|
||||
<div class="price_range">
|
||||
<el-input placeholder="最低价格" v-model="filters.min_price"></el-input>
|
||||
<span>—</span>
|
||||
<el-input placeholder="最高价格" v-model="filters.max_price"></el-input>
|
||||
</div>
|
||||
<el-button plain size="mini" @click="handlePriceRange">确定</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="list-wrap">
|
||||
<!-- <div class="goods-recommended" v-if="goodsList.length">
|
||||
<goods-recommend :page-size="goodsList.length < 5 ? 2 : 5" />
|
||||
</div> -->
|
||||
<div class="list-right">
|
||||
<!-- 排序筛选区 -->
|
||||
<div class="cargo-list" v-if="goodsList.length">
|
||||
<div class="goods-info">
|
||||
<div class="item" v-for="(item, index) in goodsList" :key="item.goods_id" @click="$router.push({ path: '/sku/' + item.sku_id })">
|
||||
<img class="img-wrap" :src="$img(item.goods_image, { size: 'mid' })" @error="item.goods_image = defaultGoodsImage" />
|
||||
<div class="price-wrap">
|
||||
<div class="price">
|
||||
<span>¥</span>
|
||||
<span>{{ showPrice(item) }}</span>
|
||||
<div class="price-icon-wrap">
|
||||
<img v-if="item.member_price && item.member_price == showPrice(item)" :src="$img('public/uniapp/index/VIP.png')" />
|
||||
<img v-else-if="item.promotion_type == 1" :src="$img('public/uniapp/index/discount.png')" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="parseInt(item.market_price)" class="market-price">¥{{ item.market_price }}</div>
|
||||
</div>
|
||||
<div class="goods-name">{{ item.goods_name }}</div>
|
||||
<div class="other-info">
|
||||
<span class="sale-num">{{ item.sale_num || 0 }}人付款</span>
|
||||
<div class="saling">
|
||||
<div v-if="item.is_free_shipping == 1" class="free-shipping">包邮</div>
|
||||
<div v-if="item.promotion_type == 1" class="free-shipping">限时折扣</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pager">
|
||||
<el-pagination background :pager-count="5" :total="total" prev-text="上一页" next-text="下一页"
|
||||
:current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
@size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange" hide-on-single-page></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
<div class="empty" v-else-if="!loading">
|
||||
<img src="~assets/images/goods_empty.png" />
|
||||
<span>没有找到您想要的商品。换个条件试试吧</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BreadCrumbs from '@/components/BreadCrumbs';
|
||||
import GoodsRecommend from '@/components/GoodsRecommend';
|
||||
import list from '@/assets/js/goods/list';
|
||||
|
||||
export default {
|
||||
name: 'list',
|
||||
components: {
|
||||
BreadCrumbs,
|
||||
GoodsRecommend
|
||||
},
|
||||
mixins: [list]
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.goods-container {
|
||||
width: 100%;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.goods-list {
|
||||
width: $width;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
%flex-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.padd-10 {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.goods-nav {
|
||||
padding: 15px 0 0 0 !important;
|
||||
|
||||
span,
|
||||
.nuxt-link-active {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.keyword {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-screen-wrap {
|
||||
margin-top: 20px;
|
||||
background-color: #fff;
|
||||
|
||||
.goods-screen-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 20px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.screen-item-name {
|
||||
width: 42px;
|
||||
margin-right: 35px;
|
||||
font-size: 14px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.screen-item-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
border-bottom: 1px dashed #ebeff3;
|
||||
padding: 10px 0;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
&:last-of-type .screen-item-content {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
.classify-info {
|
||||
.screen-item-content > li {
|
||||
padding-right: 30px;
|
||||
|
||||
a {
|
||||
font-size: 14px;
|
||||
color: #4a4a4a;
|
||||
}
|
||||
|
||||
&:last-of-type {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
&.active a,
|
||||
& a:hover {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.other-screen-info {
|
||||
.screen-item-content > div {
|
||||
cursor: pointer;
|
||||
margin-right: 40px;
|
||||
|
||||
&:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.input-wrap {
|
||||
@extend %flex-center;
|
||||
|
||||
.price_range {
|
||||
@extend %flex-center;
|
||||
|
||||
& > span {
|
||||
overflow: hidden;
|
||||
margin: 0 5px;
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.el-input__inner {
|
||||
border: none;
|
||||
width: 90px;
|
||||
height: 28px;
|
||||
background-color: #f3f5f7;
|
||||
border-radius: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
.el-button {
|
||||
margin-left: 12px;
|
||||
width: 56px;
|
||||
height: 28px;
|
||||
border-radius: 6px;
|
||||
|
||||
&.is-plain:focus,
|
||||
&.is-plain:hover {
|
||||
border-color: $base-color;
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search-arrow {
|
||||
position: relative;
|
||||
|
||||
&::after,
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: -12px;
|
||||
border: 5px solid transparent;
|
||||
}
|
||||
|
||||
&::after {
|
||||
top: 1px;
|
||||
border-bottom-color: #999;
|
||||
}
|
||||
|
||||
&::before {
|
||||
border-top-color: #999;
|
||||
bottom: 2px;
|
||||
}
|
||||
|
||||
&.arrow-down::before {
|
||||
border-top-color: $base-color;
|
||||
}
|
||||
|
||||
&.arrow-up::after {
|
||||
border-bottom-color: $base-color;
|
||||
}
|
||||
}
|
||||
|
||||
.item-other {
|
||||
.el-checkbox__inner {
|
||||
&:hover {
|
||||
border-color: $base-color;
|
||||
}
|
||||
}
|
||||
|
||||
.el-checkbox__input.is-checked .el-checkbox__inner,
|
||||
.el-checkbox__input.is-indeterminate .el-checkbox__inner {
|
||||
background-color: $base-color;
|
||||
border-color: $base-color;
|
||||
}
|
||||
|
||||
.el-checkbox__input.is-checked + .el-checkbox__label {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.search_bread {
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
margin: 0px auto;
|
||||
width: 100%;
|
||||
padding: 10px;
|
||||
|
||||
p {
|
||||
float: left;
|
||||
}
|
||||
|
||||
li {
|
||||
float: left;
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.active a {
|
||||
color: #ff547b !important;
|
||||
}
|
||||
}
|
||||
|
||||
.selected_border {
|
||||
border: 1px solid $base-color;
|
||||
}
|
||||
|
||||
.attr_filter {
|
||||
margin-top: 10px;
|
||||
|
||||
.el-tag {
|
||||
margin-right: 5px;
|
||||
margin-bottom: 10px;
|
||||
border-radius: 0;
|
||||
|
||||
.title {
|
||||
color: $base-color;
|
||||
font-size: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.category {
|
||||
margin: 0 auto 10px auto;
|
||||
border: 1px solid #eeeeee;
|
||||
}
|
||||
|
||||
.brand {
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
padding: 10px 20px 10px;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.table_head {
|
||||
color: #999;
|
||||
margin-right: 15px;
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.table_body {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
flex: 1;
|
||||
height: 105px;
|
||||
overflow: hidden;
|
||||
|
||||
&.more {
|
||||
height: 170px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.initial {
|
||||
margin: 5px auto 10px 10px;
|
||||
|
||||
span {
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 5px 10px;
|
||||
border-radius: 0;
|
||||
|
||||
&:hover {
|
||||
background-color: $base-color;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.brand-item {
|
||||
margin-right: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
width: 125px;
|
||||
height: 45px;
|
||||
|
||||
&:hover {
|
||||
border: 1px solid $base-color;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
margin: auto 25px;
|
||||
}
|
||||
}
|
||||
|
||||
.table_op {
|
||||
margin-top: 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.more-wrap {
|
||||
cursor: pointer;
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.el-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.list-wrap {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.goods-recommended {
|
||||
width: 200px;
|
||||
background-color: #fff;
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.sort {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 5px 15px;
|
||||
border: 1px solid #f1f1f1;
|
||||
border-left: none;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background: $base-color;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.item-other {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 5px 15px;
|
||||
border: 1px solid #f1f1f1;
|
||||
border-left: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.input-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.price_range {
|
||||
margin-left: 60px;
|
||||
}
|
||||
|
||||
span {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.el-input {
|
||||
width: 150px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.el-button {
|
||||
margin: 0 17px;
|
||||
}
|
||||
}
|
||||
|
||||
> div:first-child {
|
||||
border-left: 1px solid #f1f1f1;
|
||||
}
|
||||
}
|
||||
|
||||
.cargo-list {
|
||||
padding-bottom: 40px;
|
||||
}
|
||||
|
||||
.goods-info {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.item {
|
||||
width: 228px;
|
||||
margin: 0 17px 18px 0;
|
||||
padding: 18px;
|
||||
position: relative;
|
||||
background-color: #fff;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:nth-child(5n + 5) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.img-wrap {
|
||||
width: 192px;
|
||||
height: 192px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.goods-name {
|
||||
margin-top: 5px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
word-break: break-all;
|
||||
cursor: pointer;
|
||||
line-height: 1.4;
|
||||
|
||||
&:hover {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
|
||||
.other-info {
|
||||
margin-top: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.price-wrap {
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.price {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: $base-color;
|
||||
|
||||
& > span {
|
||||
font-weight: bold;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
span:nth-child(1) {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
span:nth-child(2) {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.market-price {
|
||||
color: #838383;
|
||||
text-decoration: line-through;
|
||||
margin-left: 10px;
|
||||
line-height: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.sale-num {
|
||||
display: flex;
|
||||
color: #999999;
|
||||
font-size: $ns-font-size-sm;
|
||||
|
||||
p {
|
||||
color: #4759a8;
|
||||
}
|
||||
}
|
||||
|
||||
.shop_name {
|
||||
padding: 0 10px;
|
||||
display: flex;
|
||||
color: #838383;
|
||||
}
|
||||
|
||||
.saling {
|
||||
display: flex;
|
||||
font-size: $ns-font-size-sm;
|
||||
line-height: 1;
|
||||
|
||||
.free-shipping {
|
||||
background: $base-color;
|
||||
color: #ffffff;
|
||||
padding: 3px 4px;
|
||||
border-radius: 2px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.promotion-type {
|
||||
color: $base-color;
|
||||
border: 1px solid $base-color;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 1px 3px;
|
||||
}
|
||||
}
|
||||
|
||||
.item-bottom {
|
||||
display: flex;
|
||||
margin-top: 5px;
|
||||
|
||||
.collection {
|
||||
flex: 1;
|
||||
border: 1px solid #e9e9e9;
|
||||
border-right: none;
|
||||
border-left: none;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cart {
|
||||
flex: 2;
|
||||
border: 1px solid #e9e9e9;
|
||||
border-right: none;
|
||||
height: 40px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.price-icon-wrap {
|
||||
display: inline-block;
|
||||
max-width: 35px;
|
||||
margin-left: 3px;
|
||||
line-height: 1;
|
||||
padding-bottom: 3px;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.empty {
|
||||
padding: 50px 0 60px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
|
||||
img {
|
||||
width: 400px;
|
||||
height: 244px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 14px;
|
||||
color: #4a4a4a;
|
||||
}
|
||||
}
|
||||
|
||||
.pager {
|
||||
text-align: center;
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.el-pagination.is-background .el-pager li:not(.disabled).active {
|
||||
background-color: $base-color;
|
||||
}
|
||||
|
||||
.el-pagination.is-background .el-pager li:not(.disabled):hover {
|
||||
color: $base-color;
|
||||
}
|
||||
</style>
|
||||
187
addon/pc/source/os/pages/index.vue
Executable file
187
addon/pc/source/os/pages/index.vue
Executable file
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 首页固定区 -->
|
||||
<div class="index-wrap" :style="{ background: backgroundColor }" v-if="adList.length">
|
||||
<div class="index">
|
||||
<div class="banner">
|
||||
<el-carousel height="500px" arrow="never" v-loading="loadingAd" @change="handleChange">
|
||||
<el-carousel-item v-for="item in adList" :key="item.adv_id">
|
||||
<el-image :src="$img(item.adv_image)" fit="cover" @click="$util.pushToTab(item.adv_url.url)" />
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="index-content-wrap">
|
||||
<!-- 首页中部广告位 -->
|
||||
<ul class="adv-middle" v-if="adCenterList.length">
|
||||
<li class="adv-middle-item" v-for="(item,index) in adCenterList" :key="index">
|
||||
<el-image :src="$img(item.adv_image)" fit="cover" @error="adCenterImageError(index)" @click="$util.pushToTab(item.adv_url.url)" />
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- 广告 -->
|
||||
<div class="content-div" v-if="adLeftList.length > 0 || adRightList.length > 0">
|
||||
<div class="ad-wrap">
|
||||
<div class="ad-big" v-if="adLeftList.length > 0">
|
||||
<div class="ad-big-img" v-for="(item, index) in adLeftList" :key="index">
|
||||
<el-image :src="$img(item.adv_image)" fit="cover" @error="adLeftImageError(index)" @click="$util.pushToTab(item.adv_url.url)" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="ad-small" v-if="adRightList.length > 0">
|
||||
<div class="ad-small-img" v-for="(item, index) in adRightList" :key="index">
|
||||
<el-image :src="$img(item.adv_image)" fit="cover" @error="adRightImageError(index)" @click="$util.pushToTab(item.adv_url.url)" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 限时秒杀 -->
|
||||
<div class="content-div" v-if="addonIsExit.seckill == 1 && listData.length > 0">
|
||||
<div class="seckill-wrap">
|
||||
<div class="seckill-time">
|
||||
<div class="seckill-time-left">
|
||||
<i class="iconfont icon-miaosha1 ns-text-color"></i>
|
||||
<span class="seckill-time-title ns-text-color">限时秒杀</span>
|
||||
<span>{{ seckillText }}</span>
|
||||
<count-down class="count-down" v-on:start_callback="countDownS_cb()" v-on:end_callback="countDownE_cb()"
|
||||
:currentTime="seckillTimeMachine.currentTime" :startTime="seckillTimeMachine.startTime"
|
||||
:endTime="seckillTimeMachine.endTime" :dayTxt="':'" :hourTxt="':'" :minutesTxt="':'"
|
||||
:secondsTxt="''">
|
||||
</count-down>
|
||||
</div>
|
||||
<div class="seckill-time-right" @click="$router.push('/promotion/seckill')">
|
||||
<span>更多商品</span>
|
||||
<i class="iconfont icon-arrow-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="seckill-content">
|
||||
<vue-seamless-scroll :data="listData" :class-option="optionLeft" class="seamless-warp2">
|
||||
<ul class="item" :style="{ width: 250 * listData.length + 'px' }">
|
||||
<li v-for="(item, index) in listData" :key="index">
|
||||
<div class="seckill-goods" @click="$router.push('/promotion/seckill/' + item.id)">
|
||||
<div class="seckill-goods-img">
|
||||
<img :src="$img(item.goods_image.split(',')[0], { size: 'mid' })" @error="imageError(index)" />
|
||||
</div>
|
||||
<p>{{ item.goods_name }}</p>
|
||||
<div class="seckill-price-wrap">
|
||||
<p class="ns-text-color">
|
||||
¥
|
||||
<span>{{ item.seckill_price }}</span>
|
||||
</p>
|
||||
<p class="primary-price">¥{{ item.price }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</vue-seamless-scroll>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 楼层区 -->
|
||||
<div class="content-div">
|
||||
<div class="floor">
|
||||
<div v-for="(item, index) in floorList" :key="index" class="floor_item">
|
||||
<floor-style-1 v-if="item.block_name == 'floor-style-1'" :data="item" />
|
||||
<floor-style-2 v-if="item.block_name == 'floor-style-2'" :data="item" />
|
||||
<floor-style-3 v-if="item.block_name == 'floor-style-3'" :data="item" />
|
||||
<floor-style-4 v-if="item.block_name == 'floor-style-4'" :data="item" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 浮层区 -->
|
||||
<div class="floatLayer-wrap" v-if="floatLayer.is_show_type">
|
||||
<div class="floatLayer">
|
||||
<div class="img-wrap">
|
||||
<img :src="$img(floatLayer.img_url)" @click="$util.pushToTab(floatLayer.link.url)" />
|
||||
</div>
|
||||
<i class="el-icon-circle-close" @click="closeFloat"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 悬浮搜索 -->
|
||||
<div class="fixed-box" :style="{ display: isShow ? 'block' : 'none' }">
|
||||
<ns-header-mid />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
websiteInfo
|
||||
} from "@/api/website"
|
||||
import floorStyle1 from './index/components/floor-style-1.vue';
|
||||
import floorStyle2 from './index/components/floor-style-2.vue';
|
||||
import floorStyle3 from './index/components/floor-style-3.vue';
|
||||
import floorStyle4 from './index/components/floor-style-4.vue';
|
||||
import index from '@/assets/js/index/index.js';
|
||||
import NsHeaderMid from "@/layouts/components/NsHeaderMid.vue"
|
||||
import vueSeamlessScroll from 'vue-seamless-scroll'
|
||||
import {
|
||||
mapGetters
|
||||
} from 'vuex';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
floorStyle1,
|
||||
floorStyle2,
|
||||
floorStyle3,
|
||||
floorStyle4,
|
||||
NsHeaderMid,
|
||||
vueSeamlessScroll
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['siteInfo'])
|
||||
},
|
||||
mixins: [index],
|
||||
async fetch({store, params}) {
|
||||
await store.dispatch('site/siteInfo')
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: this.siteInfo.seo_title ? this.siteInfo.seo_title : this.siteInfo.site_title,
|
||||
meta: [{
|
||||
name: 'description',
|
||||
content: this.siteInfo.seo_description
|
||||
},
|
||||
{
|
||||
name: 'keyword',
|
||||
content: this.siteInfo.seo_keywords
|
||||
},
|
||||
{
|
||||
property: 'og:title',
|
||||
content: this.siteInfo.seo_title
|
||||
},
|
||||
{
|
||||
property: 'og:description',
|
||||
content: this.siteInfo.seo_description
|
||||
},
|
||||
{
|
||||
property: 'og:type',
|
||||
content: 'website'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/css/index/index.scss';
|
||||
.count-down {
|
||||
span {
|
||||
display: inline-block;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
text-align: center;
|
||||
background: #383838;
|
||||
color: #ffffff;
|
||||
border-radius: 2px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
178
addon/pc/source/os/pages/index/components/floor-style-1.vue
Executable file
178
addon/pc/source/os/pages/index/components/floor-style-1.vue
Executable file
@@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<div class="floor-style-1">
|
||||
<div class="head-wrap" v-if="data.value.title.value.text">
|
||||
<h2 @click="$util.pushToTab(data.value.title.value.link.url)" :style="{ color: data.value.title.value.color }">{{ data.value.title.value.text }}</h2>
|
||||
</div>
|
||||
<div class="body-wrap">
|
||||
<div class="left-wrap" v-if="data.value.leftImg.value.url">
|
||||
<img :src="$img(data.value.leftImg.value.url)" @click="$util.pushToTab(data.value.leftImg.value.link.url)" />
|
||||
</div>
|
||||
<ul class="goods-list">
|
||||
<li v-for="(item, index) in data.value.goodsList.value.list" :key="index" :title="item.goods_name" @click="goSku(item.sku_id)">
|
||||
<div class="img-wrap">
|
||||
<img alt="商品图片" :src="$img(item.goods_image.split(',')[0], {size: 'mid'})" @error="imageError(index)" />
|
||||
</div>
|
||||
<h3>{{ item.goods_name }}</h3>
|
||||
<p class="desc">{{ item.introduction }}</p>
|
||||
<p class="price">
|
||||
<span class="num">{{ item.discount_price }}元</span>
|
||||
<del v-show="Number.parseInt(item.market_price)">{{ item.market_price }}元</del>
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bottom-wrap" v-if="data.value.bottomImg.value.url">
|
||||
<img :src="$img(data.value.bottomImg.value.url)" @click="$util.pushToTab(data.value.bottomImg.value.link.url)" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'floor-style-1',
|
||||
props: {
|
||||
data: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
created() {
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
methods: {
|
||||
goSku(skuId) {
|
||||
this.$util.pushToTab('/sku/' + skuId);
|
||||
},
|
||||
imageError(index) {
|
||||
this.data.value.goodsList.value.list[index].goods_image = this.defaultGoodsImage;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.floor-style-1 {
|
||||
.head-wrap h2 {
|
||||
line-height: 30px;
|
||||
color: #333;
|
||||
padding: 10px;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
width: 95%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.body-wrap {
|
||||
display: flex;
|
||||
|
||||
.left-wrap {
|
||||
width: 234px;
|
||||
height: 614px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s linear;
|
||||
|
||||
&:hover {
|
||||
z-index: 2;
|
||||
-webkit-box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1);
|
||||
-webkit-transform: translate3d(0, -2px, 0);
|
||||
transform: translate3d(0, -2px, 0);
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-list {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
width: 23%;
|
||||
margin-left: 19px;
|
||||
margin-bottom: 20px;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
padding: 10px 0;
|
||||
transition: all 0.2s linear;
|
||||
|
||||
&:hover {
|
||||
z-index: 2;
|
||||
-webkit-box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1);
|
||||
-webkit-transform: translate3d(0, -2px, 0);
|
||||
transform: translate3d(0, -2px, 0);
|
||||
}
|
||||
|
||||
.img-wrap {
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
margin: 0 auto 18px;
|
||||
text-align: center;
|
||||
line-height: 160px;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
margin: 5px 15px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.desc {
|
||||
margin: 0 30px 10px;
|
||||
height: 20px;
|
||||
font-size: 12px;
|
||||
color: #b0b0b0;
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.price {
|
||||
margin: 0 10px 14px;
|
||||
text-align: center;
|
||||
color: $base-color;
|
||||
|
||||
del {
|
||||
margin-left: 0.5em;
|
||||
color: #b0b0b0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-wrap {
|
||||
margin-top: 10px;
|
||||
width: $width;
|
||||
height: 118px;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
171
addon/pc/source/os/pages/index/components/floor-style-2.vue
Executable file
171
addon/pc/source/os/pages/index/components/floor-style-2.vue
Executable file
@@ -0,0 +1,171 @@
|
||||
<template>
|
||||
<div class="floor-style-2">
|
||||
<div class="head-wrap" v-if="data.value.title.value.text">
|
||||
<h2 @click="$util.pushToTab(data.value.title.value.link.url)" :style="{textAlign: data.value.title.value.textAlign, color: data.value.title.value.color }">{{ data.value.title.value.text }}</h2>
|
||||
<p @click="$util.pushToTab(data.value.subTitle.value.link.url)" :style="{ color: data.value.subTitle.value.color }" v-if="data.value.subTitle.value.text">{{ data.value.subTitle.value.text }}</p>
|
||||
</div>
|
||||
<div class="body-wrap">
|
||||
<ul class="goods-list">
|
||||
<li v-for="(item, index) in data.value.goodsList.value.list" :key="index" :title="item.goods_name" @click="goSku(item.sku_id)">
|
||||
<div class="img-wrap">
|
||||
<img alt="商品图片" :src="item.goods_image ? $img(item.goods_image.split(',')[0], {size: 'mid'}) : defaultGoodsImage" @error="imageError(index)" />
|
||||
</div>
|
||||
<h3>{{ item.goods_name }}</h3>
|
||||
<p class="desc">{{ item.introduction }}</p>
|
||||
<p class="price">
|
||||
<span class="num">{{ item.discount_price }}元</span>
|
||||
<del v-show="Number.parseInt(item.market_price)">{{ item.market_price }}元</del>
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bottom-wrap" v-if="data.value.bottomImg.value.url">
|
||||
<img :src="$img(data.value.bottomImg.value.url)" @click="$util.pushToTab(data.value.bottomImg.value.link.url)" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'floor-style-2',
|
||||
props: {
|
||||
data: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
created() {
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
methods: {
|
||||
goSku(skuId) {
|
||||
this.$router.push('/sku/' + skuId);
|
||||
},
|
||||
imageError(index) {
|
||||
this.data.value.goodsList.value.list[index].goods_image = this.defaultGoodsImage;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.floor-style-2 {
|
||||
.head-wrap {
|
||||
text-align: center;
|
||||
|
||||
h2 {
|
||||
line-height: 30px;
|
||||
color: #333;
|
||||
padding: 10px;
|
||||
font-size: 22px;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #b0b0b0;
|
||||
padding: 0 10px;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.body-wrap {
|
||||
.goods-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
width: 19%;
|
||||
margin-left: 15px;
|
||||
margin-bottom: 15px;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
padding: 10px 0;
|
||||
transition: all 0.2s linear;
|
||||
|
||||
&:nth-child(5n + 1) {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
z-index: 2;
|
||||
-webkit-box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1);
|
||||
-webkit-transform: translate3d(0, -2px, 0);
|
||||
transform: translate3d(0, -2px, 0);
|
||||
}
|
||||
|
||||
.img-wrap {
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
margin: 0 auto 18px;
|
||||
text-align: center;
|
||||
line-height: 160px;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
margin: 5px 15px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.desc {
|
||||
margin: 0 30px 10px;
|
||||
height: 20px;
|
||||
font-size: 12px;
|
||||
color: #b0b0b0;
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.price {
|
||||
margin: 0 10px 14px;
|
||||
text-align: center;
|
||||
color: $base-color;
|
||||
|
||||
del {
|
||||
margin-left: 0.5em;
|
||||
color: #b0b0b0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-wrap {
|
||||
margin-top: 10px;
|
||||
width: $width;
|
||||
height: 118px;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
256
addon/pc/source/os/pages/index/components/floor-style-3.vue
Executable file
256
addon/pc/source/os/pages/index/components/floor-style-3.vue
Executable file
@@ -0,0 +1,256 @@
|
||||
<template>
|
||||
<div class="floor-style-3">
|
||||
<div class="item-wrap">
|
||||
<div class="head-wrap">
|
||||
<div class="title-name" v-if="data.value.title.value.text">
|
||||
<span :style="{ backgroundColor: data.value.title.value.color }"></span>
|
||||
<h2 @click="$util.pushToTab(data.value.title.value.link.url)" :style="{ color: data.value.title.value.color }">{{ data.value.title.value.text }}</h2>
|
||||
</div>
|
||||
<div class="category-wrap">
|
||||
<li v-for="(item, index) in data.value.categoryList.value.list" :key="index">
|
||||
<router-link target="_blank" :to="{ path: '/goods/list', query: { category_id: item.category_id, level: item.level } }">{{ item.category_name }}</router-link>
|
||||
</li>
|
||||
</div>
|
||||
</div>
|
||||
<div class="body-wrap">
|
||||
<div class="left-img-wrap">
|
||||
<img v-if="data.value.leftImg.value.url" :src="$img(data.value.leftImg.value.url)" @click="$util.pushToTab(data.value.leftImg.value.link.url)" />
|
||||
</div>
|
||||
<ul class="right-goods-wrap">
|
||||
<li v-for="(item, index) in data.value.rightGoodsList.value.list" :key="index" @click="goSku(item.sku_id)">
|
||||
<h4>{{ item.goods_name }}</h4>
|
||||
<p class="ns-text-color">{{ item.introduction }}</p>
|
||||
<div class="img-wrap">
|
||||
<img alt="商品图片" :src="$img(item.goods_image.split(',')[0], {size: 'mid'})" @error="imageErrorRight(index)" />
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="bottom-goods-wrap">
|
||||
<li v-for="(item, index) in data.value.bottomGoodsList.value.list" :key="index" @click="goSku(item.sku_id)">
|
||||
<div class="info-wrap">
|
||||
<h4>{{ item.goods_name }}</h4>
|
||||
<p class="ns-text-color">{{ item.introduction }}</p>
|
||||
</div>
|
||||
<div class="img-wrap">
|
||||
<img alt="商品图片" :src="$img(item.goods_image.split(',')[0], {size: 'mid'})" @error="imageErrorBottom(index)" />
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- <ul class="brand-wrap">
|
||||
<li v-for="(item, index) in data.value.brandList.value.list" :key="index" @click="$util.pushToTab({ path: '/list', query: { brand_id: item.brand_id } })">
|
||||
<img alt="品牌图片" :src="$img(item.image_url)" />
|
||||
</li>
|
||||
</ul> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'floor-style-3',
|
||||
props: {
|
||||
data: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
created() {
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
methods: {
|
||||
goSku(skuId) {
|
||||
this.$util.pushToTab('/sku/' + skuId);
|
||||
},
|
||||
imageErrorRight(index) {
|
||||
this.data.value.rightGoodsList.value.list[index].goods_image = this.defaultGoodsImage;
|
||||
},
|
||||
imageErrorBottom(index) {
|
||||
this.data.value.bottomGoodsList.value.list[index].goods_image = this.defaultGoodsImage;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.floor-style-3 {
|
||||
overflow: hidden;
|
||||
|
||||
.item-wrap .head-wrap {
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
|
||||
.title-name {
|
||||
display: inline-block;
|
||||
|
||||
span {
|
||||
float: left;
|
||||
width: 5px;
|
||||
height: 21px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
float: left;
|
||||
margin-left: 10px;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.category-wrap {
|
||||
float: right;
|
||||
display: flex;
|
||||
|
||||
li {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.body-wrap {
|
||||
.left-img-wrap {
|
||||
width: 190px;
|
||||
height: 360px;
|
||||
float: left;
|
||||
cursor: pointer;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.right-goods-wrap {
|
||||
margin-left: 190px;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
width: 19.9%;
|
||||
background: #ffff;
|
||||
border-width: 0 0 1px 1px;
|
||||
border-color: #f9f9f9;
|
||||
border-style: solid;
|
||||
cursor: pointer;
|
||||
|
||||
h4 {
|
||||
font-size: 14px;
|
||||
margin: 10px 20px 5px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
margin: 4px 30px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.img-wrap {
|
||||
width: 105px;
|
||||
height: 105px;
|
||||
line-height: 105px;
|
||||
display: inline-block;
|
||||
margin-bottom: 10px;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-goods-wrap {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
|
||||
li {
|
||||
flex: 1;
|
||||
background: #fff;
|
||||
border-width: 0 0 1px 1px;
|
||||
border-color: #f9f9f9;
|
||||
border-style: solid;
|
||||
cursor: pointer;
|
||||
|
||||
&:first-child {
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.info-wrap {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
|
||||
h4 {
|
||||
font-size: 14px;
|
||||
margin: 0 10px 5px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
width: 90px;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
margin: 0 20px;
|
||||
width: 70px;
|
||||
}
|
||||
}
|
||||
|
||||
.img-wrap {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
line-height: 70px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.brand-wrap {
|
||||
display: flex;
|
||||
background: #fff;
|
||||
|
||||
li {
|
||||
flex: 1;
|
||||
height: 50px;
|
||||
cursor: pointer;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
background: #fff;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
226
addon/pc/source/os/pages/index/components/floor-style-4.vue
Executable file
226
addon/pc/source/os/pages/index/components/floor-style-4.vue
Executable file
@@ -0,0 +1,226 @@
|
||||
<template>
|
||||
<div class="floor-style-4">
|
||||
<div class="head-wrap" v-if="data.value.title.value.text">
|
||||
<h2 @click="$util.pushToTab(data.value.title.value.link.url)" :style="{ color: data.value.title.value.color }">{{ data.value.title.value.text }}</h2>
|
||||
<div class="more" @click="$util.pushToTab(data.value.more.value.link.url)" :style="{color: data.value.more.value.color}">
|
||||
<span>{{data.value.more.value.text}}</span>
|
||||
<i class="el-icon-arrow-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="body-wrap">
|
||||
<div class="left-wrap" v-if="data.value.leftImg.value.url">
|
||||
<img :src="$img(data.value.leftImg.value.url)" @click="$util.pushToTab(data.value.leftImg.value.link.url)" />
|
||||
</div>
|
||||
<el-carousel trigger="click" height="324px" indicator-position="none" arrow="never">
|
||||
<el-carousel-item v-for="num in itemNum" :key="num">
|
||||
<ul class="goods-list">
|
||||
<li v-for="(item, index) in itemList(num)" :key="index" :title="item.goods_name" @click="goSku(item.sku_id)">
|
||||
<div class="img-wrap">
|
||||
<img alt="商品图片" :src="$img(item.goods_image.split(',')[0], { size: 'mid' })" @error="imageError(index)" />
|
||||
</div>
|
||||
<div class="price">
|
||||
<span class="num">¥{{ item.discount_price }}</span>
|
||||
<del v-show="Number.parseInt(item.market_price)">¥{{ item.market_price }}</del>
|
||||
</div>
|
||||
<h3 class="name">{{ item.goods_name }}</h3>
|
||||
<div class="other-info" v-if="item.sale_num">
|
||||
<span>已售{{ item.sale_num }}件</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</div>
|
||||
<div class="bottom-wrap" v-if="data.value.bottomImg.value.url">
|
||||
<img :src="$img(data.value.bottomImg.value.url)" @click="$util.pushToTab(data.value.bottomImg.value.link.url)" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'floor-style-4',
|
||||
props: {
|
||||
data: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
created() {
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage']),
|
||||
goodsList() {
|
||||
let arr = [];
|
||||
try {
|
||||
arr = this.data.value.goodsList.value.list;
|
||||
} catch (e) {
|
||||
arr = [];
|
||||
}
|
||||
return arr;
|
||||
},
|
||||
itemNum() {
|
||||
let [num, listLen] = [0, this.goodsList.length];
|
||||
num = parseInt(listLen / 3);
|
||||
if (parseInt(listLen % 3) > 0) num += 1;
|
||||
return num;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goSku(skuId) {
|
||||
this.$util.pushToTab('/sku/' + skuId);
|
||||
},
|
||||
imageError(index) {
|
||||
this.data.value.goodsList.value.list[index].goods_image = this.defaultGoodsImage;
|
||||
},
|
||||
itemList(index) {
|
||||
index -= 1;
|
||||
if (!this.goodsList.length) return [];
|
||||
let [start, end, arr] = [index * 3, index * 3 + 3, []];
|
||||
arr = this.goodsList.slice(start, end);
|
||||
return arr;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.floor-style-4 {
|
||||
.head-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.head-wrap h2 {
|
||||
line-height: 30px;
|
||||
color: #333;
|
||||
padding: 10px;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.body-wrap {
|
||||
display: flex;
|
||||
|
||||
.left-wrap {
|
||||
margin-right: 15px;
|
||||
width: 478px;
|
||||
height: 324px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s linear;
|
||||
|
||||
&:hover {
|
||||
z-index: 2;
|
||||
-webkit-box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1);
|
||||
-webkit-transform: translate3d(0, -2px, 0);
|
||||
transform: translate3d(0, -2px, 0);
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.el-carousel {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.goods-list {
|
||||
display: flex;
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
width: 228px;
|
||||
height: 324px;
|
||||
margin-right: 15px;
|
||||
background-color: #fff;
|
||||
cursor: pointer;
|
||||
padding: 10px 18px;
|
||||
transition: all 0.2s linear;
|
||||
box-sizing: border-box;
|
||||
|
||||
&:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
z-index: 2;
|
||||
-webkit-box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1);
|
||||
-webkit-transform: translate3d(0, -2px, 0);
|
||||
transform: translate3d(0, -2px, 0);
|
||||
}
|
||||
|
||||
.img-wrap {
|
||||
width: 168px;
|
||||
height: 168px;
|
||||
line-height: 168px;
|
||||
margin: 0 auto 18px;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
margin-top: 5px;
|
||||
font-size: 14px;
|
||||
color: #444;
|
||||
line-height: 1.5;
|
||||
font-weight: normal;
|
||||
@extend .multi-hidden;
|
||||
}
|
||||
|
||||
.other-info {
|
||||
position: absolute;
|
||||
bottom: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
span {
|
||||
font-size: 14px;
|
||||
color: #aaa;
|
||||
}
|
||||
}
|
||||
|
||||
.price {
|
||||
.num {
|
||||
color: $base-color;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
del {
|
||||
font-size: 14px;
|
||||
margin-left: 15px;
|
||||
color: #aaa;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-wrap {
|
||||
margin-top: 35px;
|
||||
width: $width;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
235
addon/pc/source/os/pages/member/account.vue
Executable file
235
addon/pc/source/os/pages/member/account.vue
Executable file
@@ -0,0 +1,235 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<div class="my-account">
|
||||
<div class="account-wrap">
|
||||
<div class="account-left">
|
||||
<div class="title">我的可用余额(元)</div>
|
||||
<div class="money">
|
||||
<div class="balance-money">
|
||||
<b>{{ integer }}</b>
|
||||
<span>.{{ decimal }}</span>
|
||||
</div>
|
||||
<div class="tx" @click="applyWithdrawal">提现</div>
|
||||
<div class="cz" @click="rechargeList">充值</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="account-right">
|
||||
<div class="item-wrap">
|
||||
<div class="item">
|
||||
<div class="iconfont icon-ziyuan"></div>
|
||||
<div class="title">储值余额:</div>
|
||||
<b class="num">{{ balanceInfo.balance_money }}</b>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="iconfont icon-ziyuan"></div>
|
||||
<div class="title">现金余额:</div>
|
||||
<b class="num">{{ balanceInfo.balance }}</b>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail" v-loading="loading">
|
||||
<el-table :data="accountList" border>
|
||||
<el-table-column prop="type_name" label="来源" width="150"></el-table-column>
|
||||
<el-table-column prop="account_data" label="金额" width="150"></el-table-column>
|
||||
<el-table-column prop="remark" class="detail-name" label="详细说明"></el-table-column>
|
||||
<el-table-column prop="time" label="时间" width="180"></el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="pager">
|
||||
<el-pagination
|
||||
background
|
||||
:pager-count="5"
|
||||
:total="total"
|
||||
prev-text="上一页"
|
||||
next-text="下一页"
|
||||
:current-page.sync="account.page"
|
||||
:page-size.sync="account.page_size"
|
||||
@size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange"
|
||||
hide-on-single-page
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {balance, balanceDetail} from "@/api/member/account"
|
||||
|
||||
export default {
|
||||
name: "account",
|
||||
layout: "member",
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
account: {
|
||||
page: 1,
|
||||
page_size: 10
|
||||
},
|
||||
balanceInfo: {
|
||||
balance: 0,
|
||||
balance_money: 0
|
||||
},
|
||||
accountList: [],
|
||||
total: 0,
|
||||
integer: 0,
|
||||
decimal: 0,
|
||||
loading: true,
|
||||
yes: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getAccount();
|
||||
this.getAccountList()
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
//获取余额信息
|
||||
getAccount() {
|
||||
balance({account_type: "balance,balance_money"}).then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.balanceInfo = res.data;
|
||||
const price = (parseFloat(this.balanceInfo.balance) + parseFloat(this.balanceInfo.balance_money)).toFixed(2)
|
||||
let priceSplit = price.split(".");
|
||||
this.integer = priceSplit[0];
|
||||
this.decimal = priceSplit[1];
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
},
|
||||
//获取余额明细
|
||||
getAccountList() {
|
||||
balanceDetail({
|
||||
page_size: this.account.page_size,
|
||||
page: this.account.page,
|
||||
account_type: "balance"
|
||||
}).then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.accountList = res.data.list;
|
||||
this.total = res.data.count;
|
||||
this.accountList.forEach(item => {
|
||||
item.time = this.$util.timeStampTurnTime(item.create_time)
|
||||
})
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
},
|
||||
handlePageSizeChange(num) {
|
||||
this.account.page_size = num;
|
||||
this.getAccountList()
|
||||
},
|
||||
handleCurrentPageChange(page) {
|
||||
this.account.page = page
|
||||
this.getAccountList()
|
||||
},
|
||||
applyWithdrawal() {
|
||||
this.$router.push("/member/apply_withdrawal")
|
||||
},
|
||||
rechargeList() {
|
||||
this.$router.push("/member/recharge_list")
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.my-account {
|
||||
background: #ffffff;
|
||||
padding: 20px;
|
||||
|
||||
.account-wrap {
|
||||
display: flex;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.account-left {
|
||||
flex: 1;
|
||||
|
||||
.title {
|
||||
font-size: $ns-font-size-base;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.money {
|
||||
display: flex;
|
||||
|
||||
.balance-money {
|
||||
b {
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.tx {
|
||||
color: $base-color;
|
||||
margin-left: 5px;
|
||||
margin-top: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cz {
|
||||
color: $base-color;
|
||||
margin-left: 5px;
|
||||
margin-top: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.account-right {
|
||||
flex: 1;
|
||||
font-size: $ns-font-size-base;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.title {
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
.num {
|
||||
margin-left: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.page {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
padding-top: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
208
addon/pc/source/os/pages/member/account_edit.vue
Executable file
208
addon/pc/source/os/pages/member/account_edit.vue
Executable file
@@ -0,0 +1,208 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>编辑账户</span>
|
||||
</div>
|
||||
|
||||
<div v-loading="loading">
|
||||
<el-form :model="formData" :rules="rules" ref="ruleForm" label-width="80px">
|
||||
<el-form-item label="姓名" prop="realname">
|
||||
<el-input v-model="formData.realname" placeholder="请输入真实姓名" class="ns-len-input"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="手机" prop="mobile">
|
||||
<el-input v-model="formData.mobile" autocomplete="off" placeholder="请输入手机号" maxlength="11" class="ns-len-input"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="账号类型" prop="withdraw_type">
|
||||
<el-select v-model="formData.withdraw_type" placeholder="请选择账号类型">
|
||||
<el-option v-for="(value, key) in transferType" :key="key" :label="value" :value="key" :disabled="key == 'wechatpay'"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="银行名称" prop="branch_bank_name" v-if="formData.withdraw_type == 'bank'">
|
||||
<el-input v-model="formData.branch_bank_name" autocomplete="off" placeholder="请输入银行名称" maxlength="50" class="ns-len-input"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="提现账号" prop="bank_account" v-if="formData.withdraw_type != 'wechatpay' && formData.withdraw_type">
|
||||
<el-input v-model="formData.bank_account" autocomplete="off" placeholder="请输入提现账号" maxlength="30" class="ns-len-input"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button size="medium" type="primary" @click="saveAccount('ruleForm')">保存</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {transferType, accountDetail, saveAccount} from "@/api/member/member"
|
||||
|
||||
export default {
|
||||
name: "account_edit",
|
||||
layout: "member",
|
||||
data() {
|
||||
var isMobile = (rule, value, callback) => {
|
||||
if (!value) {
|
||||
return callback(new Error("手机号不能为空"))
|
||||
} else {
|
||||
if (/^\d{11}$/.test(value)) {
|
||||
callback()
|
||||
} else {
|
||||
callback(new Error("请输入正确的手机号"))
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
formData: {
|
||||
id: '',
|
||||
realname: '',
|
||||
mobile: '',
|
||||
withdraw_type: '',
|
||||
bank_account: '',
|
||||
branch_bank_name: ''
|
||||
},
|
||||
flag: false, //防重复标识
|
||||
payList: [],
|
||||
loading: true,
|
||||
index: 0,
|
||||
transferType: [],
|
||||
rules: {
|
||||
realname: [{required: true, message: "请输入真实姓名", trigger: "blur"}],
|
||||
mobile: [{required: true, validator: isMobile, trigger: "blur"}],
|
||||
withdraw_type: [{required: true, message: '请选择账号类型', trigger: 'change'}],
|
||||
branch_bank_name: [{required: true, message: "请输入银行名称", trigger: "blur"}],
|
||||
bank_account: [{required: true, message: "请输入提现账号", trigger: "blur"}],
|
||||
},
|
||||
yes: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.formData.id = this.$route.query.id;
|
||||
this.getTransferType();
|
||||
if (this.formData.id) {
|
||||
this.getAccountDetail(this.formData.id)
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 获取转账方式
|
||||
*/
|
||||
getTransferType() {
|
||||
transferType().then(res => {
|
||||
this.transferType = res.data;
|
||||
|
||||
if (!this.formData.id) { // id为空,即添加时在此结束加载
|
||||
this.loading = false
|
||||
}
|
||||
}).catch(err => {
|
||||
if (!this.formData.id) {
|
||||
this.loading = false
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 获取账户详情(编辑)
|
||||
*/
|
||||
getAccountDetail(id) {
|
||||
accountDetail({id: this.formData.id}).then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.formData.realname = res.data.realname;
|
||||
this.formData.mobile = res.data.mobile;
|
||||
this.formData.bank_account = res.data.bank_account;
|
||||
this.formData.branch_bank_name = res.data.branch_bank_name;
|
||||
this.formData.withdraw_type = res.data.withdraw_type;
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(err => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 保存
|
||||
*/
|
||||
saveAccount(formName) {
|
||||
this.$refs[formName].validate(valid => {
|
||||
if (valid) {
|
||||
var data = {
|
||||
id: this.formData.id,
|
||||
realname: this.formData.realname,
|
||||
mobile: this.formData.mobile,
|
||||
withdraw_type: this.formData.withdraw_type,
|
||||
bank_account: this.formData.bank_account,
|
||||
branch_bank_name: this.formData.branch_bank_name
|
||||
}
|
||||
|
||||
data.url = "add"
|
||||
if (this.formData.id) {
|
||||
data.url = "edit"
|
||||
}
|
||||
|
||||
if (this.flag) return
|
||||
this.flag = true
|
||||
|
||||
saveAccount(data).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$router.push({path: "/member/account_list"})
|
||||
} else {
|
||||
this.flag = false
|
||||
this.$message({message: res.message, type: "warning"})
|
||||
}
|
||||
}).catch(err => {
|
||||
this.flag = false
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.el-card.is-always-shadow,
|
||||
.el-card.is-hover-shadow:focus,
|
||||
.el-card.is-hover-shadow:hover {
|
||||
box-shadow: unset;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.ns-len-input {
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
.el-select {
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
||||
285
addon/pc/source/os/pages/member/account_list.vue
Executable file
285
addon/pc/source/os/pages/member/account_list.vue
Executable file
@@ -0,0 +1,285 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>账户列表</span>
|
||||
</div>
|
||||
|
||||
<div v-loading="loading">
|
||||
<div class="ns-member-address-list">
|
||||
<div class="text item ns-add-address" @click="addAccount('add')">
|
||||
<span>+ 新增账户</span>
|
||||
</div>
|
||||
|
||||
<div class="text item ns-account-list" v-for="(item, index) in dataList" :key="index" @click="setDefault(item.id)">
|
||||
<div class="text-name">
|
||||
<span>{{ item.realname }}</span>
|
||||
<span v-if="item.is_default == 1" class="text-default">默认</span>
|
||||
</div>
|
||||
|
||||
<div class="text-content">
|
||||
<p>手机号码:{{ item.mobile }}</p>
|
||||
<p v-if="item.withdraw_type == 'alipay'">提现账号:{{ item.bank_account }}</p>
|
||||
<p>账号类型:{{ item.withdraw_type_name }}</p>
|
||||
<p v-if="item.withdraw_type == 'bank'">银行名称:{{ item.branch_bank_name }}</p>
|
||||
</div>
|
||||
|
||||
<div class="text-operation">
|
||||
<span v-if="item.is_default != 1" @click="setDefault(item.id)">设为默认</span>
|
||||
<span @click.stop="addAccount('edit', item.id)">编辑</span>
|
||||
<span v-if="item.is_default != 1" @click.stop="delAccount(item.id, item.is_default)">删除</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pager">
|
||||
<el-pagination
|
||||
background
|
||||
:pager-count="5"
|
||||
:total="total"
|
||||
prev-text="上一页"
|
||||
next-text="下一页"
|
||||
:current-page.sync="currentPage"
|
||||
:page-size.sync="pageSize"
|
||||
@size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange"
|
||||
hide-on-single-page
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {accountList, accountDefault, delAccount} from "@/api/member/member"
|
||||
|
||||
export default {
|
||||
name: "account_list",
|
||||
layout: "member",
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
dataList: [],
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 8,
|
||||
loading: true,
|
||||
isSub: false,
|
||||
yes: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.back = this.$route.query.back
|
||||
this.getAccountList()
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
handlePageSizeChange(size) {
|
||||
this.pageSize = size
|
||||
this.refresh()
|
||||
},
|
||||
handleCurrentPageChange(page) {
|
||||
this.currentPage = page
|
||||
this.refresh()
|
||||
},
|
||||
refresh() {
|
||||
this.loading = true
|
||||
this.getAccountList()
|
||||
},
|
||||
/**
|
||||
* 获取账户列表
|
||||
*/
|
||||
getAccountList() {
|
||||
accountList({
|
||||
page_size: this.pageSize,
|
||||
page: this.currentPage
|
||||
}).then(res => {
|
||||
this.dataList = res.data.list
|
||||
this.total = res.data.count
|
||||
|
||||
let withdrawType = {
|
||||
'bank': '银行',
|
||||
'alipay': '支付宝',
|
||||
'wechatpay': '微信'
|
||||
};
|
||||
this.dataList.forEach(item => {
|
||||
item.withdraw_type_name = withdrawType[item.withdraw_type] ? withdrawType[item.withdraw_type] : '';
|
||||
})
|
||||
|
||||
this.loading = false
|
||||
}).catch(err => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
setDefault(id) {
|
||||
if (this.isSub) return;
|
||||
this.isSub = true;
|
||||
|
||||
accountDefault({
|
||||
id: id
|
||||
}).then(res => {
|
||||
if (this.back) {
|
||||
this.$router.push(this.back);
|
||||
} else {
|
||||
this.refresh()
|
||||
this.$message.success('修改默认账户成功')
|
||||
}
|
||||
this.isSub = false;
|
||||
}).catch(err => {
|
||||
this.isSub = false;
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
},
|
||||
delAccount(id) {
|
||||
this.$confirm("确定要删除该账户吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
delAccount({
|
||||
id: id
|
||||
}).then(res => {
|
||||
this.refresh()
|
||||
this.$message.success(res.message)
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 添加/编辑地址
|
||||
*/
|
||||
addAccount(type, id) {
|
||||
if (type == "edit") {
|
||||
this.$router.push({path: "/member/account_edit", query: {id: id}})
|
||||
} else {
|
||||
this.$router.push({path: "/member/account_edit"})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.el-card.is-always-shadow,
|
||||
.el-card.is-hover-shadow:focus,
|
||||
.el-card.is-hover-shadow:hover {
|
||||
box-shadow: unset;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.ns-member-address-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.ns-account-list {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.text {
|
||||
width: 32%;
|
||||
height: 170px;
|
||||
margin-right: 2%;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #d8d8d8;
|
||||
margin-bottom: 20px;
|
||||
padding: 0 15px;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
|
||||
.text-name {
|
||||
height: 37px;
|
||||
line-height: 40px;
|
||||
padding: 0 10px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
}
|
||||
|
||||
.text-default {
|
||||
display: inline-block;
|
||||
margin-left: 10px;
|
||||
background: $base-color;
|
||||
color: #ffffff;
|
||||
width: 35px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.text-content {
|
||||
padding: 10px;
|
||||
|
||||
p {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.ns-address-detail {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.text-operation {
|
||||
// 操作
|
||||
position: absolute;
|
||||
right: 12px;
|
||||
bottom: 5px;
|
||||
|
||||
span {
|
||||
margin: 0 5px;
|
||||
color: #999999;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
span:hover {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text:nth-child(3n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.ns-add-address {
|
||||
border: 1px dashed #d8d8d8;
|
||||
text-align: center;
|
||||
color: #999999;
|
||||
line-height: 170px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ns-add-address:hover {
|
||||
border-color: $base-color;
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
365
addon/pc/source/os/pages/member/activist.vue
Executable file
365
addon/pc/source/os/pages/member/activist.vue
Executable file
@@ -0,0 +1,365 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card order-list">
|
||||
<div slot="header" class="clearfix"><span>退款/售后</span></div>
|
||||
|
||||
<div v-loading="loading">
|
||||
<nav>
|
||||
<li>商品信息</li>
|
||||
<li>退款金额</li>
|
||||
<li>退款类型</li>
|
||||
<li>退款状态</li>
|
||||
<li>操作</li>
|
||||
</nav>
|
||||
|
||||
<div class="list" v-if="refundList.length > 0">
|
||||
<div class="item" v-for="(refundItem, refundIndex) in refundList" :key="refundIndex">
|
||||
<div class="head">
|
||||
<span class="create-time">{{ $util.timeStampTurnTime(refundItem.refund_action_time) }}</span>
|
||||
<span class="order-no">退款编号:{{ refundItem.refund_no }}</span>
|
||||
<router-link :to="'/shop-' + refundItem.site_id" target="_blank">{{ refundItem.site_name }}</router-link>
|
||||
<span class="order-type">{{ refundItem.refund_status == 3 ? '退款成功' : '退款中' }}</span>
|
||||
</div>
|
||||
<ul>
|
||||
<li>
|
||||
<div class="img-wrap" @click="$util.pushToTab('/sku/' + refundItem.sku_id)">
|
||||
<img :src="$img(refundItem.sku_image, { size: 'mid' })" @error="imageError(refundIndex)" />
|
||||
</div>
|
||||
<div class="info-wrap">
|
||||
<h5 @click="$util.pushToTab('/sku/' + refundItem.sku_id)">{{ refundItem.sku_name }}</h5>
|
||||
<!-- <span>规格:规格值</span> -->
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<span>¥{{ (Number(refundItem.refund_status == 3 ? refundItem.refund_real_money : refundItem.refund_apply_money) + Number(refundItem.shop_active_refund_money)).toFixed(2) }}</span>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<span>{{ refundItem.refund_type == 1 ? '退款' : '退货' }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span class="ns-text-color">{{ refundItem.refund_status_name }}</span>
|
||||
<el-link :underline="false" @click="orderDetail(refundItem)">退款详情</el-link>
|
||||
</li>
|
||||
<li>
|
||||
<template v-if="refundItem.refund_action.length > 0">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
:plain="true"
|
||||
v-for="(operationItem, operationIndex) in refundItem.refund_action"
|
||||
:key="operationIndex"
|
||||
@click="operation(operationItem.event, refundItem)"
|
||||
>{{ operationItem.title }}</el-button>
|
||||
</template>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="!loading && refundList.length == 0" class="empty-wrap">暂无相关订单</div>
|
||||
</div>
|
||||
<div class="pager">
|
||||
<el-pagination
|
||||
background
|
||||
:pager-count="5"
|
||||
:total="total"
|
||||
prev-text="上一页"
|
||||
next-text="下一页"
|
||||
:current-page.sync="currentPage"
|
||||
:page-size.sync="pageSize"
|
||||
@size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange"
|
||||
hide-on-single-page
|
||||
></el-pagination>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from 'vuex';
|
||||
import {refundList, cancleRefund} from '@/api/order/refund';
|
||||
|
||||
export default {
|
||||
name: 'activist',
|
||||
layout: "member",
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
orderStatus: 'all',
|
||||
loading: true,
|
||||
refundList: [],
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
yes: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.orderStatus = this.$route.query.status || 'all';
|
||||
this.getRefundList();
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
handleClick(tab, event) {
|
||||
this.currentPage = 1;
|
||||
this.orderStatus = tab.name;
|
||||
this.refresh();
|
||||
},
|
||||
getRefundList() {
|
||||
refundList({
|
||||
page: this.currentPage,
|
||||
page_size: this.pageSize
|
||||
}).then(res => {
|
||||
let list = [];
|
||||
if (res.code == 0 && res.data) {
|
||||
list = res.data.list;
|
||||
this.total = res.data.count;
|
||||
}
|
||||
this.refundList = list;
|
||||
this.loading = false;
|
||||
}).catch(res => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
handlePageSizeChange(size) {
|
||||
this.pageSize = size;
|
||||
this.refresh();
|
||||
},
|
||||
handleCurrentPageChange(page) {
|
||||
this.currentPage = page;
|
||||
this.refresh();
|
||||
},
|
||||
refresh() {
|
||||
this.loading = true;
|
||||
this.getRefundList();
|
||||
},
|
||||
operation(action, orderData) {
|
||||
switch (action) {
|
||||
case 'orderRefundCancel': // 撤销维权
|
||||
this.cancleRefund(orderData.order_goods_id);
|
||||
break;
|
||||
case 'orderRefundDelivery': // 退款发货
|
||||
this.$router.push({
|
||||
path: '/order/refund_detail',
|
||||
query: {order_goods_id: orderData.order_goods_id, action: 'returngoods'}
|
||||
});
|
||||
break;
|
||||
case 'orderRefundAsk':
|
||||
this.$router.push({path: '/order/refund?order_goods_id=' + orderData.order_goods_id});
|
||||
break;
|
||||
case 'orderRefundApply':
|
||||
this.$router.push({
|
||||
path: '/order/refund',
|
||||
query: { order_goods_id: orderData.order_goods_id, order_id: orderData.order_id },
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
orderDetail(data) {
|
||||
this.$router.push({path: '/order/refund_detail', query: {order_goods_id: data.order_goods_id}});
|
||||
},
|
||||
imageError(refundIndex) {
|
||||
this.refundList[refundIndex].sku_image = this.defaultGoodsImage;
|
||||
},
|
||||
cancleRefund(order_goods_id) {
|
||||
this.$confirm('撤销之后本次申请将会关闭,如后续仍有问题可再次发起申请', '提示', {
|
||||
confirmButtonText: '确认撤销',
|
||||
cancelButtonText: '暂不撤销',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
if (this.isSub) return;
|
||||
this.isSub = true;
|
||||
|
||||
cancleRefund({order_goods_id: order_goods_id}).then(res => {
|
||||
const {code, message, data} = res;
|
||||
if (code >= 0) {
|
||||
this.$message({
|
||||
message: '撤销成功',
|
||||
type: 'success'
|
||||
});
|
||||
this.getRefundList();
|
||||
} else {
|
||||
this.$message({message: message, type: 'warning'});
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.order-list {
|
||||
nav {
|
||||
overflow: hidden;
|
||||
padding: 10px 0;
|
||||
background: #fff;
|
||||
margin-bottom: 10px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 45%;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(5) {
|
||||
width: 15%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
.item {
|
||||
margin-bottom: 20px;
|
||||
border: 1px solid #eeeeee;
|
||||
border-top: 0;
|
||||
|
||||
.head {
|
||||
padding: 8px 10px;
|
||||
background: #f7f7f7;
|
||||
font-size: 12px;
|
||||
|
||||
.create-time {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
|
||||
a {
|
||||
margin: 0 10px 0 20px;
|
||||
}
|
||||
|
||||
.order-type {
|
||||
margin-left: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
background-color: #fff;
|
||||
padding: 10px;
|
||||
overflow: hidden;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
line-height: 60px;
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 45%;
|
||||
line-height: inherit;
|
||||
|
||||
.img-wrap {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.info-wrap {
|
||||
margin-left: 70px;
|
||||
|
||||
h5 {
|
||||
font-weight: normal;
|
||||
font-size: $ns-font-size-base;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
|
||||
&:hover {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: $ns-font-size-sm;
|
||||
color: #9a9a9a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
width: 14%;
|
||||
line-height: 30px;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(5) {
|
||||
width: 15%;
|
||||
line-height: initial;
|
||||
|
||||
button {
|
||||
margin-left: 0;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty-wrap {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
477
addon/pc/source/os/pages/member/address_edit.vue
Executable file
477
addon/pc/source/os/pages/member/address_edit.vue
Executable file
@@ -0,0 +1,477 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>编辑收货地址</span>
|
||||
</div>
|
||||
|
||||
<div v-loading="loading" class="ns-member-address-list">
|
||||
<el-form :model="formData" :rules="rules" ref="ruleForm" label-width="80px">
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input v-model="formData.name" placeholder="收货人姓名" class="ns-len-input" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="手机" prop="mobile">
|
||||
<el-input v-model="formData.mobile" autocomplete="off" placeholder="收货人手机号" class="ns-len-input" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="电话">
|
||||
<el-input v-model.trim="formData.telephone" autocomplete="off" placeholder="收货人固定电话(选填)" class="ns-len-input" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="地址" prop="full_address">
|
||||
<el-select :value="formData.province_id" placeholder="请选择省" @change="changeProvice">
|
||||
<el-option v-for="option in province" :key="option.id" :label="option.name" :value="option.id">
|
||||
{{ option.name }}
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-select :value="formData.city_id" placeholder="请选择市" @change="changeCity">
|
||||
<el-option v-for="option in city" :key="option.id" :label="option.name" :value="option.id">
|
||||
{{ option.name }}
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-select :value="formData.district_id" placeholder="请选择区/县" @change="changeDistrict">
|
||||
<el-option v-for="option in district" :key="option.id" :label="option.name" :value="option.id">
|
||||
{{ option.name }}
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="详细地址" prop="address">
|
||||
<el-input v-model.trim="formData.address" autocomplete="off" placeholder="定位到小区、街道、写字楼" class="ns-len-input" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="是否默认">
|
||||
<el-radio-group v-model="formData.is_default">
|
||||
<el-radio :label="1">是</el-radio>
|
||||
<el-radio :label="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item>
|
||||
<el-button type="primary" size="medium" @click="saveAddress('ruleForm')">保存</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
addressInfo,
|
||||
saveAddress
|
||||
} from "@/api/member/member"
|
||||
import {
|
||||
getArea
|
||||
} from "@/api/address"
|
||||
|
||||
export default {
|
||||
name: "address_edit",
|
||||
layout: "member",
|
||||
components: {},
|
||||
data() {
|
||||
let self = this
|
||||
var isMobile = (rule, value, callback) => {
|
||||
if (!value) {
|
||||
return callback(new Error("手机号不能为空"))
|
||||
} else {
|
||||
|
||||
if (/^\d{11}$/.test(value)) {
|
||||
callback()
|
||||
} else {
|
||||
callback(new Error("请输入正确的手机号"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var fullAddress = (rule, value, callback) => {
|
||||
if (self.formData.province_id) {
|
||||
if (self.formData.city_id) {
|
||||
if (self.district.length > 0) {
|
||||
if (self.formData.district_id) {
|
||||
return callback()
|
||||
} else {
|
||||
return callback(new Error("请选择区/县"))
|
||||
}
|
||||
} else {
|
||||
return callback()
|
||||
}
|
||||
} else {
|
||||
return callback(new Error("请选择市"))
|
||||
}
|
||||
} else {
|
||||
return callback(new Error("请选择省"))
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
formData: {
|
||||
id: 0,
|
||||
name: "",
|
||||
mobile: "",
|
||||
telephone: "",
|
||||
province_id: "",
|
||||
city_id: "",
|
||||
district_id: "",
|
||||
community_id: "",
|
||||
address: "",
|
||||
full_address: "",
|
||||
latitude: 0,
|
||||
longitude: 0,
|
||||
is_default: 1
|
||||
},
|
||||
addressValue: "",
|
||||
flag: false, //防重复标识
|
||||
defaultRegions: [],
|
||||
rules: {
|
||||
name: [{
|
||||
required: true,
|
||||
message: "请输入收货人姓名",
|
||||
trigger: "blur"
|
||||
}],
|
||||
mobile: [{
|
||||
required: true,
|
||||
validator: isMobile,
|
||||
trigger: "blur"
|
||||
}],
|
||||
address: [{
|
||||
required: true,
|
||||
message: "请输入详细地址",
|
||||
trigger: "blur"
|
||||
}],
|
||||
full_address: [{
|
||||
required: true,
|
||||
validator: fullAddress,
|
||||
trigger: "blur"
|
||||
}]
|
||||
},
|
||||
province: [],
|
||||
city: [],
|
||||
district: [],
|
||||
pickerValueArray: [],
|
||||
multiIndex: [0, 0, 0],
|
||||
isInitMultiArray: false,
|
||||
// 是否加载完默认地区
|
||||
isLoadDefaultAreas: false,
|
||||
loading: true,
|
||||
yes: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.formData.id = this.$route.query.id
|
||||
this.getAddressDetail()
|
||||
this.getDefaultAreas(0, {
|
||||
level: 0
|
||||
})
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
watch: {
|
||||
defaultRegions: {
|
||||
handler(arr, oldArr = []) {
|
||||
// 避免传的是字面量的时候重复触发
|
||||
if (arr.length !== 3 || arr.join("") === oldArr.join("")) return
|
||||
this.handleDefaultRegions()
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
pickedArr() {
|
||||
// 进行初始化
|
||||
if (this.isInitMultiArray) {
|
||||
return [this.pickerValueArray[0], this.pickerValueArray[1], this.pickerValueArray[2]]
|
||||
}
|
||||
return [this.pickerValueArray[0], this.city, this.district]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 改变省
|
||||
*/
|
||||
changeProvice(id) {
|
||||
this.formData.province_id = id;
|
||||
this.getAreas(id, data => (this.city = data))
|
||||
let obj = {}
|
||||
obj = this.province.find(item => {
|
||||
//这里的province就是上面遍历的数据源
|
||||
return item.id === id //筛选出匹配数据
|
||||
})
|
||||
this.formData.city_id = ""
|
||||
this.formData.district_id = ""
|
||||
this.formData.full_address = obj.name // 设置选中的地址
|
||||
},
|
||||
/**
|
||||
* 改变市
|
||||
*/
|
||||
changeCity(id) {
|
||||
this.formData.city_id = id;
|
||||
this.getAreas(id, data => (this.district = data))
|
||||
let obj = {}
|
||||
obj = this.city.find(item => {
|
||||
//这里的province就是上面遍历的数据源
|
||||
return item.id === id //筛选出匹配数据
|
||||
})
|
||||
this.formData.district_id = ""
|
||||
this.formData.full_address = this.formData.full_address + "-" + obj.name
|
||||
},
|
||||
/**
|
||||
* 改变区
|
||||
*/
|
||||
changeDistrict(id) {
|
||||
this.formData.district_id = id;
|
||||
let obj = {}
|
||||
obj = this.district.find(item => {
|
||||
//这里的province就是上面遍历的数据源
|
||||
return item.id === id //筛选出匹配数据
|
||||
})
|
||||
this.formData.full_address = this.formData.full_address + "-" + obj.name
|
||||
},
|
||||
/**
|
||||
* 获取地址信息
|
||||
*/
|
||||
getAddressDetail() {
|
||||
addressInfo({
|
||||
id: this.formData.id
|
||||
}).then(res => {
|
||||
let data = res.data
|
||||
if (data != null) {
|
||||
this.formData.name = data.name
|
||||
this.formData.mobile = data.mobile
|
||||
this.formData.telephone = data.telephone
|
||||
this.formData.address = data.address
|
||||
this.formData.full_address = data.full_address
|
||||
this.formData.latitude = data.latitude
|
||||
this.formData.longitude = data.longitude
|
||||
this.formData.is_default = data.is_default
|
||||
this.formData.province_id = data.province_id
|
||||
this.formData.city_id = data.city_id
|
||||
this.formData.district_id = data.district_id
|
||||
this.defaultRegions = [data.province_id, data.city_id, data.district_id]
|
||||
}
|
||||
})
|
||||
},
|
||||
// 异步获取地区
|
||||
getAreas(pid, callback) {
|
||||
getArea({
|
||||
pid: pid
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
var data = []
|
||||
res.data.forEach((item, index) => {
|
||||
data.push(item)
|
||||
})
|
||||
if (callback) callback(data)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取省市区列表
|
||||
*/
|
||||
getDefaultAreas(pid, obj) {
|
||||
getArea({
|
||||
pid: pid
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
var data = []
|
||||
var selected = undefined
|
||||
res.data.forEach((item, index) => {
|
||||
if (obj != undefined) {
|
||||
if (obj.level == 0 && obj.province_id != undefined) {
|
||||
selected = obj.province_id
|
||||
} else if (obj.level == 1 && obj.city_id != undefined) {
|
||||
selected = obj.city_id
|
||||
} else if (obj.level == 2 && obj.district_id != undefined) {
|
||||
selected = obj.district_id
|
||||
}
|
||||
}
|
||||
|
||||
if (selected == undefined && index == 0) {
|
||||
selected = item.id
|
||||
}
|
||||
data.push(item)
|
||||
})
|
||||
|
||||
this.pickerValueArray[obj.level] = data
|
||||
if (obj.level + 1 < 3) {
|
||||
obj.level++
|
||||
this.getDefaultAreas(selected, obj)
|
||||
} else {
|
||||
this.isInitMultiArray = true
|
||||
this.isLoadDefaultAreas = true
|
||||
}
|
||||
|
||||
this.province = this.pickerValueArray[0]
|
||||
}
|
||||
setTimeout(() => {
|
||||
this.loading = false
|
||||
}, 500)
|
||||
}).catch(err => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 渲染默认值
|
||||
*/
|
||||
handleDefaultRegions() {
|
||||
var time = setInterval(() => {
|
||||
if (!this.isLoadDefaultAreas) return
|
||||
this.isInitMultiArray = false
|
||||
|
||||
for (let i = 0; i < this.defaultRegions.length; i++) {
|
||||
for (let j = 0; j < this.pickerValueArray[i].length; j++) {
|
||||
this.province = this.pickerValueArray[0]
|
||||
|
||||
// 匹配省
|
||||
if (this.defaultRegions[i] == this.pickerValueArray[i][j].id) {
|
||||
// 设置选中省
|
||||
this.$set(this.multiIndex, i, j)
|
||||
// 查询市
|
||||
this.getAreas(this.pickerValueArray[i][j].id, data => {
|
||||
this.city = data
|
||||
|
||||
for (let k = 0; k < this.city.length; k++) {
|
||||
if (this.defaultRegions[1] == this.city[k].id) {
|
||||
// 设置选中市
|
||||
this.$set(this.multiIndex, 1, k)
|
||||
|
||||
// 查询区县
|
||||
this.getAreas(this.city[k].id, data => {
|
||||
this.district = data
|
||||
|
||||
// 设置选中区县
|
||||
for (let u = 0; u < this.district.length; u++) {
|
||||
if (this.defaultRegions[2] == this.district[u].id) {
|
||||
this.$set(this.multiIndex, 2, u)
|
||||
this.handleValueChange({
|
||||
detail: {
|
||||
value: [j, k, u]
|
||||
}
|
||||
})
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.isLoadDefaultAreas) clearInterval(time)
|
||||
}, 100)
|
||||
},
|
||||
handleValueChange(e) {
|
||||
// 结构赋值
|
||||
let [index0, index1, index2] = e.detail.value
|
||||
let [arr0, arr1, arr2] = this.pickedArr
|
||||
let address = [arr0[index0], arr1[index1], arr2[index2]]
|
||||
|
||||
this.formData.full_address = ""
|
||||
for (let i = 0; i < address.length; i++) {
|
||||
if (this.formData.full_address) {
|
||||
this.formData.full_address = this.formData.full_address + "-" + address[i].name
|
||||
} else {
|
||||
this.formData.full_address = this.formData.full_address + address[i].name
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 保存地址
|
||||
*/
|
||||
saveAddress(formName) {
|
||||
this.$refs[formName].validate(valid => {
|
||||
if (valid) {
|
||||
var data = {
|
||||
name: this.formData.name,
|
||||
mobile: this.formData.mobile,
|
||||
telephone: this.formData.telephone,
|
||||
province_id: this.formData.province_id,
|
||||
city_id: this.formData.city_id,
|
||||
district_id: this.formData.district_id,
|
||||
community_id: "",
|
||||
address: this.formData.address,
|
||||
full_address: this.formData.full_address,
|
||||
latitude: this.formData.latitude,
|
||||
longitude: this.formData.longitude,
|
||||
is_default: this.formData.is_default
|
||||
}
|
||||
|
||||
data.url = "add"
|
||||
if (this.formData.id) {
|
||||
data.url = "edit"
|
||||
data.id = this.formData.id
|
||||
}
|
||||
if (this.flag) return
|
||||
this.flag = true
|
||||
|
||||
saveAddress(data).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$router.push({
|
||||
path: "/member/delivery_address"
|
||||
})
|
||||
} else {
|
||||
this.flag = false
|
||||
this.$message({
|
||||
message: res.message,
|
||||
type: "warning"
|
||||
})
|
||||
}
|
||||
}).catch(err => {
|
||||
this.flag = false
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.el-card.is-always-shadow,
|
||||
.el-card.is-hover-shadow:focus,
|
||||
.el-card.is-hover-shadow:hover {
|
||||
box-shadow: unset;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.ns-len-input {
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
.el-select {
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
||||
308
addon/pc/source/os/pages/member/apply_withdrawal.vue
Executable file
308
addon/pc/source/os/pages/member/apply_withdrawal.vue
Executable file
@@ -0,0 +1,308 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/member/account' }">账户余额</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>提现申请</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
|
||||
<div class="apply-withdrawal" v-loading="loading">
|
||||
<div class="apply-wrap">
|
||||
<div class="apply-account" v-if="bankAccountInfo.withdraw_type" @click="goAccount()">
|
||||
<span class="ns-width">提现到:</span>
|
||||
<div class="apply-account-info">
|
||||
<!-- <span v-if="bankAccountInfo.withdraw_type == 'wechatpay'">{{ bankAccountInfo.mobile }}</span> -->
|
||||
<span v-if="bankAccountInfo.withdraw_type == 'wechatpay'">暂不支持微信提现,请选择支付宝</span>
|
||||
<span v-else>{{ bankAccountInfo.bank_account }}</span>
|
||||
<el-image v-if="bankAccountInfo.withdraw_type == 'alipay'" :src="$img('public/uniapp/member/apply_withdrawal/alipay.png')" fit="contain"/>
|
||||
<el-image v-else-if="bankAccountInfo.withdraw_type == 'bank'" :src="$img('public/uniapp/member/apply_withdrawal/bank.png')" fit="contain"/>
|
||||
<!-- <el-image v-else-if="bankAccountInfo.withdraw_type == 'wechatpay'" :src="$img('public/uniapp/member/apply_withdrawal/wechatpay.png')" fit="contain"></el-image> -->
|
||||
<i class="iconfont iconarrow-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="apply-account" v-else @click="goAccount()">
|
||||
<span class="ns-width">提现账户:</span>
|
||||
<div class="apply-account-info">
|
||||
<span class="ns-text-color">请选择提现账户</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="apply-account-money demo-input-suffix">
|
||||
<span class="ns-width">提现金额:</span>
|
||||
<el-input type="number" placeholder="0" v-model="withdrawMoney" :disabled="bankAccountInfo.withdraw_type == 'wechatpay'">
|
||||
<template slot="prepend">¥</template>
|
||||
</el-input>
|
||||
</div>
|
||||
<div class="apply-account-desc">
|
||||
<p>
|
||||
<span class="ns-width"></span>
|
||||
<span>可提现余额为</span>
|
||||
<span class="balance">¥{{ withdrawInfo.member_info.balance_money | moneyFormat }}</span>
|
||||
<span @click="allTx">全部提现</span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="ns-width"></span>
|
||||
<span>最小提现金额为¥{{ withdrawInfo.config.min | moneyFormat }},手续费为{{ withdrawInfo.config.rate + '%' }}</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="apply-account-btn">
|
||||
<span class="ns-width"></span>
|
||||
<el-button type="primary" size="medium" @click="withdraw" :class="{ disabled: withdrawMoney == '' || withdrawMoney == 0 }" :disabled="bankAccountInfo.withdraw_type == 'wechatpay'">提现</el-button>
|
||||
<!-- <router-link to="/member/withdrawal">提现记录</router-link> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {withdrawInfo, accountInfo, withdraw} from "@/api/member/account"
|
||||
|
||||
export default {
|
||||
name: "apply_withdrawal",
|
||||
layout: "member",
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
withdrawInfo: {
|
||||
config: {
|
||||
is_use: 0,
|
||||
min: 1,
|
||||
rate: 0
|
||||
},
|
||||
member_info: {
|
||||
balance_money: 0,
|
||||
balance_withdraw: 0,
|
||||
balance_withdraw_apply: 0
|
||||
}
|
||||
},
|
||||
bankAccountInfo: {},
|
||||
withdrawMoney: '',
|
||||
isSub: false,
|
||||
loading: true,
|
||||
yes: true
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
/**
|
||||
* 金额格式化输出
|
||||
* @param {Object} money
|
||||
*/
|
||||
moneyFormat(money) {
|
||||
return parseFloat(money).toFixed(2);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getWithdrawInfo();
|
||||
this.getBankAccountInfo();
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 获取提现信息
|
||||
*/
|
||||
getWithdrawInfo() {
|
||||
withdrawInfo().then(res => {
|
||||
if (res.code >= 0 && res.data) {
|
||||
this.withdrawInfo = res.data;
|
||||
if (this.withdrawInfo.config.is_use == 0) {
|
||||
this.$router.push('/member');
|
||||
}
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(err => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 银行账号信息
|
||||
*/
|
||||
getBankAccountInfo() {
|
||||
accountInfo().then(res => {
|
||||
if (res.code >= 0 && res.data) {
|
||||
this.bankAccountInfo = res.data;
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 全部提现
|
||||
*/
|
||||
allTx() {
|
||||
this.withdrawMoney = this.withdrawInfo.member_info.balance_money;
|
||||
},
|
||||
/**
|
||||
* 账户列表
|
||||
*/
|
||||
goAccount() {
|
||||
let back = "/member/apply_withdrawal"
|
||||
this.$router.push({path: "/member/account_list", query: {back: back}})
|
||||
},
|
||||
withdraw() {
|
||||
if (!this.bankAccountInfo.withdraw_type) {
|
||||
this.$message({
|
||||
message: "请先添加提现方式",
|
||||
type: "warning"
|
||||
})
|
||||
return;
|
||||
}
|
||||
if (this.withdrawMoney == '' || this.withdrawMoney == 0 || isNaN(parseFloat(this.withdrawMoney))) {
|
||||
this.$message({
|
||||
message: '请输入提现金额',
|
||||
type: "warning"
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (parseFloat(this.withdrawMoney) > parseFloat(this.withdrawInfo.member_info.balance_money)) {
|
||||
this.$message({
|
||||
message: '提现金额超出可提现金额',
|
||||
type: "warning"
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (parseFloat(this.withdrawMoney) < parseFloat(this.withdrawInfo.config.min)) {
|
||||
this.$message({
|
||||
message: '提现金额小于最低提现金额',
|
||||
type: "warning"
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.isSub) return;
|
||||
this.isSub = true;
|
||||
|
||||
withdraw({
|
||||
apply_money: this.withdrawMoney,
|
||||
transfer_type: this.bankAccountInfo.withdraw_type, //转账提现类型
|
||||
realname: this.bankAccountInfo.realname,
|
||||
mobile: this.bankAccountInfo.mobile,
|
||||
bank_name: this.bankAccountInfo.branch_bank_name,
|
||||
account_number: this.bankAccountInfo.bank_account
|
||||
}).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.$message({
|
||||
message: '提现申请成功!',
|
||||
type: 'success',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push('/member/withdrawal');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.isSub = false;
|
||||
this.$message({
|
||||
message: res.message,
|
||||
type: "warning"
|
||||
});
|
||||
}
|
||||
}).catch(err => {
|
||||
this.isSub = false;
|
||||
this.$message({
|
||||
message: err.message,
|
||||
type: "warning"
|
||||
});
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.apply-withdrawal {
|
||||
width: 100%;
|
||||
background-color: #FFFFFF;
|
||||
|
||||
.apply-wrap {
|
||||
display: inline-block;
|
||||
width: 500px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.apply-account {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
|
||||
.apply-account-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
span {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.el-image {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.apply-account-money {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 30px;
|
||||
|
||||
span {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.apply-account-desc {
|
||||
margin-top: 30px;
|
||||
text-align: left;
|
||||
|
||||
p:first-child {
|
||||
span.balance {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
span:nth-child(4) {
|
||||
color: $base-color;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
p:nth-child(2) {
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.apply-account-btn {
|
||||
margin-top: 30px;
|
||||
|
||||
.el-button {
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ns-width {
|
||||
display: inline-block;
|
||||
width: 115px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
431
addon/pc/source/os/pages/member/collection.vue
Executable file
431
addon/pc/source/os/pages/member/collection.vue
Executable file
@@ -0,0 +1,431 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<div class="collection" v-loading="loading">
|
||||
<el-tabs v-model="activeName" @tab-click="handleClick">
|
||||
<el-tab-pane label="宝贝" name="goods">
|
||||
<div v-if="goodsList.length > 0">
|
||||
<div class="goods">
|
||||
<div class="goods-wrap" v-for="(item, index) in goodsList" :key="item.goods_id">
|
||||
<div class="goods-item">
|
||||
<div class="img" @click="$util.pushToTab({ path: '/sku/' + item.sku_id })">
|
||||
<img :src="$img(item.goods_image.split(',')[0], { size: 'mid' })" @error="imageError(index)" />
|
||||
<i class="del el-icon-delete" @click.stop="deleteGoods(item.goods_id)"></i>
|
||||
</div>
|
||||
<div class="goods-name">{{ item.goods_name }}</div>
|
||||
<div class="price">¥{{ item.price }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pager">
|
||||
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="goodsInfo.page" :page-size="goodsInfo.page_size" background :pager-count="5" prev-text="上一页" next-text="下一页" hide-on-single-page :total="goodsTotal"></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="!loading && !goodsList.length" class="empty">您还没有关注商品哦</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
|
||||
<div class="goods-recommended">
|
||||
<div class="youLike">
|
||||
<span>猜你喜欢</span>
|
||||
</div>
|
||||
<div class="body-wrap">
|
||||
<ul class="goods-list">
|
||||
<li v-for="(item, index) in list" :key="index" :title="item.goods_name" @click="$util.pushToTab({ path: '/sku/' + item.sku_id })">
|
||||
<div class="img-wrap">
|
||||
<img alt="商品图片" :src="$img(item.goods_image.split(',')[0], {size: 'mid'})" @error="imageImgError(index)" />
|
||||
</div>
|
||||
<h3>{{ item.goods_name }}</h3>
|
||||
<p class="price">
|
||||
<span class="num">{{ item.discount_price }}元</span>
|
||||
<del>{{ item.market_price }}元</del>
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
goodsCollect,
|
||||
deleteGoods
|
||||
} from "@/api/member/collection"
|
||||
import {
|
||||
mapGetters
|
||||
} from "vuex"
|
||||
import {
|
||||
goodsRecommend
|
||||
} from '@/api/goods/goods';
|
||||
|
||||
export default {
|
||||
name: "collection",
|
||||
layout: "member",
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
goodsInfo: {
|
||||
page: 1,
|
||||
page_size: 10
|
||||
},
|
||||
shopInfo: {
|
||||
page: 1,
|
||||
page_size: 10
|
||||
},
|
||||
activeName: "goods",
|
||||
goodsTotal: 0,
|
||||
goodsList: [],
|
||||
loading: true,
|
||||
yes: true,
|
||||
list: [],
|
||||
page: 1,
|
||||
pageSize: 5
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getGoodsCollect()
|
||||
this.getGoodsRecommend()
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["defaultGoodsImage"])
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
// 获取推荐商品列列表
|
||||
getGoodsRecommend() {
|
||||
goodsRecommend({
|
||||
page: this.page,
|
||||
page_size: this.pageSize
|
||||
}).then(res => {
|
||||
if (res.code == 0) this.list = res.data.list;
|
||||
this.loading = false;
|
||||
}).catch(res => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
//获取关注商品
|
||||
getGoodsCollect() {
|
||||
goodsCollect(this.goodsInfo).then(res => {
|
||||
this.goodsTotal = res.data.count
|
||||
this.goodsList = res.data.list
|
||||
this.loading = false
|
||||
}).catch(err => {
|
||||
this.loading = false
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
},
|
||||
//删除关注商品
|
||||
deleteGoods(id) {
|
||||
deleteGoods({
|
||||
goods_id: id
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message({
|
||||
message: "取消关注成功",
|
||||
type: "success"
|
||||
})
|
||||
this.getGoodsCollect()
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
},
|
||||
handleClick(tab, event) {
|
||||
if (tab.index == "0") {
|
||||
this.loading = true
|
||||
this.getGoodsCollect()
|
||||
}
|
||||
},
|
||||
handleSizeChange(size) {
|
||||
this.goodsInfo.page_size = size
|
||||
this.loading = true
|
||||
this.getGoodsCollect()
|
||||
},
|
||||
handleCurrentChange(page) {
|
||||
this.goodsInfo.page = page
|
||||
this.loading = true
|
||||
this.getGoodsCollect()
|
||||
},
|
||||
imageError(index) {
|
||||
this.goodsList[index].sku_image = this.defaultGoodsImage
|
||||
},
|
||||
imageImgError(index) {
|
||||
this.list[index].sku_image = this.defaultGoodsImage;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.goods-recommended {
|
||||
width: 100%;
|
||||
margin-top: 15px;
|
||||
background-color: #fff;
|
||||
|
||||
.youLike {
|
||||
width: 955px;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 2px solid #dedede;
|
||||
margin: 0 20px 20px;
|
||||
|
||||
span {
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
padding: 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.body-wrap {
|
||||
.goods-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
width: 23%;
|
||||
margin-left: 19px;
|
||||
margin-bottom: 20px;
|
||||
background: #fff;
|
||||
cursor: pointer;
|
||||
padding: 10px 0;
|
||||
transition: all 0.2s linear;
|
||||
|
||||
&:hover {
|
||||
z-index: 2;
|
||||
-webkit-box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1);
|
||||
box-shadow: 0 15px 30px rgba(0, 0, 0, 0.1);
|
||||
-webkit-transform: translate3d(0, -2px, 0);
|
||||
transform: translate3d(0, -2px, 0);
|
||||
}
|
||||
|
||||
.img-wrap {
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
margin: 0 auto 18px;
|
||||
text-align: center;
|
||||
line-height: 160px;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
margin: 5px 15px;
|
||||
}
|
||||
|
||||
.desc {
|
||||
margin: 0 30px 10px;
|
||||
height: 20px;
|
||||
font-size: 12px;
|
||||
color: #b0b0b0;
|
||||
text-align: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.price {
|
||||
margin: 0 10px 14px;
|
||||
text-align: center;
|
||||
color: $base-color;
|
||||
|
||||
del {
|
||||
margin-left: 0.5em;
|
||||
color: #b0b0b0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-wrap {
|
||||
margin-top: 10px;
|
||||
width: $width;
|
||||
height: 118px;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.collection {
|
||||
background: #ffffff;
|
||||
padding: 10px 20px;
|
||||
|
||||
.goods {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.goods-wrap {
|
||||
width: 19%;
|
||||
margin-right: 1.25%;
|
||||
margin-bottom: 20px;
|
||||
|
||||
&:nth-child(5n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.goods-item {
|
||||
border: 1px solid #f1f1f1;
|
||||
box-sizing: border-box;
|
||||
padding: 10px;
|
||||
|
||||
.img {
|
||||
width: 100%;
|
||||
height: 160px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.del {
|
||||
font-size: 20px;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
padding: 3px;
|
||||
background: rgba($color: #000000, $alpha: 0.3);
|
||||
display: none;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.del {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.goods-name {
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
height: 55px;
|
||||
}
|
||||
|
||||
.price {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.shop {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.shop-wrap {
|
||||
margin: 0 15px 20px 0;
|
||||
|
||||
&:nth-child(5n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.shop-item {
|
||||
width: 156px;
|
||||
height: 227px;
|
||||
border: 1px solid #eeeeee;
|
||||
padding: 0 10px;
|
||||
cursor: pointer;
|
||||
|
||||
.head-wrap {
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
position: relative;
|
||||
|
||||
.del {
|
||||
font-size: 20px;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
padding: 3px;
|
||||
background: rgba($color: #000000, $alpha: 0.3);
|
||||
display: none;
|
||||
color: #ffffff;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.del {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.img-wrap {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.name {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.tag {
|
||||
margin-left: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.info-wrap {
|
||||
padding: 10px 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.page {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
272
addon/pc/source/os/pages/member/coupon.vue
Executable file
272
addon/pc/source/os/pages/member/coupon.vue
Executable file
@@ -0,0 +1,272 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card member-coupon">
|
||||
<div slot="header" class="clearfix"><span>我的优惠券</span></div>
|
||||
|
||||
<div>
|
||||
|
||||
<div v-loading="loading">
|
||||
<el-tabs v-model="couponstatus" @tab-click="handleClickStatus">
|
||||
<el-tab-pane label="未使用" name="1"></el-tab-pane>
|
||||
<el-tab-pane label="已使用" name="2"></el-tab-pane>
|
||||
<el-tab-pane label="已过期" name="3"></el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<div class="coupon-wrap">
|
||||
<div class="text item" :class="state == '1' ? 'coupon-not-used' : state == '2' ? 'coupon-used' : 'coupon-expire'" v-for="(item, index) in couponList" :key="index" @click="useCoupon(item)">
|
||||
<template>
|
||||
<p class="coupon-wrap-money" v-if="item.discount == '0.00' || !item.discount">
|
||||
¥
|
||||
<span>{{ item.money }}</span>
|
||||
</p>
|
||||
<p class="coupon-wrap-money" v-else>
|
||||
<span>{{ item.discount }}</span>
|
||||
折
|
||||
</p>
|
||||
</template>
|
||||
<p class="coupon-wrap-name">{{ item.platformcoupon_name }}</p>
|
||||
<template>
|
||||
<p class="coupon-wrap-least coupon-wrap-info" v-if="item.at_least > 0">满{{ item.at_least }}元可用</p>
|
||||
<p class="coupon-wrap-least coupon-wrap-info" v-else>无门槛优惠券</p>
|
||||
</template>
|
||||
<template>
|
||||
<p class="coupon-wrap-time coupon-wrap-info">{{item.end_time > 0 ? '有效期至' + $timeStampTurnTime(item.end_time) : '长期有效' }}</p>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div class="empty-text" v-if="couponList.length == 0">{{ text }}</div>
|
||||
</div>
|
||||
|
||||
<div class="pager">
|
||||
<el-pagination
|
||||
background
|
||||
:pager-count="5"
|
||||
:total="total"
|
||||
prev-text="上一页"
|
||||
next-text="下一页"
|
||||
:current-page.sync="currentPage"
|
||||
:page-size.sync="pageSize"
|
||||
@size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange"
|
||||
hide-on-single-page
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {couponList as getCouponList} from '@/api/member/member';
|
||||
import {mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'my_coupon',
|
||||
layout: "member",
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 9,
|
||||
couponstatus: '1',
|
||||
couponList: [],
|
||||
type: '',
|
||||
state: 1,
|
||||
text: '您还没有优惠券哦',
|
||||
loading: true,
|
||||
yes: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
if (this.addonIsExit && this.addonIsExit.coupon != 1) {
|
||||
this.$message({
|
||||
message: '优惠券插件未安装',
|
||||
type: 'warning',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$route.push('/member');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.getListData();
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['addonIsExit'])
|
||||
},
|
||||
watch: {
|
||||
addonIsExit() {
|
||||
if (this.addonIsExit.coupon != 1) {
|
||||
this.$message({
|
||||
message: '优惠券插件未安装',
|
||||
type: 'warning',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$route.push('/member');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 优惠券状态(未使用/已使用/已过期)
|
||||
*/
|
||||
handleClickStatus(tab, event) {
|
||||
if (tab.name == '1') {
|
||||
this.state = 1;
|
||||
this.text = '您还没有优惠券哦';
|
||||
} else if (tab.name == '2') {
|
||||
this.state = 2;
|
||||
this.text = '您还没有使用过优惠券哦';
|
||||
} else {
|
||||
this.state = 3;
|
||||
this.text = '您还没有过期优惠券哦';
|
||||
}
|
||||
this.refresh();
|
||||
},
|
||||
handlePageSizeChange(size) {
|
||||
this.pageSize = size;
|
||||
this.refresh();
|
||||
},
|
||||
handleCurrentPageChange(page) {
|
||||
this.currentPage = page;
|
||||
this.refresh();
|
||||
},
|
||||
refresh() {
|
||||
this.loading = true;
|
||||
this.getListData();
|
||||
},
|
||||
// 获取优惠券列表
|
||||
getListData() {
|
||||
getCouponList({
|
||||
page: this.currentPage,
|
||||
page_size: this.pageSize,
|
||||
state: this.state,
|
||||
is_own: this.type,
|
||||
}).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.total = res.data.count;
|
||||
this.couponList = res.data.list;
|
||||
}
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
},
|
||||
// 去使用优惠券
|
||||
useCoupon(item) {
|
||||
if (item.state == 1) {
|
||||
if (item.use_scenario != 1) {
|
||||
this.$router.push({path: '/goods/list', query: {coupon: item.coupon_type_id}});
|
||||
} else {
|
||||
this.$router.push('/goods/list');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.el-card.is-always-shadow,
|
||||
.el-card.is-hover-shadow:focus,
|
||||
.el-card.is-hover-shadow:hover {
|
||||
box-shadow: unset;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.coupon-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.text {
|
||||
width: 32%;
|
||||
height: 140px;
|
||||
margin-right: 2%;
|
||||
border-radius: 5px;
|
||||
border: 1px dashed #fff;
|
||||
margin-bottom: 20px;
|
||||
padding: 0 15px;
|
||||
box-sizing: border-box;
|
||||
color: #ffffff;
|
||||
|
||||
.coupon-wrap-money {
|
||||
span {
|
||||
font-size: 30px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.coupon-wrap-info {
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.text:nth-child(3n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.coupon-not-used {
|
||||
background-color: $base-color;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.coupon-used {
|
||||
background-color: hsl(360, 50%, 70%);
|
||||
}
|
||||
|
||||
.coupon-expire {
|
||||
background-color: #d0d0d0;
|
||||
}
|
||||
|
||||
.coupon-wrap-info {
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.empty-text {
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.member-coupon {
|
||||
.el-tabs__active-bar,
|
||||
.el-tabs__nav-wrap::after {
|
||||
/* 清除tab标签底部横线 */
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
280
addon/pc/source/os/pages/member/delivery_address.vue
Executable file
280
addon/pc/source/os/pages/member/delivery_address.vue
Executable file
@@ -0,0 +1,280 @@
|
||||
<template>
|
||||
<div class="box" v-loading="loading">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>收货地址</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="ns-member-address-list">
|
||||
<div class="text item ns-add-address" @click="addAddress('add')">
|
||||
<span>+ 添加收货地址</span>
|
||||
</div>
|
||||
|
||||
<div class="text item" v-for="(item, index) in addressList" :key="index">
|
||||
<div class="text-name">
|
||||
<span>{{ item.name }}</span>
|
||||
<span v-if="item.is_default == 1" class="text-default">默认</span>
|
||||
</div>
|
||||
|
||||
<div class="text-content">
|
||||
<p>{{ item.mobile }}</p>
|
||||
<p :title="item.full_address + item.address" class="ns-address-detail">
|
||||
{{ item.full_address }}{{ item.address }}</p>
|
||||
</div>
|
||||
|
||||
<div class="text-operation">
|
||||
<span v-if="item.is_default != 1" @click="setDefault(item.id)">设为默认</span>
|
||||
<span @click="addAddress('edit', item.id)">编辑</span>
|
||||
<span v-if="item.is_default != 1" @click="delAddress(item.id, item.is_default)">删除</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pager">
|
||||
<el-pagination background :pager-count="5" :total="total" prev-text="上一页" next-text="下一页"
|
||||
:current-page.sync="currentPage" :page-size.sync="pageSize" @size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange" hide-on-single-page></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
addressList,
|
||||
setDefault,
|
||||
deleteAddress
|
||||
} from "@/api/member/member"
|
||||
|
||||
export default {
|
||||
name: "delivery_address",
|
||||
layout: "member",
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
addressList: [],
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 8,
|
||||
loading: true,
|
||||
yes: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getListData()
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
getListData() {
|
||||
addressList({
|
||||
page: this.currentPage,
|
||||
page_size: this.pageSize,
|
||||
type: 1
|
||||
})
|
||||
.then(res => {
|
||||
const {
|
||||
count,
|
||||
page_count,
|
||||
list
|
||||
} = res.data
|
||||
this.total = count
|
||||
this.addressList = list
|
||||
this.loading = false
|
||||
})
|
||||
.catch(err => {
|
||||
this.loading = false
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
},
|
||||
handlePageSizeChange(size) {
|
||||
this.pageSize = size
|
||||
this.refresh()
|
||||
},
|
||||
handleCurrentPageChange(page) {
|
||||
this.currentPage = page
|
||||
this.refresh()
|
||||
},
|
||||
refresh() {
|
||||
this.loading = true
|
||||
this.getListData()
|
||||
},
|
||||
/**
|
||||
* 设为默认
|
||||
*/
|
||||
setDefault(id) {
|
||||
setDefault({
|
||||
id: id
|
||||
}).then(res => {
|
||||
this.refresh()
|
||||
this.$message({
|
||||
message: "修改默认地址成功",
|
||||
type: "success"
|
||||
})
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 添加/编辑地址
|
||||
*/
|
||||
addAddress(type, id) {
|
||||
if (type == "edit") {
|
||||
this.$router.push({
|
||||
path: "/member/address_edit",
|
||||
query: {
|
||||
id: id
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$router.push({
|
||||
path: "/member/address_edit"
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除地址
|
||||
*/
|
||||
delAddress(id, is_default) {
|
||||
this.$confirm("确定要删除该地址吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(() => {
|
||||
if (is_default == 1) {
|
||||
this.$message({
|
||||
type: "warning",
|
||||
message: "默认地址,不能删除!"
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
deleteAddress({
|
||||
id: id
|
||||
}).then(res => {
|
||||
this.refresh()
|
||||
this.$message({
|
||||
message: res.message,
|
||||
type: "success"
|
||||
})
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.el-card.is-always-shadow,
|
||||
.el-card.is-hover-shadow:focus,
|
||||
.el-card.is-hover-shadow:hover {
|
||||
box-shadow: unset;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.ns-member-address-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.text {
|
||||
width: 32%;
|
||||
height: 140px;
|
||||
margin-right: 2%;
|
||||
border-radius: 5px;
|
||||
border: 1px solid #d8d8d8;
|
||||
margin-bottom: 20px;
|
||||
padding: 0 15px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.text-name {
|
||||
height: 37px;
|
||||
line-height: 40px;
|
||||
padding: 0 10px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
}
|
||||
|
||||
.text-default {
|
||||
display: inline-block;
|
||||
margin-left: 10px;
|
||||
background: $base-color;
|
||||
color: #ffffff;
|
||||
width: 35px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.text-content {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.ns-address-detail {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.text-operation {
|
||||
// 操作
|
||||
text-align: right;
|
||||
|
||||
span {
|
||||
margin: 0 5px;
|
||||
color: #999999;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
span:hover {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text:nth-child(3n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.ns-add-address {
|
||||
border: 1px dashed #d8d8d8;
|
||||
text-align: center;
|
||||
color: #999999;
|
||||
line-height: 140px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ns-add-address:hover {
|
||||
border-color: $base-color;
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
223
addon/pc/source/os/pages/member/footprint.vue
Executable file
223
addon/pc/source/os/pages/member/footprint.vue
Executable file
@@ -0,0 +1,223 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card foot-print">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>我的足迹</span>
|
||||
</div>
|
||||
|
||||
<div v-loading="loading" v-if="timesArr != ''">
|
||||
<el-timeline>
|
||||
<el-timeline-item class="ns-time-line" v-for="(item, index) in timesArr" :timestamp="item" placement="top" :key="index">
|
||||
<el-card>
|
||||
<div class="ns-goods-list">
|
||||
<div class="ns-goods-li" v-for="(value, name) in footPrintData" :key="name" v-if="item == value.browse_time" @click="$util.pushToTab('/sku/' + value.sku_id)">
|
||||
<span class="ns-btn-del" @click.stop="deleteFootprint(value.id)"><i class="iconfont icon-shanchu"></i></span>
|
||||
<el-image :src="$img(value.goods_image, { size: 'mid' })" fit="contain" @error="imageError(name)"/>
|
||||
<p class="goods-name" :title="value.goods_name">{{ value.goods_name }}</p>
|
||||
<span class="goods-price">¥{{ value.goods_price }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</div>
|
||||
<div v-else class="footprint">
|
||||
<router-link to="/">暂时没有足迹~</router-link>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {footPrint, delFootprint} from "@/api/member/member"
|
||||
import {mapGetters} from "vuex"
|
||||
|
||||
export default {
|
||||
name: "footprint",
|
||||
layout: "member",
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
timesArr: [],
|
||||
footPrintData: [],
|
||||
loading: true,
|
||||
yes: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getFootPrintData()
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["defaultGoodsImage"])
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 商品列表
|
||||
*/
|
||||
getFootPrintData() {
|
||||
footPrint({
|
||||
page: 1,
|
||||
page_size: 0
|
||||
}).then(res => {
|
||||
var data = res.data.list
|
||||
this.footPrintData = []
|
||||
this.timesArr = []
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
var date = this.$util.timeStampTurnTime(data[i].browse_time).split(" ")[0]
|
||||
var flag = this.$util.inArray(date, this.timesArr)
|
||||
if (flag == -1) {
|
||||
this.timesArr.push(date)
|
||||
}
|
||||
var goods = {}
|
||||
goods.id = data[i].id
|
||||
goods.sku_id = data[i].sku_id
|
||||
goods.browse_time = date
|
||||
goods.goods_image = data[i].sku_image.split(",")[0]
|
||||
goods.goods_name = data[i].sku_name
|
||||
goods.goods_price = data[i].discount_price
|
||||
|
||||
this.footPrintData.push(goods)
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(err => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 图片加载失败
|
||||
*/
|
||||
imageError(index) {
|
||||
this.footPrintData[index].goods_image = this.defaultGoodsImage
|
||||
},
|
||||
/**
|
||||
* 删除某个足迹
|
||||
*/
|
||||
deleteFootprint(id) {
|
||||
delFootprint({
|
||||
id: id
|
||||
}).then(res => {
|
||||
this.loading = false
|
||||
this.getFootPrintData()
|
||||
this.$message({message: res.message, type: "success"})
|
||||
}).catch(err => {
|
||||
this.loading = false
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
},
|
||||
mouseenter(scope) {
|
||||
this.$set(scope, "del", true)
|
||||
},
|
||||
mouseleave(scope) {
|
||||
this.$set(scope, "del", false)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.footprint {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.el-card.is-always-shadow,
|
||||
.el-card.is-hover-shadow:focus,
|
||||
.el-card.is-hover-shadow:hover {
|
||||
box-shadow: unset;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.ns-goods-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.ns-goods-li {
|
||||
width: 32%;
|
||||
margin-right: 2%;
|
||||
margin-bottom: 20px;
|
||||
padding: 15px;
|
||||
box-sizing: border-box;
|
||||
background-color: #f1f1f1;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
|
||||
.el-image {
|
||||
width: 100%;
|
||||
height: 250px;
|
||||
}
|
||||
|
||||
.goods-name {
|
||||
margin-top: 10px;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.goods-price {
|
||||
color: $base-color;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.ns-btn-del {
|
||||
position: absolute;
|
||||
top: -6px;
|
||||
right: -6px;
|
||||
color: #999999;
|
||||
cursor: pointer;
|
||||
display: none;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
text-align: center;
|
||||
line-height: 20px;
|
||||
|
||||
i {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.ns-btn-del {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ns-goods-li:nth-child(3n) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="scss">
|
||||
.foot-print .ns-time-line .el-timeline-item__timestamp.is-top {
|
||||
font-size: 18px;
|
||||
color: #333333;
|
||||
}
|
||||
</style>
|
||||
720
addon/pc/source/os/pages/member/index.vue
Executable file
720
addon/pc/source/os/pages/member/index.vue
Executable file
@@ -0,0 +1,720 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<div class="member-index" v-loading="loading">
|
||||
<div class="member-top">
|
||||
<div class="info-wrap">
|
||||
<div class="info-top">
|
||||
<div class="avtar">
|
||||
<router-link to="/member/info">
|
||||
<img v-if="member.headimg" :src="$img(member.headimg)" @error="member.headimg = defaultHeadImage" />
|
||||
<img v-else :src="$img(defaultHeadImage)" />
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="member-wrap">
|
||||
<template v-if="member">
|
||||
<div class="name member-name" v-if="member.nickname">
|
||||
<router-link to="/member/info">{{ member.nickname }}</router-link>
|
||||
</div>
|
||||
<div class="level" v-if="member.member_level_name">{{ member.member_level_name }}</div>
|
||||
<div class="growth">
|
||||
成长值:
|
||||
<el-progress :text-inside="true" :stroke-width="10" :percentage="progress" :show-text="false"></el-progress>
|
||||
<div></div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="no-login name" v-else>未登录</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="account">
|
||||
<div class="content">
|
||||
<div class="item">
|
||||
<router-link to="/member/coupon" class="item-content">
|
||||
<img src="@/assets/images/coupon.png" alt />
|
||||
<div class="name">优惠券</div>
|
||||
<div class="num" v-if="member.member_id && couponNum">{{ couponNum }}</div>
|
||||
<div class="num" v-else>0</div>
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<div class="item">
|
||||
<router-link to="/member/my_point" class="item-content">
|
||||
<img src="@/assets/images/point.png" alt />
|
||||
<div class="name">积分</div>
|
||||
<div class="num" v-if="member.point">{{ member.point }}</div>
|
||||
<div class="num" v-else>0</div>
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="item">
|
||||
<router-link to="/member/account" class="item-content">
|
||||
<img src="@/assets/images/balance.png" alt />
|
||||
<div class="name">余额</div>
|
||||
<div class="num" v-if="member.balance || member.balance_money">{{ (parseFloat(member.balance) + parseFloat(member.balance_money)).toFixed(2) }}</div>
|
||||
<div class="num" v-else>0</div>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collection">
|
||||
<router-link to="/member/collection" class="item-content">
|
||||
<div class="title">我的关注</div>
|
||||
<div class="xian"></div>
|
||||
<div class="item-wrap">
|
||||
<div class="item">
|
||||
<div class="num">{{ goodsTotal }}</div>
|
||||
<div class="collect">商品关注</div>
|
||||
</div>
|
||||
</div>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<div class="member-bottom">
|
||||
<div class="my-order">
|
||||
<div class="order-title">我的订单</div>
|
||||
<div class="xian"></div>
|
||||
<div class="order-item">
|
||||
<router-link to="/member/order_list?status=waitpay" class="item">
|
||||
<i class="iconfont icon-daifukuan"></i>
|
||||
<div v-if="orderNum.waitPay" class="order-num">{{ orderNum.waitPay }}</div>
|
||||
<div class="name">待付款</div>
|
||||
</router-link>
|
||||
<router-link to="/member/order_list?status=waitsend" class="item">
|
||||
<i class="iconfont icon-daifahuo"></i>
|
||||
<div v-if="orderNum.readyDelivery" class="order-num">{{ orderNum.readyDelivery }}</div>
|
||||
<div class="name">待发货</div>
|
||||
</router-link>
|
||||
<router-link to="/member/order_list?status=waitconfirm" class="item">
|
||||
<i class="iconfont icon-tubiaolunkuo-"></i>
|
||||
<div v-if="orderNum.waitDelivery" class="order-num">{{ orderNum.waitDelivery }}</div>
|
||||
<div class="name">待收货</div>
|
||||
</router-link>
|
||||
<router-link to="/member/order_list?status=waitrate" class="item">
|
||||
<i class="iconfont icon-daipingjia"></i>
|
||||
<div v-if="orderNum.waitEvaluate" class="order-num">{{ orderNum.waitEvaluate }}</div>
|
||||
<div class="name">待评价</div>
|
||||
</router-link>
|
||||
<router-link to="/member/activist" class="item">
|
||||
<i class="iconfont icon-shouhou"></i>
|
||||
<div v-if="orderNum.refunding" class="order-num">{{ orderNum.refunding }}</div>
|
||||
<div class="name">退款/售后</div>
|
||||
</router-link>
|
||||
</div>
|
||||
<div v-if="orderList.length">
|
||||
<div class="order-goods-wrap" v-for="(orderItem, orderIndex) in orderList" :key="orderIndex">
|
||||
<div class="order-goods" v-for="(goodsItem, goodsIndex) in orderItem.order_goods" :key="goodsIndex">
|
||||
<div class="goods-item">
|
||||
<div class="goods-img" @click="$util.pushToTab({ path: '/sku/' + goodsItem.sku_id })">
|
||||
<img :src="$img(goodsItem.sku_image, { size: 'mid' })" @error="imageErrorOrder(orderIndex, goodsIndex)" />
|
||||
</div>
|
||||
<div class="info-wrap">
|
||||
<div class="goods-name" @click="$util.pushToTab({ path: '/sku/' + goodsItem.sku_id })">{{ goodsItem.sku_name }}</div>
|
||||
<div class="price">¥{{ goodsItem.price }}</div>
|
||||
</div>
|
||||
<div class="payment">{{ orderItem.order_status_name }}</div>
|
||||
<div class="goods-detail" @click="orderDetail(orderItem)">
|
||||
<p>查看详情</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="empty" v-else>
|
||||
<img src="@/assets/images/member-empty.png" alt />
|
||||
<div>
|
||||
<router-link to="/">您买的东西太少了,这里都空空的,快去挑选合适的商品吧!</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-right">
|
||||
<div class="my-foot">
|
||||
<div class="title">我的足迹</div>
|
||||
<div class="xian"></div>
|
||||
<div class="foot-content" v-for="(item, index) in footList" :key="item.goods_id">
|
||||
<div class="foot-item" @click="$util.pushToTab({ path: '/sku/' + item.sku_id })">
|
||||
<div class="foot-img">
|
||||
<img :src="$img(item.sku_image, { size: 'mid' })" @error="imageErrorFoot(index)" />
|
||||
</div>
|
||||
<div class="foot-info">
|
||||
<div class="foot-name">{{ item.goods_name }}</div>
|
||||
<div class="foot-price">¥{{ item.discount_price }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
orderNum,
|
||||
couponNum,
|
||||
footprint,
|
||||
levelList
|
||||
} from '@/api/member/index';
|
||||
import {
|
||||
goodsCollect
|
||||
} from '@/api/member/collection';
|
||||
import {
|
||||
apiOrderList
|
||||
} from '@/api/order/order';
|
||||
import {
|
||||
mapGetters
|
||||
} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'member',
|
||||
components: {},
|
||||
layout: 'member',
|
||||
data: () => {
|
||||
return {
|
||||
couponNum: 0,
|
||||
orderNum: {
|
||||
waitPay: 0, //待付款
|
||||
readyDelivery: 0, //待发货
|
||||
waitDelivery: 0, //待收货
|
||||
refunding: 0 // 退款中
|
||||
},
|
||||
orderList: [],
|
||||
orderStatus: 'all',
|
||||
footInfo: {
|
||||
page: 1,
|
||||
page_size: 6
|
||||
},
|
||||
total: 0,
|
||||
footList: [],
|
||||
currentPage: 1,
|
||||
loading: true,
|
||||
goodsTotal: 0,
|
||||
state: '',
|
||||
growth: '',
|
||||
levelList: [],
|
||||
member_level: {},
|
||||
progress: 0,
|
||||
yes: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getCouponNum();
|
||||
this.getOrderNum();
|
||||
this.getOrderList();
|
||||
this.getFootprint();
|
||||
this.getGoodsCollect();
|
||||
// this.$store.dispatch("member/member_detail")
|
||||
|
||||
this.$forceUpdate()
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultHeadImage', 'defaultGoodsImage', 'member'])
|
||||
},
|
||||
watch: {
|
||||
member: {
|
||||
handler() {
|
||||
if (this.member) this.getLevelList();
|
||||
},
|
||||
immediate: true,
|
||||
deep: true,
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false;
|
||||
}, 300);
|
||||
},
|
||||
methods: {
|
||||
getLevelList() {
|
||||
levelList().then(res => {
|
||||
if (res.data && res.code == 0) {
|
||||
this.levelList = res.data;
|
||||
let listIndex = this.levelList.findIndex(item => item.level_id == this.member.member_level);
|
||||
|
||||
const max = this.levelList.length;
|
||||
if (max > listIndex + 1) {
|
||||
if (this.member.growth > this.levelList[listIndex + 1].growth) {
|
||||
this.progress = 100;
|
||||
} else {
|
||||
this.progress = (this.member.growth / this.levelList[listIndex + 1].growth) * 100;
|
||||
}
|
||||
} else {
|
||||
this.progress = 100;
|
||||
}
|
||||
} else {
|
||||
this.$message.error(err.message);
|
||||
}
|
||||
})
|
||||
},
|
||||
//获取优惠券数量
|
||||
getCouponNum() {
|
||||
couponNum().then(res => {
|
||||
this.couponNum = res.data;
|
||||
})
|
||||
},
|
||||
//获取订单数量
|
||||
getOrderNum() {
|
||||
orderNum({
|
||||
order_status: 'waitpay,waitsend,waitconfirm,waitrate,refunding'
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.orderNum.waitPay = res.data.waitpay;
|
||||
this.orderNum.readyDelivery = res.data.waitsend;
|
||||
this.orderNum.waitDelivery = res.data.waitconfirm;
|
||||
this.orderNum.waitEvaluate = res.data.waitrate;
|
||||
this.orderNum.refunding = res.data.refunding;
|
||||
}
|
||||
})
|
||||
},
|
||||
//获取订单列表
|
||||
getOrderList() {
|
||||
apiOrderList({
|
||||
order_status: this.orderStatus,
|
||||
page: 1,
|
||||
page_size: 3
|
||||
}).then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.orderList = res.data.list;
|
||||
}
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
},
|
||||
//获取我的足迹
|
||||
getFootprint() {
|
||||
footprint(this.footInfo).then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.footList = res.data.list;
|
||||
this.total = res.data.count;
|
||||
}
|
||||
})
|
||||
},
|
||||
orderDetail(data) {
|
||||
switch (parseInt(data.order_type)) {
|
||||
case 2:
|
||||
// 自提订单
|
||||
this.$router.push({
|
||||
path: '/member/order_detail_pickup',
|
||||
query: {
|
||||
order_id: data.order_id
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 3:
|
||||
// 本地配送订单
|
||||
this.$router.push({
|
||||
path: '/member/order_detail_local_delivery',
|
||||
query: {
|
||||
order_id: data.order_id
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 4:
|
||||
// 虚拟订单
|
||||
this.$router.push({
|
||||
path: '/member/order_detail_virtual',
|
||||
query: {
|
||||
order_id: data.order_id
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
this.$router.push({
|
||||
path: '/member/order_detail',
|
||||
query: {
|
||||
order_id: data.order_id
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
imageErrorOrder(orderIndex, goodsIndex) {
|
||||
this.orderList[orderIndex].order_goods[goodsIndex].sku_image = this.defaultGoodsImage;
|
||||
},
|
||||
imageErrorFoot(index) {
|
||||
this.footList[index].sku_image = this.defaultGoodsImage;
|
||||
},
|
||||
getGoodsCollect() {
|
||||
goodsCollect()
|
||||
.then(res => {
|
||||
this.goodsTotal = res.data.count;
|
||||
})
|
||||
.catch(err => {
|
||||
this.loading = false;
|
||||
console.log(err.message);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #ffffff;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.member-index {
|
||||
.member-top {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
|
||||
.info-wrap {
|
||||
width: 75%;
|
||||
height: 160px;
|
||||
border: 1px solid #e9e9e9;
|
||||
background: #ffffff;
|
||||
display: flex;
|
||||
|
||||
.info-top {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 22px;
|
||||
margin-right: 0;
|
||||
width: 300px;
|
||||
border-right: 1px solid #e9e9e9;
|
||||
|
||||
.avtar {
|
||||
width: 84px;
|
||||
height: 84px;
|
||||
margin: 20px 0 10px 0;
|
||||
border: 1px solid #e9e9e9;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
margin-left: 21px;
|
||||
text-align: center;
|
||||
line-height: 84px;
|
||||
|
||||
img {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.member-wrap {
|
||||
margin-left: 20px;
|
||||
|
||||
.name {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.growth {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.el-progress {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.level {
|
||||
padding: 3px 4px;
|
||||
line-height: 1;
|
||||
color: #ffffc1;
|
||||
margin: 6px 0;
|
||||
cursor: default;
|
||||
background: linear-gradient(#636362, #4e4e4d);
|
||||
border-radius: 3px;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.account {
|
||||
width: 400px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
|
||||
.item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.item-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.name {
|
||||
margin-top: 5px;
|
||||
color: #666666;
|
||||
|
||||
&:hover {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
|
||||
.num {
|
||||
color: $ns-text-color-black;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.collection {
|
||||
background: #ffffff;
|
||||
margin-left: 20px;
|
||||
width: 210px;
|
||||
border: 1px solid #e9e9e9;
|
||||
padding-left: 20px;
|
||||
|
||||
.title {
|
||||
padding: 10px 0;
|
||||
display: inline-block;
|
||||
border-bottom: 1px solid $base-color;
|
||||
}
|
||||
|
||||
.xian {
|
||||
height: 1px;
|
||||
background: #f1f1f1;
|
||||
}
|
||||
|
||||
.item-wrap {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.item {
|
||||
flex: 1;
|
||||
margin-top: 37px;
|
||||
|
||||
.num {
|
||||
}
|
||||
|
||||
.collect {
|
||||
color: #666666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.member-bottom {
|
||||
width: 100%;
|
||||
margin-top: 15px;
|
||||
height: 553px;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
|
||||
.my-order {
|
||||
width: 75%;
|
||||
background-color: #ffffff;
|
||||
|
||||
.order-title {
|
||||
font-size: $ns-font-size-base;
|
||||
padding: 10px 0;
|
||||
margin-left: 15px;
|
||||
border-bottom: 1px solid $base-color;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.xian {
|
||||
height: 1px;
|
||||
background: #f1f1f1;
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.order-item {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
|
||||
.item {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
height: 85px;
|
||||
padding-top: 20px;
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
background: #ffffff;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.order-num {
|
||||
position: absolute;
|
||||
top: 23px;
|
||||
right: 25px;
|
||||
background: $base-color;
|
||||
border-radius: 50%;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
color: #ffff;
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: $ns-font-size-base;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.order-goods {
|
||||
.goods-item {
|
||||
display: flex;
|
||||
padding: 14px;
|
||||
border-top: 1px solid #f1f1f1;
|
||||
|
||||
.goods-img {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
|
||||
img {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
.info-wrap {
|
||||
flex: 3;
|
||||
width: 80%;
|
||||
|
||||
.goods-name {
|
||||
height: 46px;
|
||||
overflow: hidden;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.price {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
|
||||
.payment {
|
||||
flex: 2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.goods-detail {
|
||||
flex: 2;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-right {
|
||||
.my-foot {
|
||||
background: #ffffff;
|
||||
margin-left: 20px;
|
||||
width: 230px;
|
||||
|
||||
.title {
|
||||
font-size: $ns-font-size-base;
|
||||
padding: 10px 0;
|
||||
display: inline-block;
|
||||
border-bottom: 1px solid $base-color;
|
||||
margin: 0 15px;
|
||||
}
|
||||
|
||||
.xian {
|
||||
margin-left: 15px;
|
||||
background: #f1f1f1;
|
||||
height: 1px;
|
||||
}
|
||||
|
||||
.foot-content {
|
||||
.foot-item {
|
||||
display: flex;
|
||||
padding: 10px 0;
|
||||
margin: 0 15px;
|
||||
|
||||
.foot-img {
|
||||
width: 57px;
|
||||
height: 57px;
|
||||
cursor: pointer;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.foot-info {
|
||||
margin-left: 5px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
.foot-name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
line-height: 1;
|
||||
width: 140px;
|
||||
}
|
||||
|
||||
.foot-price {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty {
|
||||
text-align: center;
|
||||
margin-top: 65px;
|
||||
}
|
||||
</style>
|
||||
240
addon/pc/source/os/pages/member/info.vue
Executable file
240
addon/pc/source/os/pages/member/info.vue
Executable file
@@ -0,0 +1,240 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<div class="member-info" v-loading="loading">
|
||||
<el-tabs v-model="activeName" type="card" @tab-click="handleClick">
|
||||
<el-tab-pane label="基本信息" name="first">
|
||||
<el-form ref="infoRef" :model="memberInfo" :rules="infoRules" label-width="80px">
|
||||
<el-form-item label="账号" v-if="memberInfo.userName">
|
||||
<p>{{ memberInfo.userName }}</p>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="邮箱">
|
||||
<p v-if="memberInfo.email">{{ memberInfo.email }}</p>
|
||||
<p v-else class="toBind" @click="$router.push({ path: '/member/security' })">去绑定</p>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="手机号">
|
||||
<p v-if="memberInfo.tell">{{ memberInfo.tell }}</p>
|
||||
<p v-else class="toBind" @click="$router.push({ path: '/member/security' })">去绑定</p>
|
||||
</el-form-item>
|
||||
<el-form-item label="昵称" prop="nickName">
|
||||
<el-input v-model="memberInfo.nickName"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="btn">
|
||||
<el-button size="medium" type="primary" @click="saveInfo">保存</el-button>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="头像照片" name="second">
|
||||
<div class="preview">
|
||||
<div class="title">头像预览</div>
|
||||
<div class="content">
|
||||
完善个人信息资料,上传头像图片有助于您结识更多的朋友。
|
||||
<br />
|
||||
头像最佳默认尺寸为120x120像素。
|
||||
</div>
|
||||
</div>
|
||||
<el-upload :action="uploadActionUrl" :show-file-list="false" :on-success="handleAvatarSuccess" class="upload" accept=".png,.jpg,.jpeg">
|
||||
<div class="img-wrap">
|
||||
<img v-if="memberInfo.userHeadImg" :src="$img(memberInfo.userHeadImg)" />
|
||||
<img v-else :src="$img(defaultHeadImage)" />
|
||||
</div>
|
||||
</el-upload>
|
||||
<div class="btn">
|
||||
<el-button size="medium" type="primary" @click="uploadHeadImg">保存</el-button>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {info, nickName, headImg} from '@/api/member/info';
|
||||
import Config from '@/plugins/config';
|
||||
import {mapGetters} from 'vuex';
|
||||
import {email} from '@/api/member/security';
|
||||
|
||||
export default {
|
||||
name: 'info',
|
||||
layout: "member",
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
memberInfo: {
|
||||
userHeadImg: '',
|
||||
userName: '', //账号
|
||||
nickName: '', //昵称
|
||||
email: '',
|
||||
tell: ''
|
||||
},
|
||||
infoRules: {
|
||||
nickName: [{required: true, message: '请输入昵称', trigger: 'blur'}, {
|
||||
max: 30,
|
||||
message: '最大长度为30个字符',
|
||||
trigger: 'blur'
|
||||
}]
|
||||
},
|
||||
activeName: 'first',
|
||||
loading: true,
|
||||
uploadActionUrl: Config.baseUrl + '/api/upload/headimg',
|
||||
imgUrl: '',
|
||||
yes: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getInfo();
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
getInfo() {
|
||||
info().then(res => {
|
||||
if (res.code == 0) {
|
||||
this.memberInfo.userHeadImg = res.data.headimg;
|
||||
this.memberInfo.userName = res.data.username;
|
||||
this.memberInfo.nickName = res.data.nickname;
|
||||
this.memberInfo.email = res.data.email;
|
||||
this.memberInfo.tell = res.data.mobile;
|
||||
}
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
},
|
||||
handleClick(tab, event) {
|
||||
},
|
||||
saveInfo() {
|
||||
this.$refs.infoRef.validate(valid => {
|
||||
if (valid) {
|
||||
nickName({nickname: this.memberInfo.nickName}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message({message: '修改昵称成功', type: 'success'});
|
||||
this.getInfo();
|
||||
this.$store.dispatch('member/member_detail', {refresh: 1});
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
handleAvatarSuccess(res, file) {
|
||||
this.imgUrl = res.data.pic_path;
|
||||
this.memberInfo.userHeadImg = URL.createObjectURL(file.raw);
|
||||
},
|
||||
uploadHeadImg() {
|
||||
headImg({headimg: this.imgUrl}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message({message: '头像修改成功', type: 'success'});
|
||||
this.$store.dispatch('member/member_detail', {refresh: 1});
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultHeadImage'])
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.member-info .el-upload {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.member-info {
|
||||
background: #ffffff;
|
||||
padding: 20px;
|
||||
|
||||
.el-tab-pane {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
|
||||
.preview {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.title {
|
||||
margin-right: 20px;
|
||||
line-height: 3;
|
||||
}
|
||||
|
||||
.content {
|
||||
color: $base-color;
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
.upload {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.el-upload {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.img-wrap {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
display: block;
|
||||
line-height: 120px;
|
||||
overflow: hidden;
|
||||
border: 1px solid #f1f1f1;
|
||||
cursor: pointer;
|
||||
|
||||
img {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.el-form {
|
||||
margin-top: 20px;
|
||||
width: 500px;
|
||||
margin-left: 200px;
|
||||
|
||||
.toBind {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
144
addon/pc/source/os/pages/member/my_point.vue
Executable file
144
addon/pc/source/os/pages/member/my_point.vue
Executable file
@@ -0,0 +1,144 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<div class="my-point" v-loading="loading">
|
||||
<div class="member-point">
|
||||
<div class="title">我的积分</div>
|
||||
<div class="num">{{ memberPoint.point ? Math.ceil(memberPoint.point) : 0 }}</div>
|
||||
</div>
|
||||
<div class="detail">
|
||||
<el-table :data="pointList" border>
|
||||
<el-table-column prop="type_name" label="来源" width="150"></el-table-column>
|
||||
<el-table-column prop="pointNum" label="积分" width="150"></el-table-column>
|
||||
<el-table-column prop="remark" label="详细说明"></el-table-column>
|
||||
<el-table-column prop="time" label="时间" width="180"></el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<div class="pager">
|
||||
<el-pagination
|
||||
background
|
||||
:pager-count="5"
|
||||
:total="total"
|
||||
prev-text="上一页"
|
||||
next-text="下一页"
|
||||
:current-page.sync="pointInfo.page"
|
||||
:page-size.sync="pointInfo.page_size"
|
||||
@size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange"
|
||||
hide-on-single-page
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {pointInfo, pointList} from "@/api/member/my_point"
|
||||
|
||||
export default {
|
||||
name: "my_point",
|
||||
layout: "member",
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
pointInfo: {
|
||||
page: 1,
|
||||
page_size: 10,
|
||||
account_type: "point"
|
||||
},
|
||||
pointList: [],
|
||||
memberPoint: {
|
||||
point: 0
|
||||
},
|
||||
total: 0,
|
||||
loading: true,
|
||||
yes: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getPointInfo();
|
||||
this.getPointList()
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
getPointInfo() {
|
||||
pointInfo({account_type: this.pointInfo.account_type}).then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.memberPoint = res.data
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(err => {
|
||||
this.loading = false
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
},
|
||||
getPointList() {
|
||||
pointList(this.pointInfo).then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.pointList = res.data.list
|
||||
this.total = res.data.count
|
||||
this.pointList.forEach(item => {
|
||||
item.time = this.$util.timeStampTurnTime(item.create_time)
|
||||
item.pointNum = item.account_data > 0 ? "+" + parseInt(item.account_data) : parseInt(item.account_data)
|
||||
})
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
},
|
||||
handlePageSizeChange(num) {
|
||||
this.pointInfo.page_size = num
|
||||
this.getPointList()
|
||||
},
|
||||
handleCurrentPageChange(page) {
|
||||
this.pointInfo.page = page
|
||||
this.getPointList()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.my-point {
|
||||
background: #ffffff;
|
||||
padding: 20px;
|
||||
|
||||
.member-point {
|
||||
font-size: $ns-font-size-base;
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.num {
|
||||
font-size: 30px;
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.page {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
padding-top: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
558
addon/pc/source/os/pages/member/order_detail.vue
Executable file
558
addon/pc/source/os/pages/member/order_detail.vue
Executable file
@@ -0,0 +1,558 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card order-detail">
|
||||
<div slot="header" class="clearfix">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/member/order_list' }">订单列表</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>订单详情</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div v-loading="loading">
|
||||
<template v-if="orderDetail">
|
||||
<div class="order-status">
|
||||
<h4>
|
||||
订单状态:
|
||||
<span class="ns-text-color">{{ orderDetail.order_status_name }}</span>
|
||||
</h4>
|
||||
<div v-if="orderDetail.order_status == 0" class="go-pay">
|
||||
<p>
|
||||
需付款:
|
||||
<span>¥{{ orderDetail.pay_money }}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="operation" v-if="orderDetail.action.length > 0">
|
||||
<el-button type="primary" size="mini" plain v-if="orderDetail.is_evaluate == 1" @click="operation('memberOrderEvaluation')">
|
||||
<template v-if="orderDetail.evaluate_status == 0">评价</template>
|
||||
<template v-else-if="orderDetail.evaluate_status == 1">追评</template>
|
||||
</el-button>
|
||||
|
||||
<el-button type="primary" size="mini" :plain="operationItem.action == 'orderPay' ? false : true" v-for="(operationItem, operationIndex) in orderDetail.action" :key="operationIndex" @click="operation(operationItem.action)">
|
||||
{{ operationItem.title }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="operation" v-else-if="orderDetail.action.length == 0 && orderDetail.is_evaluate == 1">
|
||||
<el-button type="primary" size="mini" plain v-if="orderDetail.is_evaluate == 1" @click="operation('memberOrderEvaluation')">
|
||||
<template v-if="orderDetail.evaluate_status == 0">评价</template>
|
||||
<template v-else-if="orderDetail.evaluate_status == 1">追评</template>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="order-info">
|
||||
<h4>订单信息</h4>
|
||||
<ul>
|
||||
<!-- <li>
|
||||
<i class="iconfont iconmendian"></i>
|
||||
店铺:
|
||||
<router-link :to="'/shop-' + orderDetail.site_id" target="_blank">{{ orderDetail.site_name }}</router-link>
|
||||
</li> -->
|
||||
<li>订单类型:{{ orderDetail.order_type_name }}</li>
|
||||
<li>订单编号:{{ orderDetail.order_no }}</li>
|
||||
<li>订单交易号:{{ orderDetail.out_trade_no }}</li>
|
||||
<li>配送方式:{{ orderDetail.delivery_type_name }}</li>
|
||||
<li v-if="orderDetail.order_status == -1">退款途径:{{ orderDetail.refund_money_type == 1 ? '原路退款' : orderDetail.refund_money_type == 2 ? '线下退款' : '退款到余额' }}</li>
|
||||
<li>创建时间:{{ $util.timeStampTurnTime(orderDetail.create_time) }}</li>
|
||||
<li v-if="orderDetail.close_time > 0">关闭时间:{{ $util.timeStampTurnTime(orderDetail.close_time) }}</li>
|
||||
<template v-if="orderDetail.pay_status > 0">
|
||||
<li>支付方式:{{ orderDetail.pay_type_name }}</li>
|
||||
<li>支付时间:{{ $util.timeStampTurnTime(orderDetail.pay_time) }}</li>
|
||||
</template>
|
||||
<li v-if="orderDetail.promotion_type_name != ''">店铺活动:{{ orderDetail.promotion_type_name }}</li>
|
||||
<li v-if="orderDetail.buyer_message != ''">买家留言:{{ orderDetail.buyer_message }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="order-info" v-if="orderDetail.pay_type=='offlinepay'&&orderDetail.offline_pay_info">
|
||||
<h4>线下支付</h4>
|
||||
<ul>
|
||||
<li v-if="orderDetail.offline_pay_info.status_info.const=='WAIT_AUDIT'">
|
||||
支付状态:审核中
|
||||
</li>
|
||||
<li v-if="orderDetail.offline_pay_info.status_info.const=='AUDIT_REFUSE'">
|
||||
支付状态:审核被拒
|
||||
</li>
|
||||
<li v-if="orderDetail.offline_pay_info.status_info.const=='AUDIT_REFUSE'">
|
||||
审核备注:{{orderDetail.offline_pay_info.audit_remark}}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="take-delivery-info">
|
||||
<h4>收货信息</h4>
|
||||
<ul>
|
||||
<li>收货人:{{ orderDetail.name }}</li>
|
||||
<li>手机号码:{{ orderDetail.mobile }}</li>
|
||||
<li>收货地址:{{ orderDetail.full_address }} {{ orderDetail.address }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- 发票信息 -->
|
||||
<div class="take-delivery-info" v-if="orderDetail.is_invoice ==1">
|
||||
<h4>发票信息</h4>
|
||||
<ul>
|
||||
<li>发票类型:{{ orderDetail.invoice_type == 1 ? '纸质发票' : '电子发票' }}</li>
|
||||
<li>发票抬头类型:{{ orderDetail.invoice_title_type ==1 ? '个人' : '企业' }}</li>
|
||||
<li>发票抬头:{{ orderDetail.invoice_title }}</li>
|
||||
<li>发票内容:{{ orderDetail.invoice_content }}</li>
|
||||
<li v-if="orderDetail.invoice_type == 1">发票邮寄地址地址:{{ orderDetail.invoice_full_address }}</li>
|
||||
<li v-else>发票接收邮箱:{{ orderDetail.invoice_email }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<li :class="{ 'no-operation': !orderDetail.is_enable_refund }">商品信息</li>
|
||||
<li>单价</li>
|
||||
<li>数量</li>
|
||||
<li>小计</li>
|
||||
<li v-if="orderDetail.is_enable_refund">操作</li>
|
||||
</nav>
|
||||
|
||||
<!-- 订单项·商品 -->
|
||||
<div class="list">
|
||||
<ul class="item" v-for="(goodsItem, goodsIndex) in orderDetail.order_goods" :key="goodsIndex">
|
||||
<li :class="{ 'no-operation': !orderDetail.is_enable_refund }">
|
||||
<div class="img-wrap" @click="$util.pushToTab('/sku/' + goodsItem.sku_id)">
|
||||
<img :src="$img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" />
|
||||
</div>
|
||||
<div class="info-wrap">
|
||||
<h5 @click="$util.pushToTab('/sku/' + goodsItem.sku_id)">{{ goodsItem.sku_name }}</h5>
|
||||
<!-- <span>规格:规格值</span> -->
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<span>¥{{ goodsItem.price }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>{{ goodsItem.num }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>¥{{ (goodsItem.price * goodsItem.num).toFixed(2) }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<el-button type="primary" plain size="mini" v-if="orderDetail.is_enable_refund == 1 && goodsItem.refund_status == 0 && orderDetail.order_scene == 'online' && goodsItem.promotion_type != 'blindbox'" @click="$router.push({ path: '/order/refund', query: { order_goods_id: goodsItem.order_goods_id, order_id: orderId } })">申请退款</el-button>
|
||||
<el-button type="primary" plain size="mini" v-if="goodsItem.refund_status != 0" @click="$router.push({ path: '/order/refund_detail', query: { order_goods_id: goodsItem.order_goods_id } })">{{goodsItem.refund_status_name}}</el-button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- 订单总计 -->
|
||||
<ul class="total">
|
||||
<li>
|
||||
<label>商品金额:</label>
|
||||
<span>¥{{ orderDetail.goods_money }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<label>运费:</label>
|
||||
<span>¥{{ orderDetail.delivery_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.member_card_money > 0">
|
||||
<label>会员卡:</label>
|
||||
<span>¥{{ orderDetail.member_card_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.invoice_money > 0">
|
||||
<label>税费:</label>
|
||||
<span>¥{{ orderDetail.invoice_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.invoice_delivery_money > 0">
|
||||
<label>发票邮寄费:</label>
|
||||
<span>¥{{ orderDetail.invoice_delivery_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.adjust_money != 0">
|
||||
<label>订单调整:</label>
|
||||
<span>
|
||||
<template v-if="orderDetail.adjust_money < 0">-</template>
|
||||
<template v-else>+</template>
|
||||
¥{{ orderDetail.adjust_money | abs }}
|
||||
</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.promotion_money > 0">
|
||||
<label>优惠:</label>
|
||||
<span>¥{{ orderDetail.promotion_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.coupon_money > 0">
|
||||
<label>优惠券:</label>
|
||||
<span>¥{{ orderDetail.coupon_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.point_money > 0">
|
||||
<label>积分抵扣:</label>
|
||||
<span>¥{{ orderDetail.point_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.balance_money > 0">
|
||||
<label>使用余额:</label>
|
||||
<span>¥{{ orderDetail.balance_money }}</span>
|
||||
</li>
|
||||
<li class="pay-money">
|
||||
<label>实付款:</label>
|
||||
<span>¥{{ orderDetail.pay_money }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
apiOrderDetail
|
||||
} from '@/api/order/order';
|
||||
import orderMethod from '@/utils/orderMethod';
|
||||
import {
|
||||
mapGetters
|
||||
} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'order_detail',
|
||||
components: {},
|
||||
mixins: [orderMethod],
|
||||
data: () => {
|
||||
return {
|
||||
orderId: 0,
|
||||
orderDetail: null,
|
||||
loading: true,
|
||||
yes: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.orderId = this.$route.query.order_id;
|
||||
this.getOrderDetail();
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
layout: 'member',
|
||||
methods: {
|
||||
getOrderDetail() {
|
||||
apiOrderDetail({
|
||||
order_id: this.orderId
|
||||
}).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.orderDetail = res.data;
|
||||
this.loading = false;
|
||||
} else {
|
||||
this.$message({
|
||||
message: '未获取到订单信息',
|
||||
type: 'warning',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({
|
||||
path: '/member/order_list'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error({
|
||||
message: err.message,
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({
|
||||
path: '/member/order_list'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
operation(action) {
|
||||
switch (action) {
|
||||
case 'orderPay': // 支付
|
||||
this.orderPay(this.orderDetail);
|
||||
break;
|
||||
case 'orderClose': //关闭
|
||||
this.orderClose(this.orderDetail.order_id, () => {
|
||||
this.getOrderDetail();
|
||||
});
|
||||
break;
|
||||
case 'memberTakeDelivery': //收货
|
||||
this.orderDelivery(this.orderDetail.order_id, () => {
|
||||
this.getOrderDetail();
|
||||
});
|
||||
break;
|
||||
case 'trace': //查看物流
|
||||
this.$router.push({
|
||||
path: '/order/logistics',
|
||||
query: {
|
||||
order_id: this.orderDetail.order_id
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'memberOrderEvaluation': //评价
|
||||
this.$util.pushToTab({
|
||||
path: '/order/evaluate',
|
||||
query: {
|
||||
order_id: this.orderDetail.order_id
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'memberBatchRefund': //批量退款
|
||||
this.$router.push({
|
||||
path: '/order/batchrefund',
|
||||
query: {
|
||||
order_id: this.orderId
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'orderOfflinePay': //线下支付
|
||||
this.$router.push({
|
||||
path: '/pay',
|
||||
query: {
|
||||
code: this.orderDetail.offline_pay_info.out_trade_no
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'orderDelete':
|
||||
this.orderDelete(this.orderDetail.order_id, () => {
|
||||
this.$router.push({
|
||||
path: '/member/order_list',
|
||||
});
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
imageError(index) {
|
||||
this.orderDetail.order_goods[index].sku_image = this.defaultGoodsImage;
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
abs(value) {
|
||||
return Math.abs(parseFloat(value)).toFixed(2);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.order-detail {
|
||||
.order-status {
|
||||
background-color: #fff;
|
||||
margin-bottom: 20px;
|
||||
|
||||
h4 {
|
||||
margin: 10px 0 20px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.go-pay {
|
||||
p {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
|
||||
span {
|
||||
font-weight: bold;
|
||||
color: $base-color;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.operation {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.order-info {
|
||||
background-color: #fff;
|
||||
margin-bottom: 10px;
|
||||
|
||||
h4 {
|
||||
margin: 10px 0 20px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
flex: 0 0 33.3333%;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:last-child {
|
||||
flex: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.take-delivery-info {
|
||||
background-color: #fff;
|
||||
margin-bottom: 10px;
|
||||
|
||||
h4 {
|
||||
margin: 10px 0 20px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
flex: 0 0 33.3333%;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:last-child {
|
||||
flex: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nav {
|
||||
overflow: hidden;
|
||||
padding: 10px 0;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 50%;
|
||||
|
||||
&.no-operation {
|
||||
width: 60%;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(5) {
|
||||
width: 10%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
|
||||
.item {
|
||||
background-color: #fff;
|
||||
padding: 10px 0;
|
||||
overflow: hidden;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
line-height: 60px;
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 50%;
|
||||
line-height: inherit;
|
||||
|
||||
&.no-operation {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.img-wrap {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.info-wrap {
|
||||
margin-left: 70px;
|
||||
|
||||
h5 {
|
||||
font-weight: normal;
|
||||
font-size: $ns-font-size-base;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
margin-right: 10px;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: $ns-font-size-sm;
|
||||
color: #9a9a9a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(5) {
|
||||
width: 10%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 总计
|
||||
.total {
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
text-align: right;
|
||||
|
||||
li {
|
||||
span {
|
||||
width: 150px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&.pay-money {
|
||||
font-weight: bold;
|
||||
|
||||
span {
|
||||
color: $base-color;
|
||||
font-size: 16px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
490
addon/pc/source/os/pages/member/order_detail_local_delivery.vue
Executable file
490
addon/pc/source/os/pages/member/order_detail_local_delivery.vue
Executable file
@@ -0,0 +1,490 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card order-detail">
|
||||
<div slot="header" class="clearfix">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/member/order_list' }">订单列表</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>订单详情</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div v-loading="loading">
|
||||
<template v-if="orderDetail">
|
||||
<div class="order-status">
|
||||
<h4>
|
||||
订单状态:
|
||||
<span class="ns-text-color">{{ orderDetail.order_status_name }}</span>
|
||||
</h4>
|
||||
<div v-if="orderDetail.order_status == 0" class="go-pay">
|
||||
<p>
|
||||
需付款:
|
||||
<span>¥{{ orderDetail.pay_money }}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="operation" v-if="orderDetail.action.length > 0">
|
||||
<el-button type="primary" size="mini" plain v-if="orderDetail.is_evaluate == 1" @click="operation('memberOrderEvaluation')">
|
||||
<template v-if="orderDetail.evaluate_status == 0">评价</template>
|
||||
<template v-else-if="orderDetail.evaluate_status == 1">追评</template>
|
||||
</el-button>
|
||||
|
||||
<el-button type="primary" size="mini" :plain="operationItem.action == 'orderPay' ? false : true" v-for="(operationItem, operationIndex) in orderDetail.action" :key="operationIndex" @click="operation(operationItem.action)">
|
||||
{{ operationItem.title }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div class="operation" v-else-if="orderDetail.action.length == 0 && orderDetail.is_evaluate == 1">
|
||||
<el-button type="primary" size="mini" plain v-if="orderDetail.is_evaluate == 1" @click="operation('memberOrderEvaluation')">
|
||||
<template v-if="orderDetail.evaluate_status == 0">评价</template>
|
||||
<template v-else-if="orderDetail.evaluate_status == 1">追评</template>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="order-info">
|
||||
<h4>订单信息</h4>
|
||||
<ul>
|
||||
<!-- <li>
|
||||
<i class="iconfont iconmendian"></i>
|
||||
店铺:
|
||||
<router-link :to="'/shop-' + orderDetail.site_id" target="_blank">{{ orderDetail.site_name }}</router-link>
|
||||
</li> -->
|
||||
<li>订单类型:{{ orderDetail.order_type_name }}</li>
|
||||
<li>订单编号:{{ orderDetail.order_no }}</li>
|
||||
<li>订单交易号:{{ orderDetail.out_trade_no }}</li>
|
||||
<li>配送方式:{{ orderDetail.delivery_type_name }}</li>
|
||||
<li>创建时间:{{ $util.timeStampTurnTime(orderDetail.create_time) }}</li>
|
||||
<li v-if="orderDetail.close_time > 0">关闭时间:{{ $util.timeStampTurnTime(orderDetail.close_time) }}</li>
|
||||
<template v-if="orderDetail.pay_status > 0">
|
||||
<li>支付方式:{{ orderDetail.pay_type_name }}</li>
|
||||
<li>支付时间:{{ $util.timeStampTurnTime(orderDetail.pay_time) }}</li>
|
||||
</template>
|
||||
<li v-if="orderDetail.promotion_type_name != ''">店铺活动:{{ orderDetail.promotion_type_name }}</li>
|
||||
<li v-if="orderDetail.buyer_message != ''">买家留言:{{ orderDetail.buyer_message }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="take-delivery-info">
|
||||
<h4>收货信息</h4>
|
||||
<ul>
|
||||
<li>收货人:{{ orderDetail.name }}</li>
|
||||
<li>手机号码:{{ orderDetail.mobile }}</li>
|
||||
<li>收货地址:{{ orderDetail.full_address }} {{ orderDetail.address }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<li :class="{ 'no-operation': !orderDetail.is_enable_refund }">商品信息</li>
|
||||
<li>单价</li>
|
||||
<li>数量</li>
|
||||
<li>小计</li>
|
||||
<li v-if="orderDetail.is_enable_refund">操作</li>
|
||||
</nav>
|
||||
|
||||
<!-- 订单项·商品 -->
|
||||
<div class="list">
|
||||
<ul class="item" v-for="(goodsItem, goodsIndex) in orderDetail.order_goods" :key="goodsIndex">
|
||||
<li :class="{ 'no-operation': !orderDetail.is_enable_refund }">
|
||||
<div class="img-wrap" @click="$util.pushToTab('/sku/' + goodsItem.sku_id)">
|
||||
<img :src="$img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" />
|
||||
</div>
|
||||
<div class="info-wrap">
|
||||
<h5 @click="$util.pushToTab('/sku/' + goodsItem.sku_id)">{{ goodsItem.sku_name }}</h5>
|
||||
<!-- <span>规格:规格值</span> -->
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<span>¥{{ goodsItem.price }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>{{ goodsItem.num }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>¥{{ (goodsItem.price * goodsItem.num).toFixed(2) }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.is_enable_refund">
|
||||
<el-button type="primary" plain size="mini" v-if="goodsItem.refund_status == 0 || goodsItem.refund_status == -1" @click="$router.push({ path: '/order/refund', query: { order_goods_id: goodsItem.order_goods_id } })">退款</el-button>
|
||||
<el-button type="primary" plain size="mini" v-else @click="$router.push({ path: '/order/refund_detail', query: { order_goods_id: goodsItem.order_goods_id } })">查看退款</el-button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- 订单总计 -->
|
||||
<ul class="total">
|
||||
<li>
|
||||
<label>商品金额:</label>
|
||||
<span>¥{{ orderDetail.goods_money }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<label>运费:</label>
|
||||
<span>¥{{ orderDetail.delivery_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.member_card_money > 0">
|
||||
<label>会员卡:</label>
|
||||
<span>¥{{ orderDetail.member_card_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.invoice_money > 0">
|
||||
<label>税费:</label>
|
||||
<span>¥{{ orderDetail.invoice_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.invoice_delivery_money > 0">
|
||||
<label>发票邮寄费:</label>
|
||||
<span>¥{{ orderDetail.invoice_delivery_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.adjust_money != 0">
|
||||
<label>订单调整:</label>
|
||||
<span>
|
||||
<template v-if="orderDetail.adjust_money < 0">-</template>
|
||||
<template v-else>+</template>
|
||||
¥{{ orderDetail.adjust_money | abs }}
|
||||
</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.promotion_money > 0">
|
||||
<label>优惠:</label>
|
||||
<span>¥{{ orderDetail.promotion_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.coupon_money > 0">
|
||||
<label>优惠券:</label>
|
||||
<span>¥{{ orderDetail.coupon_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.point_money > 0">
|
||||
<label>积分抵扣:</label>
|
||||
<span>¥{{ orderDetail.point_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.balance_money > 0">
|
||||
<label>使用余额:</label>
|
||||
<span>¥{{ orderDetail.balance_money }}</span>
|
||||
</li>
|
||||
<li class="pay-money">
|
||||
<label>实付款:</label>
|
||||
<span>¥{{ orderDetail.pay_money }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {apiOrderDetail} from '@/api/order/order';
|
||||
import orderMethod from '@/utils/orderMethod';
|
||||
import {mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'order_detail_local_delivery',
|
||||
components: {},
|
||||
mixins: [orderMethod],
|
||||
data: () => {
|
||||
return {
|
||||
orderId: 0,
|
||||
orderDetail: null,
|
||||
loading: true,
|
||||
yes: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.orderId = this.$route.query.order_id;
|
||||
this.getOrderDetail();
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
layout: 'member',
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
getOrderDetail() {
|
||||
apiOrderDetail({
|
||||
order_id: this.orderId
|
||||
}).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.orderDetail = res.data;
|
||||
this.loading = false;
|
||||
} else {
|
||||
this.$message({
|
||||
message: '未获取到订单信息',
|
||||
type: 'warning',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({path: '/member/order_list'});
|
||||
}
|
||||
});
|
||||
}
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error({
|
||||
message: err.message,
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({path: '/member/order_list'});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
operation(action) {
|
||||
switch (action) {
|
||||
case 'orderPay': // 支付
|
||||
this.orderPay(this.orderDetail);
|
||||
break;
|
||||
case 'orderClose': //关闭
|
||||
this.orderClose(this.orderDetail.order_id, () => {
|
||||
this.getOrderDetail();
|
||||
});
|
||||
break;
|
||||
case 'memberTakeDelivery': //收货
|
||||
this.orderDelivery(this.orderDetail.order_id, () => {
|
||||
this.getOrderDetail();
|
||||
});
|
||||
break;
|
||||
case 'trace': //查看物流
|
||||
this.$router.push({path: '/order/logistics', query: {order_id: this.orderDetail.order_id}});
|
||||
break;
|
||||
case 'memberOrderEvaluation': //评价
|
||||
this.$util.pushToTab({path: '/order/evaluate', query: {order_id: this.orderDetail.order_id}});
|
||||
break;
|
||||
}
|
||||
},
|
||||
imageError(index) {
|
||||
this.orderDetail.order_goods[index].sku_image = this.defaultGoodsImage;
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
abs(value) {
|
||||
return Math.abs(parseFloat(value)).toFixed(2);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.order-detail {
|
||||
.order-status {
|
||||
background-color: #fff;
|
||||
margin-bottom: 20px;
|
||||
|
||||
h4 {
|
||||
margin: 10px 0 20px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.go-pay {
|
||||
p {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
|
||||
span {
|
||||
font-weight: bold;
|
||||
color: $base-color;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.operation {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.order-info {
|
||||
background-color: #fff;
|
||||
margin-bottom: 10px;
|
||||
|
||||
h4 {
|
||||
margin: 10px 0 20px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
flex: 0 0 33.3333%;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:last-child {
|
||||
flex: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.take-delivery-info {
|
||||
background-color: #fff;
|
||||
margin-bottom: 10px;
|
||||
|
||||
h4 {
|
||||
margin: 10px 0 20px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
flex: 0 0 33.3333%;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:last-child {
|
||||
flex: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nav {
|
||||
overflow: hidden;
|
||||
padding: 10px 0;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 50%;
|
||||
|
||||
&.no-operation {
|
||||
width: 60%;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(5) {
|
||||
width: 10%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
|
||||
.item {
|
||||
background-color: #fff;
|
||||
padding: 10px 0;
|
||||
overflow: hidden;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
line-height: 60px;
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 55%;
|
||||
line-height: inherit;
|
||||
|
||||
&.no-operation {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.img-wrap {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.info-wrap {
|
||||
margin-left: 70px;
|
||||
|
||||
h5 {
|
||||
font-weight: normal;
|
||||
font-size: $ns-font-size-base;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
|
||||
&:hover {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: $ns-font-size-sm;
|
||||
color: #9a9a9a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(5) {
|
||||
width: 10%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 总计
|
||||
.total {
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
text-align: right;
|
||||
|
||||
li {
|
||||
span {
|
||||
width: 150px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&.pay-money {
|
||||
font-weight: bold;
|
||||
|
||||
span {
|
||||
color: $base-color;
|
||||
font-size: 16px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
583
addon/pc/source/os/pages/member/order_detail_pickup.vue
Executable file
583
addon/pc/source/os/pages/member/order_detail_pickup.vue
Executable file
@@ -0,0 +1,583 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card order-detail">
|
||||
<div slot="header" class="clearfix">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/member/order_list' }">订单列表</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>订单详情</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div v-loading="loading">
|
||||
<template v-if="orderDetail">
|
||||
<div class="order-status">
|
||||
<h4>
|
||||
订单状态:
|
||||
<span class="ns-text-color">{{ orderDetail.order_status_name }}</span>
|
||||
</h4>
|
||||
<div v-if="orderDetail.order_status == 0" class="go-pay">
|
||||
<p>
|
||||
需付款:
|
||||
<span>¥{{ orderDetail.pay_money }}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="operation" v-if="orderDetail.action.length > 0">
|
||||
<el-button type="primary" size="mini" plain v-if="orderDetail.is_evaluate == 1" @click="operation('memberOrderEvaluation')">
|
||||
<template v-if="orderDetail.evaluate_status == 0">评价</template>
|
||||
<template v-else-if="orderDetail.evaluate_status == 1">追评</template>
|
||||
</el-button>
|
||||
|
||||
<el-button type="primary" size="mini" :plain="operationItem.action == 'orderPay' ? false : true" v-for="(operationItem, operationIndex) in orderDetail.action" :key="operationIndex" @click="operation(operationItem.action)">{{ operationItem.title }}</el-button>
|
||||
</div>
|
||||
<div class="operation" v-else-if="orderDetail.action.length == 0 && orderDetail.is_evaluate == 1">
|
||||
<el-button type="primary" size="mini" plain v-if="orderDetail.is_evaluate == 1" @click="operation('memberOrderEvaluation')">
|
||||
<template v-if="orderDetail.evaluate_status == 0">评价</template>
|
||||
<template v-else-if="orderDetail.evaluate_status == 1">追评</template>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pickup-info" v-if="orderDetail.pay_status">
|
||||
<h4>
|
||||
自提点:
|
||||
<span class="ns-text-color">{{ orderDetail.delivery_store_name }}</span>
|
||||
</h4>
|
||||
<ul>
|
||||
<li>
|
||||
提货码:
|
||||
<span class="ns-text-color">{{ orderDetail.delivery_code }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.delivery_store_info && orderDetail.delivery_store_info.open_date">营业时间:{{ orderDetail.delivery_store_info.open_date }}</li>
|
||||
<li v-if="orderDetail.delivery_store_info && orderDetail.delivery_store_info.telphone">联系方式:{{ orderDetail.delivery_store_info.telphone }}</li>
|
||||
<li v-if="orderDetail.delivery_store_info && orderDetail.delivery_store_info.full_address">详细地址:{{ orderDetail.delivery_store_info.full_address }}</li>
|
||||
</ul>
|
||||
<img :src="$img(orderDetail.pickup)" />
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<li :class="{ 'no-operation': !orderDetail.is_enable_refund }">商品信息</li>
|
||||
<li>单价</li>
|
||||
<li>数量</li>
|
||||
<li>小计</li>
|
||||
<li v-if="orderDetail.is_enable_refund">操作</li>
|
||||
</nav>
|
||||
|
||||
<div class="order-info">
|
||||
<h4>订单信息</h4>
|
||||
<ul>
|
||||
<!-- <li>
|
||||
<i class="iconfont iconmendian"></i>
|
||||
店铺:
|
||||
<router-link :to="'/shop-' + orderDetail.site_id" target="_blank">{{ orderDetail.site_name }}</router-link>
|
||||
</li> -->
|
||||
<li>订单类型:{{ orderDetail.order_type_name }}</li>
|
||||
<li>订单编号:{{ orderDetail.order_no }}</li>
|
||||
<li>订单交易号:{{ orderDetail.out_trade_no }}</li>
|
||||
<li>配送方式:{{ orderDetail.delivery_type_name }}</li>
|
||||
<li>创建时间:{{ $util.timeStampTurnTime(orderDetail.create_time) }}</li>
|
||||
<li v-if="orderDetail.close_time > 0">关闭时间:{{ $util.timeStampTurnTime(orderDetail.close_time) }}</li>
|
||||
<template v-if="orderDetail.pay_status > 0">
|
||||
<li>支付方式:{{ orderDetail.pay_type_name }}</li>
|
||||
<li>支付时间:{{ $util.timeStampTurnTime(orderDetail.pay_time) }}</li>
|
||||
</template>
|
||||
<li v-if="orderDetail.promotion_type_name != ''">店铺活动:{{ orderDetail.promotion_type_name }}</li>
|
||||
<li v-if="orderDetail.buyer_message != ''">买家留言:{{ orderDetail.buyer_message }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="order-info" v-if="orderDetail.pay_type=='offlinepay'&&orderDetail.offline_pay_info">
|
||||
<h4>线下支付</h4>
|
||||
<ul>
|
||||
<li v-if="orderDetail.offline_pay_info.status_info.const=='WAIT_AUDIT'">
|
||||
支付状态:审核中
|
||||
</li>
|
||||
<li v-if="orderDetail.offline_pay_info.status_info.const=='AUDIT_REFUSE'">
|
||||
支付状态:审核被拒
|
||||
</li>
|
||||
<li v-if="orderDetail.offline_pay_info.status_info.const=='AUDIT_REFUSE'">
|
||||
审核备注:{{orderDetail.offline_pay_info.audit_remark}}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="take-delivery-info">
|
||||
<h4>收货信息</h4>
|
||||
<ul>
|
||||
<li>收货人:{{ orderDetail.name }}</li>
|
||||
<li>手机号码:{{ orderDetail.mobile }}</li>
|
||||
<li>收货地址:{{ orderDetail.full_address }} {{ orderDetail.address }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- 订单项·商品 -->
|
||||
<div class="list">
|
||||
<ul class="item" v-for="(goodsItem, goodsIndex) in orderDetail.order_goods" :key="goodsIndex">
|
||||
<li :class="{ 'no-operation': !orderDetail.is_enable_refund }">
|
||||
<div class="img-wrap" @click="$util.pushToTab('/sku/' + goodsItem.sku_id)">
|
||||
<img :src="$img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" />
|
||||
</div>
|
||||
<div class="info-wrap">
|
||||
<h5 @click="$util.pushToTab('/sku/' + goodsItem.sku_id)">{{ goodsItem.sku_name }}</h5>
|
||||
<!-- <span>规格:规格值</span> -->
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<span>¥{{ goodsItem.price }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>{{ goodsItem.num }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>¥{{ (goodsItem.price * goodsItem.num).toFixed(2) }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.is_enable_refund">
|
||||
<el-button type="primary" plain size="mini" v-if="goodsItem.refund_status == 0 || goodsItem.refund_status == -1" @click="$router.push({ path: '/order/refund', query: { order_goods_id: goodsItem.order_goods_id } })">退款</el-button>
|
||||
<el-button type="primary" plain size="mini" v-else @click="$router.push({ path: '/order/refund_detail', query: { order_goods_id: goodsItem.order_goods_id } })">查看退款</el-button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- 订单总计 -->
|
||||
<ul class="total">
|
||||
<li>
|
||||
<label>商品金额:</label>
|
||||
<span>¥{{ orderDetail.goods_money }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<label>运费:</label>
|
||||
<span>¥{{ orderDetail.delivery_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.member_card_money > 0">
|
||||
<label>会员卡:</label>
|
||||
<span>¥{{ orderDetail.member_card_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.invoice_money > 0">
|
||||
<label>税费:</label>
|
||||
<span>¥{{ orderDetail.invoice_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.invoice_delivery_money > 0">
|
||||
<label>发票邮寄费:</label>
|
||||
<span>¥{{ orderDetail.invoice_delivery_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.adjust_money != 0">
|
||||
<label>订单调整:</label>
|
||||
<span>
|
||||
<template v-if="orderDetail.adjust_money < 0">-</template>
|
||||
<template v-else>+</template>
|
||||
¥{{ orderDetail.adjust_money | abs }}
|
||||
</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.promotion_money > 0">
|
||||
<label>优惠:</label>
|
||||
<span>¥{{ orderDetail.promotion_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.coupon_money > 0">
|
||||
<label>优惠券:</label>
|
||||
<span>¥{{ orderDetail.coupon_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.balance_money > 0">
|
||||
<label>使用余额:</label>
|
||||
<span>¥{{ orderDetail.balance_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.point_money > 0">
|
||||
<label>积分抵扣:</label>
|
||||
<span>¥{{ orderDetail.point_money }}</span>
|
||||
</li>
|
||||
<li class="pay-money">
|
||||
<label>实付款:</label>
|
||||
<span>¥{{ orderDetail.pay_money }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
apiOrderDetail
|
||||
} from '@/api/order/order';
|
||||
import orderMethod from '@/utils/orderMethod';
|
||||
import {
|
||||
mapGetters
|
||||
} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'order_detail_pickup',
|
||||
components: {},
|
||||
mixins: [orderMethod],
|
||||
data: () => {
|
||||
return {
|
||||
orderId: 0,
|
||||
orderDetail: null,
|
||||
loading: true,
|
||||
yes: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.orderId = this.$route.query.order_id;
|
||||
this.getOrderDetail();
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
layout: 'member',
|
||||
methods: {
|
||||
getOrderDetail() {
|
||||
apiOrderDetail({
|
||||
order_id: this.orderId
|
||||
}).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.orderDetail = res.data;
|
||||
if (this.orderDetail.delivery_store_info != '') this.orderDetail.delivery_store_info = JSON.parse(this.orderDetail
|
||||
.delivery_store_info);
|
||||
this.loading = false;
|
||||
} else {
|
||||
this.$message({
|
||||
message: '未获取到订单信息',
|
||||
type: 'warning',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({
|
||||
path: '/member/order_list'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error({
|
||||
message: err.message,
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({
|
||||
path: '/member/order_list'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
operation(action) {
|
||||
switch (action) {
|
||||
case 'orderPay': // 支付
|
||||
this.orderPay(this.orderDetail);
|
||||
break;
|
||||
case 'orderClose': //关闭
|
||||
this.orderClose(this.orderDetail.order_id, () => {
|
||||
this.getOrderDetail();
|
||||
});
|
||||
break;
|
||||
case 'memberTakeDelivery': //收货
|
||||
this.orderDelivery(this.orderDetail.order_id, () => {
|
||||
this.getOrderDetail();
|
||||
});
|
||||
break;
|
||||
case 'trace': //查看物流
|
||||
this.$router.push({
|
||||
path: '/order/logistics',
|
||||
query: {
|
||||
order_id: this.orderDetail.order_id
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'memberOrderEvaluation': //评价
|
||||
this.$router.push({
|
||||
path: '/order/evaluate',
|
||||
query: {
|
||||
order_id: this.orderDetail.order_id
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'memberBatchRefund': //批量退款
|
||||
this.$router.push({
|
||||
path: '/order/batchrefund',
|
||||
query: {
|
||||
order_id: this.orderId
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'orderOfflinePay': //线下支付
|
||||
this.$router.push({
|
||||
path: '/pay',
|
||||
query: {
|
||||
code: this.orderDetail.offline_pay_info.out_trade_no
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
imageError(index) {
|
||||
this.orderDetail.order_goods[index].sku_image = this.defaultGoodsImage;
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
abs(value) {
|
||||
return Math.abs(parseFloat(value)).toFixed(2);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.order-detail {
|
||||
.order-status {
|
||||
background-color: #fff;
|
||||
margin-bottom: 20px;
|
||||
|
||||
h4 {
|
||||
margin: 10px 0 20px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.go-pay {
|
||||
p {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
|
||||
span {
|
||||
font-weight: bold;
|
||||
color: $base-color;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.operation {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.order-info {
|
||||
background-color: #fff;
|
||||
margin-bottom: 10px;
|
||||
|
||||
h4 {
|
||||
margin: 10px 0 20px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
flex: 0 0 33.3333%;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:last-child {
|
||||
flex: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.take-delivery-info {
|
||||
background-color: #fff;
|
||||
margin-bottom: 10px;
|
||||
|
||||
h4 {
|
||||
margin: 10px 0 20px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
flex: 0 0 33.3333%;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:last-child {
|
||||
flex: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pickup-info {
|
||||
background-color: #fff;
|
||||
margin-bottom: 10px;
|
||||
|
||||
h4 {
|
||||
margin: 10px 0 20px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
flex: 0 0 33.3333%;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:last-child {
|
||||
flex: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
nav {
|
||||
overflow: hidden;
|
||||
padding: 10px 0;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 50%;
|
||||
|
||||
&.no-operation {
|
||||
width: 60%;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(5) {
|
||||
width: 10%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
|
||||
.item {
|
||||
background-color: #fff;
|
||||
padding: 10px 0;
|
||||
overflow: hidden;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
line-height: 60px;
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 50%;
|
||||
line-height: inherit;
|
||||
|
||||
&.no-operation {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.img-wrap {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.info-wrap {
|
||||
margin-left: 70px;
|
||||
cursor: pointer;
|
||||
|
||||
h5 {
|
||||
font-weight: normal;
|
||||
font-size: $ns-font-size-base;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
margin-right: 10px;
|
||||
display: inline-block;
|
||||
|
||||
&:hover {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: $ns-font-size-sm;
|
||||
color: #9a9a9a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(5) {
|
||||
width: 10%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 总计
|
||||
.total {
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
text-align: right;
|
||||
|
||||
li {
|
||||
span {
|
||||
width: 150px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&.pay-money {
|
||||
font-weight: bold;
|
||||
|
||||
span {
|
||||
color: $base-color;
|
||||
font-size: 16px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
622
addon/pc/source/os/pages/member/order_detail_virtual.vue
Executable file
622
addon/pc/source/os/pages/member/order_detail_virtual.vue
Executable file
@@ -0,0 +1,622 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card order-detail">
|
||||
<div slot="header" class="clearfix">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/member/order_list' }">订单列表</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>订单详情</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div v-loading="loading">
|
||||
<template v-if="orderDetail">
|
||||
<div class="order-status">
|
||||
<h4 style="position: relative;">
|
||||
订单状态:
|
||||
<span class="ns-text-color">{{ orderDetail.order_status_name }}</span>
|
||||
<div class="edit-time" v-if="orderDetail.order_status == 0">
|
||||
<img src="../../assets/images/order_time.png" style="width: 15px;height: 15px;margin-right: 6px;" />距离订单自动关闭,剩余
|
||||
<count-down
|
||||
style="color: #f00;margin-left: 10px;"
|
||||
class="count-down"
|
||||
v-on:start_callback="countDownS_cb()"
|
||||
v-on:end_callback="countDownE_cb()"
|
||||
:currentTime="orderDetail.currentTime"
|
||||
:startTime="orderDetail.startTime"
|
||||
:endTime="orderDetail.endTime"
|
||||
:dayTxt="':'"
|
||||
:hourTxt="':'"
|
||||
:minutesTxt="':'"
|
||||
:secondsTxt="''"
|
||||
></count-down>
|
||||
</div>
|
||||
</h4>
|
||||
<div v-if="orderDetail.order_status == 0" class="go-pay">
|
||||
<p>
|
||||
需付款:
|
||||
<span>¥{{ orderDetail.pay_money }}</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="operation" v-if="orderDetail.action.length > 0">
|
||||
<el-button type="primary" size="mini" plain v-if="orderDetail.is_evaluate == 1" @click="operation('memberOrderEvaluation')">
|
||||
<template v-if="orderDetail.evaluate_status == 0">评价</template>
|
||||
<template v-else-if="orderDetail.evaluate_status == 1">追评</template>
|
||||
</el-button>
|
||||
|
||||
<el-button type="primary" size="mini" :plain="operationItem.action == 'orderPay' ? false : true" v-for="(operationItem, operationIndex) in orderDetail.action" :key="operationIndex" @click="operation(operationItem.action)">{{ operationItem.title }}</el-button>
|
||||
</div>
|
||||
<div class="operation" v-else-if="orderDetail.action.length == 0 && orderDetail.is_evaluate == 1">
|
||||
<el-button type="primary" size="mini" plain v-if="orderDetail.is_evaluate == 1" @click="operation('memberOrderEvaluation')">
|
||||
<template v-if="orderDetail.evaluate_status == 0">评价</template>
|
||||
<template v-else-if="orderDetail.evaluate_status == 1">追评</template>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="verify-code-wrap" v-if="orderDetail.virtual_goods">
|
||||
<template v-if="orderDetail.goods_class == 2">
|
||||
<h4>核销码</h4>
|
||||
<div class="virtual-code">
|
||||
<img :src="$img(orderDetail.virtualgoods)" />
|
||||
<div class="tips">请将二维码出示给核销员</div>
|
||||
<div>核销码:{{ orderDetail.virtual_code }}</div>
|
||||
</div>
|
||||
<h4>核销信息</h4>
|
||||
<ul>
|
||||
<li>核销次数:剩余{{ orderDetail.virtual_goods.total_verify_num - orderDetail.virtual_goods.verify_num }}次/共{{ orderDetail.virtual_goods.total_verify_num }}次</li>
|
||||
<li>有效期:
|
||||
<span v-if="orderDetail.virtual_goods.expire_time > 0"> {{ $util.timeStampTurnTime(orderDetail.virtual_goods.expire_time) }}</span>
|
||||
<span v-else>永久有效</span>
|
||||
</li>
|
||||
</ul>
|
||||
<template v-if="orderDetail.virtual_goods.verify_record.length">
|
||||
<h4>核销记录</h4>
|
||||
<ul v-for="(item, index) in orderDetail.virtual_goods.verify_record" :key="index">
|
||||
<li>核销人:{{ item.verifier_name }}</li>
|
||||
<li>核销时间:{{ $util.timeStampTurnTime(item.verify_time) }}</li>
|
||||
</ul>
|
||||
</template>
|
||||
</template>
|
||||
<template v-if="orderDetail.goods_class == 3">
|
||||
<h4>卡密信息</h4>
|
||||
<ul v-for="(item, index) in orderDetail.virtual_goods" :key="index">
|
||||
<li>
|
||||
<span>卡号:{{ item.card_info.cardno }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>密码:{{ item.card_info.password }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<!-- <h4>核销信息</h4>
|
||||
<ul>
|
||||
<li>
|
||||
核销码:
|
||||
<span class="ns-text-color">{{ orderDetail.virtual_code }}</span>
|
||||
</li>
|
||||
<template v-if="orderDetail.virtual_goods.is_veirfy">
|
||||
<li>核销状态:已核销</li>
|
||||
<li>核销时间:{{ $util.timeStampTurnTime(orderDetail.virtual_goods.verify_time) }}</li>
|
||||
</template>
|
||||
</ul>
|
||||
<img :src="$img(orderDetail.virtualgoods)" /> -->
|
||||
</div>
|
||||
|
||||
<div class="order-info">
|
||||
<h4>订单信息</h4>
|
||||
<ul>
|
||||
<!-- <li>
|
||||
<i class="iconfont iconmendian"></i>
|
||||
店铺:
|
||||
<router-link :to="'/shop-' + orderDetail.site_id" target="_blank">{{ orderDetail.site_name }}</router-link>
|
||||
</li> -->
|
||||
<li>订单类型:{{ orderDetail.order_type_name }}</li>
|
||||
<li>订单编号:{{ orderDetail.order_no }}</li>
|
||||
<li>订单交易号:{{ orderDetail.out_trade_no }}</li>
|
||||
<li>创建时间:{{ $util.timeStampTurnTime(orderDetail.create_time) }}</li>
|
||||
<li v-if="orderDetail.close_time > 0">关闭时间:{{ $util.timeStampTurnTime(orderDetail.close_time) }}</li>
|
||||
<template v-if="orderDetail.pay_status > 0">
|
||||
<li>支付方式:{{ orderDetail.pay_type_name }}</li>
|
||||
<li>支付时间:{{ $util.timeStampTurnTime(orderDetail.pay_time) }}</li>
|
||||
</template>
|
||||
<li v-if="orderDetail.promotion_type_name != ''">店铺活动:{{ orderDetail.promotion_type_name }}</li>
|
||||
<li v-if="orderDetail.buyer_message != ''">买家留言:{{ orderDetail.buyer_message }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="order-info" v-if="orderDetail.pay_type=='offlinepay'&&orderDetail.offline_pay_info">
|
||||
<h4>线下支付</h4>
|
||||
<ul>
|
||||
<li v-if="orderDetail.offline_pay_info.status_info.const=='WAIT_AUDIT'">
|
||||
支付状态:审核中
|
||||
</li>
|
||||
<li v-if="orderDetail.offline_pay_info.status_info.const=='AUDIT_REFUSE'">
|
||||
支付状态:审核被拒
|
||||
</li>
|
||||
<li v-if="orderDetail.offline_pay_info.status_info.const=='AUDIT_REFUSE'">
|
||||
审核备注:{{orderDetail.offline_pay_info.audit_remark}}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<!-- 发票信息 -->
|
||||
<div class="take-delivery-info" v-if="orderDetail.is_invoice ==1">
|
||||
<h4>发票信息</h4>
|
||||
<ul>
|
||||
<li>发票类型:{{ orderDetail.invoice_type == 1 ? '纸质发票' : '电子发票' }}</li>
|
||||
<li>发票抬头类型:{{ orderDetail.invoice_title_type ==1 ? '个人' : '企业' }}</li>
|
||||
<li>发票抬头:{{ orderDetail.invoice_title }}</li>
|
||||
<li>发票内容:{{ orderDetail.invoice_content }}</li>
|
||||
<li v-if="orderDetail.invoice_type == 1">发票邮寄地址地址:{{ orderDetail.invoice_full_address }}</li>
|
||||
<li v-else>发票接收邮箱:{{ orderDetail.invoice_email }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<li :class="{ 'no-operation': !orderDetail.is_enable_refund }">商品信息</li>
|
||||
<li>单价</li>
|
||||
<li>数量</li>
|
||||
<li>小计</li>
|
||||
<li v-if="orderDetail.is_enable_refund">操作</li>
|
||||
</nav>
|
||||
|
||||
<!-- 订单项·商品 -->
|
||||
<div class="list">
|
||||
<ul class="item" v-for="(goodsItem, goodsIndex) in orderDetail.order_goods" :key="goodsIndex">
|
||||
<li :class="{ 'no-operation': !orderDetail.is_enable_refund }">
|
||||
<div class="img-wrap" @click="$util.pushToTab('/sku/' + goodsItem.sku_id)">
|
||||
<img :src="$img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" />
|
||||
</div>
|
||||
<div class="info-wrap">
|
||||
<h5 @click="$util.pushToTab('/sku/' + goodsItem.sku_id)">{{ goodsItem.sku_name }}</h5>
|
||||
<!-- <span>规格:规格值</span> -->
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<span>¥{{ goodsItem.price }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>{{ goodsItem.num }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>¥{{ (goodsItem.price * goodsItem.num).toFixed(2) }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.is_enable_refund">
|
||||
<el-button type="primary" plain size="mini" v-if="goodsItem.refund_status == 0 || goodsItem.refund_status == -1" @click="$router.push({ path: '/order/refund', query: { order_goods_id: goodsItem.order_goods_id } })">退款</el-button>
|
||||
<el-button type="primary" plain size="mini" v-else @click="$router.push({ path: '/order/refund_detail', query: { order_goods_id: goodsItem.order_goods_id } })">查看退款</el-button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- 订单总计 -->
|
||||
<ul class="total">
|
||||
<li>
|
||||
<label>商品金额:</label>
|
||||
<span>¥{{ orderDetail.goods_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.member_card_money > 0">
|
||||
<label>会员卡:</label>
|
||||
<span>¥{{ orderDetail.member_card_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.invoice_money > 0">
|
||||
<label>税费:</label>
|
||||
<span>¥{{ orderDetail.invoice_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.invoice_delivery_money > 0">
|
||||
<label>发票邮寄费:</label>
|
||||
<span>¥{{ orderDetail.invoice_delivery_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.adjust_money != 0">
|
||||
<label>订单调整:</label>
|
||||
<span>
|
||||
<template v-if="orderDetail.adjust_money < 0">-</template>
|
||||
<template v-else>+</template>
|
||||
¥{{ orderDetail.adjust_money | abs }}
|
||||
</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.promotion_money > 0">
|
||||
<label>优惠:</label>
|
||||
<span>¥{{ orderDetail.promotion_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.coupon_money > 0">
|
||||
<label>优惠券:</label>
|
||||
<span>¥{{ orderDetail.coupon_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.point_money > 0">
|
||||
<label>积分抵扣:</label>
|
||||
<span>¥{{ orderDetail.point_money }}</span>
|
||||
</li>
|
||||
<li v-if="orderDetail.balance_money > 0">
|
||||
<label>使用余额:</label>
|
||||
<span>¥{{ orderDetail.balance_money }}</span>
|
||||
</li>
|
||||
<li class="pay-money">
|
||||
<label>实付款:</label>
|
||||
<span>¥{{ orderDetail.pay_money }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {apiOrderDetail} from '@/api/order/order';
|
||||
import orderMethod from '@/utils/orderMethod';
|
||||
import {mapGetters} from 'vuex';
|
||||
import CountDown from "vue2-countdown"
|
||||
|
||||
export default {
|
||||
name: 'order_detail_virtual',
|
||||
components: {
|
||||
CountDown
|
||||
},
|
||||
mixins: [orderMethod],
|
||||
data: () => {
|
||||
return {
|
||||
orderId: 0,
|
||||
orderDetail: null,
|
||||
loading: true,
|
||||
yes: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.orderId = this.$route.query.order_id;
|
||||
this.getOrderDetail();
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['token', 'defaultGoodsImage'])
|
||||
},
|
||||
layout: 'member',
|
||||
methods: {
|
||||
countDownS_cb() {
|
||||
},
|
||||
countDownE_cb() {
|
||||
},
|
||||
getOrderDetail() {
|
||||
apiOrderDetail({
|
||||
order_id: this.orderId
|
||||
}).then(res => {
|
||||
if (res.code >= 0) {
|
||||
let date = (Date.parse(new Date())) / 1000;
|
||||
res.data.currentTime = date
|
||||
res.data.startTime = date
|
||||
res.data.endTime = res.data.create_time + res.data.auto_close
|
||||
this.orderDetail = res.data;
|
||||
if (this.orderDetail.delivery_store_info != '') this.orderDetail.delivery_store_info = JSON.parse(this.orderDetail.delivery_store_info);
|
||||
this.loading = false;
|
||||
} else {
|
||||
this.$message({
|
||||
message: '未获取到订单信息',
|
||||
type: 'warning',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({path: '/member/order_list'});
|
||||
}
|
||||
});
|
||||
}
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error({
|
||||
message: err.message,
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({path: '/member/order_list'});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
operation(action) {
|
||||
switch (action) {
|
||||
case 'orderPay': // 支付
|
||||
this.orderPay(this.orderDetail);
|
||||
break;
|
||||
case 'orderClose': //关闭
|
||||
this.orderClose(this.orderDetail.order_id, () => {
|
||||
this.getOrderDetail();
|
||||
});
|
||||
break;
|
||||
case 'memberOrderEvaluation': //评价
|
||||
this.$util.pushToTab({path: '/order/evaluate', query: {order_id: this.orderDetail.order_id}});
|
||||
break;
|
||||
case 'orderOfflinePay': //线下支付
|
||||
this.$router.push({
|
||||
path: '/pay',
|
||||
query: {
|
||||
code: this.orderDetail.offline_pay_info.out_trade_no
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
imageError(index) {
|
||||
this.orderDetail.order_goods[index].sku_image = this.defaultGoodsImage;
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
abs(value) {
|
||||
return Math.abs(parseFloat(value)).toFixed(2);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.order-detail {
|
||||
.order-status {
|
||||
background-color: #fff;
|
||||
margin-bottom: 20px;
|
||||
|
||||
h4 {
|
||||
margin: 10px 0 20px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
padding-bottom: 10px;
|
||||
|
||||
.edit-time {
|
||||
position: absolute;
|
||||
left: 160px;
|
||||
top: 2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.go-pay {
|
||||
p {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
|
||||
span {
|
||||
font-weight: bold;
|
||||
color: $base-color;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.operation {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.order-info {
|
||||
background-color: #fff;
|
||||
margin-bottom: 10px;
|
||||
|
||||
h4 {
|
||||
margin: 10px 0 20px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
flex: 0 0 33.3333%;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:last-child {
|
||||
flex: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.verify-code-wrap {
|
||||
background-color: #fff;
|
||||
margin-bottom: 10px;
|
||||
|
||||
h4 {
|
||||
margin: 10px 0 20px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
flex: 0 0 33.3333%;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
img {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.virtual-code {
|
||||
text-align: center;
|
||||
|
||||
.tips {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
nav {
|
||||
overflow: hidden;
|
||||
padding: 10px 0;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 50%;
|
||||
|
||||
&.no-operation {
|
||||
width: 60%;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(5) {
|
||||
width: 10%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
|
||||
.item {
|
||||
background-color: #fff;
|
||||
padding: 10px 0;
|
||||
overflow: hidden;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
line-height: 60px;
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 50%;
|
||||
line-height: inherit;
|
||||
|
||||
&.no-operation {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
.img-wrap {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.info-wrap {
|
||||
margin-left: 70px;
|
||||
|
||||
h5 {
|
||||
font-weight: normal;
|
||||
font-size: $ns-font-size-base;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
margin-right: 10px;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: $ns-font-size-sm;
|
||||
color: #9a9a9a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(5) {
|
||||
width: 10%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 总计
|
||||
.total {
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
text-align: right;
|
||||
|
||||
li {
|
||||
span {
|
||||
width: 150px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
&.pay-money {
|
||||
font-weight: bold;
|
||||
|
||||
span {
|
||||
color: $base-color;
|
||||
font-size: 16px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.take-delivery-info {
|
||||
background-color: #fff;
|
||||
margin-bottom: 10px;
|
||||
|
||||
h4 {
|
||||
margin: 10px 0 20px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
ul {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
flex: 0 0 33.3333%;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:last-child {
|
||||
flex: initial;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
461
addon/pc/source/os/pages/member/order_list.vue
Executable file
461
addon/pc/source/os/pages/member/order_list.vue
Executable file
@@ -0,0 +1,461 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card order-list">
|
||||
<div slot="header" class="clearfix"><span>我的订单</span></div>
|
||||
|
||||
<el-tabs v-model="orderStatus" @tab-click="handleClick">
|
||||
<el-tab-pane label="全部订单" name="all"></el-tab-pane>
|
||||
<el-tab-pane label="待付款" name="waitpay"></el-tab-pane>
|
||||
<el-tab-pane label="待发货" name="waitsend"></el-tab-pane>
|
||||
<el-tab-pane label="待收货" name="waitconfirm"></el-tab-pane>
|
||||
<el-tab-pane label="待评价" name="waitrate"></el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<div v-loading="loading">
|
||||
<nav>
|
||||
<li>商品信息</li>
|
||||
<li>单价</li>
|
||||
<li>数量</li>
|
||||
<li>实付款</li>
|
||||
<li>订单状态</li>
|
||||
<li>操作</li>
|
||||
</nav>
|
||||
|
||||
<div class="list" v-if="orderList.length > 0">
|
||||
<div class="item" v-for="(orderItem, orderIndex) in orderList" :key="orderIndex">
|
||||
<div class="head">
|
||||
<span class="create-time">{{ $util.timeStampTurnTime(orderItem.create_time) }}</span>
|
||||
<span class="order-no">订单号:{{ orderItem.order_no }}</span>
|
||||
<!-- <router-link :to="'/shop-' + orderItem.site_id" target="_blank">{{ orderItem.site_name }}</router-link> -->
|
||||
<span class="order-type">{{ orderItem.order_type_name }}</span>
|
||||
</div>
|
||||
<ul v-for="(goodsItem, goodsIndex) in orderItem.order_goods" :key="goodsIndex">
|
||||
<li>
|
||||
<div class="img-wrap" @click="$router.push('/sku/' + goodsItem.sku_id)">
|
||||
<img :src="$img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(orderIndex, goodsIndex)" />
|
||||
</div>
|
||||
<div class="info-wrap" @click="$router.push('/sku/' + goodsItem.sku_id)">
|
||||
<h5>{{ goodsItem.sku_name }}</h5>
|
||||
<!-- <span>规格:规格值</span> -->
|
||||
</div>
|
||||
<div class="order-time" v-if="orderItem.order_status == 0">
|
||||
<img src="../../assets/images/order_time.png" style="width: 15px;height: 15px;margin-right: 6px;" />距离订单自动关闭,剩余
|
||||
<count-down style="color: #f00;margin-left: 10px;" class="count-down"
|
||||
v-on:start_callback="countDownS_cb()" v-on:end_callback="countDownE_cb()"
|
||||
:currentTime="orderItem.currentTime" :startTime="orderItem.startTime"
|
||||
:endTime="orderItem.endTime"
|
||||
:dayTxt="':'" :hourTxt="':'" :minutesTxt="':'" :secondsTxt="''"></count-down>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<span>¥{{ goodsItem.price }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>{{ goodsItem.num }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>¥{{ orderItem.pay_money }}</span>
|
||||
</li>
|
||||
<template v-if="goodsIndex == 0">
|
||||
<li>
|
||||
<span class="ns-text-color">{{ orderItem.order_status_name }}</span>
|
||||
<el-link :underline="false" @click="orderDetail(orderItem)">订单详情</el-link>
|
||||
</li>
|
||||
<li>
|
||||
<template v-if="orderItem.action.length > 0">
|
||||
<el-button type="primary" size="mini" plain v-if="orderItem.is_evaluate == 1" @click="operation('memberOrderEvaluation', orderItem)">
|
||||
<template v-if="orderItem.evaluate_status == 0">评价</template>
|
||||
<template v-else-if="orderItem.evaluate_status == 1">追评</template>
|
||||
</el-button>
|
||||
|
||||
<el-button type="primary" size="mini" :plain="operationItem.action == 'orderPay' ? false : true" v-for="(operationItem, operationIndex) in orderItem.action" :key="operationIndex" @click="operation(operationItem.action, orderItem)">
|
||||
{{ operationItem.title }}
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
<template class="order-operation" v-else-if="orderItem.action.length == 0 && orderItem.is_evaluate == 1">
|
||||
<el-button type="primary" size="mini" plain v-if="orderItem.is_evaluate == 1" @click="operation('memberOrderEvaluation', orderItem)">
|
||||
<template v-if="orderItem.evaluate_status == 0">评价</template>
|
||||
<template v-else-if="orderItem.evaluate_status == 1">追评</template>
|
||||
</el-button>
|
||||
</template>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="!loading && orderList.length == 0" class="empty-wrap">暂无相关订单</div>
|
||||
</div>
|
||||
<div class="pager">
|
||||
<el-pagination background :pager-count="5" :total="total" prev-text="上一页" next-text="下一页"
|
||||
:current-page.sync="currentPage" :page-size.sync="pageSize" @size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange" hide-on-single-page></el-pagination>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapGetters
|
||||
} from 'vuex';
|
||||
import {
|
||||
apiOrderList
|
||||
} from '@/api/order/order';
|
||||
import orderMethod from '@/utils/orderMethod';
|
||||
import CountDown from "vue2-countdown"
|
||||
|
||||
export default {
|
||||
name: 'order_list',
|
||||
components: {
|
||||
CountDown
|
||||
},
|
||||
layout: 'member',
|
||||
data: () => {
|
||||
return {
|
||||
orderStatus: 'all',
|
||||
loading: true,
|
||||
orderList: [],
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
yes: true
|
||||
};
|
||||
},
|
||||
mixins: [orderMethod],
|
||||
created() {
|
||||
this.orderStatus = this.$route.query.status || 'all';
|
||||
this.getOrderList();
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
countDownS_cb() {
|
||||
},
|
||||
countDownE_cb() {
|
||||
},
|
||||
handleClick(tab, event) {
|
||||
this.currentPage = 1;
|
||||
this.orderStatus = tab.name;
|
||||
this.refresh();
|
||||
},
|
||||
getOrderList() {
|
||||
apiOrderList({
|
||||
page: this.currentPage,
|
||||
page_size: this.pageSize,
|
||||
order_status: this.orderStatus
|
||||
}).then(res => {
|
||||
let list = [];
|
||||
let auto_close = 0
|
||||
if (res.code == 0 && res.data) {
|
||||
auto_close = res.data.auto_close
|
||||
let date = (Date.parse(new Date())) / 1000
|
||||
for (let i = 0; i < res.data.list.length; i++) {
|
||||
res.data.list[i].currentTime = date
|
||||
res.data.list[i].startTime = date
|
||||
res.data.list[i].endTime = res.data.list[i].create_time + auto_close
|
||||
}
|
||||
list = res.data.list;
|
||||
this.total = res.data.count;
|
||||
}
|
||||
this.orderList = list;
|
||||
this.loading = false;
|
||||
}).catch(res => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
handlePageSizeChange(size) {
|
||||
this.pageSize = size;
|
||||
this.refresh();
|
||||
},
|
||||
handleCurrentPageChange(page) {
|
||||
this.currentPage = page;
|
||||
this.refresh();
|
||||
},
|
||||
refresh() {
|
||||
this.loading = true;
|
||||
this.getOrderList();
|
||||
},
|
||||
operation(action, orderData) {
|
||||
let index = this.status;
|
||||
switch (action) {
|
||||
case 'orderPay': // 支付
|
||||
this.orderPay(orderData);
|
||||
break;
|
||||
case 'orderClose': //关闭
|
||||
this.orderClose(orderData.order_id, () => {
|
||||
this.refresh();
|
||||
});
|
||||
break;
|
||||
case 'memberTakeDelivery': //收货
|
||||
this.orderDelivery(orderData.order_id, () => {
|
||||
this.refresh();
|
||||
});
|
||||
break;
|
||||
case 'trace': //查看物流
|
||||
this.$router.push({
|
||||
path: '/order/logistics',
|
||||
query: {
|
||||
order_id: orderData.order_id
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'memberOrderEvaluation': //评价
|
||||
this.$router.push({
|
||||
path: '/order/evaluate',
|
||||
query: {
|
||||
order_id: orderData.order_id
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'memberVirtualTakeDelivery': // 虚拟商品 确认使用
|
||||
this.orderVirtualDelivery(orderData.order_id, () => {
|
||||
this.refresh();
|
||||
});
|
||||
break;
|
||||
case 'orderOfflinePay': //线下支付
|
||||
this.$router.push({
|
||||
path: '/pay',
|
||||
query: {
|
||||
code: orderData.offline_pay_info.out_trade_no
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 'orderDelete':
|
||||
this.orderDelete(orderData.order_id, () => {
|
||||
this.refresh();
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
orderDetail(data) {
|
||||
switch (parseInt(data.order_type)) {
|
||||
case 2:
|
||||
// 自提订单
|
||||
this.$router.push({
|
||||
path: '/member/order_detail_pickup',
|
||||
query: {
|
||||
order_id: data.order_id
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 3:
|
||||
// 本地配送订单
|
||||
this.$router.push({
|
||||
path: '/member/order_detail_local_delivery',
|
||||
query: {
|
||||
order_id: data.order_id
|
||||
}
|
||||
});
|
||||
break;
|
||||
case 4:
|
||||
// 虚拟订单
|
||||
this.$router.push({
|
||||
path: '/member/order_detail_virtual',
|
||||
query: {
|
||||
order_id: data.order_id
|
||||
}
|
||||
});
|
||||
break;
|
||||
default:
|
||||
this.$router.push({
|
||||
path: '/member/order_detail',
|
||||
query: {
|
||||
order_id: data.order_id
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
imageError(orderIndex, goodsIndex) {
|
||||
this.orderList[orderIndex].order_goods[goodsIndex].sku_image = this.defaultGoodsImage;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.order-list {
|
||||
nav {
|
||||
overflow: hidden;
|
||||
padding: 10px 0;
|
||||
background: #fff;
|
||||
margin-bottom: 10px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 45%;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
&:nth-child(5) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(6) {
|
||||
width: 10%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
.item {
|
||||
margin-bottom: 20px;
|
||||
border: 1px solid #eeeeee;
|
||||
border-top: 0;
|
||||
|
||||
.head {
|
||||
padding: 8px 10px;
|
||||
background: #f7f7f7;
|
||||
font-size: 12px;
|
||||
|
||||
.create-time {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
|
||||
a {
|
||||
margin: 0 10px 0 20px;
|
||||
}
|
||||
|
||||
.order-type {
|
||||
margin-left: 30px;
|
||||
}
|
||||
}
|
||||
|
||||
.order-time {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
background-color: #fff;
|
||||
padding: 10px;
|
||||
overflow: hidden;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
line-height: 60px;
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 45%;
|
||||
line-height: inherit;
|
||||
|
||||
.img-wrap {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.info-wrap {
|
||||
margin-left: 70px;
|
||||
|
||||
h5 {
|
||||
font-weight: normal;
|
||||
font-size: $ns-font-size-base;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
margin-right: 10px;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: $ns-font-size-sm;
|
||||
color: #9a9a9a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
&:nth-child(5) {
|
||||
width: 15%;
|
||||
line-height: 30px;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(6) {
|
||||
width: 10%;
|
||||
line-height: initial;
|
||||
|
||||
button {
|
||||
margin-left: 0;
|
||||
margin-bottom: 10px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty-wrap {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
164
addon/pc/source/os/pages/member/recharge_detail.vue
Executable file
164
addon/pc/source/os/pages/member/recharge_detail.vue
Executable file
@@ -0,0 +1,164 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card recharge-detail-wrap">
|
||||
<div slot="header" class="clearfix">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/member/account' }">账户余额</el-breadcrumb-item>
|
||||
<el-breadcrumb-item :to="{ path: '/member/recharge_list' }">充值套餐列表</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>充值套餐详情</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
|
||||
<div class="recharge-detail" v-loading="loading">
|
||||
<el-image :src="$img(rechargeInfo.cover_img)" fit="contain"></el-image>
|
||||
<p class="recharge-money">
|
||||
<span class="buy-price">¥{{ rechargeInfo.buy_price }}</span>
|
||||
<span class="face-price">¥{{ rechargeInfo.face_value }}</span>
|
||||
</p>
|
||||
<p class="recharge-name">{{ rechargeInfo.recharge_name }}</p>
|
||||
<p class="recharge-point">额外赠送:{{ rechargeInfo.point }}积分</p>
|
||||
<p class="recharge-growth">额外赠送:{{ rechargeInfo.growth }}成长值</p>
|
||||
<div class="recharge-btn">
|
||||
<el-button @click="recharge">立即充值</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {rechargeDetail, recharge} from "@/api/member/account"
|
||||
import {mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: "recharge-detail",
|
||||
layout: "member",
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
id: '',
|
||||
rechargeInfo: {},
|
||||
loading: true,
|
||||
isSub: false,
|
||||
yes: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.id = this.$route.query.id;
|
||||
this.getRechargeInfo();
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
//获取详情
|
||||
getRechargeInfo() {
|
||||
rechargeDetail({
|
||||
recharge_id: this.id
|
||||
}).then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.rechargeInfo = res.data;
|
||||
if (res.data.cover_img == '') {
|
||||
this.rechargeInfo.cover_img = this.defaultGoodsImage;
|
||||
}
|
||||
} else {
|
||||
this.$message.warning(res.message)
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(err => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
recharge() {
|
||||
if (this.isSub) return
|
||||
this.isSub = true
|
||||
|
||||
recharge({
|
||||
recharge_id: this.id
|
||||
}).then(res => {
|
||||
if (res.data && res.code == 0) {
|
||||
this.$router.push({path: '/pay', query: {code: res.data}});
|
||||
} else {
|
||||
this.$message.warning(res.message)
|
||||
}
|
||||
this.isSub = false
|
||||
}).catch(err => {
|
||||
this.isSub = false
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.el-card.is-always-shadow,
|
||||
.el-card.is-hover-shadow:focus,
|
||||
.el-card.is-hover-shadow:hover {
|
||||
box-shadow: unset;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.recharge-detail-wrap {
|
||||
}
|
||||
|
||||
.recharge-detail {
|
||||
width: 300px;
|
||||
|
||||
.recharge-money {
|
||||
.buy-price {
|
||||
font-size: 25px;
|
||||
color: $base-color;
|
||||
font-weight: 600;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.face-price {
|
||||
text-decoration: line-through;
|
||||
color: #898989;
|
||||
}
|
||||
}
|
||||
|
||||
.recharge-name {
|
||||
margin: 10px 0;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.recharge-btn {
|
||||
margin-top: 30px;
|
||||
text-align: center;
|
||||
|
||||
.el-button {
|
||||
width: 300px;
|
||||
background-color: $base-color;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
291
addon/pc/source/os/pages/member/recharge_list.vue
Executable file
291
addon/pc/source/os/pages/member/recharge_list.vue
Executable file
@@ -0,0 +1,291 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/member/account' }">账户余额</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>充值套餐列表</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
|
||||
<div class="recharge-wrap" v-loading="loading">
|
||||
<div class="account-wrap">
|
||||
<div class="account-left">
|
||||
<div class="title">我的可用余额(元)</div>
|
||||
<div class="money">
|
||||
<div class="balance-money">
|
||||
<b>{{ integer }}</b>
|
||||
<span>.{{ decimal }}</span>
|
||||
</div>
|
||||
<div class="tx" @click="rechargeOrder">充值记录</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="account-right">
|
||||
<div class="item-wrap">
|
||||
<div class="item">
|
||||
<div class="iconfont icon-ziyuan"></div>
|
||||
<div class="title">可提现余额:</div>
|
||||
<b class="num">{{ balanceInfo.balance_money }}</b>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="iconfont icon-ziyuan"></div>
|
||||
<div class="title">不可提现余额:</div>
|
||||
<b class="num">{{ balanceInfo.balance }}</b>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="recharge-table">
|
||||
<el-table :data="rechargeList" border>
|
||||
<el-table-column label="套餐名称">
|
||||
<template slot-scope="scope">
|
||||
<div class="recharge-info">
|
||||
<el-image :src="$img(scope.row.cover_img)" fit="contain" @error="imageError(scope.$index)"></el-image>
|
||||
<p :title="scope.row.recharge_name">{{ scope.row.recharge_name }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="面值" width="150">
|
||||
<template slot-scope="scope">
|
||||
<div>价格:¥{{ scope.row.face_value }}</div>
|
||||
<div>充值面额:¥{{ scope.row.buy_price }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="point" label="赠送积分" width="150"></el-table-column>
|
||||
<el-table-column prop="growth" label="赠送成长值" width="150"></el-table-column>
|
||||
<el-table-column label="操作" width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" @click="handleDetail(scope.$index, scope.row)">充值</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pager">
|
||||
<el-pagination
|
||||
background
|
||||
:pager-count="5"
|
||||
:total="total"
|
||||
prev-text="上一页"
|
||||
next-text="下一页"
|
||||
:current-page.sync="currentPage"
|
||||
:page-size.sync="pageSize"
|
||||
@size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange"
|
||||
hide-on-single-page
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {balance, rechargeList} from "@/api/member/account"
|
||||
import {mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: "recharge_list",
|
||||
layout: "member",
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
balanceInfo: {
|
||||
balance: 0,
|
||||
balance_money: 0
|
||||
},
|
||||
integer: 0,
|
||||
decimal: 0,
|
||||
rechargeList: [],
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
loading: true,
|
||||
yes: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getUserInfo()
|
||||
this.getData()
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
methods: {
|
||||
handlePageSizeChange(size) {
|
||||
this.pageSize = size
|
||||
this.refresh()
|
||||
},
|
||||
handleCurrentPageChange(page) {
|
||||
this.currentPage = page
|
||||
this.refresh()
|
||||
},
|
||||
refresh() {
|
||||
this.loading = true
|
||||
this.getData()
|
||||
},
|
||||
/**
|
||||
* 获取余额信息
|
||||
*/
|
||||
getUserInfo() {
|
||||
balance({
|
||||
account_type: 'balance,balance_money'
|
||||
}).then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.balanceInfo = res.data
|
||||
const price = (parseFloat(this.balanceInfo.balance) + parseFloat(this.balanceInfo.balance_money)).toFixed(2)
|
||||
let priceSplit = price.split(".")
|
||||
this.integer = priceSplit[0]
|
||||
this.decimal = priceSplit[1]
|
||||
} else {
|
||||
this.$message.warning(res.message)
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 获取充值套餐列表
|
||||
*/
|
||||
getData() {
|
||||
rechargeList({
|
||||
page: this.currentPage,
|
||||
page_size: this.pageSize
|
||||
}).then(res => {
|
||||
if (res.code == 0 && res.data.list) {
|
||||
this.rechargeList = res.data.list
|
||||
this.total = res.data.count
|
||||
} else {
|
||||
this.$message.warning(res.message)
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(err => {
|
||||
this.loading = false
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
},
|
||||
imageError(index) {
|
||||
this.rechargeList[index].cover_img = this.defaultGoodsImage;
|
||||
},
|
||||
handleDetail(index, row) {
|
||||
this.$router.push({path: '/member/recharge_detail', query: {id: row.recharge_id}})
|
||||
},
|
||||
rechargeOrder() {
|
||||
this.$router.push('/member/recharge_order')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.el-card.is-always-shadow,
|
||||
.el-card.is-hover-shadow:focus,
|
||||
.el-card.is-hover-shadow:hover {
|
||||
box-shadow: unset;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.account-wrap {
|
||||
display: flex;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.account-left {
|
||||
flex: 1;
|
||||
|
||||
.title {
|
||||
font-size: $ns-font-size-base;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.money {
|
||||
display: flex;
|
||||
|
||||
.balance-money {
|
||||
b {
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.tx {
|
||||
color: $base-color;
|
||||
margin-left: 5px;
|
||||
margin-top: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.account-right {
|
||||
flex: 1;
|
||||
font-size: $ns-font-size-base;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.title {
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
.num {
|
||||
margin-left: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.recharge-table {
|
||||
.recharge-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.el-image {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
margin-right: 10px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
294
addon/pc/source/os/pages/member/recharge_order.vue
Executable file
294
addon/pc/source/os/pages/member/recharge_order.vue
Executable file
@@ -0,0 +1,294 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/member/account' }">账户余额</el-breadcrumb-item>
|
||||
<el-breadcrumb-item :to="{ path: '/member/recharge_list' }">充值套餐列表</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>充值记录</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
|
||||
<div v-loading="loading">
|
||||
<div class="order-list">
|
||||
<nav>
|
||||
<li>套餐名称</li>
|
||||
<li>面值</li>
|
||||
<li>购买价格</li>
|
||||
<li>赠送积分</li>
|
||||
<li>赠送成长值</li>
|
||||
</nav>
|
||||
|
||||
<div class="list" v-if="orderList.length > 0">
|
||||
<div class="item" v-for="(orderItem, orderIndex) in orderList" :key="orderIndex">
|
||||
<div class="head">
|
||||
<span class="create-time">{{ $util.timeStampTurnTime(orderItem.create_time) }}</span>
|
||||
<span class="order-no">订单号:{{ orderItem.order_no }}</span>
|
||||
</div>
|
||||
<ul>
|
||||
<li>
|
||||
<div class="img-wrap">
|
||||
<el-image :src="$img(orderItem.cover_img)" fit="cover" @error="imageError(orderIndex)"></el-image>
|
||||
</div>
|
||||
<div class="info-wrap">
|
||||
<h5 :title="orderItem.recharge_name">{{ orderItem.recharge_name }}</h5>
|
||||
<!-- <span>规格:规格值</span> -->
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<span>¥{{ orderItem.face_value }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>¥{{ orderItem.buy_price }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>{{ orderItem.point }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>{{ orderItem.growth }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="!loading && orderList.length == 0" class="empty-wrap">暂无相关订单</div>
|
||||
</div>
|
||||
|
||||
<div class="pager">
|
||||
<el-pagination
|
||||
background
|
||||
:pager-count="5"
|
||||
:total="total"
|
||||
prev-text="上一页"
|
||||
next-text="下一页"
|
||||
:current-page.sync="currentPage"
|
||||
:page-size.sync="pageSize"
|
||||
@size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange"
|
||||
hide-on-single-page
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {rechargeOrder} from "@/api/member/account"
|
||||
import {mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: "recharge_list",
|
||||
layout: "member",
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
orderList: [],
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
loading: true,
|
||||
yes: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getListData()
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
methods: {
|
||||
handlePageSizeChange(size) {
|
||||
this.pageSize = size
|
||||
this.refresh()
|
||||
},
|
||||
handleCurrentPageChange(page) {
|
||||
this.currentPage = page
|
||||
this.refresh()
|
||||
},
|
||||
refresh() {
|
||||
this.loading = true
|
||||
this.getListData()
|
||||
},
|
||||
getListData() {
|
||||
rechargeOrder({
|
||||
page: this.currentPage,
|
||||
page_size: this.pageSize
|
||||
}).then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.orderList = res.data.list;
|
||||
} else {
|
||||
this.$message.warning(res.message)
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(err => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
imageError(index) {
|
||||
this.orderList[index].cover_img = this.defaultGoodsImage;
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.el-card.is-always-shadow,
|
||||
.el-card.is-hover-shadow:focus,
|
||||
.el-card.is-hover-shadow:hover {
|
||||
box-shadow: unset;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.order-list {
|
||||
nav {
|
||||
overflow: hidden;
|
||||
padding: 10px;
|
||||
background: #fff;
|
||||
margin-bottom: 10px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 40%;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(5) {
|
||||
width: 15%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
.item {
|
||||
margin-bottom: 20px;
|
||||
border: 1px solid #eeeeee;
|
||||
border-top: 0;
|
||||
|
||||
.head {
|
||||
padding: 8px 10px;
|
||||
background: #f7f7f7;
|
||||
font-size: 12px;
|
||||
|
||||
.create-time {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
|
||||
a {
|
||||
margin: 0 10px 0 20px;
|
||||
}
|
||||
|
||||
.order-type {
|
||||
margin-left: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
background-color: #fff;
|
||||
padding: 10px;
|
||||
overflow: hidden;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
line-height: 60px;
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 40%;
|
||||
line-height: inherit;
|
||||
|
||||
.img-wrap {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
|
||||
.el-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.info-wrap {
|
||||
margin-left: 70px;
|
||||
|
||||
h5 {
|
||||
font-weight: normal;
|
||||
font-size: $ns-font-size-base;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
width: 15%;
|
||||
}
|
||||
|
||||
&:nth-child(5) {
|
||||
width: 15%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty-wrap {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
322
addon/pc/source/os/pages/member/security/index.vue
Executable file
322
addon/pc/source/os/pages/member/security/index.vue
Executable file
@@ -0,0 +1,322 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<div class="security" v-loading="loading">
|
||||
<div class="item-wrap" v-if="type == 'all'">
|
||||
<div class="item">
|
||||
<div class="item-content">
|
||||
<i class="iconfont icon-xiugaidenglumima"></i>
|
||||
<div class="name-wrap">
|
||||
<div class="name">登录密码</div>
|
||||
<div class="info">互联网账号存在被盗风险,建议您定期更改密码以保护账户安全</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<el-button type="primary" size="medium" @click="edit('password')">修改</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="item">
|
||||
<div class="item-content">
|
||||
<i class="iconfont iconyouxiang1"></i>
|
||||
<div class="name-wrap">
|
||||
<div class="name">邮箱绑定</div>
|
||||
<div class="info">验证后,可用于快速找回登录密码及支付密码</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn"><el-button type="primary" size="medium" @click="edit('email')">修改</el-button></div>
|
||||
</div> -->
|
||||
<div class="item">
|
||||
<div class="item-content">
|
||||
<i class="iconfont icon-shoujiyanzheng"></i>
|
||||
<div class="name-wrap">
|
||||
<div class="name">手机验证</div>
|
||||
<div class="info">验证后,可用于快速找回登录密码及支付密码,接收账户余额变动提醒</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<el-button type="primary" size="medium" @click="edit('tell')">修改</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="item">
|
||||
<div class="item-content">
|
||||
<i class="el-icon-lock"></i>
|
||||
<div class="name-wrap">
|
||||
<div class="name">支付密码</div>
|
||||
<div class="content">互联网支付存在被盗风险,建议您定期更改支付密码以保护账户安全</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn"><el-button type="primary" size="medium" @click="edit('payPassWord')">修改</el-button></div>
|
||||
</div> -->
|
||||
</div>
|
||||
<div class="edit" v-if="type == 'password'">
|
||||
<div class="title">修改登录密码</div>
|
||||
<div v-if="memberInfo.password">
|
||||
<div class="pass-form">
|
||||
<el-form :model="passWordForm" :rules="passWordRules" ref="passWordRef" label-width="100px">
|
||||
<el-form-item label="原密码" prop="oldPass">
|
||||
<el-input type="password" placeholder="当前密码" v-model="passWordForm.oldPass"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="pass">
|
||||
<el-input type="password" placeholder="新密码" v-model="passWordForm.pass"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码" prop="checkPass">
|
||||
<el-input type="password" placeholder="请确认新密码" v-model="passWordForm.checkPass"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<el-button type="primary" @click="save">保存</el-button>
|
||||
<el-button @click="type = 'all'">取消</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="tell-pass">
|
||||
<el-form :model="tellPassForm" :rules="tellPassRules" ref="tellPassRef" label-width="100px">
|
||||
<el-form-item label="验证码" prop="code">
|
||||
<el-input placeholder="请输入验证码" maxlength="4" v-model="tellPassForm.code">
|
||||
<template slot="append">
|
||||
<img :src="captcha.img" mode class="captcha" @click="getcaptcha" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="动态码" prop="tellPassDynacode">
|
||||
<el-input placeholder="请输入动态码" v-model="tellPassForm.tellPassDynacode">
|
||||
<template slot="append">
|
||||
<el-button type="primary" @click="getTellPassCode">{{ tellPassForm.tellPassCodeText }}</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<p class="tell-code">点击“获取动态码”,将会向您已绑定的手机号{{ memberInfo.mobile | mobile }}发送验证码</p>
|
||||
<el-form-item label="新密码" prop="pass">
|
||||
<el-input type="password" placeholder="新密码" v-model="tellPassForm.pass"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码" prop="checkPass">
|
||||
<el-input type="password" placeholder="请确认新密码" v-model="tellPassForm.checkPass"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div class="btn">
|
||||
<el-button type="primary" @click="tellPassSave">保存</el-button>
|
||||
<el-button @click="type = 'all'">取消</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="edit" v-if="type == 'email'">
|
||||
<div class="title">绑定邮箱</div>
|
||||
<div class="pass-form">
|
||||
<el-form :model="emailForm" :rules="emailRules" ref="emailRef" label-width="100px">
|
||||
<el-form-item label="当前邮箱" prop="email" v-if="emailForm.currEmail">
|
||||
<p>{{ emailForm.currEmail }}</p>
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input type="email" placeholder="请输入邮箱" v-model="emailForm.email"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="验证码" prop="code">
|
||||
<el-input placeholder="请输入验证码" maxlength="4" v-model="emailForm.code">
|
||||
<template slot="append">
|
||||
<img :src="captcha.img" mode class="captcha" @click="getcaptcha" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="动态码" prop="emailDynacode">
|
||||
<el-input placeholder="请输入动态码" v-model="emailForm.emailDynacode">
|
||||
<template slot="append">
|
||||
<el-button type="primary" @click="getEmailCode">{{ emailForm.emailCodeText }}</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<el-button type="primary" @click="bindEmail">保存</el-button>
|
||||
<el-button @click="type = 'all'">取消</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="edit" v-if="type == 'tell'">
|
||||
<div class="title">绑定手机号</div>
|
||||
<div class="pass-form">
|
||||
<el-form :model="tellForm" :rules="tellRules" ref="tellRef" label-width="100px">
|
||||
<el-form-item label="当前手机号" prop="email" v-if="tellForm.currTell">
|
||||
<p>{{ tellForm.currTell }}</p>
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号" prop="tell">
|
||||
<el-input type="tell" placeholder="请输入手机号" v-model="tellForm.tell"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="验证码" prop="code">
|
||||
<el-input placeholder="请输入验证码" maxlength="4" v-model="tellForm.code">
|
||||
<template slot="append">
|
||||
<img :src="captcha.img" mode class="captcha" @click="getcaptcha" />
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="动态码" prop="tellDynacode">
|
||||
<el-input placeholder="请输入动态码" v-model="tellForm.tellDynacode">
|
||||
<template slot="append">
|
||||
<el-button type="primary" @click="gettellCode">{{ tellForm.tellCodeText }}</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<el-button type="primary" @click="bindtell">保存</el-button>
|
||||
<el-button @click="type = 'all'">取消</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="edit-pay" v-if="type == 'payPassWord'">
|
||||
<div class="title">绑定支付密码</div>
|
||||
<div class="container">
|
||||
<div class="name" v-if="step != 0">请输入6位支付密码,建议不要使用重复或连续数字</div>
|
||||
<div class="name" v-else-if="isSend">验证码已发送至{{ tellForm.currTell | mobile }}</div>
|
||||
<div class="password-wrap">
|
||||
<el-input :maxlength="step == 0 ? 4 : 6" @change="input" ref="input" :auto-focus="true" v-model="payInput" :placeholder="palceText" v-if="step == 0"/>
|
||||
<el-input :maxlength="step == 0 ? 4 : 6" @change="input" ref="input" :auto-focus="true" v-model="payInput" type="password" :placeholder="palceText" v-else />
|
||||
<div v-show="step == 0" class="dynacode" @click="sendMobileCode">{{ payCodeText }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="btn">
|
||||
<el-button type="primary" @click="bindPayPwd" :disabled="isClick">保存</el-button>
|
||||
<el-button @click="type = 'all'">取消</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import security from './security';
|
||||
|
||||
export default {
|
||||
name: 'security',
|
||||
layout: "member",
|
||||
mixins: [security]
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.security {
|
||||
background: #ffffff;
|
||||
|
||||
.el-form {
|
||||
margin: 0 30px;
|
||||
|
||||
.captcha {
|
||||
vertical-align: top;
|
||||
max-width: inherit;
|
||||
width: 74px;
|
||||
max-height: 38px;
|
||||
line-height: 38px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.item {
|
||||
border-bottom: 1px solid #f1f1ff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 20px;
|
||||
|
||||
.item-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
i {
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
.name-wrap {
|
||||
margin-left: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.edit {
|
||||
padding: 20px;
|
||||
|
||||
.title {
|
||||
padding-bottom: 5px;
|
||||
font-size: $ns-font-size-base;
|
||||
border-bottom: 1px solid #f1f1f1;
|
||||
}
|
||||
|
||||
.pass-form {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
.el-form {
|
||||
width: 500px;
|
||||
}
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.tell-pass {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.el-form {
|
||||
width: 500px;
|
||||
}
|
||||
|
||||
.tell-code {
|
||||
margin-left: 66px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.edit-pay {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
|
||||
.title {
|
||||
font-size: $ns-font-size-base;
|
||||
border-bottom: 1px solid #f1f1f1;
|
||||
text-align: left;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.dynacode {
|
||||
cursor: pointer;
|
||||
text-align: right;
|
||||
margin-right: 329px;
|
||||
color: $base-color;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.el-input {
|
||||
width: 300px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.btn {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.name {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
600
addon/pc/source/os/pages/member/security/security.js
Executable file
600
addon/pc/source/os/pages/member/security/security.js
Executable file
@@ -0,0 +1,600 @@
|
||||
import {
|
||||
passWord,
|
||||
emailCode,
|
||||
checkEmail,
|
||||
email,
|
||||
tellCode,
|
||||
tell,
|
||||
verifyPayPwdCode,
|
||||
modifyPayPassword,
|
||||
payPwdCode,
|
||||
pwdMoblieCode
|
||||
} from "@/api/member/security"
|
||||
import {
|
||||
info
|
||||
} from "@/api/member/info"
|
||||
import {
|
||||
captcha
|
||||
} from "@/api/website"
|
||||
|
||||
export default {
|
||||
name: "security",
|
||||
components: {},
|
||||
data() {
|
||||
var validatePass = (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请输入新密码"))
|
||||
} else if (value == this.passWordForm.oldPass) {
|
||||
callback(new Error("新密码不能与原密码相同!"))
|
||||
} else {
|
||||
if (this.passWordForm.checkPass !== "") {
|
||||
this.$refs.passWordRef.validateField("checkPass")
|
||||
}
|
||||
callback()
|
||||
}
|
||||
}
|
||||
var validatePass2 = (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请再次输入密码"))
|
||||
} else if (value !== this.passWordForm.pass) {
|
||||
callback(new Error("两次输入密码不一致!"))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
var validateTellPass = (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请输入新密码"))
|
||||
} else if (value == this.tellPassForm.oldPass) {
|
||||
callback(new Error("新密码不能与原密码相同!"))
|
||||
} else {
|
||||
if (this.tellPassForm.checkPass !== "") {
|
||||
this.$refs.tellPassRef.validateField("checkPass")
|
||||
}
|
||||
callback()
|
||||
}
|
||||
}
|
||||
var validateTellPass2 = (rule, value, callback) => {
|
||||
if (value === "") {
|
||||
callback(new Error("请再次输入密码"))
|
||||
} else if (value !== this.tellPassForm.pass) {
|
||||
callback(new Error("两次输入密码不一致!"))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
var checkemail = (rules, value, callback) => {
|
||||
const regEmail = /^\w+@\w+(\.\w+)+$/
|
||||
if (regEmail.test(value)) {
|
||||
return callback()
|
||||
}
|
||||
callback(new Error("请输入正确的的邮箱"))
|
||||
}
|
||||
var checkTell = (rules, value, callback) => {
|
||||
const regMobile = /^1[3|4|5|6|7|8|9][0-9]{9}$/
|
||||
if (regMobile.test(value)) {
|
||||
return callback()
|
||||
}
|
||||
callback(new Error("请输入正确的手机号"))
|
||||
}
|
||||
return {
|
||||
type: "all",
|
||||
passWordForm: {
|
||||
oldPass: "",
|
||||
pass: "",
|
||||
checkPass: ""
|
||||
},
|
||||
emailForm: {
|
||||
email: "",
|
||||
code: "", //邮箱验证码
|
||||
emailDynacode: "", //邮箱动态验证码
|
||||
emailCodeText: "",
|
||||
key: "",
|
||||
currEmail: ""
|
||||
},
|
||||
passWordRules: {
|
||||
oldPass: [{
|
||||
required: true,
|
||||
message: "请输入原密码",
|
||||
trigger: "blur"
|
||||
}],
|
||||
pass: [{
|
||||
required: true,
|
||||
validator: validatePass,
|
||||
trigger: "blur"
|
||||
}],
|
||||
checkPass: [{
|
||||
required: true,
|
||||
validator: validatePass2,
|
||||
trigger: "blur"
|
||||
}]
|
||||
},
|
||||
emailRules: {
|
||||
email: [{
|
||||
required: true,
|
||||
message: "请输入正确的邮箱",
|
||||
trigger: "blur"
|
||||
}, {
|
||||
validator: checkemail,
|
||||
trigger: "blur"
|
||||
}],
|
||||
code: [{
|
||||
required: true,
|
||||
message: "请输入验证码",
|
||||
trigger: "blur"
|
||||
}],
|
||||
emailDynacode: [{
|
||||
required: true,
|
||||
message: "请输入动态验证码",
|
||||
trigger: "blur"
|
||||
}]
|
||||
},
|
||||
captcha: {
|
||||
id: "",
|
||||
img: ""
|
||||
},
|
||||
seconds: 120,
|
||||
timer: null,
|
||||
isSend: false,
|
||||
isMobileSend: false,
|
||||
tellForm: {
|
||||
tell: "",
|
||||
code: "", //邮箱验证码
|
||||
tellDynacode: "", //邮箱动态验证码
|
||||
tellCodeText: "",
|
||||
key: "",
|
||||
currTell: ""
|
||||
},
|
||||
tellRules: {
|
||||
tell: [{
|
||||
required: true,
|
||||
message: "请输入正确的手机号",
|
||||
trigger: "blur"
|
||||
}, {
|
||||
validator: checkTell,
|
||||
trigger: "blur"
|
||||
}],
|
||||
code: [{
|
||||
required: true,
|
||||
message: "请输入验证码",
|
||||
trigger: "blur"
|
||||
}],
|
||||
tellDynacode: [{
|
||||
required: true,
|
||||
message: "请输入动态验证码",
|
||||
trigger: "blur"
|
||||
}]
|
||||
},
|
||||
isClick: true,
|
||||
payCodeText: '获取验证码',
|
||||
step: 0,
|
||||
payCode: '', // 动态码
|
||||
payPassword: '', // 支付密码
|
||||
payRepassword: '', // 重复支付密码
|
||||
payKey: '', // 短信key
|
||||
payInput: '',
|
||||
palceText: '输入短信验证码',
|
||||
memberInfo: {},
|
||||
tellPassForm: {
|
||||
code: "",
|
||||
tellPassCodeText: "",
|
||||
key: "",
|
||||
tellPassDynacode: "",
|
||||
pass: '',
|
||||
checkPass: ''
|
||||
},
|
||||
tellPassRules: {
|
||||
code: [{
|
||||
required: true,
|
||||
message: "请输入验证码",
|
||||
trigger: "blur"
|
||||
}],
|
||||
tellPassDynacode: [{
|
||||
required: true,
|
||||
message: "请输入动态验证码",
|
||||
trigger: "blur"
|
||||
}],
|
||||
pass: [{
|
||||
required: true,
|
||||
validator: validateTellPass,
|
||||
trigger: "blur"
|
||||
}],
|
||||
checkPass: [{
|
||||
required: true,
|
||||
validator: validateTellPass2,
|
||||
trigger: "blur"
|
||||
}]
|
||||
},
|
||||
loading: true,
|
||||
yes: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.getcaptcha()
|
||||
this.seconds = 120
|
||||
this.tellForm.tellCodeText = "获取动态码"
|
||||
this.emailForm.emailCodeText = "获取动态码"
|
||||
this.tellPassForm.tellPassCodeText = "获取动态码"
|
||||
this.isSend = false
|
||||
this.isMobileSend = false
|
||||
clearInterval(this.timer)
|
||||
this.getInfo()
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
//获取个人信息
|
||||
async getInfo() {
|
||||
await info().then(res => {
|
||||
if (res.code == 0) {
|
||||
this.memberInfo = res.data
|
||||
this.emailForm.currEmail = res.data.email
|
||||
this.tellForm.currTell = res.data.mobile
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(err => {
|
||||
this.loading = false
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
},
|
||||
async edit(type) {
|
||||
await this.getInfo()
|
||||
if (type == 'payPassWord') {
|
||||
if (!this.tellForm.currTell) {
|
||||
this.$confirm("你还未绑定手机号,请先绑定手机号?", "提示信息", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning"
|
||||
}).then(res => {
|
||||
if (res = 'confirm') {
|
||||
this.type = 'tell'
|
||||
} else {
|
||||
this.type = 'all'
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.type = type
|
||||
}
|
||||
} else {
|
||||
this.type = type
|
||||
}
|
||||
},
|
||||
//获取验证码
|
||||
getcaptcha() {
|
||||
captcha({
|
||||
captcha_id: this.captcha.id
|
||||
}).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.captcha = res.data
|
||||
this.captcha.img = this.captcha.img.replace(/\r\n/g, "")
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
},
|
||||
//修改密码
|
||||
save() {
|
||||
this.$refs.passWordRef.validate(valid => {
|
||||
if (valid) {
|
||||
passWord({
|
||||
new_password: this.passWordForm.pass,
|
||||
old_password: this.passWordForm.oldPass
|
||||
}).then(res => {
|
||||
this.$message({
|
||||
message: "修改密码成功",
|
||||
type: "success"
|
||||
});
|
||||
this.type = "all";
|
||||
this.$store.dispatch("member/member_detail", {
|
||||
refresh: 1
|
||||
});
|
||||
this.passWordForm.pass = "";
|
||||
this.passWordForm.oldPass = "";
|
||||
this.passWordForm.checkPass = "";
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
// 检测邮箱是否存在
|
||||
async getCheckEmail() {
|
||||
let result = await checkEmail({
|
||||
email: this.emailForm.email
|
||||
}).then(res => {
|
||||
if (res.code != 0) {
|
||||
this.$message({
|
||||
message: res.message,
|
||||
type: "success"
|
||||
});
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message)
|
||||
});
|
||||
return result
|
||||
},
|
||||
//绑定邮箱
|
||||
async bindEmail() {
|
||||
this.$refs.emailRef.validate(valid => {
|
||||
if (valid) {
|
||||
email({
|
||||
email: this.emailForm.email,
|
||||
captcha_id: this.captcha.id,
|
||||
captcha_code: this.emailForm.code,
|
||||
code: this.emailForm.emailDynacode,
|
||||
key: this.emailForm.key
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message({
|
||||
message: "邮箱绑定成功",
|
||||
type: "success"
|
||||
});
|
||||
this.type = "all";
|
||||
this.emailForm.email = "";
|
||||
this.emailForm.code = "";
|
||||
this.emailForm.emailDynacode = "";
|
||||
clearInterval(this.timer);
|
||||
this.getcaptcha()
|
||||
}
|
||||
}).catch(err => {
|
||||
this.getcaptcha();
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
//获取手机验证码
|
||||
async gettellCode() {
|
||||
if (!this.isMobileSend) {
|
||||
this.isMobileSend = true;
|
||||
await tellCode({
|
||||
mobile: this.tellForm.tell,
|
||||
captcha_id: this.captcha.id,
|
||||
captcha_code: this.tellForm.code
|
||||
}).then(res => {
|
||||
let data = res.data;
|
||||
if (data.key) {
|
||||
if (this.seconds == 120 && this.timer == null) {
|
||||
this.timer = setInterval(() => {
|
||||
this.seconds--;
|
||||
this.tellForm.tellCodeText = "已发送(" + this.seconds + "s)"
|
||||
}, 1000)
|
||||
}
|
||||
this.tellForm.key = data.key
|
||||
} else {
|
||||
this.$message({
|
||||
message: res.message,
|
||||
type: "warning"
|
||||
});
|
||||
this.isMobileSend = false
|
||||
}
|
||||
}).catch(err => {
|
||||
this.getcaptcha();
|
||||
this.$message.error(err.message);
|
||||
if (err.message == '当前手机号已存在') {
|
||||
this.isMobileSend = false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$message({
|
||||
message: "请勿重复点击",
|
||||
type: "warning"
|
||||
})
|
||||
}
|
||||
},
|
||||
//绑定手机号
|
||||
bindtell() {
|
||||
this.$refs.tellRef.validate(valid => {
|
||||
if (valid) {
|
||||
tell({
|
||||
mobile: this.tellForm.tell,
|
||||
captcha_id: this.captcha.id,
|
||||
captcha_code: this.tellForm.code,
|
||||
code: this.tellForm.tellDynacode,
|
||||
key: this.tellForm.key
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message({
|
||||
message: "手机号绑定成功",
|
||||
type: "success"
|
||||
});
|
||||
this.type = "all";
|
||||
this.tellForm.email = "";
|
||||
this.tellForm.code = "";
|
||||
this.tellForm.emailDynacode = "";
|
||||
clearInterval(this.timer);
|
||||
this.getcaptcha()
|
||||
}
|
||||
}).catch(err => {
|
||||
this.getcaptcha();
|
||||
this.$message.error(err.message);
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
//获取输入框数据
|
||||
input(val) {
|
||||
this.isClick = false;
|
||||
if (this.step == 0 && val.length == 4) {
|
||||
this.payCode = val;
|
||||
} else if (this.step == 1 && val.length == 6) {
|
||||
this.payPassword = val;
|
||||
} else if (val.length == 6) {
|
||||
this.payRepassword = val;
|
||||
}
|
||||
|
||||
},
|
||||
//获取支付验证码
|
||||
sendMobileCode() {
|
||||
if (!this.isSend) {
|
||||
payPwdCode().then(res => {
|
||||
let data = res.data;
|
||||
if (data.key) {
|
||||
if (this.seconds == 120 && this.timer == null) {
|
||||
this.timer = setInterval(() => {
|
||||
this.seconds--;
|
||||
this.payCodeText =
|
||||
"已发送(" + this.seconds + "s)";
|
||||
}, 1000);
|
||||
}
|
||||
this.payKey = data.key;
|
||||
} else {
|
||||
this.$message({
|
||||
message: res.message,
|
||||
type: 'warning'
|
||||
});
|
||||
this.isSend = false;
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
}
|
||||
},
|
||||
//点击确定
|
||||
bindPayPwd() {
|
||||
clearInterval(this.timer);
|
||||
const reg = /^[0-9]*$/;
|
||||
if (this.step == 0) {
|
||||
verifyPayPwdCode({
|
||||
code: this.payCode,
|
||||
key: this.payKey
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$refs.input.clear();
|
||||
this.step = 1;
|
||||
this.palceText = '请设置支付密码'
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message);
|
||||
})
|
||||
} else if (this.step == 1) {
|
||||
if (reg.test(this.$refs.input.value)) {
|
||||
this.$refs.input.clear();
|
||||
this.step = 2;
|
||||
this.palceText = '请再次输入'
|
||||
} else {
|
||||
this.$message.error('请输入数字');
|
||||
this.step = 1;
|
||||
this.$refs.input.clear();
|
||||
}
|
||||
} else {
|
||||
if (this.payPassword == this.payRepassword) {
|
||||
if (this.isSub) return;
|
||||
this.isSub = true;
|
||||
modifyPayPassword({
|
||||
key: this.payKey,
|
||||
code: this.payCode,
|
||||
password: this.payPassword
|
||||
}).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.$message({
|
||||
message: "修改支付密码成功",
|
||||
type: "success"
|
||||
});
|
||||
this.type = 'all';
|
||||
this.step = 0;
|
||||
this.$refs.input.clear();
|
||||
clearInterval(this.timer)
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message);
|
||||
})
|
||||
} else {
|
||||
this.$message.error('两次密码输入不一样');
|
||||
this.initInfo();
|
||||
}
|
||||
}
|
||||
},
|
||||
//初始化信息
|
||||
initInfo() {
|
||||
this.step = 1;
|
||||
this.palceText = '请设置支付密码';
|
||||
this.password = '';
|
||||
this.repassword = '';
|
||||
this.oldpassword = '';
|
||||
this.isSub = false;
|
||||
this.$refs.input.clear();
|
||||
},
|
||||
//获取动态码
|
||||
getTellPassCode() {
|
||||
if (!this.isSend) {
|
||||
this.isSend = true;
|
||||
pwdMoblieCode({
|
||||
captcha_id: this.captcha.id,
|
||||
captcha_code: this.tellPassForm.code,
|
||||
}).then(res => {
|
||||
let data = res.data;
|
||||
if (data.key) {
|
||||
if (this.seconds == 120 && this.timer == null) {
|
||||
this.timer = setInterval(() => {
|
||||
this.seconds--;
|
||||
this.tellPassForm.tellPassCodeText = "已发送(" + this.seconds + "s)"
|
||||
}, 1000)
|
||||
}
|
||||
this.tellPassForm.key = data.key
|
||||
} else {
|
||||
this.$message({
|
||||
message: res.message,
|
||||
type: "warning"
|
||||
});
|
||||
this.isSend = false
|
||||
}
|
||||
}).catch(err => {
|
||||
this.getcaptcha();
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
} else {
|
||||
this.$message({
|
||||
message: "请勿重复点击",
|
||||
type: "warning"
|
||||
})
|
||||
}
|
||||
},
|
||||
//修改密码
|
||||
tellPassSave() {
|
||||
this.$refs.tellPassRef.validate(valid => {
|
||||
if (valid) {
|
||||
passWord({
|
||||
new_password: this.tellPassForm.pass,
|
||||
code: this.tellPassForm.tellPassDynacode,
|
||||
key: this.tellPassForm.key,
|
||||
}).then(res => {
|
||||
this.$message({
|
||||
message: "修改密码成功",
|
||||
type: "success"
|
||||
});
|
||||
this.type = "all";
|
||||
this.$store.dispatch("member/member_detail", {
|
||||
refresh: 1
|
||||
});
|
||||
this.tellPassForm.pass = "";
|
||||
this.tellPassForm.checkPass = "";
|
||||
this.tellPassForm.key = "";
|
||||
this.tellPassForm.tellPassDynacode = "";
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
filters: {
|
||||
mobile(mobile) {
|
||||
return mobile.substring(0, 4 - 1) + '****' + mobile.substring(6 + 1);
|
||||
}
|
||||
},
|
||||
}
|
||||
142
addon/pc/source/os/pages/member/withdrawal.vue
Executable file
142
addon/pc/source/os/pages/member/withdrawal.vue
Executable file
@@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>提现记录</span>
|
||||
</div>
|
||||
|
||||
<div v-loading="loading" class="withdrawal-list">
|
||||
<el-table v-if="dataList.length > 0" :data="dataList" border>
|
||||
<el-table-column prop="transfer_type_name" label="账户类型" width="150"></el-table-column>
|
||||
<el-table-column prop="apply_money" label="提现金额" width="150"></el-table-column>
|
||||
<el-table-column prop="apply_time" label="提现时间"></el-table-column>
|
||||
<el-table-column prop="status_name" label="提现状态" width="150"></el-table-column>
|
||||
<el-table-column label="操作" width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="mini" @click="handleEdit(scope.$index, scope.row)">详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div v-else-if="!loading && dataList.length == 0" class="ns-text-align">暂无提现记录</div>
|
||||
</div>
|
||||
<div class="pager">
|
||||
<el-pagination
|
||||
background
|
||||
:pager-count="5"
|
||||
:total="total"
|
||||
prev-text="上一页"
|
||||
next-text="下一页"
|
||||
:current-page.sync="currentPage"
|
||||
:page-size.sync="pageSize"
|
||||
@size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange"
|
||||
hide-on-single-page
|
||||
></el-pagination>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {withdrawList} from "@/api/member/account"
|
||||
|
||||
export default {
|
||||
name: 'withdrawal',
|
||||
layout: "member",
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
dataList: [],
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
loading: true,
|
||||
yes: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getDateList();
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
handlePageSizeChange(size) {
|
||||
this.pageSize = size
|
||||
this.refresh()
|
||||
},
|
||||
handleCurrentPageChange(page) {
|
||||
this.currentPage = page
|
||||
this.refresh()
|
||||
},
|
||||
refresh() {
|
||||
this.loading = true
|
||||
this.getDateList()
|
||||
},
|
||||
getDateList() {
|
||||
withdrawList({
|
||||
page_size: this.pageSize,
|
||||
page: this.currentPage
|
||||
}).then(res => {
|
||||
if (res.code == 0 && res.data) {
|
||||
this.dataList = res.data.list
|
||||
this.dataList.forEach(item => {
|
||||
item.apply_time = this.$util.timeStampTurnTime(item.apply_time)
|
||||
})
|
||||
this.total = res.data.count
|
||||
}
|
||||
|
||||
this.loading = false
|
||||
}).catch(err => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
handleEdit(index, row) {
|
||||
this.$router.push({path: '/member/withdrawal_detail', query: {id: row.id}})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.el-card.is-always-shadow,
|
||||
.el-card.is-hover-shadow:focus,
|
||||
.el-card.is-hover-shadow:hover {
|
||||
box-shadow: unset;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.ns-len-input {
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
.el-select {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.page-wrap {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
146
addon/pc/source/os/pages/member/withdrawal_detail.vue
Executable file
146
addon/pc/source/os/pages/member/withdrawal_detail.vue
Executable file
@@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/member/withdrawal' }">提现记录</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>提现详情</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
|
||||
<div v-loading="loading">
|
||||
<div class="money-wrap">
|
||||
<span>-{{ detail.apply_money }}</span>
|
||||
</div>
|
||||
<div class="line-wrap">
|
||||
<span class="label">当前状态</span>
|
||||
<span class="value">{{ detail.status_name }}</span>
|
||||
</div>
|
||||
<div class="line-wrap">
|
||||
<span class="label">交易号</span>
|
||||
<span class="value">{{ detail.withdraw_no }}</span>
|
||||
</div>
|
||||
<div class="line-wrap">
|
||||
<span class="label">手续费</span>
|
||||
<span class="value">¥{{ detail.service_money }}</span>
|
||||
</div>
|
||||
<div class="line-wrap">
|
||||
<span class="label">申请时间</span>
|
||||
<span class="value">{{ $util.timeStampTurnTime(detail.apply_time) }}</span>
|
||||
</div>
|
||||
<div class="line-wrap" v-if="detail.status">
|
||||
<span class="label">审核时间</span>
|
||||
<span class="value">{{ $util.timeStampTurnTime(detail.audit_time) }}</span>
|
||||
</div>
|
||||
<div class="line-wrap" v-if="detail.bank_name">
|
||||
<span class="label">银行名称</span>
|
||||
<span class="value">{{ detail.bank_name }}</span>
|
||||
</div>
|
||||
<div class="line-wrap">
|
||||
<span class="label">收款账号</span>
|
||||
<span class="value">{{ detail.account_number }}</span>
|
||||
</div>
|
||||
<div class="line-wrap" v-if="detail.status == -1 && detail.refuse_reason">
|
||||
<span class="label">拒绝理由</span>
|
||||
<span class="value">{{ detail.refuse_reason }}</span>
|
||||
</div>
|
||||
<div class="line-wrap" v-if="detail.status == 2">
|
||||
<span class="label">转账方式名称</span>
|
||||
<span class="value">{{ detail.transfer_type_name }}</span>
|
||||
</div>
|
||||
<div class="line-wrap" v-if="detail.status == 2">
|
||||
<span class="label">转账时间</span>
|
||||
<span class="value">{{ $util.timeStampTurnTime(detail.payment_time) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {withdrawDetail} from "@/api/member/account"
|
||||
|
||||
export default {
|
||||
name: 'withdrawal_detail',
|
||||
layout: "member",
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
loading: true,
|
||||
id: '',
|
||||
detail: {},
|
||||
yes: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getDetail();
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
//获得提现详情
|
||||
getDetail() {
|
||||
this.id = this.$route.query.id
|
||||
|
||||
withdrawDetail({
|
||||
id: this.id
|
||||
}).then(res => {
|
||||
if (res.data) {
|
||||
this.detail = res.data;
|
||||
}
|
||||
this.loading = false
|
||||
}).catch(err => {
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.el-card.is-always-shadow,
|
||||
.el-card.is-hover-shadow:focus,
|
||||
.el-card.is-hover-shadow:hover {
|
||||
box-shadow: unset;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.money-wrap {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.line-wrap {
|
||||
margin-top: 20px;
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
color: #898989;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
134
addon/pc/source/os/pages/order/batchrefund.vue
Executable file
134
addon/pc/source/os/pages/order/batchrefund.vue
Executable file
@@ -0,0 +1,134 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="title clearfix">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/member/order_list' }">我的订单</el-breadcrumb-item>
|
||||
<el-breadcrumb-item :to="{ path: '/member/order_detail?order_id=' + order_id }">订单详情</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>批量退款</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div slot="header" class="shopings clearfix">
|
||||
<span>选择退款商品</span>
|
||||
</div>
|
||||
<el-table ref="multipleTable" :data="orderData" tooltip-effect="dark" style="width: 100%" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55"></el-table-column>
|
||||
<el-table-column label="商品图片" width="100" prop="goods_image">
|
||||
<template slot-scope="scope">
|
||||
<img class="box-img" :src="$img(scope.row.sku_image, { size: 'mid' })" alt="" @error="scope.row.sku_image = defaultGoodsImage" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品名称" prop="goods_name"></el-table-column>
|
||||
<el-table-column label="价格" width="180" prop="price"></el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="flooter">
|
||||
<div class="flooter-left">
|
||||
<!-- <el-checkbox v-model="checked">全选</el-checkbox> -->
|
||||
</div>
|
||||
<div class="flooter-right">
|
||||
共计选中{{order_goods_ids.length}}件商品
|
||||
<el-button v-if="order_goods_ids.length" class="but" type="primary" @click="next">下一步</el-button>
|
||||
<el-button v-else class="but" type="info">请选择退款商品</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
apiOrderDetail
|
||||
} from "@/api/order/order"
|
||||
import {
|
||||
mapGetters
|
||||
} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: "account_edit",
|
||||
components: {},
|
||||
data() {
|
||||
return {
|
||||
yes: true,
|
||||
order_id: 0,
|
||||
orderData: [],
|
||||
checked: false,
|
||||
order_goods_ids: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.order_id = this.$route.query.order_id
|
||||
this.getOrderInfo()
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
layout: 'member',
|
||||
methods: {
|
||||
/**
|
||||
* 获取商品数据
|
||||
*/
|
||||
getOrderInfo() {
|
||||
apiOrderDetail({
|
||||
order_id: this.order_id
|
||||
}).then((res) => {
|
||||
if (res.code >= 0) {
|
||||
this.orderData = [];
|
||||
res.data.order_goods.forEach((item) => {
|
||||
if (item.refund_status == 0) {
|
||||
this.orderData.push(item);
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
handleSelectionChange(e) {
|
||||
this.order_goods_ids = e.map((item, index) => {
|
||||
return item.order_goods_id;
|
||||
});
|
||||
},
|
||||
next() {
|
||||
this.$router.push({
|
||||
path: '/order/orderbatch_refund',
|
||||
query: {
|
||||
order_goods_id: this.order_goods_ids.join(','),
|
||||
order_id: this.order_id
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.box-img {
|
||||
width: 70px;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.flooter {
|
||||
padding: 18px 20px;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
align-content: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.but {
|
||||
padding: 10px 20px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
padding: 0 0 18px;
|
||||
border-bottom: 1px solid #EBEEF5;
|
||||
}
|
||||
|
||||
.shopings {
|
||||
padding: 18px 0 0;
|
||||
}
|
||||
</style>
|
||||
524
addon/pc/source/os/pages/order/complain.vue
Executable file
524
addon/pc/source/os/pages/order/complain.vue
Executable file
@@ -0,0 +1,524 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<div v-loading="loading">
|
||||
<!--申请退款 start-->
|
||||
<div v-if="!complainData.complain_info || action == 'apply'">
|
||||
<el-card class="box-card order-list">
|
||||
<div slot="header" class="clearfix">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/member/activist' }">退款/售后</el-breadcrumb-item>
|
||||
<el-breadcrumb-item :to="{ path: '/order/refund_detail?order_goods_id=' + orderGoodsId }">退款详情
|
||||
</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>平台维权</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
|
||||
<!--商品信息-->
|
||||
<div>
|
||||
<div class="goods-list">
|
||||
<table>
|
||||
<tr>
|
||||
<td width="62.5%">商品</td>
|
||||
<td width="12.5%">数量</td>
|
||||
<td width="12.5%">金额</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="goods-list">
|
||||
<table>
|
||||
<tr>
|
||||
<td width="62.5%">
|
||||
<div class="goods-info">
|
||||
<div class="goods-info-left">
|
||||
<router-link :to="{ path: '/sku/' + complainData.order_goods_info.sku_id }" target="_blank">
|
||||
<img class="goods-img" :src="$img(complainData.order_goods_info.sku_image, { size: 'mid' })" @error="complainData.order_goods_info.sku_image = defaultGoodsImage" />
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="goods-info-right">
|
||||
<router-link :to="{ path: '/sku/' + complainData.order_goods_info.sku_id }" target="_blank">
|
||||
<div class="goods-name">{{ complainData.order_goods_info.sku_name }}</div>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td width="12.5%" class="goods-num">{{ complainData.order_goods_info.num }}</td>
|
||||
<td width="12.5%" class="goods-money">¥{{ complainData.order_goods_info.goods_money }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!--退款填写-->
|
||||
<div class="item-block">
|
||||
<div class="block-text"></div>
|
||||
|
||||
<el-form ref="form" label-width="80px" class="refund-form">
|
||||
<el-form-item label="退款金额">
|
||||
<el-input disabled="" :value="complainData.refund_money"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="退款原因">
|
||||
<el-select placeholder="请选择" v-model="complainReason">
|
||||
<el-option v-for="(item, itemIndex) in complainData.refund_reason_type" :key="itemIndex" :label="item" :value="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="退款说明">
|
||||
<el-input maxlength="140" show-word-limit resize="none" rows="5" placeholder="请输入退款说明(选填)" type="textarea" v-model="complainRemark"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="item-block">
|
||||
<div class="order-submit">
|
||||
<el-button type="primary" class="el-button--primary" @click="submit">提交</el-button>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!--申请退款 end-->
|
||||
|
||||
<div v-else>
|
||||
<div class="item-block">
|
||||
<div class="block-text">{{ detail.complain_status_name }}</div>
|
||||
</div>
|
||||
|
||||
<!--协商记录-->
|
||||
<div class="item-block">
|
||||
<div class="action-box">
|
||||
<span class="media-left">协商记录</span>
|
||||
<div class="media-right">
|
||||
<div class="el-button--text" @click="actionOpen ? (actionOpen = false) : (actionOpen = true)">
|
||||
协商记录
|
||||
<i :class="actionOpen ? 'rotate' : ''" class="el-icon-arrow-down"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<div v-if="actionOpen">
|
||||
<el-timeline>
|
||||
<el-timeline-item :class="{ buyer: logItem.action_way == 1, seller: logItem.action_way == 2, platform: logItem.action_way == 3 }" v-for="(logItem, logIndex) in detail.refund_log_list" :key="logIndex" :timestamp="$util.timeStampTurnTime(logItem.action_time)" placement="top">
|
||||
<div>
|
||||
<h4 v-if="logItem.action_way == 1">买家</h4>
|
||||
<h4 v-else-if="logItem.action_way == 2">卖家</h4>
|
||||
<h4 v-else-if="logItem.action_way == 3">平台</h4>
|
||||
<p>{{ logItem.action }}</p>
|
||||
</div>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--退款详情-->
|
||||
<div class="item-block">
|
||||
<div class="goods-list">
|
||||
<table>
|
||||
<tr>
|
||||
<td width="62.5%">商品</td>
|
||||
<td width="12.5%">数量</td>
|
||||
<td width="12.5%">退款金额</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item-block">
|
||||
<div class="goods-list">
|
||||
<table>
|
||||
<tr>
|
||||
<td width="62.5%">
|
||||
<div class="goods-info">
|
||||
<div class="goods-info-left">
|
||||
<router-link :to="{ path: '/sku/' + detail.sku_id }" target="_blank">
|
||||
<img class="goods-img" :src="$img(detail.sku_image, { size: 'mid' })" @error="detail.sku_image = defaultGoodsImage" />
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="goods-info-right">
|
||||
<router-link :to="{ path: '/sku/' + detail.sku_id }" target="_blank">
|
||||
<div class="goods-name">{{ detail.sku_name }}</div>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td width="12.5%" class="goods-num">{{ detail.num }}</td>
|
||||
<td width="12.5%" class="goods-money">¥{{ detail.complain_apply_money }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item-block">
|
||||
<div class="order-statistics">
|
||||
<table>
|
||||
<tr>
|
||||
<td align="right">退款原因:</td>
|
||||
<td align="left">{{ detail.complainReason }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">退款金额:</td>
|
||||
<td align="left">¥{{ detail.complain_apply_money }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">退款编号:</td>
|
||||
<td align="left">{{ detail.complain_no }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">申请时间:</td>
|
||||
<td align="left">{{ $util.timeStampTurnTime(detail.complain_apply_time) }}</td>
|
||||
</tr>
|
||||
<tr v-if="detail.complain_time">
|
||||
<td align="right">退款时间:</td>
|
||||
<td align="left">{{ $util.timeStampTurnTime(detail.complain_time) }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<div class="item-block" v-if="detail.complain_action.length">
|
||||
<div class="order-submit" v-for="(actionItem, actionIndex) in detail.complain_action" :key="actionIndex">
|
||||
<el-button type="primary" class="el-button--primary" @click="refundAction(actionItem.event)">{{ actionItem.title }}</el-button>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from 'vuex';
|
||||
import {complainData, complain, complainCancel} from '@/api/order/refund';
|
||||
|
||||
export default {
|
||||
name: 'refund',
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
orderGoodsId: 0,
|
||||
complainData: {
|
||||
order_goods_info: {
|
||||
sku_image: '',
|
||||
sku_name: ''
|
||||
}
|
||||
},
|
||||
detail: {
|
||||
sku_image: ''
|
||||
},
|
||||
complainReason: '',
|
||||
complainRemark: '',
|
||||
action: '',
|
||||
actionOpen: false,
|
||||
loading: false,
|
||||
yes: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.loading = true;
|
||||
if (this.$route.query.order_goods_id) this.orderGoodsId = this.$route.query.order_goods_id;
|
||||
this.getComplainData();
|
||||
},
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
layout: 'member',
|
||||
methods: {
|
||||
/**
|
||||
* 选择退款方式
|
||||
* @param {Object} type
|
||||
*/
|
||||
selectRefundType(type) {
|
||||
this.refund_type = type;
|
||||
},
|
||||
getComplainData() {
|
||||
this.loading = true;
|
||||
complainData({order_goods_id: this.orderGoodsId}).then(res => {
|
||||
const {code, message, data} = res;
|
||||
if (code >= 0) {
|
||||
this.complainData = res.data;
|
||||
this.detail = this.complainData.complain_info;
|
||||
this.loading = false;
|
||||
} else {
|
||||
this.$message({
|
||||
message: '未获取到该订单项退款信息',
|
||||
type: 'warning',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({path: '/member/order_list'});
|
||||
}
|
||||
});
|
||||
}
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error({
|
||||
message: err.message,
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({path: '/member/order_list'});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
submit() {
|
||||
if (this.verify()) {
|
||||
if (this.isSub) return;
|
||||
this.isSub = true;
|
||||
|
||||
let submit_data = {
|
||||
order_goods_id: this.orderGoodsId,
|
||||
complain_reason: this.complainReason,
|
||||
complain_remark: this.complainRemark
|
||||
};
|
||||
|
||||
complain(submit_data).then(res => {
|
||||
const {code, message, data} = res;
|
||||
if (code >= 0) {
|
||||
this.$message({
|
||||
message: message,
|
||||
type: 'success'
|
||||
});
|
||||
|
||||
this.getComplainData();
|
||||
this.$forceUpdate();
|
||||
this.action = '';
|
||||
} else {
|
||||
this.isSub = false;
|
||||
this.$message({message: message, type: 'warning'});
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error({
|
||||
message: err.message,
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({path: '/member/order_list'});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
verify() {
|
||||
if (this.complainReason == '') {
|
||||
this.$message({message: '请选择退款原因', type: 'warning'});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
refundAction(event) {
|
||||
switch (event) {
|
||||
case 'complainCancel':
|
||||
this.cancelRefund(this.detail.order_goods_id);
|
||||
break;
|
||||
case 'complainApply':
|
||||
this.action = 'apply';
|
||||
break;
|
||||
}
|
||||
},
|
||||
cancelRefund(order_goods_id) {
|
||||
this.$confirm('撤销之后本次申请将会关闭,如后续仍有问题可再次发起申请', '提示', {
|
||||
confirmButtonText: '确认撤销',
|
||||
cancelButtonText: '暂不撤销',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
if (this.isSub) return;
|
||||
this.isSub = true;
|
||||
|
||||
complainCancel({order_goods_id: order_goods_id}).then(res => {
|
||||
const {code, message, data} = res;
|
||||
if (code >= 0) {
|
||||
this.$message({
|
||||
message: '撤销成功',
|
||||
type: 'success',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({path: '/member/order_list'});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.$message({message: message, type: 'warning'});
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error({
|
||||
message: err.message,
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({path: '/member/order_list'});
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.el-card.is-always-shadow,
|
||||
.el-card.is-hover-shadow:focus,
|
||||
.el-card.is-hover-shadow:hover {
|
||||
box-shadow: unset;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.item-block {
|
||||
padding: 0 15px 1px;
|
||||
margin: 10px 0;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
background: #ffffff;
|
||||
|
||||
.block-text {
|
||||
border-color: #eeeeee;
|
||||
color: $ns-text-color-black;
|
||||
padding: 7px 0;
|
||||
border-bottom: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.refund-form {
|
||||
width: 350px;
|
||||
|
||||
.el-select {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.order-submit {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.goods-list {
|
||||
padding: 15px 0;
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.goods-info-left {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
float: left;
|
||||
|
||||
.goods-img {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-info-right {
|
||||
float: left;
|
||||
height: 60px;
|
||||
margin-left: 10px;
|
||||
color: $base-color;
|
||||
width: 80%;
|
||||
|
||||
.goods-name {
|
||||
line-height: 20px;
|
||||
padding-top: 10px;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.goods-spec {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pay-type-list {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.pay-type-item {
|
||||
display: inline-block;
|
||||
border: 2px solid #eeeeee;
|
||||
padding: 5px 20px;
|
||||
margin-right: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.pay-type-item.active {
|
||||
border-color: $base-color;
|
||||
}
|
||||
|
||||
.status-wrap {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.media-left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.media-right {
|
||||
float: right;
|
||||
|
||||
i.rotate {
|
||||
transform: rotate(180deg);
|
||||
transition: 0.3s;
|
||||
}
|
||||
}
|
||||
|
||||
.action-box {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.action-way {
|
||||
float: left;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.head .time {
|
||||
float: right;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.record-item {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.order-statistics {
|
||||
float: left;
|
||||
padding: 10px;
|
||||
// color: #999;
|
||||
}
|
||||
|
||||
.el-textarea .el-input__count {
|
||||
line-height: 20px;
|
||||
}
|
||||
</style>
|
||||
434
addon/pc/source/os/pages/order/evaluate.vue
Executable file
434
addon/pc/source/os/pages/order/evaluate.vue
Executable file
@@ -0,0 +1,434 @@
|
||||
<template>
|
||||
<el-form class="ns-evalute" v-loading="loading">
|
||||
<div class="ns-eva-li" v-for="(item, index) in goodsList" :key="index">
|
||||
<!-- 商品信息 -->
|
||||
<div class="ns-eva-good">
|
||||
<el-image fit="scale-down" :src="$img(item.sku_image, { size: 'mid' })" @error="imageError(index)" @click="toGoodsDetail(item.sku_id)"/>
|
||||
<p class="ns-eva-good-name" :title="item.sku_name" @click="toGoodsDetail(item.sku_id)">{{ item.sku_name }}</p>
|
||||
<p>¥{{ item.price }}</p>
|
||||
</div>
|
||||
|
||||
<!-- 评价表单 -->
|
||||
<div class="ns-eva-form">
|
||||
<div class="block" v-if="!isEvaluate">
|
||||
<span class="demonstration">描述相符:</span>
|
||||
<el-rate v-model="goodsEvalList[index].scores" @change="setStar(index)"></el-rate>
|
||||
<div class="level">
|
||||
<i class="iconfont" :class="
|
||||
goodsEvalList[index].explain_type == '1'
|
||||
? 'iconhaoping1 ns-text-color'
|
||||
: goodsEvalList[index].explain_type == '2'
|
||||
? 'iconzhongchaping ns-text-color'
|
||||
: goodsEvalList[index].explain_type == '3'
|
||||
? 'iconzhongchaping'
|
||||
: ''
|
||||
"></i>
|
||||
<span>
|
||||
{{ goodsEvalList[index].explain_type == '1' ? '好评' : goodsEvalList[index].explain_type == '2' ? '中评' : goodsEvalList[index].explain_type == '3' ? '差评' : ''}}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ns-textarea">
|
||||
<el-input v-if="!isEvaluate" type="textarea" :rows="5" placeholder="请在此处输入您的评价" v-model="goodsEvalList[index].content" maxlength="200" show-word-limit/>
|
||||
<el-input v-else type="textarea" :rows="5" placeholder="请在此处输入您的追评" v-model="goodsEvalList[index].again_content" maxlength="200" show-word-limit/>
|
||||
</div>
|
||||
|
||||
<div class="upload-wrap">
|
||||
<el-upload ref="upload" :class="{ ishide: hide[index] }" :action="uploadActionUrl" :data="uploadData"
|
||||
list-type="picture-card" :on-success="
|
||||
(file, fileList) => {
|
||||
return handleSuccess(file, fileList, index);
|
||||
}
|
||||
" :on-preview="handlePictureCardPreview" :on-remove="
|
||||
(file, fileList) => {
|
||||
return handleRemove(file, fileList, index);
|
||||
}
|
||||
" :on-exceed="handleExceed" multiple drag :limit="6">
|
||||
<i class="el-icon-plus"></i>
|
||||
<!-- <i class="el-icon-upload"></i> -->
|
||||
<!-- <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div> -->
|
||||
</el-upload>
|
||||
<el-dialog :visible.sync="dialogVisible"><img width="100%" :src="dialogImageUrl" alt="" /></el-dialog>
|
||||
<div class="tips">共6张,还能上传{{ imgList[index].length ? 6 - imgList[index].length : 6 }}张</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="save-btn-wrap">
|
||||
<el-button @click="save" type="primary">提交</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
mapGetters
|
||||
} from 'vuex';
|
||||
import {
|
||||
orderInfo,
|
||||
save,
|
||||
uploadImg
|
||||
} from '@/api/order/order';
|
||||
import Config from '@/plugins/config';
|
||||
|
||||
export default {
|
||||
name: 'evaluate',
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
loading: true,
|
||||
value1: 5,
|
||||
memberName: '',
|
||||
memberHeadimg: '',
|
||||
orderId: null,
|
||||
orderNo: '',
|
||||
isAnonymous: 0, //是否匿名发布 1.匿名,0.公开
|
||||
goodsList: [], //订单列表
|
||||
goodsEvalList: [], //评价列表
|
||||
imgList: [],
|
||||
isEvaluate: 0, //判断是否为追评
|
||||
flag: false, //防止重复点击
|
||||
siteName: '', // 店铺名称
|
||||
shop_deliverycredit: 5, // 配送服务分值
|
||||
shop_desccredit: 5, // 描述相符分值
|
||||
shop_servicecredit: 5, // 服务态度分值
|
||||
uploadActionUrl: Config.baseUrl + '/api/upload/evaluateimg',
|
||||
uploadData: {
|
||||
app_type: "pc",
|
||||
app_type_name: "PC"
|
||||
},
|
||||
dialogImageUrl: '',
|
||||
dialogVisible: false,
|
||||
hide: []
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.orderId = this.$route.query.order_id;
|
||||
this.getUserInfo();
|
||||
if (this.orderId) {
|
||||
this.getOrderInfo();
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
layout: 'member',
|
||||
methods: {
|
||||
handleSuccess(file, fileList, index) {
|
||||
let arr = this.imgList[index];
|
||||
arr = arr.concat(file.data.pic_path);
|
||||
this.imgList[index] = [];
|
||||
this.$set(this.imgList, index, arr);
|
||||
if (this.isEvaluate) {
|
||||
this.goodsEvalList[index].again_images = this.imgList[index].toString();
|
||||
} else {
|
||||
this.goodsEvalList[index].images = this.imgList[index].toString();
|
||||
}
|
||||
|
||||
if (this.imgList[index].length >= 6) {
|
||||
this.hide[index] = true;
|
||||
}
|
||||
},
|
||||
handleRemove(file, fileList, index) {
|
||||
let i = this.$util.inArray(file.response.data.pic_path, this.imgList[index]);
|
||||
this.imgList[index].splice(i, 1);
|
||||
|
||||
if (this.isEvaluate) {
|
||||
this.goodsEvalList[index].again_images = this.imgList[index].toString();
|
||||
} else {
|
||||
this.goodsEvalList[index].images = this.imgList[index].toString();
|
||||
}
|
||||
|
||||
if (this.imgList[index].length < 6) {
|
||||
this.hide[index] = false;
|
||||
}
|
||||
},
|
||||
handleExceed(file, fileList) {
|
||||
// 图片数量大于6
|
||||
this.$message.warning('上传图片最大数量为6张');
|
||||
},
|
||||
handlePictureCardPreview(file) {
|
||||
// 点开大图
|
||||
this.dialogImageUrl = file.url;
|
||||
this.dialogVisible = true;
|
||||
},
|
||||
//获取用户信息
|
||||
getUserInfo() {
|
||||
this.$store
|
||||
.dispatch('member/member_detail', {
|
||||
refresh: 1
|
||||
}).then(res => {
|
||||
this.memberName = res.data.nickname;
|
||||
this.memberHeadimg = res.data.headimg;
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
},
|
||||
//获取订单信息
|
||||
getOrderInfo() {
|
||||
//获取订单信息
|
||||
orderInfo({
|
||||
order_id: this.orderId
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.isEvaluate = res.data.evaluate_status;
|
||||
this.orderNo = res.data.list[0].order_no;
|
||||
this.goodsList = res.data.list;
|
||||
this.siteName = res.data.list[0].site_name;
|
||||
|
||||
if (this.isEvaluate) {
|
||||
for (let i = 0; i < res.data.list.length; i++) {
|
||||
let array = [];
|
||||
this.imgList.push(array);
|
||||
this.hide.push(false);
|
||||
this.goodsEvalList.push({
|
||||
order_goods_id: res.data.list[i].order_goods_id,
|
||||
goods_id: res.data.list[i].goods_id,
|
||||
sku_id: res.data.list[i].sku_id,
|
||||
again_content: '',
|
||||
again_images: '',
|
||||
site_id: res.data.list[i].site_id
|
||||
});
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < res.data.list.length; i++) {
|
||||
let array = [];
|
||||
this.imgList.push(array);
|
||||
this.goodsEvalList.push({
|
||||
content: '', // 评价内容
|
||||
images: '', //图片数组
|
||||
scores: 5, // 评分
|
||||
explain_type: 1, // 评价类型
|
||||
order_goods_id: res.data.list[i].order_goods_id,
|
||||
goods_id: res.data.list[i].goods_id,
|
||||
sku_id: res.data.list[i].sku_id,
|
||||
sku_name: res.data.list[i].sku_name,
|
||||
sku_price: res.data.list[i].price,
|
||||
sku_image: res.data.list[i].sku_image,
|
||||
site_id: res.data.list[i].site_id
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message);
|
||||
this.$router.push('/member/order_list');
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
//监听评分变化
|
||||
setStar(index) {
|
||||
if (this.goodsEvalList[index].scores >= 4) {
|
||||
this.goodsEvalList[index].explain_type = 1;
|
||||
} else if (1 < this.goodsEvalList[index].scores && this.goodsEvalList[index].scores < 4) {
|
||||
this.goodsEvalList[index].explain_type = 2;
|
||||
} else {
|
||||
this.goodsEvalList[index].explain_type = 3;
|
||||
}
|
||||
},
|
||||
imageError(index) {
|
||||
this.goodsList[index].sku_image = this.defaultGoodsImage;
|
||||
},
|
||||
/**
|
||||
* 提交
|
||||
*/
|
||||
save() {
|
||||
for (let i = 0; i < this.goodsEvalList.length; i++) {
|
||||
if (this.isEvaluate) {
|
||||
if (!this.goodsEvalList[i].again_content.trim().length) {
|
||||
this.$message({
|
||||
message: '商品的评价不能为空哦',
|
||||
type: 'warning'
|
||||
});
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!this.goodsEvalList[i].content.trim().length) {
|
||||
this.$message({
|
||||
message: '商品的评价不能为空哦',
|
||||
type: 'warning'
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let goodsEvaluate = JSON.stringify(this.goodsEvalList);
|
||||
let data = {
|
||||
order_id: this.orderId,
|
||||
goods_evaluate: goodsEvaluate,
|
||||
isEvaluate: this.isEvaluate
|
||||
};
|
||||
if (!this.isEvaluate) {
|
||||
data.order_no = this.orderNo;
|
||||
data.member_name = this.memberName;
|
||||
data.member_headimg = this.memberHeadimg;
|
||||
data.is_anonymous = this.isAnonymous;
|
||||
}
|
||||
|
||||
if (this.flag) return;
|
||||
this.flag = true;
|
||||
|
||||
save(data).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message({
|
||||
message: '评价成功',
|
||||
type: 'success',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({
|
||||
path: '/member/order_list'
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.$message({
|
||||
message: res.message,
|
||||
type: 'warning'
|
||||
});
|
||||
this.flag = false;
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message);
|
||||
this.flag = false;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 跳转到商品详情
|
||||
*/
|
||||
toGoodsDetail(id) {
|
||||
this.$util.pushToTab('sku-' + id);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.ns-evalute {
|
||||
margin: 20px 0;
|
||||
background: #ffffff;
|
||||
padding: 30px;
|
||||
border-radius: 5px;
|
||||
|
||||
.ns-eva-li {
|
||||
display: flex;
|
||||
padding: 20px 0;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
|
||||
.ns-eva-good {
|
||||
width: 30%;
|
||||
text-align: center;
|
||||
|
||||
.el-image {
|
||||
width: 125px;
|
||||
height: 125px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ns-eva-good-name {
|
||||
width: 250px;
|
||||
margin: 0 auto;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ns-eva-form {
|
||||
width: 70%;
|
||||
|
||||
.ns-textarea {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.upload-wrap {
|
||||
.tips {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.level {
|
||||
display: inline-block;
|
||||
margin-left: 50px;
|
||||
|
||||
i {
|
||||
margin-right: 5px;
|
||||
vertical-align: top;
|
||||
}
|
||||
}
|
||||
|
||||
.el-textarea {
|
||||
margin: 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.el-rate {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
||||
.save-btn-wrap {
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.el-dialog {
|
||||
img {
|
||||
width: auto;
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="scss">
|
||||
.ns-evalute {
|
||||
|
||||
.el-upload--picture-card {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.el-upload--picture-card,
|
||||
.el-upload-list--picture-card .el-upload-list__item {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
line-height: 80px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.el-upload-list--picture-card .el-upload-list__item-thumbnail {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.el-upload-list__item.is-success .el-upload-list__item-status-label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ishide .el-upload--picture-card {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.upload-wrap .el-upload-dragger {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
|
||||
}
|
||||
|
||||
.el-dialog {
|
||||
.el-dialog__body {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
184
addon/pc/source/os/pages/order/logistics.vue
Executable file
184
addon/pc/source/os/pages/order/logistics.vue
Executable file
@@ -0,0 +1,184 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card logistics">
|
||||
<div slot="header" class="clearfix">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/member/order_list' }">订单列表</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>物流详情</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div v-loading="loading">
|
||||
<el-tabs v-model="activeParcel">
|
||||
<el-tab-pane v-for="(packageItem, packageIndex) in packageList" :key="packageIndex" :label="packageItem.package_name" :name="'parcel_' + packageIndex">
|
||||
<div class="trace" v-if="packageItem.trace.success && packageItem.trace.list.length > 0">
|
||||
<el-timeline>
|
||||
<el-timeline-item v-for="(traceItem, traceIndex) in packageItem.trace.list" :timestamp="traceItem.datetime" placement="top" :type="traceIndex == 0 ? 'primary' : ''" :key="traceIndex">
|
||||
<p>{{ traceItem.remark }}</p>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</div>
|
||||
<div class="trace" v-else>
|
||||
<p class="empty-wrap">{{ packageItem.trace.reason }}</p>
|
||||
</div>
|
||||
|
||||
<ul class="info-wrap">
|
||||
<li>
|
||||
<label>运单号码:</label>
|
||||
<span>{{ packageItem.delivery_no }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<label>物流公司:</label>
|
||||
<span>{{ packageItem.express_company_name }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="goods-wrap">
|
||||
<li v-for="(goodsItem, goodsIndex) in packageItem.goods_list" :key="goodsIndex" @click="$util.pushToTab('/sku/' + goodsItem.sku_id)">
|
||||
<div class="img-wrap">
|
||||
<img :src="$img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(packageIndex, goodsIndex)" />
|
||||
</div>
|
||||
<p class="sku-name">{{ goodsItem.sku_name }} x {{ goodsItem.num }}</p>
|
||||
</li>
|
||||
</ul>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {apiOrderPackageInfo} from '@/api/order/order';
|
||||
import {mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'logistics',
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
orderId: 0,
|
||||
loading: true,
|
||||
activeParcel: 'parcel_0',
|
||||
packageList: [],
|
||||
yes: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.orderId = this.$route.query.order_id;
|
||||
if (!this.orderId) this.$router.push({path: '/member/order_list'});
|
||||
this.getOrderPackageInfo();
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
layout: 'member',
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
getOrderPackageInfo() {
|
||||
apiOrderPackageInfo({
|
||||
order_id: this.orderId
|
||||
}).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.packageList = res.data;
|
||||
this.packageList.forEach(item => {
|
||||
if (item.trace.list) {
|
||||
item.trace.list = item.trace.list.reverse();
|
||||
}
|
||||
});
|
||||
this.loading = false;
|
||||
} else {
|
||||
this.$message({
|
||||
message: '未获取到订单包裹信息!',
|
||||
type: 'warning',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({path: '/member/order_list'});
|
||||
}
|
||||
});
|
||||
}
|
||||
}).catch(res => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
imageError(packageIndex, goodsIndex) {
|
||||
this.packageList[packageIndex].goods_list[goodsIndex].sku_image = this.defaultGoodsImage;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.logistics {
|
||||
.trace {
|
||||
.empty-wrap {
|
||||
padding: 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.info-wrap {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
li {
|
||||
flex: 0 0 33.3333%;
|
||||
margin-bottom: 10px;
|
||||
|
||||
span {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.goods-wrap {
|
||||
overflow: hidden;
|
||||
margin: 10px 0;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
width: 130px;
|
||||
margin-right: 7px;
|
||||
cursor: pointer;
|
||||
|
||||
&:nth-child(n + 7) {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.img-wrap {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.sku-name {
|
||||
margin-top: 5px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
font-size: $ns-font-size-sm;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
377
addon/pc/source/os/pages/order/orderbatch_refund.vue
Executable file
377
addon/pc/source/os/pages/order/orderbatch_refund.vue
Executable file
@@ -0,0 +1,377 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<div v-loading="loading">
|
||||
<el-card class="box-card order-list">
|
||||
<div slot="header" class="clearfix">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/member/order_list' }">我的订单</el-breadcrumb-item>
|
||||
<el-breadcrumb-item :to="{ path: '/member/order_detail?order_id=' + orderId }">订单详情</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>退款</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
|
||||
<!--商品信息-->
|
||||
<div class="goods-list">
|
||||
<table>
|
||||
<tr>
|
||||
<td width="62.5%">商品</td>
|
||||
<td width="12.5%">数量</td>
|
||||
<td width="12.5%">金额</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="goods-list">
|
||||
<table>
|
||||
<tr v-for="(item,index) in refundData.order_goods_info" :key="index">
|
||||
<td width="62.5%">
|
||||
<div class="goods-info">
|
||||
<div class="goods-info-left" v-if="item.sku_image">
|
||||
<router-link :to="{ path: '/sku/' + item.sku_id }" target="_blank">
|
||||
<img class="goods-img" :src="$img(item.sku_image, { size: 'mid' })" @error="item.sku_image = defaultGoodsImage" />
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="goods-info-right">
|
||||
<router-link :to="{ path: '/sku/' + item.sku_id }" target="_blank">
|
||||
<div class="goods-name">{{ item.sku_name }}</div>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td width="12.5%" class="goods-num">{{ item.num }}</td>
|
||||
<td width="12.5%" class="goods-money">¥{{ item.goods_money }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!--退款类型 -->
|
||||
<div class="item-block">
|
||||
<div class="block-text">退款类型</div>
|
||||
|
||||
<div class="pay-type-list">
|
||||
<div class="pay-type-item" :class="refundType == 1 ? 'active' : ''" @click="selectRefundType(1)">退款无需退货</div>
|
||||
<div v-if="refundData.refund_type.length == 2" class="pay-type-item" :class="refundType == 2 ? 'active' : ''" @click="selectRefundType(2)">退货退款</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--退款填写-->
|
||||
<div class="item-block">
|
||||
<div class="block-text"></div>
|
||||
|
||||
<el-form ref="form" label-width="80px" class="refund-form">
|
||||
<el-form-item label="退款金额">
|
||||
<el-input disabled="" :value="refundData.refund_money"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="退款原因">
|
||||
<el-select placeholder="请选择" v-model="refundReason">
|
||||
<el-option v-for="(item, itemIndex) in refundData.refund_reason_type" :key="itemIndex" :label="item" :value="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="退款说明">
|
||||
<el-input maxlength="140" show-word-limit resize="none" rows="5" placeholder="请输入退款说明(选填)" type="textarea" v-model="refundRemark"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="item-block">
|
||||
<div class="order-submit">
|
||||
<el-button type="primary" class="el-button--primary" @click="submit">提交</el-button>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {refundDataBatch, refund} from '@/api/order/refund';
|
||||
import {mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'refund',
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
orderGoodsId: '',
|
||||
orderId: '',
|
||||
refundType: 1,
|
||||
refundReason: '',
|
||||
refundRemark: '',
|
||||
isIphoneX: false,
|
||||
refundData: {
|
||||
refund_type: [],
|
||||
order_goods_info: {
|
||||
sku_image: ''
|
||||
}
|
||||
},
|
||||
isSub: false,
|
||||
show_type: 0, //退款状态 1-待退款 2-已退款
|
||||
detail: {
|
||||
refund_action: []
|
||||
},
|
||||
loading: true,
|
||||
yes: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
if (this.$route.query.order_goods_id) this.orderGoodsId = this.$route.query.order_goods_id;
|
||||
if (this.$route.query.order_id) this.orderId = this.$route.query.order_id;
|
||||
this.getRefundData();
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
layout: 'member',
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 选择退款方式
|
||||
* @param {Object} type
|
||||
*/
|
||||
selectRefundType(type) {
|
||||
this.refundType = type;
|
||||
},
|
||||
getRefundData() {
|
||||
refundDataBatch({order_goods_ids: this.orderGoodsId}).then(res => {
|
||||
const {code, message, data} = res;
|
||||
if (code >= 0) {
|
||||
this.refundData = data;
|
||||
} else {
|
||||
this.$message({
|
||||
message: '未获取到该订单项退款信息!',
|
||||
type: 'warning',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({path: '/member/activist'});
|
||||
}
|
||||
});
|
||||
}
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error({
|
||||
message: err.message,
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({path: '/member/activist'});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
submit() {
|
||||
if (this.verify()) {
|
||||
if (this.isSub) return;
|
||||
this.isSub = true;
|
||||
|
||||
let submit_data = {
|
||||
order_goods_ids: this.orderGoodsId,
|
||||
refund_type: this.refundType,
|
||||
refund_reason: this.refundReason,
|
||||
refund_remark: this.refundRemark
|
||||
};
|
||||
|
||||
refund(submit_data).then(res => {
|
||||
const {code, message, data} = res;
|
||||
if (code >= 0) {
|
||||
this.$message({
|
||||
message: '申请成功!',
|
||||
type: 'success',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({path: '/member/activist'});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.isSub = false;
|
||||
this.$message({message: message, type: 'warning'});
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error({
|
||||
message: err.message,
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({path: '/member/activist'});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
verify() {
|
||||
if (this.refundReason == '') {
|
||||
this.$message({message: '请选择退款原因', type: 'warning'});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.el-card.is-always-shadow,
|
||||
.el-card.is-hover-shadow:focus,
|
||||
.el-card.is-hover-shadow:hover {
|
||||
box-shadow: unset;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.item-block {
|
||||
padding: 0 15px 1px;
|
||||
margin: 10px 0;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
background: #ffffff;
|
||||
|
||||
.block-text {
|
||||
border-color: #eeeeee;
|
||||
color: $ns-text-color-black;
|
||||
padding: 7px 0;
|
||||
border-bottom: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.refund-form {
|
||||
width: 350px;
|
||||
|
||||
.el-select {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.order-submit {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.goods-list {
|
||||
padding: 15px 0;
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.goods-info-left {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
float: left;
|
||||
|
||||
.goods-img {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-info-right {
|
||||
float: left;
|
||||
height: 60px;
|
||||
margin-left: 10px;
|
||||
color: $base-color;
|
||||
width: 80%;
|
||||
|
||||
.goods-name {
|
||||
line-height: 20px;
|
||||
padding-top: 10px;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.goods-spec {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pay-type-list {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.pay-type-item {
|
||||
display: inline-block;
|
||||
border: 2px solid #eeeeee;
|
||||
padding: 5px 20px;
|
||||
margin-right: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.pay-type-item.active {
|
||||
border-color: $base-color;
|
||||
}
|
||||
|
||||
.status-wrap {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.media-left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.media-right {
|
||||
float: right;
|
||||
|
||||
i.rotate {
|
||||
transform: rotate(180deg);
|
||||
transition: 0.3s;
|
||||
}
|
||||
}
|
||||
|
||||
.action-box {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.action-way {
|
||||
float: left;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.head .time {
|
||||
float: right;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.record-item {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.order-statistics {
|
||||
float: left;
|
||||
padding: 10px;
|
||||
// color: #999;
|
||||
}
|
||||
|
||||
.el-textarea .el-input__count {
|
||||
line-height: 20px;
|
||||
}
|
||||
</style>
|
||||
417
addon/pc/source/os/pages/order/payment.vue
Executable file
417
addon/pc/source/os/pages/order/payment.vue
Executable file
@@ -0,0 +1,417 @@
|
||||
<template>
|
||||
<div class="payment-wrap" v-loading="fullscreenLoading">
|
||||
|
||||
<!--购买虚拟类商品需填写您的手机号-->
|
||||
<div class="item-block" v-if="orderPaymentData.is_virtual == 1">
|
||||
<div class="block-text">购买虚拟类商品需填写您的手机号,以方便商家与您联系</div>
|
||||
|
||||
<el-form ref="form" size="mini" class="mobile-wrap" label-width="80px">
|
||||
<el-form-item label="手机号码">
|
||||
<el-input placeholder="请输入您的手机号码" maxlength="11" v-model="orderCreateData.member_address.mobile" @input="virtualMobileChange" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<!--收货地址-->
|
||||
<div class="item-block" v-if="orderPaymentData.is_virtual == 0">
|
||||
<div class="block-text">收货地址</div>
|
||||
|
||||
<div class="address-list">
|
||||
<div class="address-item" @click="addAddressShow">
|
||||
<div class="add-address">
|
||||
<i class="el-icon-circle-plus-outline"></i>
|
||||
添加收货地址
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="address-item" v-for="(item, key) in memberAddress" :key="item.id" :class="addressId == item.id ? 'active' : ''" v-if="key < 3 || (addressShow && key >= 3)">
|
||||
<div class="address-info">
|
||||
<div class="options">
|
||||
<div @click="editAddress(item.id)">编辑</div>
|
||||
<template v-if="item.is_default == 0">
|
||||
<el-popconfirm title="确定要删除该地址吗?" @onConfirm="deleteMemberAddress(item.id)">
|
||||
<div slot="reference">删除</div>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</div>
|
||||
<div class="address-name">{{ item.name }}</div>
|
||||
<div class="address-mobile" @click="setMemberAddress(item.id)">{{ item.mobile }}</div>
|
||||
<div class="address-desc" @click="setMemberAddress(item.id)">{{ item.full_address }} {{ item.address }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="memberAddress.length > 3 && !addressShow" @click="addressShow = true" class="el-button--text address-open">
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
更多收货地址
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--收货地址添加-->
|
||||
<el-dialog :title="addressForm.id == 0 ? '添加收货地址' : '编辑收货地址'" :visible.sync="dialogVisible" width="32%">
|
||||
<el-form ref="form" :rules="addressRules" :model="addressForm" label-width="80px">
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input v-model="addressForm.name" placeholder="收货人姓名" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="手机" prop="mobile">
|
||||
<el-input v-model="addressForm.mobile" maxlength="11" placeholder="收货人手机号" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="电话">
|
||||
<el-input v-model="addressForm.telephone" placeholder="收货人固定电话(选填)" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item class="area" label="地区" prop="area">
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="7">
|
||||
<el-select prop="province" ref="province" v-model="addressForm.province_id" @change="getAddress(1)" placeholder="请选择省">
|
||||
<el-option label="请选择省" value="0"></el-option>
|
||||
<el-option v-for="item in pickerValueArray" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-select ref="city" prop="city" v-model="addressForm.city_id" @change="getAddress(2)" placeholder="请选择市">
|
||||
<el-option label="请选择市" value="0"></el-option>
|
||||
<el-option v-for="item in cityArr" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-select ref="district" prop="district" v-model="addressForm.district_id" placeholder="请选择区/县">
|
||||
<el-option label="请选择区/县" value="0"></el-option>
|
||||
<el-option v-for="item in districtArr" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="详细地址" prop="address">
|
||||
<el-input v-model="addressForm.address" placeholder="定位小区、街道、写字楼" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="addmemberAddress('form')">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<!--使用余额-->
|
||||
<div class="item-block" v-if="orderPaymentData.member_account.balance_total > 0 && balance_show == 1">
|
||||
<div class="block-text">是否使用余额</div>
|
||||
<div class="pay-type-list">
|
||||
<div class="pay-type-item" :class="orderCreateData.is_balance ? '' : 'active'" @click="useBalance(0)">不使用余额
|
||||
</div>
|
||||
<div class="pay-type-item" :class="orderCreateData.is_balance ? 'active' : ''" @click="useBalance(1)">使用余额</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 支付密码 -->
|
||||
<el-dialog title="使用余额" :visible.sync="dialogpay" width="350px">
|
||||
<template v-if="orderPaymentData.member_account.is_pay_password == 0">
|
||||
<p>为了您的账户安全,请您先设置的支付密码</p>
|
||||
<p>可到"会员中心","账号安全","支付密码"中设置</p>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button size="small" @click="dialogpay = false">暂不设置</el-button>
|
||||
<el-button size="small" type="primary" @click="setPayPassword">立即设置</el-button>
|
||||
</span>
|
||||
</template>
|
||||
<el-form v-else status-icon ref="ruleForm" label-width="100px">
|
||||
<el-form-item label="支付密码" class="pay-password-item">
|
||||
<!--添加一个不可见的input,欺骗浏览器自动填充-->
|
||||
<el-input type="password" class="pay-password hide-password" :maxlength="6"></el-input>
|
||||
<el-input type="password" class="pay-password" :maxlength="6" v-model="password" @input="input"></el-input>
|
||||
</el-form-item>
|
||||
<p class="ns-text-color forget-password" @click="setPayPassword">忘记密码</p>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
|
||||
<!--使用积分抵扣-->
|
||||
<div class="item-block" v-if="calculateData && calculateData.max_usable_point > 0">
|
||||
<div class="block-text">是否使用积分</div>
|
||||
|
||||
<div class="pay-type-list">
|
||||
<div class="pay-type-item" :class="orderCreateData.is_point ? '' : 'active'" @click="usePoint(0)">不使用积分</div>
|
||||
<div class="pay-type-item" :class="orderCreateData.is_point ? 'active' : ''" @click="usePoint(1)">使用积分</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 配送方式 -->
|
||||
<div class="item-block padd-bom-20" v-if="orderPaymentData.delivery.express_type.length > 0">
|
||||
<div class="block-text">
|
||||
<span>配送方式</span>
|
||||
<span class="distribution" v-if="orderCreateData.delivery.delivery_type == 'store'">{{ orderCreateData.delivery.store_name }}</span>
|
||||
</div>
|
||||
<div class="pay-type-item" v-for="(item, index) in orderPaymentData.delivery.express_type" :key="index" @click="selectDeliveryType(item)" :class="item.name == orderCreateData.delivery.delivery_type ? 'active' : ''">
|
||||
{{ item.title }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--配送方式 门店 -->
|
||||
<el-dialog title="选择门店" :visible.sync="dialogStore" width="50%">
|
||||
<el-table ref="singleTable" :data="storeList" highlight-current-row @row-click="selectStore" class="cursor-pointer">
|
||||
<el-table-column label="" width="55">
|
||||
<template slot-scope="scope">
|
||||
<el-radio v-model="storeRadio" :label="scope.row"><i></i></el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="store_name" label="名称" width="160"></el-table-column>
|
||||
<el-table-column prop="store_address" label="地址"></el-table-column>
|
||||
<el-table-column prop="open_date" label="营业时间"></el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<div class="item-block" v-if="orderPaymentData.invoice && orderPaymentData.invoice.invoice_status == 1">
|
||||
<div class="block-text">发票信息</div>
|
||||
<div class="pay-type-list">
|
||||
<div class="pay-type-item" :class="orderCreateData.is_invoice == 0 ? 'active' : ''" @click="changeIsInvoice">
|
||||
无需发票
|
||||
</div>
|
||||
<div class="pay-type-item" :class="orderCreateData.is_invoice == 1 ? 'active' : ''" @click="changeIsInvoice">
|
||||
需要发票
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<div class="invoice-information" v-if="orderCreateData.is_invoice == 1">
|
||||
<div class="invoice-title">
|
||||
<div class="invoice-type-box invoice-title-box">
|
||||
<span class="invoice-name">发票类型:</span>
|
||||
<label class="invoice-to-type">
|
||||
<i class="invoice-i-input" :class="orderCreateData.invoice_type == 1 ? 'active' : ''" @click="clickType(1)"></i>
|
||||
<span>纸质</span>
|
||||
</label>
|
||||
<label class="invoice-to-type">
|
||||
<i class="invoice-i-input" :class="orderCreateData.invoice_type == 2 ? 'active' : ''" @click="clickType(2)"></i>
|
||||
<span>电子</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="invoice-type-box invoice-title-box">
|
||||
<span class="invoice-name">抬头类型:</span>
|
||||
<label class="invoice-to-type">
|
||||
<i class="invoice-i-input" :class="orderCreateData.invoice_title_type == 1 ? 'active' : ''" @click="clickTitleType(1)"></i>
|
||||
<span>个人</span>
|
||||
</label>
|
||||
<label class="invoice-to-type">
|
||||
<i class="invoice-i-input" :class="orderCreateData.invoice_title_type == 2 ? 'active' : ''" @click="clickTitleType(2)"></i>
|
||||
<span>企业</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="invoice-type-box">
|
||||
<span class="invoice-name">发票信息:</span>
|
||||
<div class="invoice-box-form">
|
||||
<input type="text" placeholder="请填写抬头名称" v-model.trim="orderCreateData.invoice_title" />
|
||||
<input type="text" placeholder="请填写纳税人识别号" v-model.trim="orderCreateData.taxpayer_number" v-if="orderCreateData.invoice_title_type == 2" />
|
||||
<input type="text" placeholder="请填写邮寄地址" v-model.trim="orderCreateData.invoice_full_address" v-show="orderCreateData.invoice_type == 1" />
|
||||
<input type="text" placeholder="请填写邮箱" v-model.trim="orderCreateData.invoice_email" v-show="orderCreateData.invoice_type == 2" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="invoice-condition">
|
||||
<span class="invoice-name">发票内容:</span>
|
||||
<div class="invoice-box-form">
|
||||
<span class="option-item" :key="index" v-for="(item, index) in orderPaymentData.invoice.invoice_content_array" @click="changeInvoiceContent(item)" :class="{ 'color-base-bg active': item == orderCreateData.invoice_content }">{{ item }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="invoice-tops">发票内容将以根据税法调整,具体请以展示为准,发票内容显示详细商品名 称及价格信息</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--商品信息-->
|
||||
<div class="item-block">
|
||||
<div class="goods-list">
|
||||
<table>
|
||||
<tr>
|
||||
<td width="50%">商品</td>
|
||||
<td width="12.5%">价格</td>
|
||||
<td width="12.5%">数量</td>
|
||||
<td width="12.5%">小计</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="item-block" v-if="calculateData">
|
||||
<div class="goods-list">
|
||||
<table>
|
||||
<tr v-for="(goodsItem, goodsIndex) in calculateData.goods_list" :key="goodsIndex">
|
||||
<td width="50%">
|
||||
<div class="goods-info">
|
||||
<div class="goods-info-left">
|
||||
<router-link :to="{ path: '/sku/' + goodsItem.sku_id }" target="_blank">
|
||||
<img class="goods-img" :src="$img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" />
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="goods-info-right">
|
||||
<router-link :to="{ path: '/sku/' + goodsItem.sku_id }" target="_blank">
|
||||
<div class="goods-name">{{ goodsItem.goods_name }}</div>
|
||||
</router-link>
|
||||
<!-- 规格 -->
|
||||
<div class="goods-spec" v-if="goodsItem.sku_spec_format">
|
||||
<span v-for="(x, i) in goodsItem.sku_spec_format" :key="i">{{ x.spec_value_name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td width="12.5%" class="goods-price">¥{{ goodsItem.price }}</td>
|
||||
<td width="12.5%" class="goods-num">{{ goodsItem.num }}</td>
|
||||
<td width="12.5%" class="goods-money">¥{{ (goodsItem.price * goodsItem.num).toFixed(2) }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--优惠券-->
|
||||
<div class="item-block" v-if="calculateData && couponList.length">
|
||||
<div class="block-text">优惠券</div>
|
||||
<div class="order-cell platform-coupon">
|
||||
<div v-if="calculateData.coupon_money != 0">
|
||||
<span class="ns-text-color" @click="openPlatformCoupon">已选择优惠券,已优惠</span>
|
||||
<span class="ns-text-color" @click="openPlatformCoupon">
|
||||
<span class="inline">¥</span>
|
||||
{{ calculateData.coupon_money }}
|
||||
</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="box ns-text-color" @click="openPlatformCoupon">不使用优惠券</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 活动优惠 -->
|
||||
<div class="item-block" v-if="promotionInfo">
|
||||
<div class="block-text">{{ promotionInfo.title }}</div>
|
||||
<div class="order-cell platform-coupon">
|
||||
<div class="box ns-text-color" v-html="promotionInfo.content"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--优惠券弹框-->
|
||||
<el-dialog title="选择优惠券" :visible.sync="dialogPlatcoupon" width="50%" @close="savePlatformCoupon()">
|
||||
<el-table ref="platformCouponTable" :data="couponList" highlight-current-row @row-click="selectPlatformCoupon" class="cursor-pointer">
|
||||
<el-table-column label="" width="55">
|
||||
<template slot-scope="scope">
|
||||
<div class="disabled-selected-wrap">
|
||||
<el-radio v-model="platformCouponRadio" :label="scope.row"><i></i></el-radio>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="platformcoupon_name" label="名称" width="200">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.coupon_name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="money" label="优惠">
|
||||
|
||||
<template slot-scope="scope">
|
||||
|
||||
<template v-if="scope.row.type == 'divideticket'">
|
||||
<span class="money">¥{{ parseFloat(scope.row.money) }}</span>
|
||||
</template>
|
||||
<template v-else-if="scope.row.type == 'reward'">
|
||||
<span class="money">¥{{ parseFloat(scope.row.money) }}</span>
|
||||
</template>
|
||||
<template v-else-if="scope.row.type == 'discount'">
|
||||
<span class="money">{{ parseFloat(scope.row.discount) }}折</span>
|
||||
</template>
|
||||
|
||||
</template>
|
||||
|
||||
</el-table-column>
|
||||
<el-table-column label="使用">
|
||||
<template slot-scope="scope">
|
||||
<span class="ns-text-color-gray ns-font-size-sm" v-if="scope.row.at_least > 0">满{{ scope.row.at_least }}可用</span>
|
||||
<span class="ns-text-color-gray ns-font-size-sm" v-else>无门槛</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="有效期">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.end_time ? $util.timeStampTurnTime(scope.row.end_time) : '长期有效' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<br />
|
||||
<div class="align-right">
|
||||
<el-button @click="dialogPlatcoupon = false">取消</el-button>
|
||||
<el-button @click="dialogPlatcoupon = false" type="primary">确认选择</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 买家留言 -->
|
||||
<div class="item-block padd-bom-10">
|
||||
<div class="block-text">买家留言:</div>
|
||||
<el-input rows="3" type="textarea" placeholder="留言前建议先与商家协调一致" v-model="orderCreateData.buyer_message" class="buyer-message" @input="textarea" maxlength="140" show-word-limit resize="none" />
|
||||
</div>
|
||||
|
||||
<!-- 总计 -->
|
||||
<div class="item-block" v-if="calculateData">
|
||||
<div class="order-statistics">
|
||||
<table>
|
||||
<tr>
|
||||
<td align="right">商品金额:</td>
|
||||
<td align="left">¥{{ calculateData.goods_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.is_virtual == 0 && calculateData.delivery_money > 0">
|
||||
<td align="right">运费:</td>
|
||||
<td align="left">¥{{ calculateData.delivery_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.invoice_money > 0">
|
||||
<td align="right">发票税费<span class="ns-text-color">({{ calculateData.invoice.invoice_rate }}%)</span>:</td>
|
||||
<td align="left">¥{{ calculateData.invoice_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.invoice_delivery_money > 0">
|
||||
<td align="right">发票邮寄费:</td>
|
||||
<td align="left">¥{{ calculateData.invoice_delivery_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.promotion_money > 0">
|
||||
<td align="right">优惠:</td>
|
||||
<td align="left">¥{{ calculateData.promotion_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.coupon_money > 0">
|
||||
<td align="right">优惠券:</td>
|
||||
<td align="left">¥{{ calculateData.coupon_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.point_money > 0">
|
||||
<td align="right">积分抵扣:</td>
|
||||
<td align="left">¥{{ calculateData.point_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.balance_money > 0">
|
||||
<td align="right">使用余额:</td>
|
||||
<td align="left">¥{{ calculateData.balance_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<!--结算-->
|
||||
<div class="item-block" v-if="calculateData">
|
||||
<div class="order-submit">
|
||||
<div class="order-money">
|
||||
共{{ calculateData.goods_num }}件,应付金额:
|
||||
<div class="ns-text-color">¥{{ calculateData.pay_money | moneyFormat }}</div>
|
||||
</div>
|
||||
<el-button type="primary" class="el-button--primary" @click="orderCreate">订单结算</el-button>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import detail from '@/assets/js/order/payment.js';
|
||||
|
||||
export default {
|
||||
name: 'payment',
|
||||
mixins: [detail]
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/css/order/payment.scss';
|
||||
</style>
|
||||
482
addon/pc/source/os/pages/order/refund.vue
Executable file
482
addon/pc/source/os/pages/order/refund.vue
Executable file
@@ -0,0 +1,482 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<div v-loading="loading">
|
||||
<el-card class="box-card order-list">
|
||||
<div slot="header" class="clearfix">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/member/order_list' }">我的订单</el-breadcrumb-item>
|
||||
<el-breadcrumb-item :to="{ path: '/member/order_detail?order_id=' + orderId }">订单详情</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>退款</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
|
||||
<!--商品信息-->
|
||||
<div class="goods-list">
|
||||
<table>
|
||||
<tr>
|
||||
<td width="62.5%">商品</td>
|
||||
<td width="12.5%">数量</td>
|
||||
<td width="12.5%">金额</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="goods-list">
|
||||
<table>
|
||||
<tr>
|
||||
<td width="62.5%">
|
||||
<div class="goods-info">
|
||||
<div class="goods-info-left">
|
||||
<router-link :to="{ path: '/sku/' + refundData.order_goods_info.sku_id }" target="_blank">
|
||||
<img class="goods-img" :src="$img(refundData.order_goods_info.sku_image, { size: 'mid' })" @error="refundData.order_goods_info.sku_image = defaultGoodsImage" />
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="goods-info-right">
|
||||
<router-link :to="{ path: '/sku/' + refundData.order_goods_info.sku_id }" target="_blank">
|
||||
<div class="goods-name">{{ refundData.order_goods_info.sku_name }}</div>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td width="12.5%" class="goods-num">{{ refundData.order_goods_info.num }}</td>
|
||||
<td width="12.5%" class="goods-money">¥{{ refundData.order_goods_info.goods_money }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!--退款类型 -->
|
||||
<div class="item-block">
|
||||
<div class="block-text">退款类型</div>
|
||||
|
||||
<div class="pay-type-list">
|
||||
<div class="pay-type-item" :class="refundType == 1 ? 'active' : ''" @click="selectRefundType(1)">退款无需退货</div>
|
||||
<div v-if="refundData.refund_type.length == 2" class="pay-type-item" :class="refundType == 2 ? 'active' : ''" @click="selectRefundType(2)">退货退款</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--退款填写-->
|
||||
<div class="item-block">
|
||||
<div class="block-text"></div>
|
||||
|
||||
<el-form ref="form" label-width="80px" class="refund-form">
|
||||
<el-form-item label="退款金额">
|
||||
<el-input disabled="" :value="refundData.refund_money"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="退款原因">
|
||||
<el-select placeholder="请选择" v-model="refundReason">
|
||||
<el-option v-for="(item, itemIndex) in refundData.refund_reason_type" :key="itemIndex" :label="item" :value="item"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="退款说明">
|
||||
<el-input maxlength="140" show-word-limit resize="none" rows="5" placeholder="请输入退款说明(选填)" type="textarea" v-model="refundRemark"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="退款图片">
|
||||
<div class="upload-wrap">
|
||||
<el-upload ref="upload" :class="{ ishide: hide }" :action="uploadActionUrl" :data="uploadData"
|
||||
list-type="picture-card" :on-success="
|
||||
(file, fileList) => {
|
||||
return handleSuccess(file, fileList);
|
||||
}
|
||||
" :on-preview="handlePictureCardPreview" :on-remove="
|
||||
(file, fileList) => {
|
||||
return handleRemove(file, fileList);
|
||||
}
|
||||
" :on-exceed="handleExceed" multiple drag :limit="5">
|
||||
<i class="el-icon-plus"></i>
|
||||
<!-- <i class="el-icon-upload"></i> -->
|
||||
<!-- <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
|
||||
<div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div> -->
|
||||
</el-upload>
|
||||
<el-dialog :visible.sync="dialogVisible"><img width="100%" :src="dialogImageUrl" alt="" /></el-dialog>
|
||||
<div class="tips">共5张,还能上传{{ imgList.length ? 5 - imgList.length : 5 }}张</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div class="item-block">
|
||||
<div class="order-submit">
|
||||
<el-button type="primary" class="el-button--primary" @click="submit">提交</el-button>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {refundData, refund, detail, delivery} from '@/api/order/refund';
|
||||
import {mapGetters} from 'vuex';
|
||||
import Config from '@/plugins/config';
|
||||
export default {
|
||||
name: 'refund',
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
orderGoodsId: '',
|
||||
orderId: '',
|
||||
refundType: 1,
|
||||
refundReason: '',
|
||||
refundRemark: '',
|
||||
isIphoneX: false,
|
||||
refundData: {
|
||||
refund_type: [],
|
||||
order_goods_info: {
|
||||
sku_image: ''
|
||||
}
|
||||
},
|
||||
isSub: false,
|
||||
show_type: 0, //退款状态 1-待退款 2-已退款
|
||||
detail: {
|
||||
refund_action: []
|
||||
},
|
||||
loading: true,
|
||||
yes: true,
|
||||
dialogVisible: false,
|
||||
hide: false,
|
||||
uploadActionUrl: Config.baseUrl + '/api/upload/refundimg',
|
||||
uploadData: {
|
||||
app_type: "pc",
|
||||
app_type_name: "PC"
|
||||
},
|
||||
imgList: [],
|
||||
dialogImageUrl: '',
|
||||
};
|
||||
},
|
||||
created() {
|
||||
if (this.$route.query.order_goods_id) this.orderGoodsId = this.$route.query.order_goods_id;
|
||||
if (this.$route.query.order_id) this.orderId = this.$route.query.order_id;
|
||||
this.getRefundData();
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
layout: 'member',
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
handleRemove(file, fileList) {
|
||||
let i = this.$util.inArray(file.response.data.pic_path, this.imgList);
|
||||
this.imgList.splice(i, 1);
|
||||
|
||||
if (this.imgList.length < 5) {
|
||||
this.hide = false;
|
||||
}
|
||||
},
|
||||
handleSuccess(file, fileList) {
|
||||
let arr = this.imgList;
|
||||
arr = arr.concat(file.data.pic_path);
|
||||
this.imgList = arr;
|
||||
|
||||
if (this.imgList.length >= 5) {
|
||||
this.hide = true;
|
||||
}
|
||||
},
|
||||
handleExceed(file, fileList) {
|
||||
// 图片数量大于5
|
||||
this.$message.warning('上传图片最大数量为5张');
|
||||
},
|
||||
handlePictureCardPreview(file) {
|
||||
// 点开大图
|
||||
this.dialogImageUrl = file.url;
|
||||
this.dialogVisible = true;
|
||||
},
|
||||
/**
|
||||
* 选择退款方式
|
||||
* @param {Object} type
|
||||
*/
|
||||
selectRefundType(type) {
|
||||
this.refundType = type;
|
||||
},
|
||||
getRefundData() {
|
||||
refundData({order_goods_id: this.orderGoodsId}).then(res => {
|
||||
const {code, message, data} = res;
|
||||
if (code >= 0) {
|
||||
this.refundData = data;
|
||||
} else {
|
||||
this.$message({
|
||||
message: '未获取到该订单项退款信息!',
|
||||
type: 'warning',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({path: '/member/activist'});
|
||||
}
|
||||
});
|
||||
}
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error({
|
||||
message: err.message,
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({path: '/member/activist'});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
submit() {
|
||||
if (this.verify()) {
|
||||
if (this.isSub) return;
|
||||
this.isSub = true;
|
||||
|
||||
let submit_data = {
|
||||
order_goods_ids: this.orderGoodsId,
|
||||
refund_type: this.refundType,
|
||||
refund_reason: this.refundReason,
|
||||
refund_remark: this.refundRemark,
|
||||
refund_images: this.imgList.toString()
|
||||
};
|
||||
|
||||
refund(submit_data).then(res => {
|
||||
const {code, message, data} = res;
|
||||
if (code >= 0) {
|
||||
this.$message({
|
||||
message: '申请成功!',
|
||||
type: 'success',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({path: '/member/activist'});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.isSub = false;
|
||||
this.$message({message: message, type: 'warning'});
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error({
|
||||
message: err.message,
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({path: '/member/activist'});
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
verify() {
|
||||
if (this.refundReason == '') {
|
||||
this.$message({message: '请选择退款原因', type: 'warning'});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.upload-wrap .el-upload--picture-card {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.upload-wrap .el-upload--picture-card,
|
||||
.upload-wrap .el-upload-list--picture-card .el-upload-list__item {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
line-height: 80px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.upload-wrap .el-upload-list--picture-card .el-upload-list__item-thumbnail {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.upload-wrap .el-upload-list__item.is-success .el-upload-list__item-status-label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.upload-wrap .ishide .el-upload--picture-card {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.upload-wrap .el-upload-dragger {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
|
||||
}
|
||||
.upload-wrap .el-upload--picture-card {
|
||||
border: none;
|
||||
}
|
||||
.upload-wrap .el-upload-dragger {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
}
|
||||
</style>
|
||||
<style lang="scss" scoped>
|
||||
.upload-wrap {
|
||||
.tips {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.el-card.is-always-shadow,
|
||||
.el-card.is-hover-shadow:focus,
|
||||
.el-card.is-hover-shadow:hover {
|
||||
box-shadow: unset;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.item-block {
|
||||
padding: 0 15px 1px;
|
||||
margin: 10px 0;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
background: #ffffff;
|
||||
|
||||
.block-text {
|
||||
border-color: #eeeeee;
|
||||
color: $ns-text-color-black;
|
||||
padding: 7px 0;
|
||||
border-bottom: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.refund-form {
|
||||
width: 350px;
|
||||
|
||||
.el-select {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.order-submit {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.goods-list {
|
||||
padding: 15px 0;
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.goods-info-left {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
float: left;
|
||||
|
||||
.goods-img {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-info-right {
|
||||
float: left;
|
||||
height: 60px;
|
||||
margin-left: 10px;
|
||||
color: $base-color;
|
||||
width: 80%;
|
||||
|
||||
.goods-name {
|
||||
line-height: 20px;
|
||||
padding-top: 10px;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.goods-spec {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pay-type-list {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.pay-type-item {
|
||||
display: inline-block;
|
||||
border: 2px solid #eeeeee;
|
||||
padding: 5px 20px;
|
||||
margin-right: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.pay-type-item.active {
|
||||
border-color: $base-color;
|
||||
}
|
||||
|
||||
.status-wrap {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.media-left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.media-right {
|
||||
float: right;
|
||||
|
||||
i.rotate {
|
||||
transform: rotate(180deg);
|
||||
transition: 0.3s;
|
||||
}
|
||||
}
|
||||
|
||||
.action-box {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.action-way {
|
||||
float: left;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.head .time {
|
||||
float: right;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.record-item {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.order-statistics {
|
||||
float: left;
|
||||
padding: 10px;
|
||||
// color: #999;
|
||||
}
|
||||
|
||||
.el-textarea .el-input__count {
|
||||
line-height: 20px;
|
||||
}
|
||||
</style>
|
||||
630
addon/pc/source/os/pages/order/refund_detail.vue
Executable file
630
addon/pc/source/os/pages/order/refund_detail.vue
Executable file
@@ -0,0 +1,630 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<div v-loading="loading">
|
||||
<!-- 退款详情start -->
|
||||
<div>
|
||||
<el-card class="box-card order-list">
|
||||
<div slot="header" class="clearfix">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/member/activist' }">退款/售后</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>退款详情</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="block-text color-red" v-if="detail.refund_status==-1">{{ detail.refund_status_name }}</div>
|
||||
<div class="block-text color-green" v-if="detail.refund_status==3">{{ detail.refund_status_name }}</div>
|
||||
<div class="fail-text" v-if="detail.refund_status==-1">
|
||||
<div class="fail-title">拒绝原因:</div>
|
||||
<div class="fail-detail">{{ detail.refund_refuse_reason }}</div>
|
||||
</div>
|
||||
<div class="block-text" v-if="detail.refund_status!=-1 && detail.refund_status!=3">
|
||||
{{ detail.refund_status_name }}
|
||||
</div>
|
||||
<div class="status-wrap">
|
||||
<div class="refund-explain" v-if="detail.refund_status == 1">
|
||||
<div>如果商家拒绝,你可重新发起申请</div>
|
||||
<div>如果商家同意,将通过申请并退款给你</div>
|
||||
<div>如果商家逾期未处理,平台将自动通过申请并退款给你</div>
|
||||
</div>
|
||||
<div class="refund-explain" v-if="detail.refund_status == 5">
|
||||
<div>如果商家确认收货将会退款给你</div>
|
||||
<div>如果商家拒绝收货,该次退款将会关闭,你可以重新发起退款</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!--协商记录-->
|
||||
<div class="item-block">
|
||||
<div class="action-box">
|
||||
<span class="media-left">协商记录</span>
|
||||
<div class="media-right">
|
||||
<div class="el-button--text" @click="actionOpen ? (actionOpen = false) : (actionOpen = true)">
|
||||
协商记录
|
||||
<i :class="actionOpen ? 'rotate' : ''" class="el-icon-arrow-down"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<div v-if="actionOpen">
|
||||
<el-timeline>
|
||||
<el-timeline-item :class="logItem.action_way == 1 ? 'buyer' : 'seller'" v-for="(logItem, logIndex) in detail.refund_log_list" :key="logIndex" :timestamp="$util.timeStampTurnTime(logItem.action_time)" placement="top">
|
||||
<div>
|
||||
<h4>{{ logItem.action_way == 1 ? '买家' : '卖家' }}</h4>
|
||||
<p>{{ logItem.action }}</p>
|
||||
</div>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 退货地址 -->
|
||||
<div class="item-block" v-if="detail.refund_status == 4">
|
||||
<div class="block-text">
|
||||
<span>收货人:{{ detail.shop_contacts }}</span>
|
||||
<span>联系电话:{{ detail.shop_mobile }}</span>
|
||||
</div>
|
||||
<div class="block-text">
|
||||
<span>退货地址:{{ detail.shop_address }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--退款详情-->
|
||||
<div class="item-block">
|
||||
<div class="goods-list">
|
||||
<table>
|
||||
<tr>
|
||||
<td width="62.5%">商品</td>
|
||||
<td width="12.5%">数量</td>
|
||||
<td width="12.5%">退款金额</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item-block">
|
||||
<div class="goods-list">
|
||||
<table>
|
||||
<tr>
|
||||
<td width="62.5%">
|
||||
<div class="goods-info">
|
||||
<div class="goods-info-left">
|
||||
<router-link :to="{ path: '/sku/' + detail.sku_id }" target="_blank">
|
||||
<img class="goods-img" :src="$img(detail.sku_image)" @error="detail.sku_image = defaultGoodsImage" />
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="goods-info-right">
|
||||
<router-link :to="{ path: '/sku/' + detail.sku_id }" target="_blank">
|
||||
<div class="goods-name">{{ detail.sku_name }}</div>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td width="12.5%" class="goods-num">{{ detail.num }}</td>
|
||||
<td width="12.5%" class="goods-money">¥{{ detail.refund_apply_money }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item-block">
|
||||
<div class="order-statistics">
|
||||
<table v-if="detail.refund_apply_money > 0">
|
||||
<!-- 申请信息 -->
|
||||
<tr>
|
||||
<td align="right">退款方式:</td>
|
||||
<td align="left">{{ detail.refund_type == 1 ? '仅退款' : '退款退货' }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">申请原因:</td>
|
||||
<td align="left">{{ detail.refund_reason }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">申请金额:</td>
|
||||
<td align="left">¥{{ detail.refund_apply_money }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">申请时间:</td>
|
||||
<td align="left">{{ $util.timeStampTurnTime(detail.refund_action_time) }}</td>
|
||||
</tr>
|
||||
<tr class="refund-images" v-if="detail.refund_images">
|
||||
<td align="right refund-title">退款图片:</td>
|
||||
<td align="left">
|
||||
<img class="image" v-for="(item,index) in detail.refund_images.split(',')" :key="index" :src="$img(item)" alt="" />
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table v-if="detail.refund_apply_money > 0 && detail.refund_status == 3">
|
||||
<!-- 退款信息 -->
|
||||
<tr>
|
||||
<td align="right">退款金额:</td>
|
||||
<td align="left">¥{{ detail.refund_apply_money }} ({{ detail.refund_money_type_name }})</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">退款编号:</td>
|
||||
<td align="left">{{ detail.refund_no }}</td>
|
||||
</tr>
|
||||
<tr v-if="detail.refund_time">
|
||||
<td align="right">退款时间:</td>
|
||||
<td align="left">{{ $util.timeStampTurnTime(detail.refund_time) }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table v-if="detail.shop_active_refund == 1">
|
||||
<!-- 主动退款信息 -->
|
||||
<tr>
|
||||
<td align="right">主动退款金额:</td>
|
||||
<td align="left">¥{{ detail.shop_active_refund_money }} ({{ detail.shop_active_refund_money_type_name }})</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">主动退款编号:</td>
|
||||
<td align="left">{{ detail.shop_active_refund_no }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="right">主动退款说明:</td>
|
||||
<td align="left">{{ detail.shop_active_refund_remark }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<div class="item-block" v-if="detail.refund_action.length">
|
||||
<div class="order-submit" v-for="(actionItem, actionIndex) in detail.refund_action" :key="actionIndex">
|
||||
<el-button type="primary" class="el-button--primary" @click="refundAction(actionItem.event)">{{ actionItem.title }}</el-button>
|
||||
</div>
|
||||
|
||||
<div class="order-submit" v-if="detail.complain_action">
|
||||
<el-button type="primary" class="el-button--primary" @click="refundAction('complain')">平台维权</el-button>
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 退款详情end -->
|
||||
|
||||
<!-- 输入物流信息弹出 -->
|
||||
<el-dialog title="输入发货物流" :visible.sync="refundDeliveryDialog" width="50%">
|
||||
<el-form ref="form" :model="formData" label-width="80px">
|
||||
<el-form-item label="物流公司">
|
||||
<el-input v-model="formData.refund_delivery_name" placeholder="请输入物流公司"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="物流单号">
|
||||
<el-input v-model="formData.refund_delivery_no" placeholder="请输入物流单号"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="物流说明">
|
||||
<el-input v-model="formData.refund_delivery_remark" placeholder="选填"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="refundDeliveryDialog = false">取 消</el-button>
|
||||
<el-button type="primary" @click="refundGoods('form')">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
refundData,
|
||||
refund,
|
||||
detail,
|
||||
delivery,
|
||||
cancleRefund
|
||||
} from '@/api/order/refund';
|
||||
import {
|
||||
mapGetters
|
||||
} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'refund_detail',
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
orderGoodsId: '',
|
||||
isSub: false,
|
||||
detail: {
|
||||
refund_action: []
|
||||
},
|
||||
formData: {
|
||||
refund_delivery_name: '',
|
||||
refund_delivery_no: '',
|
||||
refund_delivery_remark: ''
|
||||
},
|
||||
actionOpen: false, //协商记录
|
||||
refundDeliveryDialog: false, //发货地址弹出
|
||||
loading: true,
|
||||
yes: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
if (this.$route.query.order_goods_id) this.orderGoodsId = this.$route.query.order_goods_id;
|
||||
this.getRefundDetail();
|
||||
// if (this.$route.query.action && this.$route.query.action == 'returngoods') {
|
||||
// this.refundDeliveryDialog = true;
|
||||
// }
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
layout: 'member',
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
//退款详情相关
|
||||
getRefundDetail() {
|
||||
this.loading = true;
|
||||
detail({
|
||||
order_goods_id: this.orderGoodsId
|
||||
}).then(res => {
|
||||
const {
|
||||
code,
|
||||
message,
|
||||
data
|
||||
} = res;
|
||||
if (code >= 0) {
|
||||
this.detail = data;
|
||||
} else {
|
||||
this.$message({
|
||||
message: '未获取到该订单项退款信息!',
|
||||
type: 'warning',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({
|
||||
path: '/member/activist'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error({
|
||||
message: err.message,
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({
|
||||
path: '/member/activist'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
refundAction(event) {
|
||||
switch (event) {
|
||||
case 'orderRefundCancel':
|
||||
this.cancleRefund(this.detail.order_goods_id);
|
||||
break;
|
||||
case 'orderRefundDelivery':
|
||||
this.refundDeliveryDialog = true;
|
||||
break;
|
||||
case 'orderRefundAsk':
|
||||
this.$router.push({
|
||||
path: '/order/refund?order_goods_id=' + this.detail.order_goods_id
|
||||
});
|
||||
break;
|
||||
case 'complain':
|
||||
this.$router.push({
|
||||
path: '/order/complain?order_goods_id=' + this.detail.order_goods_id
|
||||
});
|
||||
break;
|
||||
case 'orderRefundApply':
|
||||
this.$router.push({
|
||||
path: '/order/refund',
|
||||
query: { order_goods_id: this.detail.order_goods_id, order_id: this.detail.order_id },
|
||||
});
|
||||
break;
|
||||
}
|
||||
},
|
||||
refundGoods() {
|
||||
if (this.formData.refund_delivery_name == '') {
|
||||
this.$message({
|
||||
message: '请输入物流公司',
|
||||
type: 'warning'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
if (this.formData.refund_delivery_no == '') {
|
||||
this.$message({
|
||||
message: '请输入物流单号',
|
||||
type: 'warning'
|
||||
});
|
||||
return false;
|
||||
}
|
||||
this.formData.order_goods_id = this.orderGoodsId;
|
||||
if (this.isSub) return;
|
||||
this.isSub = true;
|
||||
|
||||
delivery(this.formData).then(res => {
|
||||
const {
|
||||
code,
|
||||
message,
|
||||
data
|
||||
} = res;
|
||||
if (code >= 0) {
|
||||
this.getRefundDetail();
|
||||
this.refundDeliveryDialog = false;
|
||||
} else {
|
||||
this.$message({
|
||||
message: '未获取到该订单项退款信息!',
|
||||
type: 'warning',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({
|
||||
path: '/member/activist'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error({
|
||||
message: err.message,
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({
|
||||
path: '/member/activist'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
cancleRefund(order_goods_id) {
|
||||
this.$confirm('撤销之后本次申请将会关闭,如后续仍有问题可再次发起申请', '提示', {
|
||||
confirmButtonText: '确认撤销',
|
||||
cancelButtonText: '暂不撤销',
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
if (this.isSub) return;
|
||||
this.isSub = true;
|
||||
|
||||
cancleRefund({
|
||||
order_goods_id: order_goods_id
|
||||
}).then(res => {
|
||||
const {
|
||||
code,
|
||||
message,
|
||||
data
|
||||
} = res;
|
||||
if (code >= 0) {
|
||||
this.$message({
|
||||
message: '撤销成功!',
|
||||
type: 'success',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({
|
||||
path: '/member/activist'
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.$message({
|
||||
message: message,
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error({
|
||||
message: err.message,
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({
|
||||
path: '/member/activist'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.el-card.is-always-shadow,
|
||||
.el-card.is-hover-shadow:focus,
|
||||
.el-card.is-hover-shadow:hover {
|
||||
box-shadow: unset;
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.item-block {
|
||||
padding: 0 20px 1px;
|
||||
margin: 10px 0;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
background: #ffffff;
|
||||
|
||||
.block-text {
|
||||
border-color: #eeeeee;
|
||||
color: $ns-text-color-black;
|
||||
padding: 7px 0;
|
||||
border-bottom: 1px;
|
||||
|
||||
span {
|
||||
margin-right: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.fail-text {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
color: #F94460;
|
||||
padding: 7px 0;
|
||||
border-bottom: 1px;
|
||||
|
||||
.fail-title {
|
||||
width: 7%;
|
||||
}
|
||||
|
||||
.fail-detail {
|
||||
width: 93%;
|
||||
}
|
||||
}
|
||||
|
||||
.color-green {
|
||||
color: #34C25D;
|
||||
}
|
||||
|
||||
.color-red {
|
||||
color: #F94460;
|
||||
}
|
||||
|
||||
.order-submit {
|
||||
float: right;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.goods-list {
|
||||
padding: 15px 0;
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.goods-info-left {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
float: left;
|
||||
|
||||
.goods-img {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
.goods-info-right {
|
||||
float: left;
|
||||
height: 60px;
|
||||
margin-left: 10px;
|
||||
color: $base-color;
|
||||
width: 80%;
|
||||
|
||||
.goods-name {
|
||||
line-height: 20px;
|
||||
padding-top: 10px;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.goods-spec {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.pay-type-list {
|
||||
padding: 20px 0;
|
||||
}
|
||||
|
||||
.pay-type-item {
|
||||
display: inline-block;
|
||||
border: 2px solid #eeeeee;
|
||||
padding: 5px 20px;
|
||||
margin-right: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.pay-type-item.active {
|
||||
border-color: $base-color;
|
||||
}
|
||||
|
||||
.status-wrap {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.media-left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.media-right {
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
|
||||
i.rotate {
|
||||
transform: rotate(180deg);
|
||||
transition: 0.3s;
|
||||
}
|
||||
}
|
||||
|
||||
.action-box {
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.action-way {
|
||||
float: left;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.head .time {
|
||||
float: right;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.record-item {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.order-statistics {
|
||||
float: left;
|
||||
padding: 10px;
|
||||
// color: #999;
|
||||
table{
|
||||
margin-bottom:10px;
|
||||
|
||||
}
|
||||
table:last-child{
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
<style lang="scss">
|
||||
.refund-images{
|
||||
td{
|
||||
&:first-child{
|
||||
vertical-align: baseline;
|
||||
}
|
||||
}
|
||||
.image{
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
147
addon/pc/source/os/pages/order/verification.vue
Executable file
147
addon/pc/source/os/pages/order/verification.vue
Executable file
@@ -0,0 +1,147 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
<el-card class="box-card order-list">
|
||||
<div slot="header" class="clearfix"><span>核销台</span></div>
|
||||
<div class="ns-verification">
|
||||
<div class="ns-verification-flow">
|
||||
<div class="ns-verification-icon">
|
||||
<div><i class="iconfont icon-shurutianxiebi"></i></div>
|
||||
<p>输入核销码</p>
|
||||
</div>
|
||||
<div><i class="iconfont icon-jiang-copy"></i></div>
|
||||
<div class="ns-verification-icon">
|
||||
<div><i class="iconfont icon-hexiao"></i></div>
|
||||
<p>核销</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ns-verification-wrap">
|
||||
<el-input v-model="verify_code" placeholder="请输入核销码"></el-input>
|
||||
<el-button @click="confirm">确认</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
verifyInfo
|
||||
} from "@/api/order/verification"
|
||||
|
||||
export default {
|
||||
name: "verification",
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
verify_code: "",
|
||||
yes: true
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
layout: 'member',
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
confirm() {
|
||||
var reg = /[\S]+/
|
||||
if (!reg.test(this.verify_code)) {
|
||||
this.$message({
|
||||
message: "请输入核销码",
|
||||
type: "warning"
|
||||
})
|
||||
return false
|
||||
}
|
||||
verifyInfo({
|
||||
verify_code: this.verify_code
|
||||
}).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.$router.push({
|
||||
path: "/order/verification_detail",
|
||||
query: {
|
||||
code: this.verify_code
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$message({
|
||||
message: res.message,
|
||||
type: "warning"
|
||||
})
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.ns-verification {
|
||||
margin: 20px 0;
|
||||
background: #ffffff;
|
||||
padding: 80px;
|
||||
text-align: center;
|
||||
|
||||
.ns-verification-flow {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
.ns-verification-icon {
|
||||
width: 150px;
|
||||
margin: 0 20px;
|
||||
|
||||
div {
|
||||
display: inline-block;
|
||||
background: #eee;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
text-align: center;
|
||||
line-height: 60px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
p {
|
||||
color: #999999;
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
i {
|
||||
font-size: 30px;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.ns-verification-wrap {
|
||||
display: inline-block;
|
||||
width: 500px;
|
||||
margin-top: 50px;
|
||||
|
||||
.el-button {
|
||||
margin-top: 50px;
|
||||
background: $base-color;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
155
addon/pc/source/os/pages/order/verification_detail.vue
Executable file
155
addon/pc/source/os/pages/order/verification_detail.vue
Executable file
@@ -0,0 +1,155 @@
|
||||
<template>
|
||||
<el-card class="box-card order-list">
|
||||
<div slot="header" class="clearfix">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item :to="{ path: '/order/verification_list' }">核销记录</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>核销验证</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div class="ns-verification" v-loading="loading">
|
||||
<div class="ns-verification-order">
|
||||
<p class="ns-site-name">{{ verifyInfo.site_name }}</p>
|
||||
<div class="ns-goods-list" v-for="(item, index) in verifyInfo.item_array" :key="index">
|
||||
<div class="ns-goods-img">
|
||||
<el-image fit="cover" :src="$img(item.img)" @error="imageError(index)"></el-image>
|
||||
</div>
|
||||
<div class="ns-goods-info">
|
||||
<p>{{ item.name }}</p>
|
||||
<p class="ns-goods-price ns-text-color">¥{{ item.price }}</p>
|
||||
<p>数量:{{ item.num }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="ns-order-info">
|
||||
<p v-for="(item, index) in verifyInfo.remark_array" :key="index">{{ item.title }}:{{ item.value }}</p>
|
||||
<p>核销类型:{{ verifyInfo.verify_type_name }}</p>
|
||||
|
||||
<template v-if="verifyInfo.is_verify">
|
||||
<p>核销状态:已核销</p>
|
||||
<p v-if="verifyInfo.verify_time">核销人员:{{ verifyInfo.verifier_name }}</p>
|
||||
<p v-if="verifyInfo.verify_time">核销时间:{{ $timeStampTurnTime(verifyInfo.verify_time) }}</p>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div class="ns-btn">
|
||||
<el-button @click="verify" v-if="verifyInfo.is_verify == 0">确认使用</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {verifyInfo, verify} from '@/api/order/verification';
|
||||
import {mapGetters} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'verification_detail',
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
verify_code: '',
|
||||
verifyInfo: {},
|
||||
isSub: false,
|
||||
loading: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.verify_code = this.$route.query.code;
|
||||
this.getVerifyInfo();
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
layout: 'member',
|
||||
methods: {
|
||||
getVerifyInfo() {
|
||||
verifyInfo({
|
||||
verify_code: this.verify_code
|
||||
}).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.verifyInfo = res.data;
|
||||
} else {
|
||||
this.$message({message: res.message, type: 'warning'});
|
||||
this.$router.push('/member');
|
||||
}
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message);
|
||||
this.$router.push('/member');
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
verify() {
|
||||
if (this.isSub) return;
|
||||
this.isSub = true;
|
||||
verify({
|
||||
verify_code: this.verify_code
|
||||
}).then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.$message({
|
||||
message: res.message,
|
||||
type: 'success',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push('/order/verification_list');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.$message({message: res.message, type: 'warning'});
|
||||
this.isSub = false;
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message);
|
||||
this.isSub = false;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 图片加载失败
|
||||
*/
|
||||
imageError(index) {
|
||||
this.verifyInfo.item_array[index].img = this.defaultGoodsImage;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.ns-verification {
|
||||
.ns-verification-order {
|
||||
.ns-goods-list {
|
||||
display: flex;
|
||||
margin: 10px 0;
|
||||
|
||||
.el-image {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
line-height: 80px;
|
||||
text-align: center;
|
||||
margin-right: 10px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.ns-goods-price span:first-child {
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.ns-order-info {
|
||||
border-top: 1px solid #eeeeee;
|
||||
padding-top: 20px;
|
||||
color: $base-color-info;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
.ns-btn {
|
||||
text-align: right;
|
||||
|
||||
.el-button {
|
||||
background: $base-color;
|
||||
color: #ffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
301
addon/pc/source/os/pages/order/verification_list.vue
Executable file
301
addon/pc/source/os/pages/order/verification_list.vue
Executable file
@@ -0,0 +1,301 @@
|
||||
<template>
|
||||
<div class="box">
|
||||
<div class="null-page" v-show="yes"></div>
|
||||
|
||||
<el-card class="box-card order-list">
|
||||
<div slot="header" class="clearfix"><span>核销记录</span></div>
|
||||
|
||||
<div v-loading="loading">
|
||||
<el-tabs v-model="orderType" @tab-click="handleClick">
|
||||
<el-tab-pane v-for="(item, index) in typeList" :key="index" :label="item.name" :name="item.type"></el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<div>
|
||||
<nav>
|
||||
<li>商品信息</li>
|
||||
<li>单价</li>
|
||||
<li>数量</li>
|
||||
</nav>
|
||||
|
||||
<div class="list" v-if="verifyList.length > 0">
|
||||
<div class="item" v-for="(item, index) in verifyList" :key="index">
|
||||
<div class="head">
|
||||
<span class="create-time">{{ $util.timeStampTurnTime(item.create_time) }}</span>
|
||||
<router-link :to="'/shop-' + item.site_id" target="_blank">{{ item.site_name }}</router-link>
|
||||
<span class="order-type">{{ item.order_type_name }}</span>
|
||||
<span class="order-type">核销员:{{ item.verifier_name }}</span>
|
||||
</div>
|
||||
<ul v-for="(goodsItem, goodsIndex) in item.item_array" :key="goodsIndex">
|
||||
<li>
|
||||
<div class="img-wrap" @click="toVerifyDetail(item.verify_code)">
|
||||
<img :src="$img(goodsItem.img)" @error="imageError(index, goodsIndex)" />
|
||||
</div>
|
||||
<div class="info-wrap">
|
||||
<h5 @click="toVerifyDetail(item.verify_code)">{{ goodsItem.name }}</h5>
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<span>¥{{ goodsItem.price }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span>{{ goodsItem.num }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="!loading && verifyList.length == 0" class="empty-wrap">暂无相关订单</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pager">
|
||||
<el-pagination
|
||||
background
|
||||
:pager-count="5"
|
||||
:total="total"
|
||||
prev-text="上一页"
|
||||
next-text="下一页"
|
||||
:current-page.sync="currentPage"
|
||||
:page-size.sync="pageSize"
|
||||
@size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange"
|
||||
hide-on-single-page
|
||||
></el-pagination>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from 'vuex';
|
||||
import {getVerifyType, verifyList} from '@/api/order/verification';
|
||||
|
||||
export default {
|
||||
name: 'verification_list',
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
orderType: '',
|
||||
loading: true,
|
||||
typeList: [],
|
||||
verifyList: [],
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
yes: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.getVerifyType();
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
layout: 'member',
|
||||
mounted() {
|
||||
let self = this;
|
||||
setTimeout(function () {
|
||||
self.yes = false
|
||||
}, 300)
|
||||
},
|
||||
methods: {
|
||||
handlePageSizeChange(size) {
|
||||
this.pageSize = size;
|
||||
this.refresh();
|
||||
},
|
||||
handleCurrentPageChange(page) {
|
||||
this.currentPage = page;
|
||||
this.refresh();
|
||||
},
|
||||
refresh() {
|
||||
this.loading = true;
|
||||
this.getVerifyType();
|
||||
},
|
||||
/**
|
||||
* 订单类型(自提/虚拟)
|
||||
*/
|
||||
handleClick(tab, event) {
|
||||
this.refresh();
|
||||
},
|
||||
getVerifyType() {
|
||||
getVerifyType().then(res => {
|
||||
if (res.code >= 0) {
|
||||
this.typeList = [];
|
||||
this.verifyList = [];
|
||||
|
||||
Object.keys(res.data).forEach(key => {
|
||||
this.typeList.push({
|
||||
type: key,
|
||||
name: res.data[key].name
|
||||
});
|
||||
});
|
||||
|
||||
if (this.orderType == 0) {
|
||||
for (let i = 0; i < this.typeList.length; i++) {
|
||||
if (i == 0) {
|
||||
this.orderType = this.typeList[i].type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.getVerifyList(this.orderType);
|
||||
}
|
||||
})
|
||||
},
|
||||
/**
|
||||
* 获取核销记录
|
||||
*/
|
||||
getVerifyList(type) {
|
||||
verifyList({
|
||||
verify_type: type,
|
||||
page: this.currentPage,
|
||||
page_size: this.pageSize
|
||||
}).then(res => {
|
||||
this.verifyList = res.data.list;
|
||||
this.total = res.data.count;
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message);
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
imageError(orderIndex, goodsIndex) {
|
||||
this.verifyList[orderIndex].item_array[goodsIndex].img = this.defaultGoodsImage;
|
||||
},
|
||||
toVerifyDetail(code) {
|
||||
this.$router.push({path: '/order/verification_detail', query: {code: code}});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.box {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.null-page {
|
||||
width: 100%;
|
||||
height: 730px;
|
||||
background-color: #FFFFFF;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.order-list {
|
||||
nav {
|
||||
overflow: hidden;
|
||||
padding: 10px 0;
|
||||
background: #fff;
|
||||
margin-bottom: 10px;
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width: 10%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
.item {
|
||||
margin-bottom: 20px;
|
||||
border: 1px solid #eeeeee;
|
||||
border-top: 0;
|
||||
|
||||
.head {
|
||||
padding: 8px 10px;
|
||||
background: #f7f7f7;
|
||||
font-size: 12px;
|
||||
|
||||
.create-time {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
border-bottom: 1px solid #eeeeee;
|
||||
|
||||
a {
|
||||
margin: 0 10px 0 20px;
|
||||
}
|
||||
|
||||
.order-type {
|
||||
margin-left: 30px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ul {
|
||||
background-color: #fff;
|
||||
padding: 10px;
|
||||
overflow: hidden;
|
||||
|
||||
li {
|
||||
float: left;
|
||||
line-height: 60px;
|
||||
|
||||
&:nth-child(1) {
|
||||
width: 70%;
|
||||
line-height: inherit;
|
||||
|
||||
.img-wrap {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
float: left;
|
||||
margin-right: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.info-wrap {
|
||||
margin-left: 70px;
|
||||
|
||||
h5 {
|
||||
cursor: pointer;
|
||||
font-weight: normal;
|
||||
font-size: $ns-font-size-base;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
margin-right: 10px;
|
||||
display: inline-block;
|
||||
|
||||
&:hover {
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: $ns-font-size-sm;
|
||||
color: #9a9a9a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width: 10%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty-wrap {
|
||||
text-align: center;
|
||||
padding: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
851
addon/pc/source/os/pages/pay/index.vue
Executable file
851
addon/pc/source/os/pages/pay/index.vue
Executable file
@@ -0,0 +1,851 @@
|
||||
<template>
|
||||
<div class="pay-wrap" v-loading="loading">
|
||||
<div class="item-block">
|
||||
<div class="payment-detail">
|
||||
<div class="payment-media">
|
||||
<el-row>
|
||||
<el-col :span="4">
|
||||
<div class="media-left"><i class="el-icon-circle-check ns-text-color"></i></div>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="16">
|
||||
<div class="media-body">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<div class="payment-text">您的订单已提交成功,正在等待处理!</div>
|
||||
<div>
|
||||
<span>应付金额:</span>
|
||||
<span class="payment-money ns-text-color">¥{{ payInfo.pay_money }}元</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="12"></el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="4">
|
||||
<div class="media-right">
|
||||
<div class="el-button--text" @click="orderOpen ? (orderOpen = false) : (orderOpen = true)">
|
||||
订单信息
|
||||
<i :class="orderOpen ? 'rotate' : ''" class="el-icon-arrow-down"></i>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<div class="order-info" v-if="orderOpen">
|
||||
<el-row>
|
||||
<el-col :span="4" class="order-info-left"></el-col>
|
||||
<el-col :span="20">
|
||||
<div class="line"></div>
|
||||
<div class="order-item">
|
||||
<div class="item-label">交易单号:</div>
|
||||
<div class="item-value">{{ payInfo.out_trade_no }}</div>
|
||||
</div>
|
||||
<div class="order-item">
|
||||
<div class="item-label">订单内容:</div>
|
||||
<div class="item-value">{{ payInfo.pay_detail }}</div>
|
||||
</div>
|
||||
<div class="order-item">
|
||||
<div class="item-label">订单金额:</div>
|
||||
<div class="item-value">¥{{ payInfo.pay_money }}</div>
|
||||
</div>
|
||||
<div class="order-item">
|
||||
<div class="item-label">创建时间:</div>
|
||||
<div class="item-value">{{ $timeStampTurnTime(payInfo.create_time) }}</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item-block">
|
||||
<div class="block-text">支付方式</div>
|
||||
<div class="pay-type-list" v-if="payTypeList.length">
|
||||
<template v-for="(item, index) in payTypeList">
|
||||
<div class="pay-type-item" :key="index" v-if="item.type!='offlinepay'|| (item.type=='offlinepay'&&payInfo.event=='OrderPayNotify')" :class="{'active' : payIndex == index,'disable':type=='edit'&&item.type!='offlinepay'}" @click="payTypeChange(index)">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<div class="no-pay-type" v-else>
|
||||
<p>商家未配置支付方式</p>
|
||||
</div>
|
||||
<div class="offlinepay" v-if="payTypeList[payIndex].type==='offlinepay'">
|
||||
<template v-for="item in offlinepayConfig">
|
||||
<div class="offlinepay-item bank" v-if="item.key=='bank'" :key="item.key">
|
||||
<div class="title">
|
||||
银行卡
|
||||
<!-- {{item.key=='bank'?'银行卡':item.key=='wechat'?'微信支付':'支付宝支付'}} -->
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="item-label">银行名称:</div>
|
||||
<div class="item-value">{{ item.bank_name }}</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="item-label">账号名称:</div>
|
||||
<div class="item-value">{{ item.account_name }}</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="item-label">银行账号:</div>
|
||||
<div class="item-value">
|
||||
<span>{{ item.account_number }}</span>
|
||||
<span class="copy ns-text-color" @click="copy(item.account_number)">复制</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<div class="item-label">开户支行:</div>
|
||||
<div class="item-value">{{ item.branch_name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="offlinepay-item" v-else>
|
||||
<div class="title">
|
||||
{{item.key=='wechat'?'微信支付':'支付宝支付'}}
|
||||
</div>
|
||||
<div class="code">
|
||||
<div class="centent">
|
||||
<el-image :src="$util.img(item.payment_code)" :key="item.key" fit="cover" class="qrcode" />
|
||||
</div>
|
||||
<div class="bottom">
|
||||
{{ item.account_name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-block " v-if="payTypeList[payIndex].type==='offlinepay'">
|
||||
<div class="offlinepay-form">
|
||||
<div class="upload-wrap-title">
|
||||
<div class="title">上传支付凭证</div>
|
||||
<div class="title-tips">最多还可上传{{5 - offlinepayInfo.imgList.length }}张</div>
|
||||
</div>
|
||||
<div class="upload-wrap">
|
||||
<el-upload ref="upload" :class="{ 'ishide': hide}" :action="uploadActionUrl"
|
||||
:file-list="imgList"
|
||||
list-type="picture-card" :on-success="
|
||||
(file, fileList) => {
|
||||
return handleSuccess(file, fileList);
|
||||
}
|
||||
" :on-preview="handlePictureCardPreview" :on-remove="
|
||||
(file, fileList) => {
|
||||
return handleRemove(file, fileList);
|
||||
}
|
||||
" :on-exceed="handleExceed" multiple drag :limit="5">
|
||||
<i class="el-icon-plus"></i>
|
||||
</el-upload>
|
||||
<el-dialog :visible.sync="imgDialogVisible"><img width="100%" :src="dialogImageUrl" alt="" /></el-dialog>
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<el-input v-model="offlinepayInfo.desc" placeholder="请详细说明您的支付情况" type="textarea" class="remark" :maxlength="200"/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-block" v-if="payTypeList.length">
|
||||
<div class="order-submit">
|
||||
<el-button type="primary" class="el-button--primary" @click="pay">立即支付</el-button>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<el-dialog title="请确认支付是否完成" :visible.sync="dialogVisible" width="23%" top="30vh" class="confirm-pay-wrap">
|
||||
<div class="info-wrap">
|
||||
<i class="el-message-box__status el-icon-warning"></i>
|
||||
<span>完成支付前请根据您的情况点击下面的按钮</span>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="goIndex" size="small">返回首页</el-button>
|
||||
<el-button type="primary" @click="goOrderList" size="small">已完成支付</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 微信支付弹框 -->
|
||||
<el-dialog title="请用微信扫码支付" :visible.sync="openQrcode" width="300px" center>
|
||||
<div class="wechatpay-box"><img :src="payQrcode" /></div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getPayInfo,
|
||||
getPayType,
|
||||
checkPayStatus,
|
||||
pay,
|
||||
getOfflinepayConfig,
|
||||
offlinepay,
|
||||
getOfflinepayPayInfo
|
||||
} from '@/api/pay';
|
||||
import Config from '@/plugins/config';
|
||||
|
||||
export default {
|
||||
name: 'pay',
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
orderOpen: false,
|
||||
outTradeNo: '',
|
||||
payInfo: {
|
||||
pay_money: 0
|
||||
},
|
||||
payIndex: 0,
|
||||
payTypeList: [{
|
||||
name: '支付宝支付',
|
||||
icon: 'iconzhifubaozhifu-',
|
||||
type: 'alipay'
|
||||
},
|
||||
{
|
||||
name: '微信支付',
|
||||
icon: 'iconweixinzhifu',
|
||||
type: 'wechatpay'
|
||||
},
|
||||
{
|
||||
name: '线下支付',
|
||||
icon: '',
|
||||
type: 'offlinepay'
|
||||
}
|
||||
],
|
||||
payUrl: '',
|
||||
timer: null,
|
||||
payQrcode: '',
|
||||
openQrcode: false,
|
||||
loading: true,
|
||||
test: null,
|
||||
dialogVisible: false,
|
||||
offlinepayConfig: [],
|
||||
offlinepayInfo:{
|
||||
out_trade_no:'',
|
||||
imgs:'',
|
||||
imgList:[],
|
||||
desc:'',
|
||||
},
|
||||
type:'add',
|
||||
dialogImageUrl:'',
|
||||
imgDialogVisible:false,
|
||||
uploadActionUrl: Config.baseUrl + '/offlinepay/api/pay/uploadimg',
|
||||
hide:false,
|
||||
imgList:[],
|
||||
allRequestSuccess: 0,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
if (!this.$route.query.code) {
|
||||
this.$router.push({
|
||||
path: '/'
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.outTradeNo = this.$route.query.code;
|
||||
this.getPayType();
|
||||
this.getPayInfo();
|
||||
},
|
||||
watch: {
|
||||
allRequestSuccess(newValue, oldValue) {
|
||||
if ( newValue == 2 ) {
|
||||
if ( this.payInfo.pay_type == 'offlinepay' ) {
|
||||
this.payTypeList = [{icon: '', name: '线下支付', type: "offlinepay"}];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getPayInfo() {
|
||||
getPayInfo({
|
||||
out_trade_no: this.outTradeNo,
|
||||
forceLogin: true
|
||||
}).then(res => {
|
||||
const {
|
||||
code,
|
||||
message,
|
||||
data
|
||||
} = res;
|
||||
if (data) {
|
||||
this.payInfo = res.data;
|
||||
this.allRequestSuccess ++ ;
|
||||
if ( res.data.pay_type == 'offlinepay' ) {
|
||||
this.getOfflinepayPayInfoFn(this.outTradeNo);
|
||||
}
|
||||
}
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error({
|
||||
message: err.message,
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({
|
||||
path: '/member/order_list'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
getPayType() {
|
||||
getPayType({}).then(res => {
|
||||
const {
|
||||
code,
|
||||
message,
|
||||
data
|
||||
} = res;
|
||||
if (code >= 0) {
|
||||
if (res.data.pay_type == '') {
|
||||
this.payTypeList = [];
|
||||
} else {
|
||||
this.payTypeList = this.payTypeList.filter((val, key) => {
|
||||
return res.data.pay_type.indexOf(val.type) != -1
|
||||
});
|
||||
if(this.payTypeList.some(el=>el.type=='offlinepay')){
|
||||
this.getOfflinepayConfigFn()
|
||||
}
|
||||
}
|
||||
this.allRequestSuccess ++ ;
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
},
|
||||
//切换支付方式
|
||||
payTypeChange(index){
|
||||
if(this.type=='edit') return
|
||||
this.payIndex = index
|
||||
this.offlinepayInfo={
|
||||
out_trade_no:'',
|
||||
imgs:'',
|
||||
imgList:[],
|
||||
desc:'',
|
||||
}
|
||||
},
|
||||
//获取线下支付配置
|
||||
getOfflinepayConfigFn(){
|
||||
getOfflinepayConfig({}).then(res => {
|
||||
const {
|
||||
code,
|
||||
message,
|
||||
data
|
||||
} = res;
|
||||
if (code >= 0) {
|
||||
let config = data.value
|
||||
Object.keys(config).forEach(key=>{
|
||||
if(config[key].status=='1'){
|
||||
config[key].key = key
|
||||
this.offlinepayConfig.push(config[key])
|
||||
}
|
||||
});
|
||||
}
|
||||
}).catch(()=>{})
|
||||
},
|
||||
//复制银行账号
|
||||
copy(val){
|
||||
this.$copy(val)
|
||||
},
|
||||
//获取线下支付信息
|
||||
getOfflinepayPayInfoFn(out_trade_no){
|
||||
getOfflinepayPayInfo({out_trade_no}).then(res => {
|
||||
const {
|
||||
code,
|
||||
message,
|
||||
data
|
||||
} = res;
|
||||
if (code >= 0&&data) {
|
||||
this.type='edit'
|
||||
// this.payIndex = 2
|
||||
|
||||
this.offlinepayInfo = data
|
||||
this.offlinepayInfo.imgList = this.offlinepayInfo.imgs?this.offlinepayInfo.imgs.split(',').map(el=>{return {url:el}}):[]
|
||||
this.imgList = this.$util.deepClone(this.offlinepayInfo.imgList);
|
||||
this.$forceUpdate();
|
||||
}else{
|
||||
this.type = 'add'
|
||||
this.offlinepayInfo={
|
||||
out_trade_no,
|
||||
imgs:'',
|
||||
imgList:[],
|
||||
desc:'',
|
||||
}
|
||||
}
|
||||
}).catch(()=>{})
|
||||
},
|
||||
handleSuccess(file, fileList) {
|
||||
// 上传成功
|
||||
this.offlinepayInfo.imgList = this.offlinepayInfo.imgList.concat({url:file.data.pic_path});
|
||||
this.offlinepayInfo.imgs = this.offlinepayInfo.imgList.map(el=>el.url).toString()
|
||||
if ( this.offlinepayInfo.imgList.length >= 5) {
|
||||
this.hide = true;
|
||||
}
|
||||
},
|
||||
handleRemove(file, fileList) {
|
||||
this.offlinepayInfo.imgList = fileList.map(el=>{return {url:el.url}});
|
||||
|
||||
},
|
||||
handlePictureCardPreview(file) {
|
||||
// 点开大图
|
||||
this.dialogImageUrl = file.url;
|
||||
this.imgDialogVisible = true;
|
||||
},
|
||||
handleExceed(file, fileList) {
|
||||
// 图片数量大于5
|
||||
this.$message.warning('上传图片最大数量为5张');
|
||||
},
|
||||
checkPayStatus() {
|
||||
this.timer = setInterval(() => {
|
||||
checkPayStatus({
|
||||
out_trade_no: this.outTradeNo
|
||||
}).then(res => {
|
||||
const {
|
||||
code,
|
||||
message,
|
||||
data
|
||||
} = res;
|
||||
if (code >= 0) {
|
||||
if (code == 0) {
|
||||
if (data.pay_status == 2) {
|
||||
clearInterval(this.timer);
|
||||
this.dialogVisible = false;
|
||||
this.$router.push({
|
||||
path: '/pay/result?code=' + this.payInfo.out_trade_no
|
||||
});
|
||||
}
|
||||
} else {
|
||||
clearInterval(this.timer);
|
||||
}
|
||||
}
|
||||
}).catch(err => {
|
||||
clearInterval(this.timer);
|
||||
this.$router.push({
|
||||
path: '/'
|
||||
});
|
||||
});
|
||||
}, 2000);
|
||||
},
|
||||
pay() {
|
||||
var payType = this.payTypeList[this.payIndex];
|
||||
if (!payType) return;
|
||||
|
||||
let return_url = encodeURIComponent(Config.webDomain + '/pay/result?code=' + this.outTradeNo);
|
||||
if(payType.type!='offlinepay'){
|
||||
pay({
|
||||
out_trade_no: this.payInfo.out_trade_no,
|
||||
pay_type: payType.type,
|
||||
app_type: 'pc',
|
||||
return_url
|
||||
}).then(res => {
|
||||
const {
|
||||
code,
|
||||
message,
|
||||
data
|
||||
} = res;
|
||||
if (code >= 0) {
|
||||
this.checkPayStatus();
|
||||
switch (payType.type) {
|
||||
case 'alipay':
|
||||
this.payUrl = res.data.data;
|
||||
window.open(this.payUrl)
|
||||
this.open();
|
||||
break;
|
||||
case 'wechatpay':
|
||||
this.payQrcode = res.data.qrcode;
|
||||
this.openQrcode = true;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
this.$message({
|
||||
message: message,
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
}).catch(err => {
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
}else{
|
||||
if(!this.offlinepayInfo.imgList.length){
|
||||
this.$message({
|
||||
message: '请至少上传一张凭证',
|
||||
type: 'warning'
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.offlinepayInfo.out_trade_no = this.outTradeNo;
|
||||
offlinepay(this.offlinepayInfo).then(res => {
|
||||
const {
|
||||
code,
|
||||
message,
|
||||
data
|
||||
} = res;
|
||||
if (code >= 0) {
|
||||
let payPath = {
|
||||
1: '/member/order_detail',
|
||||
2: '/member/order_detail_pickup',
|
||||
3: '/member/order_detail_local_delivery',
|
||||
4: '/member/order_detail_virtual',
|
||||
}
|
||||
this.$router.push({
|
||||
path: payPath[this.payInfo.order_type],
|
||||
query: {
|
||||
order_id: this.payInfo.order_id
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
this.$message({
|
||||
message: message,
|
||||
type: 'warning'
|
||||
});
|
||||
}
|
||||
}).catch(()=>{})
|
||||
}
|
||||
|
||||
},
|
||||
open() {
|
||||
this.dialogVisible = true;
|
||||
},
|
||||
goIndex() {
|
||||
clearInterval(this.timer);
|
||||
this.dialogVisible = false;
|
||||
this.$router.push({
|
||||
path: '/'
|
||||
});
|
||||
},
|
||||
goOrderList() {
|
||||
clearInterval(this.timer);
|
||||
this.dialogVisible = false;
|
||||
this.$router.push({
|
||||
path: '/member/order_list'
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.pay-wrap {
|
||||
width: 1210px;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
.clear {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.item-block {
|
||||
padding:20px;
|
||||
margin: 10px 0;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
background: #ffffff;
|
||||
|
||||
.block-text {
|
||||
border-color: #eeeeee;
|
||||
color: $ns-text-color-black;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
border-bottom: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.media-left {
|
||||
text-align: center;
|
||||
i {
|
||||
font-size: 65px;
|
||||
}
|
||||
}
|
||||
|
||||
.payment-detail {
|
||||
padding: 30px 0;
|
||||
transition: 2s;
|
||||
}
|
||||
|
||||
.media-right {
|
||||
text-align: center;
|
||||
line-height: 65px;
|
||||
cursor: pointer;
|
||||
|
||||
i.rotate {
|
||||
transform: rotate(180deg);
|
||||
transition: 0.3s;
|
||||
}
|
||||
}
|
||||
|
||||
.payment-text {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.payment-time {
|
||||
font-size: 12px;
|
||||
line-height: 65px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
//支付方式
|
||||
.order-submit {
|
||||
float: right;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.pay-type-list {
|
||||
// padding: 20px 0;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.no-pay-type {
|
||||
padding: 30px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pay-type-item {
|
||||
display: inline-block;
|
||||
border: 2px solid #eeeeee;
|
||||
padding: 5px 20px;
|
||||
margin-right: 20px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.pay-type-item.active {
|
||||
border-color: $base-color;
|
||||
}
|
||||
.pay-type-item.disable{
|
||||
// pointer-events: none;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.mobile-wrap {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.order-info {
|
||||
.order-item {
|
||||
padding: 1px 0;
|
||||
|
||||
.item-label {
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.item-value {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.line {
|
||||
width: 100%;
|
||||
height: 1px;
|
||||
background: #f2f2f2;
|
||||
margin: 20px 0 10px 0;
|
||||
}
|
||||
|
||||
.order-info-left {
|
||||
height: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.wechatpay-box {
|
||||
text-align: center;
|
||||
|
||||
img {
|
||||
width: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
.confirm-pay-wrap {
|
||||
.el-dialog__body {
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
.info-wrap {
|
||||
i {
|
||||
position: initial;
|
||||
vertical-align: middle;
|
||||
transform: initial;
|
||||
}
|
||||
|
||||
span {
|
||||
vertical-align: middle;
|
||||
padding: 0 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="scss">
|
||||
.confirm-pay-wrap {
|
||||
.el-dialog__body {
|
||||
padding: 10px 15px;
|
||||
}
|
||||
|
||||
.el-dialog__footer {
|
||||
padding-top: 0;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
}
|
||||
.offlinepay{
|
||||
padding-top: 30px;
|
||||
margin-top: 20px;
|
||||
padding-bottom: 10px;
|
||||
border-top:1px solid #E2E6F0;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
.offlinepay-item{
|
||||
width: 380px;
|
||||
height: 305px;
|
||||
padding: 20px;
|
||||
margin-right: 15px;
|
||||
background: linear-gradient( 180deg, #F8F9FD 0%, #FFFFFF 21%);
|
||||
border-radius: 16px 16px 16px 16px;
|
||||
border: 1px solid #EFF2FF;
|
||||
box-sizing: border-box;
|
||||
&:last-child{
|
||||
margin-right: 0;
|
||||
}
|
||||
.title{
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
font-weight: 500;
|
||||
font-size: 18px;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
&.bank{
|
||||
.title{
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.item{
|
||||
display: flex;
|
||||
height: 22px;
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
margin-bottom: 20px;
|
||||
.item-label{
|
||||
color: #626779;
|
||||
}
|
||||
.copy{
|
||||
margin-left: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
.code{
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
.centent{
|
||||
border-radius: 8px;
|
||||
border: 1px solid #DEDEDE;
|
||||
padding: 14px;
|
||||
width: 180px;
|
||||
height: 180px;
|
||||
box-sizing: border-box;
|
||||
|
||||
.qrcode{
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
img{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
.bottom{
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
.offlinepay-form{
|
||||
.upload-wrap-title{
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
margin-bottom: 16px;
|
||||
.title{
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
}
|
||||
.title-tips{
|
||||
height: 17px;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
color: #626779;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
.upload-wrap{
|
||||
height: 100px;
|
||||
>div:first-child{
|
||||
height: 100px;
|
||||
}
|
||||
.tips{
|
||||
margin-top: 5px;
|
||||
}
|
||||
}
|
||||
.el-upload--picture-card {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.el-upload--picture-card,
|
||||
.el-upload-list--picture-card .el-upload-list__item {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
line-height: 80px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.el-upload-list--picture-card .el-upload-list__item-thumbnail {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.el-upload-list__item.is-success .el-upload-list__item-status-label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.ishide .el-upload--picture-card {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.upload-wrap .el-upload-dragger {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.el-dialog {
|
||||
.el-dialog__body {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
.bottom{
|
||||
margin-top: 20px;
|
||||
padding-top: 16px;
|
||||
font-size: 14px !important;
|
||||
border-top: 1px dashed #E2E6F0;
|
||||
.remark{
|
||||
.el-textarea__inner{
|
||||
border-width: 0;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
</style>
|
||||
<style lang="sss" scoped>
|
||||
|
||||
</style>
|
||||
142
addon/pc/source/os/pages/pay/result.vue
Executable file
142
addon/pc/source/os/pages/pay/result.vue
Executable file
@@ -0,0 +1,142 @@
|
||||
<template>
|
||||
<div class="pay-wrap" v-loading="fullscreenLoading">
|
||||
<div class="pay">
|
||||
<div class="pay-icon">
|
||||
<i class="ns-text-color" :class="payInfo.pay_status ? 'el-icon-circle-check' : 'el-icon-circle-close'"></i>
|
||||
</div>
|
||||
<div class="pay-text">{{ payInfo.pay_status ? '支付成功' : '支付失败' }}</div>
|
||||
<div class="pay-money">支付金额:¥{{ payInfo.pay_money }}</div>
|
||||
<div class="pay-footer">
|
||||
<router-link to="/member">
|
||||
<el-button type="primary">会员中心</el-button>
|
||||
</router-link>
|
||||
<router-link to="/" class="pay-button">
|
||||
<el-button>回到首页</el-button>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
getPayInfo
|
||||
} from '@/api/pay';
|
||||
import {
|
||||
memberInfo
|
||||
} from '@/api/member/index.js'
|
||||
|
||||
export default {
|
||||
name: 'pay_result',
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
payInfo: {},
|
||||
outTradeNo: '',
|
||||
fullscreenLoading: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
if (!this.$route.query.code) {
|
||||
this.$router.push({
|
||||
path: '/'
|
||||
});
|
||||
return;
|
||||
}
|
||||
this.outTradeNo = this.$route.query.code;
|
||||
this.getPayInfo();
|
||||
this.memberInfo()
|
||||
},
|
||||
methods: {
|
||||
getPayInfo() {
|
||||
getPayInfo({
|
||||
out_trade_no: this.outTradeNo,
|
||||
forceLogin: true
|
||||
}).then(res => {
|
||||
const {
|
||||
code,
|
||||
message,
|
||||
data
|
||||
} = res;
|
||||
if (code >= 0 && data) {
|
||||
this.payInfo = res.data;
|
||||
} else {
|
||||
this.$message({
|
||||
message: '未获取到支付信息',
|
||||
type: 'warning',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({
|
||||
path: '/member/order_list'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
this.fullscreenLoading = false;
|
||||
}).catch(err => {
|
||||
this.fullscreenLoading = false;
|
||||
this.$message.error({
|
||||
message: err.message,
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$router.push({
|
||||
path: '/member/order_list'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
memberInfo() {
|
||||
memberInfo().then(res => {
|
||||
const {
|
||||
data
|
||||
} = res
|
||||
this.$store.commit("member/SET_MEMBER", data)
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.pay-wrap {
|
||||
width: 1210px;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
.pay {
|
||||
padding: 40px 15px;
|
||||
margin: 10px 0;
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
background: #ffffff;
|
||||
|
||||
.pay-icon {
|
||||
text-align: center;
|
||||
|
||||
i {
|
||||
font-size: 65px;
|
||||
}
|
||||
}
|
||||
|
||||
.pay-text {
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.pay-money {
|
||||
text-align: center;
|
||||
color: $base-color;
|
||||
font-size: $ns-font-size-lg;
|
||||
}
|
||||
|
||||
.pay-footer {
|
||||
text-align: center;
|
||||
margin-top: 30px;
|
||||
|
||||
.pay-button {
|
||||
margin-left: 15px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
282
addon/pc/source/os/pages/promotion/combo/_id/index.vue
Executable file
282
addon/pc/source/os/pages/promotion/combo/_id/index.vue
Executable file
@@ -0,0 +1,282 @@
|
||||
<template>
|
||||
<div class="combo-detail" v-loading="loading">
|
||||
<div class="combo-title">
|
||||
<div class="title-goods">商品信息</div>
|
||||
<div class="title-orther">
|
||||
<div class="title-price">价格</div>
|
||||
<div class="title-num">数量</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item-wrap" v-for="(item, index) in goodsList.bundling_goods" :key="item.sku_item">
|
||||
<div class="item">
|
||||
<div class="info">
|
||||
<div class="img-wrap" @click="$util.pushToTab({ path: '/sku/' + item.sku_id })">
|
||||
<img :src="$img(item.sku_image, { size: 'mid' })" @error="imageError(index)" />
|
||||
</div>
|
||||
<div class="name">
|
||||
{{ item.sku_name }}
|
||||
<p v-if="num > item.stock">库存不足,剩余:{{ item.stock }}件</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="price-wrap">
|
||||
<div class="price">{{ item.price }}</div>
|
||||
<div class="num">x1</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="combo-bottom">
|
||||
<div class="num">
|
||||
<p>购买数量:</p>
|
||||
<el-input v-model="num" type="number" @change="changeNum(false)"></el-input>
|
||||
</div>
|
||||
<div class="bottom-right">
|
||||
<div class="price">
|
||||
<div class="save-price">为您节省:¥{{ saveThePrice }}</div>
|
||||
<div class="old-price">
|
||||
套餐价:
|
||||
<p>¥{{ packagePrice }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<el-button type="primary" :disabled="isDisabled ? true : false" @click="comboBuy">立即购买</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
detail
|
||||
} from '@/api/combo';
|
||||
import {
|
||||
mapGetters
|
||||
} from 'vuex';
|
||||
|
||||
export default {
|
||||
name: 'combo',
|
||||
components: {},
|
||||
data: () => {
|
||||
return {
|
||||
id: 0,
|
||||
goodsList: [],
|
||||
num: 1,
|
||||
packagePrice: 0, //套餐价
|
||||
saveThePrice: 0, //节省价格
|
||||
isDisabled: false, //按钮失效
|
||||
loading: true
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.id = this.$route.params.id;
|
||||
this.getDetail();
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage'])
|
||||
},
|
||||
watch: {
|
||||
$route(curr) {
|
||||
this.id = curr.query.id;
|
||||
this.getDetail();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getDetail() {
|
||||
detail({
|
||||
bl_id: this.id
|
||||
}).then(res => {
|
||||
if (res.data) {
|
||||
this.goodsList = res.data;
|
||||
this.changeNum();
|
||||
}
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
},
|
||||
changeNum(flag, callback) {
|
||||
setTimeout(() => {
|
||||
var disabledCount = 0;
|
||||
|
||||
// 防止空
|
||||
if (this.num.length == 0) {
|
||||
this.num = 1;
|
||||
// disabledCount++;
|
||||
}
|
||||
|
||||
// 防止输入0和负数、非法输入
|
||||
if (this.num <= 0 || isNaN(this.num)) {
|
||||
this.num = 1;
|
||||
}
|
||||
|
||||
this.num = parseInt(this.num);
|
||||
|
||||
var price = 0;
|
||||
for (var i = 0; i < this.goodsList.bundling_goods.length; i++) {
|
||||
price += parseFloat(this.goodsList.bundling_goods[i].price);
|
||||
//检测库存
|
||||
if (this.goodsList.bundling_goods[i].stock < this.num) disabledCount++;
|
||||
}
|
||||
this.isDisabled = disabledCount > 0;
|
||||
this.saveThePrice = ((price - this.goodsList.bl_price) * this.num).toFixed(2);
|
||||
this.packagePrice = (this.goodsList.bl_price * this.num).toFixed(2);
|
||||
if (callback) callback();
|
||||
}, 0);
|
||||
},
|
||||
comboBuy() {
|
||||
if (this.isDisabled) return;
|
||||
var data = {
|
||||
bl_id: this.id,
|
||||
num: this.num
|
||||
};
|
||||
|
||||
this.$store.dispatch('order/setComboOrderCreateData', data);
|
||||
|
||||
this.$router.push({
|
||||
path: '/promotion/combo/payment'
|
||||
});
|
||||
},
|
||||
imageError(index) {
|
||||
this.goodsList.bundling_goods[index].sku_image = this.defaultGoodsImage;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.combo-detail {
|
||||
width: 1210px;
|
||||
margin: 20px auto;
|
||||
|
||||
.combo-title {
|
||||
display: flex;
|
||||
background: #ffffff;
|
||||
padding: 10px;
|
||||
margin-bottom: 20px;
|
||||
justify-content: space-between;
|
||||
|
||||
.title-orther {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 150px;
|
||||
|
||||
.title-price {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.title-num {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item-wrap {
|
||||
padding: 0 10px 10px 10px;
|
||||
background: #ffffff;
|
||||
|
||||
.item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding-top: 10px;
|
||||
|
||||
.info {
|
||||
display: flex;
|
||||
|
||||
.img-wrap {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.name {
|
||||
margin-left: 5px;
|
||||
font-size: $ns-font-size-base;
|
||||
width: 500px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
position: relative;
|
||||
|
||||
p {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
color: $base-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.price-wrap {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
width: 150px;
|
||||
|
||||
.price {
|
||||
margin-right: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.num {
|
||||
padding-right: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.combo-bottom {
|
||||
background: #ffffff;
|
||||
padding: 10px;
|
||||
margin: 20px 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
.num {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
input {
|
||||
border: none;
|
||||
}
|
||||
|
||||
p {
|
||||
width: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-right {
|
||||
display: flex;
|
||||
|
||||
.price {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: 50px;
|
||||
|
||||
.save-price {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.old-price {
|
||||
margin-right: 10px;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
|
||||
p {
|
||||
color: $base-color;
|
||||
font-size: $ns-font-size-lg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
327
addon/pc/source/os/pages/promotion/combo/payment/index.vue
Executable file
327
addon/pc/source/os/pages/promotion/combo/payment/index.vue
Executable file
@@ -0,0 +1,327 @@
|
||||
<template>
|
||||
<div class="payment-wrap" v-loading="fullscreenLoading">
|
||||
|
||||
<!--购买虚拟类商品需填写您的手机号-->
|
||||
<div class="item-block" v-if="orderPaymentData.is_virtual == 1">
|
||||
<div class="block-text">购买虚拟类商品需填写您的手机号,以方便商家与您联系</div>
|
||||
|
||||
<el-form ref="form" size="mini" class="mobile-wrap" label-width="80px">
|
||||
<el-form-item label="手机号码">
|
||||
<el-input placeholder="请输入您的手机号码" maxlength="11" v-model="orderCreateData.member_address.mobile" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<!--收货地址-->
|
||||
<div class="item-block" v-if="orderPaymentData.is_virtual == 0">
|
||||
<div class="block-text">收货地址</div>
|
||||
|
||||
<div class="address-list">
|
||||
<div class="address-item" @click="addAddressShow">
|
||||
<div class="add-address">
|
||||
<i class="el-icon-circle-plus-outline"></i>
|
||||
添加收货地址
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="address-item" v-for="(item, key) in memberAddress" :key="item.id" :class="addressId == item.id ? 'active' : ''" v-if="key < 3 || (addressShow && key >= 3)">
|
||||
<div class="address-info">
|
||||
<div class="options">
|
||||
<div @click="editAddress(item.id)">编辑</div>
|
||||
<template v-if="item.is_default == 0">
|
||||
<el-popconfirm title="确定要删除该地址吗?" @onConfirm="deleteMemberAddress(item.id)">
|
||||
<div slot="reference">删除</div>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</div>
|
||||
<div class="address-name">{{ item.name }}</div>
|
||||
<div class="address-mobile" @click="setMemberAddress(item.id)">{{ item.mobile }}</div>
|
||||
<div class="address-desc" @click="setMemberAddress(item.id)">{{ item.full_address }} {{ item.address }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="memberAddress.length > 3 && !addressShow" @click="addressShow = true" class="el-button--text address-open">
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
更多收货地址
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--收货地址添加-->
|
||||
<el-dialog :title="addressForm.id == 0 ? '添加收货地址' : '编辑收货地址'" :visible.sync="dialogVisible" width="32%">
|
||||
<el-form ref="form" :rules="addressRules" :model="addressForm" label-width="80px">
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input v-model="addressForm.name" placeholder="收货人姓名" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="手机" prop="mobile">
|
||||
<el-input v-model="addressForm.mobile" maxlength="11" placeholder="收货人手机号" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="电话">
|
||||
<el-input v-model="addressForm.telephone" placeholder="收货人固定电话(选填)" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item class="area" label="地区" prop="area">
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="7">
|
||||
<el-select prop="province" ref="province" v-model="addressForm.province_id" @change="getAddress(1)" placeholder="请选择省">
|
||||
<el-option label="请选择省" value="0"></el-option>
|
||||
<el-option v-for="item in pickerValueArray" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-select ref="city" prop="city" v-model="addressForm.city_id" @change="getAddress(2)" placeholder="请选择市">
|
||||
<el-option label="请选择市" value="0"></el-option>
|
||||
<el-option v-for="item in cityArr" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-select ref="district" prop="district" v-model="addressForm.district_id" placeholder="请选择区/县">
|
||||
<el-option label="请选择区/县" value="0"></el-option>
|
||||
<el-option v-for="item in districtArr" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="详细地址" prop="address">
|
||||
<el-input v-model="addressForm.address" placeholder="定位小区、街道、写字楼" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="addmemberAddress('form')">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<!--使用余额-->
|
||||
<div class="item-block" v-if="orderPaymentData.member_account.balance_total > 0 && balance_show == 1">
|
||||
<div class="block-text">是否使用余额</div>
|
||||
<div class="pay-type-list">
|
||||
<div class="pay-type-item" :class="orderCreateData.is_balance ? '' : 'active'" @click="useBalance(0)">不使用余额
|
||||
</div>
|
||||
<div class="pay-type-item" :class="orderCreateData.is_balance ? 'active' : ''" @click="useBalance(1)">使用余额</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 支付密码 -->
|
||||
<el-dialog title="使用余额" :visible.sync="dialogpay" width="350px">
|
||||
<template v-if="orderPaymentData.member_account.is_pay_password == 0">
|
||||
<p>为了您的账户安全,请您先设置的支付密码</p>
|
||||
<p>可到"会员中心","账号安全","支付密码"中设置</p>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button size="small" @click="dialogpay = false">暂不设置</el-button>
|
||||
<el-button size="small" type="primary" @click="setPayPassword">立即设置</el-button>
|
||||
</span>
|
||||
</template>
|
||||
<el-form v-else status-icon ref="ruleForm" label-width="100px">
|
||||
<el-form-item label="支付密码" class="pay-password-item">
|
||||
<!--添加一个不可见的input,欺骗浏览器自动填充-->
|
||||
<el-input type="password" class="pay-password hide-password" :maxlength="6"></el-input>
|
||||
<el-input type="password" class="pay-password" :maxlength="6" v-model="password" @input="input"></el-input>
|
||||
</el-form-item>
|
||||
<p class="ns-text-color forget-password" @click="setPayPassword">忘记密码</p>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 配送方式 -->
|
||||
<div class="item-block padd-bom-20" v-if="orderPaymentData.delivery.express_type.length > 0">
|
||||
<div class="block-text">
|
||||
<span>配送方式</span>
|
||||
<span class="distribution" v-if="orderCreateData.delivery.delivery_type == 'store'">{{ orderCreateData.delivery.store_name }}</span>
|
||||
</div>
|
||||
<div class="pay-type-item" v-for="(item, index) in orderPaymentData.delivery.express_type" :key="index" @click="selectDeliveryType(item)" :class="item.name == orderCreateData.delivery.delivery_type ? 'active' : ''">
|
||||
{{ item.title }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--配送方式 门店 -->
|
||||
<el-dialog title="选择门店" :visible.sync="dialogStore" width="50%">
|
||||
<el-table ref="singleTable" :data="storeList" highlight-current-row @row-click="selectStore" class="cursor-pointer">
|
||||
<el-table-column label="" width="55">
|
||||
<template slot-scope="scope">
|
||||
<el-radio v-model="storeRadio" :label="scope.row"><i></i></el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="store_name" label="名称" width="160"></el-table-column>
|
||||
<el-table-column prop="store_address" label="地址"></el-table-column>
|
||||
<el-table-column prop="open_date" label="营业时间"></el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<div class="item-block" v-if="orderPaymentData.invoice && orderPaymentData.invoice.invoice_status == 1">
|
||||
<div class="block-text">发票信息</div>
|
||||
<div class="pay-type-list">
|
||||
<div class="pay-type-item" :class="orderCreateData.is_invoice == 0 ? 'active' : ''" @click="changeIsInvoice">
|
||||
无需发票
|
||||
</div>
|
||||
<div class="pay-type-item" :class="orderCreateData.is_invoice == 1 ? 'active' : ''" @click="changeIsInvoice">
|
||||
需要发票
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<div class="invoice-information" v-if="orderCreateData.is_invoice == 1">
|
||||
<div class="invoice-title">
|
||||
<div class="invoice-type-box invoice-title-box">
|
||||
<span class="invoice-name">发票类型:</span>
|
||||
<label class="invoice-to-type">
|
||||
<i class="invoice-i-input" :class="orderCreateData.invoice_type == 1 ? 'active' : ''" @click="clickType(1)"></i>
|
||||
<span>纸质</span>
|
||||
</label>
|
||||
<label class="invoice-to-type">
|
||||
<i class="invoice-i-input" :class="orderCreateData.invoice_type == 2 ? 'active' : ''" @click="clickType(2)"></i>
|
||||
<span>电子</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="invoice-type-box invoice-title-box">
|
||||
<span class="invoice-name">抬头类型:</span>
|
||||
<label class="invoice-to-type">
|
||||
<i class="invoice-i-input" :class="orderCreateData.invoice_title_type == 1 ? 'active' : ''" @click="clickTitleType(1)"></i>
|
||||
<span>个人</span>
|
||||
</label>
|
||||
<label class="invoice-to-type">
|
||||
<i class="invoice-i-input" :class="orderCreateData.invoice_title_type == 2 ? 'active' : ''" @click="clickTitleType(2)"></i>
|
||||
<span>企业</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="invoice-type-box">
|
||||
<span class="invoice-name">发票信息:</span>
|
||||
<div class="invoice-box-form">
|
||||
<input type="text" placeholder="请填写抬头名称" v-model.trim="orderCreateData.invoice_title" />
|
||||
<input type="text" placeholder="请填写纳税人识别号" v-model.trim="orderCreateData.taxpayer_number" v-if="orderCreateData.invoice_title_type == 2" />
|
||||
<input type="text" placeholder="请填写邮寄地址" v-model.trim="orderCreateData.invoice_full_address" v-show="orderCreateData.invoice_type == 1" />
|
||||
<input type="text" placeholder="请填写邮箱" v-model.trim="orderCreateData.invoice_email" v-show="orderCreateData.invoice_type == 2" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="invoice-condition">
|
||||
<span class="invoice-name">发票内容:</span>
|
||||
<div class="invoice-box-form">
|
||||
<span class="option-item" :key="index" v-for="(item, index) in orderPaymentData.invoice.invoice_content_array" @click="changeInvoiceContent(item)" :class="{ 'color-base-bg active': item == orderCreateData.invoice_content }">
|
||||
{{ item }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="invoice-tops">发票内容将以根据税法调整,具体请以展示为准,发票内容显示详细商品名 称及价格信息</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--商品信息-->
|
||||
<div class="item-block">
|
||||
<div class="goods-list">
|
||||
<table>
|
||||
<tr>
|
||||
<td width="70%">商品</td>
|
||||
<td width="15%">价格</td>
|
||||
<td width="15%">数量</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="item-block" v-if="calculateData">
|
||||
<div class="goods-list">
|
||||
<table>
|
||||
<tr v-for="(goodsItem, goodsIndex) in calculateData.goods_list" :key="goodsIndex">
|
||||
<td width="50%">
|
||||
<div class="goods-info">
|
||||
<div class="goods-info-left">
|
||||
<router-link :to="{ path: '/sku/' + goodsItem.sku_id }" target="_blank">
|
||||
<img class="goods-img" :src="$img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" />
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="goods-info-right">
|
||||
<router-link :to="{ path: '/sku/' + goodsItem.sku_id }" target="_blank">
|
||||
<div class="goods-name">{{ goodsItem.goods_name }}</div>
|
||||
</router-link>
|
||||
<!-- 规格 -->
|
||||
<div class="goods-spec" v-if="goodsItem.sku_spec_format">
|
||||
<span v-for="(x, i) in goodsItem.sku_spec_format" :key="i">{{ x.spec_value_name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td width="12.5%" class="goods-price">¥{{ goodsItem.price }}</td>
|
||||
<td width="12.5%" class="goods-num">{{ goodsItem.num }}</td>
|
||||
<td width="12.5%" class="goods-money">¥{{ (goodsItem.price * goodsItem.num).toFixed(2) }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--活动优惠-->
|
||||
<div class="item-block" v-if="promotionInfo">
|
||||
<div class="block-text">{{ promotionInfo.title }}</div>
|
||||
<div class="order-cell platform-coupon">
|
||||
<div class="box ns-text-color" v-html="promotionInfo.content"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 买家留言 -->
|
||||
<div class="item-block padd-bom-10">
|
||||
<div class="block-text">买家留言:</div>
|
||||
<el-input rows="3" type="textarea" placeholder="留言前建议先与商家协调一致" v-model="orderCreateData.buyer_message" class="buyer-message" @input="textarea" maxlength="140" show-word-limit resize="none" />
|
||||
</div>
|
||||
|
||||
<!-- 总计 -->
|
||||
<div class="item-block" v-if="calculateData">
|
||||
<div class="order-statistics">
|
||||
<table>
|
||||
<tr>
|
||||
<td align="right">商品金额:</td>
|
||||
<td align="left">¥{{ calculateData.goods_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.is_virtual == 0 && calculateData.delivery_money > 0">
|
||||
<td align="right">运费:</td>
|
||||
<td align="left">¥{{ calculateData.delivery_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.invoice_money > 0">
|
||||
<td align="right">发票税费<span class="ns-text-color">({{ calculateData.invoice.invoice_rate }}%)</span>:</td>
|
||||
<td align="left">¥{{ calculateData.invoice_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.invoice_delivery_money > 0">
|
||||
<td align="right">发票邮寄费:</td>
|
||||
<td align="left">¥{{ calculateData.invoice_delivery_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.balance_money > 0">
|
||||
<td align="right">使用余额:</td>
|
||||
<td align="left">¥{{ calculateData.balance_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<!--结算-->
|
||||
<div class="item-block" v-if="calculateData">
|
||||
<div class="order-submit">
|
||||
<div class="order-money">
|
||||
共{{ calculateData.goods_num }}件,应付金额:
|
||||
<div class="ns-text-color">¥{{ calculateData.pay_money | moneyFormat }}</div>
|
||||
</div>
|
||||
<el-button type="primary" class="el-button--primary" @click="orderCreate">订单结算</el-button>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import detail from '@/assets/js/promotion/payment_combo.js';
|
||||
|
||||
export default {
|
||||
name: 'combo_payment',
|
||||
mixins: [detail]
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/css/promotion/payment_combo.scss';
|
||||
</style>
|
||||
347
addon/pc/source/os/pages/promotion/groupbuy/_id/index.vue
Executable file
347
addon/pc/source/os/pages/promotion/groupbuy/_id/index.vue
Executable file
@@ -0,0 +1,347 @@
|
||||
<template>
|
||||
<div class="goods-detail-wrap">
|
||||
<div class="detail-nav-wrap" v-if="categoryNameArr">
|
||||
<div class="detail-nav" v-if="categoryNameArr.length">
|
||||
<template v-for="(item,index) in categoryNameArr" :keys="index">
|
||||
<router-link :to="{ path: '/goods/list', query: { category_id: item.category_id, level: index } }">
|
||||
{{item.name}}
|
||||
</router-link>
|
||||
<span class="iconfont icon-arrow-right"></span>
|
||||
</template>
|
||||
<span class="goods-name">{{goodsSkuDetail.goods_name}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-main">
|
||||
<div class="goods-detail">
|
||||
<div class="preview-wrap">
|
||||
<div class="video-player-wrap" :class="{ show: switchMedia == 'video' }" v-if="goodsSkuDetail.video_url != ''">
|
||||
<video-player v-if="goodsSkuDetail.video_url != ''" ref="videoPlayer" :playsinline="true"
|
||||
:options="playerOptions" @play="onPlayerPlay($event)" @pause="onPlayerPause($event)"
|
||||
@ended="onPlayerEnded($event)" @waiting="onPlayerWaiting($event)"
|
||||
@playing="onPlayerPlaying($event)"
|
||||
@loadeddata="onPlayerLoadeddata($event)" @timeupdate="onPlayerTimeupdate($event)"
|
||||
@canplay="onPlayerCanplay($event)" @canplaythrough="onPlayerCanplaythrough($event)"
|
||||
@statechanged="playerStateChanged($event)" @ready="playerReadied"></video-player>
|
||||
|
||||
<div class="media-mode" v-if="goodsSkuDetail.video_url != ''">
|
||||
<span :class="{ 'ns-bg-color': switchMedia == 'video' }" @click="switchMedia = 'video'">视频</span>
|
||||
<span :class="{ 'ns-bg-color': switchMedia == 'img' }" @click="switchMedia = 'img'">图片</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="magnifier-wrap">
|
||||
<pic-zoom ref="PicZoom" :url="$img(picZoomUrl)" :scale="2"></pic-zoom>
|
||||
</div>
|
||||
|
||||
<div class="spec-items">
|
||||
<span class="left-btn iconfont icon-weibiaoti35" :class="{ move: moveThumbLeft }" @click="changeThumbImg('prev')"></span>
|
||||
<span class="right-btn iconfont icon-weibiaoti35" :class="{ move: moveThumbRight }" @click="changeThumbImg('next')"></span>
|
||||
<ul :style="{ top: 42 + thumbPosition + 'px' }">
|
||||
<!-- 商品缩率图 -->
|
||||
<li v-for="(item, index) in goodsSkuDetail.sku_images" :key="index" @mousemove="picZoomUrl = item" :class="{ selected: picZoomUrl == item }">
|
||||
<img :src="$img(item, { size: 'small' })" @error="imageErrorSpec(index)" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 商品信息 -->
|
||||
<div class="basic-info-wrap" v-loading="loading">
|
||||
<h1>{{ goodsSkuDetail.sku_name }}</h1>
|
||||
<p class="desc ns-text-color" v-if="goodsSkuDetail.introduction">{{ goodsSkuDetail.introduction }}</p>
|
||||
|
||||
<div class="discount-banner ns-bg-color" v-if="groupbuyTimeMachine.currentTime">
|
||||
<div class="activity-name">
|
||||
<i class="discount-icon iconfont iconicon_naozhong"></i>
|
||||
<span>团购</span>
|
||||
</div>
|
||||
<div class="surplus-time">
|
||||
<span>{{ groupbuyText }}</span>
|
||||
<count-down class="count-down" v-on:start_callback="countDownS_cb()" v-on:end_callback="countDownE_cb()"
|
||||
:currentTime="groupbuyTimeMachine.currentTime" :startTime="groupbuyTimeMachine.startTime"
|
||||
:endTime="groupbuyTimeMachine.endTime" :dayTxt="'天'" :hourTxt="'小时'" :minutesTxt="'分钟'"
|
||||
:secondsTxt="'秒'">
|
||||
</count-down>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item-block">
|
||||
<div class="promotion-price">
|
||||
<dl class="item-line">
|
||||
<dt class="ns-text-color-gray">团购价</dt>
|
||||
<dd>
|
||||
<em class="yuan ns-text-color">¥</em>
|
||||
<span class="price ns-text-color">{{ goodsSkuDetail.groupbuy_price }}</span>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="item-line">
|
||||
<dt class="ns-text-color-gray">原价</dt>
|
||||
<dd>
|
||||
<em class="market-yuan">¥</em>
|
||||
<span class="market-price">{{ goodsSkuDetail.price }}</span>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<!-- <div class="statistical">
|
||||
<ul>
|
||||
<li>
|
||||
<p>累计评价</p>
|
||||
<span>{{ goodsSkuDetail.evaluate }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<p>累计销量</p>
|
||||
<span>{{ goodsSkuDetail.sale_num }}{{ goodsSkuDetail.unit }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div> -->
|
||||
|
||||
<dl class="item-line" v-if="goodsSkuDetail.is_virtual == 0">
|
||||
<dt>运费</dt>
|
||||
<dd>
|
||||
<i class="i-activity-flag ns-text-color ns-border-color" v-if="goodsSkuDetail.is_free_shipping">快递免邮</i>
|
||||
<i class="i-activity-flag ns-text-color ns-border-color" v-else>快递不免邮</i>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<dl class="item-line delivery" v-if="goodsSkuDetail.is_virtual == 0">
|
||||
<dt>配送至</dt>
|
||||
<dd>
|
||||
<div class="region-selected ns-border-color-gray">
|
||||
<span>
|
||||
<template v-if="selectedAddress['level_1']">
|
||||
<template v-for="item in selectedAddress">{{ item.name }}</template>
|
||||
</template>
|
||||
<template v-else>请选择配送地址</template>
|
||||
</span>
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
</div>
|
||||
|
||||
<div class="region-list ns-border-color-gray" :class="{ hide: hideRegion }">
|
||||
<ul class="nav-tabs">
|
||||
<li :class="{ active: currTabAddres == 'province' }" @click="currTabAddres = 'province'">
|
||||
<div>
|
||||
<span>{{ selectedAddress['level_1'] ? selectedAddress['level_1'].name : '请选择省' }}</span>
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
</div>
|
||||
</li>
|
||||
<li :class="{ active: currTabAddres == 'city' }" @click="currTabAddres = 'city'">
|
||||
<div>
|
||||
<span>{{ selectedAddress['level_2'] ? selectedAddress['level_2'].name : '请选择市' }}</span>
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
</div>
|
||||
</li>
|
||||
<li :class="{ active: currTabAddres == 'district' }" @click="currTabAddres = 'district'">
|
||||
<div>
|
||||
<span>{{ selectedAddress['level_3'] ? selectedAddress['level_3'].name : '请选择区/县' }}</span>
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane" :class="{ active: currTabAddres == 'province' }">
|
||||
<ul class="province">
|
||||
<li v-for="(item, index) in provinceArr" :key="index" :class="{ selected: selectedAddress['level_' + item.level] && selectedAddress['level_' + item.level].id == item.id }">
|
||||
<span @click="getAddress('city', item)">{{ item.name }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-pane" :class="{ active: currTabAddres == 'city' }">
|
||||
<ul class="city">
|
||||
<li v-for="(item, index) in cityArr" :key="index" :class="{ selected: selectedAddress['level_' + item.level] && selectedAddress['level_' + item.level].id == item.id }">
|
||||
<span @click="getAddress('district', item)">{{ item.name }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-pane" :class="{ active: currTabAddres == 'district' }">
|
||||
<ul class="district">
|
||||
<li v-for="(item, index) in districtArr" :key="index" :class="{ selected: selectedAddress['level_' + item.level] && selectedAddress['level_' + item.level].id == item.id }">
|
||||
<span @click="getAddress('community', item)">{{ item.name }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="item-line service">
|
||||
<dt>服务</dt>
|
||||
<dd>
|
||||
<span>
|
||||
由
|
||||
<span class="ns-text-color">{{siteInfo.site_name}}</span>
|
||||
发货并提供售后服务
|
||||
</span>
|
||||
</dd>
|
||||
</dl>
|
||||
<hr class="divider" />
|
||||
<div class="sku-list" v-if="goodsSkuDetail.goods_spec_format">
|
||||
<dl class="item-line" v-for="(item, index) in goodsSkuDetail.goods_spec_format" :key="index">
|
||||
<dt>{{ item.spec_name }}</dt>
|
||||
<dd>
|
||||
<ul>
|
||||
<li v-for="(item_value, index_value) in item.value" :key="index_value">
|
||||
<div :class="{
|
||||
'selected ns-border-color': item_value['selected'] || skuId == item_value.sku_id,
|
||||
disabled: item_value['disabled'] || (!item_value['selected'] && specDisabled)
|
||||
}" @click="changeSpec(item_value.sku_id, item_value.spec_id)">
|
||||
<img v-if="item_value.image" :src="$img(item_value.image, { size: 'small' })" />
|
||||
<span>{{ item_value.spec_value_name }}</span>
|
||||
<i class="iconfont iconduigou1 ns-text-color"></i>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="buy-number">
|
||||
<dl class="item-line">
|
||||
<dt>数量</dt>
|
||||
<dd>
|
||||
<div class="num-wrap">
|
||||
<div class="operation">
|
||||
<span class="decrease el-icon-minus" @click="changeNum('-')"></span>
|
||||
<el-input v-model="number" placeholder="0" @input="keyInput()"></el-input>
|
||||
<span class="increase el-icon-plus" @click="changeNum('+')"></span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="unit">{{ goodsSkuDetail.unit }}</span>
|
||||
<span class="inventory">库存{{ goodsSkuDetail.stock }}{{ goodsSkuDetail.unit }}</span>
|
||||
<!-- 限购 -->
|
||||
<em v-if="limitNumber > 0">({{ limitNumber }}{{ goodsSkuDetail.unit }}起购)</em>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<dl class="item-line buy-btn">
|
||||
<dt></dt>
|
||||
<dd v-if="goodsSkuDetail.goods_state == 1">
|
||||
<template v-if="goodsSkuDetail.goods_stock < goodsSkuDetail.buy_num && !goodsSkuDetail.sku_spec_format">
|
||||
<el-button type="info" plain disabled>库存不足</el-button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button type="primary" plain @click="buyNow">立即抢购</el-button>
|
||||
</template>
|
||||
<div class="go-phone icon-item" @click="editCollection">
|
||||
<span :class="['iconfont',(whetherCollection == 1 ? 'icon-_shouzang2 selected' : 'icon-shouzang')]"></span>
|
||||
<span>收藏</span>
|
||||
</div>
|
||||
</dd>
|
||||
|
||||
<dd v-else>
|
||||
<template>
|
||||
<el-button type="info" plain disabled>该商品已下架</el-button>
|
||||
</template>
|
||||
<div class="go-phone icon-item" @click="editCollection">
|
||||
<span :class="['iconfont',(whetherCollection == 1 ? 'icon-_shouzang2 selected' : 'icon-shouzang')]"></span>
|
||||
<span>收藏</span>
|
||||
</div>
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
<dl class="item-line merchant-service" v-show="service_list.length">
|
||||
<dt>商品服务</dt>
|
||||
<div>
|
||||
<dd class="service-li" v-for="item in service_list">
|
||||
<i class="el-icon-success"></i>
|
||||
<span class="ns-text-color-gray" :title="item.service_name">{{item.service_name}}</span>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="detail-wrap">
|
||||
|
||||
<el-tabs class="goods-tab" v-model="tabName" type="card" @tab-click="tabChange">
|
||||
<el-tab-pane label="商品详情" name="detail">
|
||||
<div v-html="goodsSkuDetail.goods_content"></div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="商品属性" name="attr">
|
||||
<ul class="attr-list">
|
||||
<template v-if="goodsSkuDetail.goods_attr_format && goodsSkuDetail.goods_attr_format.length > 0">
|
||||
<li v-for="(item, index) in goodsSkuDetail.goods_attr_format" :key="index">{{ item.attr_name }}:{{ item.attr_value_name }}</li>
|
||||
</template>
|
||||
</ul>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="evaluate_show" :label="goodsEvaluateList.length ? '商品评价(' + goodsEvaluateList.length + ')' : '商品评价'" name="evaluate" class="evaluate">
|
||||
<template v-if="goodsEvaluateList.length">
|
||||
<nav>
|
||||
<li :class="evaluaType == 0 ? 'selected' : ''" @click="evaluationType(0)">全部评价({{evaluteCount.total}})</li>
|
||||
<li :class="evaluaType == 1 ? 'selected' : ''" @click="evaluationType(1)">好评({{evaluteCount.haoping}})</li>
|
||||
<li :class="evaluaType == 2 ? 'selected' : ''" @click="evaluationType(2)">中评({{evaluteCount.zhongping}})</li>
|
||||
<li :class="evaluaType == 3 ? 'selected' : ''" @click="evaluationType(3)">差评({{evaluteCount.chaping}})</li>
|
||||
</nav>
|
||||
<ul class="list">
|
||||
<li v-for="(item, index) in goodsEvaluateList" :key="index">
|
||||
<div class="member-info">
|
||||
<img :src="$img(item.member_headimg)" @error="imageErrorEvaluate(index)" class="avatar" />
|
||||
<span>{{ item.member_name }}</span>
|
||||
</div>
|
||||
<div class="info-wrap">
|
||||
<el-rate v-model="item.star" disabled></el-rate>
|
||||
<p class="content">{{ item.content }}</p>
|
||||
<div class="img-list" v-if="item.images">
|
||||
<el-image v-for="(img, img_index) in item.images" :key="img_index" :src="$img(img)" :preview-src-list="item.imagesFormat"/>
|
||||
</div>
|
||||
<div class="sku-info">
|
||||
<span>{{ item.sku_name }}</span>
|
||||
<span class="create-time">{{ $util.timeStampTurnTime(item.create_time) }}</span>
|
||||
</div>
|
||||
<div class="evaluation-reply" v-if="item.explain_first != ''">店家回复:{{ item.explain_first }}</div>
|
||||
<template v-if="item.again_content != ''">
|
||||
<div class="review-evaluation">
|
||||
<span>追加评价</span>
|
||||
<span class="review-time">{{ $util.timeStampTurnTime(item.again_time) }}</span>
|
||||
</div>
|
||||
<p class="content">{{ item.again_content }}</p>
|
||||
<div class="img-list">
|
||||
<el-image v-for="(again_img, again_index) in item.again_images" :key="again_index" :src="$img(again_img)" :preview-src-list="item.againImagesFormat"/>
|
||||
</div>
|
||||
<div class="evaluation-reply" v-if="item.again_explain != ''">店家回复:{{ item.again_explain }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="pager">
|
||||
<el-pagination background :pager-count="5" :total="total" prev-text="上一页" next-text="下一页"
|
||||
:current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
@size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange" hide-on-single-page></el-pagination>
|
||||
</div>
|
||||
</template>
|
||||
<div class="empty" v-else>该商品暂无评价哦</div>
|
||||
</el-tab-pane>
|
||||
<template v-if="service">
|
||||
<el-tab-pane v-if="service.is_display == 1" label="售后保障" name="after_sale" class="after-sale">
|
||||
<div v-html="service.content"></div>
|
||||
</el-tab-pane>
|
||||
</template>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<!--联系客服弹窗-->
|
||||
<servicerMessage ref="servicerMessage" class="kefu" :shop="{shop_id:shopInfo.site_id,logo:shopInfo.logo,shop_name:shopInfo.site_name}"></servicerMessage>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PicZoom from 'vue-piczoom';
|
||||
import detail from '@/assets/js/promotion/detail_groupbuy.js';
|
||||
import GoodsRecommend from '@/components/GoodsRecommend';
|
||||
import servicerMessage from "@/components/message/servicerMessage";
|
||||
|
||||
export default {
|
||||
name: 'groupbuy_detail',
|
||||
components: {
|
||||
PicZoom,
|
||||
GoodsRecommend,
|
||||
servicerMessage
|
||||
},
|
||||
mixins: [detail]
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
@import '@/assets/css/promotion/detail_groupbuy.scss';
|
||||
</style>
|
||||
337
addon/pc/source/os/pages/promotion/groupbuy/index.vue
Executable file
337
addon/pc/source/os/pages/promotion/groupbuy/index.vue
Executable file
@@ -0,0 +1,337 @@
|
||||
<template>
|
||||
<div class="ns-groupbuy">
|
||||
<div class="ns-groupbuy-head">
|
||||
<el-carousel height="420px" v-loading="loadingAd" v-if="adList.length">
|
||||
<el-carousel-item v-for="item in adList" :key="item.adv_id">
|
||||
<el-image :src="$img(item.adv_image)" fit="cover" @click="$util.pushToTab(item.adv_url.url)" />
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</div>
|
||||
|
||||
<!-- 商品列表 -->
|
||||
<div class="ns-groupbuy-box" v-loading="loading">
|
||||
<div class="ns-groupbuy-title" v-if="goodsList.length">
|
||||
<span class="groupbuy-title-left">团购专区</span>
|
||||
</div>
|
||||
|
||||
<div class="goods-list" v-if="goodsList.length">
|
||||
<div class="goods" v-for="(item,index) in goodsList" :key="item.groupbuy_id" @click="$router.push('/promotion/groupbuy/' + item.groupbuy_id)">
|
||||
<!-- 商品图片区 -->
|
||||
<div class="img">
|
||||
<el-image fit="scale-down" :src="$img(item.goods_image, { size: 'mid' })" lazy @error="imageError(index)"/>
|
||||
</div>
|
||||
|
||||
<!-- 商品名称 -->
|
||||
<div class="name">
|
||||
<p :title="item.goods_name">{{ item.goods_name }}</p>
|
||||
</div>
|
||||
|
||||
<!-- 价格展示区 -->
|
||||
<div class="price">
|
||||
<div class="curr-price">
|
||||
<span>团购价</span>
|
||||
<span>¥</span>
|
||||
<span class="main_price">{{ item.groupbuy_price }}</span>
|
||||
</div>
|
||||
<span class="primary_price">¥{{ item.price }}</span>
|
||||
</div>
|
||||
<el-button>立即拼购</el-button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="!loading" class="empty-wrap">
|
||||
<img src="~assets/images/goods_empty.png">
|
||||
<span>暂无正在进行团购的商品,<router-link to="/" class="ns-text-color">去首页</router-link>看看吧</span>
|
||||
</div>
|
||||
|
||||
<div class="pager">
|
||||
<el-pagination
|
||||
background
|
||||
:pager-count="5"
|
||||
:total="total"
|
||||
prev-text="上一页"
|
||||
next-text="下一页"
|
||||
:current-page.sync="currentPage"
|
||||
:page-size.sync="pageSize"
|
||||
@size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange"
|
||||
hide-on-single-page
|
||||
></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {goodsPage} from '@/api/groupbuy';
|
||||
import {mapGetters} from 'vuex';
|
||||
import {adList} from '@/api/website';
|
||||
|
||||
export default {
|
||||
name: 'groupbuy',
|
||||
data: () => {
|
||||
return {
|
||||
loading: true,
|
||||
goodsList: [],
|
||||
total: 0,
|
||||
currentPage: 1,
|
||||
pageSize: 25,
|
||||
loadingAd: true,
|
||||
adList: []
|
||||
};
|
||||
},
|
||||
created() {
|
||||
if (this.addonIsExit && this.addonIsExit.groupbuy != 1) {
|
||||
this.$message({
|
||||
message: '团购插件未安装',
|
||||
type: 'warning',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$route.push('/');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
this.getAdList();
|
||||
this.getGoodsList();
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['defaultGoodsImage', 'addonIsExit'])
|
||||
},
|
||||
head() {
|
||||
return {
|
||||
title: '团购专区-' + this.$store.state.site.siteInfo.site_name,
|
||||
meta: [{
|
||||
name: 'description',
|
||||
content: this.$store.state.site.siteInfo.seo_description
|
||||
}, {
|
||||
name: 'keyword',
|
||||
content: this.$store.state.site.siteInfo.seo_keywords
|
||||
}]
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
addonIsExit() {
|
||||
if (this.addonIsExit.groupbuy != 1) {
|
||||
this.$message({
|
||||
message: '团购插件未安装',
|
||||
type: 'warning',
|
||||
duration: 2000,
|
||||
onClose: () => {
|
||||
this.$route.push('/');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getAdList() {
|
||||
adList({keyword: 'NS_PC_GROUPBUY'}).then(res => {
|
||||
this.adList = res.data.adv_list;
|
||||
for (let i = 0; i < this.adList.length; i++) {
|
||||
if (this.adList[i].adv_url) this.adList[i].adv_url = JSON.parse(this.adList[i].adv_url);
|
||||
}
|
||||
this.loadingAd = false;
|
||||
}).catch(err => {
|
||||
this.loadingAd = false;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 团购商品
|
||||
*/
|
||||
getGoodsList() {
|
||||
goodsPage({
|
||||
page_size: this.pageSize,
|
||||
page: this.currentPage
|
||||
}).then(res => {
|
||||
this.goodsList = res.data.list;
|
||||
this.total = res.data.count;
|
||||
this.loading = false;
|
||||
}).catch(err => {
|
||||
this.loading = false;
|
||||
this.$message.error(err.message);
|
||||
});
|
||||
},
|
||||
handlePageSizeChange(size) {
|
||||
this.pageSize = size;
|
||||
this.refresh();
|
||||
},
|
||||
handleCurrentPageChange(page) {
|
||||
this.currentPage = page;
|
||||
this.refresh();
|
||||
},
|
||||
refresh() {
|
||||
this.loading = true;
|
||||
this.getGoodsList();
|
||||
},
|
||||
/**
|
||||
* 图片加载失败
|
||||
*/
|
||||
imageError(index) {
|
||||
this.goodsList[index].goods_image = this.defaultGoodsImage;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.ns-groupbuy {
|
||||
.ns-groupbuy-box {
|
||||
padding: 48px 0;
|
||||
width: $width;
|
||||
margin: 0 auto;
|
||||
|
||||
.ns-groupbuy-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
|
||||
.groupbuy-title-left {
|
||||
font-size: 30px;
|
||||
color: #333;
|
||||
border-bottom: 4px solid #F42424;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.goods-list {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-start;
|
||||
margin-top: 32px;
|
||||
|
||||
.goods {
|
||||
margin-right: 17px;
|
||||
margin-bottom: 18px;
|
||||
width: 228px;
|
||||
background-color: #ffffff;
|
||||
overflow: hidden;
|
||||
color: #303133;
|
||||
transition: 0.3s;
|
||||
padding: 18px;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
|
||||
&:nth-child(5n+5) {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.img {
|
||||
width: 192px;
|
||||
height: 192px;
|
||||
|
||||
.el-image {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.price {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
|
||||
.curr-price {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
height: 24px;
|
||||
font-weight: bold;
|
||||
color: $base-color;
|
||||
|
||||
span:first-child {
|
||||
font-size: 14px;
|
||||
margin-right: 1px;
|
||||
}
|
||||
|
||||
span:nth-child(2) {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.main_price {
|
||||
color: $base-color;
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.primary_price {
|
||||
text-decoration: line-through;
|
||||
color: $base-color-info;
|
||||
margin-left: 5px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.el-button {
|
||||
width: 100%;
|
||||
height: 42px;
|
||||
line-height: 42px;
|
||||
background: $base-color;
|
||||
color: #ffffff;
|
||||
margin-top: 10px;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
padding: 0;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.name {
|
||||
margin-top: 12px;
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 5px;
|
||||
white-space: normal;
|
||||
overflow: hidden;
|
||||
|
||||
p {
|
||||
line-height: 24px;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty-wrap {
|
||||
padding: 50px 0 60px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-sizing: border-box;
|
||||
|
||||
img {
|
||||
width: 400px;
|
||||
height: 244px;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 14px;
|
||||
color: #4A4A4A;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="scss">
|
||||
.ns-groupbuy {
|
||||
.ns-groupbuy-head {
|
||||
width: $width;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.el-carousel {
|
||||
.el-image {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.el-image__inner {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.el-carousel__arrow--right {
|
||||
right: 60px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
326
addon/pc/source/os/pages/promotion/groupbuy/payment/index.vue
Executable file
326
addon/pc/source/os/pages/promotion/groupbuy/payment/index.vue
Executable file
@@ -0,0 +1,326 @@
|
||||
<template>
|
||||
<div class="payment-wrap" v-loading="fullscreenLoading">
|
||||
|
||||
<!--购买虚拟类商品需填写您的手机号-->
|
||||
<div class="item-block" v-if="orderPaymentData.is_virtual == 1">
|
||||
<div class="block-text">购买虚拟类商品需填写您的手机号,以方便商家与您联系</div>
|
||||
|
||||
<el-form ref="form" size="mini" class="mobile-wrap" label-width="80px">
|
||||
<el-form-item label="手机号码">
|
||||
<el-input placeholder="请输入您的手机号码" maxlength="11" v-model="orderCreateData.member_address.mobile" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<!--收货地址-->
|
||||
<div class="item-block" v-if="orderPaymentData.is_virtual == 0">
|
||||
<div class="block-text">收货地址</div>
|
||||
|
||||
<div class="address-list">
|
||||
<div class="address-item" @click="addAddressShow">
|
||||
<div class="add-address">
|
||||
<i class="el-icon-circle-plus-outline"></i>
|
||||
添加收货地址
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="address-item" v-for="(item, key) in memberAddress" :key="item.id" :class="addressId == item.id ? 'active' : ''" v-if="key < 3 || (addressShow && key >= 3)">
|
||||
<div class="address-info">
|
||||
<div class="options">
|
||||
<div @click="editAddress(item.id)">编辑</div>
|
||||
<template v-if="item.is_default == 0">
|
||||
<el-popconfirm title="确定要删除该地址吗?" @onConfirm="deleteMemberAddress(item.id)">
|
||||
<div slot="reference">删除</div>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</div>
|
||||
<div class="address-name">{{ item.name }}</div>
|
||||
<div class="address-mobile" @click="setMemberAddress(item.id)">{{ item.mobile }}</div>
|
||||
<div class="address-desc" @click="setMemberAddress(item.id)">{{ item.full_address }} {{ item.address }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="memberAddress.length > 3 && !addressShow" @click="addressShow = true" class="el-button--text address-open">
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
更多收货地址
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--收货地址添加-->
|
||||
<el-dialog :title="addressForm.id == 0 ? '添加收货地址' : '编辑收货地址'" :visible.sync="dialogVisible" width="32%">
|
||||
<el-form ref="form" :rules="addressRules" :model="addressForm" label-width="80px">
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input v-model="addressForm.name" placeholder="收货人姓名" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="手机" prop="mobile">
|
||||
<el-input v-model="addressForm.mobile" maxlength="11" placeholder="收货人手机号" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="电话">
|
||||
<el-input v-model="addressForm.telephone" placeholder="收货人固定电话(选填)" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item class="area" label="地区" prop="area">
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="7">
|
||||
<el-select prop="province" ref="province" v-model="addressForm.province_id" @change="getAddress(1)" placeholder="请选择省">
|
||||
<el-option label="请选择省" value="0"></el-option>
|
||||
<el-option v-for="item in pickerValueArray" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-select ref="city" prop="city" v-model="addressForm.city_id" @change="getAddress(2)" placeholder="请选择市">
|
||||
<el-option label="请选择市" value="0"></el-option>
|
||||
<el-option v-for="item in cityArr" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-select ref="district" prop="district" v-model="addressForm.district_id" placeholder="请选择区/县">
|
||||
<el-option label="请选择区/县" value="0"></el-option>
|
||||
<el-option v-for="item in districtArr" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="详细地址" prop="address">
|
||||
<el-input v-model="addressForm.address" placeholder="定位小区、街道、写字楼" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="addmemberAddress('form')">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<!--使用余额-->
|
||||
<div class="item-block" v-if="orderPaymentData.member_account.balance_total > 0 && balance_show == 1">
|
||||
<div class="block-text">是否使用余额</div>
|
||||
<div class="pay-type-list">
|
||||
<div class="pay-type-item" :class="orderCreateData.is_balance ? '' : 'active'" @click="useBalance(0)">不使用余额</div>
|
||||
<div class="pay-type-item" :class="orderCreateData.is_balance ? 'active' : ''" @click="useBalance(1)">使用余额</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 支付密码 -->
|
||||
<el-dialog title="使用余额" :visible.sync="dialogpay" width="350px">
|
||||
<template v-if="orderPaymentData.member_account.is_pay_password == 0">
|
||||
<p>为了您的账户安全,请您先设置的支付密码</p>
|
||||
<p>可到"会员中心","账号安全","支付密码"中设置</p>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button size="small" @click="dialogpay = false">暂不设置</el-button>
|
||||
<el-button size="small" type="primary" @click="setPayPassword">立即设置</el-button>
|
||||
</span>
|
||||
</template>
|
||||
<el-form v-else status-icon ref="ruleForm" label-width="100px">
|
||||
<el-form-item label="支付密码" class="pay-password-item">
|
||||
<!--添加一个不可见的input,欺骗浏览器自动填充-->
|
||||
<el-input type="password" class="pay-password hide-password" :maxlength="6"></el-input>
|
||||
<el-input type="password" class="pay-password" :maxlength="6" v-model="password" @input="input"></el-input>
|
||||
</el-form-item>
|
||||
<p class="ns-text-color forget-password" @click="setPayPassword">忘记密码</p>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 配送方式 -->
|
||||
<div class="item-block padd-bom-20" v-if="orderPaymentData.delivery.express_type.length > 0">
|
||||
<div class="block-text">
|
||||
<span>配送方式</span>
|
||||
<span class="distribution" v-if="orderCreateData.delivery.delivery_type == 'store'">{{ orderCreateData.delivery.store_name }}</span>
|
||||
</div>
|
||||
<div class="pay-type-item" v-for="(item, index) in orderPaymentData.delivery.express_type" :key="index" @click="selectDeliveryType(item)" :class="item.name == orderCreateData.delivery.delivery_type ? 'active' : ''">
|
||||
{{ item.title }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--配送方式 门店 -->
|
||||
<el-dialog title="选择门店" :visible.sync="dialogStore" width="50%">
|
||||
<el-table ref="singleTable" :data="storeList" highlight-current-row @row-click="selectStore" class="cursor-pointer">
|
||||
<el-table-column label="" width="55">
|
||||
<template slot-scope="scope">
|
||||
<el-radio v-model="storeRadio" :label="scope.row"><i></i></el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="store_name" label="名称" width="160"></el-table-column>
|
||||
<el-table-column prop="store_address" label="地址"></el-table-column>
|
||||
<el-table-column prop="open_date" label="营业时间"></el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<div class="item-block" v-if="orderPaymentData.invoice && orderPaymentData.invoice.invoice_status == 1">
|
||||
<div class="block-text">发票信息</div>
|
||||
<div class="pay-type-list">
|
||||
<div class="pay-type-item" :class="orderCreateData.is_invoice == 0 ? 'active' : ''" @click="changeIsInvoice">无需发票</div>
|
||||
<div class="pay-type-item" :class="orderCreateData.is_invoice == 1 ? 'active' : ''" @click="changeIsInvoice">需要发票</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<div class="invoice-information" v-if="orderCreateData.is_invoice == 1">
|
||||
<div class="invoice-title">
|
||||
<div class="invoice-type-box invoice-title-box">
|
||||
<span class="invoice-name">发票类型:</span>
|
||||
<label class="invoice-to-type">
|
||||
<i class="invoice-i-input" :class="orderCreateData.invoice_type == 1 ? 'active' : ''" @click="clickType(1)"></i>
|
||||
<span>纸质</span>
|
||||
</label>
|
||||
<label class="invoice-to-type">
|
||||
<i class="invoice-i-input" :class="orderCreateData.invoice_type == 2 ? 'active' : ''" @click="clickType(2)"></i>
|
||||
<span>电子</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="invoice-type-box invoice-title-box">
|
||||
<span class="invoice-name">抬头类型:</span>
|
||||
<label class="invoice-to-type">
|
||||
<i class="invoice-i-input" :class="orderCreateData.invoice_title_type == 1 ? 'active' : ''" @click="clickTitleType(1)"></i>
|
||||
<span>个人</span>
|
||||
</label>
|
||||
<label class="invoice-to-type">
|
||||
<i class="invoice-i-input" :class="orderCreateData.invoice_title_type == 2 ? 'active' : ''" @click="clickTitleType(2)"></i>
|
||||
<span>企业</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="invoice-type-box">
|
||||
<span class="invoice-name">发票信息:</span>
|
||||
<div class="invoice-box-form">
|
||||
<input type="text" placeholder="请填写抬头名称" v-model.trim="orderCreateData.invoice_title" />
|
||||
<input type="text" placeholder="请填写纳税人识别号" v-model.trim="orderCreateData.taxpayer_number" v-if="orderCreateData.invoice_title_type == 2" />
|
||||
<input type="text" placeholder="请填写邮寄地址" v-model.trim="orderCreateData.invoice_full_address" v-show="orderCreateData.invoice_type == 1" />
|
||||
<input type="text" placeholder="请填写邮箱" v-model.trim="orderCreateData.invoice_email" v-show="orderCreateData.invoice_type == 2" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="invoice-condition">
|
||||
<span class="invoice-name">发票内容:</span>
|
||||
<div class="invoice-box-form">
|
||||
<span class="option-item" :key="index" v-for="(item, index) in orderPaymentData.invoice.invoice_content_array" @click="changeInvoiceContent(item)" :class="{ 'color-base-bg active': item == orderCreateData.invoice_content }">
|
||||
{{ item }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="invoice-tops">发票内容将以根据税法调整,具体请以展示为准,发票内容显示详细商品名 称及价格信息</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--商品信息-->
|
||||
<div class="item-block">
|
||||
<div class="goods-list">
|
||||
<table>
|
||||
<tr>
|
||||
<td width="50%">商品</td>
|
||||
<td width="12.5%">价格</td>
|
||||
<td width="12.5%">数量</td>
|
||||
<td width="12.5%">小计</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="item-block" v-if="calculateData">
|
||||
<div class="goods-list">
|
||||
<table>
|
||||
<tr v-for="(goodsItem, goodsIndex) in calculateData.goods_list" :key="goodsIndex">
|
||||
<td width="50%">
|
||||
<div class="goods-info">
|
||||
<div class="goods-info-left">
|
||||
<router-link :to="{ path: '/sku/' + goodsItem.sku_id }" target="_blank">
|
||||
<img class="goods-img" :src="$img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" />
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="goods-info-right">
|
||||
<router-link :to="{ path: '/sku/' + goodsItem.sku_id }" target="_blank">
|
||||
<div class="goods-name">{{ goodsItem.goods_name }}</div>
|
||||
</router-link>
|
||||
<!-- 规格 -->
|
||||
<div class="goods-spec" v-if="goodsItem.sku_spec_format">
|
||||
<span v-for="(x, i) in goodsItem.sku_spec_format" :key="i">{{ x.spec_value_name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td width="12.5%" class="goods-price">¥{{ goodsItem.price }}</td>
|
||||
<td width="12.5%" class="goods-num">{{ goodsItem.num }}</td>
|
||||
<td width="12.5%" class="goods-money">¥{{ (goodsItem.price * goodsItem.num).toFixed(2) }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 活动优惠 -->
|
||||
<div class="item-block" v-if="promotionInfo">
|
||||
<div class="block-text">{{ promotionInfo.title }}</div>
|
||||
<div class="order-cell platform-coupon">
|
||||
<div class="box ns-text-color" v-html="promotionInfo.content"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 买家留言 -->
|
||||
<div class="item-block padd-bom-10">
|
||||
<div class="block-text">买家留言:</div>
|
||||
<el-input rows="3" type="textarea" placeholder="留言前建议先与商家协调一致" v-model="orderCreateData.buyer_message" class="buyer-message" @input="textarea" maxlength="140" show-word-limit resize="none" />
|
||||
</div>
|
||||
|
||||
<!-- 总计 -->
|
||||
<div class="item-block" v-if="calculateData">
|
||||
<div class="order-statistics">
|
||||
<table>
|
||||
<tr>
|
||||
<td align="right">商品金额:</td>
|
||||
<td align="left">¥{{ calculateData.goods_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.is_virtual == 0 && calculateData.delivery_money > 0">
|
||||
<td align="right">运费:</td>
|
||||
<td align="left">¥{{ calculateData.delivery_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.invoice_money > 0">
|
||||
<td align="right">发票税费<span class="ns-text-color">({{ calculateData.invoice.invoice_rate }}%)</span>:</td>
|
||||
<td align="left">¥{{ calculateData.invoice_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.invoice_delivery_money > 0">
|
||||
<td align="right">发票邮寄费:</td>
|
||||
<td align="left">¥{{ calculateData.invoice_delivery_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.promotion_money > 0">
|
||||
<td align="right">优惠:</td>
|
||||
<td align="left">¥{{ calculateData.promotion_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.balance_money > 0">
|
||||
<td align="right">使用余额:</td>
|
||||
<td align="left">¥{{ calculateData.balance_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<!--结算-->
|
||||
<div class="item-block" v-if="calculateData">
|
||||
<div class="order-submit">
|
||||
<div class="order-money">
|
||||
共{{ calculateData.goods_num }}件,应付金额:
|
||||
<div class="ns-text-color">¥{{ calculateData.pay_money | moneyFormat }}</div>
|
||||
</div>
|
||||
<el-button type="primary" class="el-button--primary" @click="orderCreate">订单结算</el-button>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import detail from '@/assets/js/promotion/payment_groupbuy.js';
|
||||
|
||||
export default {
|
||||
name: 'groupbuy_payment',
|
||||
mixins: [detail]
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/css/promotion/payment_groupbuy.scss';
|
||||
</style>
|
||||
354
addon/pc/source/os/pages/promotion/seckill/_id/index.vue
Executable file
354
addon/pc/source/os/pages/promotion/seckill/_id/index.vue
Executable file
@@ -0,0 +1,354 @@
|
||||
<template>
|
||||
<div class="goods-detail-wrap">
|
||||
<div class="detail-nav-wrap" v-if="categoryNameArr">
|
||||
<div class="detail-nav" v-if="categoryNameArr.length">
|
||||
<template v-for="(item,index) in categoryNameArr" :keys="index">
|
||||
<router-link :to="{ path: '/goods/list', query: { category_id: item.category_id, level: index } }">
|
||||
{{item.name}}
|
||||
</router-link>
|
||||
<span class="iconfont icon-arrow-right"></span>
|
||||
</template>
|
||||
<span class="goods-name">{{goodsSkuDetail.goods_name}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-main">
|
||||
<div class="goods-detail">
|
||||
|
||||
<div class="preview-wrap">
|
||||
<div class="video-player-wrap" :class="{ show: switchMedia == 'video' }" v-if="goodsSkuDetail.video_url != ''">
|
||||
<video-player v-if="goodsSkuDetail.video_url != ''" ref="videoPlayer" :playsinline="true"
|
||||
:options="playerOptions" @play="onPlayerPlay($event)" @pause="onPlayerPause($event)"
|
||||
@ended="onPlayerEnded($event)" @waiting="onPlayerWaiting($event)"
|
||||
@playing="onPlayerPlaying($event)"
|
||||
@loadeddata="onPlayerLoadeddata($event)" @timeupdate="onPlayerTimeupdate($event)"
|
||||
@canplay="onPlayerCanplay($event)" @canplaythrough="onPlayerCanplaythrough($event)"
|
||||
@statechanged="playerStateChanged($event)" @ready="playerReadied"></video-player>
|
||||
|
||||
<div class="media-mode" v-if="goodsSkuDetail.video_url != ''">
|
||||
<span :class="{ 'ns-bg-color': switchMedia == 'video' }" @click="switchMedia = 'video'">视频</span>
|
||||
<span :class="{ 'ns-bg-color': switchMedia == 'img' }" @click="switchMedia = 'img'">图片</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="magnifier-wrap">
|
||||
<pic-zoom ref="PicZoom" :url="$img(picZoomUrl)" :scale="2"></pic-zoom>
|
||||
</div>
|
||||
|
||||
<div class="spec-items">
|
||||
<span class="left-btn iconfont icon-weibiaoti35" :class="{ move: moveThumbLeft }" @click="changeThumbImg('prev')"></span>
|
||||
<span class="right-btn iconfont icon-weibiaoti35" :class="{ move: moveThumbRight }" @click="changeThumbImg('next')"></span>
|
||||
<ul :style="{ top: 42 + thumbPosition + 'px' }">
|
||||
<!-- 商品缩率图 -->
|
||||
<li v-for="(item, index) in goodsSkuDetail.sku_images" :key="index" @mousemove="picZoomUrl = item" :class="{ selected: picZoomUrl == item }">
|
||||
<img :src="$img(item, { size: 'small' })" @error="imageErrorSpec(index)" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- <div class="share-collect">
|
||||
<div @click="editCollection">
|
||||
<i class="iconfont" :class="whetherCollection == 1 ? 'iconlikefill ns-text-color' : 'iconlike'"></i>
|
||||
<span data-collects="0">关注商品({{ goodsSkuDetail.collect_num }})</span>
|
||||
</div>
|
||||
<div v-if="kefuConfig.system == 0 && kefuConfig.open_pc == 1">
|
||||
<i class="iconfont iconzhanghao"></i>
|
||||
<span data-collects="0"><a :href="kefuConfig.open_url" target="_blank">联系客服</a></span>
|
||||
</div>
|
||||
<div @click="service_link" v-else-if="kefuConfig.system == 1">
|
||||
<i class="iconfont iconzhanghao"></i>
|
||||
<span data-collects="0">联系客服</span>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
<!-- 商品信息 -->
|
||||
<div class="basic-info-wrap" v-loading="loading">
|
||||
<h1>{{ goodsSkuDetail.sku_name }}</h1>
|
||||
<p class="desc ns-text-color" v-if="goodsSkuDetail.introduction">{{ goodsSkuDetail.introduction }}</p>
|
||||
|
||||
<div class="discount-banner ns-bg-color" v-if="seckillTimeMachine.currentTime">
|
||||
<div class="activity-name"><i class="discount-icon iconfont iconicon_naozhong"></i><span>限时秒杀</span></div>
|
||||
<div class="surplus-time">
|
||||
<span>{{ seckillText }}</span>
|
||||
<count-down class="count-down" v-on:start_callback="countDownS_cb()" v-on:end_callback="countDownE_cb()"
|
||||
:currentTime="seckillTimeMachine.currentTime" :startTime="seckillTimeMachine.startTime"
|
||||
:endTime="seckillTimeMachine.endTime" :dayTxt="'天'" :hourTxt="'小时'" :minutesTxt="'分钟'"
|
||||
:secondsTxt="'秒'">
|
||||
</count-down>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item-block">
|
||||
<div class="promotion-price">
|
||||
<dl class="item-line">
|
||||
<dt class="ns-text-color-gray">秒杀价</dt>
|
||||
<dd>
|
||||
<em class="yuan ns-text-color">¥</em>
|
||||
<span class="price ns-text-color">{{ goodsSkuDetail.seckill_price }}</span>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="item-line">
|
||||
<dt class="ns-text-color-gray">原价</dt>
|
||||
<dd>
|
||||
<em class="market-yuan">¥</em>
|
||||
<span class="market-price">{{ goodsSkuDetail.price }}</span>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<!-- <div class="statistical">
|
||||
<ul>
|
||||
<li>
|
||||
<p>累计评价</p>
|
||||
<span>{{ goodsSkuDetail.evaluate }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<p>累计销量</p>
|
||||
<span>{{ goodsSkuDetail.sale_num }}{{ goodsSkuDetail.unit }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div> -->
|
||||
|
||||
<dl class="item-line" v-if="goodsSkuDetail.is_virtual == 0">
|
||||
<dt>运费</dt>
|
||||
<dd>
|
||||
<i class="i-activity-flag ns-text-color ns-border-color" v-if="goodsSkuDetail.is_free_shipping">快递免邮</i>
|
||||
<i class="i-activity-flag ns-text-color ns-border-color" v-else>快递不免邮</i>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
<dl class="item-line delivery" v-if="goodsSkuDetail.is_virtual == 0">
|
||||
<dt>配送至</dt>
|
||||
<dd>
|
||||
<div class="region-selected ns-border-color-gray">
|
||||
<span>
|
||||
<template v-if="selectedAddress['level_1']">
|
||||
<template v-for="item in selectedAddress">{{ item.name }}</template>
|
||||
</template>
|
||||
<template v-else>请选择配送地址</template>
|
||||
</span>
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
</div>
|
||||
|
||||
<div class="region-list ns-border-color-gray" :class="{ hide: hideRegion }">
|
||||
<ul class="nav-tabs">
|
||||
<li :class="{ active: currTabAddres == 'province' }" @click="currTabAddres = 'province'">
|
||||
<div>
|
||||
<span>{{ selectedAddress['level_1'] ? selectedAddress['level_1'].name : '请选择省' }}</span>
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
</div>
|
||||
</li>
|
||||
<li :class="{ active: currTabAddres == 'city' }" @click="currTabAddres = 'city'">
|
||||
<div>
|
||||
<span>{{ selectedAddress['level_2'] ? selectedAddress['level_2'].name : '请选择市' }}</span>
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
</div>
|
||||
</li>
|
||||
<li :class="{ active: currTabAddres == 'district' }" @click="currTabAddres = 'district'">
|
||||
<div>
|
||||
<span>{{ selectedAddress['level_3'] ? selectedAddress['level_3'].name : '请选择区/县' }}</span>
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane" :class="{ active: currTabAddres == 'province' }">
|
||||
<ul class="province">
|
||||
<li v-for="(item, index) in provinceArr" :key="index" :class="{ selected: selectedAddress['level_' + item.level] && selectedAddress['level_' + item.level].id == item.id }">
|
||||
<span @click="getAddress('city', item)">{{ item.name }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-pane" :class="{ active: currTabAddres == 'city' }">
|
||||
<ul class="city">
|
||||
<li v-for="(item, index) in cityArr" :key="index" :class="{ selected: selectedAddress['level_' + item.level] && selectedAddress['level_' + item.level].id == item.id }">
|
||||
<span @click="getAddress('district', item)">{{ item.name }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-pane" :class="{ active: currTabAddres == 'district' }">
|
||||
<ul class="district">
|
||||
<li v-for="(item, index) in districtArr" :key="index" :class="{ selected: selectedAddress['level_' + item.level] && selectedAddress['level_' + item.level].id == item.id }">
|
||||
<span @click="getAddress('community', item)">{{ item.name }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="item-line service">
|
||||
<dt>服务</dt>
|
||||
<dd>
|
||||
<span>
|
||||
由<span class="ns-text-color">{{siteInfo.site_name}}</span>发货并提供售后服务
|
||||
</span>
|
||||
</dd>
|
||||
</dl>
|
||||
<hr class="divider" />
|
||||
<div class="sku-list" v-if="goodsSkuDetail.goods_spec_format">
|
||||
<dl class="item-line" v-for="(item, index) in goodsSkuDetail.goods_spec_format" :key="index">
|
||||
<dt>{{ item.spec_name }}</dt>
|
||||
<dd>
|
||||
<ul>
|
||||
<li v-for="(item_value, index_value) in item.value" :key="index_value">
|
||||
<div :class="{ 'selected ns-border-color': item_value['selected'] || skuId == item_value.sku_id, disabled: item_value['disabled'] }" @click="changeSpec(item_value.sku_id, item_value.spec_id, item_value.disabled)">
|
||||
<img v-if="item_value.image" :src="$img(item_value.image, { size: 'small' })" />
|
||||
<span>{{ item_value.spec_value_name }}</span>
|
||||
<i class="iconfont iconduigou1 ns-text-color"></i>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="buy-number">
|
||||
<dl class="item-line">
|
||||
<dt>数量</dt>
|
||||
<dd>
|
||||
<div class="num-wrap">
|
||||
<div class="operation">
|
||||
<span class="decrease el-icon-minus" @click="changeNum('-')"></span>
|
||||
<el-input v-model="number" placeholder="0" @input="keyInput()"></el-input>
|
||||
<span class="increase el-icon-plus" @click="changeNum('+')"></span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="unit">{{ goodsSkuDetail.unit }}</span>
|
||||
<span class="inventory">库存{{ goodsSkuDetail.stock }}{{ goodsSkuDetail.unit }}</span>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<dl class="item-line buy-btn">
|
||||
<dt></dt>
|
||||
<dd v-if="goodsSkuDetail.goods_state == 1">
|
||||
<template>
|
||||
<el-button type="primary" plain @click="buyNow" v-if="goodsSkuDetail.stock > 0">立即抢购</el-button>
|
||||
<el-button type="info" plain v-else disabled>库存不足</el-button>
|
||||
</template>
|
||||
<div class="go-phone icon-item" @click="editCollection">
|
||||
<span :class="['iconfont',(whetherCollection == 1 ? 'icon-_shouzang2 selected' : 'icon-shouzang')]"></span>
|
||||
<span>收藏</span>
|
||||
</div>
|
||||
</dd>
|
||||
<dd v-else>
|
||||
<template>
|
||||
<el-button type="info" plain disabled>该商品已下架</el-button>
|
||||
</template>
|
||||
<div class="go-phone icon-item" @click="editCollection">
|
||||
<span :class="['iconfont',(whetherCollection == 1 ? 'icon-_shouzang2 selected' : 'icon-shouzang')]"></span>
|
||||
<span>收藏</span>
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="item-line merchant-service" v-show="service_list.length">
|
||||
<dt>商品服务</dt>
|
||||
<div>
|
||||
<dd v-for="item in service_list">
|
||||
<i class="el-icon-success"></i>
|
||||
<span class="ns-text-color-gray" :title="item.service_name">{{item.service_name}}</span>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="detail-wrap">
|
||||
<!-- <div class="goods-recommended">
|
||||
<goods-recommend />
|
||||
</div> -->
|
||||
|
||||
<el-tabs class="goods-tab" v-model="tabName" type="card" @tab-click="tabChange">
|
||||
<el-tab-pane label="商品详情" name="detail">
|
||||
<div v-html="goodsSkuDetail.goods_content"></div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="商品属性" name="attr">
|
||||
<ul class="attr-list">
|
||||
<template v-if="goodsSkuDetail.goods_attr_format && goodsSkuDetail.goods_attr_format.length > 0">
|
||||
<li v-for="(item, index) in goodsSkuDetail.goods_attr_format" :key="index">
|
||||
{{ item.attr_name }}:{{ item.attr_value_name }}
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="evaluate_show" :label="goodsEvaluateList.length ? '商品评价(' + goodsEvaluateList.length + ')' : '商品评价'" name="evaluate" class="evaluate">
|
||||
<template v-if="goodsEvaluateList.length">
|
||||
<nav>
|
||||
<li :class="evaluaType == 0 ? 'selected' : ''" @click="evaluationType(0)">全部评价({{evaluteCount.total}})</li>
|
||||
<li :class="evaluaType == 1 ? 'selected' : ''" @click="evaluationType(1)">好评({{evaluteCount.haoping}})</li>
|
||||
<li :class="evaluaType == 2 ? 'selected' : ''" @click="evaluationType(2)">中评({{evaluteCount.zhongping}})</li>
|
||||
<li :class="evaluaType == 3 ? 'selected' : ''" @click="evaluationType(3)">差评({{evaluteCount.chaping}})</li>
|
||||
</nav>
|
||||
<ul class="list">
|
||||
<li v-for="(item, index) in goodsEvaluateList" :key="index">
|
||||
<div class="member-info">
|
||||
<img :src="$img(item.member_headimg)" @error="imageErrorEvaluate(index)" class="avatar" />
|
||||
<span>{{ item.member_name }}</span>
|
||||
</div>
|
||||
<div class="info-wrap">
|
||||
<el-rate v-model="item.star" disabled></el-rate>
|
||||
<p class="content">{{ item.content }}</p>
|
||||
<div class="img-list" v-if="item.images">
|
||||
<el-image v-for="(img, img_index) in item.images" :key="img_index" :src="$img(img)" :preview-src-list="item.imagesFormat"/>
|
||||
</div>
|
||||
<div class="sku-info">
|
||||
<span>{{ item.sku_name }}</span>
|
||||
<span class="create-time">{{ $util.timeStampTurnTime(item.create_time) }}</span>
|
||||
</div>
|
||||
<div class="evaluation-reply" v-if="item.explain_first != ''">店家回复:{{ item.explain_first }}</div>
|
||||
<template v-if="item.again_content != ''">
|
||||
<div class="review-evaluation">
|
||||
<span>追加评价</span>
|
||||
<span class="review-time">{{ $util.timeStampTurnTime(item.again_time) }}</span>
|
||||
</div>
|
||||
<p class="content">{{ item.again_content }}</p>
|
||||
<div class="img-list">
|
||||
<el-image v-for="(again_img, again_index) in item.again_images" :key="again_index" :src="$img(again_img)" :preview-src-list="item.againImagesFormat"/>
|
||||
</div>
|
||||
<div class="evaluation-reply" v-if="item.again_explain != ''">店家回复:{{ item.again_explain }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="pager">
|
||||
<el-pagination background :pager-count="5" :total="total" prev-text="上一页" next-text="下一页"
|
||||
:current-page.sync="currentPage" :page-size.sync="pageSize"
|
||||
@size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange" hide-on-single-page></el-pagination>
|
||||
</div>
|
||||
</template>
|
||||
<div class="empty" v-else>该商品暂无评价哦</div>
|
||||
</el-tab-pane>
|
||||
<template v-if="service">
|
||||
<el-tab-pane v-if="service.is_display == 1" label="售后保障" name="after_sale" class="after-sale">
|
||||
<div v-html="service.content"></div>
|
||||
</el-tab-pane>
|
||||
</template>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<!--联系客服弹窗-->
|
||||
<servicerMessage ref="servicerMessage" class="kefu" :shop="{shop_id:shopInfo.site_id,logo:shopInfo.logo,shop_name:shopInfo.site_name}"></servicerMessage>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PicZoom from "vue-piczoom"
|
||||
import detail from "@/assets/js/promotion/detail_seckill.js"
|
||||
import GoodsRecommend from "@/components/GoodsRecommend"
|
||||
import servicerMessage from "@/components/message/servicerMessage";
|
||||
|
||||
export default {
|
||||
name: "seckill_detail",
|
||||
components: {
|
||||
PicZoom,
|
||||
GoodsRecommend,
|
||||
servicerMessage
|
||||
},
|
||||
mixins: [detail]
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
@import "@/assets/css/promotion/detail_seckill.scss";
|
||||
</style>
|
||||
151
addon/pc/source/os/pages/promotion/seckill/index.vue
Executable file
151
addon/pc/source/os/pages/promotion/seckill/index.vue
Executable file
@@ -0,0 +1,151 @@
|
||||
<template>
|
||||
<div class="ns-seckill">
|
||||
<div class="ns-seckill-head" v-loading="loadingAd">
|
||||
<el-carousel height="420px" v-if="adList.length" indicator-position="none">
|
||||
<el-carousel-item v-for="item in adList" :key="item.adv_id">
|
||||
<el-image :src="$img(item.adv_image)" @click="$util.pushToTab(item.adv_url.url)" />
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
|
||||
<div class="ns-seckill-time-box" v-if="timeList.length > 0">
|
||||
<span v-if="timeList.length > 4" class="left-btn el-icon-arrow-left" @click="changeThumbImg('prev')"></span>
|
||||
<span v-if="timeList.length > 4" class="right-btn el-icon-arrow-right" @click="changeThumbImg('next')"></span>
|
||||
<div class="ns-seckill-time-list" ref="seckillTime">
|
||||
<ul class="seckill-time-ul" :style="{ left: thumbPosition + 'px' }">
|
||||
<!-- 商品缩率图 -->
|
||||
<li v-for="(item, key) in timeList" :key="key" slot="label" class="seckill-time-li" :class="{ 'selected-tab': seckillId == item.id }" @click="handleSelected(key, item)">
|
||||
<div>{{ item.seckill_start_time_show + " - " + item.seckill_end_time_show }}</div>
|
||||
<div v-if="item.type == 'today'">
|
||||
<p class="em font-size-tag " v-if="!item.isNow">即将开始</p>
|
||||
<p class="em font-size-tag " v-else-if="item.isNow">抢购中</p>
|
||||
</div>
|
||||
<div v-else>
|
||||
<p>敬请期待</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 商品列表 -->
|
||||
<div class="ns-seckill-box" v-loading="loading" ref="seckillGoods" v-if="timeList.length > 0 && goodsList.length > 0">
|
||||
<div class="ns-seckill-title">
|
||||
<div class="seckill-title-left">
|
||||
<span class="name">限时秒杀</span>
|
||||
<span class="desc">限时秒杀,每款限购一件</span>
|
||||
</div>
|
||||
|
||||
<div class="ns-seckill-right" v-show="seckillIndex == index && isTrue && isNoClick == false">
|
||||
<span>{{ seckillText }}</span>
|
||||
<count-down class="count-down" v-on:start_callback="countDownS_cb()" v-on:end_callback="countDownE_cb()"
|
||||
:currentTime="seckillTimeMachine.currentTime" :startTime="seckillTimeMachine.startTime"
|
||||
:endTime="seckillTimeMachine.endTime" :dayTxt="':'" :hourTxt="':'" :minutesTxt="':'"
|
||||
:secondsTxt="''">
|
||||
</count-down>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="goods-list">
|
||||
<div class="goods" v-for="(item, key) in goodsList" :key="key" @click="toGoodsDetail(item.id)">
|
||||
<div class="img">
|
||||
<el-image fit="scale-down" :src="$img(item.goods_image, { size: 'mid' })" lazy @error="imageError(index)"/>
|
||||
</div>
|
||||
<div class="name">
|
||||
<p :title="item.goods_name">{{ item.goods_name }}</p>
|
||||
</div>
|
||||
|
||||
<!-- 价格展示区 -->
|
||||
<div class="price">
|
||||
<div class="curr-price">
|
||||
<span>秒杀价</span>
|
||||
<span>¥</span>
|
||||
<span class="main_price">{{ item.seckill_price }}</span>
|
||||
</div>
|
||||
<span class="primary_price">¥{{ item.price }}</span>
|
||||
</div>
|
||||
|
||||
<el-button v-if="seckillIndex == index && timeList[index].isNow && shouType == true">立即抢购</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pager">
|
||||
<el-pagination background :pager-count="5" :total="total" prev-text="上一页" next-text="下一页"
|
||||
:current-page.sync="currentPage" :page-size.sync="pageSize" @size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange" hide-on-single-page></el-pagination>
|
||||
</div>
|
||||
</div>
|
||||
<div class="empty-wrap" v-else-if="!loading">
|
||||
<img src="~assets/images/goods_empty.png">
|
||||
<span>暂无正在进行秒杀的商品,<router-link to="/" class="ns-text-color">去首页</router-link>看看吧</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import list from "@/assets/js/promotion/list_seckill.js"
|
||||
|
||||
export default {
|
||||
name: "seckill",
|
||||
components: {},
|
||||
mixins: [list]
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "@/assets/css/promotion/list_seckill.scss";
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
.seckill-time {
|
||||
.el-tabs__nav-wrap {
|
||||
height: 56px;
|
||||
|
||||
.el-tabs__nav {
|
||||
height: 56px;
|
||||
}
|
||||
|
||||
.el-tabs__nav-next,
|
||||
.el-tabs__nav-prev {
|
||||
line-height: 56px;
|
||||
}
|
||||
|
||||
.el-tabs__item {
|
||||
width: 150px;
|
||||
height: 56px;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.el-tabs__nav-wrap::after {
|
||||
height: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.ns-seckill {
|
||||
.el-carousel {
|
||||
.el-image__inner {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.el-carousel__arrow--right {
|
||||
right: 60px;
|
||||
}
|
||||
|
||||
.count-down {
|
||||
span {
|
||||
display: inline-block;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
text-align: center;
|
||||
background: #383838;
|
||||
color: #fff;
|
||||
border-radius: 6px;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
327
addon/pc/source/os/pages/promotion/seckill/payment/index.vue
Executable file
327
addon/pc/source/os/pages/promotion/seckill/payment/index.vue
Executable file
@@ -0,0 +1,327 @@
|
||||
<template>
|
||||
<div class="payment-wrap" v-loading="fullscreenLoading">
|
||||
|
||||
<!--购买虚拟类商品需填写您的手机号-->
|
||||
<div class="item-block" v-if="orderPaymentData.is_virtual == 1">
|
||||
<div class="block-text">购买虚拟类商品需填写您的手机号,以方便商家与您联系</div>
|
||||
|
||||
<el-form ref="form" size="mini" class="mobile-wrap" label-width="80px">
|
||||
<el-form-item label="手机号码">
|
||||
<el-input placeholder="请输入您的手机号码" maxlength="11" v-model="orderCreateData.member_address.mobile" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<!--收货地址-->
|
||||
<div class="item-block" v-if="orderPaymentData.is_virtual == 0">
|
||||
<div class="block-text">收货地址</div>
|
||||
|
||||
<div class="address-list">
|
||||
<div class="address-item" @click="addAddressShow">
|
||||
<div class="add-address">
|
||||
<i class="el-icon-circle-plus-outline"></i>
|
||||
添加收货地址
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="address-item" v-for="(item, key) in memberAddress" :key="item.id" :class="addressId == item.id ? 'active' : ''" v-if="key < 3 || (addressShow && key >= 3)">
|
||||
<div class="address-info">
|
||||
<div class="options">
|
||||
<div @click="editAddress(item.id)">编辑</div>
|
||||
<template v-if="item.is_default == 0">
|
||||
<el-popconfirm title="确定要删除该地址吗?" @onConfirm="deleteMemberAddress(item.id)">
|
||||
<div slot="reference">删除</div>
|
||||
</el-popconfirm>
|
||||
</template>
|
||||
</div>
|
||||
<div class="address-name">{{ item.name }}</div>
|
||||
<div class="address-mobile" @click="setMemberAddress(item.id)">{{ item.mobile }}</div>
|
||||
<div class="address-desc" @click="setMemberAddress(item.id)">{{ item.full_address }} {{ item.address }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="memberAddress.length > 3 && !addressShow" @click="addressShow = true" class="el-button--text address-open">
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
更多收货地址
|
||||
</div>
|
||||
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--收货地址添加-->
|
||||
<el-dialog :title="addressForm.id == 0 ? '添加收货地址' : '编辑收货地址'" :visible.sync="dialogVisible" width="32%">
|
||||
<el-form ref="form" :rules="addressRules" :model="addressForm" label-width="80px">
|
||||
<el-form-item label="姓名" prop="name">
|
||||
<el-input v-model="addressForm.name" placeholder="收货人姓名" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="手机" prop="mobile">
|
||||
<el-input v-model="addressForm.mobile" maxlength="11" placeholder="收货人手机号" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="电话">
|
||||
<el-input v-model="addressForm.telephone" placeholder="收货人固定电话(选填)" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item class="area" label="地区" prop="area">
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="7">
|
||||
<el-select prop="province" ref="province" v-model="addressForm.province_id" @change="getAddress(1)" placeholder="请选择省">
|
||||
<el-option label="请选择省" value="0"></el-option>
|
||||
<el-option v-for="item in pickerValueArray" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-select ref="city" prop="city" v-model="addressForm.city_id" @change="getAddress(2)" placeholder="请选择市">
|
||||
<el-option label="请选择市" value="0"></el-option>
|
||||
<el-option v-for="item in cityArr" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<el-select ref="district" prop="district" v-model="addressForm.district_id" placeholder="请选择区/县">
|
||||
<el-option label="请选择区/县" value="0"></el-option>
|
||||
<el-option v-for="item in districtArr" :key="item.id" :label="item.name" :value="item.id"></el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="详细地址" prop="address">
|
||||
<el-input v-model="addressForm.address" placeholder="定位小区、街道、写字楼" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="addmemberAddress('form')">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<!--使用余额-->
|
||||
<div class="item-block" v-if="orderPaymentData.member_account.balance_total > 0 && balance_show == 1">
|
||||
<div class="block-text">是否使用余额</div>
|
||||
<div class="pay-type-list">
|
||||
<div class="pay-type-item" :class="orderCreateData.is_balance ? '' : 'active'" @click="useBalance(0)">不使用余额
|
||||
</div>
|
||||
<div class="pay-type-item" :class="orderCreateData.is_balance ? 'active' : ''" @click="useBalance(1)">使用余额</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 支付密码 -->
|
||||
<el-dialog title="使用余额" :visible.sync="dialogpay" width="350px">
|
||||
<template v-if="orderPaymentData.member_account.is_pay_password == 0">
|
||||
<p>为了您的账户安全,请您先设置的支付密码</p>
|
||||
<p>可到"会员中心","账号安全","支付密码"中设置</p>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button size="small" @click="dialogpay = false">暂不设置</el-button>
|
||||
<el-button size="small" type="primary" @click="setPayPassword">立即设置</el-button>
|
||||
</span>
|
||||
</template>
|
||||
<el-form v-else status-icon ref="ruleForm" label-width="100px">
|
||||
<el-form-item label="支付密码" class="pay-password-item">
|
||||
<!--添加一个不可见的input,欺骗浏览器自动填充-->
|
||||
<el-input type="password" class="pay-password hide-password" :maxlength="6"></el-input>
|
||||
<el-input type="password" class="pay-password" :maxlength="6" v-model="password" @input="input"></el-input>
|
||||
</el-form-item>
|
||||
<p class="ns-text-color forget-password" @click="setPayPassword">忘记密码</p>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 配送方式 -->
|
||||
<div class="item-block padd-bom-20" v-if="orderPaymentData.delivery.express_type.length > 0">
|
||||
<div class="block-text">
|
||||
<span>配送方式</span>
|
||||
<span class="distribution" v-if="orderCreateData.delivery.delivery_type == 'store'">{{ orderCreateData.delivery.store_name }}</span>
|
||||
</div>
|
||||
<div class="pay-type-item" v-for="(item, index) in orderPaymentData.delivery.express_type" :key="index" @click="selectDeliveryType(item)" :class="item.name == orderCreateData.delivery.delivery_type ? 'active' : ''">
|
||||
{{ item.title }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--配送方式 门店 -->
|
||||
<el-dialog title="选择门店" :visible.sync="dialogStore" width="50%">
|
||||
<el-table ref="singleTable" :data="storeList" highlight-current-row @row-click="selectStore" class="cursor-pointer">
|
||||
<el-table-column label="" width="55">
|
||||
<template slot-scope="scope">
|
||||
<el-radio v-model="storeRadio" :label="scope.row"><i></i></el-radio>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="store_name" label="名称" width="160"></el-table-column>
|
||||
<el-table-column prop="store_address" label="地址"></el-table-column>
|
||||
<el-table-column prop="open_date" label="营业时间"></el-table-column>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<div class="item-block" v-if="orderPaymentData.invoice">
|
||||
<div class="block-text">发票信息</div>
|
||||
<div class="pay-type-list">
|
||||
<div class="pay-type-item" :class="orderCreateData.is_invoice == 0 ? 'active' : ''" @click="changeIsInvoice">无需发票</div>
|
||||
<div class="pay-type-item" :class="orderCreateData.is_invoice == 1 ? 'active' : ''" @click="changeIsInvoice">需要发票</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<div class="invoice-information" v-if="orderCreateData.is_invoice == 1">
|
||||
<div class="invoice-title">
|
||||
<div class="invoice-type-box invoice-title-box">
|
||||
<span class="invoice-name">发票类型:</span>
|
||||
<label class="invoice-to-type">
|
||||
<i class="invoice-i-input" :class="orderCreateData.invoice_type == 1 ? 'active' : ''" @click="clickType(1)"></i>
|
||||
<span>纸质</span>
|
||||
</label>
|
||||
<label class="invoice-to-type">
|
||||
<i class="invoice-i-input" :class="orderCreateData.invoice_type == 2 ? 'active' : ''" @click="clickType(2)"></i>
|
||||
<span>电子</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="invoice-type-box invoice-title-box">
|
||||
<span class="invoice-name">抬头类型:</span>
|
||||
<label class="invoice-to-type">
|
||||
<i class="invoice-i-input" :class="orderCreateData.invoice_title_type == 1 ? 'active' : ''" @click="clickTitleType(1)"></i>
|
||||
<span>个人</span>
|
||||
</label>
|
||||
<label class="invoice-to-type">
|
||||
<i class="invoice-i-input" :class="orderCreateData.invoice_title_type == 2 ? 'active' : ''" @click="clickTitleType(2)"></i>
|
||||
<span>企业</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="invoice-type-box">
|
||||
<span class="invoice-name">发票信息:</span>
|
||||
<div class="invoice-box-form">
|
||||
<input type="text" placeholder="请填写抬头名称" v-model.trim="orderCreateData.invoice_title" />
|
||||
<input type="text" placeholder="请填写纳税人识别号" v-model.trim="orderCreateData.taxpayer_number" v-if="orderCreateData.invoice_title_type == 2" />
|
||||
<input type="text" placeholder="请填写邮寄地址" v-model.trim="orderCreateData.invoice_full_address" v-show="orderCreateData.invoice_type == 1" />
|
||||
<input type="text" placeholder="请填写邮箱" v-model.trim="orderCreateData.invoice_email" v-show="orderCreateData.invoice_type == 2" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="invoice-condition">
|
||||
<span class="invoice-name">发票内容:</span>
|
||||
<div class="invoice-box-form">
|
||||
<span class="option-item" :key="index" v-for="(item, index) in orderPaymentData.invoice.invoice_content_array" @click="changeInvoiceContent(item)" :class="{ 'color-base-bg active': item == orderCreateData.invoice_content }">
|
||||
{{ item }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="invoice-tops">发票内容将以根据税法调整,具体请以展示为准,发票内容显示详细商品名 称及价格信息</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--商品信息-->
|
||||
<div class="item-block">
|
||||
<div class="goods-list">
|
||||
<table>
|
||||
<tr>
|
||||
<td width="50%">商品</td>
|
||||
<td width="12.5%">价格</td>
|
||||
<td width="12.5%">数量</td>
|
||||
<td width="12.5%">小计</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="item-block" v-if="calculateData">
|
||||
<div class="goods-list">
|
||||
<table>
|
||||
<tr v-for="(goodsItem, goodsIndex) in calculateData.goods_list" :key="goodsIndex">
|
||||
<td width="50%">
|
||||
<div class="goods-info">
|
||||
<div class="goods-info-left">
|
||||
<router-link :to="{ path: '/sku/' + goodsItem.sku_id }" target="_blank">
|
||||
<img class="goods-img" :src="$img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" />
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="goods-info-right">
|
||||
<router-link :to="{ path: '/sku/' + goodsItem.sku_id }" target="_blank">
|
||||
<div class="goods-name">{{ goodsItem.goods_name }}</div>
|
||||
</router-link>
|
||||
<!-- 规格 -->
|
||||
<div class="goods-spec" v-if="goodsItem.sku_spec_format">
|
||||
<span v-for="(x, i) in goodsItem.sku_spec_format" :key="i">{{ x.spec_value_name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td width="12.5%" class="goods-price">¥{{ goodsItem.price }}</td>
|
||||
<td width="12.5%" class="goods-num">{{ goodsItem.num }}</td>
|
||||
<td width="12.5%" class="goods-money">¥{{ (goodsItem.price * goodsItem.num).toFixed(2) }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 活动优惠 -->
|
||||
<div class="item-block" v-if="promotionInfo">
|
||||
<div class="block-text">{{ promotionInfo.title }}</div>
|
||||
<div class="order-cell platform-coupon">
|
||||
<div class="box ns-text-color" v-html="promotionInfo.content"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 买家留言 -->
|
||||
<div class="item-block padd-bom-10">
|
||||
<div class="block-text">买家留言:</div>
|
||||
<el-input rows="3" type="textarea" placeholder="留言前建议先与商家协调一致" v-model="orderCreateData.buyer_message" class="buyer-message" @input="textarea" maxlength="140" show-word-limit resize="none" />
|
||||
</div>
|
||||
|
||||
<!-- 总计 -->
|
||||
<div class="item-block" v-if="calculateData">
|
||||
<div class="order-statistics">
|
||||
<table>
|
||||
<tr>
|
||||
<td align="right">商品金额:</td>
|
||||
<td align="left">¥{{ calculateData.goods_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.is_virtual == 0 && calculateData.delivery_money > 0">
|
||||
<td align="right">运费:</td>
|
||||
<td align="left">¥{{ calculateData.delivery_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.invoice_money > 0">
|
||||
<td align="right">发票税费<span class="ns-text-color">({{ calculateData.invoice.invoice_rate }}%)</span>:</td>
|
||||
<td align="left">¥{{ calculateData.invoice_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.invoice_delivery_money > 0">
|
||||
<td align="right">发票邮寄费:</td>
|
||||
<td align="left">¥{{ calculateData.invoice_delivery_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.promotion_money > 0">
|
||||
<td align="right">优惠:</td>
|
||||
<td align="left">¥{{ calculateData.promotion_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
<tr v-if="calculateData.balance_money > 0">
|
||||
<td align="right">使用余额:</td>
|
||||
<td align="left">¥{{ calculateData.balance_money | moneyFormat }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
||||
<!--结算-->
|
||||
<div class="item-block" v-if="calculateData">
|
||||
<div class="order-submit">
|
||||
<div class="order-money">
|
||||
共{{ calculateData.goods_num }}件,应付金额:
|
||||
<div class="ns-text-color">¥{{ calculateData.pay_money | moneyFormat }}</div>
|
||||
</div>
|
||||
<el-button type="primary" class="el-button--primary" @click="orderCreate">订单结算</el-button>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import detail from '@/assets/js/promotion/payment_seckill.js';
|
||||
|
||||
export default {
|
||||
name: 'seckill_payment',
|
||||
mixins: [detail]
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/assets/css/promotion/payment_seckill.scss';
|
||||
</style>
|
||||
511
addon/pc/source/os/pages/sku/_id/index.vue
Executable file
511
addon/pc/source/os/pages/sku/_id/index.vue
Executable file
@@ -0,0 +1,511 @@
|
||||
<template>
|
||||
<div class="goods-detail-wrap">
|
||||
<div class="detail-nav-wrap" v-if="categoryNameArr">
|
||||
<div class="detail-nav" v-if="categoryNameArr.length">
|
||||
<template v-for="(item, index) in categoryNameArr" :keys="index">
|
||||
<router-link :to="{ path: '/goods/list', query: { category_id: item.category_id, level: index } }">{{ item.name }}
|
||||
</router-link>
|
||||
<span class="iconfont icon-arrow-right"></span>
|
||||
</template>
|
||||
<span class="goods-name">{{ goodsSkuDetail.goods_name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-main">
|
||||
<div class="goods-detail">
|
||||
<div class="preview-wrap">
|
||||
<div class="video-player-wrap" :class="{ show: switchMedia == 'video' }" v-if="goodsSkuDetail.video_url != ''">
|
||||
<client-only>
|
||||
<video-player
|
||||
v-if="goodsSkuDetail.video_url != ''"
|
||||
ref="videoPlayer"
|
||||
:playsinline="true"
|
||||
:options="playerOptions"
|
||||
@play="onPlayerPlay($event)"
|
||||
@pause="onPlayerPause($event)"
|
||||
@ended="onPlayerEnded($event)"
|
||||
@waiting="onPlayerWaiting($event)"
|
||||
@playing="onPlayerPlaying($event)"
|
||||
@loadeddata="onPlayerLoadeddata($event)"
|
||||
@timeupdate="onPlayerTimeupdate($event)"
|
||||
@canplay="onPlayerCanplay($event)"
|
||||
@canplaythrough="onPlayerCanplaythrough($event)"
|
||||
@statechanged="playerStateChanged($event)"
|
||||
@ready="playerReadied"
|
||||
></video-player>
|
||||
</client-only>
|
||||
|
||||
<div class="media-mode" v-if="goodsSkuDetail.video_url != ''">
|
||||
<span :class="{ 'ns-bg-color': switchMedia == 'video' }" @click="switchMedia = 'video'">视频</span>
|
||||
<span :class="{ 'ns-bg-color': switchMedia == 'img' }" @click="switchMedia = 'img'">图片</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- , { size: 'big' } -->
|
||||
<div class="magnifier-wrap">
|
||||
<pic-zoom ref="PicZoom" :url="$img(picZoomUrl)" :scale="2"></pic-zoom>
|
||||
</div>
|
||||
|
||||
<div class="spec-items">
|
||||
<span class="left-btn iconfont icon-weibiaoti35" :class="{ move: moveThumbLeft }" @click="changeThumbImg('prev')"></span>
|
||||
<span class="right-btn iconfont icon-weibiaoti35" :class="{ move: moveThumbRight }" @click="changeThumbImg('next')"></span>
|
||||
<ul :style="{ top: 42 + thumbPosition + 'px' }">
|
||||
<!-- 商品缩率图 -->
|
||||
<li v-for="(item, index) in goodsSkuDetail.sku_images" :key="index" @mousemove="picZoomUrl = item" :class="{ selected: picZoomUrl == item }">
|
||||
<img :src="$img(item, { size: 'small' })" @error="imageErrorSpec(index)" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- <div class="share-collect">
|
||||
<div @click="editCollection">
|
||||
<i class="iconfont" :class="whetherCollection == 1 ? 'iconlikefill ns-text-color' : 'iconlike'"></i>
|
||||
<span data-collects="0">关注商品({{ goodsSkuDetail.collect_num }})</span>
|
||||
</div>
|
||||
<div v-if="kefuConfig.system == 0 && kefuConfig.open_pc == 1">
|
||||
<i class="iconfont icon-zhanghao"></i>
|
||||
<span data-collects="0"><a :href="kefuConfig.open_url" target="_blank">联系客服</a></span>
|
||||
</div>
|
||||
<div @click="service_link" v-else-if="kefuConfig.system == 1">
|
||||
<i class="iconfont icon-zhanghao"></i>
|
||||
<span data-collects="0">联系客服</span>
|
||||
</div>
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
<!-- 商品信息 -->
|
||||
<div class="basic-info-wrap" v-loading="loading">
|
||||
<h1>{{ goodsSkuDetail.goods_name }}</h1>
|
||||
<p class="desc" v-if="goodsSkuDetail.introduction">{{ goodsSkuDetail.introduction }}</p>
|
||||
|
||||
<div class="discount-banner ns-bg-color" v-if="goodsSkuDetail.promotion_type == 1 && discountTimeMachine.currentTime && addonIsExit.discount">
|
||||
<div class="activity-name">
|
||||
<i class="discount-icon iconfont icon-icon_naozhong"></i>
|
||||
<span>限时折扣</span>
|
||||
</div>
|
||||
<div class="surplus-time">
|
||||
<span>{{ discountText }}</span>
|
||||
<count-down
|
||||
class="count-down"
|
||||
v-on:start_callback="countDownS_cb()"
|
||||
v-on:end_callback="countDownE_cb()"
|
||||
:currentTime="discountTimeMachine.currentTime"
|
||||
:startTime="discountTimeMachine.startTime"
|
||||
:endTime="discountTimeMachine.endTime"
|
||||
:dayTxt="'天'"
|
||||
:hourTxt="'小时'"
|
||||
:minutesTxt="'分钟'"
|
||||
:secondsTxt="'秒'"
|
||||
></count-down>
|
||||
|
||||
<!-- :tipText="'距离开始文字1'"
|
||||
:tipTextEnd="'距离结束文字1'"
|
||||
:endText="'结束自定义文字2'"-->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item-block">
|
||||
<div class="promotion-price">
|
||||
<dl class="item-line">
|
||||
<dt class="ns-text-color-gray">销售价</dt>
|
||||
<dd>
|
||||
<em class="yuan ns-text-color">¥</em>
|
||||
<span class="price ns-text-color">{{ goodsSkuDetail.discount_price }}</span>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="item-line" v-if="goodsSkuDetail.promotion_type == 1 && discountTimeMachine.currentTime">
|
||||
<dt class="ns-text-color-gray">原价</dt>
|
||||
<dd>
|
||||
<em class="market-yuan">¥</em>
|
||||
<span class="market-price">{{ goodsSkuDetail.price }}</span>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="item-line" v-if="goodsSkuDetail.member_price > 0">
|
||||
<dt class="ns-text-color-gray">会员价</dt>
|
||||
<dd>
|
||||
<em class="market-yuan">¥</em>
|
||||
<span class="member_price">{{ goodsSkuDetail.member_price }}</span>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="item-line" v-if="goodsSkuDetail.market_price > 0">
|
||||
<dt class="ns-text-color-gray">市场价</dt>
|
||||
<dd>
|
||||
<em class="market-yuan">¥</em>
|
||||
<span class="market-price">{{ goodsSkuDetail.market_price }}</span>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<!-- <div class="statistical">
|
||||
<ul>
|
||||
<li>
|
||||
<p>累计评价</p>
|
||||
<span>{{ goodsSkuDetail.evaluate }}</span>
|
||||
</li>
|
||||
<li>
|
||||
<p>累计销量</p>
|
||||
<span>{{ goodsSkuDetail.sale_num }}{{ goodsSkuDetail.unit }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div> -->
|
||||
<dl class="item-line coupon-list" v-if="addonIsExit.coupon && couponList.length">
|
||||
<dt class="ns-text-color-gray">优惠券</dt>
|
||||
<div>
|
||||
<dd>
|
||||
<p v-for="(item, index) in couponList" :key="index" class="ns-text-color" @click="receiveCoupon(item.coupon_type_id)">
|
||||
<span class="ns-border-color" v-if="item.type == 'discount'">{{ item.discount }}折</span>
|
||||
<span class="ns-border-color" v-if="item.type == 'reward'">¥{{ item.money }}</span>
|
||||
</p>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
<dl class="item-line manjian" v-if="manjian.manjian" style="align-items: top;">
|
||||
<dt>满减</dt>
|
||||
<dd>
|
||||
<i class="i-activity-flag ns-text-color ns-border-color">{{ manjian.manjian_name }}</i>
|
||||
<span>{{ manjian.manjian }}</span>
|
||||
<!-- <view class="item" v-if="manjian.manjian != undefined" style="display: flex;">
|
||||
<view class="free-tip color-base-text color-base-border">满减</view>
|
||||
<text class="font-size-base">{{ manjian.manjian }}</text>
|
||||
</view> -->
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="item-line mansong" v-if="manjian.mansong != undefined">
|
||||
<dt>满送</dt>
|
||||
<dd>
|
||||
<i class="i-activity-flag ns-text-color ns-border-color" style="height: 14px;line-height: 14px;margin-top: 5px;">{{ manjian.manjian_name }}</i>
|
||||
<span>{{ manjian.mansong }}</span>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="item-line" v-if="manjian.free_shipping != undefined">
|
||||
<dt>包邮</dt>
|
||||
<dd>
|
||||
<i class="i-activity-flag ns-text-color ns-border-color">{{ manjian.free_shipping}}</i>
|
||||
</dd>
|
||||
</dl>
|
||||
<!-- <div class="manjian-box">
|
||||
<dl class="item-line manjian manjian-hide" v-if="addonIsExit.manjian && manjian.manjian_name">
|
||||
<dt>满减</dt>
|
||||
<dd>
|
||||
<i class="i-activity-flag ns-text-color ns-border-color">{{ manjian.manjian_name }}</i>
|
||||
<span v-if="manjian.manjian"><i class="i-activity-flag ns-text-color ns-border-color">满减</i></span>
|
||||
<span v-if="manjian.mansong"><i class="i-activity-flag ns-text-color ns-border-color">满送</i></span>
|
||||
<span v-if="manjian.free_shipping"><i class="i-activity-flag ns-text-color ns-border-color">包邮</i></span>
|
||||
</dd>
|
||||
<span class="manjian-open">展开促销<i class="el-icon-arrow-down"></i></span>
|
||||
</dl>
|
||||
<dl class="item-line manjian manjian-show" v-if="addonIsExit.manjian && manjian.manjian_name">
|
||||
<dt>满减</dt>
|
||||
<dd>
|
||||
<span v-if="manjian.manjian"><i class="i-activity-flag ns-text-color ns-border-color">满减</i>{{ manjian.manjian }}</span></br>
|
||||
<span v-if="manjian.mansong"><i class="i-activity-flag ns-text-color ns-border-color">满送</i>{{ manjian.mansong }}</span></br>
|
||||
<span v-if="manjian.free_shipping"><i class="i-activity-flag ns-text-color ns-border-color">包邮</i>{{ manjian.free_shipping }}</span>
|
||||
</dd>
|
||||
</dl>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- <dl class="item-line" v-if="goodsSkuDetail.is_virtual == 0">
|
||||
<dt>运费</dt>
|
||||
<dd>
|
||||
<i class="i-activity-flag ns-text-color ns-border-color" v-if="goodsSkuDetail.is_free_shipping">快递免邮</i>
|
||||
<i class="i-activity-flag ns-text-color ns-border-color" v-else>快递不免邮</i>
|
||||
</dd>
|
||||
</dl> -->
|
||||
<dl class="item-line delivery" v-if="goodsSkuDetail.is_virtual == 0">
|
||||
<dt>配送至</dt>
|
||||
<dd>
|
||||
<div class="region-selected ns-border-color-gray">
|
||||
<span>
|
||||
<template v-if="selectedAddress['level_1']">
|
||||
<template v-for="item in selectedAddress">
|
||||
{{ item.name }}
|
||||
</template>
|
||||
</template>
|
||||
<template v-else>
|
||||
请选择配送地址
|
||||
</template>
|
||||
</span>
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
</div>
|
||||
|
||||
<div class="region-list ns-border-color-gray" :class="{ hide: hideRegion }">
|
||||
<ul class="nav-tabs">
|
||||
<li :class="{ active: currTabAddres == 'province' }" @click="currTabAddres = 'province'">
|
||||
<div>
|
||||
<span>{{ selectedAddress['level_1'] ? selectedAddress['level_1'].name : '请选择省' }}</span>
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
</div>
|
||||
</li>
|
||||
<li :class="{ active: currTabAddres == 'city' }" @click="currTabAddres = 'city'">
|
||||
<div>
|
||||
<span>{{ selectedAddress['level_2'] ? selectedAddress['level_2'].name : '请选择市' }}</span>
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
</div>
|
||||
</li>
|
||||
<li :class="{ active: currTabAddres == 'district' }" @click="currTabAddres = 'district'">
|
||||
<div>
|
||||
<span>{{ selectedAddress['level_3'] ? selectedAddress['level_3'].name : '请选择区/县' }}</span>
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane" :class="{ active: currTabAddres == 'province' }">
|
||||
<ul class="province">
|
||||
<li v-for="(item, index) in provinceArr" :key="index" :class="{ selected: selectedAddress['level_' + item.level] && selectedAddress['level_' + item.level].id == item.id }">
|
||||
<span @click="getAddress('city', item)">{{ item.name }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-pane" :class="{ active: currTabAddres == 'city' }">
|
||||
<ul class="city">
|
||||
<li v-for="(item, index) in cityArr" :key="index" :class="{ selected: selectedAddress['level_' + item.level] && selectedAddress['level_' + item.level].id == item.id }">
|
||||
<span @click="getAddress('district', item)">{{ item.name }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="tab-pane" :class="{ active: currTabAddres == 'district' }">
|
||||
<ul class="district">
|
||||
<li v-for="(item, index) in districtArr" :key="index" :class="{ selected: selectedAddress['level_' + item.level] && selectedAddress['level_' + item.level].id == item.id }">
|
||||
<span @click="getAddress('community', item)">{{ item.name }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="item-line service">
|
||||
<dt>服务</dt>
|
||||
<dd>
|
||||
<span>
|
||||
由
|
||||
<span class="ns-text-color">{{ siteInfo.site_name }}</span>
|
||||
发货并提供售后服务
|
||||
</span>
|
||||
</dd>
|
||||
</dl>
|
||||
<hr class="divider" />
|
||||
<div class="sku-list" v-if="goodsSkuDetail.goods_spec_format">
|
||||
<dl class="item-line" v-for="(item, index) in goodsSkuDetail.goods_spec_format" :key="index">
|
||||
<dt>{{ item.spec_name }}</dt>
|
||||
<dd>
|
||||
<ul>
|
||||
<li v-for="(item_value, index_value) in item.value" :key="index_value">
|
||||
<div :class="{ 'selected ns-border-color': item_value['selected'] || skuId == item_value.sku_id,disabled: item_value['disabled'] || (!item_value['selected'] && specDisabled) }" @click="changeSpec(item_value.sku_id, item_value.spec_id)">
|
||||
<img v-if="item_value.image" :src="$img(item_value.image, { size: 'small' })" />
|
||||
<span>{{ item_value.spec_value_name }}</span>
|
||||
<!-- <i class="iconfont icon-duigou1 ns-text-color"></i> -->
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="buy-number">
|
||||
<dl class="item-line">
|
||||
<dt>数量</dt>
|
||||
<dd>
|
||||
<div class="num-wrap">
|
||||
<div class="operation">
|
||||
<span class="decrease el-icon-minus" @click="changeNum('-')"></span>
|
||||
<el-input v-model="number" placeholder="0" @input="keyInput()"></el-input>
|
||||
<span class="increase el-icon-plus" @click="changeNum('+')"></span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="unit">{{ goodsSkuDetail.unit }}</span>
|
||||
<span class="inventory" v-if="goodsSkuDetail.stock_show">库存{{ goodsSkuDetail.stock }}{{ goodsSkuDetail.unit }}</span>
|
||||
<!-- 限购 -->
|
||||
<em v-if="(goodsSkuDetail.is_limit == 1 && goodsSkuDetail.max_buy > 0) || goodsSkuDetail.min_buy > 1" class="restrictions">
|
||||
<span v-if="(goodsSkuDetail.is_limit == 1 && goodsSkuDetail.max_buy > 0) && goodsSkuDetail.min_buy > 1">({{ goodsSkuDetail.min_buy }}{{ goodsSkuDetail.unit }}起售,限购{{ goodsSkuDetail.max_buy }}{{ goodsSkuDetail.unit }})</span>
|
||||
<span v-else-if="goodsSkuDetail.is_limit == 1 && goodsSkuDetail.max_buy > 0">(限购{{ goodsSkuDetail.max_buy }}{{ goodsSkuDetail.unit }})</span>
|
||||
<span v-else-if="goodsSkuDetail.min_buy > 1">({{ goodsSkuDetail.min_buy }}{{ goodsSkuDetail.unit }}起售)</span>
|
||||
</em>
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<dl class="item-line buy-btn">
|
||||
<dt></dt>
|
||||
<dd v-if="goodsSkuDetail.goods_state == 1">
|
||||
<template v-if="goodsSkuDetail.stock == 0">
|
||||
<el-button type="info" plain disabled>库存不足</el-button>
|
||||
</template>
|
||||
|
||||
<template v-else-if="goodsSkuDetail.max_buy != 0 && goodsSkuDetail.purchased_num >= goodsSkuDetail.max_buy">
|
||||
<el-button type="info" plain disabled>已达最大限购数量</el-button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button type="primary" plain @click="buyNow">立即购买</el-button>
|
||||
<el-button type="primary" icon="el-icon-shopping-cart-2" v-if="goodsSkuDetail.is_virtual == 0" @click="joinCart">加入购物车</el-button>
|
||||
</template>
|
||||
|
||||
<div class="go-phone icon-item" @click="editCollection">
|
||||
<span :class="['iconfont', whetherCollection == 1 ? 'icon-_shouzang2 selected' : 'icon-shouzang']"></span>
|
||||
<span>收藏</span>
|
||||
</div>
|
||||
<div href="javascript:;" class="go-phone">
|
||||
<img src="@/assets/images/goods/qrcode.png" />
|
||||
<span>二维码</span>
|
||||
<div class="qrcode-wrap"><img :src="qrcode" alt="二维码图片" /></div>
|
||||
</div>
|
||||
</dd>
|
||||
|
||||
<dd v-else>
|
||||
<template>
|
||||
<el-button type="info" plain disabled>该商品已下架</el-button>
|
||||
</template>
|
||||
<div class="go-phone icon-item" @click="editCollection">
|
||||
<span :class="['iconfont', whetherCollection == 1 ? 'icon-_shouzang2 selected' : 'icon-shouzang']"></span>
|
||||
<span>收藏</span>
|
||||
</div>
|
||||
<div href="javascript:;" class="go-phone">
|
||||
<img src="@/assets/images/goods/qrcode.png" />
|
||||
<span>二维码</span>
|
||||
<div class="qrcode-wrap"><img :src="qrcode" alt="二维码图片" /></div>
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
<dl class="item-line merchant-service" v-show="service_list.length">
|
||||
<dt>商品服务</dt>
|
||||
<div>
|
||||
<dd v-for="item in service_list">
|
||||
<i class="el-icon-success"></i>
|
||||
<span class="ns-text-color-gray" :title="item.service_name">{{ item.service_name }}</span>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<!-- 组合套餐 -->
|
||||
<el-tabs class="bundling-wrap" v-model="tabBundling" @tab-click="bundlingChange" v-if="addonIsExit.bundling && bundling.length && bundling[0].bl_name">
|
||||
<el-tab-pane :label="item.bl_name" :name="'bundling_' + item.bl_id" v-for="(item, index) in bundling" :key="index">
|
||||
<!-- <div class="master">
|
||||
<div class="sku-img"><img :src="$img(goodsSkuDetail.sku_image, { size: 'mid' })" /></div>
|
||||
<div class="sku-name">{{ goodsSkuDetail.sku_name }}</div>
|
||||
<div class="sku-price ns-text-color">¥{{ goodsSkuDetail.discount_price }}</div>
|
||||
<i class="el-icon-plus"></i>
|
||||
</div> -->
|
||||
<div class="operation">
|
||||
<div class="price-wrap">
|
||||
<span>组合套餐价</span>
|
||||
<strong class="bl-price ns-text-color">¥{{ item.bl_price }}</strong>
|
||||
</div>
|
||||
<el-button type="primary" size="medium" @click="$router.push('/promotion/combo/' + item.bl_id)">立即购买</el-button>
|
||||
<i class="equal">=</i>
|
||||
</div>
|
||||
|
||||
<div class="suits">
|
||||
<ul>
|
||||
<li v-for="(goods, goods_index) in item.bundling_goods" :key="goods_index" @click="$util.pushToTab({ path: '/sku/' + goods.sku_id })">
|
||||
<div class="sku-img"><img :src="$img(goods.sku_image, { size: 'mid' })" /></div>
|
||||
<div class="sku-name">{{ goods.sku_name }}</div>
|
||||
<div class="sku-price ns-text-color">¥{{ goods.price }}</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<div class="detail-wrap">
|
||||
<!-- <div class="goods-recommended">
|
||||
<goods-recommend />
|
||||
</div> -->
|
||||
|
||||
<el-tabs class="goods-tab" v-model="tabName" type="card" @tab-click="tabChange">
|
||||
<el-tab-pane label="商品详情" name="detail">
|
||||
<div v-html="goodsSkuDetail.goods_content"></div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="商品属性" name="attr">
|
||||
<ul class="attr-list">
|
||||
<template v-if="goodsSkuDetail.goods_attr_format && goodsSkuDetail.goods_attr_format.length > 0">
|
||||
<li v-for="(item, index) in goodsSkuDetail.goods_attr_format" :key="index">{{ item.attr_name }}:{{ item.attr_value_name }}</li>
|
||||
</template>
|
||||
</ul>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="evaluate_show" :label="evaluteCount.total ? '商品评价(' + evaluteCount.total + ')' : '商品评价'" name="evaluate" class="evaluate">
|
||||
<template v-if="evaluteCount.total">
|
||||
<nav>
|
||||
<li :class="evaluaType == 0 ? 'selected' : ''" @click="evaluationType(0)">全部评价({{ evaluteCount.total }})</li>
|
||||
<li :class="evaluaType == 1 ? 'selected' : ''" @click="evaluationType(1)">好评({{ evaluteCount.haoping }})</li>
|
||||
<li :class="evaluaType == 2 ? 'selected' : ''" @click="evaluationType(2)">中评({{ evaluteCount.zhongping }})</li>
|
||||
<li :class="evaluaType == 3 ? 'selected' : ''" @click="evaluationType(3)">差评({{ evaluteCount.chaping }})</li>
|
||||
</nav>
|
||||
<ul class="list">
|
||||
<li v-for="(item, index) in goodsEvaluateList" :key="index">
|
||||
<div class="member-info">
|
||||
<img :src="$img(item.member_headimg)" @error="imageErrorEvaluate(index)" class="avatar" />
|
||||
<span>{{ item.member_name }}</span>
|
||||
</div>
|
||||
<div class="info-wrap">
|
||||
<el-rate v-model="item.star" disabled></el-rate>
|
||||
<p class="content">{{ item.content }}</p>
|
||||
<div class="img-list" v-if="item.images">
|
||||
<el-image v-for="(img, img_index) in item.images" :key="img_index" :src="$img(img)" :preview-src-list="item.imagesFormat"/>
|
||||
</div>
|
||||
<div class="sku-info">
|
||||
<span>{{ item.sku_name }}</span>
|
||||
<span class="create-time">{{ $util.timeStampTurnTime(item.create_time) }}</span>
|
||||
</div>
|
||||
<div class="evaluation-reply" v-if="item.explain_first != ''">店家回复:{{ item.explain_first }}</div>
|
||||
<template v-if="item.again_is_audit == 1">
|
||||
<div class="review-evaluation">
|
||||
<span>追加评价</span>
|
||||
<span class="review-time">{{ $util.timeStampTurnTime(item.again_time) }}</span>
|
||||
</div>
|
||||
<p class="content">{{ item.again_content }}</p>
|
||||
<div class="img-list">
|
||||
<el-image v-for="(again_img, again_index) in item.again_images" :key="again_index" :src="$img(again_img)" :preview-src-list="item.againImagesFormat" />
|
||||
</div>
|
||||
<div class="evaluation-reply" v-if="item.again_explain != ''">店家回复:{{ item.again_explain }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="pager">
|
||||
<el-pagination
|
||||
background
|
||||
:pager-count="5"
|
||||
:total="total"
|
||||
prev-text="上一页"
|
||||
next-text="下一页"
|
||||
:current-page.sync="currentPage"
|
||||
:page-size.sync="pageSize"
|
||||
@size-change="handlePageSizeChange"
|
||||
@current-change="handleCurrentPageChange"
|
||||
hide-on-single-page
|
||||
></el-pagination>
|
||||
</div>
|
||||
</template>
|
||||
<div class="empty" v-else>该商品暂无评价哦</div>
|
||||
</el-tab-pane>
|
||||
<template v-if="service">
|
||||
<el-tab-pane v-if="service_is_display.is_display == 1" :label="service.title" name="after_sale" class="after-sale">
|
||||
<div v-html="service.content"></div>
|
||||
</el-tab-pane>
|
||||
</template>
|
||||
</el-tabs>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PicZoom from 'vue-piczoom';
|
||||
import detail from '@/assets/js/goods/detail';
|
||||
import GoodsRecommend from '@/components/GoodsRecommend';
|
||||
|
||||
export default {
|
||||
name: 'detail',
|
||||
components: {
|
||||
PicZoom,
|
||||
GoodsRecommend,
|
||||
},
|
||||
mixins: [detail]
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
@import '@/assets/css/goods/detail.scss';
|
||||
</style>
|
||||
Reference in New Issue
Block a user