0602
This commit is contained in:
@@ -0,0 +1,297 @@
|
||||
<template>
|
||||
<view class="page-container">
|
||||
<!-- 库存调整 -->
|
||||
<view class="page-body">
|
||||
<view class="form-section">
|
||||
<view class="form-group">
|
||||
<view class="form-item">
|
||||
<text class="form-label required">数字识别码</text>
|
||||
<view class="input-row">
|
||||
<input class="form-input" placeholder="输入或扫码" v-model="form.code" />
|
||||
<view class="input-extra">
|
||||
<button class="btn btn-sm btn-outline" @click="scanCode">扫码</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="form-label required">调整重量(KG)</text>
|
||||
<input class="form-input" type="digit" placeholder="请输入调整后的重量" v-model="form.weight" />
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="form-label required">调整原因</text>
|
||||
<picker class="form-value" mode="selector" :range="reasonOptions" range-key="label" @change="onReasonChange">
|
||||
<text>{{ reasonLabel || '请选择' }}</text>
|
||||
<uni-icons type="right" size="14" color="#cccccc"></uni-icons>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="data-list">
|
||||
<view class="data-card">
|
||||
<view class="data-card-header">
|
||||
<text class="data-card-title">{{ (recordData.list && recordData.list[1]) || '' }}</text>
|
||||
<text class="data-card-tag orange">待调整</text>
|
||||
</view>
|
||||
<view class="data-card-row"><text>当前状态:</text><text class="val">{{ recordData.lx || '' }}</text></view>
|
||||
<view class="data-card-row"><text>数字识别码:</text><text class="val">{{ recordData.list && recordData.list[2] || '' }}</text></view>
|
||||
<view class="data-card-row"><text>当前重量:</text><text class="val">{{ (recordData.list && recordData.list[0]) || '' }}</text></view>
|
||||
<view class="data-card-row"><text>登记时间:</text><text class="val">{{ (recordData.list && recordData.list[3]) || '' }}</text></view>
|
||||
<!-- <view class="data-card-actions">
|
||||
<button class="btn btn-sm btn-outline" @click="handleGoSelect">选择</button>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="btn-area">
|
||||
<button class="btn btn-outline" @click="handleQuery">查询</button>
|
||||
<button class="btn btn-primary" @click="handleSubmit" :disabled="!canSubmit">提交调整</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 台账类型选择弹窗 -->
|
||||
<view class="type-modal-mask" v-if="showTypeModal" @click="showTypeModal = false">
|
||||
<view class="type-modal" @click.stop>
|
||||
<view class="type-modal-head">
|
||||
<text class="type-modal-title">选择台账类型</text>
|
||||
<text class="type-modal-close" @click="showTypeModal = false">✕</text>
|
||||
</view>
|
||||
<scroll-view class="type-modal-body" scroll-y>
|
||||
<view
|
||||
class="type-modal-item"
|
||||
v-for="item in ledgerTypeList"
|
||||
:key="item.id"
|
||||
@click="onTypeSelect(item)"
|
||||
>
|
||||
<text>{{ item.alias }}</text>
|
||||
<uni-icons type="right" size="14" color="#cccccc"></uni-icons>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { api } from '@/api/index'
|
||||
import scanMixin from '@/utils/barcodeMixin.js'
|
||||
import { getDateTime } from '@/utils/common.js'
|
||||
// 库存调整
|
||||
export default {
|
||||
mixins: [scanMixin],
|
||||
data() {
|
||||
return {
|
||||
reasonOptions: [
|
||||
{ value: 'SAR1', label: '贮存一段时间后库存发生变化' },
|
||||
{ value: 'SAR2', label: '不同称重设备导致的重量差异或原先库存重量为预估值' }
|
||||
],
|
||||
form: {
|
||||
code: '',
|
||||
weight: '',
|
||||
reason: 'SAR1',
|
||||
time: ''
|
||||
},
|
||||
recordData: {},
|
||||
/* 选择模式回传标记 */
|
||||
isSelected: false,
|
||||
selectedItem: null,
|
||||
/* 台账类型选择弹窗 */
|
||||
showTypeModal: false,
|
||||
ledgerTypeList: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
canSubmit() {
|
||||
return this.recordData.list && this.recordData.list.length && this.form.weight && this.form.reason
|
||||
},
|
||||
reasonLabel() {
|
||||
const found = this.reasonOptions.find(item => item.value === this.form.reason)
|
||||
return found ? found.label : ''
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
if (this.reasonOptions.length) {
|
||||
this.form.reason = this.reasonOptions[0].value
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
// 从选择页返回时,处理选中的数据
|
||||
if (this.isSelected && this.selectedItem) {
|
||||
const item = this.selectedItem
|
||||
this.isSelected = false
|
||||
this.selectedItem = null
|
||||
|
||||
let ledgerCode = ''
|
||||
if (typeof item === 'object' && item !== null) {
|
||||
ledgerCode = item.digital_id || item.code || ''
|
||||
if (!ledgerCode) {
|
||||
const keys = Object.keys(item)
|
||||
ledgerCode = keys.length ? (item[keys[0]] || '') : ''
|
||||
}
|
||||
} else {
|
||||
// 字符串类型:按空格分割,取第一部分作为台账编号
|
||||
const parts = String(item).split(/\s+/).filter(p => p)
|
||||
ledgerCode = parts.length > 0 ? parts[0] : ''
|
||||
}
|
||||
if (ledgerCode) {
|
||||
this.handleClickQuery(ledgerCode)
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/** 扫码结果回调:填充数字识别码 -> 自动查询 */
|
||||
onBarcodeScanned(barcode) {
|
||||
this.form.code = barcode
|
||||
uni.showToast({ title: '扫码成功 ' + barcode, icon: 'none' })
|
||||
this.handleQuery()
|
||||
},
|
||||
handleQuery() {
|
||||
if (!this.form.code) return uni.showToast({ title: '请输入数字识别码', icon: 'none' })
|
||||
api.scanGet({ code: this.form.code }).then(res => {
|
||||
console.log('res', res)
|
||||
this.recordData = res.data
|
||||
this.form.weight = ''
|
||||
// this.form.reason = ''
|
||||
uni.showToast({ title: '查询成功', icon: 'success' })
|
||||
}).catch(() => {
|
||||
this.recordData = {}
|
||||
})
|
||||
},
|
||||
onReasonChange(e) {
|
||||
const index = e.detail.value
|
||||
this.form.reason = this.reasonOptions[index].value
|
||||
},
|
||||
/** 选择回传后调用 clickGet 查询数据,ledgerCode 为台账编号 */
|
||||
handleClickQuery(ledgerCode) {
|
||||
if (!ledgerCode) return
|
||||
api.clickGet({ code: ledgerCode }).then(res => {
|
||||
console.log('ledgerCode', ledgerCode)
|
||||
console.log('res', res)
|
||||
this.recordData = res.data
|
||||
// 处理 data 字段:如果是字符串则按空格分割成数组
|
||||
if (this.recordData.data && typeof this.recordData.data === 'string') {
|
||||
this.recordData.data = this.recordData.data.split(/\s+/).filter(item => item)
|
||||
}
|
||||
this.form.code = res.data.digital_id || ''
|
||||
this.form.weight = ''
|
||||
// this.form.reason = ''
|
||||
}).catch(() => {
|
||||
this.recordData = {}
|
||||
})
|
||||
},
|
||||
/** 跳转到台账列表选择页 */
|
||||
async handleGoSelect() {
|
||||
try {
|
||||
const res = await api.ledgetType()
|
||||
if (res.data.length) {
|
||||
this.ledgerTypeList = res.data.sort((a, b) => a.sort_order - b.sort_order)
|
||||
this.showTypeModal = true
|
||||
} else {
|
||||
uni.showToast({ title: '暂无可选台账类型', icon: 'none' })
|
||||
}
|
||||
} catch (e) {
|
||||
// request.js 已处理 loading 和错误提示
|
||||
}
|
||||
},
|
||||
/** 选择台账类型后跳转 detail 页 */
|
||||
onTypeSelect(item) {
|
||||
this.showTypeModal = false
|
||||
uni.navigateTo({
|
||||
url: '/pages/ledger/detail?mode=select&item=' + encodeURIComponent(JSON.stringify(item))
|
||||
})
|
||||
},
|
||||
handleSubmit() {
|
||||
if (!this.canSubmit) return
|
||||
api.adjust({
|
||||
code: this.form.code,
|
||||
weight: parseFloat(this.form.weight),
|
||||
time: getDateTime(),
|
||||
reason: this.form.reason
|
||||
}).then(res => {
|
||||
uni.showToast({ title: '提交成功', icon: 'success' })
|
||||
setTimeout(() => {
|
||||
this.recordData = {};
|
||||
this.form = {
|
||||
code: '',
|
||||
weight: '',
|
||||
reason: this.reasonOptions[0].value,
|
||||
time: ''
|
||||
}
|
||||
}, 1500)
|
||||
}).catch(() => {
|
||||
// request.js 已处理 loading 和错误提示
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.data-card-tag.orange {
|
||||
background-color: #fff7e6;
|
||||
color: #fa8c16;
|
||||
border: 1px solid #ffd591;
|
||||
}
|
||||
|
||||
/* 台账类型选择弹窗 */
|
||||
.type-modal-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.type-modal {
|
||||
width: 100%;
|
||||
max-height: 60vh;
|
||||
background: #ffffff;
|
||||
border-radius: $border-radius-xl $border-radius-xl 0 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.type-modal-head {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: $spacing-md;
|
||||
border-bottom: 1px solid $border-color;
|
||||
}
|
||||
|
||||
.type-modal-title {
|
||||
font-size: $font-size-lg;
|
||||
font-weight: 600;
|
||||
color: $text-primary;
|
||||
}
|
||||
|
||||
.type-modal-close {
|
||||
font-size: 18px;
|
||||
color: $text-placeholder;
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.type-modal-body {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.type-modal-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: $spacing-md;
|
||||
border-bottom: 1px solid $border-light;
|
||||
font-size: $font-size-base;
|
||||
color: $text-primary;
|
||||
|
||||
&:active {
|
||||
background: $bg-primary;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,353 @@
|
||||
<template>
|
||||
<view class="page-container">
|
||||
<!-- 联单生成 -->
|
||||
<view class="page-body">
|
||||
<view class="form-section">
|
||||
<view class="form-group">
|
||||
<!-- 处置公司(默认选中第一项) -->
|
||||
<view class="form-item">
|
||||
<text class="form-label required">处置公司</text>
|
||||
<picker :value="selectedTypeIndex" class="form-value" mode="selector" :range="typeCorpOptions" range-key="label" @change="onTypeCorpChange">
|
||||
<text>{{ form.type_corp_name || '请选择处置公司' }}</text>
|
||||
<uni-icons type="right" size="14" color="#cccccc"></uni-icons>
|
||||
</picker>
|
||||
</view>
|
||||
<!-- 运输经办人(type=3) -->
|
||||
<view class="form-item">
|
||||
<text class="form-label required">运输经办人</text>
|
||||
<picker :value="transportHandlerIndex" class="form-value" mode="selector" :range="transportHandlerOptions" range-key="label" @change="onTransportHandlerChange">
|
||||
<text>{{ transportHandlerIndex >= 0 ? transportHandlerOptions[transportHandlerIndex].label : '请选择运输经办人' }}</text>
|
||||
<uni-icons type="right" size="14" color="#cccccc"></uni-icons>
|
||||
</picker>
|
||||
</view>
|
||||
<!-- 出库经办人(type=4) -->
|
||||
<view class="form-item">
|
||||
<text class="form-label required">出库经办人</text>
|
||||
<picker :value="outHandlerIndex" class="form-value" mode="selector" :range="outHandlerOptions" range-key="label" @change="onOutHandlerChange">
|
||||
<text>{{ outHandlerIndex >= 0 ? outHandlerOptions[outHandlerIndex].label : '请选择出库经办人' }}</text>
|
||||
<uni-icons type="right" size="14" color="#cccccc"></uni-icons>
|
||||
</picker>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 处置公司详情信息 -->
|
||||
<view class="data-list" v-if="selectedTypeCorp">
|
||||
<view class="data-card">
|
||||
<view class="data-card-header"><text class="data-card-title">已选处置公司</text></view>
|
||||
<view class="data-card-row"><text>处置公司:</text><text class="val">{{ selectedTypeCorp.jydwmc || '-' }}</text></view>
|
||||
<view class="data-card-row"><text>废物名称:</text><text class="val">{{ selectedTypeCorp.fwmc || '-' }}</text></view>
|
||||
<view class="data-card-row"><text>废物代码:</text><text class="val">{{ selectedTypeCorp.fwdm || '-' }}</text></view>
|
||||
</view>
|
||||
<!-- type_corp_info 返回的信息 -->
|
||||
<view class="data-card" v-if="typeCorpInfoData.summary_lines && typeCorpInfoData.summary_lines.length">
|
||||
<view class="data-card-header" @click="summaryExpanded = !summaryExpanded">
|
||||
<text class="data-card-title">汇总信息</text>
|
||||
<text class="data-card-toggle">{{ summaryExpanded ? '收起 ▲' : '更多 ▼' }}</text>
|
||||
</view>
|
||||
<view class="data-card-body" :class="{ collapsed: !summaryExpanded }">
|
||||
<view class="data-card-row" v-for="(line, i) in typeCorpInfoData.summary_lines" :key="'s'+i">
|
||||
<text class="val summary-text">{{ line }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="data-card" v-if="typeCorpInfoData.receiver_company || typeCorpInfoData.transport_company">
|
||||
<view class="data-card-header"><text class="data-card-title">企业与经办人</text></view>
|
||||
<view class="data-card-row" v-if="typeCorpInfoData.receiver_company"><text>接收企业:</text><text class="val">{{ typeCorpInfoData.receiver_company }}</text></view>
|
||||
<view class="data-card-row" v-if="typeCorpInfoData.receiver_handler"><text>出库经办人:</text><text class="val">{{ typeCorpInfoData.receiver_handler }}</text></view>
|
||||
<view class="data-card-row" v-if="typeCorpInfoData.transport_company"><text>运输公司:</text><text class="val">{{ typeCorpInfoData.transport_company }}</text></view>
|
||||
<view class="data-card-row" v-if="typeCorpInfoData.transport_handler"><text>运输经办人:</text><text class="val">{{ typeCorpInfoData.transport_handler }}</text></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 提交按钮 -->
|
||||
<view class="btn-area">
|
||||
<button class="btn btn-outline" @click="handleQueryManifestList">查询联单列表</button>
|
||||
<button class="btn btn-primary btn-block" :disabled="!canSubmit" @click="handleSubmit">联单填领</button>
|
||||
</view>
|
||||
|
||||
<!-- 联单列表 -->
|
||||
<view class="data-list" v-if="manifestListData.length">
|
||||
<view class="data-card" v-for="(item, idx) in manifestListData" :key="idx">
|
||||
<view class="data-card-header">
|
||||
<text class="data-card-title">联单 {{ idx + 1 }}</text>
|
||||
<text class="data-card-tag" :class="item.ldzt === '100' ? 'orange' : 'red'">{{ item.ldzt === '100' ? '待处理' : item.ldzt }}</text>
|
||||
</view>
|
||||
<view class="data-card-row">
|
||||
<text>联单编号:</text>
|
||||
<text class="val">{{ item.ldbh || '-' }}</text>
|
||||
</view>
|
||||
<view class="data-card-row">
|
||||
<text>联单类型:</text>
|
||||
<text class="val">{{ item.ldlx || '-' }}</text>
|
||||
</view>
|
||||
<view class="data-card-row">
|
||||
<text>运输单位:</text>
|
||||
<text class="val">{{ item.ysdwmc || '-' }}</text>
|
||||
</view>
|
||||
<view class="data-card-row">
|
||||
<text>转运数量:</text>
|
||||
<text class="val">{{ item.zysl }}</text><text class="val">{{ item.jldw || '' }}</text>
|
||||
</view>
|
||||
<view class="data-card-row">
|
||||
<text>接收数量:</text><text class="val">{{ item.jssl }}</text><text class="val">{{ item.jldw || '' }}</text>
|
||||
</view>
|
||||
<view class="data-card-row">
|
||||
<text>危废运出时间:</text><text class="val">{{ item.wfycsj || '-' }}</text>
|
||||
</view>
|
||||
<view class="data-card-row">
|
||||
<text>办结时间:</text><text class="val">{{ item.bjsj || '-' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { api } from '@/api/index'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
/** 处置公司选项 */
|
||||
typeCorpOptions: [],
|
||||
/** 当前选中项在 typeCorpOptions 中的索引 */
|
||||
selectedTypeIndex: -1,
|
||||
/** 联单表单 */
|
||||
form: {
|
||||
type_corp: '',
|
||||
type_corp_name: '',
|
||||
ysjbr: '', // 运输经办人编码 type=3
|
||||
ckjbr: '' // 出库经办人编码 type=4
|
||||
},
|
||||
/** 运输经办人选项(type=3) */
|
||||
transportHandlerOptions: [],
|
||||
transportHandlerIndex: -1,
|
||||
/** 出库经办人选项(type=4) */
|
||||
outHandlerOptions: [],
|
||||
outHandlerIndex: -1,
|
||||
/** 汇总信息是否展开 */
|
||||
summaryExpanded: false,
|
||||
/** type_corp_info 接口返回数据 */
|
||||
typeCorpInfoData: {},
|
||||
/** 当前选中的处置公司(typeCorpList 中的原始数据) */
|
||||
selectedTypeCorp: null,
|
||||
/** 联单列表(manifestList 返回) */
|
||||
manifestListData: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
/** 处置公司已选择且两个经办人都已选择才可提交 */
|
||||
canSubmit() {
|
||||
return this.form.type_corp !== '' && this.form.ysjbr !== '' && this.form.ckjbr !== ''
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
// 先加载处置公司列表,再加载详情
|
||||
this.initPage()
|
||||
},
|
||||
methods: {
|
||||
// ==================== 页面初始化 ====================
|
||||
/** 初始化页面:依次获取 type_corp_list -> type_corp_info */
|
||||
async initPage() {
|
||||
await this.loadTypeCorpList()
|
||||
// 加载经办人列表
|
||||
await Promise.all([
|
||||
this.loadHandlers(3),
|
||||
this.loadHandlers(4)
|
||||
])
|
||||
// 默认选中第一项
|
||||
if (this.typeCorpOptions.length > 0) {
|
||||
const first = this.typeCorpOptions[0]
|
||||
this.selectTypeCorp(first)
|
||||
}
|
||||
// 默认选中经办人第一项
|
||||
if (this.transportHandlerOptions.length > 0) {
|
||||
this.transportHandlerIndex = 0
|
||||
this.form.ysjbr = this.transportHandlerOptions[0].value
|
||||
}
|
||||
if (this.outHandlerOptions.length > 0) {
|
||||
this.outHandlerIndex = 0
|
||||
this.form.ckjbr = this.outHandlerOptions[0].value
|
||||
}
|
||||
},
|
||||
|
||||
// ==================== 数据加载 ====================
|
||||
/** 加载处置公司列表(typeCorpList) */
|
||||
async loadTypeCorpList() {
|
||||
try {
|
||||
const res = await api.typeCorpList()
|
||||
console.log('[联单] typeCorpList:', res)
|
||||
if (res.code === 1000 && res.data) {
|
||||
this.typeCorpOptions = (Array.isArray(res.data) ? res.data : (res.data.list || [])).map(item => ({
|
||||
value: item.ctid,
|
||||
label: item.alias,
|
||||
ctid: item.ctid,
|
||||
jyqyid: item.jyqyid,
|
||||
jydwmc: item.jydwmc,
|
||||
cfxxtybh: item.cfxxtybh,
|
||||
fwmc: item.fwmc,
|
||||
fwdm: item.fwdm
|
||||
}))
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[联单] typeCorpList 加载失败:', e)
|
||||
}
|
||||
},
|
||||
|
||||
/** 加载处置公司详情(typeCorpInfo)并用返回数据填充表单 */
|
||||
async loadTypeCorpInfo(ctid) {
|
||||
try {
|
||||
const selected = this.typeCorpOptions.find(item => item.ctid === ctid)
|
||||
if (!selected) return
|
||||
const res = await api.typeCorpInfo({
|
||||
ctid: selected.ctid,
|
||||
cfxxtybh: selected.cfxxtybh,
|
||||
jyqyid: selected.jyqyid
|
||||
})
|
||||
console.log('[联单] typeCorpInfo:', res)
|
||||
if (res.code === 1000 && res.data) {
|
||||
this.typeCorpInfoData = res.data
|
||||
} else {
|
||||
this.typeCorpInfoData = {}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[联单] typeCorpInfo 加载失败:', e)
|
||||
this.typeCorpInfoData = {}
|
||||
}
|
||||
},
|
||||
|
||||
/** 查询联单列表(manifestList) */
|
||||
async handleQueryManifestList() {
|
||||
try {
|
||||
const res = await api.manifestList()
|
||||
console.log('[联单] manifestList:', res)
|
||||
if (res.data) {
|
||||
this.manifestListData = Array.isArray(res.data) ? res.data : (res.data.list || [])
|
||||
uni.showToast({ title: `查询到${this.manifestListData.length}条联单`, icon: 'success' })
|
||||
} else {
|
||||
this.manifestListData = []
|
||||
uni.showToast({ title: res.message || '暂无联单数据', icon: 'none' })
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[联单] manifestList 查询失败:', e)
|
||||
}
|
||||
},
|
||||
|
||||
// ==================== 表单事件 ====================
|
||||
/** 选中处置公司 */
|
||||
selectTypeCorp(item) {
|
||||
this.form.type_corp = item.ctid
|
||||
this.form.type_corp_name = item.jydwmc
|
||||
this.selectedTypeCorp = item
|
||||
this.selectedTypeIndex = this.typeCorpOptions.findIndex(opt => opt.ctid === item.ctid)
|
||||
// 选中后自动加载 type_corp_info
|
||||
this.loadTypeCorpInfo(item.ctid)
|
||||
},
|
||||
|
||||
/** 处置公司 picker change */
|
||||
onTypeCorpChange(e) {
|
||||
this.selectedTypeIndex = e.detail.value
|
||||
const selected = this.typeCorpOptions[e.detail.value]
|
||||
this.selectTypeCorp(selected)
|
||||
},
|
||||
|
||||
/** 加载经办人列表(handler) */
|
||||
async loadHandlers(type) {
|
||||
try {
|
||||
const res = await api.handler({ type })
|
||||
console.log(`[联单] handler(type=${type}):`, res)
|
||||
if (res.code === 1000 && res.data) {
|
||||
const list = Array.isArray(res.data) ? res.data : (res.data.list || [])
|
||||
const options = list.map(item => ({
|
||||
value: item.handler_code || item.code || '',
|
||||
label: item.handler_name || item.name || item.handler_code || item.code || ''
|
||||
}))
|
||||
if (type === 3) {
|
||||
this.transportHandlerOptions = options
|
||||
} else if (type === 4) {
|
||||
this.outHandlerOptions = options
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`[联单] handler(type=${type}) 加载失败:`, e)
|
||||
}
|
||||
},
|
||||
|
||||
/** 运输经办人 picker change */
|
||||
onTransportHandlerChange(e) {
|
||||
this.transportHandlerIndex = e.detail.value
|
||||
this.form.ysjbr = this.transportHandlerOptions[e.detail.value].value
|
||||
},
|
||||
|
||||
/** 出库经办人 picker change */
|
||||
onOutHandlerChange(e) {
|
||||
this.outHandlerIndex = e.detail.value
|
||||
this.form.ckjbr = this.outHandlerOptions[e.detail.value].value
|
||||
},
|
||||
|
||||
// ==================== 提交 ====================
|
||||
/** 提交联单(manifestCreate) */
|
||||
handleSubmit() {
|
||||
if (!this.canSubmit) return
|
||||
|
||||
api.manifestCreate({
|
||||
ctid: this.form.type_corp,
|
||||
tcode: '',
|
||||
ysjbr: this.form.ysjbr,
|
||||
ckjbr: this.form.ckjbr
|
||||
}).then(res => {
|
||||
console.log('[联单] manifestCreate:', res)
|
||||
uni.showToast({ title: '提交成功', icon: 'success' })
|
||||
}).catch(e => {
|
||||
console.error('[联单] 提交失败:', e)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.readonly {
|
||||
color: #999;
|
||||
}
|
||||
.form-section{
|
||||
padding-bottom: 6px;
|
||||
.form-group{
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
.summary-text {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
.data-card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.data-card-toggle {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
font-weight: 400;
|
||||
}
|
||||
.data-card-body.collapsed .data-card-row:nth-child(n+4) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.data-card-tag {
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
&.orange {
|
||||
background-color: #fff7e6;
|
||||
color: #fa8c16;
|
||||
border: 1px solid #ffd591;
|
||||
}
|
||||
&.red {
|
||||
background-color: #fff1f0;
|
||||
color: #f5222d;
|
||||
border: 1px solid #ffa39e;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,235 @@
|
||||
<template>
|
||||
<view class="page-container">
|
||||
<!-- 标签补打 -->
|
||||
|
||||
<view class="page-body">
|
||||
<view class="form-section">
|
||||
<view class="form-group">
|
||||
<view class="form-item">
|
||||
<text class="form-label required">数字识别码</text>
|
||||
<view class="input-row">
|
||||
<input class="form-input" placeholder="请输入数字识别码" v-model="form.code" />
|
||||
<view class="input-extra">
|
||||
<button class="btn btn-sm btn-outline" @click="scanCode">扫码</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="form-label">危废名称</text>
|
||||
<text class="form-value">{{ previewData.fwmc || '-' }}</text>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="form-label">产生时间</text>
|
||||
<text class="form-value">{{ previewData.cssj || '-' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 标签预览 -->
|
||||
<view class="label-preview">
|
||||
<view class="label-header" @click="expanded = !expanded">
|
||||
<text>危废标签</text>
|
||||
<text class="label-toggle">{{ expanded ? '收起 ▲' : '更多 ▼' }}</text>
|
||||
</view>
|
||||
<view class="label-content" :class="{ collapsed: !expanded }">
|
||||
<view class="label-row"><text class="label-key">废物名称</text><text class="label-val">{{ previewData.fwmc }}</text></view>
|
||||
<view class="label-row"><text class="label-key">废物代码</text><text class="label-val">{{ previewData.fwdm }}</text></view>
|
||||
<view class="label-row"><text class="label-key">废物类别</text><text class="label-val">{{ previewData.fwlb }}</text></view>
|
||||
<view class="label-row"><text class="label-key">废物形态</text><text class="label-val">{{ previewData.fwxt }}</text></view>
|
||||
<view class="label-row"><text class="label-key">数字识别码</text><text class="label-val label-code">{{ previewData.szsbm }}</text></view>
|
||||
|
||||
<view class="label-row"><text class="label-key">主要成分</text><text class="label-val">{{ previewData.zycf }}</text></view>
|
||||
<view class="label-row"><text class="label-key">有害成分</text><text class="label-val">{{ previewData.yhcf }}</text></view>
|
||||
<view class="label-row"><text class="label-key">危险特性</text><text class="label-val">{{ previewData.wxtx }}</text></view>
|
||||
<view class="label-row"><text class="label-key">注意事项</text><text class="label-val">{{ previewData.zysx }}</text></view>
|
||||
|
||||
<view class="label-row"><text class="label-key">产生数量</text><text class="label-val">{{ previewData.csl }} {{ previewData.jldw }}</text></view>
|
||||
<view class="label-row"><text class="label-key">产生时间</text><text class="label-val">{{ previewData.cssj }}</text></view>
|
||||
|
||||
<view class="label-row"><text class="label-key">单位名称</text><text class="label-val">{{ previewData.dwmc }}</text></view>
|
||||
<view class="label-row"><text class="label-key">联系人</text><text class="label-val">{{ previewData.lxr }}</text></view>
|
||||
<view class="label-row"><text class="label-key">联系电话</text><text class="label-val">{{ previewData.lxrsj }}</text></view>
|
||||
|
||||
<view class="label-row"><text class="label-key">容器类型</text><text class="label-val">{{ previewData.rqlx }}</text></view>
|
||||
<view class="label-row"><text class="label-key">容器材质</text><text class="label-val">{{ previewData.rqcz }}</text></view>
|
||||
<view class="label-row"><text class="label-key">容器容量</text><text class="label-val">{{ previewData.rqrl }}</text></view>
|
||||
|
||||
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="btn-area">
|
||||
<button class="btn btn-outline" @click="handleQuery">查询</button>
|
||||
<button class="btn btn-primary" @click="handlePrint" :disabled="!previewData.fwmc">打印标签</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { api } from '@/api/index'
|
||||
import scanMixin from '@/utils/barcodeMixin.js'
|
||||
// #ifdef APP-PLUS
|
||||
import printerService from '@/utils/BluetoothPrinterService.js'
|
||||
// #endif
|
||||
|
||||
export default {
|
||||
mixins: [scanMixin],
|
||||
data() {
|
||||
return {
|
||||
form: { code: '' },
|
||||
previewData: {},
|
||||
expanded: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/** 扫码结果回调:填充数字识别码 -> 自动查询 */
|
||||
onBarcodeScanned(barcode) {
|
||||
this.form.code = barcode
|
||||
uni.showToast({ title: '扫码成功 ' + barcode, icon: 'none' })
|
||||
this.handleQuery()
|
||||
},
|
||||
|
||||
// 查询
|
||||
async handleQuery() {
|
||||
if (!this.form.code) return uni.showToast({ title: '请输入数字识别码', icon: 'none' })
|
||||
|
||||
try {
|
||||
const res = await api.labelPrint({ code: this.form.code })
|
||||
|
||||
if (res.data) {
|
||||
this.previewData = res.data
|
||||
uni.showToast({ title: '查询成功', icon: 'none' })
|
||||
} else {
|
||||
this.previewData = {}
|
||||
uni.showToast({ title: res.msg || '未查询到数据', icon: 'none' })
|
||||
}
|
||||
} catch (e) {
|
||||
// request.js 已处理 loading 和错误提示
|
||||
console.error('[补打] 查询失败:', e)
|
||||
}
|
||||
},
|
||||
async handlePrint() {
|
||||
if (!this.previewData.fwmc) {
|
||||
return uni.showToast({ title: '请先查询危废信息', icon: 'none' })
|
||||
}
|
||||
// #ifdef APP-PLUS
|
||||
const printData = this.printData()
|
||||
uni.showToast({ title: '打印中...', icon: 'none' })
|
||||
try {
|
||||
await printerService.init()
|
||||
await printerService.autoConnect()
|
||||
await printerService.printWasteLabel(printData)
|
||||
await this.handleDisconnect()
|
||||
uni.showToast({ title: '打印成功', icon: 'success' })
|
||||
} catch (error) {
|
||||
console.error('[补打] 打印失败:', error)
|
||||
uni.showToast({ title: '打印失败: ' + error, icon: 'none' })
|
||||
}
|
||||
// #endif
|
||||
// #ifdef MP
|
||||
uni.showToast({ title: '小程序暂不支持蓝牙打印', icon: 'none' })
|
||||
// #endif
|
||||
},
|
||||
// #ifdef APP-PLUS
|
||||
/** 断开蓝牙连接 */
|
||||
async handleDisconnect() {
|
||||
try {
|
||||
await printerService.disconnect()
|
||||
} catch (err) {
|
||||
console.warn('[补打] 蓝牙断开失败:', err)
|
||||
}
|
||||
},
|
||||
// #endif
|
||||
printData() {
|
||||
const printData = {
|
||||
'mingcheng': this.previewData.fwmc || '', // 危废名称
|
||||
'leibie': this.previewData.fwlb || '', // 危废类别
|
||||
'daima': this.previewData.fwdm || '', // 危废代码
|
||||
'xingtai': this.previewData.fwxt || '-', // 废物形态
|
||||
'zhuyaochengfen': this.previewData.zycf || '-', // 主要成分
|
||||
'youhaichengfen': this.previewData.yhcf || '-', // 有害成分
|
||||
'zhuyi': this.previewData.zysx || '-', // 注意事项
|
||||
'shibiema': this.previewData.szsbm || '', // 数字识别码
|
||||
'danwei': this.previewData.dwmc || '', // 单位名称
|
||||
'lianxi': this.previewData.lxr || '', // 联系人
|
||||
'riqi': this.previewData.cssj || '', // 产生时间
|
||||
'zhongliang': (this.previewData.csl || '') + ' ' + (this.previewData.jldw || ''), // 重量
|
||||
'beizhu': '危险特性: ' + (this.previewData.wxtx || '-'), // 备注
|
||||
'biaoshi': '', // 标识
|
||||
'qrcode': this.previewData.wxfwbqewm || '', // 二维码
|
||||
'lianxidianhua': this.previewData.lxrsj || '', // 联系电话
|
||||
'rongqileixing': this.previewData.rqlx || '', // 容器类型
|
||||
'rongqicaizhi': this.previewData.rqcz || '', // 容器材质
|
||||
'rongqirongliang': this.previewData.rqrl || '', // 容器容量
|
||||
}
|
||||
return printData
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
.label-preview {
|
||||
background: #ffffff;
|
||||
margin: 0 $spacing-md $spacing-md;
|
||||
border-radius: $border-radius-md;
|
||||
border: 2px dashed $border-color;
|
||||
overflow: hidden;
|
||||
}
|
||||
.label-header {
|
||||
background: $primary-color;
|
||||
color: #ffffff;
|
||||
text-align: center;
|
||||
padding: 8px 12px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.label-toggle {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
opacity: 0.9;
|
||||
}
|
||||
// 收起时隐藏第6条及以后的行
|
||||
.label-content.collapsed .label-row:nth-child(n+6) {
|
||||
display: none;
|
||||
}
|
||||
.label-content {
|
||||
padding: $spacing-md;
|
||||
}
|
||||
.label-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding: 6px 0;
|
||||
border-bottom: 1px solid $border-light;
|
||||
&:last-child { border-bottom: none; }
|
||||
}
|
||||
.label-section-title {
|
||||
padding: 10px 0 6px;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
color: $primary-color;
|
||||
border-bottom: 1px solid $border-light;
|
||||
margin-bottom: 4px;
|
||||
&:first-child { padding-top: 0; }
|
||||
}
|
||||
.label-key { color: $text-secondary; font-size: 13px; }
|
||||
.label-val { color: $text-primary; font-size: 13px; font-weight: 500; }
|
||||
.label-code {
|
||||
font-size: 11px !important;
|
||||
word-break: break-all;
|
||||
text-align: right;
|
||||
max-width: 60%;
|
||||
}
|
||||
.label-reprint {
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: $danger-color;
|
||||
margin-top: 8px;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<view class="page-container">
|
||||
|
||||
<view class="page-body">
|
||||
<view class="form-section">
|
||||
<view class="form-group">
|
||||
<view class="form-item">
|
||||
<text class="form-label required">数字识别码</text>
|
||||
<view class="input-row">
|
||||
<input class="form-input" placeholder="请输入数字识别码" v-model="form.code" />
|
||||
<view class="input-extra">
|
||||
<button class="btn btn-sm btn-outline" @click="scanCode">扫码</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<text class="form-label required">撤销原因</text>
|
||||
<input class="form-input" placeholder="请输入撤销原因" v-model="form.reason" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="data-list">
|
||||
<view class="data-card">
|
||||
<view class="data-card-header">
|
||||
<text class="data-card-title">{{ (recordData.list && recordData.list[1]) || '' }}</text>
|
||||
<text class="data-card-tag red">待撤销</text>
|
||||
</view>
|
||||
<view class="data-card-row"><text>当前状态:</text><text class="val">{{ recordData.lx || '' }}</text></view>
|
||||
<view class="data-card-row"><text>数字识别码:</text><text class="val">{{ recordData.list && recordData.list[2]|| '' }}</text></view>
|
||||
<view class="data-card-row"><text>重量:</text><text class="val">{{ (recordData.list && recordData.list[0]) || '' }}</text></view>
|
||||
<view class="data-card-row"><text>登记时间:</text><text class="val">{{ (recordData.list && recordData.list[3]) || '' }}</text></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="tip-bar tip-bar-danger">
|
||||
⚠️ 撤销操作不可逆,请谨慎操作!
|
||||
</view>
|
||||
|
||||
<view class="btn-area">
|
||||
<button class="btn btn-outline" @click="handleQuery">查询</button>
|
||||
<button class="btn btn-danger" @click="handleUndo" :disabled="!canUndo">确认撤销</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { api } from '@/api/index'
|
||||
import scanMixin from '@/utils/barcodeMixin.js'
|
||||
|
||||
export default {
|
||||
mixins: [scanMixin],
|
||||
data() {
|
||||
return {
|
||||
form: { code: '', reason: '', type: 'auto' },
|
||||
recordData: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
canUndo() {
|
||||
return this.recordData.list && this.recordData.list.length && this.form.reason
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/** 扫码结果回调:填充数字识别码 -> 自动查询 */
|
||||
onBarcodeScanned(barcode) {
|
||||
this.form.code = barcode
|
||||
uni.showToast({ title: '扫码成功 ' + barcode, icon: 'none' })
|
||||
this.handleQuery()
|
||||
},
|
||||
|
||||
// ==================== 原有方法 ====================
|
||||
handleQuery() {
|
||||
if (!this.form.code) return uni.showToast({ title: '请输入数字识别码', icon: 'none' })
|
||||
api.scanGet({ code: this.form.code }).then(res => {
|
||||
this.recordData = res.data
|
||||
this.form.reason = ''
|
||||
uni.showToast({ title: '查询成功', icon: 'success' })
|
||||
}).catch(() => {
|
||||
this.recordData = {}
|
||||
})
|
||||
},
|
||||
handleUndo() {
|
||||
if (!this.canUndo) return
|
||||
uni.showModal({
|
||||
title: '确认撤销',
|
||||
content: '确定要撤销这条记录吗?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
api.undo({
|
||||
code: this.form.code,
|
||||
reason: this.form.reason,
|
||||
type: this.form.type
|
||||
}).then(res => {
|
||||
uni.showToast({ title: '撤销成功', icon: 'success' })
|
||||
setTimeout(() => { this.recordData = {}; this.form = { code: this.form.code, reason: '', type: 'auto' } }, 1500)
|
||||
}).catch(() => {
|
||||
// request.js 已处理 loading 和错误提示
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
Reference in New Issue
Block a user