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

1103 lines
45 KiB
Vue

<template>
<el-row v-if="order_id">
<el-col :span="16" style="text-align: left;">
<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>
<el-col :span="8">
<el-button type="warning" v-if="editable && goodsList.length" @click="refresh" :icon="Camera" size="large">
扫描验证
</el-button>
<el-button color="#0f6b9c" v-if="editable" :disabled="goodsList.length==0 || !goods_change" @click="saveGoods" :icon="ShoppingCartFull" size="large">
保存商品
</el-button>
<span class="ml-20">
<slot name="nogo"></slot>
</span>
</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">
<el-button color="#b23b2f" @click="create" :icon="EditPen" size="large" :disabled="!userInfo.id">创建订单</el-button>
</div>
</el-form-item>
</el-form>
</el-col>
<el-col :span="8">
<span class="ml-30"><slot name="nogo"></slot></span>
</el-col>
</el-row>
<hr style="margin: 20px 0;" v-if="order_id">
<div v-if="order_id">
<el-button v-if="editable" type="primary" :icon="DocumentCopy" @click="fileInput">批量导入产品</el-button>
<div class="flex w-full justify-center items-center">
<el-table
ref="goodsTableRef"
v-loading="loading"
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-key="id"
border
@row-click="handleRowEdit"
>
<el-table-column fixed label="#" type="index" width="50" align="center" header-align="center">
<template #default="{ $index }">
<div class="allowDrag cursor-move" v-if="editable">
<span>{{ $index + 1 }}</span>
</div>
</template>
</el-table-column>
<el-table-column prop="b_name" label="品牌" header-align="center" align="left" width="120">
<template #default="{row,$index}">
<el-text size="small">{{ row.b_name }}</el-text>
</template>
</el-table-column>
<el-table-column prop="code" label="件号" width="120" show-overflow-tooltip header-align="center">
<template #default="{row,$index}">
<el-text size="small" tag="b">{{ row.code }}</el-text>
</template>
</el-table-column>
<el-table-column prop="new_code" label="更新件号" header-align="center" width="110" show-overflow-tooltip>
<template #default="{row,$index}">
<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).toFixed(2) }}</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).toFixed(2) }}</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">
<template #default="scope">
<el-text size="small" tag="b">{{ scope.row.amount }}</el-text>
</template>
</el-table-column>
<el-table-column prop="note" label="备注" header-align="center" width="140" show-overflow-tooltip>
<template #default="scope">
<el-text size="small">{{ scope.row.note }}</el-text>
</template>
</el-table-column>
<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">
<template #default="{row: $row}">
{{ dayjs($row.up_time).format('YY-MM-DD') }}
</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">
<template #default="{row: $row}">
<el-text :type="$row.no_tax == '0' ? 'info' : 'danger'" tag="b">{{ $row.sell_price }}</el-text>
</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>
<el-table-column label="" header-align="center" align="center" width="260">
<template #default="scope">
<el-button
size="small"
type="danger"
:icon="Delete"
@click.stop="()=>goodsList.splice(scope.$index,1)"
/>
<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)"
/>
<el-button
size="small"
type="info"
:disabled="!`${scope.row.id}`.startsWith('0-')"
@click.stop="() => {}"
>
<el-icon><Camera /></el-icon>
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="flex w-full justify-center items-center mt-2px">
<el-table
v-if="editable"
fit
:data="edit_data"
class="text-xs w-auto"
:header-cell-style="{background: '#e0f2fe', color: 'black',borderColor: 'black'}"
:cell-style="{borderColor: 'black'}"
style="border: 1px solid black;"
size="small"
:show-header="false"
border
>
<el-table-column fixed label="#" type="index" width="50" align="center" header-align="center">
<template #default="{row}">
<span></span>
</template>
</el-table-column>
<el-table-column prop="b_name" label="品牌" header-align="center" align="left" width="120">
<template #default="{row}">
<BrandPicker v-model="row.brand_info" class="inline-input w-full" size="small" :width="100" />
</template>
</el-table-column>
<el-table-column prop="code" label="件号" width="120" header-align="center">
<template #default="{row}">
<ProductPicker v-model="row.code" class="inline-input w-full" size="small" :width="100" @selected="handleProductSelect" />
</template>
</el-table-column>
<el-table-column prop="new_code" label="更新件号" header-align="center" width="110">
<template #default="{row}">
<el-input v-model="row.new_code" class="inline-input w-full" size="small" />
</template>
</el-table-column>
<el-table-column label="名称" width="140" header-align="center">
<template #default="{row}">
<el-input v-model="row.name" class="inline-input w-full" size="small" />
</template>
</el-table-column>
<el-table-column prop="price" label="面价" header-align="center" align="right" width="110">
<template #default="{row}">
<el-input v-model="row.price" class="inline-input w-full" size="small" />
</template>
</el-table-column>
<el-table-column prop="add_time" label="价格版本" header-align="center" align="center" width="110">
<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="{row}">
<el-input v-model="row.sell_price" class="inline-input w-full" size="small" />
</template>
</el-table-column>
<el-table-column prop="weight" label="重量" header-align="center" align="right" width="80">
<template #default="{row}">
<el-input v-model="row.weight" class="inline-input w-full" size="small" />
</template>
</el-table-column>
<el-table-column prop="volume" label="体积" header-align="center" align="right" width="80">
<template #default="{row}">
<el-input v-model="row.volumn" class="inline-input w-full" size="small" />
</template>
</el-table-column>
<el-table-column prop="amount" label="数量" width="60" header-align="center" align="center">
<template #default="{row}">
<el-input type="number" v-model="row.amount" class="inline-input w-full" size="small" />
</template>
</el-table-column>
<el-table-column prop="note" label="备注" header-align="center" width="140">
<template #default="{row}">
<el-input v-model="row.note" class="inline-input w-full" size="small" />
</template>
</el-table-column>
<el-table-column label="商品来源" prop="seller" width="100" header-align="center" align="center"/>
<el-table-column label="" header-align="center" align="center" width="260">
<template #default="{row}">
<el-button
size="small"
type="primary"
:icon="Plus"
@click.stop="submit_product"
/>
<el-button
size="small"
type="danger"
:icon="Delete"
@click.stop="clearInput"
/>
</template>
</el-table-column>
</el-table>
</div>
</div>
<el-dialog
v-model="centerDialogVisible"
title="更新预订商品信息"
width="32%"
destroy-on-close
center
>
<el-card class="box-card-edit">
<el-form :inline="true">
<el-form-item label="产品编码">
<el-input v-model.trim="new_product.code" placeholder="产品编码" />
</el-form-item>
<el-form-item label="更新件号">
<el-input v-model.trim="new_product.new_code" placeholder="更新件号" />
</el-form-item>
<el-form-item label="商品名称">
<el-input v-model.trim="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.trim="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,onBeforeUnmount,watch } from 'vue'
import { EditPen,MessageBox,Plus,Delete,ArrowUpBold,ArrowDownBold,DocumentCopy,UploadFilled,ShoppingCartFull,Refresh,Camera } from '@element-plus/icons-vue'
import FocusIn from '@/components/icons/FocusIn.vue'
import dayjs from 'dayjs'
import {md5} from '@/utils'
import * as XLSX from 'xlsx'
import { memberInfo,searchMember,addLog } from '@/api'
import { onlyGoodsByCode,partsGoodsById,productInfo,hasProduct,hasFocus,hasFocusBatch,hasBrandProduct,addFocusLog,updateFocus } from '@/api/product'
import { createInquiry,inquiryInfo,inquiryGoodsList,update,addInquiryGoods,hasSupplyInquiry } from '@/api/inquiry'
import { ElMessage,ElMessageBox } from 'element-plus'
import BrandPicker from '@/components/BrandPicker.vue'
import ProductPicker from '@/components/ProductPicker.vue'
import { useUserStore } from '@/store'
import Sortable from "sortablejs";
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('')
const loading = ref(false)
const emit = defineEmits(['status-change','add-goods','next-step','finish'])
const props = defineProps({
'orderId': {
type:Number,
default: 0
},
'orderStatus': {
type:Number,
default: 0
},
})
const has_supply_inquiry = ref(false)
const load = async() => {
const { data:order } = await inquiryInfo(order_id.value)
if(order.data.id && +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) {
res.data.forEach(item => {
if(!item.id) {
item.id = `${item.brand}-${item.code}`
}
})
let data_arr = res.data.map(item => ({brand: item.brand,code: item.code}))
const { data:r } = await hasFocusBatch(data_arr)
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
}
}
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
}
setSort()
}
onMounted(async() => {
order_id.value = +props.orderId
order_status.value = +props.orderStatus
if(order_id.value != 0) {
await load()
}
setSort()
})
const goods_change = computed(() => {
return md5(JSON.stringify(goodsList.value.slice(0,-1))) !== goodsHash.value
})
const editable = computed(() => {
return order_status.value == 0 && !has_supply_inquiry.value
})
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 = ''
}
}
const create = async () => {
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
const { data:order } = await inquiryInfo(order_id.value)
if(order.data.id && +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
goodsList.value = []
setSort()
goodsHash.value = md5(JSON.stringify([]))
const { data:member } = await memberInfo(+order.data.user_id)
if(member.data.id) {
userInfo.value = member.data
}
await addLog(order_id.value,`${user_store.userName}(${user_store.userId})`,action,`客户:${userInfo.value.username}(${userInfo.value.id})`)
ElMessage({
message: '订单创建成功!',
type: 'success',
})
emit('status-change',order_id.value,'create-inquiry')
}
} 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',
})
emit('status-change',order_id.value,'customer-change')
}
}
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',
})
emit('status-change',order_id.value,'note-change')
}
}
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',
})
emit('status-change',order_id.value,'subject-change')
}
}
const baseItem = {
id: 0,
brand_info: {id: 0,name: ''},
code: '',
short_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: '',
}
let new_product = reactive({
id: 0,
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_data = ref([Object.assign({},baseItem)])
const edit_row = ref(0)
const centerDialogVisible = ref(false)
const handleRowEdit = (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 < 0) {
return
}
edit_row.value = idx
new_product = reactive({
id: row.id,
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
}
const editProduct = async () => {
if(!new_product.code || !new_product.brand_info.id) {
return
}
let product_data = {}
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
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) ? +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
}
} else {
const {code,name,brand_info,price,sell_price,amount,note} = new_product
product_data = {
id: `${brand_info.id}-${code.trim()}`,
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,
volumn: 0.000,
type:'other',
amount: parseInt(amount) ? +amount : 1,
note,
seller: '待定',
seller_id: 0
}
}
if(goodsList.value[edit_row.value].id == product_data.id) {
Object.assign(goodsList.value[edit_row.value],product_data)
} else {
let idx = goodsList.value.findIndex(item => item.id == product_data.id)
if(idx < 0) {
Object.assign(goodsList.value[edit_row.value],product_data)
} else {
ElMessageBox.confirm('当前商品已存在,是否合并?', '商品已存在',{
confirmButtonText: '合并',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
goodsList.value[idx]['amount'] += +product_data.amount
goodsList.value.splice(edit_row.value,1)
ElMessage({
message: '商品合并成功!',
type: 'success',
})
})
.catch(() => {
ElMessage({
message: '商品合并已取消',
type: 'info',
})
})
}
}
setSort()
centerDialogVisible.value = false
}
const submit_product = async () => {
let row = edit_data.value[0]
if(row.brand_info?.id && row.brand != row.brand_info?.id) {
row.brand = row.brand_info.id
row.b_name = row.brand_info.name
}
row.goods = []
if(!row.id) {
row.code = row.code.trim()
row.id = `${row.brand}-${row.code.trim()}`
row.type = 'other'
row.seller = '待定'
row.seller_id = 0
row.short_code = row.code.replace('-','').replace(' ','0')
const { data:goods } = await onlyGoodsByCode(row.code,row.brand)
if(goods.data && goods.data.length) {
row.goods = goods.data
}
} else {
const { data:goods } = await partsGoodsById(row.id)
if(goods.data && goods.data.length) {
row.goods = goods.data
}
}
pushRow(row)
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 = {
brand_info: {
id: brand,
name: b_name
},
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[0] = Object.assign({},product_data)
}
}
}
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)
}
}
setSort()
}
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) ? +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 reloadRow = async (idx) => {
let item = goodsList.value[idx]
Object.assign(goodsList.value[idx],await reloadData(item))
setSort()
}
const refresh = async () => {
let goods_data = []
loading.value = true
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 = res.data.findIndex(it => it.brand == item.brand && it.code == item.code)
res.data[idx].focus = item.has_focus
}
goodsList.value.forEach((item,idx) => {
Object.assign(item,goods_data[idx])
})
setSort()
loading.value = false
}
const clearInput = () => edit_data.value = [Object.assign({}, baseItem)]
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))
ElMessage({
message: "成功修改订单商品!",
type: 'success',
})
emit('status-change',order_id.value,'save-goods')
}
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-${item.A}`,
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) {
await addFocusLog(res.data.id,`${user_store.userName}(${user_store.userId})`,`从订单(${order_id.value})新增,${note}`)
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
}
// 拖拽排序相关测试
const goodsTableRef = ref(null);
let sortableInstance = null;
function setSort() {
nextTick(() => {
const tbody = goodsTableRef.value?.$el.querySelector(".el-table__body-wrapper tbody");
if (!tbody) {
console.warn("tbody 不存在,拖拽初始化失败");
return;
}
// 销毁旧实例
if (sortableInstance) {
sortableInstance.destroy();
}
// 创建新的拖拽实例
sortableInstance = Sortable.create(tbody, {
handle: ".allowDrag", // 指定拖拽区域
animation: 150,
onEnd: (evt) => {
const movedItem = goodsList.value.splice(evt.oldIndex, 1)[0];
goodsList.value.splice(evt.newIndex, 0, movedItem);
},
});
});
}
// function handleSort() {
// if (sortableInstance) {
// sortableInstance.sort(goodsList.value.map(f => f.id));
// }
// }
</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>