176 lines
4.9 KiB
Vue
176 lines
4.9 KiB
Vue
<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>
|