<!-- 打印箱码/装箱 -->
<template>
    <div class="table-box">
        <ListBtns :selectionList="datas.selectionList" @handleParentCallback="handleParentCallback" :ruleForm="datas.ruleForm" />
        <ProTable
            ref="proTable"
            :formData="datas.formData"
            :columns="datas.columns"
            :request-api="getListApi"
            :init-param="datas.initParam"
            @selectionChange="selectionChange"
            :orgCode="datas.ruleForm.orgCode"
        >
            <template #boxBillNo="scope">
                <a @click="handleOpen(scope.row)" class="break-word to-details">
                    {{ scope.row.boxBillNo }}
                </a>
            </template>
        </ProTable>
        <!-- 生成装箱 -->

        <el-dialog
            v-model="datas.generateVisible"
            title="生成箱码"
            width="620px"
            :close-on-press-escape="false"
            :close-on-click-modal="false"
            :distinguish-cancel-and-close="true"
            :z-index="20"
            destroy-on-close
            :before-close="
                () => {
                    datas.generateVisible = false;
                }
            "
            @close="handleCloseGenerateCode"
        >
            <el-form
                ref="ruleFormRef"
                style="width: 300px"
                :model="datas.numberRuleForm"
                :rules="datas.numberRules"
                class="demo-ruleForm"
            >
                <el-form-item label="数量: " prop="number">
                    <el-input v-model="datas.numberRuleForm.number" style="width: 224px" @input="valueVerify" :maxlength="3" />
                    <!-- <el-input-number v-model="datas.numberRuleForm.number" :min="1" :max="999" :controls="false" step-strictly /> -->
                    <el-tooltip effect="dark" content="最大箱码生成数量为999" placement="top">
                        <el-icon style="cursor: pointer"><QuestionFilled /></el-icon>
                    </el-tooltip>
                </el-form-item>
            </el-form>
            <template #footer>
                <div class="dialog-footer">
                    <el-button type="primary" @click="submitForm(ruleFormRef)"> 确认 </el-button>
                    <el-button @click="resetForm(ruleFormRef)">取消</el-button>
                </div>
            </template>
        </el-dialog>
        <!-- 开始装箱 -->
        <div class="start-box">
            <el-dialog
                v-model="datas.startVisible"
                title="装箱"
                width="966px"
                :close-on-press-escape="false"
                :close-on-click-modal="false"
                :distinguish-cancel-and-close="true"
                destroy-on-close
                :z-index="20"
                @close="handleCloseGenerateCode1"
                :before-close="handleBeforeClose"
            >
                <div style="display: flex">
                    <div style="width: 780px">
                        <div style="display: flex; justify-content: space-between; margin-top: 16px; margin-bottom: 16px">
                            <div>
                                <span>箱号: </span>
                                <el-input
                                    v-model="datas.boxBillNo"
                                    style="width: 240px"
                                    placeholder="请输入箱号(支持扫描枪和手动输入)"
                                    ref="refInput"
                                    @keyup.enter="handleGetInputValue"
                                    :disabled="datas.boxBillNoDisabled"
                                />
                                <el-tooltip
                                    effect="dark"
                                    content="请将输入法切换到英文(中文输入法会与扫描枪产生冲突) !"
                                    placement="top"
                                >
                                    <el-icon style="cursor: pointer"><QuestionFilled /></el-icon>
                                </el-tooltip>
                            </div>
                            <div
                                style="
                                    display: flex;
                                    flex-direction: column;
                                    align-items: center;
                                    justify-content: center;
                                    width: 194px;
                                    height: 80px;
                                    font-size: 18px;
                                    font-weight: bold;
                                    color: red;
                                    background-color: rgb(247 136 5 / 20%);

                                    /* border: 1px solid #000000; */
                                    border-radius: 4px;
                                "
                            >
                                <div style="font-size: 32px; color: #f78805">
                                    {{ number }}
                                </div>
                                <div style="font-size: 14px; color: #f78805">已装数</div>
                            </div>
                        </div>

                        <FormTable
                            :columns="datas.formTableColumns"
                            :tableData="datas.formTableData"
                            @handleKeyupEnterInputValue="handleKeyupEnterInputValue"
                            ref="formTableRef"
                            :isRowStyle="true"
                            :isStatus="datas.isStatus"
                            :rowStyle="rowStyle"
                        >
                            <template #operation="scope">
                                <el-button type="primary" size="small" @click="handleDelete(scope)">删除</el-button>
                            </template>
                        </FormTable>
                    </div>

                    <div style="padding-top: 16px; margin-left: 16px; border-left: 1px solid #eeeeee">
                        <div @click="handleSave('commit')" class="btn" v-if="isShowBtns.isWC">完成装箱</div>
                        <div @click="handleEmpty" class="btn" v-if="isShowBtns.isQKZX">清空装箱信息</div>
                        <div @click="handleSave('save')" class="btn" v-if="isShowBtns.isBC">保存</div>
                    </div>
                </div>
            </el-dialog>
        </div>
    </div>
