<template>
	<lay-container style="height:700px;overflow: hidden;">
		<view class="empty-small2">
			<lay-button size="sm" type="normal" @click="editChildData()">新增子项
			</lay-button>
			<lay-table class="table-box240" :columns="dataColumn" id="FID" :dataSource="dataList" height="250px">
				<template v-slot:operator="{ data }">
					<div>
						<lay-button size="xs" type="normal" @click="editChildData(data)">编辑</lay-button>
						<lay-button size="xs" type="danger" @click="_deleteChildData(data)">删除</lay-button>
					</div>
				</template>
			</lay-table>
		</view>
		<lay-form :model="editDataInfo" class="edit-info layui-item50 color999">
			<lay-form-item label-width="140" label="系列" prop="FFactoryCode">
				<lay-input v-model="editDataInfo.FFactoryCode"></lay-input>
			</lay-form-item>
			<lay-form-item label-width="140" label="包规代码" prop="FCode" required >
				<lay-input v-model="editDataInfo.FCode"></lay-input>
			</lay-form-item>
			<lay-form-item label-width="140" label="标准BOM数量(KG)" prop="FBomUnit">
				<lay-input v-model="editDataInfo.FBomUnit"></lay-input>
			</lay-form-item>
			<lay-form-item label-width="140" label="包装规格" prop="FSpecs">
				<lay-input v-model="editDataInfo.FSpecs"></lay-input>
			</lay-form-item>
			<lay-form-item label-width="140" label="净重(KG)" prop="FNetWeight">
				<lay-input v-model="editDataInfo.FNetWeight" @change="culGrossWeight()"></lay-input>
			</lay-form-item>
			<lay-form-item label-width="140" label="毛重(KG)" prop="FGrossWeight" :initValidate="false">
				<lay-input v-model="editDataInfo.FGrossWeight" disabled="true"></lay-input>
			</lay-form-item>
			<lay-form-item label-width="140" label="外形尺寸(MM)" prop="FSize" :initValidate="false">
				<lay-input v-model="editDataInfo.FSize" disabled="true"></lay-input>
			</lay-form-item>
			<lay-form-item label-width="140" label="体积(m³)" prop="FVolume" :initValidate="false">
				<lay-input v-model="editDataInfo.FVolume" disabled="true"></lay-input>
			</lay-form-item>
			<lay-form-item label-width="140" label="备注" prop="FCode">
				<lay-input v-model="editDataInfo.FRemark"></lay-input>
			</lay-form-item>
		</lay-form>
		<view class="menuBtn">
			<lay-button type="danger" @click="submitClick(1)">提交</lay-button>
			<lay-button type="primary" @click="submitClick(0)">保存</lay-button>
			<lay-button @click="this.$emit('cancelClick')">取消</lay-button>
		</view>
		<div class="float-clear"></div>
		<lay-layer area="800px" v-model="showEditBox" :title="'新增子项'">
			<PackageItem :dataInfoObj="itemInfoObj" @submitClick="editChildSubmit" @cancelClick="cancelClick"></PackageItem>
		</lay-layer>
	</lay-container>
</template>
<style scoped>
	.edit-info {
		margin: 0 28px;
		display: block;
		display: block;
		clear: both;
		float: none;
		overflow: auto;
		height: 290px;
	}

	.float-clear {
		overflow: hidden;
		display: block;
		clear: both;
		float: none;
		height: 0;
	}

	.menuBtn {
		display: block;
		text-align: center;
		width: 96%;
		margin: 10px auto;
	}

	.empty-small2 {
		max-width: 96%;
		margin: 20px auto;
		display: block;
	}

	.empty-small2>.layui-btn {
		margin-bottom: 16px;
	}

	.note {
		color: #999;
		font-size: 12px;
		margin: 12px auto 2px;
		text-align: right;
	}
