开票
Showing
3 changed files
with
335 additions
and
73 deletions
| ... | @@ -205,12 +205,12 @@ | ... | @@ -205,12 +205,12 @@ |
| 205 | <text class="value ">{{ item.orderName || '——' }}</text> | 205 | <text class="value ">{{ item.orderName || '——' }}</text> |
| 206 | </view> | 206 | </view> |
| 207 | <text :class="{ | 207 | <text :class="{ |
| 208 | 'status-wait': item.auditStatus == 0, | 208 | 'status-wait': item.payStatus == 3, |
| 209 | 'status-pending': item.auditStatus == 1, | 209 | 'status-pending': item.payStatus == 0, |
| 210 | 'status-success': item.auditStatus == 2, | 210 | 'status-success': item.payStatus == 1, |
| 211 | 'status-danger': item.auditStatus == 3 | 211 | 'status-danger': item.payStatus == 2 |
| 212 | }" | 212 | }" |
| 213 | class="status-tag ">{{ getAuditStatusText(item.auditStatus) }} | 213 | class="status-tag ">{{ getStatusText(item.payStatus) }} |
| 214 | </text> | 214 | </text> |
| 215 | </view> | 215 | </view> |
| 216 | </view> | 216 | </view> |
| ... | @@ -228,7 +228,6 @@ | ... | @@ -228,7 +228,6 @@ |
| 228 | <view class="date"> | 228 | <view class="date"> |
| 229 | <view class="data-header"> | 229 | <view class="data-header"> |
| 230 | <text class="value"> | 230 | <text class="value"> |
| 231 | <text class="tradeNo">缴费编号:</text> | ||
| 232 | {{ item.wfCode || '——' }} | 231 | {{ item.wfCode || '——' }} |
| 233 | </text> | 232 | </text> |
| 234 | </view> | 233 | </view> |
| ... | @@ -297,7 +296,7 @@ | ... | @@ -297,7 +296,7 @@ |
| 297 | <template v-if="item.payStatus == 1 && item.invoiceStatus != 1&& item.auditStatus == 2 &&item.price>0"> | 296 | <template v-if="item.payStatus == 1 && item.invoiceStatus != 1&& item.auditStatus == 2 &&item.price>0"> |
| 298 | <button :disabled="item.invoiceStatus === 1" class="btn btn-view-invoice" | 297 | <button :disabled="item.invoiceStatus === 1" class="btn btn-view-invoice" |
| 299 | @click.stop="makeInvoiceFN(item)"> | 298 | @click.stop="makeInvoiceFN(item)"> |
| 300 | 申请票据 | 299 | 申请开票 |
| 301 | </button> | 300 | </button> |
| 302 | </template> | 301 | </template> |
| 303 | <!-- 已申请票据:查看票据 --> | 302 | <!-- 已申请票据:查看票据 --> |
| ... | @@ -718,12 +717,15 @@ const makeInvoiceFN = (item) => { | ... | @@ -718,12 +717,15 @@ const makeInvoiceFN = (item) => { |
| 718 | needRefresh.value = true; | 717 | needRefresh.value = true; |
| 719 | // 根据tab类型决定跳转页面:个人/单位会员开非税票,级位/段位/越段考试开增值税票 | 718 | // 根据tab类型决定跳转页面:个人/单位会员开非税票,级位/段位/越段考试开增值税票 |
| 720 | let url = ''; | 719 | let url = ''; |
| 720 | const ziZhangBu = item.ziZhangBu ? '&ziZhangBu=1' : ''; | ||
| 721 | if (currentTab.value === '0' || currentTab.value === '1') { | 721 | if (currentTab.value === '0' || currentTab.value === '1') { |
| 722 | // 个人/单位会员 - 非税开票 | 722 | // 个人/单位会员 - 非税开票 |
| 723 | url = `/pages/invoice/applyFeisui?orderId=${item.id}&amount=${item.price}`; | 723 | // 如果是對公转账(ziZhangBu有值),只能开企业发票 |
| 724 | |||
| 725 | url = `/pages/invoice/applyFeisui?orderId=${item.id}&amount=${item.price}${ziZhangBu}`; | ||
| 724 | } else { | 726 | } else { |
| 725 | // 级位/段位/越段考试 - 增值税开票 | 727 | // 级位/段位/越段考试 - 增值税开票 |
| 726 | url = `/pages/invoice/apply?orderId=${item.id}&amount=${item.price}`; | 728 | url = `/pages/invoice/apply?orderId=${item.id}&amount=${item.price}${ziZhangBu}`; |
| 727 | } | 729 | } |
| 728 | uni.navigateTo({ url }); | 730 | uni.navigateTo({ url }); |
| 729 | }; | 731 | }; | ... | ... |
| 1 | <template> | 1 | <template> |
| 2 | <view class="invoice-apply"> | 2 | <view class="invoice-apply"> |
| 3 | <!-- 成功确认弹框 --> | ||
| 4 | <view class="success-modal" v-if="showSuccessModal"> | ||
| 5 | <view class="success-mask" @click="closeSuccessModal"></view> | ||
| 6 | <view class="success-content"> | ||
| 7 | <view class="success-icon">✓</view> | ||
| 8 | <view class="success-title">发票申请提交成功!</view> | ||
| 9 | <view class="success-desc">您的发票申请已成功提交,我们将在1-7个工作日内为您处理。</view> | ||
| 10 | <button class="success-btn" @click="closeSuccessModal">确定</button> | ||
| 11 | </view> | ||
| 12 | </view> | ||
| 13 | |||
| 3 | <view class="content"> | 14 | <view class="content"> |
| 4 | <!-- 发票类型 --> | 15 | <!-- 开票类型 --> |
| 5 | <view class="form-item"> | 16 | <view class="form-item"> |
| 17 | <text class="label">开票类型</text> | ||
| 18 | <view class="type-select"> | ||
| 19 | <view | ||
| 20 | :class="{ active: form.type === '1' }" | ||
| 21 | class="type-option" | ||
| 22 | @click="changeInvoiceType('1')" | ||
| 23 | > | ||
| 24 | <view class="type-icon enterprise">企</view> | ||
| 25 | <view class="type-info"> | ||
| 26 | <text class="type-name">企业单位</text> | ||
| 27 | <text class="type-desc">可开增值税发票</text> | ||
| 28 | </view> | ||
| 29 | </view> | ||
| 30 | <view | ||
| 31 | v-if="showPersonalType" | ||
| 32 | :class="{ active: form.type === '2' }" | ||
| 33 | class="type-option" | ||
| 34 | @click="changeInvoiceType('2')" | ||
| 35 | > | ||
| 36 | <view class="type-icon">个</view> | ||
| 37 | <view class="type-info"> | ||
| 38 | <text class="type-name">个人/非企业</text> | ||
| 39 | <text class="type-desc">仅可开普通发票</text> | ||
| 40 | </view> | ||
| 41 | </view> | ||
| 42 | </view> | ||
| 43 | </view> | ||
| 44 | |||
| 45 | <!-- 发票类型(企业才显示两个选项) --> | ||
| 46 | <view v-if="form.type === '1'" class="form-item"> | ||
| 6 | <text class="label">发票类型</text> | 47 | <text class="label">发票类型</text> |
| 7 | <view class="type-select"> | 48 | <view class="type-select"> |
| 8 | <!-- <view | 49 | <view |
| 9 | :class="{ active: form.invoiceType === '2' }" | 50 | :class="{ active: form.invoiceType === '2' }" |
| 10 | class="type-option" | 51 | class="type-option" |
| 11 | @click="form.invoiceType = '2'" | 52 | @click="form.invoiceType = '2'" |
| 12 | > | 53 | > |
| 13 | <view class="type-icon">个</view> | 54 | <view class="type-icon">普</view> |
| 14 | <view class="type-info"> | 55 | <view class="type-info"> |
| 15 | <text class="type-name">非税票</text> | 56 | <text class="type-name">普通发票</text> |
| 16 | <text class="type-desc">个人/非企业单位</text> | 57 | <text class="type-desc">个人/非企业单位</text> |
| 17 | </view> | 58 | </view> |
| 18 | </view> --> | 59 | </view> |
| 19 | <view | 60 | <view |
| 20 | :class="{ active: form.invoiceType === '1' }" | 61 | :class="{ active: form.invoiceType === '1' }" |
| 21 | class="type-option" | 62 | class="type-option" |
| 22 | @click="form.invoiceType = '1'" | 63 | @click="form.invoiceType = '1'" |
| 23 | > | 64 | > |
| 24 | <view class="type-icon enterprise">企</view> | 65 | <view class="type-icon enterprise">增</view> |
| 25 | <view class="type-info"> | 66 | <view class="type-info"> |
| 26 | <text class="type-name">增值税发票</text> | 67 | <text class="type-name">增值税专用票据</text> |
| 27 | <text class="type-desc">企业/可抵扣</text> | 68 | <text class="type-desc">企业/可抵扣</text> |
| 28 | </view> | 69 | </view> |
| 29 | </view> | 70 | </view> |
| ... | @@ -36,17 +77,19 @@ | ... | @@ -36,17 +77,19 @@ |
| 36 | <input | 77 | <input |
| 37 | v-model="form.name" | 78 | v-model="form.name" |
| 38 | class="input" | 79 | class="input" |
| 39 | placeholder="请输入公司全称或个人姓名" | 80 | :disabled="!showPersonalType && form.invoiceType === '1'" |
| 81 | :placeholder="form.type === '1' ? '请输入公司全称' : '请输入发票抬头'" | ||
| 40 | /> | 82 | /> |
| 41 | <text class="hint">请确保发票抬头与公司营业执照或个人身份证上的名称一致。</text> | 83 | <text class="hint">请确保发票抬头与公司营业执照或个人身份证上的名称一致。</text> |
| 42 | </view> | 84 | </view> |
| 43 | 85 | ||
| 44 | <!-- 纳税人识别号(企业才显示) --> | 86 | <!-- 纳税人识别号(企业才显示) --> |
| 45 | <view v-if="form.invoiceType === '1'" class="form-item column"> | 87 | <view v-if="form.type === '1' && form.invoiceType === '1'" class="form-item column"> |
| 46 | <text class="label">纳税人识别号</text> | 88 | <text class="label">纳税人识别号</text> |
| 47 | <input | 89 | <input |
| 48 | v-model="form.taxno" | 90 | v-model="form.taxno" |
| 49 | class="input" | 91 | class="input" |
| 92 | :disabled="!showPersonalType && form.invoiceType === '1'" | ||
| 50 | maxlength="20" | 93 | maxlength="20" |
| 51 | placeholder="请输入纳税人识别号" | 94 | placeholder="请输入纳税人识别号" |
| 52 | /> | 95 | /> |
| ... | @@ -68,12 +111,6 @@ | ... | @@ -68,12 +111,6 @@ |
| 68 | </view> | 111 | </view> |
| 69 | </view> | 112 | </view> |
| 70 | 113 | ||
| 71 | <!-- 开票金额 --> | ||
| 72 | <!-- <view class="form-item"> | ||
| 73 | <text class="label">开票金额</text> | ||
| 74 | <text class="amount">¥ {{ (Number(form.amount)).toFixed(2) }}</text> | ||
| 75 | </view> --> | ||
| 76 | |||
| 77 | <!-- 接收邮箱 --> | 114 | <!-- 接收邮箱 --> |
| 78 | <view class="form-item column"> | 115 | <view class="form-item column"> |
| 79 | <text class="label">接收邮箱号码</text> | 116 | <text class="label">接收邮箱号码</text> |
| ... | @@ -100,12 +137,20 @@ | ... | @@ -100,12 +137,20 @@ |
| 100 | import {ref, reactive} from 'vue'; | 137 | import {ref, reactive} from 'vue'; |
| 101 | import {onLoad} from '@dcloudio/uni-app'; | 138 | import {onLoad} from '@dcloudio/uni-app'; |
| 102 | import {outputInvoiceNo} from '@/common/api.js'; | 139 | import {outputInvoiceNo} from '@/common/api.js'; |
| 140 | import customModal from '@/components/custom-modal.vue'; | ||
| 103 | 141 | ||
| 142 | const app = getApp(); | ||
| 104 | const submitting = ref(false); | 143 | const submitting = ref(false); |
| 105 | const type = ref(0) //1个人订单只开普票 | 144 | const showSuccessModal = ref(false); |
| 106 | // 表单数据(与PC端字段完全对齐) | 145 | |
| 146 | // 是否显示个人/非企业选项 | ||
| 147 | const showPersonalType = ref(true); | ||
| 148 | |||
| 149 | // form.type: '1'=企业单位 '2'=个人/非企业 | ||
| 150 | // form.invoiceType: '1'=增值税专用票据 '2'=普通发票 | ||
| 107 | const form = reactive({ | 151 | const form = reactive({ |
| 108 | invoiceType: '1', // 1=企业 2=个人 | 152 | type: '1', // 开票类型:1=企业单位 2=个人/非企业 |
| 153 | invoiceType: '1', // 发票类型:1=增值税专用票据 2=普通发票 | ||
| 109 | deliveryMethod: '1', // 接收方式:1=电子发票 | 154 | deliveryMethod: '1', // 接收方式:1=电子发票 |
| 110 | name: '', // 发票抬头 | 155 | name: '', // 发票抬头 |
| 111 | taxno: '', // 纳税人识别号 | 156 | taxno: '', // 纳税人识别号 |
| ... | @@ -114,22 +159,44 @@ const form = reactive({ | ... | @@ -114,22 +159,44 @@ const form = reactive({ |
| 114 | id: '' // 订单ID | 159 | id: '' // 订单ID |
| 115 | }); | 160 | }); |
| 116 | 161 | ||
| 117 | // 页面加载(接收PC端传来的参数) | 162 | // 切换开票类型 |
| 163 | function changeInvoiceType(val) { | ||
| 164 | form.type = val | ||
| 165 | if (val === '2') { | ||
| 166 | // 个人/非企业,只能选普通发票 | ||
| 167 | form.invoiceType = '2' | ||
| 168 | form.taxno = '' | ||
| 169 | form.name = '' | ||
| 170 | } | ||
| 171 | } | ||
| 172 | |||
| 173 | // 页面加载 | ||
| 118 | onLoad((options) => { | 174 | onLoad((options) => { |
| 119 | if (options.id || options.orderId) { | 175 | if (options.id || options.orderId) { |
| 120 | form.id = options.id || options.orderId; | 176 | form.id = options.id || options.orderId; |
| 121 | form.amount = options.amount; | 177 | form.amount = options.amount; |
| 122 | } | 178 | } |
| 123 | if (options.invoiceType) { | 179 | |
| 124 | form.invoiceType = options.invoiceType; | 180 | // 个人订单只开普票,隐藏个人/非企业选项 |
| 181 | if (options.ziZhangBu == '1') { | ||
| 182 | showPersonalType.value = false | ||
| 183 | form.type = '1' | ||
| 184 | form.invoiceType = '1' | ||
| 185 | } | ||
| 186 | console.log(333,options) | ||
| 187 | |||
| 188 | // 自动填充发票抬头和纳税人识别号 | ||
| 189 | const memberInfo = app.globalData.memberInfo | ||
| 190 | if (memberInfo && options.ziZhangBu == '1') { | ||
| 191 | form.name = memberInfo.companyName || '' | ||
| 192 | form.taxno = memberInfo.creditCode || '' | ||
| 125 | } | 193 | } |
| 126 | type.value = options.type ?? 0 | 194 | |
| 127 | console.log(options) | 195 | console.log('增值税开票参数:', options) |
| 128 | }); | 196 | }); |
| 129 | 197 | ||
| 130 | // 表单验证 | 198 | // 表单验证 |
| 131 | const validateForm = () => { | 199 | const validateForm = () => { |
| 132 | // 发票抬头校验 | ||
| 133 | if (!form.name) { | 200 | if (!form.name) { |
| 134 | uni.showToast({title: '请输入发票抬头', icon: 'none'}); | 201 | uni.showToast({title: '请输入发票抬头', icon: 'none'}); |
| 135 | return false; | 202 | return false; |
| ... | @@ -140,13 +207,13 @@ const validateForm = () => { | ... | @@ -140,13 +207,13 @@ const validateForm = () => { |
| 140 | } | 207 | } |
| 141 | 208 | ||
| 142 | // 企业必须填纳税人识别号 | 209 | // 企业必须填纳税人识别号 |
| 143 | if (form.invoiceType === '1' && !form.taxno) { | 210 | if (form.type === '1' && !form.taxno) { |
| 144 | uni.showToast({title: '请输入纳税人识别号', icon: 'none'}); | 211 | uni.showToast({title: '请输入纳税人识别号', icon: 'none'}); |
| 145 | return false; | 212 | return false; |
| 146 | } | 213 | } |
| 147 | 214 | ||
| 148 | // 纳税人识别号格式校验(同PC) | 215 | // 纳税人识别号格式校验 |
| 149 | if (form.invoiceType === '1') { | 216 | if (form.type === '1') { |
| 150 | const taxReg = /^[A-Z0-9]{15}$|^[A-Z0-9]{18}$|^[A-Z0-9]{20}$/; | 217 | const taxReg = /^[A-Z0-9]{15}$|^[A-Z0-9]{18}$|^[A-Z0-9]{20}$/; |
| 151 | if (!taxReg.test(form.taxno)) { | 218 | if (!taxReg.test(form.taxno)) { |
| 152 | uni.showToast({title: '纳税人识别号格式不正确', icon: 'none'}); | 219 | uni.showToast({title: '纳税人识别号格式不正确', icon: 'none'}); |
| ... | @@ -168,7 +235,7 @@ const validateForm = () => { | ... | @@ -168,7 +235,7 @@ const validateForm = () => { |
| 168 | return true; | 235 | return true; |
| 169 | }; | 236 | }; |
| 170 | 237 | ||
| 171 | // 提交发票申请(与PC逻辑完全一致) | 238 | // 提交发票申请 |
| 172 | const handleSubmit = async () => { | 239 | const handleSubmit = async () => { |
| 173 | if (submitting.value) return; | 240 | if (submitting.value) return; |
| 174 | if (!validateForm()) return; | 241 | if (!validateForm()) return; |
| ... | @@ -177,27 +244,27 @@ const handleSubmit = async () => { | ... | @@ -177,27 +244,27 @@ const handleSubmit = async () => { |
| 177 | console.log('提交表单数据:', form); | 244 | console.log('提交表单数据:', form); |
| 178 | try { | 245 | try { |
| 179 | await outputInvoiceNo(form); | 246 | await outputInvoiceNo(form); |
| 180 | uni.showToast({ | 247 | showSuccessModal.value = true; |
| 181 | title: '开票申请提交成功', | ||
| 182 | icon: 'success' | ||
| 183 | }); | ||
| 184 | setTimeout(() => { | ||
| 185 | uni.navigateBack(); | ||
| 186 | }, 1500); | ||
| 187 | } catch (error) { | 248 | } catch (error) { |
| 188 | console.log(error) | 249 | console.log(error) |
| 189 | submitting.value = false; | 250 | submitting.value = false; |
| 190 | // 错误已由 request.js 处理 | ||
| 191 | } finally { | 251 | } finally { |
| 192 | submitting.value = false; | 252 | submitting.value = false; |
| 193 | } | 253 | } |
| 194 | }; | 254 | }; |
| 255 | |||
| 256 | // 关闭弹框并返回 | ||
| 257 | function closeSuccessModal() { | ||
| 258 | showSuccessModal.value = false; | ||
| 259 | uni.navigateBack(); | ||
| 260 | } | ||
| 195 | </script> | 261 | </script> |
| 196 | 262 | ||
| 197 | <style lang="scss" scoped> | 263 | <style lang="scss" scoped> |
| 198 | .invoice-apply { | 264 | .invoice-apply { |
| 199 | min-height: 100vh; | 265 | min-height: 100vh; |
| 200 | background: #f5f7fa; | 266 | background: #f5f7fa; |
| 267 | padding-bottom: calc(40rpx + env(safe-area-inset-bottom)); | ||
| 201 | } | 268 | } |
| 202 | 269 | ||
| 203 | .content { | 270 | .content { |
| ... | @@ -239,13 +306,12 @@ const handleSubmit = async () => { | ... | @@ -239,13 +306,12 @@ const handleSubmit = async () => { |
| 239 | &::placeholder { | 306 | &::placeholder { |
| 240 | color: #999; | 307 | color: #999; |
| 241 | font-size: 28rpx; | 308 | font-size: 28rpx; |
| 242 | line-height: 80rpx; | ||
| 243 | } | ||
| 244 | } | 309 | } |
| 245 | 310 | ||
| 246 | .form-item.column .input { | 311 | &[disabled] { |
| 247 | width: 100%; | 312 | background: #f5f5f5; |
| 248 | display: block; | 313 | color: #999; |
| 314 | } | ||
| 249 | } | 315 | } |
| 250 | 316 | ||
| 251 | .hint { | 317 | .hint { |
| ... | @@ -253,15 +319,9 @@ const handleSubmit = async () => { | ... | @@ -253,15 +319,9 @@ const handleSubmit = async () => { |
| 253 | color: #909399; | 319 | color: #909399; |
| 254 | margin-top: 8rpx; | 320 | margin-top: 8rpx; |
| 255 | } | 321 | } |
| 256 | |||
| 257 | .amount { | ||
| 258 | font-size: 32rpx; | ||
| 259 | color: #AD181F; | ||
| 260 | font-weight: 600; | ||
| 261 | } | ||
| 262 | } | 322 | } |
| 263 | 323 | ||
| 264 | /* 发票类型选择 */ | 324 | /* 开票类型选择 */ |
| 265 | .type-select { | 325 | .type-select { |
| 266 | display: flex; | 326 | display: flex; |
| 267 | gap: 20rpx; | 327 | gap: 20rpx; |
| ... | @@ -285,28 +345,33 @@ const handleSubmit = async () => { | ... | @@ -285,28 +345,33 @@ const handleSubmit = async () => { |
| 285 | .type-icon { | 345 | .type-icon { |
| 286 | width: 60rpx; | 346 | width: 60rpx; |
| 287 | height: 60rpx; | 347 | height: 60rpx; |
| 288 | background: #f5f7ff; | 348 | background: #fbd9d9; |
| 289 | border-radius: 8rpx; | 349 | border-radius: 8rpx; |
| 290 | display: flex; | 350 | display: flex; |
| 291 | align-items: center; | 351 | align-items: center; |
| 292 | justify-content: center; | 352 | justify-content: center; |
| 293 | font-size: 24rpx; | 353 | font-size: 24rpx; |
| 294 | color: #409eff; | 354 | color: #AD181F; |
| 295 | font-weight: 600; | 355 | font-weight: 600; |
| 296 | margin-right: 16rpx; | 356 | margin-right: 16rpx; |
| 297 | 357 | ||
| 298 | &.enterprise { | 358 | // &.enterprise { |
| 299 | background: #f0f6ff; | 359 | // background: #f0f6ff; |
| 300 | color: #1561CB; | 360 | // color: #1561CB; |
| 301 | } | 361 | // } |
| 302 | } | 362 | } |
| 303 | 363 | ||
| 304 | &.active .type-icon { | 364 | &.active .type-icon { |
| 305 | background: #AD181F; | 365 | background: #AD181F; |
| 306 | color: #fff; | 366 | color: #fff; |
| 367 | |||
| 368 | &.enterprise { | ||
| 369 | background: #AD181F; | ||
| 370 | } | ||
| 307 | } | 371 | } |
| 308 | 372 | ||
| 309 | .type-info { | 373 | .type-info { |
| 374 | flex: 1; | ||
| 310 | display: flex; | 375 | display: flex; |
| 311 | flex-direction: column; | 376 | flex-direction: column; |
| 312 | 377 | ||
| ... | @@ -345,13 +410,13 @@ const handleSubmit = async () => { | ... | @@ -345,13 +410,13 @@ const handleSubmit = async () => { |
| 345 | .method-icon { | 410 | .method-icon { |
| 346 | width: 60rpx; | 411 | width: 60rpx; |
| 347 | height: 60rpx; | 412 | height: 60rpx; |
| 348 | background: #f5f7ff; | 413 | background: #fbd9d9; |
| 349 | border-radius: 12rpx; | 414 | border-radius: 12rpx; |
| 350 | display: flex; | 415 | display: flex; |
| 351 | align-items: center; | 416 | align-items: center; |
| 352 | justify-content: center; | 417 | justify-content: center; |
| 353 | font-size: 24rpx; | 418 | font-size: 24rpx; |
| 354 | color: #409eff; | 419 | color: #AD181F; |
| 355 | font-weight: 600; | 420 | font-weight: 600; |
| 356 | margin-right: 16rpx; | 421 | margin-right: 16rpx; |
| 357 | } | 422 | } |
| ... | @@ -415,4 +480,84 @@ const handleSubmit = async () => { | ... | @@ -415,4 +480,84 @@ const handleSubmit = async () => { |
| 415 | background: #c0c4cc; | 480 | background: #c0c4cc; |
| 416 | } | 481 | } |
| 417 | } | 482 | } |
| 483 | |||
| 484 | /* 成功弹框 */ | ||
| 485 | .success-modal { | ||
| 486 | position: fixed; | ||
| 487 | top: 0; | ||
| 488 | left: 0; | ||
| 489 | right: 0; | ||
| 490 | bottom: 0; | ||
| 491 | z-index: 9999; | ||
| 492 | display: flex; | ||
| 493 | align-items: center; | ||
| 494 | justify-content: center; | ||
| 495 | } | ||
| 496 | |||
| 497 | .success-mask { | ||
| 498 | position: absolute; | ||
| 499 | top: 0; | ||
| 500 | left: 0; | ||
| 501 | right: 0; | ||
| 502 | bottom: 0; | ||
| 503 | background: rgba(0, 0, 0, 0.5); | ||
| 504 | } | ||
| 505 | |||
| 506 | .success-content { | ||
| 507 | position: relative; | ||
| 508 | width: 560rpx; | ||
| 509 | background: #fff; | ||
| 510 | border-radius: 24rpx; | ||
| 511 | padding: 50rpx 40rpx 40rpx; | ||
| 512 | box-sizing: border-box; | ||
| 513 | display: flex; | ||
| 514 | flex-direction: column; | ||
| 515 | align-items: center; | ||
| 516 | z-index: 1; | ||
| 517 | } | ||
| 518 | |||
| 519 | .success-icon { | ||
| 520 | width: 100rpx; | ||
| 521 | height: 100rpx; | ||
| 522 | border-radius: 50%; | ||
| 523 | background: #f0f9f0; | ||
| 524 | display: flex; | ||
| 525 | align-items: center; | ||
| 526 | justify-content: center; | ||
| 527 | margin-bottom: 30rpx; | ||
| 528 | font-size: 48rpx; | ||
| 529 | color: #52c41a; | ||
| 530 | } | ||
| 531 | |||
| 532 | .success-title { | ||
| 533 | font-size: 34rpx; | ||
| 534 | font-weight: 600; | ||
| 535 | color: #333; | ||
| 536 | margin-bottom: 16rpx; | ||
| 537 | text-align: center; | ||
| 538 | } | ||
| 539 | |||
| 540 | .success-desc { | ||
| 541 | font-size: 26rpx; | ||
| 542 | color: #999; | ||
| 543 | line-height: 1.6; | ||
| 544 | text-align: center; | ||
| 545 | margin-bottom: 40rpx; | ||
| 546 | } | ||
| 547 | |||
| 548 | .success-btn { | ||
| 549 | width: 100%; | ||
| 550 | height: 80rpx; | ||
| 551 | line-height: 80rpx; | ||
| 552 | background: #AD181F; | ||
| 553 | color: #fff; | ||
| 554 | font-size: 30rpx; | ||
| 555 | border-radius: 40rpx; | ||
| 556 | border: none; | ||
| 557 | text-align: center; | ||
| 558 | } | ||
| 559 | |||
| 560 | .success-btn::after { | ||
| 561 | border: none; | ||
| 562 | } | ||
| 418 | </style> | 563 | </style> |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| 1 | <template> | 1 | <template> |
| 2 | <view class="invoice-apply"> | 2 | <view class="invoice-apply"> |
| 3 | <!-- 成功确认弹框 --> | ||
| 4 | <view class="success-modal" v-if="showSuccessModal"> | ||
| 5 | <view class="success-mask" @click="closeSuccessModal"></view> | ||
| 6 | <view class="success-content"> | ||
| 7 | <view class="success-icon">✓</view> | ||
| 8 | <view class="success-title">发票申请提交成功!</view> | ||
| 9 | <view class="success-desc">您的发票申请已成功提交,我们将在1-7个工作日内为您处理。</view> | ||
| 10 | <button class="success-btn" @click="closeSuccessModal">确定</button> | ||
| 11 | </view> | ||
| 12 | </view> | ||
| 13 | |||
| 3 | <view class="content"> | 14 | <view class="content"> |
| 4 | <!-- 发票信息标题 --> | 15 | <!-- 发票信息标题 --> |
| 5 | <view class="section-header"> | 16 | <view class="section-header"> |
| ... | @@ -24,6 +35,7 @@ | ... | @@ -24,6 +35,7 @@ |
| 24 | </view> | 35 | </view> |
| 25 | </view> | 36 | </view> |
| 26 | <view | 37 | <view |
| 38 | v-if="showIndividualType" | ||
| 27 | :class="{ active: form.type === '1' }" | 39 | :class="{ active: form.type === '1' }" |
| 28 | class="type-option" | 40 | class="type-option" |
| 29 | @click="form.type = '1'" | 41 | @click="form.type = '1'" |
| ... | @@ -45,6 +57,7 @@ | ... | @@ -45,6 +57,7 @@ |
| 45 | <input | 57 | <input |
| 46 | v-model="form.name" | 58 | v-model="form.name" |
| 47 | class="input" | 59 | class="input" |
| 60 | :disabled="!showIndividualType" | ||
| 48 | :placeholder="form.type === '0' ? '请输入公司全称' : '请输入发票抬头'" | 61 | :placeholder="form.type === '0' ? '请输入公司全称' : '请输入发票抬头'" |
| 49 | /> | 62 | /> |
| 50 | <text class="hint">请确保发票抬头与公司营业执照或个人身份证上的名称一致</text> | 63 | <text class="hint">请确保发票抬头与公司营业执照或个人身份证上的名称一致</text> |
| ... | @@ -58,6 +71,7 @@ | ... | @@ -58,6 +71,7 @@ |
| 58 | class="input" | 71 | class="input" |
| 59 | maxlength="20" | 72 | maxlength="20" |
| 60 | placeholder="请输入纳税人识别号" | 73 | placeholder="请输入纳税人识别号" |
| 74 | :disabled="!showIndividualType" | ||
| 61 | /> | 75 | /> |
| 62 | <text class="hint">企业税务登记证上的号码,一般为 15、18 或 20 位</text> | 76 | <text class="hint">企业税务登记证上的号码,一般为 15、18 或 20 位</text> |
| 63 | </view> | 77 | </view> |
| ... | @@ -82,8 +96,12 @@ | ... | @@ -82,8 +96,12 @@ |
| 82 | import {ref, reactive} from 'vue'; | 96 | import {ref, reactive} from 'vue'; |
| 83 | import {onLoad} from '@dcloudio/uni-app'; | 97 | import {onLoad} from '@dcloudio/uni-app'; |
| 84 | import {outputInvoiceNoFeisui} from '@/common/api.js'; | 98 | import {outputInvoiceNoFeisui} from '@/common/api.js'; |
| 99 | import customModal from '@/components/custom-modal.vue'; | ||
| 85 | 100 | ||
| 101 | const app = getApp(); | ||
| 86 | const submitting = ref(false); | 102 | const submitting = ref(false); |
| 103 | const showSuccessModal = ref(false); | ||
| 104 | const showIndividualType = ref(true); | ||
| 87 | 105 | ||
| 88 | // 表单数据 | 106 | // 表单数据 |
| 89 | const form = reactive({ | 107 | const form = reactive({ |
| ... | @@ -100,6 +118,23 @@ onLoad((options) => { | ... | @@ -100,6 +118,23 @@ onLoad((options) => { |
| 100 | form.id = options.id || options.orderId; | 118 | form.id = options.id || options.orderId; |
| 101 | form.amount = options.amount || 0; | 119 | form.amount = options.amount || 0; |
| 102 | } | 120 | } |
| 121 | |||
| 122 | // 自动填充发票抬头和纳税人识别号(与PC端一致) | ||
| 123 | const memberInfo = app.globalData.memberInfo | ||
| 124 | |||
| 125 | |||
| 126 | // 如果是对公转账(ziZhangBu有值),默认只能开企业发票,隐藏个人选项 | ||
| 127 | if (options.ziZhangBu == '1') { | ||
| 128 | form.type = '0' | ||
| 129 | showIndividualType.value = false | ||
| 130 | } else { | ||
| 131 | showIndividualType.value = true | ||
| 132 | } | ||
| 133 | if (memberInfo && options.ziZhangBu == '1') { | ||
| 134 | form.name = memberInfo.companyName || '' | ||
| 135 | form.taxno = memberInfo.creditCode || '' | ||
| 136 | } | ||
| 137 | |||
| 103 | console.log('非税开票参数:', options) | 138 | console.log('非税开票参数:', options) |
| 104 | }); | 139 | }); |
| 105 | 140 | ||
| ... | @@ -122,7 +157,7 @@ const validateForm = () => { | ... | @@ -122,7 +157,7 @@ const validateForm = () => { |
| 122 | } | 157 | } |
| 123 | 158 | ||
| 124 | // 纳税人识别号格式校验 | 159 | // 纳税人识别号格式校验 |
| 125 | if (form.type === '0') { | 160 | if (form.type === '0' ) { |
| 126 | const taxReg = /^[A-Z0-9]{15}$|^[A-Z0-9]{18}$|^[A-Z0-9]{20}$/; | 161 | const taxReg = /^[A-Z0-9]{15}$|^[A-Z0-9]{18}$|^[A-Z0-9]{20}$/; |
| 127 | if (!taxReg.test(form.taxno)) { | 162 | if (!taxReg.test(form.taxno)) { |
| 128 | uni.showToast({title: '纳税人识别号格式不正确', icon: 'none'}); | 163 | uni.showToast({title: '纳税人识别号格式不正确', icon: 'none'}); |
| ... | @@ -142,13 +177,7 @@ const handleSubmit = async () => { | ... | @@ -142,13 +177,7 @@ const handleSubmit = async () => { |
| 142 | console.log('提交非税开票表单数据:', form); | 177 | console.log('提交非税开票表单数据:', form); |
| 143 | try { | 178 | try { |
| 144 | await outputInvoiceNoFeisui(form); | 179 | await outputInvoiceNoFeisui(form); |
| 145 | uni.showToast({ | 180 | showSuccessModal.value = true; |
| 146 | title: '开票申请提交成功', | ||
| 147 | icon: 'success' | ||
| 148 | }); | ||
| 149 | setTimeout(() => { | ||
| 150 | uni.navigateBack(); | ||
| 151 | }, 1500); | ||
| 152 | } catch (error) { | 181 | } catch (error) { |
| 153 | console.log('非税开票失败:', error); | 182 | console.log('非税开票失败:', error); |
| 154 | submitting.value = false; | 183 | submitting.value = false; |
| ... | @@ -156,6 +185,12 @@ const handleSubmit = async () => { | ... | @@ -156,6 +185,12 @@ const handleSubmit = async () => { |
| 156 | submitting.value = false; | 185 | submitting.value = false; |
| 157 | } | 186 | } |
| 158 | }; | 187 | }; |
| 188 | |||
| 189 | // 关闭弹框并返回 | ||
| 190 | function closeSuccessModal() { | ||
| 191 | showSuccessModal.value = false; | ||
| 192 | uni.navigateBack(); | ||
| 193 | } | ||
| 159 | </script> | 194 | </script> |
| 160 | 195 | ||
| 161 | <style lang="scss" scoped> | 196 | <style lang="scss" scoped> |
| ... | @@ -342,4 +377,84 @@ const handleSubmit = async () => { | ... | @@ -342,4 +377,84 @@ const handleSubmit = async () => { |
| 342 | background: #c0c4cc; | 377 | background: #c0c4cc; |
| 343 | } | 378 | } |
| 344 | } | 379 | } |
| 380 | |||
| 381 | /* 成功弹框 */ | ||
| 382 | .success-modal { | ||
| 383 | position: fixed; | ||
| 384 | top: 0; | ||
| 385 | left: 0; | ||
| 386 | right: 0; | ||
| 387 | bottom: 0; | ||
| 388 | z-index: 9999; | ||
| 389 | display: flex; | ||
| 390 | align-items: center; | ||
| 391 | justify-content: center; | ||
| 392 | } | ||
| 393 | |||
| 394 | .success-mask { | ||
| 395 | position: absolute; | ||
| 396 | top: 0; | ||
| 397 | left: 0; | ||
| 398 | right: 0; | ||
| 399 | bottom: 0; | ||
| 400 | background: rgba(0, 0, 0, 0.5); | ||
| 401 | } | ||
| 402 | |||
| 403 | .success-content { | ||
| 404 | position: relative; | ||
| 405 | width: 560rpx; | ||
| 406 | background: #fff; | ||
| 407 | border-radius: 24rpx; | ||
| 408 | padding: 50rpx 40rpx 40rpx; | ||
| 409 | box-sizing: border-box; | ||
| 410 | display: flex; | ||
| 411 | flex-direction: column; | ||
| 412 | align-items: center; | ||
| 413 | z-index: 1; | ||
| 414 | } | ||
| 415 | |||
| 416 | .success-icon { | ||
| 417 | width: 100rpx; | ||
| 418 | height: 100rpx; | ||
| 419 | border-radius: 50%; | ||
| 420 | background: #f0f9f0; | ||
| 421 | display: flex; | ||
| 422 | align-items: center; | ||
| 423 | justify-content: center; | ||
| 424 | margin-bottom: 30rpx; | ||
| 425 | font-size: 48rpx; | ||
| 426 | color: #52c41a; | ||
| 427 | } | ||
| 428 | |||
| 429 | .success-title { | ||
| 430 | font-size: 34rpx; | ||
| 431 | font-weight: 600; | ||
| 432 | color: #333; | ||
| 433 | margin-bottom: 16rpx; | ||
| 434 | text-align: center; | ||
| 435 | } | ||
| 436 | |||
| 437 | .success-desc { | ||
| 438 | font-size: 26rpx; | ||
| 439 | color: #999; | ||
| 440 | line-height: 1.6; | ||
| 441 | text-align: center; | ||
| 442 | margin-bottom: 40rpx; | ||
| 443 | } | ||
| 444 | |||
| 445 | .success-btn { | ||
| 446 | width: 100%; | ||
| 447 | height: 80rpx; | ||
| 448 | line-height: 80rpx; | ||
| 449 | background: #AD181F; | ||
| 450 | color: #fff; | ||
| 451 | font-size: 30rpx; | ||
| 452 | border-radius: 40rpx; | ||
| 453 | border: none; | ||
| 454 | text-align: center; | ||
| 455 | } | ||
| 456 | |||
| 457 | .success-btn::after { | ||
| 458 | border: none; | ||
| 459 | } | ||
| 345 | </style> | 460 | </style> |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
-
Please register or sign in to post a comment