</template>

<script setup lang="ts" name="boxCode">
import ListBtns from "@/components/ListBtns/index.vue";
import ProTable from "@/components/ProTable/index.vue";
import FormTable from "@/components/FormTable/index.vue";
import { useAuthStore } from "@/stores/modules/auth";
import $Bus from "@/utils/mittBus";
import { QuestionFilled } from "@element-plus/icons-vue";
import { ref, reactive } from "vue";
import type { FormInstance } from "element-plus";
import { FORM_TABLE_DATA_INIT } from "./constant/list";
//接口
import { getListApi, getBoxGenerateApi, getSaveBoxApi, getSerialNumberApi, getBeginCartonApi } from "@/api/modules/boxCode";
//getSerialNumber
import { msgHtml, initSave, initDelete, getBoxInfo, initOpen, getClearBox, btnsEvent } from "./init/index";
//表格TS
import { ProTableInstance } from "@/components/ProTable/interface";
import { integerRexg } from "@/utils/regexp/index";
//深拷贝方法
import { cloneDeep } from "lodash-es";
//用户信息
import { useUserStore } from "@/stores/modules/user";
// 获取用户信息(组织id)
const userStore: any = useUserStore();
// 列表页面搜索条件和表格配置项
import {
    RULE_FORM,
    FORM_DATA,
    COLUMNS,
    NUM_RULE_FORM,
    NUM_RULES,
    FORM_TABLE_DATA,
    FORM_TABLE_COLUMNS
} from "./constant/list/index";

// 获取 ProTable 元素，调用其获取刷新数据方法（还能获取到当前查询参数，方便导出携带参数）CTN00000102
const proTable = ref<ProTableInstance>();
const ruleFormRef = ref<FormInstance>();
const refInput = ref<any>();
const formTableRef = ref<any>();
const septNumber = ref<any>(false);
const authStore = useAuthStore();
const SHOW_BTBS: any = authStore.btnsAuthList;

const isShowBtns = reactive<any>({
    isWC: false,
    isQKZX: false,
    isBC: false
});
if (SHOW_BTBS["boxCode"] && SHOW_BTBS["boxCode"].length) {
    isShowBtns.isWC = SHOW_BTBS["boxCode"].includes("boxCodeWC") || false;
    isShowBtns.isQKZX = SHOW_BTBS["boxCode"].includes("boxCodeQKZX") || false;
    isShowBtns.isBC = SHOW_BTBS["boxCode"].includes("boxCodeBC") || false;
}

// 数据源
const datas = reactive<any>({
    generateVisible: false, //生成箱码显示隐藏
    startVisible: false, //装箱显示隐藏
    columns: COLUMNS, //列表配置项
    initParam: cloneDeep(RULE_FORM), // 初始化搜索条件|重置搜索条件
    ruleForm: cloneDeep(RULE_FORM), // 搜索条件
    formData: FORM_DATA, //搜索配置项
    numberRuleForm: cloneDeep(NUM_RULE_FORM), //生成箱码
    boxBillNo: "", //装箱箱号值
    boxBillNoObj: {}, //装箱箱号信息(后端返回)
    boxBillNoDisabled: false, //裝箱箱号禁止条件
    numberRules: NUM_RULES, //生成箱码rules值
    selectionList: [], //表格选择后的数据
    formTableColumns: cloneDeep(FORM_TABLE_COLUMNS), //装箱列表配置项
    formTableData: cloneDeep(FORM_TABLE_DATA), //装箱列表数据
    isStatus: false, //已完成时为true否则未false
    isBtnClick: false //記錄用戶點擊按鈕，通過這個狀態去刷新列表頁面
});

