874 lines
22 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="order-detail-container">
<!-- 基础信息区域 -->
<view class="info-section">
<uni-row class="info-grid">
<uni-col class="flex-row">
<view class="label">货主: </view>
<uni-data-select
v-model="form.companyId"
:localdata="companyOptions"
text-field="text"
value-field="value"
@change="handleCompanyChange"
/>
</uni-col>
</uni-row>
<uni-row class="info-grid">
<uni-col :span="12">
<view v-if="creditperiValue == 0" class="label">剩余金额:现款</view>
<view v-else class="label">剩余金额:{{ remainingMoney }}</view>
</uni-col>
<uni-col :span="12">
<view class="label">订单金额:{{ orderAmount }}</view>
</uni-col>
</uni-row>
<uni-row class="info-grid">
<uni-col :span="24" style="display: flex;">
<view class="label">已选补差:</view>
<view class="">
<view style="color: red;font-size: 14px;" v-if="buchaGoodsList.length && selectedBuChaItems.length==0">
&nbsp;&nbsp;提示:当前有补差数据可选择
</view>
<view v-else class="" v-for="(item,index) in selectedBuChaItems" :key="index">
商品:{{item.goodsname}},金额:{{item.piaokou}}
</view>
</view>
</uni-col>
</uni-row>
<button type="primary"
@click="showBuchaList"
v-show="buchaGoodsList.length > 0 && !isShowingBuchaList"
size="default"
>
选择补差
</button>
<button type="primary" @click="showGoodsList" v-show="isShowingBuchaList">
返回商品列表
</button>
</view>
<!-- 补差列表 -->
<view v-if="isShowingBuchaList">
<view class="goods-section">
<view class="section-title">
<view class="">补差商品信息</view>
<view class="select-all">
<checkbox
:checked="allSelected"
@click="toggleSelectAll"
></checkbox>
</view>
</view>
<view v-if="buchaGoodsList.length === 0" class="no-data">
暂无补差数据
</view>
<view v-else class="goods-double-column">
<checkbox-group @change="checkboxChange">
<view
v-for="(goods, index) in buchaGoodsList"
:key="goods.piaokouid"
class="goods-item"
>
<view class="goods-header">
<text class="serial-number">{{ index + 1 }}</text>
<text class="goods-name">{{ goods.goodsname }}</text>
<checkbox :checked="selectedBuChaItems.some(item => item.piaokouid === goods.piaokouid)"
:value="String(goods.piaokouid)"></checkbox>
</view>
<view class="goods-content">
<uni-row class="info-row">
<uni-col :span="12" class="info-pair">
<view class="label">申请日期:{{ goods.applydate }}</view>
</uni-col>
<uni-col :span="12" class="info-pair">
<view class="label">补差类型:{{ goods.piaokoutype }}</view>
</uni-col>
</uni-row>
<uni-row class="info-row">
<uni-col :span="12" class="info-pair">
<view class="label">商品简称:{{ goods.shortname }}</view>
</uni-col>
<uni-col :span="12" class="info-pair">
<view class="label">可补差金额:{{ goods.piaokou }}</view>
</uni-col>
</uni-row>
</view>
</view>
</checkbox-group>
</view>
</view>
<!-- 补差操作按钮 -->
<view class="action-buttons">
<button @click="goAdd" class="btn btn-secondary">添加补差</button>
<button @click="showGoodsList" class="btn btn-primary">取消</button>
</view>
</view>
<!-- 商品信息区域 -->
<view v-if="!isShowingBuchaList">
<MBLoading v-if="loading"/>
<view v-else>
<view class="goods-section">
<view class="section-title">商品信息</view>
<view v-if="goodsList.length === 0" class="no-data">
暂无商品数据
</view>
<view v-else class="goods-double-column">
<view
v-for="(goods, index) in goodsList"
:key="goods.goodsid"
class="goods-item"
>
<view class="goods-header">
<text class="serial-number">{{ index + 1 }}</text>
<text class="goods-name">{{ goods.goodsname }}</text>
</view>
<view class="goods-content">
<uni-row class="info-row">
<uni-col :span="12" class="info-pair">
<view class="label">件装数:{{ goods.packingnum }}</view>
</uni-col>
<uni-col :span="12" class="info-pair">
<view class="label">供应参考价:{{ goods.invoiceprice }}</view>
</uni-col>
</uni-row>
<uni-row class="info-row">
<uni-col :span="12" class="info-pair">
<view class="label">前三月平均数:{{ goods.threeMonths }}</view>
</uni-col>
<uni-col :span="12" class="info-pair">
<view class="label">使用票扣:{{ goods.piaokou }}</view>
</uni-col>
</uni-row>
<uni-row class="info-row">
<uni-col :span="12" class="info-pair">
<view class="label">小计:{{ goods.allmoney }}</view>
</uni-col>
<uni-col :span="12" class="info-pair">
<view class="label">税率:{{ goods.taxrate }}</view>
</uni-col>
</uni-row>
<uni-row class="info-row">
<uni-col :span="12" class="info-pair flex-row" >
<view class="label">采购数量:</view>
<input
class="uni-input custom-input"
v-model="goods.goodsnum"
placeholder="请输入采购数量"
@blur="e => handleInput(e,index)"/>
</uni-col>
</uni-row>
</view>
</view>
</view>
</view>
<!-- 商品列表操作按钮 -->
<view class="action-buttons ">
<button @click="goSave" class="btn btn-secondary" :loading="btnloading" :disabled="btnloading">保存</button>
<button @click="goSubmit" class="btn btn-primary":loading="btnloading" :disabled="btnloading">确认提交</button>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { onMounted, ref, nextTick } from 'vue'
import { productListWithUserId, addsalemain, getsalemaincheckAmount, listsaleBusGoodsList,
salemainpiAoKouList, salemaincheckQa } from '../../../../api/orderManager/index.js'
import { useUserStore } from '@/store'
import MBLoading from "@/components/MB/MBLoading.vue";
const userStore = useUserStore()
const userID = ref(userStore.id)
const loading = ref(true)
const btnloading = ref(false)
// 状态控制
const isShowingBuchaList = ref(false) // 是否显示补差列表
// 数据
const selectedBuChaItems = ref([]) // 已选补差具体项
const buchaGoodsList = ref([]) // 补差商品列表
const goodsList = ref([]) // 商品列表
const form = ref({ companyId: null })
const remainingMoney = ref(0) // 剩余金额
const orderAmount = ref(0.00) // 订单金额
const creditperiValue = ref() // 信用期
// 补差选择相关
const allSelected = ref(false) // 是否全选
const tempSelectedItems = ref([]) // 临时选中的补差项
// 生产单位选项
const companyOptions = ref([])
const isInitializing = ref(false)
onMounted(async () => {
isInitializing.value = true
try {
await getDeptLists()
if (companyOptions.value.length > 0) {
form.value.companyId = companyOptions.value[0].value
// 在初始化时手动调用
await getEdu()
}
} catch (error) {
console.error('初始化失败:', error)
} finally {
isInitializing.value = false
}
})
// 获取补差列表数据
function getsalemainpiAoKouList() {
const body = { companyId: form.value.companyId }
// buchaGoodsList.value = data1.data
salemainpiAoKouList(body).then(res => {
buchaGoodsList.value = res.data || []
})
}
// 获取商品列表
function GetlistsaleBusGoodsList() {
loading.value = true
const KeSaleGoodsParams = {
companyId: form.value.companyId,
userid: userID.value,
deleteflag: 0,
}
const KeSaleGoodsQuery = { pageNum: 1, pageSize: 999 }
listsaleBusGoodsList(KeSaleGoodsParams, KeSaleGoodsQuery).then(res => {
goodsList.value = res.data || []
loading.value = false
})
}
/** 查询部门列表 */
async function getDeptLists() {
try {
const res = await productListWithUserId()
const sortedData = [...res.data].sort((a, b) => {
const order = [4, 1, 2, 3]
return order.indexOf(a.companyId) - order.indexOf(b.companyId)
})
companyOptions.value = sortedData.map(item => ({
value: item.companyId,
text: item.companyName
}))
if (companyOptions.value.length > 0) {
form.value.companyId = companyOptions.value[0].value
}
return companyOptions.value
} catch (error) {
console.error('获取部门列表失败:', error)
throw error
}
}
function handleCompanyChange() {
// 如果是初始化阶段,不触发
if (isInitializing.value) return
//清除订单金额
orderAmount.value = ''
// 切换生产单位时,先隐藏补差列表
isShowingBuchaList.value = false
// 清空已选补差数据
selectedBuChaItems.value = []
tempSelectedItems.value = []
allSelected.value = false
goodsList.value = []
buchaGoodsList.value = []
// 重新获取额度并加载商品列表
getEdu()
}
/** 更改生产单位时,查询额度 */
function getEdu() {
console.log('生产单位ID:', form.value.companyId)
// 确保显示商品列表
isShowingBuchaList.value = false
// 清空已选补差数据
selectedBuChaItems.value = []
tempSelectedItems.value = []
allSelected.value = false
const AmountqueryParams = {
companyId: form.value.companyId,
saleId: 0,
}
getsalemaincheckAmount(AmountqueryParams).then(res => {
if (res.data) {
creditperiValue.value = res.data.creditperiod
remainingMoney.value = res.data.amounts
} else {
remainingMoney.value = 0
}
GetlistsaleBusGoodsList()
getsalemainpiAoKouList()
getQa()
})
}
// 修改调用质保协议
const getQa = () => {
return new Promise((resolve) => {
const huozhuid = form.value.companyId
const paramsdata= {
companyId:huozhuid,
}
salemaincheckQa(paramsdata).then(res => {
if(res.code === 500 || res.code === 601){
proxy.$modal.msgError(res.msg)
btnloading.value = true; // 禁用保存和提交按钮
resolve(false)
}else if(res.code === 200){
btnloading.value = false; // 启用保存和提交按钮
resolve(true)
}else{
// 其他未知状态,默认禁用
btnloading.value = true; // 禁用保存和提交按钮
resolve(false)
}
}).catch(() => {
btnloading.value = true; // 禁用保存和提交按钮
resolve(false)
});
});
}
/** 显示补差列表 */
function showBuchaList() {
isShowingBuchaList.value = true
// 将已选补差同步到临时选中项
tempSelectedItems.value = [...selectedBuChaItems.value]
updateAllSelectedState()
window.scrollTo({ top: 0, behavior: 'smooth' })
}
/** 显示商品列表 */
function showGoodsList() {
isShowingBuchaList.value = false
window.scrollTo({ top: 0, behavior: 'smooth' })
}
/** 更新全选状态 */
function updateAllSelectedState() {
if (buchaGoodsList.value.length === 0) {
allSelected.value = false
return
}
const allIds = buchaGoodsList.value.map(item => item.piaokouid)
const selectedIds = tempSelectedItems.value.map(item => item.piaokouid)
allSelected.value = allIds.length > 0 &&
allIds.every(id => selectedIds.includes(id))
}
/** 补差选择变化 */
const checkboxChange = (value) => {
console.log('checkboxChange触发value:', value)
const idList = value.detail.value
// 清空临时选中项
tempSelectedItems.value = []
// 根据选中的ID列表重新构建选中项
if (idList.length > 0) {
buchaGoodsList.value.forEach(item => {
if (idList.includes(String(item.piaokouid))) {
tempSelectedItems.value.push({
piaokouid: item.piaokouid,
goodsid: item.goodsid,
goodsname: item.goodsname,
piaokou: item.piaokou,
applydate: item.applydate,
piaokoutype: item.piaokoutype,
shortname: item.shortname
})
}
})
}
// 更新全选状态
updateAllSelectedState()
console.log('当前选中的补差项:', tempSelectedItems.value)
}
/** 全选/全不选 */
const toggleSelectAll = () => {
if (!allSelected.value) {
// 全选
tempSelectedItems.value = [...buchaGoodsList.value]
allSelected.value = true
} else {
// 全不选
tempSelectedItems.value = []
allSelected.value = false
}
}
/** 添加补差 */
const goAdd = () => {
console.log('点击添加补差,当前选中的补差数据:', tempSelectedItems.value)
if (tempSelectedItems.value.length === 0) {
uni.showToast({
title: '请选择补差数据!',
icon: 'none',
duration: 2000
})
return
}
// 调用选择补差函数
ChooseBtn(tempSelectedItems.value)
uni.showToast({
title: '添加成功!',
icon: 'success',
duration: 2000
})
showGoodsList()
}
/** 选择补差按钮逻辑 */
const ChooseBtn = (data) => {
console.log('ChooseBtn被调用传入数据:', data)
// 隐藏补差列表
isShowingBuchaList.value = false
if (!Array.isArray(data)) {
console.error('补差数据不是数组:', data)
data = []
}
// 保存当前选中的具体补差项
selectedBuChaItems.value = [...data]
// 1. 先清空所有商品的补差金额
goodsList.value = goodsList.value.map(item => ({
...item,
piaokou: 0
}))
// 2. 按 goodsid 汇总补差金额
const piaokouMap = data.reduce((acc, item) => {
const goodsid = item.goodsid
acc[goodsid] = (acc[goodsid] || 0) + (Number(item.piaokou) || 0)
return acc
}, {})
console.log('补差金额汇总结果:', piaokouMap)
// 3. 更新对应商品的补差金额
goodsList.value = goodsList.value.map(item => {
if (piaokouMap.hasOwnProperty(item.goodsid)) {
return {
...item,
piaokou: Number(piaokouMap[item.goodsid]) // 保持为数字类型
}
}
return item
})
console.log('更新后的商品列表:', goodsList.value)
}
/** 计算小计 */
const handleInput = (e, index) => {
const value = e.detail ? e.detail.value : e.target.value
const num = Number(value)
if (isNaN(num)) {
goodsList.value[index].goodsnum = 0
goodsList.value[index].allmoney = 0
return
}
// 更新采购数量
goodsList.value[index].goodsnum = num
// 重新计算小计 = 采购数量 × 供应参考价
const invoiceprice = Number(goodsList.value[index].invoiceprice) || 0
goodsList.value[index].allmoney = Math.ceil(num * invoiceprice * 100) / 100
// 计算订单总金额
orderAmount.value = goodsList.value.reduce((sum, item) => {
const num = Number(item.goodsnum) || 0
const price = Number(item.invoiceprice) || 0
return sum + num * price
}, 0)
orderAmount.value = Math.ceil(orderAmount.value * 100) / 100
}
/** 验证票扣金额 - 简化版 */
const validatePiaokou = () => {
// 找出所有商品中票扣大于小计的情况
const invalidItems = goodsList.value.filter(item => {
const piaokou = Number(item.piaokou || 0)
const allmoney = Number(item.allmoney || 0)
// 只需判断票扣是否大于小计
return piaokou > allmoney
})
if (invalidItems.length > 0) {
// 构建错误提示信息
const errorMessage = `以下商品的票扣金额大于小计金额:\n` +
invalidItems.map(item =>
`- ${item.goodsname} (票扣: ${item.piaokou}, 小计: ${item.allmoney})`
).join('\n')
uni.showToast({
title: errorMessage,
icon: 'none',
duration: 3000
})
return false
}
//增加订单金额不能大于剩余金额判断
if(orderAmount.value > remainingMoney.value){
uni.showToast({
title: '订单金额不能大于剩余金额!',
icon: 'none',
duration: 2000
})
return false
}
return true
}
/** 保存 */
const goSave = () => {
const filteredData = goodsList.value.filter(item =>
item.goodsnum !== null &&
item.goodsnum !== '' &&
Number(item.goodsnum) !== 0 &&
!isNaN(Number(item.goodsnum))
)
if (filteredData.length === 0) {
uni.showToast({
title: '请至少选择一个商品并输入采购数量!',
icon: 'none',
duration: 2000
})
return
}
form.value.saledetailList = filteredData.map(item => ({
...item,
price: item.invoiceprice,
xiaoji: item.allmoney
}))
// 添加验证
if (!validatePiaokou()) {
return // 验证不通过,停止执行
}
btnloading.value = true
form.value.state = 0 // 0为保存可修改编辑1的时候为提交
addsalemain(form.value).then(res => {
uni.showToast({
title: '保存成功!',
icon: 'success',
duration: 2000
})
btnloading.value = false
uni.navigateTo({
url: '/pages/work/OrderManager/index'
})
}).catch(err => {
console.error('保存失败:', err)
uni.showToast({
title: '保存失败!',
icon: 'error',
duration: 2000
})
btnloading.value = false
})
}
/** 提交 */
const goSubmit = () => {
const filteredData = goodsList.value.filter(item =>
item.goodsnum !== null &&
item.goodsnum !== '' &&
Number(item.goodsnum) !== 0 &&
!isNaN(Number(item.goodsnum))
)
if (filteredData.length === 0) {
uni.showToast({
title: '请至少选择一个商品并输入采购数量!',
icon: 'none',
duration: 2000
})
return
}
form.value.saledetailList = filteredData.map(item => ({
...item,
price: item.invoiceprice,
xiaoji: item.allmoney
}))
// 添加验证
if (!validatePiaokou()) {
return // 验证不通过,停止执行
}
btnloading.value = true
form.value.state = 1 // 1为提交
addsalemain(form.value).then(res => {
uni.showToast({
title: '提交成功!',
icon: 'success',
duration: 2000
})
btnloading.value = false
uni.navigateTo({
url: '/pages/work/OrderManager/index'
})
}).catch(err => {
console.error('提交失败:', err)
uni.showToast({
title: '提交失败!',
icon: 'error',
duration: 2000
})
btnloading.value = false
})
}
</script>
<style lang="scss" scoped>
.select-all {
margin-left: auto;
}
.custom-input {
border: 1px solid #ccc;
border-radius: 4px;
padding: 5px;
height: 25px;
width: 80px;
}
.order-detail-container {
padding: 16px;
background-color: #f5f5f5;
min-height: 100vh;
}
.flex-row {
display: flex;
align-items: center;
gap: 10px;
}
.info-section {
background: #fff;
border-radius: 12px;
padding: 16px;
margin-bottom: 20px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.info-grid {
margin-bottom: 20rpx;
margin-top: 20rpx;
}
.label {
font-size: 14px;
color: #666;
margin-bottom: 4px;
font-weight: 500;
}
.amount {
color: #f56c6c;
font-weight: 600;
}
/* 商品信息区域 */
.goods-section {
background: #fff;
border-radius: 12px;
padding: 16px;
margin-bottom: 20px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.section-title {
font-size: 16px;
color: #333;
margin: 0 0 16px 0;
padding-bottom: 8px;
border-bottom: 1px solid #eee;
font-weight: 600;
display: flex;
align-items: center;
}
.no-data {
text-align: center;
color: #999;
padding: 40px 0;
font-size: 14px;
}
/* 商品双栏布局 */
.goods-double-column {
display: flex;
flex-direction: column;
gap: 12px;
}
.goods-item {
border: 1px solid #eee;
border-radius: 12px;
overflow: hidden;
background: #fafafa;
}
.goods-header {
background: #409eff;
color: white;
padding: 5px 8px;
display: flex;
align-items: center;
gap: 12px;
}
.serial-number {
display: inline-flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
background: rgba(255, 255, 255, 0.2);
border-radius: 50%;
font-size: 12px;
font-weight: 600;
}
.goods-name {
font-size: 15px;
font-weight: 600;
flex: 1;
}
/* 商品内容区域 */
.goods-content {
padding: 12px 16px;
}
.info-row {
display: flex;
margin-bottom: 8px;
}
.info-pair {
flex: 1;
padding: 0 8px;
}
.info-pair .label {
font-size: 14px;
color: #666;
margin-bottom: 2px;
}
.info-pair .value {
font-size: 14px;
color: #333;
font-weight: 500;
text-align: right;
}
/* 操作按钮 */
.action-buttons {
display: flex;
justify-content: center;
gap: 12px;
padding: 16px;
background: #fff;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
.btn {
padding: 2px 0;
border: none;
// border-radius: 8px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
min-width: 80px;
text-align: center;
flex: 1;
}
.btn-primary {
background: #409eff;
color: white;
font-size: 14px;
}
.btn-secondary {
background: #67c23a;
color: white;
font-size: 14px;
}
/* 响应式设计 */
@media (max-width: 768px) {
.order-detail-container {
padding: 12px;
}
.action-buttons {
flex-direction: column;
}
.btn {
width: 100%;
margin-bottom: 8px;
}
.btn:last-child {
margin-bottom: 0;
}
}
uni-button{
padding: 2px 0;
font-size: 14px;
}
</style>