1
This commit is contained in:
@@ -168,29 +168,33 @@
|
|||||||
<el-input
|
<el-input
|
||||||
v-model="historyKeyword"
|
v-model="historyKeyword"
|
||||||
clearable
|
clearable
|
||||||
placeholder="搜型号、地址、下单人、订单号、分销标记"
|
placeholder="搜型号、地址、下单人、订单号、分销标记;待填写在前"
|
||||||
prefix-icon="el-icon-search"
|
prefix-icon="el-icon-search"
|
||||||
@keyup.enter.native="searchHistory"
|
@keyup.enter.native="searchHistory"
|
||||||
@clear="searchHistory"
|
@clear="searchHistory"
|
||||||
/>
|
/>
|
||||||
<el-button type="primary" :loading="historyLoading" @click="searchHistory">搜索</el-button>
|
<el-button type="primary" :loading="historyLoading" @click="searchHistory">搜索</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
<p class="history-hint">待填写(生成后未补全)排在前面,已落库记录也保留。</p>
|
||||||
<div class="history-list" v-loading="historyLoading">
|
<div class="history-list" v-loading="historyLoading">
|
||||||
<div v-if="!historyList.length && !historyLoading" class="history-empty">暂无历史记录</div>
|
<div v-if="!historyList.length && !historyLoading" class="history-empty">暂无历史记录</div>
|
||||||
<div
|
<div
|
||||||
v-for="row in historyList"
|
v-for="row in historyList"
|
||||||
:key="row.id"
|
:key="row.key"
|
||||||
class="history-item"
|
class="history-item"
|
||||||
@click="applyHistoryOrder(row)"
|
:class="{ 'is-unfilled': !row.filled }"
|
||||||
|
@click="applyHistoryItem(row)"
|
||||||
>
|
>
|
||||||
<div class="history-item-top">
|
<div class="history-item-top">
|
||||||
<span class="history-model">{{ historyFullModel(row) || '无型号' }}</span>
|
<span class="history-model">{{ historyItemModel(row) || '无型号' }}</span>
|
||||||
<span class="history-time">{{ formatHistoryTime(row) }}</span>
|
<span class="history-time">{{ formatHistoryTime(row) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="history-item-meta">
|
<div class="history-item-meta">
|
||||||
|
<el-tag v-if="!row.filled" type="warning" size="mini">待填写</el-tag>
|
||||||
|
<el-tag v-else type="success" size="mini">已落库</el-tag>
|
||||||
<span v-if="row.distributionMark">{{ row.distributionMark }}</span>
|
<span v-if="row.distributionMark">{{ row.distributionMark }}</span>
|
||||||
<span v-if="row.buyer">{{ row.buyer }}</span>
|
<span v-if="row.buyer">{{ row.buyer }}</span>
|
||||||
<span v-if="row.paymentAmount != null">付款 {{ formatMoneyText(row.paymentAmount) }}</span>
|
<span v-if="row.paymentAmount != null && row.paymentAmount !== ''">付款 {{ formatHistoryMoney(row.paymentAmount) }}</span>
|
||||||
<span v-if="row.orderId">{{ row.orderId }}</span>
|
<span v-if="row.orderId">{{ row.orderId }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="row.address" class="history-item-addr">{{ row.address }}</div>
|
<div v-if="row.address" class="history-item-addr">{{ row.address }}</div>
|
||||||
@@ -204,7 +208,7 @@
|
|||||||
:page-size="historyPageSize"
|
:page-size="historyPageSize"
|
||||||
:total="historyTotal"
|
:total="historyTotal"
|
||||||
:pager-count="isMobile ? 5 : 7"
|
:pager-count="isMobile ? 5 : 7"
|
||||||
@current-change="loadHistory"
|
@current-change="sliceHistoryPage"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@@ -218,7 +222,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { executeInstruction, executeInstructionWithForce } from '@/api/system/instruction'
|
import { executeInstruction, executeInstructionWithForce, getHistory } from '@/api/system/instruction'
|
||||||
import { listJDOrders, listQuickRecordModelOptions, listQuickRecordShopOptions } from '@/api/system/jdorder'
|
import { listJDOrders, listQuickRecordModelOptions, listQuickRecordShopOptions } from '@/api/system/jdorder'
|
||||||
import QuickRecordModelShopConfig from './components/QuickRecordModelShopConfig.vue'
|
import QuickRecordModelShopConfig from './components/QuickRecordModelShopConfig.vue'
|
||||||
|
|
||||||
@@ -261,6 +265,7 @@ export default {
|
|||||||
historyVisible: false,
|
historyVisible: false,
|
||||||
historyLoading: false,
|
historyLoading: false,
|
||||||
historyKeyword: '',
|
historyKeyword: '',
|
||||||
|
historyAll: [],
|
||||||
historyList: [],
|
historyList: [],
|
||||||
historyPage: 1,
|
historyPage: 1,
|
||||||
historyPageSize: 15,
|
historyPageSize: 15,
|
||||||
@@ -720,20 +725,200 @@ export default {
|
|||||||
this.historyPage = 1
|
this.historyPage = 1
|
||||||
this.loadHistory()
|
this.loadHistory()
|
||||||
},
|
},
|
||||||
|
sliceHistoryPage() {
|
||||||
|
const start = (this.historyPage - 1) * this.historyPageSize
|
||||||
|
this.historyList = this.historyAll.slice(start, start + this.historyPageSize)
|
||||||
|
},
|
||||||
|
extractHistoryParts(item) {
|
||||||
|
const raw = String(item || '')
|
||||||
|
const idx = raw.indexOf(' | ')
|
||||||
|
return {
|
||||||
|
time: idx > 0 ? raw.slice(0, idx) : '',
|
||||||
|
text: idx > 0 ? raw.slice(idx + 3) : raw
|
||||||
|
}
|
||||||
|
},
|
||||||
|
extractFormBody(full) {
|
||||||
|
const raw = String(full || '').replace(/\r\n/g, '\n').trim()
|
||||||
|
if (!raw) return ''
|
||||||
|
const sep = /\n-{3,}\s*落库回执\s*-{3,}\s*\n/
|
||||||
|
const m = sep.exec(raw)
|
||||||
|
return m ? raw.slice(0, m.index).trim() : raw
|
||||||
|
},
|
||||||
|
extractFormField(text, startLabel, endLabels) {
|
||||||
|
const src = String(text || '')
|
||||||
|
const idx = src.indexOf(startLabel)
|
||||||
|
if (idx < 0) return ''
|
||||||
|
let rest = src.slice(idx + startLabel.length)
|
||||||
|
let end = rest.length
|
||||||
|
;(endLabels || []).forEach(lab => {
|
||||||
|
if (!lab) return
|
||||||
|
const i = rest.indexOf(lab)
|
||||||
|
if (i >= 0 && i < end) end = i
|
||||||
|
})
|
||||||
|
return rest
|
||||||
|
.slice(0, end)
|
||||||
|
.replace(/[━—\-]{3,}/g, '')
|
||||||
|
.replace(/\n{2,}/g, '\n')
|
||||||
|
.trim()
|
||||||
|
},
|
||||||
|
parseOrderFormText(text) {
|
||||||
|
const raw = String(text || '').replace(/\r\n/g, '\n')
|
||||||
|
const isNew = raw.includes('下单人(需填):')
|
||||||
|
|| raw.includes('下单链接(必须用这个):')
|
||||||
|
|| raw.includes('—————————')
|
||||||
|
const field = (start, ends) => this.extractFormField(raw, start, ends)
|
||||||
|
if (isNew) {
|
||||||
|
return {
|
||||||
|
remark: field('单:', ['分销标记:']),
|
||||||
|
mark: field('分销标记:', ['第三方单号:', '—————————', '下单链接(必须用这个):']),
|
||||||
|
thirdParty: field('第三方单号:', ['—————————', '下单链接(必须用这个):']),
|
||||||
|
link: field('下单链接(必须用这个):', ['下单地址(注意带分机):', '—————————']),
|
||||||
|
address: field('下单地址(注意带分机):', ['—————————', '型号:']),
|
||||||
|
model: field('型号:', ['下单人(需填):', '下单付款(注意核对):']),
|
||||||
|
buyer: field('下单人(需填):', ['下单付款(注意核对):']),
|
||||||
|
payment: field('下单付款(注意核对):', ['后返金额(注意核对):']),
|
||||||
|
rebate: field('后返金额(注意核对):', ['订单号(需填):']),
|
||||||
|
orderId: field('订单号(需填):', ['物流链接(需填):']),
|
||||||
|
logistics: field('物流链接(需填):', ['备注(下单号码有变动', '—————————', '京粉实际价格'])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
remark: field('单:', ['备注:', '分销标记:']),
|
||||||
|
mark: field('分销标记:', ['第三方单号:', '型号:']),
|
||||||
|
thirdParty: field('第三方单号:', ['型号:']),
|
||||||
|
model: field('型号:', ['链接:']),
|
||||||
|
link: field('链接:', ['下单付款:']),
|
||||||
|
payment: field('下单付款:', ['后返金额:']),
|
||||||
|
rebate: field('后返金额:', ['地址:']),
|
||||||
|
address: field('地址:', ['物流链接:']),
|
||||||
|
logistics: field('物流链接:', ['订单号:']),
|
||||||
|
orderId: field('订单号:', ['下单人:']),
|
||||||
|
buyer: field('下单人:', ['京粉实际价格:'])
|
||||||
|
}
|
||||||
|
},
|
||||||
|
isPersistFilledText(parsed) {
|
||||||
|
if (!parsed) return false
|
||||||
|
return !!(
|
||||||
|
String(parsed.buyer || '').trim()
|
||||||
|
&& String(parsed.payment || '').trim()
|
||||||
|
&& String(parsed.orderId || '').trim()
|
||||||
|
&& String(parsed.logistics || '').trim()
|
||||||
|
)
|
||||||
|
},
|
||||||
|
isPersistFilledOrder(row) {
|
||||||
|
if (!row) return false
|
||||||
|
return !!(
|
||||||
|
String(row.buyer || '').trim()
|
||||||
|
&& row.paymentAmount != null && row.paymentAmount !== ''
|
||||||
|
&& String(row.orderId || '').trim()
|
||||||
|
&& String(row.logisticsLink || '').trim()
|
||||||
|
)
|
||||||
|
},
|
||||||
|
historyItemMatchesKeyword(item, kw) {
|
||||||
|
if (!kw) return true
|
||||||
|
const blob = [
|
||||||
|
item.modelNumber,
|
||||||
|
item.modelShop,
|
||||||
|
this.historyItemModel(item),
|
||||||
|
item.address,
|
||||||
|
item.buyer,
|
||||||
|
item.orderId,
|
||||||
|
item.distributionMark,
|
||||||
|
item.thirdPartyOrderNo,
|
||||||
|
item.remark
|
||||||
|
].join(' ').toLowerCase()
|
||||||
|
return blob.includes(kw.toLowerCase())
|
||||||
|
},
|
||||||
|
normalizeDraftItem(rawItem) {
|
||||||
|
const parts = this.extractHistoryParts(rawItem)
|
||||||
|
const body = this.extractFormBody(parts.text)
|
||||||
|
if (!this.formBodyLooksPersistable(body)) return null
|
||||||
|
const parsed = this.parseOrderFormText(body)
|
||||||
|
const modelFull = String(parsed.model || '').split('\n')[0].trim()
|
||||||
|
const shopParsed = this.parseModelWithShop(modelFull)
|
||||||
|
return {
|
||||||
|
key: 'draft-' + (parsed.remark || parts.time || modelFull),
|
||||||
|
source: 'draft',
|
||||||
|
filled: this.isPersistFilledText(parsed),
|
||||||
|
remark: String(parsed.remark || '').trim(),
|
||||||
|
distributionMark: String(parsed.mark || '').trim(),
|
||||||
|
modelNumber: shopParsed.base || modelFull,
|
||||||
|
modelShop: shopParsed.prefix,
|
||||||
|
address: this.compressAddressOneLine(parsed.address),
|
||||||
|
link: String(parsed.link || '').trim(),
|
||||||
|
thirdPartyOrderNo: String(parsed.thirdParty || '').trim(),
|
||||||
|
buyer: String(parsed.buyer || '').trim(),
|
||||||
|
paymentAmount: String(parsed.payment || '').trim(),
|
||||||
|
rebateAmount: String(parsed.rebate || '').trim(),
|
||||||
|
orderId: String(parsed.orderId || '').trim(),
|
||||||
|
logisticsLink: String(parsed.logistics || '').trim(),
|
||||||
|
orderTime: parts.time,
|
||||||
|
rawText: body
|
||||||
|
}
|
||||||
|
},
|
||||||
|
normalizeOrderItem(row) {
|
||||||
|
if (!row) return null
|
||||||
|
return {
|
||||||
|
key: 'order-' + (row.id || row.remark || row.orderId),
|
||||||
|
source: 'order',
|
||||||
|
filled: this.isPersistFilledOrder(row),
|
||||||
|
remark: row.remark || '',
|
||||||
|
distributionMark: row.distributionMark || '',
|
||||||
|
modelNumber: row.modelNumber || '',
|
||||||
|
modelShop: row.modelShop || '',
|
||||||
|
address: row.address || '',
|
||||||
|
link: row.link || '',
|
||||||
|
thirdPartyOrderNo: row.thirdPartyOrderNo || '',
|
||||||
|
buyer: row.buyer || '',
|
||||||
|
paymentAmount: row.paymentAmount,
|
||||||
|
rebateAmount: row.rebateAmount,
|
||||||
|
orderId: row.orderId || '',
|
||||||
|
logisticsLink: row.logisticsLink || '',
|
||||||
|
orderTime: row.orderTime || row.createTime,
|
||||||
|
id: row.id
|
||||||
|
}
|
||||||
|
},
|
||||||
async loadHistory() {
|
async loadHistory() {
|
||||||
this.historyLoading = true
|
this.historyLoading = true
|
||||||
try {
|
try {
|
||||||
const kw = (this.historyKeyword || '').trim()
|
const kw = (this.historyKeyword || '').trim()
|
||||||
const res = await listJDOrders({
|
const [histRes, orderRes] = await Promise.all([
|
||||||
pageNum: this.historyPage,
|
getHistory('response', 300, kw || undefined),
|
||||||
pageSize: this.historyPageSize,
|
listJDOrders({
|
||||||
|
pageNum: 1,
|
||||||
|
pageSize: 100,
|
||||||
orderBy: 'id',
|
orderBy: 'id',
|
||||||
isAsc: 'desc',
|
isAsc: 'desc',
|
||||||
quickRecordSearch: kw || undefined
|
quickRecordSearch: kw || undefined
|
||||||
})
|
})
|
||||||
this.historyList = (res && res.rows) || []
|
])
|
||||||
this.historyTotal = (res && res.total) || 0
|
const orders = ((orderRes && orderRes.rows) || []).map(this.normalizeOrderItem).filter(Boolean)
|
||||||
|
const persistedRemarks = new Set(
|
||||||
|
orders.map(o => String(o.remark || '').trim()).filter(Boolean)
|
||||||
|
)
|
||||||
|
const draftMap = new Map()
|
||||||
|
;((histRes && histRes.data) || []).forEach(raw => {
|
||||||
|
const draft = this.normalizeDraftItem(raw)
|
||||||
|
if (!draft) return
|
||||||
|
if (kw && !this.historyItemMatchesKeyword(draft, kw)) return
|
||||||
|
const remark = draft.remark
|
||||||
|
if (remark && persistedRemarks.has(remark)) return
|
||||||
|
if (remark && draftMap.has(remark)) return
|
||||||
|
const fallbackKey = draft.key
|
||||||
|
if (!remark && draftMap.has(fallbackKey)) return
|
||||||
|
draftMap.set(remark || fallbackKey, draft)
|
||||||
|
})
|
||||||
|
const drafts = Array.from(draftMap.values()).filter(d => !d.filled)
|
||||||
|
const unfilledOrders = orders.filter(o => !o.filled)
|
||||||
|
const filledOrders = orders.filter(o => o.filled)
|
||||||
|
this.historyAll = [...drafts, ...unfilledOrders, ...filledOrders]
|
||||||
|
this.historyTotal = this.historyAll.length
|
||||||
|
if ((this.historyPage - 1) * this.historyPageSize >= this.historyTotal) {
|
||||||
|
this.historyPage = 1
|
||||||
|
}
|
||||||
|
this.sliceHistoryPage()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
this.historyAll = []
|
||||||
this.historyList = []
|
this.historyList = []
|
||||||
this.historyTotal = 0
|
this.historyTotal = 0
|
||||||
this.$modal.msgError('加载历史记录失败')
|
this.$modal.msgError('加载历史记录失败')
|
||||||
@@ -741,7 +926,7 @@ export default {
|
|||||||
this.historyLoading = false
|
this.historyLoading = false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
historyFullModel(row) {
|
historyItemModel(row) {
|
||||||
if (!row) return ''
|
if (!row) return ''
|
||||||
const base = String(row.modelNumber || '').trim()
|
const base = String(row.modelNumber || '').trim()
|
||||||
const shop = String(row.modelShop || '').trim()
|
const shop = String(row.modelShop || '').trim()
|
||||||
@@ -750,6 +935,11 @@ export default {
|
|||||||
if (base.endsWith(shop)) return base
|
if (base.endsWith(shop)) return base
|
||||||
return base + shop
|
return base + shop
|
||||||
},
|
},
|
||||||
|
formatHistoryMoney(v) {
|
||||||
|
if (v == null || v === '') return ''
|
||||||
|
if (typeof v === 'number') return this.formatMoneyText(v)
|
||||||
|
return String(v)
|
||||||
|
},
|
||||||
formatHistoryTime(row) {
|
formatHistoryTime(row) {
|
||||||
const raw = (row && (row.orderTime || row.createTime)) || ''
|
const raw = (row && (row.orderTime || row.createTime)) || ''
|
||||||
if (!raw) return ''
|
if (!raw) return ''
|
||||||
@@ -772,26 +962,26 @@ export default {
|
|||||||
}
|
}
|
||||||
this.form.markSuffix = v
|
this.form.markSuffix = v
|
||||||
},
|
},
|
||||||
applyHistoryOrder(row) {
|
applyHistoryItem(row) {
|
||||||
if (!row) return
|
if (!row) return
|
||||||
this.applyMarkSuffixFromText(row.distributionMark)
|
this.applyMarkSuffixFromText(row.distributionMark)
|
||||||
if (row.modelShop) {
|
if (row.modelShop) {
|
||||||
this.form.model = String(row.modelNumber || '').trim()
|
this.form.model = String(row.modelNumber || '').trim()
|
||||||
this.form.shopPrefix = String(row.modelShop || '').trim()
|
this.form.shopPrefix = String(row.modelShop || '').trim()
|
||||||
} else {
|
} else {
|
||||||
this.applyModelWithShop(this.historyFullModel(row))
|
this.applyModelWithShop(this.historyItemModel(row))
|
||||||
}
|
}
|
||||||
this.form.address = this.compressAddressOneLine(row.address)
|
this.form.address = this.compressAddressOneLine(row.address)
|
||||||
this.form.link = String(row.link || '').trim()
|
this.form.link = String(row.link || '').trim()
|
||||||
this.form.thirdPartyOrderNoText = String(row.thirdPartyOrderNo || '').trim()
|
this.form.thirdPartyOrderNoText = String(row.thirdPartyOrderNo || '').trim()
|
||||||
this.form.buyer = String(row.buyer || '').trim()
|
this.form.buyer = String(row.buyer || '').trim()
|
||||||
this.form.paymentText = this.formatMoneyText(row.paymentAmount)
|
this.form.paymentText = this.formatHistoryMoney(row.paymentAmount)
|
||||||
this.form.rebateText = this.formatMoneyText(row.rebateAmount)
|
this.form.rebateText = this.formatHistoryMoney(row.rebateAmount)
|
||||||
this.form.orderIdText = String(row.orderId || '').trim()
|
this.form.orderIdText = String(row.orderId || '').trim()
|
||||||
this.form.logisticsLink = String(row.logisticsLink || '').trim()
|
this.form.logisticsLink = String(row.logisticsLink || '').trim()
|
||||||
this.resultText = ''
|
this.resultText = row.rawText || ''
|
||||||
this.historyVisible = false
|
this.historyVisible = false
|
||||||
this.$modal.msgSuccess('已回填历史记录,可修改后录单')
|
this.$modal.msgSuccess(row.filled ? '已回填历史记录,可修改后录单' : '已回填待填写表单,请补全后录单')
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
const formEl = this.$el && this.$el.querySelector('.fadan-form')
|
const formEl = this.$el && this.$el.querySelector('.fadan-form')
|
||||||
if (formEl && formEl.scrollIntoView) {
|
if (formEl && formEl.scrollIntoView) {
|
||||||
@@ -970,6 +1160,12 @@ export default {
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.history-hint {
|
||||||
|
margin: 0 0 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
.history-list {
|
.history-list {
|
||||||
max-height: 52vh;
|
max-height: 52vh;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
@@ -997,6 +1193,11 @@ export default {
|
|||||||
background: #f5faff;
|
background: #f5faff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.history-item.is-unfilled {
|
||||||
|
border-color: #f5dab1;
|
||||||
|
background: #fdf6ec;
|
||||||
|
}
|
||||||
|
|
||||||
.history-item-top {
|
.history-item-top {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|||||||
Reference in New Issue
Block a user