datas.ruleForm.createUser = userStore.userInfo.nickname;
datas.initParam.createUser = userStore.userInfo.nickname;
// 定义一个用于存储定时器ID的变量
// let timerId: any = "";
//input输入验证
const valueVerify = () => {
    datas.numberRuleForm.number = integerRexg(datas.numberRuleForm.number);
};
//顶部按钮回调
const handleParentCallback = (result?: any) => {
    const { type } = result;
    btnsEvent(datas, type, refInput, proTable);
};
//条码录入列表表格选择事件
const selectionChange = (selection: any) => {
    datas.selectionList = selection;
};
//生成箱码提交接口
const getBoxGenerate = async () => {
    septNumber.value = false;
    const result = await getBoxGenerateApi(datas.numberRuleForm);
    if (result.status === 200 && result.isSuccess) {
        msgHtml("箱码生成成功 !");
        setTimeout(() => {
            datas.generateVisible = false;
            // datas.ruleForm.createUser = userStore.userInfo.nickname;
            // datas.initParam.createUser = userStore.userInfo.nickname;
            proTable.value!.getTableList();
        }, 500);
    }
};
//生成箱码提交
const submitForm = async (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    await formEl.validate((valid, fields) => {
        if (valid) {
            getBoxGenerate();
        } else {
            console.log("error submit!", fields);
        }
    });
};
//生成箱码取消
const resetForm = (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    formEl.resetFields();
    datas.generateVisible = false;
};
//打开装箱弹窗
const handleOpen = async (row: any) => {
    datas.isStatus = row.status == "已完成" ? true : false;
    datas.boxBillNo = row.boxBillNo;
    datas.startVisible = true;
    septNumber.value = false;
    datas.boxBillNoDisabled = true; //裝箱箱号禁止条件
    datas.formTableData = [];
    await initOpen(datas, row, formTableRef);
};
//关闭生成装箱弹窗需要做的事情
const handleCloseGenerateCode = () => {
    septNumber.value = false;
    datas.numberRuleForm.number = null;
};
//开始装箱弹窗关闭前的操作
const handleBeforeClose = async () => {
    septNumber.value = false;
    if (!datas.isStatus && datas.boxBillNo) {
        let is = datas.formTableData.some((item: any) => {
            return item.materialNumber && !item.isOldData;
        });

        if (is) {
            let paramsArray = datas.formTableData.filter((item: any) => {
                if (item.materialNumber) {
                    return item;
                }
            });
            let newParamsArray: any[] = [];
            let length = paramsArray.length;
            for (let i = 0; i < length; i++) {
                let item = paramsArray[i];
                if (!item.isOldData) {
                    let obj = {
                        materialNumber: item.materialNumber,
                        serialNumber: item.isNumber ? item.numberCode : item.serialNumber,
                        twoSerialNumber: item?.twoSerialNumber ? item?.twoSerialNumber : "",
                        specifications: item.specifications
                        // twoNumberCode: item?.twoNumberCode ? item?.twoNumberCode : ""
                    };
                    newParamsArray.push(obj);
                }
            }
            const result = await getSaveBoxApi({
                boxId: datas.boxBillNoObj.id,
                isCarton: false,
                details: newParamsArray
            });
            if (result.status === 200) {
                proTable.value!.reset();
            }
        }
    }
    // clearInterval(timerId);
    datas.startVisible = false;
};
//关闭开始装箱弹窗需要做的事情
const handleCloseGenerateCode1 = () => {
    septNumber.value = false;
    datas.boxBillNo = "";
    datas.boxBillNoDisabled = false;
    //当用户进行了操作才去刷新页面
    if (datas.isBtnClick) {
        proTable.value!.reset();
        //proTable.value!.getTableList();
    }
    datas.formTableData = cloneDeep(FORM_TABLE_DATA);
    datas.isBtnClick = false;
    datas.isStatus = false;
    datas.boxBillNoObj = {};
};
//箱号输入监听事件
const handleGetInputValue = () => {
    getBoxInfo(datas, formTableRef);
};
const getBeginCarton = async (boxId: any) => {
    const result = await getBeginCartonApi({ boxId });
    if (result.status === 200) {
    }
};
const isNumeric = (str: any) => {
    return /^\d+$/.test(str);
};
//获取用户输入或扫描枪输入的值
const handleKeyupEnterInputValue = async (params: any) => {
    const { item, index } = params;
    const { orgCode } = userStore;
    //获取用户输入的序列号(数字序列号)
    let serialNumber = datas.formTableData[index][item.prop];
    if (!serialNumber) {
        msgHtml("序列号不能为空,请输入序列号 !");
        return;
    }
    //用户会可以输入数字数列号,通过接口将用户输入的数字序列号转换成序列号然后再做对比
    const result = await getSerialNumberApi({ serialNumber, orgCode });
    let data: any = {};
    if (result.status === 200) {
        data = result.data;
    }
    //data為空的話重置對於的數據
    if (!data || JSON.stringify(data) === "{}") {
        datas.formTableData[index]["serialNumber"] = "";
        formTableRef.value.inputElement[0].focus();
        msgHtml(result.message);
        return;
    }
    //序列碼是否裝箱
    if (data?.isCarton) {
        datas.formTableData[index]["serialNumber"] = "";
        formTableRef.value.inputElement[0].focus();
        msgHtml("此序列号已装箱, 不能再次装箱 !");
        return;
    }
    //序列碼是否已存在，如果存在則提示
    let length = datas.formTableData.length;
    for (let i = 0; i < length; i++) {
        //判断当前序列号是否已经扫描过
        // (i !== index && datas.formTableData[i].serialNumber === data.serialNumber) ||
        //     datas.formTableData[i].twoSerialNumber === data.serialNumber ||
        //     datas.formTableData[i].suitNumber === data.suitNumber)

        //判断当前序列号是否已经扫描过
        if (i !== index && datas.formTableData[i].suitNumber === data.suitNumber) {
            datas.formTableData[index]["serialNumber"] = "";
            formTableRef.value.inputElement[index].focus();
            msgHtml("此序列号已扫描,无需再次扫描 !");
            return;
        }
    }

    //判断是不是数字序列号,如果是数字序列号的话就传数字序列号
    data.isNumber = isNumeric(serialNumber);
    //当前行复制
    datas.formTableData[index] = data;
    datas.formTableData[index].disabled = true;
    //当第一次添加行的时候需要调用这个接口通知后端修改装箱时间
    if (datas.formTableData.length === 1) {
        getBeginCarton(datas.boxBillNoObj.id);
    }
    //0位置添加一个空白行
    datas.formTableData.unshift(cloneDeep(FORM_TABLE_DATA_INIT));
    nextTick(() => {
        formTableRef.value.inputElement[0].focus();
    });
    septNumber.value = true;
};
//删除
const handleDelete = (scope: any) => {
    septNumber.value = false;
    if (datas.isStatus) {
        msgHtml("该箱已完成装箱,禁止删除操作 !");
        return;
    }
    if (datas.formTableData.length === 1) {
        msgHtml("请保留至少一条数据 !");
        return;
    }
    if (scope.$index === 0) {
        msgHtml("该数据不允许删除,否则将无法添加数据 !");
        return;
    }
    initDelete(datas, scope);
};
//保存|完成装箱
const handleSave = async (type: any) => {
    septNumber.value = false;
    if (datas.isStatus) {
        msgHtml("该箱已完成装箱,禁止操作 !");

        return;
    }
    //septNumber.value
    await initSave(datas, type, formTableRef, refInput);
    datas.isBtnClick = true;
};
//已装箱数量
const number = computed(() => {
    let list = datas.formTableData.filter((item: any) => {
        return item.materialNumber;
    });
    return list.length;
});
//清空装箱
const handleEmpty = async () => {
    septNumber.value = false;
    if (datas.isStatus) {
        msgHtml("该箱已完成装箱,禁止清空操作 !");
        return;
    }

    const is = await getClearBox(datas, formTableRef);
    datas.isBtnClick = is;
};

