@ -11,7 +11,7 @@
@keyup.enter ="fetchData"
>
< template # append >
< el-button :icon = "Search" @click ="fetchData" / >
< el-button :icon = "Search" @click ="fetchData" / >
< / template >
< / el -input >
< / div >
@ -27,11 +27,15 @@
< el-checkbox-group v-model = "visibleColumnProps" class="column-selector" >
< div class = "col-group-title" > 基础信息 < / div >
< el-row :gutter = "10" >
< el-col :span = "12" v-for = "c in baseColumns" :key="c.prop"><el-checkbox :label="c.prop" > {{ c.label }} < / el -checkbox > < / el-col >
< el-col :span = "12" v-for = "c in baseColumns" :key="c.prop" >
< el -checkbox :label = "c.prop" > { { c . label } } < / el-checkbox >
< / el-col >
< / el-row >
< div class = "col-group-title" style = "margin-top:10px" > 库存与商务 < / div >
< el-row :gutter = "10" >
< el-col :span = "12" v-for = "c in stockColumns" :key="c.prop"><el-checkbox :label="c.prop" > {{ c.label }} < / el -checkbox > < / el-col >
< el-col :span = "12" v-for = "c in stockColumns" :key="c.prop" >
< el -checkbox :label = "c.prop" > { { c . label } } < / el-checkbox >
< / el-col >
< / el-row >
< / el-checkbox-group >
< / el-popover >
@ -80,8 +84,12 @@
< / template >
< template # default = "scope" v-else-if = "col.prop.includes('link')" >
< el -link v-if = "scope.row[col.prop]" type="primary" :href="scope.row[col.prop]" target="_blank" :underline="false" >
< el -icon > < Link / > < / el-icon > 查看
< el -link v-if = "scope.row[col.prop]" type="primary" :href="scope.row[col.prop]" target="_blank"
:underline = "false" >
< el-icon >
< Link / >
< / el-icon >
查看
< / el-link >
< / template >
@ -94,7 +102,10 @@
< el-table-column label = "操作" width = "220" fixed = "right" align = "center" >
< template # default = "{ row }" >
< el-button link type = "warning" size = "default" @click ="handlePrint(row)" >
< el -icon > < Printer / > < / el-icon > 打印
< el -icon >
< Printer / >
< / el-icon >
打印
< / el-button >
< el-button link type = "primary" size = "default" @click ="handleUpdate(row)" > 编辑 < / el -button >
< el-popconfirm title = "确定删除该条记录吗?不可恢复。" @confirm ="handleDelete(row)" width = "220" >
@ -132,7 +143,9 @@
< div class = "form-card basic-card" >
< div class = "card-title" >
< el-icon class = "icon" > < Box / > < / el-icon >
< el-icon class = "icon" >
< Box / >
< / el-icon >
< span > 1. 基础信息 < / span >
< span class = "sub-title" v-if = "dialogStatus === 'create'" > ( 请先搜索锁定物料 ) < / span >
< / div >
@ -172,18 +185,38 @@
< / el-col >
< el-col :span = "14" style = "display: flex; align-items: center;" >
< span class = "search-tip" >
< el-icon > < InfoFilled / > < / el-icon > 未输入时展示最新物料 ; 输入关键词进行精确搜索 。
< el-icon > < InfoFilled / > < / el-icon > 未输入时展示最新物料 ; 输入关键词进行精确搜索 。
< / span >
< / el-col >
< / el-row >
< div class = "read-only-grid" >
< el-row :gutter = "20" >
< el-col :span = "8" > < el-form-item label = "名称" > < el-input v-model = "form.material_name" disabled class="is-text-view" / > < / el-form-item > < / el-col >
< el-col :span = "8" > < el-form-item label = "规格型号" > < el-input v-model = "form.spec_model" disabled class="is-text-view" / > < / el-form-item > < / el-col >
< el-col :span = "8" > < el-form-item label = "单位" > < el-input v-model = "form.unit " disabled class="is-text-view" / > < / el-form-item > < / el-col >
< el-col :span = "8" > < el-form-item label = "类别" > < el-input v-model = "form.category" disabled class="is-text-view" / > < / el-form-item > < / el-col >
< el-col :span = "8" > < el-form-item label = "类型" > < el-input v-model = "form.material_type" disabled class="is-text-view" / > < / el-form-item > < / el-col >
< el-col :span = "8" >
< el-form-item label = "名称" >
< el-input v-model = "form.material_name " disabled class="is-text-view" / >
< / el -form -item >
< / el-col >
< el-col :span = "8" >
< el-form-item label = "规格型号" >
< el-input v-model = "form.spec_model" disabled class="is-text-view" />
< / el -form -item >
< / el-col >
< el-col :span = "8" >
< el-form-item label = "单位" >
< el-input v-model = "form.unit" disabled class="is-text-view" />
< / el -form -item >
< / el-col >
< el-col :span = "8" >
< el-form-item label = "类别" >
< el-input v-model = "form.category" disabled class="is-text-view" />
< / el -form -item >
< / el-col >
< el-col :span = "8" >
< el-form-item label = "类型" >
< el-input v-model = "form.material_type" disabled class="is-text-view" />
< / el -form -item >
< / el-col >
< / el-row >
< / div >
< / div >
@ -191,7 +224,9 @@
< div class = "form-card inbound-card" >
< div class = "card-title" >
< el-icon class = "icon" > < House / > < / el-icon >
< el-icon class = "icon" >
< House / >
< / el-icon >
< span > 2. 入库详情 < / span >
< / div >
@ -201,28 +236,38 @@
< el-form-item label = "编码/SKU" prop = "sku" >
< el-input
v-model = "form.sku"
placeholder = "系统自动生成 (0000000X)"
placeholder = "系统自动生成 (000000000 X)"
disabled
/ >
< / el-form-item >
< / el-col >
< el-col :span = "6" >
< el-form-item label = "入库日期" prop = "in_date" >
< el-date-picker v-model = "form.in_date" type="date" value-format="YYYY-MM-DD" style="width:100%" disabled / >
< el-date-picker v-model = "form.in_date" type="date" value-format="YYYY-MM-DD" style="width:100%"
disabled / >
< / el-form-item >
< / el-col >
< el-col :span = "6" >
< el-form-item label = "条码" prop = "barcode" >
< el-input v-model = "form.barcode" placeholder="扫描条码" />
< / el -form -item >
< / el-col >
< el-col :span = "6" >
< el-form-item label = "库位" prop = "warehouse_location" >
< el-input v-model = "form.warehouse_location" placeholder="例如: A-01-02" />
< / el -form -item >
< / el-col >
< el-col :span = "6" > < el-form-item label = "条码" prop = "barcode" > < el-input v-model = "form.barcode" placeholder="扫描条码" / > < / el-form-item > < / el-col >
< el-col :span = "6" > < el-form-item label = "库位" prop = "warehouse_location" > < el-input v-model = "form.warehouse_location" placeholder="例如: A-01-02" / > < / el-form-item > < / el-col >
< / el-row >
< div class = "identity-panel" >
< el-row >
< el-col :span = "24" style = "margin-bottom: 8px;" >
< el-radio-group v-model = "entryMode" @change="handleEntryModeChange" :disabled="modeLocked" size="small" class="custom-radio-group" >
< el-radio-group v-model = "entryMode" @change="handleEntryModeChange" :disabled="modeLocked"
size = "small" class = "custom-radio-group" >
< el-radio-button label = "batch" > 按批号入库 ( Batch ) < / el-radio-button >
< el-radio-button label = "serial" > 按序列号入库 ( SN ) < / el-radio-button >
< / el-radio-group >
< span v-if = "modeLocked" class="locked-msg" > < el -icon > < Lock / > < / el-icon > 历史锁定 < / span >
< span v-if = "modeLocked" class="locked-msg" > < el -icon > < Lock / > < / el-icon > 历史锁定 < / span >
< / el-col >
< / el-row >
@ -257,27 +302,28 @@
< el-row :gutter = "20" style = "margin-top: 10px;" >
< el-col :span = "6" >
< el-form-item label = "入库数量" prop = "in_quantity" >
< el-input-number v-model = "form.in_quantity" :min="1" controls-position="right" style="width:100%" class="strong-input" / >
< el-input-number v-model = "form.in_quantity" :min="1" controls-position="right" style="width:100%"
class = "strong-input" / >
< / el-form-item >
< / el-col >
< template v-if = "dialogStatus === 'update'" >
< el -col :span = "6" >
< el-form-item label = "当前库存" prop = "stock_quantity" >
< el-input-number v-model = "form.stock_quantity" disabled style="width:100%" :controls="false" / >
< el-input-number v-model = "form.stock_quantity" disabled style="width:100%" :controls="false" / >
< / el -form -item >
< / el-col >
< el-col :span = "6" >
< el-form-item label = "当前可用" prop = "available_quantity" >
< el-input-number v-model = "form.available_quantity" disabled style="width:100%" :controls="false" / >
< el-input-number v-model = "form.available_quantity" disabled style="width:100%" :controls="false" / >
< / el -form -item >
< / el-col >
< el-col :span = "6" >
< el-form-item label = "库存状态" prop = "status" >
< el-select v-model = "form.status" style="width:100%" >
< el -option label = "在库" value = "在库" / >
< el-option label = "出库" value = "出库" / >
< el-option label = "损耗" value = "损耗" / >
< el -option label = "在库" value = "在库" / >
< el-option label = "出库" value = "出库" / >
< el-option label = "损耗" value = "损耗" / >
< / el-select >
< / el-form-item >
< / el-col >
@ -292,7 +338,11 @@
< / el-select >
< / el-form-item >
< / el-col >
< el-col :span = "12" > < el-form-item label = "到货图片" prop = "arrival_photo" > < el-input v-model = "form.arrival_photo" placeholder="输入图片 URL" / > < / el-form-item > < / el-col >
< el-col :span = "12" >
< el-form-item label = "到货图片" prop = "arrival_photo" >
< el-input v-model = "form.arrival_photo" placeholder="输入图片 URL" />
< / el -form -item >
< / el-col >
< / el-row >
< div class = "divider-text" > 商务与采购信息 < / div >
@ -314,15 +364,22 @@
< / el-autocomplete >
< / el-form-item >
< / el-col >
< el-col :span = "6" > < el-form-item label = "汇率" > < el-input-number v-model = "form.exchange_rate" :precision="2" controls-position="right" style="width:100%" /> < / el -form -item > < / el-col >
< el-col :span = "6" >
< el-form-item label = "汇率" >
< el-input-number v-model = "form.exchange_rate" :precision="2" controls-position="right"
style = "width:100%" / >
< / el-form-item >
< / el-col >
< el-col :span = "6" >
< el-form-item label = "含税单价" prop = "unit_price" >
< el-input-number v-model = "form.unit_price" :precision="4" controls-position="right" style="width:100%" / >
< el-input-number v-model = "form.unit_price" :precision="4" controls-position="right"
style = "width:100%" / >
< / el-form-item >
< / el-col >
< el-col :span = "6" >
< el-form-item label = "总价" >
< el-input-number v-model = "form.total_price" :precision="2" disabled :controls="false" style="width:100%" class="total-price-input" />
< el-input-number v-model = "form.total_price" :precision="2" disabled :controls="false"
style = "width:100%" class = "total-price-input" / >
< / el-form-item >
< / el-col >
< / el-row >
@ -370,8 +427,16 @@
< / el-row >
< el-row :gutter = "20" >
< el-col :span = "12" > < el-form-item label = "原始链接" > < el-input v-model = "form.source_link" placeholder="http://" / > < / el-form-item > < / el-col >
< el-col :span = "12" > < el-form-item label = "详情 链接" > < el-input v-model = "form.detail_link" placeholder="http://" / > < / el-form-item > < / el-col >
< el-col :span = "12" >
< el-form-item label = "原始 链接" >
< el-input v-model = "form.source_link" placeholder="http://" />
< / el -form -item >
< / el-col >
< el-col :span = "12" >
< el-form-item label = "详情链接" >
< el-input v-model = "form.detail_link" placeholder="http://" />
< / el -form -item >
< / el-col >
< / el-row >
< / div >
< / div >
@ -398,7 +463,7 @@
>
< div style = "text-align: center;" >
< div v-loading = "printLoading" class="preview-box" >
< img v-if = "previewUrl" :src="previewUrl" alt="Label Preview" style="width: 100%; border: 1px solid #ccc;" / >
< img v-if = "previewUrl" :src="previewUrl" alt="Label Preview" style="width: 100%; border: 1px solid #ccc;" / >
< div v-else class = "empty-preview" > 正在生成预览 ... < / div >
< / div >
@ -411,7 +476,10 @@
< div class = "dialog-footer" >
< el-button @click ="printVisible = false" > 取消 < / el -button >
< el-button type = "primary" :loading = "printing" @click ="confirmPrint" >
< el -icon > < Printer / > < / el-icon > 确认打印
< el -icon >
< Printer / >
< / el-icon >
确认打印
< / el-button >
< / div >
< / template >
@ -421,9 +489,9 @@
< / template >
< script setup lang = "ts" >
import { ref , reactive , onMounted , watch } from 'vue'
import { Plus , Setting , Refresh , Search , Lock , Box , House , InfoFilled , Link , Printer } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import { ref , reactive , onMounted , watch } from 'vue'
import { Plus , Setting , Refresh , Search , Lock , Box , House , InfoFilled , Link , Printer } from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'
import dayjs from 'dayjs'
import {
getBuyList ,
@ -432,7 +500,7 @@ import {
deleteBuyInbound ,
searchMaterialBase
} from '@/api/inbound/buy'
import { getLabelPreview , executePrint } from '@/api/common/print'
import { getLabelPreview , executePrint } from '@/api/common/print'
// ------------------------------------
// 状态与变量
@ -445,7 +513,7 @@ const dialogStatus = ref<'create' | 'update'>('create')
const tableData = ref ( [ ] )
const total = ref ( 0 )
const formRef = ref ( )
const queryParams = reactive ( { page : 1 , pageSize : 15 , keyword : '' } )
const queryParams = reactive ( { page : 1 , pageSize : 15 , keyword : '' } )
const materialOptions = ref < any [ ] > ( [ ] )
// 打印相关变量
@ -460,37 +528,37 @@ const modeLocked = ref(false)
// 列定义
const baseColumns = [
{ prop : 'material_name' , label : '名称' } ,
{ prop : 'category' , label : '类别' } ,
{ prop : 'material_type' , label : '类型' } ,
{ prop : 'spec_model' , label : '规格型号' } ,
{ prop : 'unit' , label : '单位' } ,
{ prop : 'material_name' , label : '名称' } ,
{ prop : 'category' , label : '类别' } ,
{ prop : 'material_type' , label : '类型' } ,
{ prop : 'spec_model' , label : '规格型号' } ,
{ prop : 'unit' , label : '单位' } ,
]
const stockColumns = [
{ prop : 'id' , label : 'ID' , minWidth : '60' } ,
{ prop : 'base_id' , label : 'BaseID' , minWidth : '80' } ,
{ prop : 'sku' , label : 'SKU' , minWidth : '120' } ,
{ prop : 'inbound_date' , label : '入库日期' , minWidth : '120' } ,
{ prop : 'barcode' , label : '条码' , minWidth : '120' } ,
{ prop : 'serial_number' , label : '序列号' , minWidth : '150' } ,
{ prop : 'batch_number' , label : '批号' , minWidth : '150' } ,
{ prop : 'status' , label : '状态' , minWidth : '100' } ,
{ prop : 'inspection_status' , label : '到检' , minWidth : '100' } ,
{ prop : 'qty_inbound' , label : '入库量' , minWidth : '100' } ,
{ prop : 'qty_stock' , label : '库存数' , minWidth : '100' } ,
{ prop : 'qty_available' , label : '可用数' , minWidth : '100' } ,
{ prop : 'warehouse_loc' , label : '库位' , minWidth : '120' } ,
{ prop : 'unit_price' , label : '单价' , minWidth : '120' } ,
{ prop : 'total_price' , label : '总价' , minWidth : '120' } ,
{ prop : 'currency' , label : '币种' , minWidth : '80' } ,
{ prop : 'exchange_rate' , label : '汇率' , minWidth : '80' } ,
{ prop : 'supplier_name' , label : '供应商' , minWidth : '150' } ,
{ prop : 'purchaser' , label : '采购人' , minWidth : '100' } ,
{ prop : 'purchaser_email' , label : '邮箱' , minWidth : '150' } ,
{ prop : 'source_link' , label : '采购链接' , minWidth : '100' } ,
{ prop : 'detail_link' , label : '详情链接' , minWidth : '100' } ,
{ prop : 'arrival_photo' , label : '到货图' , minWidth : '100' }
{ prop : 'id' , label : 'ID' , minWidth : '60' } ,
{ prop : 'base_id' , label : 'BaseID' , minWidth : '80' } ,
{ prop : 'sku' , label : 'SKU' , minWidth : '120' } ,
{ prop : 'inbound_date' , label : '入库日期' , minWidth : '120' } ,
{ prop : 'barcode' , label : '条码' , minWidth : '120' } ,
{ prop : 'serial_number' , label : '序列号' , minWidth : '150' } ,
{ prop : 'batch_number' , label : '批号' , minWidth : '150' } ,
{ prop : 'status' , label : '状态' , minWidth : '100' } ,
{ prop : 'inspection_status' , label : '到检' , minWidth : '100' } ,
{ prop : 'qty_inbound' , label : '入库量' , minWidth : '100' } ,
{ prop : 'qty_stock' , label : '库存数' , minWidth : '100' } ,
{ prop : 'qty_available' , label : '可用数' , minWidth : '100' } ,
{ prop : 'warehouse_loc' , label : '库位' , minWidth : '120' } ,
{ prop : 'unit_price' , label : '单价' , minWidth : '120' } ,
{ prop : 'total_price' , label : '总价' , minWidth : '120' } ,
{ prop : 'currency' , label : '币种' , minWidth : '80' } ,
{ prop : 'exchange_rate' , label : '汇率' , minWidth : '80' } ,
{ prop : 'supplier_name' , label : '供应商' , minWidth : '150' } ,
{ prop : 'purchaser' , label : '采购人' , minWidth : '100' } ,
{ prop : 'purchaser_email' , label : '邮箱' , minWidth : '150' } ,
{ prop : 'source_link' , label : '采购链接' , minWidth : '100' } ,
{ prop : 'detail_link' , label : '详情链接' , minWidth : '100' } ,
{ prop : 'arrival_photo' , label : '到货图' , minWidth : '100' }
]
const allColumns = [ ... baseColumns , ... stockColumns ]
@ -516,7 +584,7 @@ const visibleColumnProps = ref(getSavedColumns())
watch ( visibleColumnProps , ( newVal ) => {
localStorage . setItem ( STORAGE _KEY _COLS , JSON . stringify ( newVal ) )
} , { deep : true } )
} , { deep : true } )
const form = reactive ( {
@ -554,7 +622,9 @@ const saveToHistory = (key: string, value: string) => {
list . unshift ( value )
if ( list . length > 20 ) list = list . slice ( 0 , 20 ) // 最多存20条
localStorage . setItem ( key , JSON . stringify ( list ) )
} catch ( e ) { console . error ( 'save history failed' , e ) }
} catch ( e ) {
console . error ( 'save history failed' , e )
}
}
// 获取历史 (String 类型)
@ -562,8 +632,10 @@ const getHistoryList = (key: string): any[] => {
try {
const existing = localStorage . getItem ( key )
const list = existing ? JSON . parse ( existing ) : [ ]
return list . map ( ( v : string ) => ( { value : v } ) )
} catch ( e ) { return [ ] }
return list . map ( ( v : string ) => ( { value : v } ) )
} catch ( e ) {
return [ ]
}
}
// 保存物料历史 (Object 类型)
@ -574,17 +646,20 @@ const saveMaterialHistory = (item: any) => {
const existing = localStorage . getItem ( key )
let list = existing ? JSON . parse ( existing ) : [ ]
list = list . filter ( ( i : any ) => i . id !== item . id )
list . unshift ( { ... item , isHistory : true } )
list . unshift ( { ... item , isHistory : true } )
if ( list . length > 10 ) list = list . slice ( 0 , 10 )
localStorage . setItem ( key , JSON . stringify ( list ) )
} catch ( e ) { }
} catch ( e ) {
}
}
const getMaterialHistory = ( ) => {
try {
const existing = localStorage . getItem ( HISTORY _KEYS . MATERIAL )
return existing ? JSON . parse ( existing ) : [ ]
} catch ( e ) { return [ ] }
} catch ( e ) {
return [ ]
}
}
@ -600,7 +675,7 @@ const createFilter = (queryString: string) => {
// 辅助函数:从当前表格提取
const getTableDataUnique = ( field : string ) => {
const uniqueItems = Array . from ( new Set ( tableData . value . map ( ( i : any ) => i [ field ] ) . filter ( Boolean ) ) )
return uniqueItems . map ( i => ( { value : i } ) )
return uniqueItems . map ( i => ( { value : i } ) )
}
// 通用查询: 历史记录 + 当前页面数据
@ -632,9 +707,9 @@ const handleEmailSelect = (item: any) => saveToHistory(HISTORY_KEYS.EMAIL, item.
// 4. 币种 (固定+过滤)
const currencyOptions = [
{ value : 'CNY' , desc : '人民币' } ,
{ value : 'USD' , desc : '美元' } ,
{ value : 'EUR' , desc : '欧元' }
{ value : 'CNY' , desc : '人民币' } ,
{ value : 'USD' , desc : '美元' } ,
{ value : 'EUR' , desc : '欧元' }
]
const querySearchCurrency = ( queryString : string , cb : any ) => {
const results = queryString ? currencyOptions . filter ( createFilter ( queryString ) ) : currencyOptions
@ -657,7 +732,7 @@ const handleSearchMaterial = async (query: string) => {
searchLoading . value = true
try {
const res : any = await searchMaterialBase ( query )
const apiResults = ( res . data || [ ] ) . map ( ( i : any ) => ( { ... i , isHistory : false } ) )
const apiResults = ( res . data || [ ] ) . map ( ( i : any ) => ( { ... i , isHistory : false } ) )
if ( ! query ) {
const history = getMaterialHistory ( )
@ -715,10 +790,10 @@ const validateIdentity = (rule: any, value: any, callback: any) => {
}
const rules = {
base _id : [ { required : true , message : '请选择物料' , trigger : 'change' } ] ,
in _quantity : [ { required : true , message : '请输入数量' , trigger : 'blur' } ] ,
serial _number : [ { validator : validateIdentity , trigger : 'blur' } , { validator : validateUnique , trigger : 'blur' } ] ,
batch _number : [ { validator : validateIdentity , trigger : 'blur' } , { validator : validateUnique , trigger : 'blur' } ]
base _id : [ { required : true , message : '请选择物料' , trigger : 'change' } ] ,
in _quantity : [ { required : true , message : '请输入数量' , trigger : 'blur' } ] ,
serial _number : [ { validator : validateIdentity , trigger : 'blur' } , { validator : validateUnique , trigger : 'blur' } ] ,
batch _number : [ { validator : validateIdentity , trigger : 'blur' } , { validator : validateUnique , trigger : 'blur' } ]
}
// ------------------------------------
@ -726,7 +801,7 @@ const rules = {
// ------------------------------------
const checkHistoryAndSetMode = async ( baseId : number ) => {
try {
const res : any = await getBuyList ( { page : 1 , pageSize : 1000 } )
const res : any = await getBuyList ( { page : 1 , pageSize : 1000 } )
const allItems = res . data . items || [ ]
const historyItems = allItems . filter ( ( item : any ) => item . base _id === baseId )
@ -749,7 +824,7 @@ const checkHistoryAndSetMode = async (baseId: number) => {
form . batch _number = '000001'
}
if ( formRef . value ) {
if ( formRef . value ) {
formRef . value . clearValidate ( 'serial_number' )
formRef . value . clearValidate ( 'batch_number' )
}
@ -771,10 +846,10 @@ const handleEntryModeChange = (val: string) => {
if ( val === 'batch' ) {
form . serial _number = ''
form . batch _number = '000001'
if ( formRef . value ) formRef . value . clearValidate ( 'serial_number' )
if ( formRef . value ) formRef . value . clearValidate ( 'serial_number' )
} else {
form . batch _number = ''
if ( formRef . value ) formRef . value . clearValidate ( 'batch_number' )
if ( formRef . value ) formRef . value . clearValidate ( 'batch_number' )
}
}
@ -788,7 +863,9 @@ const fetchData = async () => {
const res : any = await getBuyList ( queryParams )
tableData . value = res . data . items || [ ]
total . value = res . data . total || 0
} finally { loading . value = false }
} finally {
loading . value = false
}
}
const handleCreate = ( ) => {
@ -943,7 +1020,7 @@ const handlePrint = async (row: any) => {
try {
const res : any = await getLabelPreview ( printData )
previewUrl . value = res . data
} catch ( e ) {
} catch ( e ) {
ElMessage . error ( '预览生成失败' )
} finally {
printLoading . value = false
@ -956,7 +1033,7 @@ const confirmPrint = async () => {
await executePrint ( currentPrintData . value )
ElMessage . success ( '指令已发送' )
printVisible . value = false
} catch ( e : any ) {
} catch ( e : any ) {
ElMessage . error ( e . msg || '打印失败' )
} finally {
printing . value = false
@ -980,7 +1057,7 @@ const resetForm = () => {
}
const getStatusType = ( status : string ) => {
const map : any = { '在库' : 'success' , '出库' : 'info' , '损耗' : 'danger' }
const map : any = { '在库' : 'success' , '出库' : 'info' , '损耗' : 'danger' }
return map [ status ] || 'warning'
}
@ -1009,30 +1086,70 @@ onMounted(() => fetchData())
background : # fff ;
padding : 15 px 20 px ;
border - radius : 8 px ;
box - shadow : 0 2 px 12 px 0 rgba ( 0 , 0 , 0 , 0.05 ) ;
box - shadow : 0 2 px 12 px 0 rgba ( 0 , 0 , 0 , 0.05 ) ;
}
. left - tools {
flex : 0 0 350 px ;
}
. right - tools {
display : flex ;
gap : 10 px ;
align - items : center ;
}
. action - btn {
font - weight : 500 ;
}
. left - tools { flex : 0 0 350 px ; }
. right - tools { display : flex ; gap : 10 px ; align - items : center ; }
. action - btn { font - weight : 500 ; }
/* 表格美化 */
. modern - table {
border - radius : 8 px ;
overflow : hidden ;
box - shadow : 0 2 px 12 px 0 rgba ( 0 , 0 , 0 , 0.05 ) ;
box - shadow : 0 2 px 12 px 0 rgba ( 0 , 0 , 0 , 0.05 ) ;
}
: deep ( . table - header - gray th ) {
background - color : # f8f9fb ! important ;
color : # 606266 ;
font - weight : 600 ;
height : 50 px ;
}
. tag - sn { color : # 409 EFF ; font - weight : bold ; font - family : monospace ; }
. tag - b n { color : # 67 C23A ; font - weight : bold ; font - family : monospace ; }
. money - text { font - family : 'Consolas' , monospace ; color : # 303133 ; }
. stock - num { font - weight : bold ; color : # 333 ; font - size : 15 px ; }
. avail - num { font - weight : bold ; color : # 67 C23A ; font - size : 15 px ; }
. sum - tag { margin - left : 4 px ; transform : scale ( 0.9 ) ; }
. tag - s n {
color : # 409 EFF ;
font - weight : bold ;
font - family : monospace ;
}
. tag - bn {
color : # 67 C23A ;
font - weight : bold ;
font - family : monospace ;
}
. money - text {
font - family : 'Consolas' , monospace ;
color : # 303133 ;
}
. stock - num {
font - weight : bold ;
color : # 333 ;
font - size : 15 px ;
}
. avail - num {
font - weight : bold ;
color : # 67 C23A ;
font - size : 15 px ;
}
. sum - tag {
margin - left : 4 px ;
transform : scale ( 0.9 ) ;
}
/* 弹窗核心样式调整 */
: deep ( . el - dialog _ _body ) {
@ -1066,14 +1183,38 @@ onMounted(() => fetchData())
display : flex ;
align - items : center ;
}
. card - title . icon { margin - right : 8 px ; font - size : 18 px ; color : # 409 EFF ; }
. card - title . sub - title { font - size : 12 px ; color : # 909399 ; font - weight : normal ; margin - left : 10 px ; }
. card - content { padding : 15 px 20 px ; }
. card - title . icon {
margin - right : 8 px ;
font - size : 18 px ;
color : # 409 EFF ;
}
. card - title . sub - title {
font - size : 12 px ;
color : # 909399 ;
font - weight : normal ;
margin - left : 10 px ;
}
. card - content {
padding : 15 px 20 px ;
}
/* 基础信息卡片 */
. basic - card { border - left : 4 px solid # 409 EFF ; }
. search - tip { color : # 909399 ; font - size : 12 px ; margin - left : 10 px ; display : flex ; align - items : center ; gap : 4 px ; }
. basic - card {
border - left : 4 px solid # 409 EFF ;
}
. search - tip {
color : # 909399 ;
font - size : 12 px ;
margin - left : 10 px ;
display : flex ;
align - items : center ;
gap : 4 px ;
}
. is - text - view : deep ( . el - input _ _wrapper ) {
box - shadow : none ! important ;
background - color : # f5f7fa ;
@ -1081,10 +1222,17 @@ onMounted(() => fetchData())
border - radius : 0 ;
padding - left : 0 ;
}
. is - text - view : deep ( . el - input _ _inner ) { color : # 606266 ; font - weight : 500 ; font - size : 13 px ; }
. is - text - view : deep ( . el - input _ _inner ) {
color : # 606266 ;
font - weight : 500 ;
font - size : 13 px ;
}
/* 入库信息卡片 */
. inbound - card { border - left : 4 px solid # 67 C23A ; }
. inbound - card {
border - left : 4 px solid # 67 C23A ;
}
/* 身份区域 (SN/BN) */
. identity - panel {
@ -1094,11 +1242,33 @@ onMounted(() => fetchData())
padding : 12 px ;
margin - bottom : 15 px ;
}
. custom - radio - group { margin - bottom : 10 px ; }
. locked - msg { font - size : 12 px ; color : # e6a23c ; margin - left : 15 px ; }
. prefix - tag { font - weight : bold ; font - size : 12 px ; padding : 0 5 px ; border - radius : 4 px ; }
. prefix - tag . bn { color : # 67 C23A ; background : # f0f9eb ; }
. prefix - tag . sn { color : # 409 EFF ; background : # ecf5ff ; }
. custom - radio - group {
margin - bottom : 10 px ;
}
. locked - msg {
font - size : 12 px ;
color : # e6a23c ;
margin - left : 15 px ;
}
. prefix - tag {
font - weight : bold ;
font - size : 12 px ;
padding : 0 5 px ;
border - radius : 4 px ;
}
. prefix - tag . bn {
color : # 67 C23A ;
background : # f0f9eb ;
}
. prefix - tag . sn {
color : # 409 EFF ;
background : # ecf5ff ;
}
/* 分割线 */
. divider - text {
@ -1110,13 +1280,20 @@ onMounted(() => fetchData())
font - size : 13 px ;
font - weight : 500 ;
}
. divider - text : : before , . divider - text : : after {
content : '' ;
flex : 1 ;
border - bottom : 1 px solid # ebeef5 ;
}
. divider - text : : before { margin - right : 15 px ; }
. divider - text : : after { margin - left : 15 px ; }
. divider - text : : before {
margin - right : 15 px ;
}
. divider - text : : after {
margin - left : 15 px ;
}
/* 底部按钮 */
. dialog - footer {
@ -1128,10 +1305,27 @@ onMounted(() => fetchData())
border - top : 1 px solid # ebeef5 ;
}
. option - item { display : flex ; justify - content : space - between ; width : 100 % ; align - items : center ; }
. opt - name { font - weight : bold ; }
. opt - spec { color : # 8492 a6 ; font - size : 13 px ; margin - right : 10 px ; }
. total - price - input : deep ( . el - input _ _inner ) { color : # F56C6C ; font - weight : bold ; }
. option - item {
display : flex ;
justify - content : space - between ;
width : 100 % ;
align - items : center ;
}
. opt - name {
font - weight : bold ;
}
. opt - spec {
color : # 8492 a6 ;
font - size : 13 px ;
margin - right : 10 px ;
}
. total - price - input : deep ( . el - input _ _inner ) {
color : # F56C6C ;
font - weight : bold ;
}
. preview - box {
min - height : 150 px ;
@ -1141,5 +1335,8 @@ onMounted(() => fetchData())
background : # f5f7fa ;
border - radius : 4 px ;
}
. empty - preview { color : # 909399 ; }
. empty - preview {
color : # 909399 ;
}
< / style >