|
@@ -0,0 +1,453 @@
|
|
|
+<template>
|
|
|
+ <div class="invoice-modules">
|
|
|
+ <h4 class="module-label">发票信息</h4>
|
|
|
+ <ul class="invoice-list">
|
|
|
+ <li class="invoice-select-w" :class="{'is-active': invoiceStatus === 0}" @click="invoiceType=0;">
|
|
|
+ 不需要发票
|
|
|
+ </li>
|
|
|
+ <li class="invoice-select-w" :class="{'is-active': invoiceStatus === 2}" @click="visible = true;invoiceType=2;">
|
|
|
+ 增值税普票(电子发票)
|
|
|
+ </li>
|
|
|
+ <li class="invoice-select-w" :class="{'is-active': invoiceStatus === 3}" @click="visible = true;invoiceType=3;">
|
|
|
+ 增值税专用发票
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ <h-modal :visible="visible" :showClose="false">
|
|
|
+ <div class="invoice-modal">
|
|
|
+ <h2 class="modal-title">发票信息</h2>
|
|
|
+ <div class="modal-content">
|
|
|
+ <div class="form-tabs">
|
|
|
+ <div class="tab" :class="{'is-active': invoiceType === item.type}" v-for="item in tabs" :key="item.type" @click="invoiceType=item.type">{{item.name}}</div>
|
|
|
+ </div>
|
|
|
+ <!-- 电子发票 -->
|
|
|
+ <div class="form form-1" v-show="invoiceType === 2">
|
|
|
+ <div class="form-item">
|
|
|
+ <div class="form-label">*电子发票</div>
|
|
|
+ <div class="form-input">
|
|
|
+ <input type="text" placeholder="接受发票的邮箱地址" v-model="invoiceForm.emailAddress">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="form-item">
|
|
|
+ <div class="form-label"></div>
|
|
|
+ <div class="form-input">
|
|
|
+ <span class="select-label " :class="{'is-active': invoiceSubType === 1}" @click="invoiceSubType = 1">个人</span>
|
|
|
+ <span class="select-label" :class="{'is-active': invoiceSubType === 2}" @click="invoiceSubType = 2">单位</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="form-item" v-show="invoiceSubType === 1">
|
|
|
+ <div class="form-label">*发票抬头</div>
|
|
|
+ <div class="form-input">
|
|
|
+ <input type="text" placeholder="个人" v-model="invoiceForm.title">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="form-item" v-show="invoiceSubType === 2">
|
|
|
+ <div class="form-label">*发票抬头</div>
|
|
|
+ <div class="form-input">
|
|
|
+ <input type="text" placeholder="请输入单位名称" v-model="invoiceForm.title">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="form-item" v-show="invoiceSubType === 2">
|
|
|
+ <div class="form-label">*纳税人识别号</div>
|
|
|
+ <div class="form-input">
|
|
|
+ <input type="text" placeholder="请输入18位税务登记号" v-model="invoiceForm.code">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 专用发票 -->
|
|
|
+ <div class="form" v-show="invoiceType === 3">
|
|
|
+ <div class="form-item">
|
|
|
+ <div class="form-label">*单位名称</div>
|
|
|
+ <div class="form-input">
|
|
|
+ <input type="text" placeholder="" v-model="invoiceForm3.title">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="form-item">
|
|
|
+ <div class="form-label">*纳税人识别号</div>
|
|
|
+ <div class="form-input">
|
|
|
+ <input type="text" placeholder="" v-model="invoiceForm3.code">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="form-item">
|
|
|
+ <div class="form-label">*注册地址</div>
|
|
|
+ <div class="form-input">
|
|
|
+ <input type="text" placeholder="" v-model="invoiceForm3.organizedAddress">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="form-item">
|
|
|
+ <div class="form-label">*注册电话</div>
|
|
|
+ <div class="form-input">
|
|
|
+ <input type="text" placeholder="" v-model="invoiceForm3.registerPhone">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="form-item">
|
|
|
+ <div class="form-label">*开户银行</div>
|
|
|
+ <div class="form-input">
|
|
|
+ <input type="text" placeholder="" v-model="invoiceForm3.bankName" >
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="form-item">
|
|
|
+ <div class="form-label">*银行账户</div>
|
|
|
+ <div class="form-input">
|
|
|
+ <input type="text" placeholder="" v-model="invoiceForm3.bankAccount">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="modal-tips">
|
|
|
+ <div class="tips-left">温馨提示:</div>
|
|
|
+ <div class="tips-content">专票随商品一并寄出,若因特殊情况会于10天内顺丰寄送给您(如遇节假日稍有延迟)。请注意查收;增值税专用发票收到后请妥善保存,如退货请一同寄回,如退货专票未能寄回,则需扣除相应的税点。</div>
|
|
|
+ </div>
|
|
|
+ <div class="actions-w">
|
|
|
+ <div class="cancel-btn" @click="visible=false">取消</div>
|
|
|
+ <div class="submit-btn" @click="saveInvoice">保存并使用</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </h-modal>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { mapState } from 'vuex'
|
|
|
+import { reg } from '@/util'
|
|
|
+
|
|
|
+var cloneObj = function (obj) {
|
|
|
+ var newObj = {}
|
|
|
+ if (obj instanceof Array) {
|
|
|
+ newObj = []
|
|
|
+ }
|
|
|
+ for (var key in obj) {
|
|
|
+ var val = obj[key] || ''
|
|
|
+ newObj[key] = typeof val === 'object' ? cloneObj(val) : val
|
|
|
+ }
|
|
|
+ return newObj
|
|
|
+}
|
|
|
+
|
|
|
+export default {
|
|
|
+ data () {
|
|
|
+ return {
|
|
|
+ visible: false,
|
|
|
+ tabs: [{
|
|
|
+ name: '电子普通发票',
|
|
|
+ type: 2
|
|
|
+ }, {
|
|
|
+ name: '专用发票',
|
|
|
+ type: 3
|
|
|
+ }],
|
|
|
+ invoiceForm: {
|
|
|
+ title: ''
|
|
|
+ },
|
|
|
+ invoiceForm3: {},
|
|
|
+ invoiceType: 2,
|
|
|
+ invoiceSubType: 1,
|
|
|
+ invoiceStatus: 0
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ ...mapState({
|
|
|
+ token: state => state.user.token,
|
|
|
+ langToast: state => state.language.home.toast,
|
|
|
+ language: state => state.language.current,
|
|
|
+ editInvoice2: state => {
|
|
|
+ let type = Object.prototype.toString.call(state.user.invoice2)
|
|
|
+ if (type === '[object Object]') {
|
|
|
+ return state.user.invoice2
|
|
|
+ }
|
|
|
+ let condition = state.user.invoice2 && state.user.invoice2 !== 'null' && type !== '[object Array]'
|
|
|
+ return cloneObj(condition ? JSON.parse(state.user.invoice2) : {})
|
|
|
+ },
|
|
|
+ editInvoice3: state => {
|
|
|
+ let type = Object.prototype.toString.call(state.user.invoice3)
|
|
|
+ if (type === '[object Object]') {
|
|
|
+ return state.user.invoice3
|
|
|
+ }
|
|
|
+ let condition = state.user.invoice3 && state.user.invoice3 !== 'null' && type !== '[object Array]'
|
|
|
+ return cloneObj(condition ? JSON.parse(state.user.invoice3) : {})
|
|
|
+ },
|
|
|
+ invoice2: state => {
|
|
|
+ let type = Object.prototype.toString.call(state.user.invoice2)
|
|
|
+ if (type === '[object Object]') {
|
|
|
+ return state.user.invoice2
|
|
|
+ }
|
|
|
+ let condition = state.user.invoice2 && state.user.invoice2 !== 'null' && type !== '[object Array]'
|
|
|
+ return (condition ? JSON.parse(state.user.invoice2) : {})
|
|
|
+ },
|
|
|
+ invoice3: state => {
|
|
|
+ let type = Object.prototype.toString.call(state.user.invoice3)
|
|
|
+ if (type === '[object Object]') {
|
|
|
+ return state.user.invoice3
|
|
|
+ }
|
|
|
+ let condition = state.user.invoice3 && state.user.invoice3 !== 'null' && type !== '[object Array]'
|
|
|
+
|
|
|
+ return (condition ? JSON.parse(state.user.invoice3) : {})
|
|
|
+ }
|
|
|
+ }),
|
|
|
+
|
|
|
+ },
|
|
|
+ mounted () {
|
|
|
+ this.invoiceForm3 = this.editInvoice3
|
|
|
+ this.invoiceForm = this.editInvoice2
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ saveInvoice () {
|
|
|
+ let isObject = function (obj) {
|
|
|
+ return JSON.stringify(obj) === '{}' ? '' : obj
|
|
|
+ }
|
|
|
+ let params = {}
|
|
|
+ const { invoiceType, invoiceSubType } = this
|
|
|
+ let check = value => {
|
|
|
+ for (let i = 0, len = value.length; i < len; i++) {
|
|
|
+ if (!value[i].val) {
|
|
|
+ return this.$toast.show('warn', (this.language === 'en' ? value[i].En : value[i].name) + this.langToast['7'])
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true
|
|
|
+ }
|
|
|
+
|
|
|
+ if (invoiceType === 2) {
|
|
|
+ let { title, code } = this.invoiceForm
|
|
|
+ code = invoiceSubType === 1 ? '' : code
|
|
|
+ if (invoiceSubType === 2 && code.length !== 18) {
|
|
|
+ return this.$toast.show('warn', this.langToast['21'])
|
|
|
+ }
|
|
|
+ params = {
|
|
|
+ invoiceType,
|
|
|
+ title,
|
|
|
+ code
|
|
|
+ }
|
|
|
+
|
|
|
+ let checkStr = [
|
|
|
+ {
|
|
|
+ name: '发票抬头',
|
|
|
+ En: 'Title',
|
|
|
+ val: title
|
|
|
+ },
|
|
|
+ // {
|
|
|
+ // name: '电子邮箱',
|
|
|
+ // En: 'Email',
|
|
|
+ // val: emailAddress
|
|
|
+ // }
|
|
|
+ ]
|
|
|
+ if (!check(checkStr)) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ let {title: title1, code: code1, organizedAddress: organizedAddress1, registerPhone: registerPhone1, bankName: bankName1, bankAccount: bankAccount1} = this.invoiceForm3
|
|
|
+ let title = isObject(title1)
|
|
|
+ let code = isObject(code1)
|
|
|
+ let organizedAddress = isObject(organizedAddress1)
|
|
|
+ let registerPhone = isObject(registerPhone1)
|
|
|
+ let bankName = isObject(bankName1)
|
|
|
+ let bankAccount = isObject(bankAccount1)
|
|
|
+
|
|
|
+ params = {
|
|
|
+ invoiceType,
|
|
|
+ title,
|
|
|
+ code,
|
|
|
+ organizedAddress,
|
|
|
+ registerPhone,
|
|
|
+ bankName,
|
|
|
+ bankAccount
|
|
|
+ }
|
|
|
+ let checkStr = [
|
|
|
+ {
|
|
|
+ name: '发票抬头',
|
|
|
+ En: 'Title',
|
|
|
+ val: title
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '税务登记号',
|
|
|
+ En: 'Code',
|
|
|
+ val: code
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '注册地址',
|
|
|
+ En: 'Organized Address',
|
|
|
+ val: organizedAddress
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '注册电话',
|
|
|
+ En: 'Register Phone',
|
|
|
+ val: registerPhone
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '开户银行',
|
|
|
+ En: 'Bank Name',
|
|
|
+ val: bankName
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: '银行账号',
|
|
|
+ En: 'Bank Account',
|
|
|
+ val: bankAccount
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ if (!check(checkStr)) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (!code || code.length !== 18) {
|
|
|
+ return this.$toast.show('warn', this.langToast['21'])
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!reg.guhua.test(registerPhone)) {
|
|
|
+ return this.$toast.show('warn', this.langToast['22'])
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ this.$http
|
|
|
+ .post('user/invoice/save', params, {
|
|
|
+ headers: {
|
|
|
+ token: this.token
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .then(data => {
|
|
|
+ this.invoiceStatus = true
|
|
|
+ this.$store.dispatch('getInvoice', {
|
|
|
+ type: invoiceType,
|
|
|
+ params: {
|
|
|
+ invoiceType: invoiceType
|
|
|
+ }
|
|
|
+ })
|
|
|
+ this.invoiceStatus = this.invoiceType
|
|
|
+ this.visible = false
|
|
|
+ console.log(this.invoice2)
|
|
|
+ let invoice = this.invoiceType === 2 ? this.invoice2 : this.invoice3
|
|
|
+ invoice['invoiceType'] = invoice['type']
|
|
|
+ this.$emit('change', invoice)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+<style lang="less" scoped>
|
|
|
+.invoice-modules {
|
|
|
+ height: 133px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+.invoice-list {
|
|
|
+ display: flex;
|
|
|
+ .invoice-select-w {
|
|
|
+ margin-right: 20px;
|
|
|
+ width: 250px;
|
|
|
+ height: 55px;
|
|
|
+ line-height: 55px;
|
|
|
+ text-align: center;
|
|
|
+ background: #F7F7F7;
|
|
|
+ border: 1px solid #F7F7F7;
|
|
|
+ font-size: 12px;
|
|
|
+ cursor: pointer;
|
|
|
+ &.is-active {
|
|
|
+ border-color: #1FE4DC;
|
|
|
+ background: #fff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+.invoice-modal {
|
|
|
+ width: 533px;
|
|
|
+ text-align: center;
|
|
|
+ padding: 38px;
|
|
|
+ .modal-title {
|
|
|
+ font-size: 20px;
|
|
|
+ line-height: 25px;
|
|
|
+ margin-bottom: 27px;
|
|
|
+ }
|
|
|
+ .form-tabs {
|
|
|
+
|
|
|
+
|
|
|
+ margin-bottom: 30px;
|
|
|
+ .tab {
|
|
|
+ display: inline-block;
|
|
|
+ width: 50%;
|
|
|
+ padding-bottom: 12px;
|
|
|
+ border-bottom: 1px solid #707070;
|
|
|
+ cursor: pointer;
|
|
|
+ &.is-active {
|
|
|
+ font-weight: bold;
|
|
|
+ border-bottom: 2px solid #1FE4DC;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .form-1 {
|
|
|
+ min-height: 213px;
|
|
|
+ }
|
|
|
+ .form-item {
|
|
|
+ width: 100%;
|
|
|
+ padding-left: 128px;
|
|
|
+ position: relative;
|
|
|
+ margin-bottom: 20px;
|
|
|
+ color: #202020;
|
|
|
+ .form-label {
|
|
|
+ position: absolute;
|
|
|
+ left: 0;
|
|
|
+ line-height: 42px;
|
|
|
+ }
|
|
|
+ input {
|
|
|
+ width: 100%;
|
|
|
+ border:1px solid rgba(144,144,144,1);
|
|
|
+ opacity:1;
|
|
|
+ border-radius:3px;
|
|
|
+ padding-left: 10px;
|
|
|
+ line-height: 42px;
|
|
|
+ font-size: 16px;
|
|
|
+ }
|
|
|
+ .form-input {
|
|
|
+ text-align: left;
|
|
|
+ }
|
|
|
+ .select-label {
|
|
|
+ position: relative;
|
|
|
+ padding-left: 22px;
|
|
|
+ cursor: pointer;
|
|
|
+ margin-right: 70px;
|
|
|
+ &::before {
|
|
|
+ content: '';
|
|
|
+ display: inline-block;
|
|
|
+ width: 12px;
|
|
|
+ height: 12px;
|
|
|
+ border-radius: 50%;
|
|
|
+ border: 1px solid #909090;
|
|
|
+ vertical-align: middle;
|
|
|
+ position: absolute;
|
|
|
+ top: 5px;
|
|
|
+ left: 0;
|
|
|
+ background: #fff;
|
|
|
+ }
|
|
|
+ &.is-active {
|
|
|
+ &::before {
|
|
|
+ background: #1FE4DC;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .modal-tips {
|
|
|
+ background: #F7F7F7;
|
|
|
+ font-size: 10px;
|
|
|
+ padding: 12px 22px;
|
|
|
+ margin-top: 26px;
|
|
|
+ &>* {
|
|
|
+ display: inline-block;
|
|
|
+ vertical-align: middle;
|
|
|
+ text-align: left;
|
|
|
+ }
|
|
|
+ .tips-content {
|
|
|
+ width: 345px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .actions-w {
|
|
|
+ display: flex;
|
|
|
+ width: 100%;
|
|
|
+ margin-top: 40px;
|
|
|
+ & > div {
|
|
|
+ flex: 1;
|
|
|
+ height: 55px;
|
|
|
+ line-height: 55px;
|
|
|
+ text-align: center;
|
|
|
+ margin-right: 0;
|
|
|
+ font-weight: bold;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ .cancel-btn {
|
|
|
+ margin-right: 26px;
|
|
|
+ background: #EBEBEB;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|