//装箱弹窗的对比
const rowStyle = ({ row, rowIndex }: any) => {
    if (datas.formTableData.length && row.materialNumber) {
        //根据装箱状态去拿数据对比.已完成状态下和第一行做对比否则选择第二行做对比
        let length = datas.formTableData.length;
        //获取最后一条数据用于和数组前面的数据做对比
        let materialNumber = datas.formTableData[length - 1].materialNumber;
        console.log(rowIndex);
        if (materialNumber && length > 0 && row.materialNumber != materialNumber) {
            return "color: red;";
        } else {
            return "";
        }
    } else {
        return "";
    }
};
//监听开始装箱弹窗是否已经打开,打开了15秒一次调用保存接口
// watch(
//     () => septNumber.value,
//     newVal => {
//         if (newVal) {
//             timerId = setInterval(() => {
//                 handleSave("hideSave");
//             }, 1500000000);
//         } else {
//             clearInterval(timerId);
//         }
//     }
// );
//监听orgCode
watch(
    () => userStore.orgCode,
    newVal => {
        datas.ruleForm.orgCode = newVal;
        datas.initParam.orgCode = newVal;
        datas.numberRuleForm.orgCode = newVal;
    },
    {
        immediate: true,
        deep: true
    }
);
onMounted(() => {
    $Bus.on("clearBoxCodeCreateUser", () => {
        datas.ruleForm.createUser = "";
        datas.initParam.createUser = "";
    });
    $Bus.on("setBoxCodeInputCreateUser", (params: any) => {
        const { createUser } = params;
        datas.ruleForm.createUser = createUser;
        datas.initParam.createUser = createUser;
    });
});
// 别忘了在组件销毁时清除定时器，避免内存泄漏
// onBeforeUnmount(() => {
//     clearInterval(timerId);
// });
</script>

<style scope lang="scss">
@import "./index.scss";
.message_style {
    font-size: 16px;
}
</style>
<style lang="scss"></style>
