开票
Showing
4 changed files
with
341 additions
and
259 deletions
| ... | @@ -2265,3 +2265,15 @@ export function refundOrder(id) { | ... | @@ -2265,3 +2265,15 @@ export function refundOrder(id) { |
| 2265 | method: 'post' | 2265 | method: 'post' |
| 2266 | }) | 2266 | }) |
| 2267 | } | 2267 | } |
| 2268 | |||
| 2269 | /** | ||
| 2270 | * 红冲 | ||
| 2271 | * @param params | ||
| 2272 | * @returns {id} | ||
| 2273 | */ | ||
| 2274 | export function invoiceFastRed(id) { | ||
| 2275 | return request({ | ||
| 2276 | url: `/common/order/invoiceFastRed/${id}`, | ||
| 2277 | method: 'post' | ||
| 2278 | }) | ||
| 2279 | } | ||
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| 1 | // dev | 1 | // dev |
| 2 | // const baseUrl_api = 'http://192.168.1.222:8787' | 2 | const baseUrl_api = 'http://192.168.1.222:8787' |
| 3 | // const baseUrl_api = 'http://47.98.186.233:8787' | 3 | // const baseUrl_api = 'http://47.98.186.233:8787' |
| 4 | const baseUrl_api = 'https://tk001.wxjylt.com/stage-api/' | 4 | // const baseUrl_api = 'https://tk001.wxjylt.com/stage-api/' |
| 5 | const loginImage_api = 'https://tk001.wxjylt.com/stage-api' | 5 | const loginImage_api = 'https://tk001.wxjylt.com/stage-api' |
| 6 | const payUrl = 'https://wxpay.cmbc.com.cn/mobilePlatform/appserver/lcbpPay.do' | 6 | const payUrl = 'https://wxpay.cmbc.com.cn/mobilePlatform/appserver/lcbpPay.do' |
| 7 | 7 | ... | ... |
| ... | @@ -51,39 +51,20 @@ | ... | @@ -51,39 +51,20 @@ |
| 51 | <view class="card-header"> | 51 | <view class="card-header"> |
| 52 | <view class="date"> | 52 | <view class="date"> |
| 53 | <view class="data-header"> | 53 | <view class="data-header"> |
| 54 | <text class="member-label">{{ tabs.find(t => t.type === currentTab)?.label }}·</text> | 54 | <text class="member-label">{{ getOrderLabel(item) }} ·</text> |
| 55 | <text class="value ">{{ item.orderName || '——' }}</text> | 55 | <text class="value ml10">{{ item.wfCode || '——' }} ·</text> |
| 56 | <text class="pay-type ml10">{{ String(item.payType) === '3' ? '对公转账' : '民生付' }}</text> | ||
| 56 | </view> | 57 | </view> |
| 57 | <text :class="{ | 58 | <text :class="{ |
| 58 | 'status-wait': item.auditStatus == 0, | 59 | 'status-wait': item.payStatus == 3, |
| 59 | 'status-pending': item.auditStatus == 1, | 60 | 'status-pending': item.payStatus == 0, |
| 60 | 'status-success': item.auditStatus == 2, | 61 | 'status-success': item.payStatus == 1, |
| 61 | 'status-danger': item.auditStatus == 3 | 62 | 'status-danger': item.payStatus == 2 || item.payStatus == 4 |
| 62 | }" | 63 | }" |
| 63 | class="status-tag ">{{ getAuditStatusText(item.auditStatus) }} | 64 | class="status-tag ">{{ getStatusText(item.payStatus) }} |
| 64 | </text> | 65 | </text> |
| 65 | </view> | 66 | </view> |
| 66 | </view> | 67 | </view> |
| 67 | <view class="card-header"> | ||
| 68 | <view class="date"> | ||
| 69 | <view class="data-header"> | ||
| 70 | <text class="value"> | ||
| 71 | <text class="tradeNo">订单编号:</text> | ||
| 72 | {{ item.tradeNo || '——' }} | ||
| 73 | </text> | ||
| 74 | </view> | ||
| 75 | </view> | ||
| 76 | </view> | ||
| 77 | <view class="card-header"> | ||
| 78 | <view class="date"> | ||
| 79 | <view class="data-header"> | ||
| 80 | <text class="value"> | ||
| 81 | <text class="tradeNo">缴费编号:</text> | ||
| 82 | {{ item.wfCode || '——' }} | ||
| 83 | </text> | ||
| 84 | </view> | ||
| 85 | </view> | ||
| 86 | </view> | ||
| 87 | <view class="member-time"> | 68 | <view class="member-time"> |
| 88 | <view class="label"> | 69 | <view class="label"> |
| 89 | <text class="star">★</text> | 70 | <text class="star">★</text> |
| ... | @@ -91,78 +72,25 @@ | ... | @@ -91,78 +72,25 @@ |
| 91 | </view> | 72 | </view> |
| 92 | <view class="price"> | 73 | <view class="price"> |
| 93 | <view>¥{{ item.price || '0.00' }}</view> | 74 | <view>¥{{ item.price || '0.00' }}</view> |
| 94 | <view v-if="item.type==0" class="person">共{{ item.content?.allPersonCount || 0 }}人</view> | 75 | <view class="person">{{ getOrderCountText(item) }}</view> |
| 95 | <view v-if="item.type==1" class="person">共{{ item.content?.yearCount || 0 }}年</view> | ||
| 96 | <view v-if="item.type==2||item.type==3||item.type==4" class="person">共{{ | ||
| 97 | item.content?.personCount || 0 | ||
| 98 | }}人 | ||
| 99 | </view> | ||
| 100 | </view> | 76 | </view> |
| 101 | </view> | 77 | </view> |
| 102 | 78 | ||
| 103 | <!-- 核心:前2tab仅展示缴费年限,后2tab仅展示人数合计 --> | ||
| 104 | <view v-if="item.content" class="info-section flex f-j-s"> | ||
| 105 | <!-- 个人/单位会员(仅缴费年限) --> | ||
| 106 | <view v-if="currentTab === '0' || currentTab === '1'" class="single-info"> | ||
| 107 | <view class="label">缴费年限:</view> | ||
| 108 | <view class="value">{{ item.content.yearCount || 0 }}</view> | ||
| 109 | </view> | ||
| 110 | <!-- 级位/段位考试(仅人数合计) --> | ||
| 111 | <view v-if="currentTab === '2' || currentTab === '3' || currentTab === '4'" class="single-info"> | ||
| 112 | <view class="label">人数合计</view> | ||
| 113 | <view class="value">{{ item.content.personCount || 0 }}</view> | ||
| 114 | </view> | ||
| 115 | <view class="line"></view> | ||
| 116 | <view class="single-info"> | ||
| 117 | <view class="label">订单状态</view> | ||
| 118 | <view :class="item.effect == 1 ? 'text-success' : 'text-warning'" class="value"> | ||
| 119 | {{ item.effect == 1 ? '已生效' : '未生效' }} | ||
| 120 | </view> | ||
| 121 | </view> | ||
| 122 | <view class="line"></view> | ||
| 123 | <view class="single-info"> | ||
| 124 | <view class="label">缴费状态</view> | ||
| 125 | <view | ||
| 126 | :class="{ | ||
| 127 | 'text-primary': item.payStatus == 0, | ||
| 128 | 'text-success': item.payStatus == 1, | ||
| 129 | 'text-danger': item.payStatus == 2 | ||
| 130 | }" | ||
| 131 | class="value" | ||
| 132 | > | ||
| 133 | {{ item.payStatus == 0 ? '待缴费' : item.payStatus == 1 ? '缴费成功' : '订单取消' }} | ||
| 134 | </view> | ||
| 135 | </view> | ||
| 136 | </view> | ||
| 137 | |||
| 138 | <!-- 按钮组:靠右紧凑展示 --> | ||
| 139 | <view class="btn-group"> | 79 | <view class="btn-group"> |
| 140 | <view> | 80 | <template v-if="isZtxRole"> |
| 141 | <text class="more" @click.stop="goToDetail(item)">更多</text> | 81 | <button :class="{ disabled: isRefundDisabled(item) }" :disabled="isRefundDisabled(item)" class="btn btn-pay" @click.stop="handleRefund(item)">退款</button> |
| 142 | </view> | ||
| 143 | <view class="btn-flex"> | ||
| 144 | <!-- 已缴费:申请开票/已开票(需要审核通过才能开票) --> | ||
| 145 | <template> | ||
| 146 | <button class="btn btn-info" @click.stop="goToDetail(item)">查看明细</button> | ||
| 147 | </template> | 82 | </template> |
| 148 | <!-- 已缴费:申请开票/已开票(需要审核通过才能开票) --> | 83 | <template v-else> |
| 149 | <template v-if="item.payStatus == 1 && item.invoiceStatus != 1&& item.auditStatus == 2 &&item.price>0"> | 84 | <button :class="{ disabled: isPayDisabled(item) }" :disabled="isPayDisabled(item)" class="btn btn-pay" @click.stop="handlePay(item)">支付</button> |
| 150 | <button :disabled="item.invoiceStatus === 1" class="btn btn-view-invoice" | 85 | <button v-if="canShowCancel(item)" :class="{ disabled: isCancelDisabled(item) }" :disabled="isCancelDisabled(item)" class="btn btn-cancel" @click.stop="handleCancel(item)">取消订单</button> |
| 151 | @click.stop="makeInvoiceFN(item)"> | 86 | <template v-if="canShowInvoiceApply(item)"> |
| 152 | 开票 | 87 | <button :class="{ disabled: isInvoiceDisabled(item) }" :disabled="isInvoiceDisabled(item)" class="btn btn-view-invoice" @click.stop="makeInvoiceFN(item)">申请开票</button> |
| 153 | </button> | ||
| 154 | </template> | 88 | </template> |
| 155 | <!-- 已开票:查看发票 --> | 89 | <template v-if="hasInvoice(item)"> |
| 156 | <template v-if="item.invoiceStatus == 1"> | ||
| 157 | <button class="btn btn-invoice" @click.stop="viewInvoice(item)">查看发票</button> | 90 | <button class="btn btn-invoice" @click.stop="viewInvoice(item)">查看发票</button> |
| 158 | </template> | 91 | </template> |
| 159 | <!-- 未缴费:去缴费 + 取消订单 --> | 92 | <button v-if="canShowReIssue(item)" :class="{ disabled: isReIssueDisabled(item) }" :disabled="isReIssueDisabled(item)" class="btn btn-view-invoice" @click.stop="handleReIssue(item)">重新开票</button> |
| 160 | <!-- <template v-if="item.payStatus == 0"> | 93 | </template> |
| 161 | <button class="btn btn-cancel" @click="handleCancel(item)">取消订单</button> | ||
| 162 | <button class="btn btn-pay" @click="handlePay(item)">去缴费</button> | ||
| 163 | </template> --> | ||
| 164 | </view> | ||
| 165 | |||
| 166 | </view> | 94 | </view> |
| 167 | </view> | 95 | </view> |
| 168 | </view> | 96 | </view> |
| ... | @@ -271,41 +199,11 @@ import dayjs from 'dayjs' | ... | @@ -271,41 +199,11 @@ import dayjs from 'dayjs' |
| 271 | const deptType = ref(0); | 199 | const deptType = ref(0); |
| 272 | 200 | ||
| 273 | 201 | ||
| 274 | // 标签栏配置(根据deptType动态生成) | 202 | const tabs = [ |
| 275 | const tabs = computed(() => { | ||
| 276 | const dt = Number(deptType.value) | ||
| 277 | console.log('tabs computed, deptType:', deptType.value, 'dt:', dt, 'dt===6:', dt === 6, 'dt==6:', dt == 6); | ||
| 278 | |||
| 279 | if (dt === 6) { | ||
| 280 | console.log('返回3个tab: 个人会员、单位会员、级位考试'); | ||
| 281 | return [ | ||
| 282 | {name: '个人会员', type: '0', label: "会员"}, | ||
| 283 | {name: '单位会员', type: '1', label: "单位"}, | ||
| 284 | {name: '级位考试', type: '2', label: "级位"} | ||
| 285 | ]; | ||
| 286 | } else if (dt === 2) { | ||
| 287 | console.log('返回3个tab: 单位会员、段位考试、越段考试'); | ||
| 288 | return [ | ||
| 289 | // {name: '单位会员', type: '1'}, | ||
| 290 | {name: '段位考试', type: '3', label: "段位"}, | ||
| 291 | {name: '越段考试', type: '4', label: "越段"} | ||
| 292 | ]; | ||
| 293 | } else if (dt === 1) { | ||
| 294 | console.log('返回默认5个tab, dt值为:', dt); | ||
| 295 | return [ | ||
| 296 | {name: '个人会员', type: '0', label: "会员"}, | ||
| 297 | {name: '单位会员', type: '1', label: "单位"}, | ||
| 298 | {name: '级位考试', type: '2', label: "级位"}, | ||
| 299 | {name: '段位考试', type: '3', label: "段位"}, | 203 | {name: '段位考试', type: '3', label: "段位"}, |
| 300 | {name: '越段考试', type: '4', label: "越段"} | 204 | {name: '越段考试', type: '4', label: "越段"} |
| 301 | ]; | 205 | ]; |
| 302 | } else { | 206 | const currentTab = ref('3'); |
| 303 | return [ | ||
| 304 | {name: '单位会员', type: '1', label: "单位"}, | ||
| 305 | ]; | ||
| 306 | } | ||
| 307 | }); | ||
| 308 | const currentTab = ref('0'); | ||
| 309 | 207 | ||
| 310 | // 数据与分页配置 | 208 | // 数据与分页配置 |
| 311 | const list = ref([]); | 209 | const list = ref([]); |
| ... | @@ -318,7 +216,7 @@ const pageSize = ref(10); | ... | @@ -318,7 +216,7 @@ const pageSize = ref(10); |
| 318 | const queryParams = reactive({ | 216 | const queryParams = reactive({ |
| 319 | pageNum: 1, | 217 | pageNum: 1, |
| 320 | pageSize: 10, | 218 | pageSize: 10, |
| 321 | type: '0', | 219 | type: '3', |
| 322 | queryType: '1', | 220 | queryType: '1', |
| 323 | // payStatus: '' | 221 | // payStatus: '' |
| 324 | }); | 222 | }); |
| ... | @@ -338,13 +236,14 @@ const cancelModalContent = ref(''); | ... | @@ -338,13 +236,14 @@ const cancelModalContent = ref(''); |
| 338 | 236 | ||
| 339 | // 当前操作的订单 | 237 | // 当前操作的订单 |
| 340 | const currentOrder = ref(null); | 238 | const currentOrder = ref(null); |
| 239 | const isZtxRole = computed(() => Number(deptType.value) === 1) | ||
| 341 | 240 | ||
| 342 | // 页面挂载初始化 | 241 | // 页面挂载初始化 |
| 343 | onLoad((option) => { | 242 | onLoad((option) => { |
| 344 | // 获取app实例和deptType | 243 | // 获取app实例和deptType |
| 345 | const app = getApp(); | 244 | const app = getApp(); |
| 346 | deptType.value = Number(app.globalData?.deptType || 0); | 245 | deptType.value = Number(app.globalData?.deptType || 0); |
| 347 | const firstType = tabs.value[0]?.type ?? '0'; | 246 | const firstType = tabs[0]?.type ?? '3'; |
| 348 | // currentTab.value = option.type || firstType; | 247 | // currentTab.value = option.type || firstType; |
| 349 | // queryParams.type = option.type || firstType; | 248 | // queryParams.type = option.type || firstType; |
| 350 | currentTab.value = firstType; | 249 | currentTab.value = firstType; |
| ... | @@ -390,7 +289,8 @@ const getStatusText = (status) => { | ... | @@ -390,7 +289,8 @@ const getStatusText = (status) => { |
| 390 | const map = { | 289 | const map = { |
| 391 | 0: '待缴费', | 290 | 0: '待缴费', |
| 392 | 1: '缴费成功', | 291 | 1: '缴费成功', |
| 393 | 2: '订单取消' | 292 | 2: '已取消', |
| 293 | 4: '已退款' | ||
| 394 | }; | 294 | }; |
| 395 | return map[status] || ''; | 295 | return map[status] || ''; |
| 396 | }; | 296 | }; |
| ... | @@ -401,7 +301,10 @@ const getAuditStatusText = (status) => { | ... | @@ -401,7 +301,10 @@ const getAuditStatusText = (status) => { |
| 401 | 0: '待提交', | 301 | 0: '待提交', |
| 402 | 1: '审核中', | 302 | 1: '审核中', |
| 403 | 2: '审核通过', | 303 | 2: '审核通过', |
| 404 | 3: '审核拒绝' | 304 | 3: '审核拒绝', |
| 305 | 4: '已退回', | ||
| 306 | 8: '已取消', | ||
| 307 | 9: '待支付' | ||
| 405 | }; | 308 | }; |
| 406 | return map[status] || ''; | 309 | return map[status] || ''; |
| 407 | }; | 310 | }; |
| ... | @@ -416,9 +319,57 @@ const filterType = (row) => { | ... | @@ -416,9 +319,57 @@ const filterType = (row) => { |
| 416 | if (row == 1) return '单位会员缴费办理' | 319 | if (row == 1) return '单位会员缴费办理' |
| 417 | if (row == 2) return '级位考试办理' | 320 | if (row == 2) return '级位考试办理' |
| 418 | if (row == 3) return '段位考试办理' | 321 | if (row == 3) return '段位考试办理' |
| 419 | if (row == 4) return '越位考试办理' | 322 | if (row == 4) return '越段考试办理' |
| 323 | } | ||
| 324 | |||
| 325 | const getOrderLabel = (item) => { | ||
| 326 | const map = { | ||
| 327 | 3: '段位', | ||
| 328 | 4: '越段' | ||
| 329 | } | ||
| 330 | return map[item?.type] || tabs.find(t => t.type === currentTab.value)?.label || '订单' | ||
| 420 | } | 331 | } |
| 421 | 332 | ||
| 333 | const getOrderCountText = (item) => { | ||
| 334 | return `共${item?.content?.personCount || 0}人` | ||
| 335 | } | ||
| 336 | |||
| 337 | const hasInvoice = (item) => String(item?.invoiceStatus) === '1' | ||
| 338 | |||
| 339 | const isPayDisabled = (item) => String(item?.auditStatus) !== '9' | ||
| 340 | |||
| 341 | const canShowCancel = (item) => String(item?.auditStatus) === '9' | ||
| 342 | |||
| 343 | const isCancelDisabled = (item) => String(item?.auditStatus) !== '9' | ||
| 344 | |||
| 345 | const canShowInvoiceApply = (item) => !hasInvoice(item) | ||
| 346 | |||
| 347 | const isInvoiceDisabled = (item) => { | ||
| 348 | return String(item?.payStatus) !== '1' || | ||
| 349 | hasInvoice(item) || | ||
| 350 | String(item?.auditStatus) !== '2' || | ||
| 351 | Number(item?.price || 0) <= 0 | ||
| 352 | } | ||
| 353 | |||
| 354 | const isWithinCalendarMonth = (dateValue) => { | ||
| 355 | if (!dateValue) return false | ||
| 356 | const date = dayjs(dateValue) | ||
| 357 | if (!date.isValid()) return false | ||
| 358 | return date.isSame(dayjs(), 'month') | ||
| 359 | } | ||
| 360 | |||
| 361 | const canShowReIssue = (item) => !isZtxRole.value && String(item?.auditStatus) !== '9' | ||
| 362 | |||
| 363 | const isReIssueDisabled = (item) => { | ||
| 364 | return !hasInvoice(item) || | ||
| 365 | !isWithinCalendarMonth(item?.invoiceTime) || | ||
| 366 | String(item?.payStatus) === '4' || | ||
| 367 | String(item?.redFlag) === '1' || | ||
| 368 | String(item?.payType) === '3' | ||
| 369 | } | ||
| 370 | |||
| 371 | const isRefundDisabled = (item) => String(item?.payStatus) !== '1' || hasInvoice(item) | ||
| 372 | |||
| 422 | 373 | ||
| 423 | // 数据请求核心方法 | 374 | // 数据请求核心方法 |
| 424 | const initData = async () => { | 375 | const initData = async () => { |
| ... | @@ -493,22 +444,15 @@ const confirmDel = async () => { | ... | @@ -493,22 +444,15 @@ const confirmDel = async () => { |
| 493 | const goToDetail = (item) => { | 444 | const goToDetail = (item) => { |
| 494 | console.log("goToDetail:", item); | 445 | console.log("goToDetail:", item); |
| 495 | console.log("currentTab.value", currentTab.value); | 446 | console.log("currentTab.value", currentTab.value); |
| 496 | const form = encodeURIComponent(JSON.stringify(item)) | ||
| 497 | switch (currentTab.value) { | 447 | switch (currentTab.value) { |
| 498 | case '1': | ||
| 499 | uni.navigateTo({url: `/group/groupOrderDetail?form=${form}`}); | ||
| 500 | break; | ||
| 501 | case '2': | ||
| 502 | case '3': | 448 | case '3': |
| 503 | case '4': | 449 | case '4': |
| 504 | uni.navigateTo({url: `/pages/rank/applyDetail?examId=${item.sourceId || item.id}&type=${queryParams.type}`}); | 450 | uni.navigateTo({url: `/pages/rank/applyDetail?examId=${item.sourceId || item.id}&type=${queryParams.type}`}); |
| 505 | break; | 451 | break; |
| 506 | case '0': | ||
| 507 | default: | 452 | default: |
| 508 | uni.navigateTo({url: `/personalVip/orderDetail?rangeId=${item.sourceId || item.id}&type=${queryParams.type}`}); | 453 | uni.navigateTo({url: `/pages/rank/applyDetail?examId=${item.sourceId || item.id}&type=${queryParams.type}`}); |
| 509 | break; | 454 | break; |
| 510 | } | 455 | } |
| 511 | // uni.navigateTo({url: `/pages/rank/applyDetail?examId=${item.sourceId || item.id}&type=${queryParams.type}`}); | ||
| 512 | } | 456 | } |
| 513 | 457 | ||
| 514 | // 关闭删除弹窗 | 458 | // 关闭删除弹窗 |
| ... | @@ -520,17 +464,15 @@ const closeDelPopup = () => { | ... | @@ -520,17 +464,15 @@ const closeDelPopup = () => { |
| 520 | 464 | ||
| 521 | // 去缴费 | 465 | // 去缴费 |
| 522 | const handlePay = async (item) => { | 466 | const handlePay = async (item) => { |
| 523 | if (item.payStatus !== 0) return; | 467 | if (isPayDisabled(item)) return; |
| 524 | try { | 468 | uni.navigateTo({ |
| 525 | await api.goPay({id: item.id}); | 469 | url: `/level/paymentDetail?examId=${item.sourceId || item.id}&orderId=${item.id}` |
| 526 | uni.navigateTo({url: `/pages/pay/pay?orderId=${item.id}`}); | 470 | }); |
| 527 | } catch (e) { | ||
| 528 | uni.showToast({title: '发起支付失败', icon: 'none'}); | ||
| 529 | } | ||
| 530 | }; | 471 | }; |
| 531 | 472 | ||
| 532 | // 申请开票 | 473 | // 申请开票 |
| 533 | const makeInvoiceFN = (item) => { | 474 | const makeInvoiceFN = (item) => { |
| 475 | if (isInvoiceDisabled(item)) return | ||
| 534 | // 开票条件:缴费成功 && 未开票 && 审核通过 | 476 | // 开票条件:缴费成功 && 未开票 && 审核通过 |
| 535 | // if (item.payStatus !== 1 || item.invoiceStatus === 1 || item.auditStatus !== 2) { | 477 | // if (item.payStatus !== 1 || item.invoiceStatus === 1 || item.auditStatus !== 2) { |
| 536 | // return; | 478 | // return; |
| ... | @@ -549,6 +491,26 @@ const makeInvoiceFN = (item) => { | ... | @@ -549,6 +491,26 @@ const makeInvoiceFN = (item) => { |
| 549 | uni.navigateTo({ url }); | 491 | uni.navigateTo({ url }); |
| 550 | }; | 492 | }; |
| 551 | 493 | ||
| 494 | const handleReIssue = async (item) => { | ||
| 495 | if (isReIssueDisabled(item)) return | ||
| 496 | const { confirm } = await uni.showModal({ | ||
| 497 | title: '提示', | ||
| 498 | content: '开票后30天内仅可重开一次,是否确认重新开票?原发票将作废且无法恢复。' | ||
| 499 | }) | ||
| 500 | if (!confirm) return | ||
| 501 | |||
| 502 | try { | ||
| 503 | uni.showLoading({ title: '处理中...' }) | ||
| 504 | await api.invoiceFastRed(item.id) | ||
| 505 | uni.hideLoading() | ||
| 506 | await initData() | ||
| 507 | makeInvoiceFN({ ...item, invoiceStatus: '0' }) | ||
| 508 | } catch (e) { | ||
| 509 | uni.hideLoading() | ||
| 510 | uni.showToast({ title: '重新开票失败', icon: 'none' }) | ||
| 511 | } | ||
| 512 | } | ||
| 513 | |||
| 552 | // 查看发票 | 514 | // 查看发票 |
| 553 | const viewInvoice = (item) => { | 515 | const viewInvoice = (item) => { |
| 554 | // 个人/单位会员(type 0或1)直接跳转webview页面展示发票 | 516 | // 个人/单位会员(type 0或1)直接跳转webview页面展示发票 |
| ... | @@ -590,8 +552,9 @@ const closeInvoiceWebview = () => { | ... | @@ -590,8 +552,9 @@ const closeInvoiceWebview = () => { |
| 590 | 552 | ||
| 591 | // 取消订单 | 553 | // 取消订单 |
| 592 | const handleCancel = (item) => { | 554 | const handleCancel = (item) => { |
| 555 | if (isCancelDisabled(item)) return | ||
| 593 | currentOrder.value = item; | 556 | currentOrder.value = item; |
| 594 | cancelModalContent.value = `是否确认取消订单编号为"${item.tradeNo}"的订单?`; | 557 | cancelModalContent.value = `是否确认取消缴费编号为"${item.wfCode}"的订单?`; |
| 595 | showCancelPopup.value = true; | 558 | showCancelPopup.value = true; |
| 596 | isPopupOpen.value = true; | 559 | isPopupOpen.value = true; |
| 597 | }; | 560 | }; |
| ... | @@ -600,7 +563,7 @@ const handleCancel = (item) => { | ... | @@ -600,7 +563,7 @@ const handleCancel = (item) => { |
| 600 | const confirmCancel = async () => { | 563 | const confirmCancel = async () => { |
| 601 | if (!currentOrder.value) return; | 564 | if (!currentOrder.value) return; |
| 602 | try { | 565 | try { |
| 603 | await api.cancelPay(currentOrder.value.id); | 566 | await api.cancelOrder(currentOrder.value.id); |
| 604 | uni.showToast({title: '取消成功', icon: 'success'}); | 567 | uni.showToast({title: '取消成功', icon: 'success'}); |
| 605 | pageNum.value = 1; | 568 | pageNum.value = 1; |
| 606 | list.value = []; | 569 | list.value = []; |
| ... | @@ -617,14 +580,38 @@ const closeCancelPopup = () => { | ... | @@ -617,14 +580,38 @@ const closeCancelPopup = () => { |
| 617 | isPopupOpen.value = false; | 580 | isPopupOpen.value = false; |
| 618 | currentOrder.value = null; | 581 | currentOrder.value = null; |
| 619 | }; | 582 | }; |
| 583 | |||
| 584 | const handleRefund = async (item) => { | ||
| 585 | if (isRefundDisabled(item)) return | ||
| 586 | const { confirm } = await uni.showModal({ | ||
| 587 | title: '提示', | ||
| 588 | content: `缴费编号为"${item.wfCode}"的订单是否确认退款?` | ||
| 589 | }) | ||
| 590 | if (!confirm) return | ||
| 591 | |||
| 592 | try { | ||
| 593 | uni.showLoading({ title: '处理中...' }) | ||
| 594 | await api.refundOrder(item.id) | ||
| 595 | uni.showToast({ title: '操作成功', icon: 'success' }) | ||
| 596 | pageNum.value = 1 | ||
| 597 | list.value = [] | ||
| 598 | hasMore.value = true | ||
| 599 | await initData() | ||
| 600 | } catch (e) { | ||
| 601 | uni.showToast({ title: '退款失败', icon: 'none' }) | ||
| 602 | } finally { | ||
| 603 | uni.hideLoading() | ||
| 604 | } | ||
| 605 | } | ||
| 620 | </script> | 606 | </script> |
| 621 | 607 | ||
| 622 | <style lang="scss" scoped> | 608 | <style lang="scss" scoped> |
| 623 | .order-page { | 609 | .order-page { |
| 624 | background: #f5f7fa; | 610 | background: #ededf0; |
| 625 | height: 100vh; | 611 | height: 100vh; |
| 626 | display: flex; | 612 | display: flex; |
| 627 | flex-direction: column; | 613 | flex-direction: column; |
| 614 | overflow: hidden; | ||
| 628 | 615 | ||
| 629 | &.no-scroll { | 616 | &.no-scroll { |
| 630 | overflow: hidden; | 617 | overflow: hidden; |
| ... | @@ -677,18 +664,18 @@ const closeCancelPopup = () => { | ... | @@ -677,18 +664,18 @@ const closeCancelPopup = () => { |
| 677 | // 标签栏样式 | 664 | // 标签栏样式 |
| 678 | .tab-bar { | 665 | .tab-bar { |
| 679 | display: flex; | 666 | display: flex; |
| 680 | //background: #fff; | ||
| 681 | //border-bottom: 1rpx solid #eee; | ||
| 682 | flex-shrink: 0; | 667 | flex-shrink: 0; |
| 668 | padding: 22rpx 70rpx 4rpx; | ||
| 669 | background: #ededf0; | ||
| 683 | 670 | ||
| 684 | .tab-item { | 671 | .tab-item { |
| 685 | flex: 1; | 672 | flex: 1; |
| 686 | text-align: center; | 673 | padding: 0 0 14rpx; |
| 687 | padding: 24rpx 0; | ||
| 688 | font-size: 30rpx; | 674 | font-size: 30rpx; |
| 689 | color: #666; | 675 | color: #666; |
| 690 | position: relative; | 676 | position: relative; |
| 691 | font-weight: bold; | 677 | font-weight: bold; |
| 678 | text-align: center; | ||
| 692 | 679 | ||
| 693 | &.active { | 680 | &.active { |
| 694 | color: #c30d23; | 681 | color: #c30d23; |
| ... | @@ -700,9 +687,8 @@ const closeCancelPopup = () => { | ... | @@ -700,9 +687,8 @@ const closeCancelPopup = () => { |
| 700 | bottom: 0; | 687 | bottom: 0; |
| 701 | left: 50%; | 688 | left: 50%; |
| 702 | transform: translateX(-50%); | 689 | transform: translateX(-50%); |
| 703 | width: 60rpx; | 690 | width: 72rpx; |
| 704 | height: 6rpx; | 691 | height: 4rpx; |
| 705 | //background: linear-gradient(90deg, #FF755A, #F51722); | ||
| 706 | background: #c30d23; | 692 | background: #c30d23; |
| 707 | border-radius: 2rpx; | 693 | border-radius: 2rpx; |
| 708 | } | 694 | } |
| ... | @@ -713,13 +699,17 @@ const closeCancelPopup = () => { | ... | @@ -713,13 +699,17 @@ const closeCancelPopup = () => { |
| 713 | // 滚动列表容器 | 699 | // 滚动列表容器 |
| 714 | .order-list-scroll { | 700 | .order-list-scroll { |
| 715 | flex: 1; | 701 | flex: 1; |
| 716 | height: auto; | 702 | height: 0; |
| 717 | overflow: auto; | 703 | min-height: 0; |
| 704 | overflow: hidden; | ||
| 705 | background: #ededf0; | ||
| 718 | } | 706 | } |
| 719 | 707 | ||
| 720 | // 订单列表 | 708 | // 订单列表 |
| 721 | .order-list { | 709 | .order-list { |
| 722 | padding: 20rpx; | 710 | min-height: 100%; |
| 711 | box-sizing: border-box; | ||
| 712 | padding: 0 24rpx calc(180rpx + env(safe-area-inset-bottom)); | ||
| 723 | 713 | ||
| 724 | .order-card { | 714 | .order-card { |
| 725 | background: #fff; | 715 | background: #fff; |
| ... | @@ -919,30 +909,20 @@ const closeCancelPopup = () => { | ... | @@ -919,30 +909,20 @@ const closeCancelPopup = () => { |
| 919 | // 按钮组 | 909 | // 按钮组 |
| 920 | .btn-group { | 910 | .btn-group { |
| 921 | display: flex; | 911 | display: flex; |
| 922 | justify-content: space-between; | 912 | justify-content: flex-end; |
| 923 | align-items: center; | 913 | align-items: center; |
| 924 | gap: 16rpx; | 914 | gap: 16rpx; |
| 925 | width: 100%; | 915 | width: 100%; |
| 926 | margin-top: 20rpx; | 916 | margin-top: 16rpx; |
| 927 | 917 | flex-wrap: wrap; | |
| 928 | .more { | ||
| 929 | color: #666; | ||
| 930 | } | ||
| 931 | |||
| 932 | .btn-flex { | ||
| 933 | display: flex; | ||
| 934 | justify-content: flex-end; | ||
| 935 | gap: 16rpx; | ||
| 936 | } | ||
| 937 | 918 | ||
| 938 | .btn { | 919 | .btn { |
| 939 | // 固定宽度,所有按钮一样大 | 920 | width: 140rpx; |
| 940 | width: 160rpx; | 921 | height: 48rpx; |
| 941 | height: 50rpx; | 922 | line-height: 48rpx; |
| 942 | line-height: 50rpx; | ||
| 943 | padding: 0; | 923 | padding: 0; |
| 944 | border-radius: 20rpx; | 924 | border-radius: 10rpx; |
| 945 | font-size: 28rpx; | 925 | font-size: 24rpx; |
| 946 | white-space: nowrap; | 926 | white-space: nowrap; |
| 947 | font-weight: bold; | 927 | font-weight: bold; |
| 948 | border: none; | 928 | border: none; |
| ... | @@ -977,7 +957,8 @@ const closeCancelPopup = () => { | ... | @@ -977,7 +957,8 @@ const closeCancelPopup = () => { |
| 977 | 957 | ||
| 978 | &.btn-info { | 958 | &.btn-info { |
| 979 | color: #444; | 959 | color: #444; |
| 980 | border: 1rpx solid #666; | 960 | border: 1rpx solid #d7d7d7; |
| 961 | background: #fff; | ||
| 981 | } | 962 | } |
| 982 | 963 | ||
| 983 | &.btn-cancel { | 964 | &.btn-cancel { |
| ... | @@ -993,8 +974,12 @@ const closeCancelPopup = () => { | ... | @@ -993,8 +974,12 @@ const closeCancelPopup = () => { |
| 993 | border: 1rpx solid #c30d23; | 974 | border: 1rpx solid #c30d23; |
| 994 | } | 975 | } |
| 995 | 976 | ||
| 996 | &:disabled { | 977 | &.disabled, |
| 997 | opacity: 0.6; | 978 | &[disabled] { |
| 979 | background: #f5f5f5 !important; | ||
| 980 | color: #b8b8b8 !important; | ||
| 981 | border: 1rpx solid #e1e1e1 !important; | ||
| 982 | opacity: 1; | ||
| 998 | pointer-events: none; | 983 | pointer-events: none; |
| 999 | } | 984 | } |
| 1000 | } | 985 | } |
| ... | @@ -1206,10 +1191,10 @@ const closeCancelPopup = () => { | ... | @@ -1206,10 +1191,10 @@ const closeCancelPopup = () => { |
| 1206 | 1191 | ||
| 1207 | .order-card-new { | 1192 | .order-card-new { |
| 1208 | background: #fff; | 1193 | background: #fff; |
| 1209 | margin-bottom: 20rpx; | 1194 | margin-bottom: 22rpx; |
| 1210 | padding: 20rpx; | 1195 | padding: 22rpx 18rpx 18rpx; |
| 1211 | box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04); | 1196 | box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.04); |
| 1212 | border-radius: 12rpx; | 1197 | border-radius: 18rpx; |
| 1213 | display: flex; | 1198 | display: flex; |
| 1214 | flex-direction: column; | 1199 | flex-direction: column; |
| 1215 | 1200 | ||
| ... | @@ -1233,6 +1218,8 @@ const closeCancelPopup = () => { | ... | @@ -1233,6 +1218,8 @@ const closeCancelPopup = () => { |
| 1233 | 1218 | ||
| 1234 | .data-header { | 1219 | .data-header { |
| 1235 | display: flex; | 1220 | display: flex; |
| 1221 | align-items: center; | ||
| 1222 | min-width: 0; | ||
| 1236 | } | 1223 | } |
| 1237 | 1224 | ||
| 1238 | .member-label { | 1225 | .member-label { |
| ... | @@ -1243,13 +1230,19 @@ const closeCancelPopup = () => { | ... | @@ -1243,13 +1230,19 @@ const closeCancelPopup = () => { |
| 1243 | 1230 | ||
| 1244 | .value { | 1231 | .value { |
| 1245 | color: #000; | 1232 | color: #000; |
| 1246 | font-size: 28rpx; | 1233 | font-size: 27rpx; |
| 1247 | font-weight: bold; | 1234 | font-weight: bold; |
| 1235 | max-width: 460rpx; | ||
| 1236 | overflow: hidden; | ||
| 1237 | white-space: nowrap; | ||
| 1238 | text-overflow: ellipsis; | ||
| 1239 | } | ||
| 1248 | 1240 | ||
| 1249 | .tradeNo { | 1241 | .pay-type { |
| 1250 | color: #999; | 1242 | color: #999; |
| 1251 | font-size: 26rpx; | 1243 | font-size: 26rpx; |
| 1252 | } | 1244 | font-weight: normal; |
| 1245 | flex-shrink: 0; | ||
| 1253 | } | 1246 | } |
| 1254 | 1247 | ||
| 1255 | .date-text { | 1248 | .date-text { |
| ... | @@ -1264,7 +1257,8 @@ const closeCancelPopup = () => { | ... | @@ -1264,7 +1257,8 @@ const closeCancelPopup = () => { |
| 1264 | } | 1257 | } |
| 1265 | 1258 | ||
| 1266 | .status-tag { | 1259 | .status-tag { |
| 1267 | font-size: 26rpx; | 1260 | font-size: 24rpx; |
| 1261 | color: #999; | ||
| 1268 | //padding: 6rpx 16rpx; | 1262 | //padding: 6rpx 16rpx; |
| 1269 | //border-radius: 20rpx; | 1263 | //border-radius: 20rpx; |
| 1270 | 1264 | ||
| ... | @@ -1317,22 +1311,27 @@ const closeCancelPopup = () => { | ... | @@ -1317,22 +1311,27 @@ const closeCancelPopup = () => { |
| 1317 | width: 100%; | 1311 | width: 100%; |
| 1318 | display: flex; | 1312 | display: flex; |
| 1319 | justify-content: space-between; | 1313 | justify-content: space-between; |
| 1320 | padding-bottom: 10rpx; | 1314 | padding-bottom: 4rpx; |
| 1321 | 1315 | ||
| 1322 | .label { | 1316 | .label { |
| 1317 | max-width: 480rpx; | ||
| 1318 | color: #555; | ||
| 1323 | font-size: 26rpx; | 1319 | font-size: 26rpx; |
| 1324 | color: #999; | 1320 | font-weight: 700; |
| 1321 | line-height: 1.4; | ||
| 1325 | 1322 | ||
| 1326 | .star { | 1323 | .star { |
| 1327 | color: #000; | 1324 | color: #777; |
| 1328 | font-size: 28rpx; | 1325 | font-size: 26rpx; |
| 1329 | } | 1326 | } |
| 1330 | } | 1327 | } |
| 1331 | 1328 | ||
| 1332 | .price { | 1329 | .price { |
| 1333 | font-size: 30rpx; | 1330 | min-width: 130rpx; |
| 1334 | color: #000; | 1331 | color: #333; |
| 1335 | font-weight: bold; | 1332 | font-size: 26rpx; |
| 1333 | font-weight: 500; | ||
| 1334 | text-align: right; | ||
| 1336 | 1335 | ||
| 1337 | .person { | 1336 | .person { |
| 1338 | font-size: 24rpx; | 1337 | font-size: 24rpx; | ... | ... |
| ... | @@ -41,7 +41,12 @@ | ... | @@ -41,7 +41,12 @@ |
| 41 | </view> | 41 | </view> |
| 42 | </view> | 42 | </view> |
| 43 | 43 | ||
| 44 | <view class="status-filter"> | 44 | <scroll-view |
| 45 | :show-scrollbar="false" | ||
| 46 | class="status-filter" | ||
| 47 | scroll-x | ||
| 48 | > | ||
| 49 | <view class="status-filter-inner"> | ||
| 45 | <view | 50 | <view |
| 46 | v-for="(tab, index) in statusTabs" | 51 | v-for="(tab, index) in statusTabs" |
| 47 | :key="index" | 52 | :key="index" |
| ... | @@ -51,11 +56,12 @@ | ... | @@ -51,11 +56,12 @@ |
| 51 | > | 56 | > |
| 52 | {{ tab.name }} | 57 | {{ tab.name }} |
| 53 | </view> | 58 | </view> |
| 59 | </view> | ||
| 54 | <!-- <view class="filter-entry"> | 60 | <!-- <view class="filter-entry"> |
| 55 | <text class="filter-icon">▽</text> | 61 | <text class="filter-icon">▽</text> |
| 56 | <text>筛选</text> | 62 | <text>筛选</text> |
| 57 | </view> --> | 63 | </view> --> |
| 58 | </view> | 64 | </scroll-view> |
| 59 | 65 | ||
| 60 | <!-- 订单列表 --> | 66 | <!-- 订单列表 --> |
| 61 | <scroll-view | 67 | <scroll-view |
| ... | @@ -86,7 +92,7 @@ | ... | @@ -86,7 +92,7 @@ |
| 86 | 'status-wait': item.payStatus == 3, | 92 | 'status-wait': item.payStatus == 3, |
| 87 | 'status-pending': item.payStatus == 0, | 93 | 'status-pending': item.payStatus == 0, |
| 88 | 'status-success': item.payStatus == 1, | 94 | 'status-success': item.payStatus == 1, |
| 89 | 'status-danger': item.payStatus == 2 | 95 | 'status-danger': item.payStatus == 2 || item.payStatus == 4 |
| 90 | }" | 96 | }" |
| 91 | class="status-tag ">{{ getStatusText(item.payStatus) }} | 97 | class="status-tag ">{{ getStatusText(item.payStatus) }} |
| 92 | </text> | 98 | </text> |
| ... | @@ -99,24 +105,24 @@ | ... | @@ -99,24 +105,24 @@ |
| 99 | </view> | 105 | </view> |
| 100 | <view class="price"> | 106 | <view class="price"> |
| 101 | <view>¥{{ item.price || '0.00' }}</view> | 107 | <view>¥{{ item.price || '0.00' }}</view> |
| 102 | <view v-if="item.type==0" class="person">共{{ item.content?.allPersonCount || 0 }}人</view> | 108 | <view class="person">{{ getOrderCountText(item) }}</view> |
| 103 | <view v-if="item.type==1" class="person">共{{ item.content?.yearCount || 0 }}年</view> | ||
| 104 | <view v-if="item.type==2||item.type==3||item.type==4" class="person">共{{ | ||
| 105 | item.content?.personCount || 0 | ||
| 106 | }}人 | ||
| 107 | </view> | ||
| 108 | </view> | 109 | </view> |
| 109 | </view> | 110 | </view> |
| 110 | <view class="btn-group"> | 111 | <view class="btn-group"> |
| 111 | 112 | <template v-if="isZtxRole"> | |
| 113 | <button :class="{ disabled: isRefundDisabled(item) }" :disabled="isRefundDisabled(item)" class="btn btn-danger" @click.stop="handleRefund(item)">退款</button> | ||
| 114 | </template> | ||
| 115 | <template v-else> | ||
| 112 | <button :class="{ disabled: isPayDisabled(item) }" :disabled="isPayDisabled(item)" class="btn btn-pay" @click.stop="handlePay(item)">支付</button> | 116 | <button :class="{ disabled: isPayDisabled(item) }" :disabled="isPayDisabled(item)" class="btn btn-pay" @click.stop="handlePay(item)">支付</button> |
| 113 | <button :class="{ disabled: isCancelDisabled(item) }" :disabled="isCancelDisabled(item)" class="btn btn-cancel" @click.stop="handleCancel(item)">取消订单</button> | 117 | <button v-if="canShowCancel(item)" :class="{ disabled: isCancelDisabled(item) }" :disabled="isCancelDisabled(item)" class="btn btn-cancel" @click.stop="handleCancel(item)">取消订单</button> |
| 114 | <template v-if="!hasInvoice(item)"> | 118 | <template v-if="canShowInvoiceApply(item)"> |
| 115 | <button :class="{ disabled: isInvoiceDisabled(item) }" :disabled="isInvoiceDisabled(item)" class="btn btn-view-invoice" @click.stop="makeInvoiceFN(item)">申请开票</button> | 119 | <button :class="{ disabled: isInvoiceDisabled(item) }" :disabled="isInvoiceDisabled(item)" class="btn btn-view-invoice" @click.stop="makeInvoiceFN(item)">申请开票</button> |
| 116 | </template> | 120 | </template> |
| 117 | <template v-else> | 121 | <template v-if="hasInvoice(item)"> |
| 118 | <button class="btn btn-invoice" @click.stop="viewInvoice(item)">查看发票</button> | 122 | <button class="btn btn-invoice" @click.stop="viewInvoice(item)">查看发票</button> |
| 119 | </template> | 123 | </template> |
| 124 | <button v-if="canShowReIssue(item)" :class="{ disabled: isReIssueDisabled(item) }" :disabled="isReIssueDisabled(item)" class="btn btn-danger" @click.stop="handleReIssue(item)">重新开票</button> | ||
| 125 | </template> | ||
| 120 | </view> | 126 | </view> |
| 121 | </view> | 127 | </view> |
| 122 | </view> | 128 | </view> |
| ... | @@ -229,47 +235,19 @@ import DaoGuanTabBar from '@/components/dao-guan-tab-bar.vue' | ... | @@ -229,47 +235,19 @@ import DaoGuanTabBar from '@/components/dao-guan-tab-bar.vue' |
| 229 | const deptType = ref(0); | 235 | const deptType = ref(0); |
| 230 | 236 | ||
| 231 | 237 | ||
| 232 | // 标签栏配置(根据deptType动态生成) | 238 | const tabs = [ |
| 233 | const tabs = computed(() => { | ||
| 234 | const dt = Number(deptType.value) | ||
| 235 | console.log('tabs computed, deptType:', deptType.value, 'dt:', dt, 'dt===6:', dt === 6, 'dt==6:', dt == 6); | ||
| 236 | |||
| 237 | if (dt === 6) { | ||
| 238 | console.log('返回3个tab: 个人会员、单位会员、级位考试'); | ||
| 239 | return [ | ||
| 240 | {name: '个人会员', type: '0', label: "会员"}, | 239 | {name: '个人会员', type: '0', label: "会员"}, |
| 241 | {name: '单位会员', type: '1', label: "单位"}, | 240 | {name: '单位会员', type: '1', label: "单位"}, |
| 242 | {name: '级位考试', type: '2', label: "级位"} | 241 | {name: '级位考试', type: '2', label: "级位"} |
| 243 | ]; | 242 | ]; |
| 244 | } else if (dt === 2) { | ||
| 245 | console.log('返回3个tab: 单位会员、段位考试、越段考试'); | ||
| 246 | return [ | ||
| 247 | // {name: '单位会员', type: '1'}, | ||
| 248 | {name: '段位考试', type: '3', label: "段位"}, | ||
| 249 | {name: '越段考试', type: '4', label: "越段"} | ||
| 250 | ]; | ||
| 251 | } else if (dt === 1) { | ||
| 252 | console.log('返回默认5个tab, dt值为:', dt); | ||
| 253 | return [ | ||
| 254 | {name: '个人会员', type: '0', label: "会员"}, | ||
| 255 | {name: '单位会员', type: '1', label: "单位"}, | ||
| 256 | {name: '级位考试', type: '2', label: "级位"}, | ||
| 257 | {name: '段位考试', type: '3', label: "段位"}, | ||
| 258 | {name: '越段考试', type: '4', label: "越段"} | ||
| 259 | ]; | ||
| 260 | } else { | ||
| 261 | return [ | ||
| 262 | {name: '单位会员', type: '1', label: "单位"}, | ||
| 263 | ]; | ||
| 264 | } | ||
| 265 | }); | ||
| 266 | const currentTab = ref('0'); | 243 | const currentTab = ref('0'); |
| 267 | const currentStatus = ref(''); | 244 | const currentStatus = ref(''); |
| 268 | const statusTabs = [ | 245 | const statusTabs = [ |
| 269 | { name: '全部', type: '' }, | 246 | { name: '全部', type: '' }, |
| 270 | { name: '待缴费', type: '0' }, | 247 | { name: '待缴费', type: '0' }, |
| 271 | { name: '缴费成功', type: '1' }, | 248 | { name: '缴费成功', type: '1' }, |
| 272 | { name: '订单取消', type: '2' } | 249 | { name: '已取消', type: '2' }, |
| 250 | { name: '已退款', type: '4' } | ||
| 273 | ] | 251 | ] |
| 274 | 252 | ||
| 275 | // 数据与分页配置 | 253 | // 数据与分页配置 |
| ... | @@ -303,13 +281,14 @@ const cancelModalContent = ref(''); | ... | @@ -303,13 +281,14 @@ const cancelModalContent = ref(''); |
| 303 | 281 | ||
| 304 | // 当前操作的订单 | 282 | // 当前操作的订单 |
| 305 | const currentOrder = ref(null); | 283 | const currentOrder = ref(null); |
| 284 | const isZtxRole = computed(() => Number(deptType.value) === 1) | ||
| 306 | 285 | ||
| 307 | // 页面挂载初始化 | 286 | // 页面挂载初始化 |
| 308 | onLoad((option) => { | 287 | onLoad((option) => { |
| 309 | // 获取app实例和deptType | 288 | // 获取app实例和deptType |
| 310 | const app = getApp(); | 289 | const app = getApp(); |
| 311 | deptType.value = Number(app.globalData?.deptType || 0); | 290 | deptType.value = Number(app.globalData?.deptType || 0); |
| 312 | const firstType = tabs.value[0]?.type ?? '0'; | 291 | const firstType = tabs[0]?.type ?? '0'; |
| 313 | // currentTab.value = option.type || firstType; | 292 | // currentTab.value = option.type || firstType; |
| 314 | // queryParams.type = option.type || firstType; | 293 | // queryParams.type = option.type || firstType; |
| 315 | currentTab.value = firstType; | 294 | currentTab.value = firstType; |
| ... | @@ -364,18 +343,8 @@ const getStatusText = (status) => { | ... | @@ -364,18 +343,8 @@ const getStatusText = (status) => { |
| 364 | const map = { | 343 | const map = { |
| 365 | 0: '待缴费', | 344 | 0: '待缴费', |
| 366 | 1: '缴费成功', | 345 | 1: '缴费成功', |
| 367 | 2: '订单取消' | 346 | 2: '已取消', |
| 368 | }; | 347 | 4: '已退款' |
| 369 | return map[status] || ''; | ||
| 370 | }; | ||
| 371 | |||
| 372 | // 审核状态文本映射 | ||
| 373 | const getAuditStatusText = (status) => { | ||
| 374 | const map = { | ||
| 375 | 0: '待提交', | ||
| 376 | 1: '审核中', | ||
| 377 | 2: '审核通过', | ||
| 378 | 3: '审核拒绝' | ||
| 379 | }; | 348 | }; |
| 380 | return map[status] || ''; | 349 | return map[status] || ''; |
| 381 | }; | 350 | }; |
| ... | @@ -388,7 +357,7 @@ const getOrderLabel = (item) => { | ... | @@ -388,7 +357,7 @@ const getOrderLabel = (item) => { |
| 388 | 3: '段位', | 357 | 3: '段位', |
| 389 | 4: '越段' | 358 | 4: '越段' |
| 390 | } | 359 | } |
| 391 | return map[item.type] || tabs.value.find(t => t.type === currentTab.value)?.label || '订单' | 360 | return map[item.type] || tabs.find(t => t.type === currentTab.value)?.label || '订单' |
| 392 | } | 361 | } |
| 393 | 362 | ||
| 394 | const filterTime = (row) => { | 363 | const filterTime = (row) => { |
| ... | @@ -401,7 +370,14 @@ const filterType = (row) => { | ... | @@ -401,7 +370,14 @@ const filterType = (row) => { |
| 401 | if (row == 1) return '单位会员缴费办理' | 370 | if (row == 1) return '单位会员缴费办理' |
| 402 | if (row == 2) return '级位考试办理' | 371 | if (row == 2) return '级位考试办理' |
| 403 | if (row == 3) return '段位考试办理' | 372 | if (row == 3) return '段位考试办理' |
| 404 | if (row == 4) return '越位考试办理' | 373 | if (row == 4) return '越段考试办理' |
| 374 | } | ||
| 375 | |||
| 376 | const getOrderCountText = (item) => { | ||
| 377 | if (isPersonalOrder(item)) return `共${item?.content?.allPersonCount || 0}人` | ||
| 378 | if (isGroupOrder(item)) return `共${item?.content?.yearCount || 0}年` | ||
| 379 | if (isLevelOrder(item)) return `共${item?.content?.personCount || 0}人` | ||
| 380 | return '' | ||
| 405 | } | 381 | } |
| 406 | 382 | ||
| 407 | const getRowType = (item) => String(item?.type ?? currentTab.value) | 383 | const getRowType = (item) => String(item?.type ?? currentTab.value) |
| ... | @@ -412,6 +388,11 @@ const isGroupOrder = (item) => getRowType(item) === '1' | ... | @@ -412,6 +388,11 @@ const isGroupOrder = (item) => getRowType(item) === '1' |
| 412 | 388 | ||
| 413 | const isLevelOrder = (item) => ['2', '3', '4'].includes(getRowType(item)) | 389 | const isLevelOrder = (item) => ['2', '3', '4'].includes(getRowType(item)) |
| 414 | 390 | ||
| 391 | const canShowCancel = (item) => { | ||
| 392 | if (isGroupOrder(item)) return String(item?.auditStatus) === '0' | ||
| 393 | return String(item?.auditStatus) === '9' | ||
| 394 | } | ||
| 395 | |||
| 415 | const isPayDisabled = (item) => { | 396 | const isPayDisabled = (item) => { |
| 416 | if (isPersonalOrder(item)) return String(item?.auditStatus) !== '9' | 397 | if (isPersonalOrder(item)) return String(item?.auditStatus) !== '9' |
| 417 | if (isLevelOrder(item)) return String(item?.auditStatus) !== '9' | 398 | if (isLevelOrder(item)) return String(item?.auditStatus) !== '9' |
| ... | @@ -422,19 +403,43 @@ const isPayDisabled = (item) => { | ... | @@ -422,19 +403,43 @@ const isPayDisabled = (item) => { |
| 422 | const isCancelDisabled = (item) => { | 403 | const isCancelDisabled = (item) => { |
| 423 | if (isPersonalOrder(item)) return String(item?.auditStatus) !== '9' | 404 | if (isPersonalOrder(item)) return String(item?.auditStatus) !== '9' |
| 424 | if (isLevelOrder(item)) return String(item?.auditStatus) !== '9' | 405 | if (isLevelOrder(item)) return String(item?.auditStatus) !== '9' |
| 425 | if (String(item?.payStatus) !== '0') return true | 406 | return String(item?.payStatus) !== '0' |
| 426 | return false | ||
| 427 | } | 407 | } |
| 428 | 408 | ||
| 429 | const hasInvoice = (item) => String(item?.invoiceStatus) === '1' | 409 | const hasInvoice = (item) => String(item?.invoiceStatus) === '1' |
| 430 | 410 | ||
| 411 | const canShowInvoiceApply = (item) => !hasInvoice(item) | ||
| 412 | |||
| 431 | const isInvoiceDisabled = (item) => { | 413 | const isInvoiceDisabled = (item) => { |
| 432 | if (hasInvoice(item)) return true | 414 | if (hasInvoice(item)) return true |
| 433 | if (isPersonalOrder(item)) return String(item?.auditStatus) !== '2' | 415 | if (isPersonalOrder(item)) return String(item?.auditStatus) !== '2' || String(item?.payStatus) === '4' |
| 434 | if (isLevelOrder(item)) return String(item?.payStatus) !== '1' || String(item?.auditStatus) !== '2' || Number(item?.price || 0) <= 0 | 416 | if (isLevelOrder(item)) return String(item?.payStatus) !== '1' || String(item?.auditStatus) !== '2' || Number(item?.price || 0) <= 0 |
| 435 | return String(item?.payStatus) !== '1' || String(item?.auditStatus) !== '2' || Number(item?.price || 0) <= 0 | 417 | return String(item?.payStatus) !== '1' || String(item?.auditStatus) !== '2' || Number(item?.price || 0) <= 0 |
| 436 | } | 418 | } |
| 437 | 419 | ||
| 420 | const isWithinCalendarMonth = (dateValue) => { | ||
| 421 | if (!dateValue) return false | ||
| 422 | const date = dayjs(dateValue) | ||
| 423 | if (!date.isValid()) return false | ||
| 424 | return date.isSame(dayjs(), 'month') | ||
| 425 | } | ||
| 426 | |||
| 427 | const canShowReIssue = (item) => { | ||
| 428 | if (isZtxRole.value) return false | ||
| 429 | if (isGroupOrder(item)) return String(item?.auditStatus) !== '0' | ||
| 430 | return String(item?.auditStatus) !== '9' | ||
| 431 | } | ||
| 432 | |||
| 433 | const isReIssueDisabled = (item) => { | ||
| 434 | return String(item?.invoiceStatus) !== '1' || | ||
| 435 | !isWithinCalendarMonth(item?.invoiceTime) || | ||
| 436 | String(item?.payStatus) === '4' || | ||
| 437 | String(item?.redFlag) === '1' || | ||
| 438 | String(item?.payType) === '3' | ||
| 439 | } | ||
| 440 | |||
| 441 | const isRefundDisabled = (item) => String(item?.payStatus) !== '1' || String(item?.invoiceStatus) === '1' | ||
| 442 | |||
| 438 | const encodeQueryValue = (value) => encodeURIComponent(value || '') | 443 | const encodeQueryValue = (value) => encodeURIComponent(value || '') |
| 439 | 444 | ||
| 440 | const getPayName = (item) => { | 445 | const getPayName = (item) => { |
| ... | @@ -576,6 +581,7 @@ const handlePay = async (item) => { | ... | @@ -576,6 +581,7 @@ const handlePay = async (item) => { |
| 576 | 581 | ||
| 577 | // 申请开票 | 582 | // 申请开票 |
| 578 | const makeInvoiceFN = (item) => { | 583 | const makeInvoiceFN = (item) => { |
| 584 | if (isInvoiceDisabled(item)) return | ||
| 579 | // 开票条件:缴费成功 && 未开票 && 审核通过 | 585 | // 开票条件:缴费成功 && 未开票 && 审核通过 |
| 580 | // if (item.payStatus !== 1 || item.invoiceStatus === 1 || item.auditStatus !== 2) { | 586 | // if (item.payStatus !== 1 || item.invoiceStatus === 1 || item.auditStatus !== 2) { |
| 581 | // return; | 587 | // return; |
| ... | @@ -597,6 +603,26 @@ const makeInvoiceFN = (item) => { | ... | @@ -597,6 +603,26 @@ const makeInvoiceFN = (item) => { |
| 597 | uni.navigateTo({ url }); | 603 | uni.navigateTo({ url }); |
| 598 | }; | 604 | }; |
| 599 | 605 | ||
| 606 | const handleReIssue = async (item) => { | ||
| 607 | if (isReIssueDisabled(item)) return | ||
| 608 | const { confirm } = await uni.showModal({ | ||
| 609 | title: '提示', | ||
| 610 | content: '开票后30天内仅可重开一次,是否确认重新开票?原发票将作废且无法恢复。' | ||
| 611 | }) | ||
| 612 | if (!confirm) return | ||
| 613 | |||
| 614 | try { | ||
| 615 | uni.showLoading({ title: '处理中...' }) | ||
| 616 | await api.invoiceFastRed(item.id) | ||
| 617 | uni.hideLoading() | ||
| 618 | await initData() | ||
| 619 | makeInvoiceFN({ ...item, invoiceStatus: '0' }) | ||
| 620 | } catch (e) { | ||
| 621 | uni.hideLoading() | ||
| 622 | uni.showToast({ title: '重新开票失败', icon: 'none' }) | ||
| 623 | } | ||
| 624 | } | ||
| 625 | |||
| 600 | // 查看发票 | 626 | // 查看发票 |
| 601 | const viewInvoice = (item) => { | 627 | const viewInvoice = (item) => { |
| 602 | // 个人/单位会员(type 0或1)直接跳转webview页面展示发票 | 628 | // 个人/单位会员(type 0或1)直接跳转webview页面展示发票 |
| ... | @@ -638,6 +664,7 @@ const closeInvoiceWebview = () => { | ... | @@ -638,6 +664,7 @@ const closeInvoiceWebview = () => { |
| 638 | 664 | ||
| 639 | // 取消订单 | 665 | // 取消订单 |
| 640 | const handleCancel = (item) => { | 666 | const handleCancel = (item) => { |
| 667 | if (isCancelDisabled(item)) return | ||
| 641 | currentOrder.value = item; | 668 | currentOrder.value = item; |
| 642 | cancelModalContent.value = `是否确认取消缴费编号为"${item.wfCode}"的订单?`; | 669 | cancelModalContent.value = `是否确认取消缴费编号为"${item.wfCode}"的订单?`; |
| 643 | showCancelPopup.value = true; | 670 | showCancelPopup.value = true; |
| ... | @@ -666,6 +693,29 @@ const closeCancelPopup = () => { | ... | @@ -666,6 +693,29 @@ const closeCancelPopup = () => { |
| 666 | currentOrder.value = null; | 693 | currentOrder.value = null; |
| 667 | }; | 694 | }; |
| 668 | 695 | ||
| 696 | const handleRefund = async (item) => { | ||
| 697 | if (isRefundDisabled(item)) return | ||
| 698 | const { confirm } = await uni.showModal({ | ||
| 699 | title: '提示', | ||
| 700 | content: `缴费编号为"${item.wfCode}"的订单是否确认退款?` | ||
| 701 | }) | ||
| 702 | if (!confirm) return | ||
| 703 | |||
| 704 | try { | ||
| 705 | uni.showLoading({ title: '处理中...' }) | ||
| 706 | await api.refundOrder(item.id) | ||
| 707 | uni.showToast({ title: '操作成功', icon: 'success' }) | ||
| 708 | pageNum.value = 1 | ||
| 709 | list.value = [] | ||
| 710 | hasMore.value = true | ||
| 711 | await initData() | ||
| 712 | } catch (e) { | ||
| 713 | uni.showToast({ title: '退款失败', icon: 'none' }) | ||
| 714 | } finally { | ||
| 715 | uni.hideLoading() | ||
| 716 | } | ||
| 717 | } | ||
| 718 | |||
| 669 | // 底部导航切换 | 719 | // 底部导航切换 |
| 670 | const onTabSwitch = (index, url) => { | 720 | const onTabSwitch = (index, url) => { |
| 671 | // tab switch handled by component | 721 | // tab switch handled by component |
| ... | @@ -813,14 +863,25 @@ const onTabSwitch = (index, url) => { | ... | @@ -813,14 +863,25 @@ const onTabSwitch = (index, url) => { |
| 813 | } | 863 | } |
| 814 | 864 | ||
| 815 | .status-filter { | 865 | .status-filter { |
| 816 | display: flex; | ||
| 817 | align-items: center; | ||
| 818 | flex-shrink: 0; | 866 | flex-shrink: 0; |
| 819 | padding: 10rpx 26rpx 18rpx; | 867 | padding: 10rpx 26rpx 18rpx; |
| 820 | background: #ededf0; | 868 | background: #ededf0; |
| 869 | white-space: nowrap; | ||
| 870 | width: 100%; | ||
| 871 | box-sizing: border-box; | ||
| 872 | } | ||
| 873 | |||
| 874 | .status-filter-inner { | ||
| 875 | display: inline-flex; | ||
| 876 | align-items: center; | ||
| 877 | white-space: nowrap; | ||
| 821 | } | 878 | } |
| 822 | 879 | ||
| 823 | .status-filter-item { | 880 | .status-filter-item { |
| 881 | display: inline-flex; | ||
| 882 | align-items: center; | ||
| 883 | justify-content: center; | ||
| 884 | flex: 0 0 auto; | ||
| 824 | height: 48rpx; | 885 | height: 48rpx; |
| 825 | line-height: 48rpx; | 886 | line-height: 48rpx; |
| 826 | margin-right: 18rpx; | 887 | margin-right: 18rpx; |
| ... | @@ -829,6 +890,7 @@ const onTabSwitch = (index, url) => { | ... | @@ -829,6 +890,7 @@ const onTabSwitch = (index, url) => { |
| 829 | background: #fff; | 890 | background: #fff; |
| 830 | color: #777; | 891 | color: #777; |
| 831 | font-size: 26rpx; | 892 | font-size: 26rpx; |
| 893 | white-space: nowrap; | ||
| 832 | } | 894 | } |
| 833 | 895 | ||
| 834 | .status-filter-item.active { | 896 | .status-filter-item.active { |
| ... | @@ -1129,6 +1191,12 @@ const onTabSwitch = (index, url) => { | ... | @@ -1129,6 +1191,12 @@ const onTabSwitch = (index, url) => { |
| 1129 | border: 1rpx solid #c30d23; | 1191 | border: 1rpx solid #c30d23; |
| 1130 | } | 1192 | } |
| 1131 | 1193 | ||
| 1194 | &.btn-danger { | ||
| 1195 | background: #fff; | ||
| 1196 | color: #c30d23; | ||
| 1197 | border: 1rpx solid #c30d23; | ||
| 1198 | } | ||
| 1199 | |||
| 1132 | &.disabled, | 1200 | &.disabled, |
| 1133 | &[disabled] { | 1201 | &[disabled] { |
| 1134 | background: #f5f5f5 !important; | 1202 | background: #f5f5f5 !important; |
| ... | @@ -1393,6 +1461,8 @@ const onTabSwitch = (index, url) => { | ... | @@ -1393,6 +1461,8 @@ const onTabSwitch = (index, url) => { |
| 1393 | 1461 | ||
| 1394 | .data-header { | 1462 | .data-header { |
| 1395 | display: flex; | 1463 | display: flex; |
| 1464 | align-items: center; | ||
| 1465 | min-width: 0; | ||
| 1396 | } | 1466 | } |
| 1397 | 1467 | ||
| 1398 | .member-label { | 1468 | .member-label { |
| ... | @@ -1415,6 +1485,7 @@ const onTabSwitch = (index, url) => { | ... | @@ -1415,6 +1485,7 @@ const onTabSwitch = (index, url) => { |
| 1415 | color: #999; | 1485 | color: #999; |
| 1416 | font-size: 26rpx; | 1486 | font-size: 26rpx; |
| 1417 | font-weight: normal; | 1487 | font-weight: normal; |
| 1488 | flex-shrink: 0; | ||
| 1418 | } | 1489 | } |
| 1419 | 1490 | ||
| 1420 | .date-text { | 1491 | .date-text { | ... | ... |
-
Please register or sign in to post a comment