Files
xk-doctor-wx/subPackages/sub_business_shared/order/components/ErpSyncPopup.vue
2026-06-18 10:20:24 +08:00

176 lines
4.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<drawer-page-container
v-model="show"
title="ERP 同步记录"
height="80%"
tall
:show-close="true"
:closeable="false"
@close="onClose"
>
<view class="popup-wrap">
<view class="summary">
<text>订单号{{ orderNo || '—' }}</text>
<text class="status-tag" :class="{ synced: isSyncErp === 1 }">{{ isSyncErp === 1 ? '已同步' : '未同步' }}</text>
</view>
<view v-if="showSyncBtn" class="sync-bar">
<button class="btn-sync" :loading="syncing" @click="handleSync">同步到 ERP</button>
</view>
<scroll-view scroll-y class="log-scroll" @scrolltolower="loadMore">
<view v-if="loading && !logs.length" class="hint">加载中...</view>
<view v-else-if="!logs.length" class="hint">暂无同步记录</view>
<view v-for="row in logs" :key="row.id" class="log-item">
<view class="log-head">
<text class="log-time">{{ row.created_at }}</text>
<text class="log-result" :class="{ ok: row.is_success === 1 }">
{{ row.is_success === 1 ? '成功' : '失败' }}
</text>
</view>
<view class="log-preview">{{ row.content_preview || row.content || '—' }}</view>
</view>
<view v-if="loadingMore" class="hint">加载更多...</view>
</scroll-view>
</view>
</drawer-page-container>
</template>
<script>
import DrawerPageContainer from '@/subPackages/sub_business_shared/components/DrawerPageContainer.vue'
export default {
name: 'ErpSyncPopup',
components: { DrawerPageContainer },
props: {
bizApi: { type: Object, required: true },
},
data() {
return {
show: false,
orderId: 0,
orderNo: '',
isSyncErp: 0,
logs: [],
page: 1,
pageSize: 10,
total: 0,
loading: false,
loadingMore: false,
syncing: false,
}
},
computed: {
showSyncBtn() {
return this.isSyncErp !== 1
},
},
methods: {
open(order) {
this.orderId = order.id
this.orderNo = order.order_no || ''
this.isSyncErp = Number(order.is_sync_erp)
this.logs = []
this.page = 1
this.total = 0
this.show = true
this.loadLogs(false)
},
onClose() {
this.show = false
},
loadLogs(append) {
if (!this.orderId) return
if (append) {
if (this.logs.length >= this.total) return
this.loadingMore = true
} else {
this.loading = true
}
const page = append ? this.page + 1 : 1
this.bizApi.getChinaErpSyncLogs({
order_id: this.orderId,
page,
pageSize: this.pageSize,
}).then(w => {
if (!w.ok) return
const d = w.data || {}
const list = d.list || []
this.total = d.total != null ? d.total : list.length
this.page = page
this.logs = append ? this.logs.concat(list) : list
}).finally(() => {
this.loading = false
this.loadingMore = false
})
},
loadMore() {
if (!this.loading && !this.loadingMore) {
this.loadLogs(true)
}
},
handleSync() {
uni.showModal({
title: '同步到 ERP',
content: `确认将订单 ${this.orderNo || this.orderId} 同步到 MES`,
success: (r) => {
if (!r.confirm) return
this.syncing = true
this.bizApi.syncChinaOrderToErp({ order_id: this.orderId }).then(w => {
if (w.ok) {
uni.showToast({ title: '同步成功' })
this.isSyncErp = 1
this.page = 1
this.loadLogs(false)
this.$emit('success')
}
}).finally(() => { this.syncing = false })
},
})
},
},
}
</script>
<style lang="scss" scoped>
.popup-wrap {
padding: 0 32rpx 32rpx;
height: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
}
.summary {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 26rpx;
color: #4E5969;
margin-bottom: 16rpx;
flex-shrink: 0;
}
.status-tag {
padding: 4rpx 16rpx;
border-radius: 8rpx;
background: #FFF3E8;
color: #FF7D00;
font-size: 22rpx;
}
.status-tag.synced { background: rgba(106,205,187,.1); color: #6acdbb; }
.sync-bar { margin-bottom: 16rpx; flex-shrink: 0; }
.btn-sync {
margin: 0;
background: #6acdbb;
color: #fff;
border-radius: 12rpx;
font-size: 28rpx;
}
.btn-sync::after { display: none; }
.log-scroll { flex: 1; min-height: 0; }
.hint { text-align: center; color: #86909C; font-size: 26rpx; padding: 32rpx 0; }
.log-item { background: #F7F8FA; border-radius: 12rpx; padding: 20rpx; margin-bottom: 16rpx; }
.log-head { display: flex; justify-content: space-between; margin-bottom: 8rpx; }
.log-time { font-size: 24rpx; color: #86909C; }
.log-result { font-size: 24rpx; color: #F53F3F; }
.log-result.ok { color: #6acdbb; }
.log-preview { font-size: 26rpx; color: #4E5969; word-break: break-all; }
</style>