Files
hazardousWaste_app/pages/components/MaterialList.vue

315 lines
12 KiB
Vue
Raw Permalink 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="materialList">
<view class="remarkLine">
<text>物料列表</text>
<uv-button type="primary" v-if="isAddMaterial" :plain="true" size="small" text="添加物料"
@tap="toMaterial"></uv-button>
<view v-if="isShowRqCode" class="flex align-center justify-between">
<text class="f-12 mr-16 grey" style="font-size: 12px;" v-if="num > 0">
剩余<text style="color: red;">
{{ num }}
</text>种物料未生成唯一码
</text>
<uv-button type="primary" :plain="true" size="small" text="快速生成唯一码"
@tap="toGenerateUniqueCodeQuickly"></uv-button>
</view>
</view>
<!-- 物料列表-->
<view class="material-list-container">
<uni-forms ref="materialFormRef" :modelValue="formData">
<view v-for="(item, idx) in formData.material" :key="item.id || idx" class="material-box"
@longpress="() => handleItemLongPress(item, index)">
<view class="material-item" v-if="`${item?.isDelete}` === '0'">
<!-- 标题 -->
<view class="title mb-2">
{{ item.materialName }} ({{ item.materialCode }})
</view>
<!-- 副标题简称/型号/规格/类型 -->
<view class="subTitle mb-2">
<text v-if="item.materialShortName">{{ item.materialShortName }} / </text>
<text v-if="item.model">{{ item.model }} / </text>
<text v-if="item.specification">{{ item.specification }} / </text>
<text v-if="item.typeName">{{ item.typeName }}</text>
</view>
<!-- uniqueCode -->
<view class="uniqueCode mb-2">
<text class="f-12 " v-if="item.uniqueCode">唯一码{{ item?.uniqueCode }}</text>
</view>
<!-- 数量 + 单位 -->
<view class="tag-row mb-2">
<text class="tag-error">{{ getTypeParentNames(item.typeParentNames) }}</text>
<view class="quantity-form">
<uni-forms-item :name="`material[${idx}].quantity`" label-width="0">
<uni-easyinput :disabled="!edit || isEdit == '5'"
v-model="formData.material[idx].quantity" type="number" :clearable="false"
placeholder="数量" />
</uni-forms-item>
<text class="unit">{{ item.unitName }}</text>
</view>
</view>
<!-- 库存状态 -->
<view class="flex justify-between mb-2 " v-if="isEdit == 3 && includes(keyType, 'stockIn')">
<p style="font-size: 13px;">
已入库
<text style="color:green">{{ getStockQuantity(item, 'complete') }}</text>
</p>
<p style="font-size: 13px;">
剩余
<text style="color:red">{{ getStockQuantity(item, 'remaining') }}</text>
</p>
</view>
<view class="flex justify-between mb-2 " v-if="isEdit == 3 && includes(keyType, 'stockOut')">
<p style="font-size: 13px;">
已出库
<text style="color:green">{{ getStockQuantity(item, 'complete') }}</text>
</p>
<p style="font-size: 13px;">
剩余
<text style="color:red">{{ getStockQuantity(item, 'remaining') }}</text>
</p>
</view>
<!-- 备注 -->
<view class="remark-row">
<uni-forms-item :name="`material[${idx}].remark`" label="备注:">
<uni-easyinput :disabled="!edit" v-model="formData.material[idx].remark" type="text"
:clearable="false" :inputBorder="false" placeholder="请填写备注信息" />
</uni-forms-item>
</view>
</view>
</view>
<!-- 空数据提示 -->
<view class="empty" v-if="!formData.material?.length">
暂无物料请添加物料
</view>
</uni-forms>
</view>
<!-- 选择物料 -->
<uv-modal ref="modalRef" class="chooseModal" :title="none" :showConfirmButton="false" :showCancelButton="false">
<p class="title">请选择称重来源</p>
<p class="link" v-if="includes(keyType, 'declaration')" @tap="toMaterialSelection('2')">蓝牙电子秤</p>
<p class="link" @tap="toMaterialSelection('0')">无线液位计</p>
<p class="link" @tap="toMaterialSelection('1')">手动输入</p>
</uv-modal>
<!-- 删除弹窗 -->
<view>
<uni-popup ref="alertDialog" type="center">
<uni-popup-dialog type="error" v-if="isDialog" cancelText="取消" confirmText="确认" title="是否需要删除该唯一码?"
@confirm="dialogConfirm" @close="dialogClose"></uni-popup-dialog>
</uni-popup>
</view>
</view>
</template>
<script setup>
import { computed, ref, toRefs } from 'vue';
import { assign, findIndex, includes } from 'lodash';
import { getStockQuantity, objectToQuery } from '../until';
import { getTypeParentNames } from '../warehousing/uniqueCode/until';
const OPERATE_CONFIG = {
// 唯一码创建 /唯一码编辑 /唯一码详情 /入库单开单
issueUniqueCode: {
toMaterialUrl: '/pages/warehousing/uniqueCode/issueUniqueCode/materialSelection',
title: '入库单开单'
},
// 入库单入库
stockIn: {
toMaterialUrl: '/pages/warehousing/uniqueCode/issueUniqueCode/index',
title: '入库单开单'
},
// 申报单开单
declaration: {
toMaterialUrl: '/pages/warehousing/uniqueCode/issueUniqueCode/materialSelection',
title: '申报单开单'
},
my: {
toMaterialUrl: '/pages/warehousing/uniqueCode/issueUniqueCode/index',
title: '申报单开单'
},
}
const props = defineProps({
formData: { type: Object, default: () => ({ material: [], remark: '' }), required: true },//物料信息
isEdit: { type: Boolean, default: true, required: true }, //编辑1 / 物料只读2 / 入/出库单只读3 /入库生成唯一码编辑4 /5数量不可编辑 备注可编辑
pathParams: { type: Object, default: {} }, //只读时传入对应的code、id
extendData: { type: Object, default: {} }, //其他额外参数
})
const emit = defineEmits(["setStorage"]); //申报开单 选择物料存储所填数据
const { formData, isEdit, pathParams, extendData } = toRefs(props)
// 标识:页面
const keyType = computed(() => pathParams.value.type)
// 标识:是否为编辑状态
const edit = computed(() => includes(['1', '4', '5'], `${isEdit.value}`))
// 标识:显示添加物料按钮 编辑1且非开单页面以及非出库相关页面
const isAddMaterial = computed(() => `${isEdit.value}` === '1' && keyType.value != 'stockIn_inbound' && !includes(keyType.value, 'stockOut'))
// 标识:显示快速生成唯一码 编辑5数量不可编辑 备注可编辑且非出库相关页面
const isShowRqCode = computed(() => `${isEdit.value}` === '5' && !includes(keyType.value, 'stockOut'))
// 删除:数据
const delItem = ref(null)
// 删除:开关
const alertDialog = ref(null)
// 删除:开关
const isDialog = ref(false)
// 数据:开单-可选择的物料列表
const selectMaterialList = computed(() => extendData.value?.selectMaterialList)
const num = computed(() => selectMaterialList.value?.length || 0)
// 弹窗:入库单开单
const modalRef = ref()
// 按钮:添加物料
const toMaterial = () => {
if (keyType.value == 'stockIn' || includes(keyType.value, 'declaration')) { // 入库单开单 - 添加物料可选择手输入/无线液位计
modalRef.value.open()
} else {
const path = objectToQuery(pathParams.value)
const value = uni.getStorageSync('app_material');
uni.setStorageSync('app_material', [{ ...value[0], uniqueCodeRemark: formData.value?.remark }]); // 将最新的唯一码备注写入缓存
uni.navigateTo({
url: `${OPERATE_CONFIG.issueUniqueCode.toMaterialUrl}${path}`
})
}
}
// 添加物料弹窗: 入库单入库、申报开单 时可选择手动/无线液
const toMaterialSelection = (type) => {
// 0无线液 1手动输入 2蓝牙
let url = ''
const path = objectToQuery(pathParams.value)
if (type === '1') {
emit("setStorage");
url = `${OPERATE_CONFIG.issueUniqueCode.toMaterialUrl}`
}
uni.navigateTo({
url: `${url}${path}`
})
}
// 快速生成唯一码 -
const toGenerateUniqueCodeQuickly = () => {
const path = objectToQuery(pathParams.value)
uni.navigateTo({
url: `${OPERATE_CONFIG.stockIn.toMaterialUrl}${path}`
})
}
// 删除弹窗:显示 长按事件
const handleItemLongPress = (val) => {
alertDialog.value.open()
isDialog.value = true
delItem.value = val
}
// 删除弹窗:关闭
const dialogClose = () => {
alertDialog.value.close()
isDialog.value = false
}
// 删除弹窗:确认
const dialogConfirm = () => {
const idx = findIndex(formData.value.material, (i) => `${i.id}` === `${delItem.value.id}`)
assign(formData.value.material[idx], { isDelete: '1' });
uni.setStorageSync('app_material', formData.value.material)
}
const getMaterialList = () => {
const material = formData.value?.material || []
const params = material?.map((i) => ({
...i,
material: {
//? 这里的判断是为了区分 =详情带出的物料以及新增的物料 详情带出的物料有id以及materialId 新增物料id为物料id materialId无值
materialId: i.materialId ? i.materialId : i.id,
id: i.materialId ? i.id : null,
remark: i.remark,
quantity: i.quantity,
unitId: i.unitId,
isDelete: i?.isDelete,
uniqueCode: i?.uniqueCode
},
}))
return params
}
defineExpose({
getMaterialList
})
</script>
<style scoped lang="scss">
.remarkLine {
display: flex;
align-items: center;
background-color: #fff;
justify-content: space-between;
padding: 12px 15px;
margin-bottom: 2rpx;
text {
font-weight: 700;
font-size: 13px;
}
.btn-link {
font-weight: 500;
color: #3c9cff;
}
text {
font-size: 14px;
}
p {
font-weight: 700;
font-size: 14px;
}
}
::v-deep .uv-button {
height: 30px;
// line-height: 60rpx;
font-size: 24rpx;
}
.material-item {
padding: 12px 15px;
}
.empty {
text-align: center;
padding: 60rpx 0;
color: #999;
font-size: 26rpx;
}
::v-deep.chooseModal {
.uv-modal__content {
display: block;
padding-top: 24rpx !important;
padding: 48rpx;
.title {
font-size: 16px;
margin: 16rpx 0;
}
.link {
color: #999;
margin-top: 24rpx;
font-size: 14px;
}
}
}
</style>