</style>
<script>
	import {
		ref,
		reactive
	} from 'vue';
	import {
		getPackageChildList,
	} from "/src/api/api/package";
	import {
		updatePackageData
	} from "/src/api/api/package";

	import PackageItem from "./PackageItem.vue";

	export default {
		components: {
			PackageItem
		},
		props: {
			dataInfoObj: {
				type: Object,
				default: () => {},
			}
		},
		mounted() {
			this.editDataInfo = JSON.parse(JSON.stringify(this.dataInfoObj));
			if (this.dataInfoObj.FID) {
				this._getChildList();
			}
		},
		setup () {
			let dataColumn = [{
					type: "number",
					width: "40px"
				}, {
					title: "子项代码",
					key: "FCode",
					width: "170px"
				}, {
					title: "名称",
					key: "FName",
				},
				{
					title: "包材外形尺寸(长*宽*高)(mm)",
					key: "FOutSize"
				},
				{
					title: "包材重量(kg)",
					key: "FWeight",
					width: "130px"
				},
				{
					title: "数量",
					key: "FCount",
					width: "100px"
				},
				{
					title: "单位",
					key: "FUnit",
					width: "100px"
				},
				{
					title: "操作",
					key: "operator",
					width: "140px",
					customSlot: 'operator'
				}
			];
			dataColumn.forEach((item) => {
				item.align = "center";
			});
			const dataList = ref([]);
			const delList = ref([]);
			const editDataInfo = ref({});
			const children = ref([]);
			const showEditBox = ref(false);
			const itemInfoObj = ref({});
			const isNewItem = ref(false);

			return {
				editDataInfo,
				dataColumn,
				dataList,
				delList,
				children,
				showEditBox,
				itemInfoObj,
				isNewItem
			}
		},
		methods: {
			editChildData(itemData) {
				this.isNewItem = itemData === undefined;
				this.itemInfoObj = itemData || {};
				this.showEditBox = true;
			},
			cancelClick() {
				this.showEditBox = false;
			},
			editChildSubmit(itemInfo) {
				if (this.isNewItem) {
					this.dataList.push(itemInfo);
				} else {
					Object.assign(this.itemInfoObj, itemInfo);
				}

				// 当前子项选择包规对应尺寸
				if (itemInfo.FIsPackageSize == 1) {
					// 其他子项设置为包规不对应尺寸
					this.dataList.forEach(d => {
						d.FIsPackageSize = 0;
					});

					// 判断一下当前子项输入的尺寸是不是一个合规的数学表达式
					if (this.isMathExpression(itemInfo.FOutSize)) {
						// 当前包材的外形尺寸设置为子项的外形尺寸
						this.editDataInfo.FSize = itemInfo.FOutSize;

						// 根据外形尺寸计算体积
						var volume = eval(itemInfo.FOutSize) / 1000000000;
						this.editDataInfo.FVolume = volume.toString();
					}
				}

				// 计算毛重
				this.culGrossWeight();
				this.showEditBox = false;
			},
			_deleteChildData(data) {
				let $this = this;
				layer.confirm("子项新视图也会删除，你确定要删除此子项吗？", {
					title: "提示",
					btn: [{
							text: '确定',
							callback: function(id) {
								layer.close(id);
								$this.dataList.splice($this.dataList.indexOf(data), 1);
								
								// 当子项的FID >= 0时，代表该子项在表中已存在，需要逻辑删除 
								// 把删除的子项添加到删除子项列表中
								if (data.FID >= 0) {
									data.FDeleted = 1
									$this.delList.push(data)
								}

								// 计算毛重
								$this.culGrossWeight();
								$this.showEditBox = false;
							}
						},
						{
							text: '取消',
							callback: function(id) {
								layer.close(id);
							}
						}
					]
				});
			},
			async submitClick(status) {
				let idx = layer.load(2);
				let postData = JSON.parse(JSON.stringify(this.editDataInfo));
				delete postData["FAddDate"];
				delete postData["FEditDate"];
				delete postData["FDeleted"];

				// 拼接页面存在的子项列表和被删除的子项列表
				// 删除的子项列表中只包含库中已存在的子项，此操作在_deleteChildData中处理
				this.children = this.children.concat(this.dataList)
				this.children = this.children.concat(this.delList)

				postData.FChild = JSON.stringify(this.children);
				postData.FStatus = status;
				postData.FOperateType = "1";
				let result = await updatePackageData(postData) || -1;
				if (result > 0) this.$emit('cancelClick', true);
				layer.close(idx);
			},
			async _getChildList() {
				let result = await getPackageChildList({
					FPageIndex: 1,
					FPageSize: 999,
					FPageOrderBy: "FID",
					FPackageID: this.editDataInfo.FID
				});

				this.dataList = result.Data.List || [];
			},
			// 设置毛重
			culGrossWeight() {
				// 计算子项重量
				var grossWeight = 0;
				if (this.dataList.length > 0) {
					this.dataList.forEach(d => {
						var weight = parseFloat(d.FWeight);
						if (!isNaN(weight)) {
							grossWeight = grossWeight + weight;
						}
					});
				}

				// 子项重量 + 净重
				var netWeight = parseFloat(this.editDataInfo.FNetWeight)
				if (!isNaN(netWeight)) {
					grossWeight = grossWeight + netWeight;
				}
				
				this.editDataInfo.FGrossWeight = grossWeight.toString();
			},
			// 校验字符串是否数学表达式（用于根据外形尺寸计算体积）
			isMathExpression(str) {
				const regex = /^[\d\+\-\*\/\(\)\.]+$/; // 定义匹配数学表达式的正则表达式
				if (!regex.test(str)) {
					return false; // 不符合正则表达式，不是数学表达式
				}

				// 判断左右括号的数量是否匹配
				let leftBracketCount = 0;
				let rightBracketCount = 0;
				for (let i = 0; i < str.length; i++) {
					if (str[i] === "(") {
					leftBracketCount++;
					} else if (str[i] === ")") {
					rightBracketCount++;
					}
				}
				if (leftBracketCount !== rightBracketCount) {
					return false; // 左右括号数量不匹配，不是数学表达式
				}

				// 判断运算符的使用是否符合运算优先级
				const operators = "+-*/";
				for (let i = 0; i < str.length; i++) {
					if (operators.includes(str[i])) {
					// 运算符前后必须都是数字或右括号
					if (
						(i === 0 || !/\d|\)/.test(str[i - 1])) ||
						(i === str.length - 1 || !/\d|\(|/.test(str[i + 1]))
					) {
						return false; // 不符合运算优先级，不是数学表达式
					}
					}
				}

				// 字符串符合数学表达式的规则
				return true;
			}
		}
	}
</script>
