jifuyun-order-v1/src/components/Base.vue

1034 lines
42 KiB
Vue
Raw Normal View History

2025-07-05 21:43:01 +08:00
<template>
<el-row v-if="order_id">
2025-07-19 03:18:35 +08:00
<el-col :span="16" style="text-align: left;">
2025-07-05 21:43:01 +08:00
<el-form inline>
<el-form-item label="订单号">
<el-text type="primary" tag="b">{{ order_no }}</el-text>
</el-form-item>
<el-form-item label="客户">
<span v-if="enableCustomerEdit">
<el-autocomplete
v-model="customer_search"
:fetch-suggestions="customerSearch"
@select="updateCustomer"
clearable
class="inline-input w-50"
placeholder="名称关键字或手机号"
/>
<span class="ml-8px">
<el-button size="small" type="danger" circle @click="() => enableCustomerEdit = false"><i class="fa fa-close"></i></el-button>
</span>
</span>
<span v-else>
<el-button text type="primary" @click="handleCustomerEdit">
{{ userInfo.username }}
<el-icon class="el-icon--right"><EditPen /></el-icon>
</el-button>
</span>
</el-form-item>
<el-form-item label="订单备注">
<el-input v-model="order_note" @change="handleNoteChange" />
</el-form-item>
<el-form-item label="订单主题">
<el-input v-model="order_subject" @change="handleSubjectChange" />
</el-form-item>
</el-form>
</el-col>
2025-07-19 03:18:35 +08:00
<el-col :span="8">
<el-button type="warning" v-if="order_status==0 && goodsList.length && !has_supply_inquiry" @click="refresh" :icon="Camera" size="large">
2025-07-14 17:06:03 +08:00
扫描验证
</el-button>
2025-07-19 03:18:35 +08:00
<el-button color="#0f6b9c" v-if="order_status==0 && !has_supply_inquiry" :disabled="goodsList.length==0 || !goods_change" @click="saveGoods" :icon="ShoppingCartFull" size="large">
2025-07-05 21:43:01 +08:00
保存商品
</el-button>
2025-07-19 03:18:35 +08:00
<slot name="nogo"></slot>
2025-07-05 21:43:01 +08:00
</el-col>
</el-row>
<el-row v-else>
<el-col :span="8" :offset="8">
<el-form>
<el-form-item label="客户选择">
<el-autocomplete
v-model="customer_search"
:fetch-suggestions="customerSearch"
@select="handleCustomerSelect"
clearable
class="inline-input w-50"
placeholder="名称关键字或手机号"
/>
<el-text style="font-weight: 600;margin-left: 20px;" type="primary">{{ userInfo.username }}</el-text>
</el-form-item>
<el-form-item label="订单备注">
<el-input v-model="order_note" />
</el-form-item>
<el-form-item label="订单主题">
<el-input v-model="order_subject"/>
</el-form-item>
<el-form-item>
<div class="flex justify-center w-full">
2025-07-19 03:18:35 +08:00
<el-button color="#b23b2f" @click="create" :icon="EditPen" size="large" :disabled="!userInfo.id">创建订单</el-button>
2025-07-05 21:43:01 +08:00
</div>
</el-form-item>
</el-form>
</el-col>
2025-07-19 03:18:35 +08:00
<el-col :span="8">
<slot name="nogo"></slot>
2025-07-05 21:43:01 +08:00
</el-col>
</el-row>
<hr style="margin: 20px 0;" v-if="order_id">
<div v-if="order_id">
2025-07-19 03:18:35 +08:00
<el-button v-if="order_status==0 && !has_supply_inquiry" type="primary" :icon="DocumentCopy" @click="fileInput">批量导入产品</el-button>
2025-07-05 21:43:01 +08:00
<div class="flex w-full">
<el-table
ref="goodsTableRef"
2025-07-19 03:18:35 +08:00
v-loading="loading"
2025-07-05 21:43:01 +08:00
fit
:data="goodsList"
class="mt-4 text-xs w-auto"
:header-cell-style="{background: '#e0f2fe', color: 'black',borderColor: 'black'}"
:cell-style="{borderColor: 'black'}"
style="border: 1px solid black;"
size="small"
@row-click="editRow"
border
>
<el-table-column fixed label="#" type="index" width="50" align="center" header-align="center" />
<el-table-column prop="b_name" label="品牌" header-align="center" width="80" />
<el-table-column prop="code" label="件号" width="120" show-overflow-tooltip header-align="center">
<template #default="scope">
<el-popover effect="light" trigger="hover" placement="left-start" width="auto">
<template #default>
<div>代码: {{ scope.row.code }}</div>
<div>品名: {{ scope.row.name }}</div>
<div>品牌: {{ scope.row.b_name }}</div>
<div>数量: {{ scope.row.amount }}</div>
<div>备注: {{ scope.row.note }}</div>
</template>
<template #reference>
<el-text size="small" tag="b">{{ scope.row.code }}</el-text>
</template>
</el-popover>
</template>
</el-table-column>
<el-table-column prop="new_code" label="更新件号" header-align="center" width="110" show-overflow-tooltip>
<template #default="{row}">
<el-text size="small">{{ row.new_code }}</el-text>
</template>
</el-table-column>
<el-table-column label="名称" width="140" show-overflow-tooltip header-align="center">
<template #default="scope">
<el-text size="small">{{ scope.row.name }}</el-text>
</template>
</el-table-column>
<el-table-column prop="price" label="面价" header-align="center" align="right" width="110">
<template #default="scope">
<el-text size="small" tag="b" type="primary">{{ scope.row.price }}</el-text>
</template>
</el-table-column>
<el-table-column prop="add_time" label="价格版本" header-align="center" align="center" width="110" show-overflow-tooltip>
<template #default="{row}">
<el-text size="small" tag="b" type="danger">{{ row.add_time }}</el-text>
</template>
</el-table-column>
<el-table-column prop="sell_price" label="预估价" header-align="center" align="right" width="110">
<template #default="scope">
<el-text size="small" tag="b" type="success">{{ scope.row.sell_price }}</el-text>
</template>
</el-table-column>
<el-table-column prop="weight" label="重量" header-align="center" align="right" width="80">
<template #default="scope">
<el-text size="small">{{ scope.row.weight }}</el-text>
</template>
</el-table-column>
<el-table-column prop="volume" label="体积" header-align="center" align="right" width="80">
<template #default="scope">
<el-text size="small">{{ scope.row.volumn }}</el-text>
</template>
</el-table-column>
<el-table-column prop="amount" label="数量" width="60" header-align="center" align="center"/>
<el-table-column prop="note" label="备注" header-align="center" width="140" show-overflow-tooltip/>
<el-table-column prop="seller" label="商品来源" width="100" show-overflow-tooltip header-align="center" align="center">
<template #default="{row}">
<el-popover v-if="row.goods && row.goods.length" effect="light" trigger="hover" placement="left-start" width="auto">
<template #default>
<el-table
fit
:data="row.goods"
:height="240"
style="width: 400px;"
border
>
<el-table-column prop="seller_name" label="商户" show-overflow-tooltip />
<el-table-column prop="up_time" label="上架时间" show-overflow-tooltip align="center">
2025-07-14 17:06:03 +08:00
<template #default="{row: $row}">
{{ dayjs($row.up_time).format('YY-MM-DD') }}
2025-07-05 21:43:01 +08:00
</template>
</el-table-column>
<el-table-column prop="store_nums" label="库存" show-overflow-tooltip width="80px" align="right" />
<el-table-column prop="sell_price" label="售价" width="100px" align="right">
2025-07-14 17:06:03 +08:00
<template #default="{row: $row}">
<el-text :type="$row.no_tax == '0' ? 'info' : 'danger'" tag="b">{{ $row.sell_price }}</el-text>
2025-07-05 21:43:01 +08:00
</template>
</el-table-column>
</el-table>
</template>
<template #reference>
<el-text type="danger" tag="b" size="small">商城有货</el-text>
</template>
</el-popover>
<span v-else>
<el-text v-if="row.seller_id>0" tag="b">{{ row.seller }}</el-text>
<el-text v-else-if="row.type=='product'" type="success" tag="b" size="small">{{ row.seller }}</el-text>
<el-text v-else-if="row.type=='goods'" type="primary" tag="b" size="small">{{ row.seller }}</el-text>
<el-text v-else-if="row.type=='other'" type="warning" tag="b" size="small">{{ row.seller }}</el-text>
</span>
</template>
</el-table-column>
2025-07-19 03:18:35 +08:00
<el-table-column label="" header-align="center" align="center" v-if="order_status==0 && !has_supply_inquiry" width="300">
2025-07-05 21:43:01 +08:00
<template #default="scope">
<el-button
size="small"
type="primary"
:disabled="scope.$index==0"
:icon="ArrowUpBold"
@click.stop="moveUp(scope.$index,scope.row)"
/>
<el-button
size="small"
type="primary"
:disabled="scope.$index==(goodsList.length-1)"
:icon="ArrowDownBold"
@click.stop="moveDown(scope.$index,scope.row)"
/>
<el-button
size="small"
type="danger"
:icon="Delete"
@click.stop="()=>goodsList.splice(scope.$index,1)"
/>
2025-07-14 17:06:03 +08:00
<el-button
size="small"
:type="scope.row.focus ? 'danger' : 'success'"
:disabled="scope.row.focus"
@click.stop="setFocusItem(scope.row,scope.$index)"
>
<el-icon color="#FFF">
<FocusIn />
</el-icon>
</el-button>
<el-button
size="small"
type="primary"
:icon="Refresh"
@click.stop="reloadRow(scope.$index)"
/>
2025-07-19 03:18:35 +08:00
<el-button
size="small"
type="info"
:disabled="!`${scope.row.id}`.startsWith('0-')"
@click.stop="() => {}"
>
<el-icon><Camera /></el-icon>
</el-button>
2025-07-05 21:43:01 +08:00
</template>
</el-table-column>
</el-table>
</div>
2025-07-19 03:18:35 +08:00
<div class="w-full flex gap-2 items-center mt-4 justify-around bg-sky-50 p-2" v-if="order_status==0 && !has_supply_inquiry">
2025-07-05 21:43:01 +08:00
<div class="flex items-center">
<div class="font-bold">品牌</div>
<BrandPicker v-model="brandInfo" class="inline-input w-40 ml-2" :width="120" :font="12" />
</div>
<div class="flex items-center">
<div class="font-bold">件号</div>
<ProductPicker v-model.trim="product_code" class="inline-input w-40 ml-2" @selected="handleProductSelect" :width="120" :font="12" />
</div>
<div class="flex items-center">
<div class="font-bold">更新件号</div>
<div class="ml-2">
<el-input v-model="edit_data.new_code" clearable class="inline-input" style="width: 140px;font-size: 12px;"></el-input>
</div>
</div>
<div class="flex items-center">
<div class="font-bold">名称</div>
<div class="ml-2">
<el-input v-model="edit_data.name" clearable class="inline-input" style="width: 140px;font-size: 12px;"></el-input>
</div>
</div>
<div class="flex items-center">
<div class="font-bold">面价</div>
<div class="ml-2">
<el-input v-model="edit_data.price" :input-style="{'text-align': 'right'}" style="width: 90px;font-size: 12px;"></el-input>
</div>
</div>
<div class="flex items-center">
<div class="font-bold">预估价</div>
<div class="ml-2">
<el-input v-model="edit_data.sell_price" :input-style="{'text-align': 'right'}" style="width: 90px;font-size: 12px;"></el-input>
</div>
</div>
<div class="flex items-center">
<div class="font-bold">重量</div>
<div class="ml-2">
<el-input v-model="edit_data.weight" :input-style="{'text-align': 'right'}" style="width: 80px;font-size: 12px;"></el-input>
</div>
</div>
<div class="flex items-center">
<div class="font-bold">体积</div>
<div class="ml-2">
<el-input v-model="edit_data.volumn" :input-style="{'text-align': 'right'}" style="width: 80px;font-size: 12px;"></el-input>
</div>
</div>
<div class="flex items-center">
<div class="font-bold">数量</div>
<div class="ml-2">
<el-input v-model.number="edit_data.amount" :input-style="{'text-align': 'right'}" style="width: 80px;font-size: 12px;"></el-input>
</div>
</div>
<div class="flex items-center">
<div class="font-bold">备注</div>
<div class="ml-2">
<el-input v-model="edit_data.note" clearable class="inline-input" style="width: 160px;font-size: 12px;"></el-input>
</div>
</div>
<div class="flex items-center">
<el-button
size="default"
type="primary"
color="#0f6b9c"
:icon="Plus"
:disabled="!product_code || !brandInfo.id"
@click="submit_product"
>添加
</el-button>
<el-button
size="default"
type="danger"
:icon="Delete"
@click="clearInput"
class="ml-4"
>擦除
</el-button>
</div>
</div>
</div>
<el-dialog
v-model="centerDialogVisible"
title="更新预订商品信息"
width="30%"
destroy-on-close
center
>
<el-card class="box-card-edit">
<el-form :inline="true">
<el-form-item label="产品编码">
<el-input v-model="new_product.code" placeholder="产品编码" />
</el-form-item>
<el-form-item label="更新件号">
<el-input v-model="new_product.new_code" placeholder="更新件号" />
</el-form-item>
<el-form-item label="商品名称">
<el-input v-model="new_product.name" placeholder="商品名称" />
</el-form-item>
<el-form-item label="商品品牌">
<BrandPicker v-model="new_product.brand_info" class="inline-input w-40" />
</el-form-item>
<el-form-item label="商品面价">
<el-input v-model="new_product.price" placeholder="商品面价" />
</el-form-item>
<el-form-item label="商品售价">
<el-input v-model="new_product.sell_price" placeholder="商品售价" />
</el-form-item>
<el-form-item label="购买数量">
<el-input-number v-model="new_product.amount" :min="1" />
</el-form-item>
<el-form-item label="商品备注">
<el-input v-model="new_product.note" placeholder="商品备注" />
</el-form-item>
</el-form>
</el-card>
<template #footer>
<span class="dialog-footer">
<el-button type="success" @click="editProduct" :icon="UploadFilled">确认更新</el-button>
</span>
</template>
</el-dialog>
<el-dialog
v-model="focusDialogVisible"
title="大件跟踪"
width="30%"
destroy-on-close
center
>
<el-card class="box-card-edit">
<template #header>
<div class="card-header">
<span>跟踪{{`${focusInfo.b_name} ${focusInfo.code}`}}</span>
</div>
</template>
<el-form :inline="true">
<el-form-item label="更新件号">
<el-input v-model="focusInfo.new_code" placeholder="更新件号" />
</el-form-item>
<el-form-item label="产品面价">
<el-input v-model="focusInfo.price" />
</el-form-item>
</el-form>
<el-form style="margin-top: 20px;">
<el-form-item label="跟踪备注">
<el-input v-model="focusInfo.note" placeholder="跟踪备注" />
</el-form-item>
</el-form>
</el-card>
<template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="handleFocusItem" :icon="EditPen">
备注完成
</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import { ref,reactive,computed,nextTick,onMounted,onUnmounted } from 'vue'
2025-07-14 17:06:03 +08:00
import { EditPen,MessageBox,Plus,Delete,ArrowUpBold,ArrowDownBold,DocumentCopy,UploadFilled,ShoppingCartFull,Refresh,Camera } from '@element-plus/icons-vue'
2025-07-05 21:43:01 +08:00
import FocusIn from '@/components/icons/FocusIn.vue'
import dayjs from 'dayjs'
import {md5} from '@/utils'
import * as XLSX from 'xlsx'
2025-07-14 17:06:03 +08:00
import { memberInfo,searchMember,addLog } from '@/api'
import { onlyGoodsByCode,partsGoodsById,productInfo,hasProduct,hasFocus,hasFocusBatch,hasBrandProduct,addFocusLog,updateFocus } from '@/api/product'
2025-07-19 03:18:35 +08:00
import { createInquiry,inquiryInfo,inquiryGoodsList,update,addInquiryGoods,hasSupplyInquiry } from '@/api/inquiry'
2025-07-05 21:43:01 +08:00
import { ElMessage } from 'element-plus'
import BrandPicker from '@/components/BrandPicker.vue'
import ProductPicker from '@/components/ProductPicker.vue'
import { useUserStore } from '@/store'
const user_store = useUserStore()
const order_id = ref(0)
const order_status = ref(0)
const order_no = ref('')
const order_note = ref('')
const order_subject = ref('')
const userInfo = ref({
id: 0,
username: '',
})
const goodsList = ref([])
const goodsHash = ref('')
2025-07-19 03:18:35 +08:00
const loading = ref(false)
2025-07-05 21:43:01 +08:00
2025-07-14 17:06:03 +08:00
const emit = defineEmits(['status-change','add-goods','next-step','finish'])
2025-07-05 21:43:01 +08:00
const props = defineProps({
'orderId': {
type:Number,
default: 0
},
'orderStatus': {
type:Number,
default: 0
},
})
2025-07-19 03:18:35 +08:00
const has_supply_inquiry = ref(false)
const load = async() => {
const { data:order } = await inquiryInfo(order_id.value)
if(order.data.id && parseInt(order.data.id) == order_id.value) {
order_status.value = +order.data.status
order_no.value = order.data.order_no
order_note.value = order.data.note
order_subject.value = order.data.subject
const { user_id } = order.data
const { data:member } = await memberInfo(user_id)
if(member.data.id) {
userInfo.value = member.data
}
loading.value = true
const { data:res } = await inquiryGoodsList(order_id.value)
if(res.data.length > 0) {
2025-07-05 21:43:01 +08:00
let data_arr = res.data.map(item => ({brand: item.brand,code: item.code}))
const { data:r } = await hasFocusBatch(data_arr)
2025-07-14 17:06:03 +08:00
for(let item of r.data) {
let idx = res.data.findIndex(it => it.brand == item.brand && it.code == item.code)
res.data[idx].focus = item.has_focus
}
2025-07-05 21:43:01 +08:00
}
2025-07-19 03:18:35 +08:00
goodsHash.value = md5(JSON.stringify(res.data))
goodsList.value.push(...res.data)
loading.value = false
const { data:rb } = await hasSupplyInquiry(order_id.value)
has_supply_inquiry.value = +rb.data > 0
2025-07-05 21:43:01 +08:00
}
2025-07-19 03:18:35 +08:00
}
2025-07-05 21:43:01 +08:00
2025-07-19 03:18:35 +08:00
onMounted(async() => {
order_id.value = +props.orderId
order_status.value = +props.orderStatus
if(order_id.value != 0) {
await load()
2025-07-14 17:06:03 +08:00
}
})
2025-07-19 03:18:35 +08:00
// onUnmounted(() => {
// if(goods_change.value) {
// ElMessage({
// message: '商品列表有变更,请保存后再进行其他操作',
// type: 'warning',
// })
// }
// })
2025-07-05 21:43:01 +08:00
const goods_change = computed(() => {
return md5(JSON.stringify(goodsList.value)) !== goodsHash.value
})
2025-07-19 03:18:35 +08:00
// const orderDialogVisible = ref(false)
// const order_info = ref({
// order_id: 0,
// userInfo: {
// id: 0,
// username: '',
// head_ico: '',
// },
// sellerInfo: {
// seller_name: '',
// seller_id: 0,
// },
// note: '',
// subject: ''
// })
2025-07-05 21:43:01 +08:00
const customer_search = ref('')
const enableCustomerEdit = ref(false)
const handleCustomerEdit = () => {
enableCustomerEdit.value = true
customer_search.value = ''
}
const customerSearch = async (qs, cb) => {
if(qs && qs.length >= 2) {
try {
const {data:clist} = await searchMember(qs)
var list = clist.data
if (list.length == 0) {
list.push({
id: '-1',
value: '无匹配结果'
})
cb(list);
} else {
list = list.map(item => {
return {
value:`${item.username} ${item.true_name ?? ''} ${item.mobile ?? ''}`,
id: `${item.id}`
}
})
cb(list);
}
} catch (error) {
console.log(error)
}
}
}
const updateCustomer = async (item) => {
if(item.id != -1 && item.id != userInfo.value.id) {
const {data:user} = await memberInfo(item.id)
if(user.data) {
userInfo.value = {...user.data}
}
customer_search.value = ''
await handleCustomerChange()
}
enableCustomerEdit.value = false
}
const handleCustomerSelect = async (item) => {
if(item.id != -1) {
const {data:user} = await memberInfo(item.id)
if(user.data) {
userInfo.value = {...user.data}
}
customer_search.value = ''
}
}
2025-07-19 03:18:35 +08:00
const create = async () => {
2025-07-05 21:43:01 +08:00
if(!userInfo.value.id) {
ElMessage({
message: '创建订单必须先选择客户',
type: 'warning',
})
return
}
let action = '创建用户订单'
const { data:res } = await createInquiry(userInfo.value.id,order_note.value,order_subject.value)
if(res.data.order_id) {
order_id.value = res.data.order_id
order_no.value = res.data.order_no
2025-07-19 03:18:35 +08:00
await load()
2025-07-05 21:43:01 +08:00
await addLog(order_id.value,`${user_store.userName}(${user_store.userId})`,action,`客户:${userInfo.value.username}(${userInfo.value.id})`)
ElMessage({
message: '订单创建成功!',
type: 'success',
})
2025-07-19 03:18:35 +08:00
emit('status-change',order_id.value,'create-inquiry')
2025-07-05 21:43:01 +08:00
} else {
ElMessage({
message: '订单创建失败!',
type: 'warning',
})
}
}
const handleCustomerChange = async () => {
if(order_id.value) {
const {data: res} = await update(order_id.value,{user_id: userInfo.value.id})
await addLog(order_id.value,`${user_store.userName}(${user_store.userId})`,'修改订单客户信息',`${userInfo.value.username}(${userInfo.value.id})`)
ElMessage({
message: '成功修改订单客户!',
type: 'success',
})
2025-07-19 03:18:35 +08:00
emit('status-change',order_id.value,'customer-change')
2025-07-05 21:43:01 +08:00
}
}
const handleNoteChange = async () => {
if(order_id.value) {
await update(order_id.value,{note:order_note.value})
await addLog(order_id.value,`${user_store.userName}(${user_store.userId})`,'修改订单备注',order_note.value)
ElMessage({
message: '成功修改订单备注!',
type: 'success',
})
2025-07-19 03:18:35 +08:00
emit('status-change',order_id.value,'note-change')
2025-07-05 21:43:01 +08:00
}
}
const handleSubjectChange = async () => {
if(order_id.value) {
await update(order_id.value,{subject:order_subject.value})
await addLog(order_id.value,`${user_store.userName}(${user_store.userId})`,'修改订单主题',order_subject.value)
ElMessage({
message: '成功修改订单主题!',
type: 'success',
})
2025-07-19 03:18:35 +08:00
emit('status-change',order_id.value,'subject-change')
2025-07-05 21:43:01 +08:00
}
}
const baseItem = {
code: '',
new_code: '',
name: '',
b_name: '',
brand: 0,
price: 0,
sell_price: 0,
weight: 0.000,
volumn: 0.000,
amount: 1,
type: 'other',
seller: '待定',
seller_id: 0,
note: ''
}
const brandInfo = ref({})
const product_code = ref('')
const edit_data = ref(baseItem)
let new_product = reactive({
code: '',
new_code: '',
name: '',
brand_info: {id: 0,name: ''},
brand_name: '',
brand: 0,
price: 0.00,
sell_price: 0.00,
amount: 1,
note: '',
add_time: '',
})
const edit_row = ref(0)
const centerDialogVisible = ref(false)
const editRow = (row,column,evt) => {
if(order_status.value > 0) {
return
}
let idx = goodsList.value.findIndex((item) => item.id == row.id && item.code == row.code)
if(idx <= -1) {
return
}
edit_row.value = idx
new_product = reactive({
code: row.code,
new_code: row.new_code,
name: row.name,
brand_info: {id: row.brand,name: row.b_name},
brand_name: row.b_name,
brand: row.brand,
price: row.price,
sell_price: row.sell_price,
amount: row.amount,
note: row.note,
add_time: row.add_time,
})
centerDialogVisible.value = true
}
2025-07-14 17:06:03 +08:00
const reloadRow = async (idx,evt) => {
let item = goodsList.value[idx]
goodsList.value[idx] = await reloadData(item)
}
2025-07-05 21:43:01 +08:00
const editProduct = async () => {
if(!new_product.code || !new_product.brand_info.id) {
return
}
const {data:product} = await hasProduct(new_product.brand_info.id,new_product.code)
if(product.data.bid) {
const {bid:id,code,short_code,cn_name,en_name,brand,b_name,price,dealer_price,order_price: sell_price,weight,volume,add_time} = product.data
let product_data = {
id,
name: cn_name ? cn_name : en_name,
code,
short_code,
new_code: new_product.new_code,
b_name,
brand,
price,
sell_price,
weight,
volume,
type: 'product',
amount: parseInt(new_product.amount) ? parseInt(new_product.amount) : 1,
note: new_product.note,
seller: '预订产品',
seller_id: 0,
add_time,
}
if(new_product.price > 0 && new_product.price != product_data.price) {
product_data.price = new_product.price
}
if(new_product.sell_price > 0 && new_product.sell_price != product_data.sell_price) {
product_data.sell_price = new_product.sell_price
}
Object.assign(goodsList.value[edit_row.value],product_data)
} else {
const {code,name,brand_info,price,sell_price,amount,note} = new_product
let add_data = {
id: 0,
name,
code,
short_code: code.trim().replace('-','').replace(' ','0'),
new_code: new_product.new_code,
brand: brand_info.id,
b_name: brand_info.name,
price,
sell_price,
weight: 0.000,
volume: 0.000,
type:'other',
amount: parseInt(amount) ? parseInt(amount) : 1,
note,
seller: '待定',
seller_id: 0
}
Object.assign(goodsList.value[edit_row.value],add_data)
}
centerDialogVisible.value = false
}
const submit_product = async () => {
if(brandInfo.value.id && edit_data.value.brand != brandInfo.value.id) {
edit_data.value.brand = brandInfo.value.id
edit_data.value.b_name = brandInfo.value.name
}
edit_data.value.goods = []
if(!edit_data.value.id) {
edit_data.value.type = 'other'
edit_data.value.seller = '待定'
edit_data.value.seller_id = 0
edit_data.value.code = product_code.value
edit_data.value.short_code = product_code.value.trim().replace('-','').replace(' ','0')
const {data:goods} = await onlyGoodsByCode(edit_data.value.code,edit_data.value.brand)
if(goods.data && goods.data.length) {
edit_data.value.goods = goods.data
}
} else {
const {data:goods} = await partsGoodsById(edit_data.value.id)
if(goods.data && goods.data.length) {
edit_data.value.goods = goods.data
}
}
pushRow(edit_data.value)
clearInput()
}
const handleProductSelect = async (item) => {
if(item.id > 0) {
const {data:data} = await productInfo(item.id)
if(data.data && data.data.bid) {
const {bid:id,code,short_code,cn_name,en_name,brand,b_name,price,dealer_price,order_price: sell_price,weight,volume,add_time} = data.data
let product_data = {
id,
name: cn_name ? cn_name : en_name,
code,
short_code,
b_name,
brand,
price,
sell_price,
weight,
volume,
type: 'product',
amount: 1,
note: '',
seller: '预订产品',
seller_id: 0,
add_time
}
edit_data.value = product_data
product_code.value = code
brandInfo.value = {id: brand,name: b_name}
}
}
}
const pushRow = (row) => {
if(row.type != 'other') {
let index = goodsList.value.findIndex(item => item.id == row.id && item.type == row.type)
if(index != -1) {
goodsList.value[index]['amount'] += row['amount']
} else {
goodsList.value.push(row)
}
} else {
let index = goodsList.value.findIndex(item => item.code == row.code && item.brand == row.brand && item.type == 'other')
if(index != -1) {
goodsList.value[index]['amount'] += row['amount']
} else {
goodsList.value.push(row)
}
}
}
2025-07-14 17:06:03 +08:00
const reloadData = async (item) => {
const { data:product } = await hasProduct(item.brand,item.code)
if(product.data.bid) {
const {bid:id,code,short_code,cn_name,en_name,brand,b_name,price,dealer_price,order_price:sell_price,weight,volume,add_time,goods} = product.data
let product_data = {
id,
name: cn_name ? cn_name : en_name,
code,
short_code,
new_code: item.new_code,
b_name,
brand,
price,
sell_price,
weight,
volume,
type: 'product',
amount: parseInt(item.amount) ? parseInt(item.amount) : 1,
note: item.note,
seller: '预订产品',
seller_id: 0,
add_time,
goods,
}
if(item.price > 0 && item.price != product_data.price) {
product_data.price = item.price
}
if(item.sell_price > 0 && item.sell_price != product_data.sell_price) {
product_data.sell_price = item.sell_price
}
return product_data
}
return item
}
const refresh = async () => {
let goods_data = []
2025-07-19 03:18:35 +08:00
loading.value = true
2025-07-14 17:06:03 +08:00
for(let item of goodsList.value) {
goods_data.push(await reloadData(item))
}
let data_arr = goods_data.map(item => ({brand: item.brand,code: item.code}))
const { data:res } = await hasFocusBatch(data_arr)
for(let item of res.data) {
let idx = goods_data.findIndex(it => it.brand == item.brand && it.code == item.code)
goods_data[idx].focus = item.has_focus
}
let goods_hash = md5(JSON.stringify(goods_data))
if(goodsHash.value != goods_hash) {
goodsList.value = goods_data
}
2025-07-19 03:18:35 +08:00
loading.value = false
2025-07-14 17:06:03 +08:00
}
2025-07-05 21:43:01 +08:00
const clearInput = () => {
nextTick(() => {
edit_data.value = Object.assign({},baseItem)
brandInfo.value = {}
product_code.value = ''
})
}
const moveUp = (index,row) => {
goodsList.value.splice(index-1,0,row)
goodsList.value.splice(index+1,1)
}
const moveDown = (index,row) => {
goodsList.value.splice(index,1)
goodsList.value.splice(index+1,0,row)
}
2025-07-14 17:06:03 +08:00
const saveGoods = async () => {
await addInquiryGoods(order_id.value,goodsList.value)
await addLog(props.orderId,`${user_store.userName}(${user_store.userId})`,'修改商品',JSON.stringify(goodsList.value))
goodsHash.value = md5(JSON.stringify(goodsList.value))
2025-07-05 21:43:01 +08:00
ElMessage({
message: "成功修改订单商品!",
type: 'success',
})
2025-07-19 03:18:35 +08:00
emit('status-change',order_id.value,'save-goods')
2025-07-05 21:43:01 +08:00
}
const fileInput = async () => {
const [hFile] = await window.showOpenFilePicker({
types: [{
description: '数据表',
accept: {
'application/vnd.ms-excel': ['.xlsx', '.xls', /*...*/ ]
}
}],
excludeAcceptAllOption: true,
multiple: false
});
const ab = await (await hFile.getFile()).arrayBuffer();
const wb = XLSX.read(ab);
const sheet = wb.SheetNames[0]
let input_data = XLSX.utils.sheet_to_json(wb.Sheets[sheet], {header: "A",raw: false})
input_data = input_data.filter(item => item.A && item.A.trim())
for(let i in input_data) {
let item = input_data[i]
if(item.A) {
let amount = item.C ? isNaN(parseInt(item.C)) ? 1 : parseInt(item.C) : 1
let note = item.D ? item.D : ''
let product_data = {
id: 0,
name: '',
code: item.A,
short_code: item.A.trim().replace('-','').replace(' ','0'),
b_name: '',
brand: 0,
price: 0.00,
sell_price: 0.00,
weight: 0.000,
volume: 0.000,
type: 'other',
amount,
note,
seller: '待定',
seller_id: 0,
}
const {data:data} = await hasBrandProduct(item.B,item.A)
if(data.data && data.data.bid) {
const {bid:id,code,short_code,cn_name,en_name,brand,b_name,price,dealer_price,order_price: sell_price,weight,volume,add_time} = data.data
product_data = {
id,
name: cn_name ? cn_name : en_name,
code: code ? code : item.A,
short_code,
b_name,
brand,
price,
sell_price,
weight,
volume,
type: 'product',
amount,
note,
seller: '预订产品',
seller_id: 0,
add_time,
}
}
product_data.goods = []
if(product_data.id) {
let { data:goods } = await partsGoodsById(product_data.id)
product_data.goods = goods.data
} else {
let { data:goods } = await onlyGoodsByCode(product_data.code,product_data.brand)
product_data.goods = goods.data
}
pushRow(product_data)
}
}
}
const focusDialogVisible = ref(false)
const focusInfo = ref({})
const handleFocusItem = async () => {
let { code,new_code,brand,price,note,index,name } = focusInfo.value
let focus_data = {
code,
brand,
price,
new_code,
name
}
let { data:res } = await updateFocus(focus_data)
if(res.data && res.data.id) {
2025-07-14 17:06:03 +08:00
await addFocusLog(res.data.id,`${user_store.userName}(${user_store.userId})`,`从订单(${order_id.value})新增,${note}`)
2025-07-05 21:43:01 +08:00
goodsList.value[index].focus = true
}
focusDialogVisible.value = false
}
const setFocusItem = async (row,index) => {
focusInfo.value.index = index
focusInfo.value.code = row.code
focusInfo.value.name = row.name
focusInfo.value.price = row.price
focusInfo.value.brand = row.brand
focusInfo.value.b_name = row.b_name
focusInfo.value.note = ''
focusInfo.value.new_code = null
focusDialogVisible.value = true
}
</script>
<style lang='scss' scoped>
.info-item {
padding-left: 20px;
font-size: 14px;
.title {
font-weight: bold;
}
.info {
color: #d80010;
}
}
.box-card-edit {
max-height: 35vh;
overflow-y: auto;
.focus-line {
margin-top: 10px;
display: grid;
grid-template-columns: 1fr 3fr;
gap: 30px;
.focus-title {
font-weight: bold;
text-align: right;
}
}
.focus-line:last-child {
padding-bottom: 20px;
}
}
</style>