freight-web/src/pagesReceive/form/pricingForm.vue

891 lines
21 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="c-card app-container">
<u-form
labelPosition="left"
:model="model1"
:rules="rules"
ref="form"
:labelWidth="80"
:labelStyle="{ padding: '0rpx 10rpx' }"
:errorType="'border-bottom'"
>
<u-form-item
:prop="`order.${item.key}`"
:label="item.name"
:required="item.required"
v-for="(item, index) in prePage ? formAttrList1 : formAttrList"
:key="index"
@click="item.fn"
:borderBottom="false"
>
<u-textarea
v-if="item.type === 'textarea'"
v-model="(model1.order as any)[item.key]"
:placeholder="`请输入${item.name}`"
></u-textarea>
<!-- v-model="(model1.order as any)[item.key]" -->
<u-input
v-model="(model1.order as any)[item.key]"
v-if="item.type === 'select' || item.type === 'input'"
:placeholder="`请${item.type === 'select' ? '选择' : '输入'}${
item.name
}`"
clearable
:customStyle="{}"
border="none"
:value="(model1.order as any)[item.key]"
@change="(e:any) => {handleInput(e, item)}"
:disabled="item.disabled || item.type === 'select'"
:disabledColor="['收货产品','车牌号'].indexOf(item.name) > -1 ? '#ffffff' : '#f5f7fa'"
@clear="handleClear(item)"
@blur="(e:any) => {handleBlur(e, item)}"
>
<template #suffix>
<text v-if="item.key === 'subtractNum'">
{{ model1.order.buttonType === 0 ? item.unit : "%" }}
</text>
<text v-else>
{{ item.unit }}
</text>
</template>
</u-input>
<!-- @afterRead="afterRead"
@delete="deletePic" -->
<uni-file-picker
v-if="item.type === 'upload'"
:limit="9"
title="最多可上传9张图片"
:auto-upload="false"
fileMediatype="image"
ref="filesRef"
v-model="model1.order.fileLists"
@delete="handleDelete"
></uni-file-picker>
<!-- 当定价后编辑入库单 不能更改称重方式 -->
<u-radio-group
v-if="item.type === 'radio'"
v-model="(model1.order as any)[item.key]"
placement="row"
:disabled="
model1.order.scaleStatus === 1 && item.key === 'weighingMethod'
"
>
<u-radio
v-for="(c, index) in item.child"
:key="index"
activeColor="#00DCEE"
:label="c.name"
:name="c.id"
:customStyle="{ marginRight: '10px' }"
></u-radio>
</u-radio-group>
<template #right v-if="item.type === 'select'">
<u-icon name="arrow-right"></u-icon>
</template>
</u-form-item>
<u-form-item :label="'现场照片'" v-if="model1.order.id">
<Photo
:params="{
businessId: model1.order.id,
orderType: OrderType.Receive,
imagesType: ImagesType.Tare,
}"
/>
</u-form-item>
</u-form>
<block
v-for="(item, index) in prePage ? formAttrList1 : formAttrList"
:key="index"
>
<u-action-sheet
v-if="item.type === 'select'"
:actions="contrlModalParams[item.childKey].list"
:title="contrlModalParams[item.childKey].title"
:show="contrlModalParams[item.childKey].isShow"
@select="(v: any) => handleSelect(item.childKey, v)"
@close="contrlModalParams[item.childKey].isShow = false"
:closeOnClickAction="true"
:safeAreaInsetBottom="true"
></u-action-sheet>
</block>
</view>
<view class="btn-box">
<u-button text="暂不定价" @click="handleBack()"></u-button>
<u-button
type="primary"
:text="title === '定价详情' ? '定价' : '保存'"
@click="save()"
></u-button>
</view>
<!-- 收货产品弹框 -->
<ProductDialog
:show="showDialog.showProduct"
@handleDialog="(v:boolean) => {handleDialog('showProduct', v)}"
@changeProduct="changeProduct"
ref="productRef"
:isShipment="false"
></ProductDialog>
<!-- 车牌号 -->
<CarNoDialog
:show="showDialog.showCarNo"
@handleDialog="(v:boolean) => {handleDialog('showCarNo', v)}"
@changeCarNo="changeCarNo"
ref="carNoRef"
></CarNoDialog>
</template>
<script setup lang="ts">
import type { ComType } from "@/types/global";
import { ReceiveApi, PictureApi, SupplierApi } from "@/services/index";
import _ from "underscore";
import { onLoad, onShow } from "@dcloudio/uni-app";
import { ImagesType, OrderType } from "@/utils/enum";
import ProductDialog from "@/components/Dialog/ProductDialog.vue";
import valid from "@/utils/validate";
import { countDots, isTwoDecimalPlaces, num_subtract, num_multiply } from "@/utils";
import Photo from "@/components/Photo/index.vue";
import CarNoDialog from "@/components/Dialog/CarNoDialog.vue";
const changeCarNo = (plate: string) => {
if (plate.length >= 7) model1.order.carNumber = plate;
showDialog.showCarNo = false;
};
const handleClear = (item: any) => {
(model1.order as any)[item.key] = "";
};
// 供应商选择
const showDialog = <
{
[key: string]: boolean;
}
>reactive({
showProduct: false,
showCarNo: false,
});
const handleDialog = (key: string, v: boolean) => {
showDialog[key] = v;
};
// 收货产品选择
const changeProduct = (obj: any) => {
model1.order.productName = obj.reProductsName; // 收货产品名称
model1.order.productId = obj.id; // 收货产品Id,
model1.order.price = obj.commonPrice; // 设置常用价格
model1.order.minPrice = obj.minPrice; // 保存最大最小值
model1.order.maxPrice = obj.maxPrice;
};
// 单价 毛重 杂质扣除校验
const handleInput = (e: any, item: any) => {
if (item.key === "price" || item.key === "grossWeight") {
const temp = e?.replace(valid.valid_decimal.pattern, "");
if (countDots(temp).length > 1) {
uni.showToast({
title: "请输入正确的" + item.name,
icon: "none",
});
}
setTimeout(() => {
model1.order[item.key] = temp;
}, 10);
}
if (item.key === "subtractNum") {
const temp = e?.replace(valid.valid_decimal.pattern, "");
if (
model1.order.buttonType === 1 &&
(parseInt(temp) > 100 || parseInt(temp) < 0)
) {
uni.showToast({
title: `${item.name}正确范围是0-100`,
icon: "none",
});
}
setTimeout(() => {
model1.order[item.key] = temp;
}, 10);
}
};
const handleBlur = (e: any, item: any) => {
if (item.blur) {
item.blur();
}
if (item.key === "subtractNum") {
if (
countDots(model1.order.subtractNum) === 1 &&
isTwoDecimalPlaces(model1.order.subtractNum)
) {
uni.showToast({
title: "杂质扣除最多只能输入2位小数",
icon: "none",
});
return;
}
}
};
const model1 = reactive<{ order: Order }>({
order: {
id: 0,
userName: "", // 供应商名称
userId: "", // 供应商Id,
carNumber: "",
productId: "", // 产品Id,
productName: "", // 产品名称
price: 0, // 单价
buttonType: 0, // 0扣杂1扣点
weighingMethod: 0, // 0有皮重 1零皮重
multiCategory: 0, // 0单品类 1多品类
fileLists: [],
scaleStatus: 1,
netWeight: 0,
balanceTotalPrice: 0,
},
});
const rules = reactive({
"order.userName": {
type: "string",
required: true,
message: "请输入供应商",
trigger: ["blur", "change"],
},
"order.productName": {
type: "string",
required: true,
message: "请选择收货产品名称",
trigger: ["blur", "change"],
},
"order.price": [
{
type: "number",
required: true,
message: "单价为空或单价输入错误",
trigger: ["blur", "change"],
},
],
"order.grossWeight": {
type: "number",
required: true,
message: "请输入毛重",
trigger: ["blur", "change"],
},
"order.weighingMethod": {
type: "number",
required: true,
message: "请选择称重方式",
trigger: ["blur", "change"],
},
"order.multiCategory": {
type: "number",
required: true,
message: "请选择品类",
trigger: ["blur", "change"],
},
});
const contrlModalParams = reactive<ComType>({
isShowSplTime: false,
spltime: Number(new Date()),
userSelect: {
isShow: false,
title: "标题",
list: [],
},
productSelect: {
isShow: false,
title: "标题",
list: [],
},
});
const formAttrList = reactive<ComType>([
{
name: "供应商",
key: "userName",
type: "input",
unit: "",
required: true,
fn: () => {},
blur: () => {
updateSupplierUserName();
},
},
{
name: "车牌号",
key: "carNumber",
type: "input",
unit: "",
disabled: true,
fn: () => {
showDialog.showCarNo = true;
},
},
{
name: "收货产品",
key: "productName",
type: "select",
unit: "",
childKey: "productSelect",
required: true,
fn: () => {
handleDialog("showProduct", true);
uni.hideKeyboard();
// contrlModalParams.productSelect.isShow = true;
// contrlModalParams.productSelect.title = "收货产品";
},
},
{
name: "单价",
key: "price",
type: "input",
unit: "元/KG",
required: true,
},
{
name: "毛重",
key: "grossWeight",
type: "input",
unit: "KG",
required: true,
disabled: true,
},
{
name: "扣杂",
key: "buttonType",
type: "radio",
child: [
{
id: 0,
name: "按固定重量",
},
{
id: 1,
name: "按百分比",
},
],
},
{
name: "杂质扣除",
key: "subtractNum",
type: "input",
unit: "KG",
},
{
name: "称重方式",
key: "weighingMethod",
type: "radio",
required: true,
child: [
{
id: 0,
name: "有皮重",
},
{
id: 1,
name: "零皮重",
},
],
},
{
name: "多品类",
key: "multiCategory",
type: "radio",
required: true,
child: [
{
id: 0,
name: "单品类",
},
{
id: 1,
name: "多品类",
},
],
},
{
name: "备注",
key: "notes",
type: "textarea",
},
{
name: "货品照片",
key: "photo",
type: "upload",
},
]);
const formAttrList1 = reactive<ComType>([
{
name: "供应商",
key: "userName",
type: "input",
unit: "",
required: true,
blur: () => {
updateSupplierUserName();
},
},
{
name: "车牌号",
key: "carNumber",
type: "input",
unit: "",
},
{
name: "收货产品",
key: "productName",
type: "select",
unit: "",
childKey: "productSelect",
required: true,
fn: () => {
handleDialog("showProduct", true);
uni.hideKeyboard();
// contrlModalParams.productSelect.isShow = true;
// contrlModalParams.productSelect.title = "收货产品";
},
},
{
name: "毛重",
key: "grossWeight",
type: "input",
unit: "KG",
required: true,
disabled: true,
},
{
name: "皮重",
key: "tare",
type: "input",
unit: "KG",
required: true,
disabled: true,
},
{
name: "扣杂",
key: "buttonType",
type: "radio",
child: [
{
id: 0,
name: "按固定重量",
},
{
id: 1,
name: "按百分比",
},
],
},
{
name: "杂质扣除",
key: "subtractNum",
type: "input",
unit: "KG",
},
{
name: "净重",
key: "netWeight",
type: "input",
unit: "KG",
required: true,
disabled: true,
},
{
name: "单价",
key: "price",
type: "input",
unit: "元/KG",
required: true,
},
{
name: "预估总价",
key: "totalPrice",
type: "input",
unit: "元",
disabled: true,
},
{
name: "实际付款",
key: "balanceTotalPrice",
type: "input",
required: true,
unit: "元",
},
{
name: "备注",
key: "notes",
type: "textarea",
},
{
name: "货品照片",
key: "photo",
type: "upload",
},
]);
// 监听毛重 皮重
watch(
[
() => model1.order.grossWeight,
() => model1.order.tare,
() => model1.order.price,
() => model1.order.subtractNum,
() => model1.order.buttonType,
],
([grossWeightNew, tareNew]) => {
/**
* 过磅净重: 毛重-皮重
结算重量: 过磅净重-扣杂
预估总价: 结算单价*结算重量
实际收入:实际结算金额-运费-杂费
*/
if (model1.order.scaleStatus === 0) {
return;
}
model1.order.netWeight = <any>num_subtract((parseFloat(grossWeightNew as any) || 0), (parseFloat(tareNew as any) || 0)).toFixed(2)
if (model1.order.buttonType === 0) {
if (model1.order.subtractNum) {
model1.order.netWeight = <any>num_subtract(<any>model1.order.netWeight, model1.order.subtractNum).toFixed(2)
}
} else if (model1.order.buttonType === 1) {
if (model1.order.subtractNum) {
model1.order.netWeight = <any>num_multiply(<any>model1.order.netWeight,((100 - model1.order.subtractNum) / 100)).toFixed(2)
}
}
// 实际付款默认=预估总价,当系统自动算出预估总价时,值需同步
if (<number>model1.order.balanceTotalPrice <= 0) {
model1.order.balanceTotalPrice = model1.order.totalPrice;
}
}
);
const handleSelect = (key: string, v: any) => {
contrlModalParams[key].isShow = false;
if (key === "userSelect") {
model1.order.userName = v.name;
model1.order.userId = v.id;
} else if (key === "productSelect") {
model1.order.productName = v.name;
model1.order.productId = v.id;
}
};
const handleBack = () => {
uni.navigateBack();
};
// const files = ref<FileObj[]>([]);
const filesRef = ref();
const handleUpload = () => {
return filesRef.value[0].filesList.map((item: any, index: number) => {
if (item.fileID) {
return;
}
return new Promise((resolve) => {
PictureApi.upload({
files: item,
path: item.path,
})
.then((res) => {
if (res.code === 200) {
resolve({
...(res.data as any),
businessId: model1.order.id,
imagesType: ImagesType.NORMARL, // 普通资源
orderType: OrderType.Receive, // 入库单
});
}
})
.catch((e) => {
return;
});
});
});
};
/**
*
*/
const handleDelete = (e: any) => {
if (e.tempFile.fileID) {
PictureApi.deleteById({ id: e.tempFile.fileID }).then((res) => {
if (res.code === 200) {
uni.showToast({ title: "已删除" });
}
});
}
};
const updateSupplierUserName = () => {
const { userId, userName } = model1.order;
SupplierApi.updateSupplierUserName({ id: userId, name: userName }).then(
(res) => {
if (res.code === 200) {
uni.showToast({ title: "供应商名称已更新" });
}
}
);
};
/**
* 点击保存 先执行upload接口
* 上传成功后 保存图片资源 和更新订单数据
*/
const form = ref();
const check = () => {
return new Promise((resolve) => {
form.value
.validate()
.then((res: boolean) => {
resolve(res);
})
.catch((errors: any) => {
resolve(false);
uni.showToast({
icon: "none",
title: errors[0].message || "校验失败",
});
});
});
};
const save = () => {
if (model1.order.carNumber) {
if (!valid.carNo.pattern.test(model1.order.carNumber)) {
uni.showToast({ icon: "none", title: "请输入正确的车牌号" });
return;
}
}
if (
model1.order.price &&
model1.order.price.toString()[model1.order.price.toString().length - 1] ===
"."
) {
uni.showToast({
title: "请输入正确的单价",
icon: "none",
});
return;
}
if (
model1.order.grossWeight?.toString() &&
model1.order.grossWeight?.toString()[
model1.order.grossWeight?.toString().length - 1
] === "."
) {
uni.showToast({
title: "请输入正确的毛重",
icon: "none",
});
return;
}
if (
countDots(model1.order.price + "") === 1 &&
isTwoDecimalPlaces(model1.order.price)
) {
uni.showToast({
title: "单价最多只能输入2位小数",
icon: "none",
});
return;
}
if (
countDots(model1.order.balanceTotalPrice + "") === 1 &&
isTwoDecimalPlaces(model1.order.balanceTotalPrice)
) {
uni.showToast({
title: "实际付款最多只能输入2位小数",
icon: "none",
});
return;
}
if (
countDots(model1.order.subtractNum) === 1 &&
isTwoDecimalPlaces(model1.order.subtractNum)
) {
uni.showToast({
title: "杂质扣除最多只能输入2位小数",
icon: "none",
});
return;
}
check().then((res) => {
if (res) {
// 保存前先更新供应商名称
startSave();
}
});
};
const startSave = () => {
Promise.all(handleUpload()).then((res) => {
if (res.filter((item) => item).length > 0) {
PictureApi.addListAnnex({ annexPos: res.filter((item) => item) }).then(
(res1) => {
if (res1.code === 200) {
console.log("*** 资源文件更新成功");
}
}
);
}
});
updateOrder();
};
const updateOrder = () => {
// 更新定价单
/**
* 0有皮重 1零皮重
* 有皮重 scaleState = 1 带过皮
零皮重 scaleState = 2 带审核
*/
// 若是补单数据 则不做此判断
// 到待审核状态不用关心补单的逻辑
if (<number>model1.order.scaleStatus < 2) {
if (!model1.order.repairFlag) {
if (model1.order.weighingMethod === 0) {
model1.order.scaleStatus = 1;
} else if (model1.order.weighingMethod === 1) {
model1.order.scaleStatus = 2;
}
}
}
//
/**
* buttonType
* 0扣杂1扣点
* buttonType===0 buckleMiscellaneous
* buttonType===1 points
*
*/
if (model1.order.buttonType === 0) {
model1.order.buckleMiscellaneous = model1.order.subtractNum;
} else if (model1.order.buttonType === 1) {
model1.order.points = model1.order.subtractNum;
}
ReceiveApi.updateOne({ ...model1.order }).then((res) => {
if (res.code === 200) {
// 定价后 若是零皮-》跳转到【付款审核】 有皮重->【待过皮重】
// 当上一页为审核页
if (prePage.value === "review") {
uni.redirectTo({
url:
"/pagesReceive/review/index?id=" +
model1.order.id +
`&scaleStatus=` +
model1.order.scaleStatus, // 要跳转到的页面路径
});
} else {
// 0有皮重 1零皮重
uni.navigateBack();
}
}
});
};
const prePage = ref("");
const title = ref("");
onLoad((option: any) => {
model1.order.id = parseInt(option.id);
prePage.value = option.prePage;
title.value = option.title;
if (prePage.value) {
uni.setNavigationBarTitle({
title: "编辑信息",
});
}
if (option.title) {
uni.setNavigationBarTitle({
title: option.title,
});
}
if (model1.order.id) {
ReceiveApi.getDetailById({ id: model1.order.id }).then((res) => {
if (res.code === 200) {
// 基于id查询重新赋值
model1.order = {
...res.data,
buttonType: res.data.buttonType !== null ? res.data.buttonType : 0,
weighingMethod:
res.data.weighingMethod !== null ? res.data.weighingMethod : 0,
multiCategory:
res.data.multiCategory !== null ? res.data.multiCategory : 0,
subtractNum:
res.data.buttonType === 0
? res.data.buckleMiscellaneous
: res.data.points,
balanceTotalPrice: res.data.balanceTotalPrice
? res.data.balanceTotalPrice
: res.data.totalPrice,
fileLists: model1.order.fileLists.map((item: any) => {
return { ...item, fileID: item.id };
}),
};
}
});
PictureApi.getAnnex({
businessId: model1.order.id.toString(),
orderType: OrderType.Receive,
imagesType: ImagesType.NORMARL,
}).then((res) => {
if (res.code === 200) {
model1.order.fileLists = res.data;
}
});
}
uni.$on("pricingParams", (data) => {
model1.order.userName = data.name;
});
});
onShow(() => {});
onUnmounted(() => {
uni.$off("pricingParams", () => {});
});
</script>
<style lang="scss" scoped>
.c-card {
background: #ffffff;
// box-shadow: 0rpx 0rpx 10rpx 0rpx rgba(5, 68, 37, 0.12);
border-radius: 13rpx;
margin: 30rpx 25rpx;
padding: 0rpx 20rpx;
::v-deep .u-form-item {
height: auto;
}
::v-deep .u-form-item + .u-form-item {
border-top: 1rpx solid rgba(233, 233, 233, 0.76);
}
}
.btn-box {
margin-top: 60rpx;
display: flex;
background: #ffffff;
box-shadow: 0rpx 0rpx 10rpx 0rpx rgba(0, 56, 93, 0.12);
border-radius: 13rpx 13rpx 0rpx 0rpx;
padding: 25rpx 50rpx;
position: fixed;
width: calc(100vw - 100rpx);
bottom: 0rpx;
z-index: 999;
::v-deep button {
border-radius: 43rpx;
}
::v-deep button + button {
margin-left: 30rpx;
}
}
</style>