Mr.Zhang
2023-08-17 f0c673877d2dd1bdeea0e1ddb6a7222c9e012f95
Merge commit 'd044dc871c16f05c9a1fb1489621020c91ec9d59'

* commit 'd044dc871c16f05c9a1fb1489621020c91ec9d59':
h5一键报工
111
# 工资表配置表 导出模板索字段添加
# 工资表配置表 导出模板索字段添加
# 工资表配置表 导出模板索字段添加
# 工资表配置表 导出模板添加字段
修復bug
修復bug
111
修復bug
修復bug
# 工资表配置表 联调修改

# Conflicts:
# web_standard/.env.development
已添加12个文件
已修改47个文件
4431 ■■■■■ 文件已修改
h5_standard/.env.development 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/.env.production 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/apis/ExWarehouse.ts 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/apis/PlanningAPI.ts 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/assets/icon/ic_ar@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/assets/icon/ic_close@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/components/common/Access.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/components/newCom/Material.vue 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/components/newCom/MaterialY.vue 417 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/components/newCom/location.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/components/newCom/productionProcess.vue 258 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/components/newCom/quality.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/components/newCom/user.vue 330 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/main.ts 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/router/module/workOrder/index.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/views/LogInAgain.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/views/needToBeDealtWith/addWarehousing.vue 66 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/views/needToBeDealtWith/outbound.vue 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/views/workOrder/afterWorkReport.vue 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/views/workOrder/index.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/views/workOrder/processPlan.vue 232 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/views/workOrder/reportingForWork.vue 1853 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/src/views/wxLogin.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/api/business/SalaryParamController.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/api/business/UnqualifiedRecordController.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/api/ext/CategoryExtController.java 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/api/ext/PlansExtController.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/api/ext/SalaryParamExtController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/config/shiro/ShiroRealm.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/core/utils/excel/EasyExcelUtil.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/dao/business/UnqualifiedRecordMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/dao/business/dto/AutoWorkReportDTO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/dao/business/dto/CreateUnqualifiedDTO.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/dao/business/model/UnqualifiedRecord.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/dao/business/vo/SalaryParamVO.java 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/dao/business/vo/WorkPlansVO.java 30 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/dao/ext/dto/QueryPlansExtDTO.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/dao/ext/dto/QueryUserSalaryListDTO.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/dao/ext/dto/SalaryParamImportDTO.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/dao/ext/vo/BomExtListVO.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/dao/ext/vo/CompanyExtListVO.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/dao/ext/vo/PlansExtListVO.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/service/business/UnqualifiedRecordService.java 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/service/business/impl/CompanyOpenServiceImpl.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/service/business/impl/CompanyServiceImpl.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/service/business/impl/SalaryParamServiceImpl.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/service/business/impl/UnqualifiedRecordServiceImpl.java 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/service/business/impl/WOutboundServiceImpl.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/service/ext/CategoryExtService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/service/ext/impl/CategoryExtServiceImpl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/service/ext/impl/DepartmentExtServiceImpl.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/service/ext/impl/PlansExtServiceImpl.java 80 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/service/ext/impl/WorkPlansExtServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/java/doumeemes/service/ext/impl/WorkorderRecordStandardServiceImpl.java 276 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/resources/mappers/PlansExtMapper.xml 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/resources/mappers/SalaryParamMapper.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/resources/mappers/UserDeviceExtMapper.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/resources/mappers/WorkPlansExtMapper.xml 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server/src/main/resources/mappers/WorkorderRecordExtMapper.xml 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
h5_standard/.env.development
@@ -13,9 +13,10 @@
# VUE_APP_API = 'http://192.168.0.12:10012/'
# ä»»åº·æœ¬åœ°
# VUE_APP_API = 'http://192.168.0.15:10021/'
VUE_APP_API = 'http://192.168.0.15:10021/'
# VUE_APP_API = 'http://192.168.0.127:10021/'
VUE_APP_API = 'https://dmtest.ahapp.net/doumeeplant_api/'
# VUE_APP_API = 'https://dmtest.ahapp.net/doumeeplant_api/'
# VUE_APP_API = 'http://192.168.0.13:10012/'
h5_standard/.env.production
@@ -18,7 +18,7 @@
# VUE_APP_API = 'https://hsky.doumee.com/doumeeplant_api/'
# æµ‹è¯•
# VUE_APP_API = 'https://dmtest.ahapp.net/doumeeplant_api/'
VUE_APP_API = 'https://dmtest.ahapp.net/doumeeplant_api/'
# æ¼”示
VUE_APP_API = 'https://www.mes.red/doumeeplant/'
# VUE_APP_API = 'https://www.mes.red/doumeeplant/'
h5_standard/src/apis/ExWarehouse.ts
@@ -186,4 +186,13 @@
        method: 'post',
        data
    })
}
// æ ¹æ®ä¾›éœ€è®¡åˆ’查询可用库存
export function getStockByPlansForStandard(data: any): Promise<any> {
    return httpRequest({
        url:  '/ext/workorderRecordExt/getStockByPlansForStandard',
        method: 'post',
        data
    })
}
h5_standard/src/apis/PlanningAPI.ts
@@ -104,3 +104,47 @@
        method: 'get'
    })
}
// æ ¹æ®å¯¹è±¡ä¿¡æ¯æŸ¥è¯¢
export function queryOne (data: any): Promise<any> {
    return httpRequest({
        url: '/ext/salaryParam/queryOne',
        method: 'post',
        data
    })
}
// ä¸€é”®æŠ¥å·¥
export function autoWorkReport (data: any): Promise<any> {
    return httpRequest({
        url: '/ext/plansExt/autoWorkReport',
        method: 'post',
        data
    })
}
// æ ¹æ®id查询
export function getIdPlansExt(id: any): Promise<any> {
    return httpRequest({
        url: `/ext/plansExt/${id}`,
        method: 'get'
    })
}
// åˆ—表查询
export function categoryExtList (data: any): Promise<any> {
    return httpRequest({
        url: '/ext/categoryExt/list',
        method: 'post',
        data
    })
}
// æŸ¥è¯¢å…¨éƒ¨
export function allUser (data: any): Promise<any> {
    return httpRequest({
        url: '/ext/companyUserExt/allUser',
        method: 'post',
        data
    })
}
h5_standard/src/assets/icon/ic_ar@2x.png
h5_standard/src/assets/icon/ic_close@2x.png
h5_standard/src/components/common/Access.vue
@@ -53,7 +53,7 @@
    import { choiceStockPageByTransfer } from '@/apis/ExWarehouse'
    import { model } from '@/interface'
    import { Attribute } from '@/enum'
    import { judgmentPlatform } from "@/utils/utils"
    import { judgmentPlatform } from "@/utils"
    import vSearch from '@/components/common/Search.vue'
    import vLableSelection from '@/components/common/LabelSelection.vue'
h5_standard/src/components/newCom/Material.vue
@@ -1,13 +1,17 @@
<template>
    <van-popup
        v-model:show="props.show"
        :close-on-click-overlay="false"
        round
        position="bottom"
        :style="{ height: '80%' }">
        <div class="title">
            <div class="close" @click="close"><van-icon name="arrow-down" size="30" color="#ffffff" /></div>
        </div>
        <div class="content">
            <div class="content_search content_top">
                <div class="title">
                    <img class="close" src="@/assets/icon/ic_close@2x.png" alt="" style="opacity: 0;" />
                    <span>选择生产人员</span>
                    <img class="close" src="@/assets/icon/ic_close@2x.png" alt="" @click="close" />
                </div>
                <v-Search @searchInput="searchInput" @submit="submit" :isShow="false" placeholder="搜索物料名称"></v-Search>
            </div>
            <div class="content_total">共{{form.total}}条数据</div>
@@ -163,21 +167,6 @@
</script>
<style lang="scss" scoped>
    .title {
        position: fixed;
        right: 50px;
        bottom: 100px;
        z-index: 9;
        .close {
            width: 80px;
            height: 80px;
            border-radius: 50%;
            background: #999999;
            display: flex;
            align-items: center;
            justify-content: center;
        }
    }
    .content {
        .content_code {
            position: fixed;
@@ -197,6 +186,24 @@
            position: sticky;
            top: 88px;
            z-index: 9;
            .title {
                width: 100%;
                padding: 0 0 30px 0;
                box-sizing: border-box;
                display: flex;
                align-items: center;
                justify-content: space-between;
                span {
                    font-size: 30px;
                    font-family: PingFangSC-Medium, PingFang SC;
                    font-weight: 500;
                    color: #222222;
                }
                .close {
                    width: 28px;
                    height: 28px;
                }
            }
            .content_search_x {
                height: 24px;
            }
@@ -209,7 +216,7 @@
            color: #666666;
            position: sticky;
            z-index: 99;
            top: 127px;
            top: 195px;
        }
        .content_list {
            width: 100%;
h5_standard/src/components/newCom/MaterialY.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,417 @@
<template>
    <van-popup
        v-model:show="props.show"
        :close-on-click-overlay="false"
        round
        position="bottom"
        :style="{ height: '80%' }">
        <div class="title">
            <div class="close" @click="close"><van-icon name="arrow-down" size="30" color="#ffffff" /></div>
        </div>
        <div class="content">
            <div class="content_search content_top">
                <v-Search @searchInput="searchInput" @submit="submit" :isShow="false" placeholder="搜索物料名称"></v-Search>
            </div>
            <div class="content_total">共{{form.total}}条数据</div>
            <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
                <van-list
                    v-model:loading="loading"
                    :finished="finished"
                    finished-text="没有更多了~"
                    @load="onLoad"
                >
                <div class="content_list">
                        <div class="page_content" v-for="(item1, idx) in list" :key="idx" @click="jump(item1)">
                            <div class="page_content_title">
                                <div class="page_content_title_top">
                                    <span v-if="item1.batch">{{ item1.materialName + ' | ' + item1.materialCode }}</span>
                                    <span v-else>{{ item1.materialName + ' | ' + item1.materialCode }}</span>
                                    <!-- <span>{{item1.num}}{{item1.unitName}}</span> -->
                                </div>
                                <div class="page_content_title_bottom">
                                    <span>{{ item1.locationName }}&nbsp;/&nbsp;</span>
                                    <span>{{ item1.num }}{{ item1.unitName }}</span>
                                </div>
                                <div class="page_content_title_bottom">
                                    <span class="green" v-if="item1.qualityType == 0">合格&nbsp;<span class="black">/</span>&nbsp;</span>
                                    <span class="warning" v-else-if="item1.qualityType == 1">不良&nbsp;<span class="black">/</span>&nbsp;</span>
                                    <span class="error" v-else-if="item1.qualityType == 2">报废&nbsp;<span class="black">/</span>&nbsp;</span>
                                    <span v-else>-&nbsp;/&nbsp;</span>
                                    <span>{{item1.procedureName ? item1.procedureName : '-'}}&nbsp;/&nbsp;</span>
                                    <span>{{item1.batch ? item1.batch : '-'}}</span>
                                </div>
                            </div>
                        </div>
                        <!-- <div class="content_list_item" v-for="(item, i) in props.list" :key="i" @click="jump(item)">
                            <div class="content_list_item_name">{{item.materialName}}</div>
                        </div> -->
                    </div>
                    <!-- <div class="content_list">
                        <div class="content_list_item" v-for="(item, i) in list" :key="i" @click="jump(item)">
                            <div class="content_list_item_name">{{item.mmodelUnionName}}</div>
                        </div>
                    </div> -->
                </van-list>
            </van-pull-refresh>
        </div>
    </van-popup>
</template>
<script setup lang="ts">
    import { defineProps, defineEmits, onMounted, ref, reactive, watch } from 'vue'
    import { getStockByPlansForStandard } from '@/apis/ExWarehouse'
    import { model } from '@/interface'
    import { judgmentPlatform } from "@/utils/utils"
    import vSearch from '@/components/common/Search.vue'
    // æœç´¢æ•°æ®æŽ¥å£
    interface form extends model {
        total: number,
        name: string
    }
    const form = reactive<form>({
        capacity: 50,
        page: 0,
        total: 0,
        name: '',
    })
    // åˆ—表数据
    const list: any = ref([]);
    const loading = ref(false);
    const finished = ref(false);
    const refreshing = ref(false);
    let isOne = ref(true)
    // æœç´¢æ¡†
    const searchInput = (data: any) => {
        form.page = 0
        finished.value = false
        list.value = []
        form.name = data
        onLoad()
    }
    // æœç´¢æäº¤
    const submit = (): void => {
        form.page = 0
        finished.value = false
        list.value = []
        onLoad()
    }
    // è¿”回上一页带参数
    const jump = (item: any) => {
        emit('value', item)
    }
    // èŽ·å–ç‰©æ–™åˆ—è¡¨æ•°æ®
    const onLoad = async () => {
        if (!finished.value) {
            loading.value = true;
            form.page = form.page + 1
            getStockByPlansForStandard({
                capacity: form.capacity,
                page: form.page,
                model: {
                    ids: props.ids,
                    materialName: form.name,
                    deviceId: props.deviceId,
                    plansId: props.plansId
                }
            }).then(res => {
                isOne.value = false
                if (refreshing.value) {
                    list.value = []
                    refreshing.value = false;
                }
                loading.value = false;
                if (res.code === 200 && res.data.records && res.data.records.length !== 0) {
                    form.total = res.data.total
                    list.value.push(...res.data.records)
                } else {
                    finished.value = true;
                }
            }).catch((err: any) => {
                loading.value = false;
                finished.value = true;
                if (refreshing.value) {
                    list.value = []
                    refreshing.value = false;
                }
            })
        }
    }
    // ä¸‹æ‹‰åˆ·æ–°ä¼˜åŒ–页面
    const onRefresh = () => {
        finished.value = false;
        form.page = 0
        loading.value = true;
        onLoad()
    }
    let status = ref<boolean>(false)
    const props = defineProps({
        show: {
            type: Boolean,
            required: true
        },
        plansId: {
            type: String,
            required: true
        },
        deviceId: {
            type: String,
            required: true
        },
        ids: {
            type: String,
            required: false
        }
    })
    const emit = defineEmits(['close', 'value'])
    // å…³é—­å›žè°ƒ
    const close = () => {
        emit('close')
    }
    onMounted(() => {
        status.value = judgmentPlatform()
    })
    watch(() => props.show, (news) => {
        if (news && !isOne.value) {
            list.value = []
            finished.value = false;
            form.page = 0
            form.name = ''
            loading.value = true;
            onLoad()
        }
    })
</script>
<style lang="scss" scoped>
    .title {
        position: fixed;
        right: 50px;
        bottom: 100px;
        z-index: 9;
        .close {
            width: 80px;
            height: 80px;
            border-radius: 50%;
            background: #999999;
            display: flex;
            align-items: center;
            justify-content: center;
        }
    }
    .content {
        .content_code {
            position: fixed;
            right: 30px;
            bottom: 100px;
            img {
                width: 138px;
                height: 138px;
            }
        }
        .content_top {
            top: 0 !important;
        }
        .content_search {
            padding: 30px;
            background: white;
            position: sticky;
            top: 88px;
            z-index: 9;
            .content_search_x {
                height: 24px;
            }
        }
        .content_total {
            padding: 24px 30px;
            background: #F7F7F7;
            font-size: 24px;
            font-weight: 400;
            color: #666666;
            position: sticky;
            z-index: 99;
            top: 127px;
        }
        .content_list {
            width: 100%;
            height: 100%;
            display: flex;
            flex-direction: column;
            .page_content {
                margin-top: 36px;
                padding: 0 30px;
                box-sizing: border-box;
                .page_content_title {
                    display: flex;
                    flex-direction: column;
                    margin-bottom: 10px;
                    .page_content_title_top {
                        display: flex;
                        align-items: center;
                        justify-content: space-between;
                        span {
                            &:nth-child(1) {
                                font-size: 30px;
                                font-weight: 500;
                                color: #222222;
                            }
                            &:nth-child(2) {
                                flex-shrink: 0;
                                font-size: 24px;
                                font-weight: 400;
                                color: #333333;
                                span {
                                    font-size: 24px;
                                    color: $nav-color;
                                }
                            }
                        }
                    }
                    .page_content_title_loa {
                        font-size: 26px;
                        font-family: PingFangSC-Regular, PingFang SC;
                        font-weight: 400;
                        color: #333333;
                        margin-top: 10px;
                    }
                    .page_content_title_bottom {
                        margin-top: 10px;
                        .green {
                            color: $nav-stateColor7 !important;
                            .black {
                                color: black !important;
                            }
                        }
                        .warning {
                            color: $nav-stateColor5 !important;
                            .black {
                                color: black !important;
                            }
                        }
                        .error {
                            color: $nav-stateColor4 !important;
                            .black {
                                color: black !important;
                            }
                        }
                        span {
                            font-size: 24px;
                            font-weight: 400;
                            color: #666666;
                        }
                    }
                }
                .lineBorder {
                    border: none !important;
                    padding-bottom: 0 !important;
                    margin-bottom: 24px;
                }
                .page_content_list {
                    width: 100%;
                    display: flex;
                    align-items: center;
                    flex-wrap: wrap;
                    &:first-child {
                        margin: 0;
                    }
                    &:last-child {
                        border: none;
                    }
                    .page_content_list_nums {
                        width: 30%;
                        display: flex;
                        .page_content_list_num_label {
                            font-size: 26px;
                            font-weight: 400;
                            color: #666666;
                        }
                        .page_content_list_num_nr {
                            font-size: 26px;
                            font-weight: 400;
                            color: #222222;
                        }
                    }
                    .page_content_list_num {
                        width: 70%;
                        display: flex;
                        .page_content_list_num_label {
                            font-size: 26px;
                            font-weight: 400;
                            color: #666666;
                        }
                        .page_content_list_num_nr {
                            font-size: 26px;
                            font-weight: 400;
                            color: #222222;
                        }
                    }
                    .page_content_list_items {
                        width: 30%;
                        display: flex;
                        margin-top: 24px;
                        .page_content_list_item_label {
                            font-size: 26px;
                            font-weight: 400;
                            color: #666666;
                            flex-shrink: 0;
                        }
                        .page_content_list_item_nr {
                            font-size: 26px;
                            font-weight: 400;
                            color: #222222;
                        }
                    }
                    .page_content_list_item {
                        width: 70%;
                        display: flex;
                        .page_content_list_item_label {
                            font-size: 26px;
                            font-weight: 400;
                            color: #666666;
                            flex-shrink: 0;
                        }
                        .page_content_list_item_nr {
                            font-size: 26px;
                            font-weight: 400;
                            color: #222222;
                        }
                    }
                }
            }
            .content_list_item {
                padding: 30px;
                display: flex;
                border-bottom: 1px solid #ececec;
                .serious {
                    color: $nav-stateColor4 !important;
                }
                .success {
                    color: $nav-stateColor2 !important;
                }
                .warning {
                    color: $nav-stateColor5 !important;
                }
                .content_list_item_status {
                    font-size: 28px;
                    margin-right: 10px;
                }
                .content_list_item_name {
                    font-size: 28px;
                }
            }
        }
    }
</style>
h5_standard/src/components/newCom/location.vue
@@ -1,6 +1,8 @@
<template>
    <van-popup
        v-model:show="props.show"
        :close-on-click-overlay="false"
        round
        position="bottom"
        :style="{ height: '60%' }">
        <div class="title">
h5_standard/src/components/newCom/productionProcess.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,258 @@
<template>
    <van-popup
        v-model:show="props.show"
        :close-on-click-overlay="false"
        round
        position="bottom"
        :style="{ height: '60%' }">
        <div class="title">
            <div class="close" @click="close"><van-icon name="arrow-down" size="30" color="#ffffff" /></div>
        </div>
        <div class="content">
            <div class="content_list">
                <div class="content_list_item" v-for="(item, i) in props.list" :key="i" @click="jump(item)">
                    <div class="content_list_item_name">{{item.name}}</div>
                </div>
            </div>
        </div>
    </van-popup>
</template>
<script setup lang="ts">
    import { defineProps, defineEmits, ref } from 'vue'
    // è¿”回上一页带参数
    const jump = (item: any) => {
        emit('value', item)
    }
    const props: any = defineProps({
        show: {
            type: Boolean,
            required: true
        },
        list: {
            type: Array,
            required: true
        }
    })
    const emit = defineEmits(['close', 'value'])
    // å…³é—­å›žè°ƒ
    const close = () => {
        emit('close')
    }
</script>
<style lang="scss" scoped>
    .title {
        position: fixed;
        right: 50px;
        bottom: 100px;
        z-index: 9;
        .close {
            width: 80px;
            height: 80px;
            border-radius: 50%;
            background: #999999;
            display: flex;
            align-items: center;
            justify-content: center;
        }
    }
    .content {
        .content_code {
            position: fixed;
            right: 30px;
            bottom: 100px;
            img {
                width: 138px;
                height: 138px;
            }
        }
        .content_top {
            top: 0 !important;
        }
        .content_search {
            padding: 30px;
            background: white;
            position: sticky;
            top: 88px;
            z-index: 9;
            .content_search_x {
                height: 24px;
            }
        }
        .content_total {
            padding: 24px 30px;
            background: #F7F7F7;
            font-size: 24px;
            font-weight: 400;
            color: #666666;
            position: sticky;
            z-index: 99;
            top: 127px;
        }
        .content_list {
            width: 100%;
            height: 100%;
            display: flex;
            flex-direction: column;
            .page_content {
                margin-top: 36px;
                padding: 0 30px;
                box-sizing: border-box;
                .page_content_title {
                    display: flex;
                    flex-direction: column;
                    margin-bottom: 10px;
                    .page_content_title_top {
                        display: flex;
                        align-items: center;
                        justify-content: space-between;
                        span {
                            &:nth-child(1) {
                                font-size: 30px;
                                font-weight: 500;
                                color: #222222;
                            }
                            &:nth-child(2) {
                                flex-shrink: 0;
                                font-size: 24px;
                                font-weight: 400;
                                color: #333333;
                                span {
                                    font-size: 24px;
                                    color: $nav-color;
                                }
                            }
                        }
                    }
                    .page_content_title_bottom {
                        .green {
                            color: $nav-stateColor7 !important;
                            .black {
                                color: black !important;
                            }
                        }
                        .warning {
                            color: $nav-stateColor5 !important;
                            .black {
                                color: black !important;
                            }
                        }
                        .error {
                            color: $nav-stateColor4 !important;
                            .black {
                                color: black !important;
                            }
                        }
                        span {
                            font-size: 24px;
                            font-weight: 400;
                            color: #666666;
                        }
                    }
                }
                .lineBorder {
                    border: none !important;
                    padding-bottom: 0 !important;
                    margin-bottom: 24px;
                }
                .page_content_list {
                    width: 100%;
                    display: flex;
                    align-items: center;
                    flex-wrap: wrap;
                    &:first-child {
                        margin: 0;
                    }
                    &:last-child {
                        border: none;
                    }
                    .page_content_list_nums {
                        width: 30%;
                        display: flex;
                        .page_content_list_num_label {
                            font-size: 26px;
                            font-weight: 400;
                            color: #666666;
                        }
                        .page_content_list_num_nr {
                            font-size: 26px;
                            font-weight: 400;
                            color: #222222;
                        }
                    }
                    .page_content_list_num {
                        width: 70%;
                        display: flex;
                        .page_content_list_num_label {
                            font-size: 26px;
                            font-weight: 400;
                            color: #666666;
                        }
                        .page_content_list_num_nr {
                            font-size: 26px;
                            font-weight: 400;
                            color: #222222;
                        }
                    }
                    .page_content_list_items {
                        width: 30%;
                        display: flex;
                        margin-top: 24px;
                        .page_content_list_item_label {
                            font-size: 26px;
                            font-weight: 400;
                            color: #666666;
                            flex-shrink: 0;
                        }
                        .page_content_list_item_nr {
                            font-size: 26px;
                            font-weight: 400;
                            color: #222222;
                        }
                    }
                    .page_content_list_item {
                        width: 70%;
                        display: flex;
                        .page_content_list_item_label {
                            font-size: 26px;
                            font-weight: 400;
                            color: #666666;
                            flex-shrink: 0;
                        }
                        .page_content_list_item_nr {
                            font-size: 26px;
                            font-weight: 400;
                            color: #222222;
                        }
                    }
                }
            }
            .content_list_item {
                padding: 30px;
                display: flex;
                border-bottom: 1px solid #ececec;
                .serious {
                    color: $nav-stateColor4 !important;
                }
                .success {
                    color: $nav-stateColor2 !important;
                }
                .warning {
                    color: $nav-stateColor5 !important;
                }
                .content_list_item_status {
                    font-size: 28px;
                    margin-right: 10px;
                }
                .content_list_item_name {
                    font-size: 28px;
                }
            }
        }
    }
</style>
h5_standard/src/components/newCom/quality.vue
@@ -1,6 +1,7 @@
<template>
    <van-popup
        v-model:show="props.show"
        :close-on-click-overlay="false"
        position="bottom"
        :style="{ height: '60%' }">
        <div class="title">
h5_standard/src/components/newCom/user.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,330 @@
<template>
    <van-popup
        v-model:show="props.show"
        :close-on-click-overlay="false"
        position="bottom"
        round
        :style="{ height: '80%' }">
        <div class="content">
            <div class="content_search content_top">
                <div class="title">
                    <img class="close" src="@/assets/icon/ic_close@2x.png" alt="" style="opacity: 0;" />
                    <span>选择生产人员</span>
                    <img class="close" src="@/assets/icon/ic_close@2x.png" alt="" @click="close" />
                </div>
                <v-Search @searchInput="searchInput" @submit="submit" :isShow="false" placeholder="搜索姓名"></v-Search>
            </div>
            <div class="content_total">共{{form.total}}条数据</div>
            <div class="content_list">
                <div class="content_list_item" v-for="(item, i) in list" :key="i" @click="jump(item)">
                    <div class="content_list_item_name">{{item.name}}&nbsp;|&nbsp;{{item.dmodel.name}}</div>
                </div>
            </div>
        </div>
    </van-popup>
</template>
<script setup lang="ts">
    import { defineProps, defineEmits, onMounted, ref, reactive } from 'vue'
    import { materialDistributeExt } from '@/apis/ExWarehouse'
    import { getFindAll, allUser } from '@/apis/PlanningAPI'
    import { model } from '@/interface'
    import { judgmentPlatform } from "@/utils/utils"
    import vSearch from '@/components/common/Search.vue'
    // æœç´¢æ•°æ®æŽ¥å£
    interface form extends model {
        total: number,
        name: string
    }
    const form = reactive<form>({
        capacity: 50,
        page: 0,
        total: 0,
        name: '',
    })
    // åˆ—表数据
    const list: any = ref([]);
    const loading = ref(false);
    const finished = ref(false);
    const refreshing = ref(false)
    // æœç´¢æ¡†
    const searchInput = (data: any) => {
        form.page = 0
        finished.value = false
        list.value = []
        form.name = data
        onLoad()
    }
    // æœç´¢æäº¤
    const submit = (): void => {
        form.page = 0
        finished.value = false
        list.value = []
        onLoad()
    }
    // è¿”回上一页带参数
    const jump = (item: any) => {
        emit('value', item)
    }
    // èŽ·å–ç‰©æ–™åˆ—è¡¨æ•°æ®
    const onLoad = async () => {
        loading.value = true;
        allUser({ name: form.name })
            .then(res => {
                loading.value = false;
                if (res.code === 200 && res.data && res.data.length !== 0) {
                    form.total = res.data.length
                    list.value = res.data
                } else {
                    finished.value = true;
                }
            }).catch((err: any) => {
                loading.value = false;
                finished.value = true;
                if (refreshing.value) {
                    list.value = []
                    refreshing.value = false;
                }
            })
    }
    const props = defineProps({
        show: {
            type: Boolean,
            required: true
        }
    })
    const emit = defineEmits(['close', 'value'])
    // å…³é—­å›žè°ƒ
    const close = () => {
        emit('close')
    }
    onMounted(() => {
        onLoad()
    })
</script>
<style lang="scss" scoped>
    .content {
        .content_code {
            position: fixed;
            right: 30px;
            bottom: 100px;
            img {
                width: 138px;
                height: 138px;
            }
        }
        .content_top {
            top: 0 !important;
        }
        .content_search {
            padding: 30px;
            background: white;
            position: sticky;
            top: 88px;
            z-index: 9;
            .title {
                width: 100%;
                padding: 0 0 30px 0;
                box-sizing: border-box;
                display: flex;
                align-items: center;
                justify-content: space-between;
                span {
                    font-size: 30px;
                    font-family: PingFangSC-Medium, PingFang SC;
                    font-weight: 500;
                    color: #222222;
                }
                .close {
                    width: 28px;
                    height: 28px;
                }
            }
            .content_search_x {
                height: 24px;
            }
        }
        .content_total {
            padding: 24px 30px;
            background: #F7F7F7;
            font-size: 24px;
            font-weight: 400;
            color: #666666;
            position: sticky;
            z-index: 99;
            top: 195px;
        }
        .content_list {
            width: 100%;
            height: 100%;
            display: flex;
            flex-direction: column;
            .page_content {
                margin-top: 36px;
                padding: 0 30px;
                box-sizing: border-box;
                .page_content_title {
                    display: flex;
                    flex-direction: column;
                    margin-bottom: 10px;
                    .page_content_title_top {
                        display: flex;
                        align-items: center;
                        justify-content: space-between;
                        span {
                            &:nth-child(1) {
                                font-size: 30px;
                                font-weight: 500;
                                color: #222222;
                            }
                            &:nth-child(2) {
                                flex-shrink: 0;
                                font-size: 24px;
                                font-weight: 400;
                                color: #333333;
                                span {
                                    font-size: 24px;
                                    color: $nav-color;
                                }
                            }
                        }
                    }
                    .page_content_title_bottom {
                        .green {
                            color: $nav-stateColor7 !important;
                            .black {
                                color: black !important;
                            }
                        }
                        .warning {
                            color: $nav-stateColor5 !important;
                            .black {
                                color: black !important;
                            }
                        }
                        .error {
                            color: $nav-stateColor4 !important;
                            .black {
                                color: black !important;
                            }
                        }
                        span {
                            font-size: 24px;
                            font-weight: 400;
                            color: #666666;
                        }
                    }
                }
                .lineBorder {
                    border: none !important;
                    padding-bottom: 0 !important;
                    margin-bottom: 24px;
                }
                .page_content_list {
                    width: 100%;
                    display: flex;
                    align-items: center;
                    flex-wrap: wrap;
                    &:first-child {
                        margin: 0;
                    }
                    &:last-child {
                        border: none;
                    }
                    .page_content_list_nums {
                        width: 30%;
                        display: flex;
                        .page_content_list_num_label {
                            font-size: 26px;
                            font-weight: 400;
                            color: #666666;
                        }
                        .page_content_list_num_nr {
                            font-size: 26px;
                            font-weight: 400;
                            color: #222222;
                        }
                    }
                    .page_content_list_num {
                        width: 70%;
                        display: flex;
                        .page_content_list_num_label {
                            font-size: 26px;
                            font-weight: 400;
                            color: #666666;
                        }
                        .page_content_list_num_nr {
                            font-size: 26px;
                            font-weight: 400;
                            color: #222222;
                        }
                    }
                    .page_content_list_items {
                        width: 30%;
                        display: flex;
                        margin-top: 24px;
                        .page_content_list_item_label {
                            font-size: 26px;
                            font-weight: 400;
                            color: #666666;
                            flex-shrink: 0;
                        }
                        .page_content_list_item_nr {
                            font-size: 26px;
                            font-weight: 400;
                            color: #222222;
                        }
                    }
                    .page_content_list_item {
                        width: 70%;
                        display: flex;
                        .page_content_list_item_label {
                            font-size: 26px;
                            font-weight: 400;
                            color: #666666;
                            flex-shrink: 0;
                        }
                        .page_content_list_item_nr {
                            font-size: 26px;
                            font-weight: 400;
                            color: #222222;
                        }
                    }
                }
            }
            .content_list_item {
                padding: 30px;
                display: flex;
                border-bottom: 1px solid #ececec;
                .serious {
                    color: $nav-stateColor4 !important;
                }
                .success {
                    color: $nav-stateColor2 !important;
                }
                .warning {
                    color: $nav-stateColor5 !important;
                }
                .content_list_item_status {
                    font-size: 28px;
                    margin-right: 10px;
                }
                .content_list_item_name {
                    font-size: 28px;
                }
            }
        }
    }
</style>
h5_standard/src/main.ts
@@ -1,4 +1,5 @@
import { createApp } from 'vue'
import mitt from 'mitt'
// import VConsole from 'vconsole'
import App from './App.vue'
import router from './router'
@@ -16,6 +17,8 @@
const app = createApp(App)
app.config.globalProperties.$Bus = mitt()
app.config.globalProperties.$onWait = new Promise((resolve) => {
    app.config.globalProperties.$reslove = resolve
})
h5_standard/src/router/module/workOrder/index.ts
@@ -192,9 +192,18 @@
                name: 'reportingForWork',
                meta: {
                    title: '一键报工',
                    keepAlive: false
                    keepAlive: true
                },
                component: () => import('@/views/workOrder/reportingForWork.vue')
            },
            {
                path: '/workOrder/processPlans',
                name: 'processPlans',
                meta: {
                    title: '选择工序计划',
                    keepAlive: false
                },
                component: () => import('@/views/workOrder/processPlan.vue')
            }
        ]
    }
h5_standard/src/views/LogInAgain.vue
@@ -80,7 +80,7 @@
      // let res = await testLogin({  // è‹±å­å§
      //   username: '18055151023',
      //   password: '123456',
      //   companyId: '1',
      //   companyId: '8',
      //   uuid: '0000',
      //   code: '0000'
      // })
h5_standard/src/views/needToBeDealtWith/addWarehousing.vue
@@ -29,7 +29,7 @@
            </div>
            <van-swipe-cell v-for="(item, index) in list" :key="index">
                <div class="rework_qd_list">
                    <div class="rework_qd_item" @click="openL(index)">
                    <div class="rework_qd_item" @click="openL(index)" v-if="location">
                        <span><b>*</b>入库货位</span>
                        <div class="rework_qd_item_right">
                            <span :class="item.locationName ? 'black' : ''">{{item.locationName ? item.locationName : '请选择'}}</span>
@@ -43,13 +43,13 @@
                            <van-icon name="arrow" size="20" color="#999999" />
                        </div>
                    </div>
                    <!-- <div class="rework_qd_item" v-if="form.type != 25">
                    <div class="rework_qd_item" v-if="form.type != 25" @click="openGX(index)">
                        <span>生产工序</span>
                        <div class="rework_qd_item_right">
                            <span :class="item.procedureName ? 'black' : ''">{{item.procedureName ? item.procedureName : '请选择'}}</span>
                            <van-icon name="arrow" size="20" color="#999999" />
                        </div>
                    </div> -->
                    </div>
                    <div class="rework_qd_item" @click="openQ(index)">
                        <span><b>*</b>质量属性</span>
                        <div class="rework_qd_item_right">
@@ -87,8 +87,10 @@
        <Quality :show="qualityShow" @close="close2" @value="getValue2" />
        <!-- é€‰æ‹©è´§ä½ -->
        <Location :show="locationShow" :list="locationList" @close="close3" @value="getValue3" />
        <!-- å·¥åº -->
        <ProductionProcess :show="productionShow" :list="productionList" @close="close4" @value="getValue4" />
        <!-- å•据类型 -->
        <van-popup v-model:show="typeShow" position="bottom" :style="{ height: '50%' }">
        <van-popup v-model:show="typeShow" round position="bottom" :style="{ height: '50%' }">
            <van-picker
                :columns="columns"
                @confirm="onConfirm1"
@@ -103,11 +105,13 @@
    import { onMounted, ref, reactive } from 'vue'
    import { useRouter } from 'vue-router'
    import { Toast } from 'vant'
    import { createForStandard, getListByWarehouseId, wOutBoundForStockUp } from '@/apis/WorkOrderAPI'
    import { getListByWarehouseId, wOutBoundForStockUp } from '@/apis/WorkOrderAPI'
    import { getListByMaterialId } from '@/apis/ExWarehouse'
    import Warehouse from '@/components/common/Warehouse.vue'
    import Material from '@/components/newCom/Material.vue'
    import Quality from '@/components/newCom/quality.vue'
    import Location from '@/components/newCom/location.vue'
    import ProductionProcess from '@/components/newCom/productionProcess.vue'
    const router = useRouter()
    // è¡¨å•数据
@@ -119,6 +123,8 @@
    })
    let locationList: any = ref([])
    let location: any = ref(true)
    let productionList: any = ref([])
    let i = ref(0)
@@ -150,6 +156,7 @@
    let qualityShow = ref<boolean>(false)
    let locationShow = ref<boolean>(false)
    let typeShow = ref<boolean>(false)
    let productionShow = ref<boolean>(false)
    // æ‰“开选择物料
    const openMaterial = (index: number) => {
@@ -160,6 +167,11 @@
    const openQ = (index: number) => {
        i.value = index
        qualityShow.value = true
    }
    // æ‰“开工序
    const openGX = (index: number) => {
        i.value = index
        productionShow.value = true
    }
    // æ‰“开选择货位
    const openL = (index: number) => {
@@ -188,6 +200,12 @@
    const onConfirm1 = (value: any) => {
        form.typeName = value.name
        form.type = value.id
        if (value.id == 25) {
            list.value.forEach(item => {
                item.procedureId = ''
                item.procedureName = ''
            })
        }
        typeShow.value = false
    };
    const onCancel = () => {
@@ -265,6 +283,10 @@
    const close3 = (): void => {
        locationShow.value = false
    }
    // å…³é—­è´§ä½é€‰æ‹©å¼¹æ¡†
    const close4 = (): void => {
        productionShow.value = false
    }
    // é€‰æ‹©ä»“库回调
    const getValue = (item: any): void => {
        form.warehouseName = item.name
@@ -273,21 +295,39 @@
            .then(res => {
                if (res.code === 200) {
                    locationList.value = res.data
                    list.value.forEach(item => {
                        item.locationId = ''
                        item.locationName = ''
                    })
                    if (res.data.length === 1) {
                        location.value = false
                        list.value.forEach(item => {
                            item.locationId = res.data[0].id
                            item.locationName = res.data[0].unionName
                        })
                    } else {
                        location.value = true
                        list.value.forEach(item => {
                            item.locationId = ''
                            item.locationName = ''
                        })
                    }
                }
            })
        warehouseShow.value = false
    }
    // é€‰æ‹©ç‰©æ–™
    const getValue1 = (item: any): void => {
        console.log(item)
        list.value[i.value].materialName = item.mmodelUnionName
        list.value[i.value].materialId = item.id
        list.value[i.value].unitId = item.unitId
        list.value[i.value].unitName = item.umodelName
        // èŽ·å–ç‰©æ–™ä¸‹å·¥åº
        getListByMaterialId({
            materialId: item.id
        }).then(res => {
            if (res.code === 200) {
                productionList.value = res.data
                list.value[i.value].procedureId = ''
                list.value[i.value].procedureName = ''
            }
        })
        materialsShow.value = false
    }
    // é€‰æ‹©è´¨é‡å±žæ€§
@@ -302,6 +342,12 @@
        list.value[i.value].locationName = item.unionName
        locationShow.value = false
    }
    // é€‰æ‹©å·¥åº
    const getValue4 = (item: any): void => {
        list.value[i.value].procedureId = item.id
        list.value[i.value].procedureName = item.name
        productionShow.value = false
    }
    onMounted(() => {
        // èŽ·å–å·¥è£…ä¿¡æ¯
        // getLKInfo(route.query.id as string)
h5_standard/src/views/needToBeDealtWith/outbound.vue
@@ -61,7 +61,7 @@
        <Warehouse :show="warehouseShow" @close="close" @value="getValue" />
        <Materials ref="Material" :show="materialsShow" :id="form.warehouseId.toString()" @close="close1" @value="getValue1" />
        <!-- å•据类型 -->
        <van-popup v-model:show="typeShow" position="bottom" :style="{ height: '50%' }">
        <van-popup v-model:show="typeShow" round position="bottom" :style="{ height: '50%' }">
            <van-picker
                :columns="columns"
                @confirm="onConfirm1"
@@ -124,6 +124,8 @@
    // æäº¤
    const onConfirm = () => {
        if (!form.type) return Toast('请选择单据类型')
        if (!form.warehouseId) return Toast('请选择出库仓库')
        if (list.value.length === 0) return Toast('至少选择一条出库物料')
        for (let i = 0; i < list.value.length; i++) {
            if (!list.value[i].num || list.value[i].num == '' || list.value[i].num == 0) {
                return Toast(`第${i + 1}个出库物料数量必须大于0`)
h5_standard/src/views/workOrder/afterWorkReport.vue
@@ -357,15 +357,17 @@
        }).then(res => {
            if (res.code === 200) {
                if (res.data.length > 0) {
                    res.data.forEach((item: any) => {
                        if (item.doneType === 1) {
                            produceFrom.undesirable = item.num
                            produceFrom.undesirableId = item.id
                        } else {
                            produceFrom.qualified = item.num
                            produceFrom.qualifiedId = item.id
                        }
                    })
                    produceFrom.qualified = res.data[0].qualifiedNum
                    produceFrom.undesirable = res.data[0].unqualifiedNum
                    // res.data.forEach((item: any) => {
                    //     if (item.doneType === 1) {
                    //         produceFrom.undesirable = item.num
                    //         produceFrom.undesirableId = item.id
                    //     } else {
                    //         produceFrom.qualified = item.num
                    //         produceFrom.qualifiedId = item.id
                    //     }
                    // })
                }
                // res.data.forEach((item: any) => {
                //     if (item.doneType === 0) { // åˆæ ¼
h5_standard/src/views/workOrder/index.vue
@@ -150,7 +150,7 @@
            num: '0'
        },
        {
            id: [2,3],
            id: [2,3,7],
            name: '生产中',
            num: '0'
        },
@@ -213,6 +213,7 @@
    // åˆ‡æ¢åˆ†ç±»
    const clickTag = (id: any): void => {
        console.log()
        form.total = 0
        form.statusList = id
        form.page = 0
h5_standard/src/views/workOrder/processPlan.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,232 @@
<template>
    <div class="content">
        <van-pull-refresh v-model="refreshing" @refresh="onRefresh">
            <van-list
                v-model:loading="loading"
                :finished="finished"
                finished-text="没有更多了~"
                @load="onLoad">
                <div class="content_list">
                    <van-swipe-cell v-for="(item, i) in listData" :key="i">
                        <div class="content_list_item" @click="clickItem(item)">
                            <div class="content_list_item_title">
                                <span>{{item.materialName}}|{{item.produceName}}</span>
                                <div class="content_list_item_title_tips" v-if="item.urgent">优先{{ item.urgent }}</div>
                            </div>
                            <div class="content_list_item_nr">
                                <div class="content_list_item_nr_box">
                                    <div class="label">物料编码:</div>
                                    <div class="cr">{{item.materialName}}丨{{item.materialCode}}</div>
                                </div>
                                <div class="content_list_item_nr_box">
                                    <div class="label">计划数量:</div>
                                    <div class="cr">{{item.num}}{{item.umodel.name}}</div>
                                </div>
                                <div class="content_list_item_nr_box">
                                    <div class="label">计划日期:</div>
                                    <div class="cr">{{item.workPlanStartDate}} ~ {{item.workPlanEndDate}}</div>
                                </div>
                                <div class="content_list_item_nr_box">
                                    <div class="label">计划员:</div>
                                    <div class="cr">{{item.planUserName}}</div>
                                </div>
                                <div class="content_list_item_nr_box">
                                    <div class="label">生产批次:</div>
                                    <div class="cr">{{item.batch}}</div>
                                </div>
                                <div class="content_list_item_nr_box" v-if="item.salesOrder">
                                    <div class="label">销售订单:</div>
                                    <div class="cr">{{ item.salesOrder }}</div>
                                </div>
                            </div>
                        </div>
                    </van-swipe-cell>
                </div>
            </van-list>
        </van-pull-refresh>
    </div>
</template>
<script setup lang="ts">
    import { reactive, ref, onBeforeUnmount, getCurrentInstance } from "vue"
    import { useRouter, useRoute } from "vue-router"
    import { getList } from "@/apis/PlanningAPI"
    const route = useRoute()
    const router = useRouter()
    const { $Bus }  = getCurrentInstance().appContext.config.globalProperties
    // åˆ†é¡µæŸ¥è¯¢æ•°æ®
    const pageData = reactive({
        capacity: 10,
        page: 0,
        total: 0
    })
    // åˆ—表数据
    let listData: any = ref([])
    const loading = ref(false)
    const finished = ref(false)
    const refreshing = ref(false)
    const clickItem = (obj: any) => {
        $Bus.emit('callback', obj)
        router.go(-1)
    }
    // åˆ—表
    const onLoad = () => {
        if (!finished.value) {
            pageData.page = pageData.page + 1
            loading.value = true
            getList({
                capacity: pageData.capacity,
                page: pageData.page,
                model: {
                    statusList: [1, 4],
                    paused: 0
                },
                sorts: [
                    { direction: 'DESC', property: 'CREATE_TIME' }
                ]
            }).then(res => {
                if (refreshing.value) {
                    listData.value = []
                    refreshing.value = false;
                }
                loading.value = false
                if (res.code === 200 && res.data.records && res.data.records.length !== 0) {
                    pageData.total = res.data.total
                    listData.value.push(...res.data.records)
                } else {
                    finished.value = true
                }
            }).catch(err => {
                loading.value = false
                finished.value = true
                if (refreshing.value) {
                    listData.value = []
                    refreshing.value = false;
                }
            })
        }
    }
    // ä¸‹æ‹‰åˆ·æ–°ä¼˜åŒ–页面
    const onRefresh = () => {
        finished.value = false;
        pageData.page = 0
        loading.value = true;
        onLoad();
    }
    onBeforeUnmount(() => {
        $Bus.all.delete("changeOdr")
    })
</script>
<style lang="scss" scoped>
    .content {
        width: 100%;
        // height: 100%;
        position: absolute;
        background: #F7F7F7;
        .content_list {
            width: 100%;
            height: 100%;
            display: flex;
            flex-direction: column;
            .content_list_item {
                padding: 30px;
                background: #ffffff;
                margin-bottom: 20px;
                .content_list_item_title {
                    display: flex;
                    align-items: center;
                    .content_list_item_title_tips {
                        padding: 4px 8px;
                        box-sizing: border-box;
                        background: #DE5243;
                        border-radius: 8px;
                        font-size: 22px;
                        font-family: PingFangSC-Regular, PingFang SC;
                        font-weight: 400;
                        color: #FFFFFF;
                        margin-left: 16px;
                    }
                    .warning {
                        color: $nav-stateColor1 !important;
                    }
                    .green {
                        color: $nav-stateColor6 !important;
                    }
                    span {
                        font-size: 32px;
                        font-family: PingFangSC-Medium, PingFang SC;
                        font-weight: 500;
                        color: #333333;
                    }
                }
                .content_list_item_nr {
                    padding: 24px 30px;
                    background: #F7F7F7;
                    border-radius: 16px;
                    margin-top: 30px;
                    display: flex;
                    justify-content: space-between;
                    flex-wrap: wrap;
                    .content_list_item_nr_boxs {
                        width: 45%;
                        display: flex;
                        margin-top: 24px;
                        &:nth-child(1) {
                            margin-top: 0;
                        }
                        &:nth-child(2) {
                            margin-top: 0;
                        }
                        .warning {
                            color: $nav-stateColor4 !important;
                        }
                        .label {
                            flex-shrink: 0;
                            font-size: 24px;
                            font-weight: 400;
                            color: #666666;
                        }
                        .cr {
                            flex: 1;
                            font-size: 24px;
                            font-weight: 400;
                            color: #222222;
                            overflow: hidden;
                            white-space: nowrap;
                            text-overflow: ellipsis;
                            -o-text-overflow:ellipsis;
                        }
                    }
                    .content_list_item_nr_box {
                        width: 100%;
                        display: flex;
                        margin-top: 24px;
                        &:nth-child(1) {
                            margin-top: 0;
                        }
                        .label {
                            font-size: 24px;
                            font-weight: 400;
                            color: #666666;
                            flex-shrink: 0;
                        }
                        .cr {
                            font-size: 24px;
                            font-weight: 400;
                            color: #222222;
                        }
                    }
                }
            }
        }
    }
</style>
h5_standard/src/views/workOrder/reportingForWork.vue
@@ -1,42 +1,84 @@
<template>
    <div class="bg">
        <!--  æŠ•料明细/合格产出明细/不良产出明细  -->
        <div class="bg_plan" @click="selectPlan">
            <div class="bg_plan_label" v-if="!from.processPlan">
                <span><b>*</b>工序生产计划</span>
            </div>
            <div class="bg_plan_nr" v-else>
                <span>{{ from.processPlan.materialName }} | {{ from.processPlan.materialCode }} | {{ from.processPlan.produceName }}</span>
                <span>{{ from.processPlan.batch }}{{ from.processPlan.salesOrder ? ` / ${from.processPlan.salesOrder}` : '' }}</span>
                <span>计划时间:{{ from.processPlan.workPlanStartDate }} ~ {{ from.processPlan.workPlanEndDate }}</span>
                <span>计划进度:{{from.processPlan.num}}/{{from.processPlan.workorderDistributNum}}{{ from.processPlan.unitName }}</span>
            </div>
            <div class="bg_plan_label_val">
                <span v-if="!from.processPlan">请选择</span>
                <img src="@/assets/icon/ic_ar@2x.png" alt="" />
            </div>
        </div>
        <div class="bg_list">
            <div class="bg_list_item">
                <div class="bg_list_item_top">
                    <div class="bg_list_item_top_left">
                        <div class="bg_list_item_top_left_x"></div>
                        <span>投料明细</span>
                        <!-- <span class="blue left">{{tlTotal()}}</span> -->
                    </div>
                    <div class="bg_list_item_top_right" @click="jumpTL" v-if="proxy.$auth('h5:workorderinput:create') && (info.bomType !== 1 || info.bomType == 0 || !info.bomType)">
                        <img src="@/assets/icon/gongdan_ic_shoudong@2x.png" alt="" />
                        <span>手动录入</span>
                        <span>生产信息</span>
                    </div>
                </div>
                <template v-if="feedingData && feedingData.length > 0">
                    <van-swipe-cell v-for="(item, index) in feedingData" :key="index">
                        <div class="bg_list_item_num">
                            <div class="bg_list_item_num_item">
                                <!-- <span>{{item.code}}</span> -->
                                <div class="bg_list_item_num_item_wl">
                                    <span> {{ item.materialName }}{{ item.procedureName ? `&nbsp;|&nbsp;${item.procedureName}` : '' }}</span>
                                    <div class="bg_list_item_num_item_wl_lx">
                                        <span class="green" v-if="item.qualityType == 0">合格&nbsp;/&nbsp;</span>
                                        <span class="yellow" v-if="item.qualityType == 1">不良&nbsp;/&nbsp;</span>
                                        <span class="red" v-if="item.qualityType == 2">报废&nbsp;/&nbsp;</span>
                                        <span>{{ item.locationName }}</span>
                                        <span>{{ item.batch ? `&nbsp;/&nbsp;${item.batch}` : '' }}</span>
                <div class="bg_list_item_h">
                    <div class="bg_list_item_num" @click="openDev">
                        <div class="bg_list_item_num_item">
                            <span>生产设备</span>
                            <div class="bg_list_item_num_item_sr">
                                <span :style="{color: from.deviceName ? '#333' : ''}">{{from.deviceName ? from.deviceName : '请选择'}}</span>
                                <img src="@/assets/icon/ic_ar@2x.png" alt="" />
                            </div>
                        </div>
                    </div>
                    <div class="bg_list_item_num" @click="userShow = true">
                        <div class="bg_list_item_num_item">
                            <span>生产人员</span>
                            <div class="bg_list_item_num_item_sr">
                                <span :style="{color: from.userName ? '#333' : ''}">{{from.userName ? from.userName : '请选择'}}</span>
                                <img src="@/assets/icon/ic_ar@2x.png" alt="" />
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="bg_list_item">
                <div class="bg_list_item_top">
                    <div class="bg_list_item_top_left">
                        <div class="bg_list_item_top_left_x"></div>
                        <span>生产信息</span>
                    </div>
                    <div class="bg_list_item_top_right" @click="openMaterial" v-if="(hasBom == 1 && bomType != 1) || hasBom == 0">
                        <img src="@/assets/icon/gongdan_ic_shoudong@2x.png" alt="" />
                        <span>新增投料</span>
                    </div>
                </div>
                <template v-if="wuList.length > 0">
                    <van-swipe-cell v-for="(item, index) in wuList" :key="index">
                        <div class="bg_list_item_h">
                            <div class="bg_list_item_num">
                                <div class="bg_list_item_num_item">
                                    <div class="bg_list_item_num_item_wl">
                                        <span>{{ item.materialName }}{{ item.procedureName ? ` | ${item.procedureName}` : '' }}</span>
                                        <div class="bg_list_item_num_item_wl_lx">
                                            <span class="green" v-if="item.qualityType == 0">合格&nbsp;/&nbsp;</span>
                                            <span class="yellow" v-if="item.qualityType == 1">不良&nbsp;/&nbsp;</span>
                                            <span class="red" v-if="item.qualityType == 2">报废&nbsp;/&nbsp;</span>
                                            <span>{{ item.locationName }}&nbsp;/&nbsp;</span>
                                            <span>{{ item.batch }}</span>
                                        </div>
                                    </div>
                                </div>
                                <div class="bg_list_item_num_item_sr">
                                    <input v-model="item.num" :disabled="!proxy.$auth('h5:workorderinput:update')" @blur="change(item.id, item.num, 'T', item.maxNum, item, item.unitAttribute)" type="number" />
                                    <span>{{item.unitName}}</span>
                                    <div class="bg_list_item_num_item_sr">
                                        <input type="number" v-model="item.num" @input="inputwl(index)" />
                                        <span>{{ item.unitName }}</span>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <template #right v-if="proxy.$auth('h5:workorderinput:delete')">
                            <van-button style="height: 100%;" square text="删除" @click="deleItem(item.id, 'T')" type="danger" />
                        <template #right>
                            <van-button style="height: 100%;" @click="deleItem(index)" square text="删除" type="danger" />
                        </template>
                    </van-swipe-cell>
                </template>
@@ -45,993 +87,538 @@
                        <span>暂无数据</span>
                    </div>
                </template>
                <div class="kong" v-if="hasBom == 1 && bomType == 1">
                    <span>当前工序无需投料</span>
                </div>
            </div>
            <div class="bg_list_item">
            <div class="bg_list_item bottomval">
                <div class="bg_list_item_top">
                    <div class="bg_list_item_top_left">
                        <div class="bg_list_item_top_left_x"></div>
                        <span>产出明细</span>
                    </div>
                </div>
                <!-- <template v-if="produceData && produceData.length > 0"> -->
                    <!-- v-for="(item, index) in produceData" :key="index" -->
                    <van-swipe-cell>
                        <div class="bg_list_item_num">
                            <div class="bg_list_item_num_item">
                                <span>良品数</span>
                                <div class="bg_list_item_num_item_sr">
                                    <!-- :disabled="!proxy.$auth('h5:workorderoutput:update')" -->
                                    <!-- @blur="change(item.id, item.num, 'C', item.maxNum, item)" -->
                                    <input type="number" v-model="produceFrom.qualified" @blur="changeCC('0', produceFrom.qualified, produceFrom.qualifiedId)" placeholder="请输入" />
                                    <span v-if="info.umodel">{{info.umodel.name}}</span>
                                </div>
                <div class="bg_list_item_h">
                    <div class="bg_list_item_num">
                        <div class="bg_list_item_num_item">
                            <span><b>*</b>良品数</span>
                            <div class="bg_list_item_num_item_sr">
                                <input type="number" v-model="from.qualified" @input="changeNum(1)" placeholder="请输入" />
                                <span>块</span>
                            </div>
                        </div>
                    </van-swipe-cell>
                    <van-swipe-cell>
                        <div class="bg_list_item_num">
                            <!-- @blur="change(item.id, item.num, 'C', item.maxNum, item)" -->
                            <div class="bg_list_item_num_item">
                                <span>不良数</span>
                                <div class="bg_list_item_num_item_sr">
                                    <!-- :disabled="!proxy.$auth('h5:workorderoutput:update')" -->
                                    <!-- @blur="change(item.id, item.num, 'C', item.maxNum, item)" -->
                                    <input type="number" v-model="produceFrom.undesirable" @blur="changeCC('1', produceFrom.undesirable, produceFrom.undesirableId)" placeholder="请输入" />
                                    <span v-if="info.umodel">{{info.umodel.name}}</span>
                                </div>
                            </div>
                        </div>
                    </van-swipe-cell>
                    <!-- <van-swipe-cell>
                        <div class="bg_list_item_num">
                            <div class="bg_list_item_num_item" @click="show = true">
                                <span>不良项</span>
                                <div class="bg_list_item_num_item_sr">
                                    <span>设置 ></span>
                                </div>
                            </div>
                        </div>
                    </van-swipe-cell> -->
                <!-- </template>
                <template v-else>
                    <div class="kong">
                        <span>暂无数据</span>
                    </div>
                </template> -->
                    <div class="bg_list_item_num">
                        <div class="bg_list_item_num_item">
                            <span>不良数</span>
                            <div class="bg_list_item_num_item_sr">
                                <input type="number" v-model="from.undesirable" @input="changeNum(2)" placeholder="请输入" />
                                <span>块</span>
                            </div>
                        </div>
                    </div>
                    <div class="bg_list_item_num" v-if="from.undesirable > 0">
                        <div class="bg_list_item_num_item" @click="show = true">
                            <span><b>*</b>不良项</span>
                            <div class="bg_list_item_num_item_sr">
                                <span class="wulll" :style="{color: from.defectiveName ? '#305ED5' : ''}">{{from.defectiveName ? from.defectiveName : '设置'}}</span>
                                <img src="@/assets/icon/ic_ar@2x.png" alt="" />
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <!-- <div class="bg_list_item">
            <div class="bg_plan" @click="TimeShow = true">
                <div class="bg_plan_label">
                    <span><b>*</b>报工时长</span>
                </div>
                <div class="bg_plan_label_val">
                    <span :style="{color: from.durationName ? '#333' : ''}">{{from.durationName ? from.durationName : '请选择'}}</span>
                    <img src="@/assets/icon/ic_ar@2x.png" alt="" />
                </div>
            </div>
            <div class="bg_list_item" v-if="infoBox">
                <div class="bg_list_item_top">
                    <div class="bg_list_item_top_left">
                        <div class="bg_list_item_top_left_x"></div>
                        <span>合格产出明细</span>
                        <span class="blue left">{{ccTotal()}}</span>
                    </div>
                    <div class="bg_list_item_top_right" @click="jumpCC" v-if="proxy.$auth('h5:workorderoutput:create')">
                        <img src="@/assets/icon/gongdan_ic_shoudong@2x.png" alt="" />
                        <span>手动录入</span>
                        <span>工资绩效</span>
                    </div>
                </div>
                <template v-if="produceData && produceData.length > 0">
                    <van-swipe-cell v-for="(item, index) in produceData" :key="index">
                        <div class="bg_list_item_num">
                            <div class="bg_list_item_num_item">
                                <span>{{item.code}}</span>
                                <div class="bg_list_item_num_item_sr">
                                    <input v-model="item.num" :disabled="!proxy.$auth('h5:workorderoutput:update')" @blur="change(item.id, item.num, 'C', item.maxNum, item)" type="number" />
                                    <span>{{item.company}}</span>
                                </div>
                <div class="bg_list_item_h">
                    <div class="bg_list_item_num">
                        <div class="bg_list_item_num_item">
                            <span>计件方式</span>
                            <div class="bg_list_item_num_item_list">
                                <div class="bg_list_item_num_item_list_item active" v-if="infoBox.type == 0">计件</div>
                                <div class="bg_list_item_num_item_list_item active" v-if="infoBox.type == 1">计时</div>
                            </div>
                        </div>
                        <template #right v-if="proxy.$auth('h5:workorderoutput:delete')">
                            <van-button style="height: 100%;" square text="删除" @click="deleItem(item.id, 'C')" type="danger" />
                        </template>
                    </van-swipe-cell>
                </template>
                <template v-else>
                    <div class="kong">
                        <span>暂无数据</span>
                    </div>
                </template>
            </div>
            <div class="bg_list_item">
                <div class="bg_list_item_top">
                    <div class="bg_list_item_top_left">
                        <div class="warning"></div>
                        <span>不良产出明细</span>
                        <span class="yellow left">{{blTotal()}}</span>
                    </div>
                </div>
                <template v-if="undesirable && undesirable.length > 0">
                    <van-swipe-cell v-for="(item, index) in undesirable" :key="index">
                        <div class="bg_list_item_num">
                            <div class="bg_list_item_num_item">
                                <span>{{item.code}}</span>
                                <div class="bg_list_item_num_item_sr">
                                    <input v-model="item.num" :disabled="!proxy.$auth('h5:workorderoutput:update')" @blur="change(item.id, item.num, 'C', item.maxNum, item)" type="number" />
                                    <span>{{item.company}}</span>
                                </div>
                    <div class="bg_list_item_num">
                        <div class="bg_list_item_num_item">
                            <span>工资单价</span>
                            <div class="bg_list_item_num_item_sr">
                                <span class="color1">{{infoBox.salary}}元/{{infoBox.type == 0 ? 'ä»¶' : '时'}}</span>
                            </div>
                        </div>
                        <template #right v-if="proxy.$auth('h5:workorderoutput:delete')">
                            <van-button style="height: 100%;" square text="删除" @click="deleItem(item.id, 'C')" type="danger" />
                        </template>
                    </van-swipe-cell>
                </template>
                <template v-else>
                    <div class="kong">
                        <span>暂无数据</span>
                    </div>
                </template>
            </div>
            <div class="bg_list_item">
                <div class="bg_list_item_top">
                    <div class="bg_list_item_top_left">
                        <div class="error"></div>
                        <span>报废产出明细</span>
                        <span class="red left">{{bfTotal()}}</span>
                    </div>
                </div>
                <template v-if="scrap && scrap.length > 0">
                    <van-swipe-cell v-for="(item, index) in scrap" :key="index">
                        <div class="bg_list_item_num">
                            <div class="bg_list_item_num_item">
                                <span>{{item.code}}</span>
                                <div class="bg_list_item_num_item_sr">
                                    <input v-model="item.num" :disabled="!proxy.$auth('h5:workorderoutput:update')" @blur="change(item.id, item.num, 'C', item.maxNum, item)" type="number" />
                                    <span>{{item.company}}</span>
                                </div>
                    <div class="bg_list_item_num">
                        <div class="bg_list_item_num_item">
                            <span>预计工资</span>
                            <div class="bg_list_item_num_item_sr">
                                <span class="color1">{{expectedSalary}}元</span>
                            </div>
                        </div>
                        <template #right v-if="proxy.$auth('h5:workorderoutput:delete')">
                            <van-button style="height: 100%;" square text="删除" @click="deleItem(item.id, 'C')" type="danger" />
                        </template>
                    </van-swipe-cell>
                </template>
                <template v-else>
                    <div class="kong">
                        <span>暂无数据</span>
                    </div>
                </template>
            </div> -->
        </div>
        <div class="details_dj">
            <div class="details_dj_title">
                <div class="details_dj_title_left">
                    <div class="details_x"></div>
                    <span>生产点检</span>
                </div>
                <div class="details_dj_title_right" @click="jumpdj" v-if="proxy.$auth('h5:workorder:processRecord')">
                    <img src="@/assets/icon/gongdan_ic_shoudong@2x.png" alt="" />
                    <span>手动录入</span>
                </div>
            </div>
            <div class="details_dj_list">
                <van-list
                    v-model:loading="loading"
                    :finished="finished"
                    finished-text="没有更多了~"
                    @load="pageDJs">
                    <van-swipe-cell v-for="(item, index) in djData" :key="index">
                        <div class="details_dj_list_item">
                            <span>{{item.attrName}}:{{item.val}}</span>
                            <span>{{item.userName}} {{item.createTime}}</span>
                    <div class="bg_list_item_num">
                        <div class="bg_list_item_num_item">
                            <span>达标率</span>
                            <div class="bg_list_item_num_item_sr">
                                <span class="color1">{{complianceRate}}%</span>
                            </div>
                        </div>
                        <template #right>
                            <van-button square type="danger" style="height: 100%;" @click="dele(item.id)" text="删除" />
                        </template>
                    </van-swipe-cell>
                </van-list>
                    </div>
                </div>
            </div>
        </div>
        <!--  æŠ¥å·¥æŒ‰é’®  -->
        <template v-if="info.status === 2 || info.procedureNeedcheck === 1">
            <div class="bh_zw"></div>
            <div class="bg_footer">
                <div class="bg_footer_submit" @click="submit">确认报工</div>
            </div>
        </template>
        <!--  æ‰«ç ç»„ä»¶  -->
        <v-ScanCode
            :openCode="openCode"
            :infos="['请扫描工装码']"
            @closePopup="closePopup"
            @onDecode="onDecode" />
        <!--  æŠ¥å·¥ç»Ÿè®¡æ•°æ®  -->
        <van-popup v-model:show="statistics" round :closeable="true" position="bottom" :style="{ height: '53%' }">
            <div class="tg">
                <div class="tg_header">请确认报工信息</div>
                <div class="tg_table">
                    <div class="tg_table_header">
                        <div class="tg_table_header_item">类型</div>
                        <div class="tg_table_header_item">物料名称</div>
                        <!-- <div class="tg_table_header_item">工装数量</div> -->
                        <div class="tg_table_header_item">物料数量</div>
                    </div>
                    <div class="nr" v-if="statisticsData.length > 0">
                        <div class="tg_table_nr" v-for="(item, index) in statisticsData" :key="index">
                            <div class="tg_table_nr_item">{{item.name}}</div>
                            <div class="tg_table_nr_item">{{item.materialName}}</div>
                            <!-- <div class="tg_table_nr_item">{{item.gznum}}</div> -->
                            <div class="tg_table_nr_item" :style="item.name === '工单未投料' ? 'color: #DE5243' : ''">{{item.num}}</div>
                        </div>
                    </div>
                    <div class="nr" v-else>
                        <div class="tg_table_nr">
                            <div class="tg_table_nr_item1">暂无数据</div>
                        </div>
                    </div>
                </div>
                <div class="tg_footer">
                    <button class="tg_footer_qr" @click="submitBG" v-if="proxy.$auth('h5:workorderoutput:confirm') && isSubmit">确认报工</button>
                    <div class="tg_footer_fh" @click="gofh" v-else-if="!isSubmit">返回修改</div>
                </div>
            </div>
        </van-popup>
        <div class="bh_zw"></div>
        <div class="bg_footer">
            <div class="bg_footer_submit1">继续报工</div>
            <div class="bg_footer_submit" @click="submit">提交</div>
        </div>
        <!-- é€‰æ‹©ä¸è‰¯é¡¹ -->
        <van-popup v-model:show="show" round position="bottom" :style="{ height: '53%' }">
            <div class="bl">
                <div class="bl_head">
                    <span @click="show = false">取消</span>
                    <img src="@/assets/icon/ic_close@2x.png" style="opacity: 0;" alt="" />
                    <span>不良项</span>
                    <span>确认</span>
                    <!-- <span>确认</span> -->
                    <img src="@/assets/icon/ic_close@2x.png" @click="show = false" alt="" />
                </div>
                <div class="bl_list">
                    <div class="bl_list_item" v-for="(item, i) in 12" :key="i">
                    <div class="bl_list_item" v-for="(item, i) in cateList" :key="i" @click="changeChecked(i)">
                        <div class="bl_list_item_left">
                            <input type="checkbox" :checked="true" name="" id="" />
                            <span>有划痕</span>
                            <input type="checkbox" :checked="item.active" />
                            <span>{{ item.name }}</span>
                        </div>
                        <div class="bl_list_item_right">
                            <input type="number" placeholder="请输入" />
                            <input type="number" @click.stop v-model="item.num" placeholder="0" />
                        </div>
                    </div>
                </div>
                <div class="bl_footer" @click="onConfirm3">确认</div>
            </div>
        </van-popup>
        <!--  å…¥åº“物料  -->
        <MaterialY :show="show1" :plansId="String(plansId)" :ids="ids" :deviceId="String(deviceId)" @close="close" @value="getValue" />
        <!-- è®¾å¤‡ -->
        <van-popup v-model:show="deviceShow" round position="bottom" :style="{ height: '50%' }">
            <van-picker
                :columns="deviceList"
                @confirm="onConfirm"
                @cancel="onCancel"
                :columns-field-names="customFieldName"
            />
        </van-popup>
        <!-- äººå‘˜ -->
        <user :show="userShow" @close="onCancel1" @value="onConfirm1" />
        <!-- æ—¶é—´ -->
        <van-popup v-model:show="TimeShow" round position="bottom" :style="{ height: '50%' }">
            <van-datetime-picker
                v-model="from.time"
                type="time"
                title="选择时间"
                @confirm="onConfirm2"
                @cancel="onCancel2"
            />
        </van-popup>
    </div>
</template>
<script setup lang="ts">
    import { getCurrentInstance, nextTick, onMounted, ref, reactive } from 'vue'
    import { useRouter, useRoute } from "vue-router"
    import { Dialog, Toast } from 'vant'
    import { REGULAR } from '@/utils/utils'
    import {
        getBarcodeContent,
        queryById,
        getOrocessRecord,
        deleteCT,
        updateById,
        comfirmDone,
        comfirmDoneStandard,
        getListByCondition,
        allForStandard,
        pageDJ,
        deletedj,
        dealWorkorderRecordStandard,
        getWorkorderRecordListStandard
    } from '@/apis/WorkOrderAPI'
    import { QRCodeType } from '@/enum'
    const { proxy }: any = getCurrentInstance()
    import VWorkOrderInfo from '@/components/common/WorkOrderInfo.vue'
    import { onMounted, ref, reactive, getCurrentInstance, computed } from 'vue'
    import { useRouter } from 'vue-router'
    import { getDeviceByCondition, getFindAll, queryOne, autoWorkReport, getIdPlansExt, categoryExtList } from '@/apis/PlanningAPI'
    import MaterialY from '@/components/newCom/MaterialY.vue'
    import user from '@/components/newCom/user.vue'
    import { Toast } from 'vant'
    const {$Bus} = getCurrentInstance().appContext.config.globalProperties
    const router = useRouter()
    const route = useRoute()
    const loading = ref(false);
    const finished = ref(false);
    let show = ref(false)
    // ç‚¹æ£€æ•°æ®
    let djData: any = ref([])
    // åˆ†é¡µæŸ¥è¯¢æ•°æ®
    let page = reactive({
        capacity: 10,
        page: 0
    let show1 = ref(false)
    let TimeShow = ref(false)
    let deviceId = ref('')
    let plansId = ref('')
    let ids = ref('')
    let total: any = ref('')    // å¯æŠ•数量
    let from: any = reactive({
        processPlan: null,
        deviceId: '',
        deviceName: '',
        userId: '',
        userName: '',
        qualified: '',  // è‰¯å“æ•°
        undesirable: '', // ä¸è‰¯æ•°
        duration: '',
        durationName: '',
        time: '',
        defective: [],
        defectiveName: ''
    })
    // äº§å‡ºåˆæ ¼/不良
    let produceFrom = reactive({
        qualifiedId: '',
        qualified: '',  // åˆæ ¼
        undesirableId: '',
        undesirable: '' // ä¸è‰¯
    })
    let infoBox: any = ref(null)     // å·¥èµ„绩效
    // è¯¦æƒ…数据
    const info: any = ref({})
    let bomType: any = ref('')
    let hasBom: any = ref('')
    let deviceShow = ref(false)
    let deviceList = ref([])
    let cateList:any = ref([])
    const customFieldName = {
        text: 'name'
    };
    let userShow = ref(false)
    let userList = ref([])
    let wuList: any = ref([])
    // åˆ¤æ–­æ˜¯å¦èƒ½æäº¤
    let isSubmit: any = ref<boolean>(false)
    // ä¸è‰¯æ˜Žç»†
    let undesirable: any = ref([])
    // æŠ¥åºŸæ˜Žç»†
    let scrap: any = ref([])
    // æ‰«ç ç±»åž‹
    let type: any = ref('')
    // ç»Ÿè®¡æ•°æ®
    let statisticsData: any = ref([
        // {
        //     name: '工单投料',
        //     materialName: '黄沙',
        //     num: 0
        // },
        // {
        //     name: '工单合格产出',
        //     materialName: '黄沙',
        //     num: 0
        // },
        // {
        //     name: '工单不良产出',
        //     materialName: '黄沙',
        //     num: 0
        // },
        // {
        //     name: '工单未投料',
        //     materialName: '黄沙',
        //     num: 0
        // }
    ])
    // æŠ•料数据
    const feedingData: any = ref([])
    // äº§å‡ºæ•°æ®
    const produceData: any = ref([])
    // æŽ§åˆ¶æ‰«ç æ˜¾ç¤ºéšè—
    const openCode = ref<boolean>(false)
    // æŽ§åˆ¶æŠ¥å·¥ç»Ÿè®¡
    const statistics = ref<boolean>(false)
    // æŠ•料统计
    const tlTotal = (): string => {
        if (feedingData.value.length > 0) {
            let total: number = 0
            feedingData.value.forEach((element: any) => {
                total = total + element.num
            })
            return `${total}`
    // äº§å‡ºæ•°é‡éªŒè¯
    const changeNum = (type: number) => {
        let num = total.value - (Number(from.qualified) + Number(from.undesirable))
        if (type == 2) {
            from.defective = []
            from.defectiveName = ''
        }
        return ''
    }
    // ä¿®æ”¹äº§å‡º
    const changeCC = (downType: string, num: number, recordId: string) => {
        if (!num) return
        console.log(produceFrom.qualified + produceFrom.undesirable)
        if ((produceFrom.qualified + produceFrom.undesirable) > info.value.planNum) {
            return Toast.fail({ message: '产出数量不能大于计划数量', duration: 2000 })
        }
        if (num >= 0) {
            dealWorkorderRecordStandard({
                downType, num, recordId, workorderId: route.query.id
            }).then(res => {
                if (res.code === 200) {
                    getOrocessRecordCC()
                }
            })
        } else {
            if (downType == 0) {
                produceFrom.qualified = 0
        if (num < 0) {
            Toast('产出数量不能大于可产出数量!')
            if (type == 1) {
                from.qualified = ''
            } else {
                produceFrom.undesirable = 0
                from.undesirable = ''
            }
            Toast.fail({ message: '产出数量不能小于0', duration: 2000 })
        }
    }
    // è·³è½¬ç‚¹æ£€
    const jumpdj = () => {
        router.push({ name: 'spotCheck', query: { id: route.query.id } })
    }
    // åˆ é™¤ç‚¹æ£€
    const dele = (id: string | number): void => {
        deletedj(id)
            .then(res => {
                if (res.code === 200) {
                    djData.value = []
                    finished.value = false
                    page.page = 0
                    pageDJs()
                }
            })
    }
    // ç‚¹æ£€æ•°æ®
    const pageDJs = () => {
        if (!finished.value) {
            page.page = page.page + 1
            loading.value = true
            pageDJ({
                capacity: page.capacity,
                page: page.page,
                model: {
                    workorderId: route.query.id
                }
            }).then(res => {
                if (res.code === 200 && res.data && res.data.records.length !== 0) {
                    djData.value.push(...res.data.records)
                } else {
                    finished.value = true
                }
                loading.value = false
            }).catch(err => {
                loading.value = false
                finished.value = true
            })
    // éªŒè¯ç‰©æ–™æ•°é‡
    const inputwl = (i: number) => {
        if (wuList.value[i].num > wuList.value[i].total) {
            wuList.value[i].num = ''
            Toast('投料数量不能大于库存数量')
        }
    }
    // ç»Ÿè®¡
    const ccTotal = (): string => {
        if (produceData.value.length > 0) {
            let total: number = 0
            produceData.value.forEach((element: any) => {
                total = total + element.num
            })
            return `${total}${produceData.value[0].company}`
        }
        return ''
    const changeChecked = (i: number) => {
        cateList.value[i].active = !cateList.value[i].active
    }
    // ç»Ÿè®¡
    const blTotal = (): string => {
        if (undesirable.value.length > 0) {
            let total: number = 0
            undesirable.value.forEach((element: any) => {
                total = total + element.num
            })
            return `${total}${undesirable.value[0].company}`
        }
        return ''
    }
    // ç»Ÿè®¡
    const bfTotal = (): string => {
        if (scrap.value.length > 0) {
            let total: number = 0
            scrap.value.forEach((element: any) => {
                total = total + element.num
            })
            return `${total}${scrap.value[0].company}`
        }
        return ''
    }
    // åˆ é™¤äº§å‡º/投料
    const deleItem = (id: any, type: string) => {
        Dialog.confirm({
            title: '提示',
            message: '确定删除此条记录吗?',
        }).then(() => {
            deleteCT(id)
                .then(res => {
                    if (res.code === 200 && type === 'C') {
                        getOrocessRecordCC()
                    } else if (res.code === 200 && type === 'T') {
                        getOrocessRecords()
                    }
                })
        }).catch(() => {
            // on cancel
    const onConfirm3 = () => {
        let isOpen = false
        cateList.value.forEach((item: any, index: number) => {
            if (item.active) {
                isOpen = true
            }
        })
    }
    // è·³è½¬æ‰‹åŠ¨äº§å‡º
    const jumpCC = () => {
        router.push({ name: 'manualOutput', query: { id: route.query.id, num: produceData.value.length > 0 ? produceData.value[0].num : '' } })
    }
    // è·³è½¬æ‰‹åŠ¨æŠ•æ–™
    const jumpTL = () => {
        router.push({ name: 'manualFeeding', query: { id: route.query.id } })
    }
    // å…³é—­æ‰«ç ç»„ä»¶
    const closePopup = (): void => {
        openCode.value = false
    }
    // èŽ·å–æ‰«ç å€¼
    const onDecode = (data: string[]): void => {
        getBarcodeContent({
            barcode: data[0]
        }).then(res => {
            if (res.code === 200) {
                if (res.data.barcodeType === QRCodeType.GZ) {
                    if (type.value === 'tl') {    // æŠ•料操作
                        getListByCondition({ id: res.data.id })
                            .then(gz => {
                                if (gz.code === 200) {
                                    if (gz.data[0].status !== 1) {
                                        router.push({ name: 'codeScanningFeeding', query: { id: route.query.id, gzId: res.data.id } })
                                    } else {
                                        Toast.fail({ message: '扫描的工装状态不能为空', duration: 2000 })
                                    }
                                }
                            })
                    }
                    if (type.value === 'cc') {    // äº§å‡ºæ“ä½œ
                        router.push({ name: 'codeScanningOutput', query: { id: route.query.id, gzId: res.data.id } })
                    }
                } else {
                    Toast({ message: '请扫描正确的篮筐码', duration: 2000 })
        if (!isOpen) return Toast('请选择不良项')
        let arr: any = []
        let total: any = 0
        let name: any = ''
        cateList.value.forEach((item: any, index: number) => {
            if (item.active) {
                if (item.num <= 0) {
                    return Toast('不良数量必须大于0')
                }
                total = total += item.num
                arr.push(item)
                name += item.name + item.num + ';'
            }
        })
        nextTick(() => {
            openCode.value = false
        })
        if (total !== from.undesirable) return Toast('不良数必须等于产出不良数')
        from.defective = arr
        from.defectiveName = name
        show.value = false
    }
    // è·³è½¬æ‰‹åŠ¨æŠ•æ–™
    const jump = () => {
        router.push({ name: 'manualFeeding', query: { id: route.query.id } })
    }
    // è·³è½¬æ‰«ç æŠ•æ–™
    const jump1 = (types: string) => {
        type.value = types
        openCode.value = true
    }
    // æŸ¥è¯¢å·¥å•详情
    const queryByIds = () => {
        queryById(route.query.id).then(res => {
            if (res.code === 200) {
                info.value = res.data
            }
        })
    }
    // æŸ¥è¯¢å·¥å•生产记录---投料
    const getOrocessRecords = () => {
        feedingData.value = []
        allForStandard({
            workorderId: route.query.id,
            type: 0
        }).then(res => {
            if (res.code === 200) {
                feedingData.value = res.data
                // res.data.forEach((item: any) => {
                //     feedingData.value.push({ id: item.id, company: item.umodel.name, gz: item.amodel.code, name: item.mmodel.name, code: item.amodel.code + ' - ' + item.mmodel.name, num: item.num, ynum: item.num, maxNum: item.amodel.num })
                // })
            }
        })
    }
    // æŸ¥è¯¢å·¥å•生产记录---产出
    const getOrocessRecordCC = () => {
        produceData.value = []
        undesirable.value = []
        scrap.value = []
        getWorkorderRecordListStandard({
            workorderId: route.query.id
        }).then(res => {
            if (res.code === 200) {
                if (res.data.length > 0) {
                    res.data.forEach((item: any) => {
                        if (item.doneType === 1) {
                            produceFrom.undesirable = item.num
                            produceFrom.undesirableId = item.id
                        } else {
                            produceFrom.qualified = item.num
                            produceFrom.qualifiedId = item.id
                        }
                    })
                }
                // res.data.forEach((item: any) => {
                //     if (item.doneType === 0 || !item.doneType) { // åˆæ ¼ | æ··åˆ
                //         produceData.value.push({ id: item.id, company: item.umodel.name, name: item.mmodel.name, code: item.amodel.code + ' - ' + item.mmodel.name, num: item.num, ynum: item.num, maxNum: item.amodel.num })
                //     } else if (item.doneType === 1) { // ä¸è‰¯
                //         undesirable.value.push({ id: item.id, company: item.umodel.name, name: item.mmodel.name, code: item.amodel.code + ' - ' + item.mmodel.name, num: item.num, ynum: item.num, maxNum: item.amodel.num })
                //     } else if (item.doneType === 2) { // æŠ¥åºŸ
                //         scrap.value.push({ id: item.id, company: item.umodel.name, name: item.mmodel.name, code: item.amodel.code + ' - ' + item.mmodel.name, num: item.num, ynum: item.num, maxNum: item.amodel.num })
                //     }
                // })
            }
        })
    }
    // ç¼–辑投料/产出
    const change = (id: any, num: any, type: any, maxNum: number, item: object, unitAttribute: number): void => {
        let obj: any = item
        if (type === 'T') {
            if (unitAttribute == 0 && num != '') {
                if(!REGULAR.positiveInteger.test(num)){
                    obj.num = obj.ynum
                    Toast({ message: '只能输入正整数' })
                    return
                }
            }
            if (unitAttribute == 1 && num != '') {
                if(!REGULAR.number.test(num)){
                    Toast({ message: '只能输入正整数或小数(最多四位)' })
                    obj.num = obj.ynum
                    return
                }
            }
            if (num > maxNum) {
                obj.num = obj.ynum
                Toast.fail({ message: '超出工装总数' })
                return
            }
        } else if (type === 'C' && num > info.value.planNum) {
            obj.num = obj.ynum
            Toast.fail({ message: '产出数量不能超过计划数量' })
            return
        }
        updateById({ id: id, num: num }).then(res => {
            if (res.code === 200 && type === 'T') {
                getOrocessRecords()
            } else if (res.code === 200 && type === 'C') {
                getOrocessRecordCC()
            }
        })
    }
    // ç¡®è®¤æŠ¥å·¥
    const submit = () => {
        if (info.value.bomType === 1) {  // æ‹‰å¼
            console.log('拉式')
            statisticsData.value = []
            if (info.value.hasBom === 0) {
                console.log('无bom')
                // let data: any = [
                //     { name: '工单投料', gznum: feedingData.value.length, wlmc: feedingData.value.length > 0 ? feedingData.value[0].name : '', wlnum: 0 },
                //     { name: '工单合格产出', gznum: produceData.value.length, wlmc: produceData.value.length > 0 ? produceData.value[0].name : '', wlnum: 0 },
                //     { name: '工单不良产出', gznum: 0, wlmc: '', wlnum: 0 },
                //     { name: '工单未投料', gznum: '', wlmc: feedingData.value.length > 0 ? feedingData.value[0].name : '', wlnum: 0 }
                // ]
                // if (undesirable.value.length > 0) {   // åˆ¤æ–­æœ‰æ²¡æœ‰ä¸è‰¯
                //     data[2].wlmc = undesirable.value[0].name
                //     data[2].gznum = data[2].gznum + undesirable.value.length
                // }
                // if (scrap.value.length > 0) {   // åˆ¤æ–­æœ‰æ²¡æœ‰ä¸è‰¯
                //     data[2].wlmc = scrap.value[0].name
                //     data[2].gznum = data[2].gznum + scrap.value.length
                // }
                // let tl: number = 0
                // let cc: number = 0
                // let bl: number = 0
                // undesirable.value.forEach((item: any) => {  // ä¸è‰¯
                //     bl = bl + item.num
                // })
                // scrap.value.forEach((item: any) => {  // æŠ¥åºŸ
                //     bl = bl + item.num
                // })
                // if (produceData.value.length > 0) {   // åˆ¤æ–­æœ‰æ²¡æœ‰åˆæ ¼äº§å‡º
                //     produceData.value.forEach((item: any) => {  // äº§å‡º
                //         cc = cc + item.num
                //     })
                // }
                // feedingData.value.forEach((item: any) => {  // æŠ•æ–™
                //     tl = tl + item.num
                // })
                // data[0].wlnum = tl.toString() + info.value.umodel.name
                // if (produceData.value.length > 0) {
                //     data[1].wlnum = cc.toString() + info.value.umodel.name
                // }
                // data[2].wlnum = bl.toString() + info.value.umodel.name
                // let total: number = info.value.planNum - (Number(cc) + Number(bl))
                // data[data.length - 1].wlnum = (info.value.planNum - Number(cc) - Number(bl)).toString() + info.value.umodel.name
                // if (total === 0) {
                //     isSubmit.value = true
                // } else {
                //     isSubmit.value = false
                // }
                let arr: any = []
                let tl = 0
                let res = getGroupNum(feedingData.value)
                for (let i in res) {
                    let num = 0
                    res[i].forEach((item: any) => {
                        num += item.num
                    })
                    arr.push({ name: '工单投料', materialName: i + res[i][0].procedureName, num: num })
                }
                feedingData.value.forEach((item: any) => {
                    tl += item.num
                })
                statisticsData.value = [...statisticsData.value, ...arr]
                statisticsData.value.push({ name: '工单合格产出', materialName:  info.value.mmodel.name + '-' + info.value.procedureName, num: produceFrom.qualified })
                statisticsData.value.push({ name: '工单不良产出', materialName:  info.value.mmodel.name + '-' + info.value.procedureName, num: produceFrom.undesirable })
                statisticsData.value.push({ name: '工单未投料', materialName: '', num: info.value.planNum - Number(produceFrom.qualified) - Number(produceFrom.undesirable) })
                let total: number = info.value.planNum - (Number(produceFrom.qualified) + Number(produceFrom.undesirable))
                if (total === 0) {
                    isSubmit.value = true
                } else {
                    isSubmit.value = false
                }
                // if (Number(tl) <= info.value.planNum) {
                //   let total: number = Number(tl) - Number(cc) - Number(bl)  // æ˜¯å¦æœ‰ä½™
                //   data[data.length - 1].wlnum = (Number(tl) - Number(cc) - Number(bl)).toString() + info.value.umodel.name
                //   if (total === 0) {
                //     isSubmit.value = true
                //   } else {
                //     isSubmit.value = false
                //   }
                // } else {
                //   isSubmit.value = false
                // }
                // statisticsData.value = data
            } else if (info.value.hasBom === 1) {  // æœ‰bom情况
                console.log('有bom')
                // let cc: number = 0
                // let bl: number = 0
                // let newData: any = {}
                // if (feedingData.value.length > 0) {  // æŠ•æ–™
                //     feedingData.value.forEach((e: any) => {
                //         if (Object.keys(newData).indexOf('' + e.name) === -1) {
                //             newData[e.name] = []
                //         }
                //         newData[e.name].push(e)
                //     })
                //     for (let key in newData) {
                //         let obj = { name: '工单投料', gznum: newData[key].length, wlmc: key, wlnum: 0, num: 0 }
                //         newData[key].forEach((item: any) => {
                //             obj.wlnum = obj.wlnum + item.num
                //             obj.num = item.num
                //         })
                //         obj.wlnum = obj.wlnum.toString() + newData[key][0].company as never
                //         statisticsData.value.push(obj)
                //     }
                // }
                // if (produceData.value.length > 0) {  // äº§å‡º
                //     produceData.value.forEach((item: any) => {
                //         cc = cc + item.num
                //     })
                //     statisticsData.value.push({ name: '工单合格产出', gznum: produceData.value.length, wlmc: info.value.mmodel.name, wlnum: cc + info.value.umodel.name, num: cc })
                // }
                // if (undesirable.value.length > 0 || scrap.value.length > 0) {  // ä¸è‰¯/报废
                //     undesirable.value.forEach((item: any) => {
                //         bl = bl + item.num
                //     })
                //     scrap.value.forEach((item: any) => {
                //         bl = bl + item.num
                //     })
                //     statisticsData.value.push({ name: '工单不良产出', gznum: undesirable.value.length + scrap.value.length, wlmc: info.value.mmodel.name, wlnum: bl + info.value.umodel.name, num: bl })
                // }
                // let totaltl: number = 0
                // let totalcc: number = 0
                // let totalbl: number = 0
                // statisticsData.value.forEach((item: any) => {
                //     if (item.name === '工单投料') {
                //         totaltl = totaltl + item.num
                //     } else if (item.name === '工单合格产出') {
                //         totalcc = totalcc + item.num
                //     } else if (item.name === '工单不良产出') {
                //         totalbl = totalbl + item.num
                //     }
                // })
                // isSubmit.value = totalcc + totalbl <= info.value.planNum;
                let arr: any = []
                let tl = 0
                let res = getGroupNum(feedingData.value)
                for (let i in res) {
                    let num = 0
                    res[i].forEach((item: any) => {
                        num += item.num
                    })
                    arr.push({ name: '工单投料', materialName: i, num: num })
                }
                feedingData.value.forEach((item:any) => {
                    tl += item.num
                })
                statisticsData.value = [...statisticsData.value, ...arr]
                statisticsData.value.push({ name: '工单合格产出', materialName:  info.value.mmodel.name + '-' + info.value.procedureName, num: produceFrom.qualified })
                statisticsData.value.push({ name: '工单不良产出', materialName:  info.value.mmodel.name + '-' + info.value.procedureName, num: produceFrom.undesirable })
                isSubmit.value = produceFrom.qualified + produceFrom.undesirable <= info.value.planNum;
            }
        if (!from.processPlan) return Toast('计划不能为空')
        if (!from.deviceId) return Toast('设备不能为空')
        if (!from.userId) return Toast('生产人员不能为空')
        if (hasBom.value == 1 && bomType.value == 1) {
            console.log('不需要投料')
        } else {
            console.log('推式')
            if (feedingData.value.length === 0) {
                Toast.fail({ message: '投料明细不能为空' })
                return
            }
            statisticsData.value = []
            if (info.value.hasBom === 0) {
                console.log('无bom')
                // let data: any = [
                //     { name: '工单投料', gznum: feedingData.value.length, wlmc: feedingData.value.length > 0 ? feedingData.value[0].name : '', wlnum: 0 },
                //     { name: '工单合格产出', gznum: produceData.value.length, wlmc: produceData.value.length > 0 ? produceData.value[0].name : '', wlnum: 0 },
                //     { name: '工单不良产出', gznum: 0, wlmc: '', wlnum: 0 },
                //     { name: '工单未投料', gznum: '', wlmc: feedingData.value.length > 0 ? feedingData.value[0].name : '', wlnum: 0 }
                // ]
                // if (undesirable.value.length > 0) {   // åˆ¤æ–­æœ‰æ²¡æœ‰ä¸è‰¯
                //     data[2].wlmc = undesirable.value[0].name
                //     data[2].gznum = data[2].gznum + undesirable.value.length
                // }
                // if (scrap.value.length > 0) {   // åˆ¤æ–­æœ‰æ²¡æœ‰ä¸è‰¯
                //     data[2].wlmc = scrap.value[0].name
                //     data[2].gznum = data[2].gznum + scrap.value.length
                // }
                // let tl = 0
                // let cc = 0
                // let bl = 0
                // undesirable.value.forEach((item: any) => {  // ä¸è‰¯
                //     bl = bl + item.num
                // })
                // scrap.value.forEach((item: any) => {  // æŠ¥åºŸ
                //     bl = bl + item.num
                // })
                // if (produceData.value.length > 0) {   // åˆ¤æ–­æœ‰æ²¡æœ‰åˆæ ¼äº§å‡º
                //     produceData.value.forEach((item: any) => {  // äº§å‡º
                //         cc = cc + item.num
                //     })
                // }
                // feedingData.value.forEach((item: any) => {  // æŠ•æ–™
                //     tl = tl + item.num
                // })
                // data[0].wlnum = tl.toString() + info.value.umodel.name
                // if (produceData.value.length > 0) {
                //     data[1].wlnum = cc.toString() + info.value.umodel.name
                // }
                // data[2].wlnum = bl.toString() + info.value.umodel.name
                // if (Number(tl) <= info.value.planNum) {
                //     let total: number = Number(tl) - Number(cc) - Number(bl)  // æ˜¯å¦æœ‰ä½™
                //     data[data.length - 1].wlnum = (Number(tl) - Number(cc) - Number(bl)).toString() + info.value.umodel.name
                //     if (total === 0) {
                //         isSubmit.value = true
                //     } else {
                //         isSubmit.value = false
                //     }
                // } else {
                //     isSubmit.value = false
                // }
                // statisticsData.value = data
                let arr: any = []
                let tl = 0
                let res = getGroupNum(feedingData.value)
                for (let i in res) {
                    let num = 0
                    res[i].forEach((item: any) => {
                        num += item.num
                    })
                    arr.push({ name: '工单投料', materialName: i + '-' + res[i][0].procedureName, num: num })
                }
                feedingData.value.forEach((item:any) => {
                    tl += item.num
                })
                statisticsData.value = [...statisticsData.value, ...arr]
                statisticsData.value.push({ name: '工单合格产出', materialName: info.value.mmodel.name + '-' + info.value.procedureName, num: produceFrom.qualified })
                statisticsData.value.push({ name: '工单不良产出', materialName: info.value.mmodel.name + '-' + info.value.procedureName, num: produceFrom.undesirable })
                if (Number(tl) <= info.value.planNum) {
                    let total: number = Number(tl) - Number(produceFrom.qualified) - Number(produceFrom.undesirable)  // æ˜¯å¦æœ‰ä½™
                    statisticsData.value.push({ name: '工单未投料', materialName: '', num: (Number(tl) - Number(produceFrom.qualified) - Number(produceFrom.undesirable)).toFixed(2) })
                    if (total === 0) {
                        isSubmit.value = true
                    } else {
                        isSubmit.value = false
                    }
                } else {
                    isSubmit.value = false
                }
            } else if (info.value.hasBom === 1) {  // æœ‰bom情况
                console.log('有bom')
                let arr: any = []
                let tl = 0
                let res = getGroupNum(feedingData.value)
                for (let i in res) {
                    let num = 0
                    res[i].forEach((item: any) => {
                        num += item.num
                    })
                    arr.push({ name: '工单投料', materialName: i, num: num })
                }
                feedingData.value.forEach((item:any) => {
                    tl += item.num
                })
                statisticsData.value = [...statisticsData.value, ...arr]
                statisticsData.value.push({ name: '工单合格产出', materialName: info.value.mmodel.name + '-' + info.value.procedureName, num: produceFrom.qualified })
                statisticsData.value.push({ name: '工单不良产出', materialName: info.value.mmodel.name + '-' + info.value.procedureName, num: produceFrom.undesirable })
                // isSubmit.value = produceFrom.qualified + produceFrom.undesirable <= info.value.planNum;
                isSubmit.value = true
            }
            if (!wuList.value.length === 0) return Toast('投料不能为空')
        }
        statistics.value = true
    }
    // æ ¹æ®æŸä¸ªå­—段进行分组
    const getGroupNum = (arr: any) => {
        let newArry: any = {};
        for (let i = 0; i < arr.length; i++) {
            if (newArry[arr[i].materialName]) {
                newArry[arr[i].materialName].push(arr[i])
            } else {
                newArry[arr[i].materialName] = [arr[i]]
            }
        if (!from.qualified) return Toast('良品数不能为空')
        // æœ‰ä¸è‰¯æ•°
        if (from.undesirable > 0) {
            if (from.defective.length === 0) return Toast('不良项不能为空')
        }
        return newArry;
    }
    // è¿”回修改
    const gofh = () => {
        statistics.value = false
    }
    // ç¡®è®¤æŠ¥å·¥
    const submitBG = () => {
        comfirmDoneStandard({
            id: route.query.id
        if (!from.duration) return Toast('报工时长不能为空')
        autoWorkReport({
            createWorkorderRecordDTO: {
                duration: from.duration,
                qualifiedNum: from.qualified,
                unQualifiedNum: from.undesirable
            },
            plansId: from.processPlan.id,
            proGroupId: deviceId.value,
            proUserList: [from.userId],
            recordList: wuList.value.map((item: any) => {
                return {
                    wstockId: item.id,
                    num: item.num
                }
            }),
            createUnqualifiedDTOList: from.defective.map((item: any) => {
                return {
                    categoryId: item.id,
                    unQualifiedNum: item.num
                }
            })
        }).then(res => {
            if (res.code === 200) {
                Toast.success({ message: '报工成功', forbidClick: true, duration: 2000 })
                Toast.success({message: '报工成功!'})
                setTimeout(() => {
                    router.go(-2)
                }, 2000)
                    router.go(-1)
                }, 2000);
            }
        })
    }
    // é¢„计工资
    const expectedSalary = computed(() => {
        if (!infoBox.value) return 0
        // æŒ‰ä»¶è®¡ç®—
        if (infoBox.value.type == 0) {
            console.log('计件')
            if (!from.qualified) return 0
            if (infoBox.value.unqualified == 1) {   // æ˜¯å¦è®¡å…¥ä¸è‰¯å“
                let total = Number(from.qualified) + Number(from.undesirable)
                return total * infoBox.value.salary
            } else {
                return Number(from.qualified) * infoBox.value.salary
            }
        } else {
            console.log('计时')
            if (!from.duration) return 0;
            let h = (from.duration / 60 / 60).toFixed(2)
            return Number(h) * infoBox.value.salary
        }
    })
    // è¾¾æ ‡çއ
    const complianceRate = computed(() => {
        if (!infoBox.value) return 0;
        if (!from.qualified) return 0;
        if (!from.duration) return 0;
        // æŒ‰ä»¶è®¡ç®—
        // if (infoBox.value.type == 0) {
            // if (infoBox.value.unqualified == 1) {   // æ˜¯å¦è®¡å…¥ä¸è‰¯å“
                let a = ((Number(from.qualified) + Number(from.undesirable)) / (from.duration / 60 / 60)).toFixed(2)
                let b = (infoBox.value.num / (infoBox.value.times / 60 / 60)).toFixed(2)
                console.log(a)
                console.log(b)
                return (Number(a) / Number(b)).toFixed(2)
                // let total = (Number(from.qualified) + Number(from.undesirable)) / ((from.duration * 60 * 60) * infoBox.value.num / )
                // return total * infoBox.value.salary;
            // } else {
            //     return Number(from.qualified) * infoBox.value.salary;
            // }
        // } else {
        //     console.log('按时长')
        // }
    })
    const deleItem = (index: number) => {
        if (wuList.value.length === 1) return Toast('至少保留一项内容')
        wuList.value.splice(index, 1)
    }
    const openDev = () => {
        if (!from.processPlan) return Toast('请先选择工序生产计划')
        deviceShow.value = true
    }
    const openMaterial = () => {
        if (!plansId.value) return Toast('请先选择工序生产计划')
        if (!deviceId.value) return Toast('请先选择生产设备')
        show1.value = true
    }
    const onConfirm1 = (e: any) => {
        from.userId = e.userId
        from.userName = e.name
        userShow.value = false
    }
    const onConfirm2 = (e: string) => {
        let h = Number(e.substring(0, 2))
        let m = Number(e.substring(3, 5))
        let s = 0
        if (h > 0) {
            s += h * 60 * 60
        }
        if (m > 0) {
            s += m * 60
        }
        from.duration = s
        from.durationName = `${h}小时${m}分钟`
        TimeShow.value = false
    }
    const onCancel1 = () => {
        userShow.value = false
    }
    const onCancel2 = () => {
        TimeShow.value = false
    }
    const onConfirm = (e: any) => {
        from.deviceId = e.id
        from.deviceName = e.name
        deviceId.value = e.id
        from.userId = ''
        from.userName = ''
        // getFindAll({
        //     deviceId: e.id,
        //     planId: from.processPlan.id
        // }).then(res => {
        //     if (res.code === 200) {
        //         res.data.forEach((item: any) => {
        //             item.name = item.umodel.name + '-' + item.tmodel.name
        //         })
        //         userList.value = res.data
        //     }
        // })
        deviceShow.value = false
    }
    const onCancel = () => {
        deviceShow.value = false
    }
    const selectPlan = () => {
        router.push({ name: 'processPlans' })
    }
    const close = () => {
        show1.value = false
    }
    const getData = () => {
        categoryExtList({
            cateType: "3"
        }).then(res => {
            if (res.code === 200) {
                res.data.forEach((item: any) => {
                    item.active = false
                    item.num = ''
                })
                cateList.value = res.data
            }
        })
    }
    // é€‰æ‹©ç‰©æ–™
    const getValue = (val: any) => {
        let obj = JSON.parse(JSON.stringify(val))
        obj.total = val.num
        wuList.value.unshift(obj)
        let arr = wuList.value.map((item: any) => item.id)
        ids.value = arr.join(',')
        show1.value = false
    }
    onMounted(() => {
        pageDJs()
        queryByIds()
        getOrocessRecords()
        getOrocessRecordCC()
        getData()
        $Bus.on('callback', (res: any)=>{
            from.processPlan = res
            plansId.value = res.id
            from.deviceId = ''
            from.deviceName = ''
            deviceId.value = ''
            from.userId = ''
            from.userName = ''
            total.value = res.num - res.workorderDistributNum
            // èŽ·å–è®¾å¤‡
            getDeviceByCondition({ procedureId: res.procedureId })
                .then(res1 => {
                    if (res1.code === 200) {
                        deviceId.value = res1.data[0].id
                        from.deviceId = res1.data[0].id
                        from.deviceName = res1.data[0].name
                        deviceList.value = res1.data
                    }
                })
            // èŽ·å–ç±»åž‹
            getIdPlansExt(res.id)
                .then(res2 => {
                    if (res.code === 200) {
                        bomType.value = res2.data.bomType
                        hasBom.value = res2.data.hasBom
                    }
                })
            // èŽ·å–å·¥èµ„ç»©æ•ˆæ•°æ®
            queryOne({
                deleted: 0,
                departId: res.factoryId,
                materialId: res.materialId,
                procedureId: res.procedureId
            }).then(result => {
                if (result.code === 200) {
                    infoBox.value = result.data
                }
            })
        })
    })
</script>
<style lang="scss" scoped>
    .bg {
        width: 100%;
        /*height: 100%;*/
        position: absolute;
        background: #F7F7F7;
        .details_cz {
        .bg_plan {
            width: 100%;
            // height: 98px;
            padding: 30px;
            box-sizing: border-box;
            background: #FFFFFF;
            margin-bottom: 40px;
            display: flex;
            align-items: center;
            justify-content: space-between;
            .details_cz_sdtl {
                width: 330px;
                height: 76px;
                background: #FFFFFF;
                border-radius: 36px;
                display: flex;
                align-items: center;
                justify-content: center;
                img {
                    width: 28px;
                    height: 28px;
                    margin-right: 14px;
                }
                span {
                    font-size: 26px;
                    font-weight: 400;
                    color: #222222;
            span {
                font-size: 30px;
                font-family: PingFangSC-Regular, PingFang SC;
                font-weight: 400;
                color: #222222;
                b {
                    color: red;
                }
            }
            .details_cz_smtl {
                /*width: 330px;*/
                flex: 1;
                height: 76px;
                background: $nav-color;
                border-radius: 36px;
            .bg_plan_nr {
                display: flex;
                flex-direction: column;
                span {
                    font-size: 24px;
                    font-family: PingFangSC-Regular, PingFang SC;
                    font-weight: 400;
                    color: #666666;
                    margin-top: 20px;
                    &:first-child {
                        font-size: 32px;
                        font-family: PingFangSC-Medium, PingFang SC;
                        font-weight: 500;
                        color: #333333;
                        margin-top: 0 !important;
                    }
                }
            }
            .bg_plan_label_val {
                display: flex;
                align-items: center;
                justify-content: center;
                img {
                    width: 28px;
                    height: 28px;
                    margin-right: 14px;
                }
                span {
                    font-size: 26px;
                    font-size: 28px;
                    font-family: PingFangSC-Regular, PingFang SC;
                    font-weight: 400;
                    color: #ffffff;
                    color: #999999;
                }
                img {
                    width: 12px;
                    height: 24px;
                    margin-left: 20px;
                }
            }
        }
@@ -1039,7 +626,9 @@
            width: 100%;
            display: flex;
            flex-direction: column;
            margin-top: 30px;
            .bottomval {
                margin-bottom: 20px !important;
            }
            .bg_list_item {
                display: flex;
                flex-direction: column;
@@ -1111,172 +700,165 @@
                        }
                    }
                }
                .bg_list_item_num {
                .top {
                    margin-top: 20px !important;
                }
                .bg_list_item_h {
                    width: 100%;
                    background: white;
                    padding: 0 30px;
                    box-sizing: border-box;
                    .kong {
                        text-align: center;
                        font-size: 25px;
                        padding: 30px 0;
                        background: #ffffff;
                    }
                    .bg_list_item_num_item {
                    background: white;
                    .bg_list_item_num {
                        width: 100%;
                        min-height: 98px;
                        background: white;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                        // height: 118px;
                        padding: 15px 0;
                        box-sizing: border-box;
                        justify-content: space-between;
                        border-bottom: 1px solid #E5E5E5;
                        border-bottom: 1PX solid #E5E5E5;
                        &:last-child {
                            border: none;
                            border: none !important;
                        }
                        .bg_list_item_num_item_wl {
                            flex-shrink: 0;
                        .kong {
                            text-align: center;
                            font-size: 25px;
                            padding: 30px 0;
                            background: #ffffff;
                        }
                        .bg_list_item_num_item {
                            width: 100%;
                            height: 100%;
                            display: flex;
                            flex-direction: column;
                            span {
                                font-size: 34px;
                                color: #222222;
                            align-items: center;
                            // height: 118px;
                            padding: 15px 0;
                            box-sizing: border-box;
                            justify-content: space-between;
                            border-bottom: 1px solid #E5E5E5;
                            &:last-child {
                                border: none;
                            }
                            .bg_list_item_num_item_wl_lx {
                                margin-top: 10px;
                                span {
                                    color: #222222;
                                    font-size: 28px;
                            .bg_list_item_num_item_list {
                                display: flex;
                                align-items: center;
                                .active {
                                    background: #305ED5 !important;
                                    color: #FFFFFF !important;
                                }
                                .bg_list_item_num_item_list_item {
                                    width: 116px;
                                    height: 62px;
                                    line-height: 62px;
                                    text-align: center;
                                    background: #F2F2F2;
                                    border-radius: 8px;
                                    font-size: 26px;
                                    font-family: PingFangSC-Regular, PingFang SC;
                                    font-weight: 400;
                                    color: #333333;
                                    margin-right: 20px;
                                    &:last-child {
                                        margin: 0 !important;
                                    }
                                }
                            }
                        }
                        .warning {
                            color: $nav-stateColor5 !important;
                        }
                        .err {
                            color: $nav-stateColor4 !important;
                        }
                        span {
                            flex-shrink: 0;
                            overflow: hidden;
                            text-overflow: ellipsis;
                            white-space: nowrap;
                            .bg_list_item_num_item_wl {
                                flex-shrink: 0;
                                display: flex;
                                flex-direction: column;
                                span {
                                    font-size: 34px;
                                    color: #222222;
                                }
                                .bg_list_item_num_item_wl_lx {
                                    margin-top: 10px;
                                    span {
                                        color: #222222;
                                        font-size: 28px;
                                    }
                                }
                            }
                            .warning {
                                color: $nav-stateColor5 !important;
                                margin-right: 5px;
                            }
                            .err {
                                color: $nav-stateColor4 !important;
                                margin-right: 5px;
                            }
                            &:nth-child(1) {
                                font-size: 30px;
                                font-weight: 400;
                                color: #222222;
                            }
                            &:nth-child(2) {
                                font-size: 28px;
                                font-weight: 400;
                                color: #333333;
                                flex-shrink: 0;
                            }
                        }
                        .bg_list_item_num_item_sr {
                            flex: 1;
                            display: flex;
                            align-items: center;
                            justify-content: flex-end;
                            input::-webkit-input-placeholder {
                                font-size: 28px;
                            }
                            input {
                                text-align: right;
                                width: 180px;
                                height: 60px;
                                border-radius: 8px;
                                border: 1PX solid #E5E5E5;
                                margin-right: 20px;
                                font-size: 28px;
                                font-weight: 400;
                                color: #333333;
                                padding: 0 30px
                            img {
                                width: 12px;
                                height: 24px;
                                margin-left: 20px;
                            }
                            span {
                                font-size: 28px;
                                font-weight: 400;
                                color: #666666;
                                flex-shrink: 0;
                                overflow: hidden;
                                text-overflow: ellipsis;
                                white-space: nowrap;
                                b {
                                    font-size: 30px;
                                    color: red;
                                    margin-right: 5px;
                                }
                                .warning {
                                    color: $nav-stateColor5 !important;
                                    margin-right: 5px;
                                }
                                .err {
                                    color: $nav-stateColor4 !important;
                                    margin-right: 5px;
                                }
                                &:nth-child(1) {
                                    font-size: 30px;
                                    font-weight: 400;
                                    color: #222222;
                                }
                                &:nth-child(2) {
                                    font-size: 28px;
                                    font-weight: 400;
                                    color: #333333;
                                    flex-shrink: 0;
                                }
                            }
                        }
                    }
                }
            }
        }
        .details_dj {
            display: flex;
            flex-direction: column;
            .details_dj_title {
                width: 100%;
                display: flex;
                align-items: center;
                justify-content: space-between;
                padding: 0 30px 30px 30px;
                box-sizing: border-box;
                .details_dj_title_left {
                    display: flex;
                    align-items: center;
                    .details_x {
                        width: 8px;
                        height: 30px;
                        background: $nav-color;
                        border-radius: 2px;
                        margin-right: 12px;
                    }
                    span {
                        font-size: 32px;
                        font-weight: 500;
                        color: #222222;
                    }
                }
                .details_dj_title_right {
                    display: flex;
                    align-items: center;
                    img {
                        width: 28px;
                        height: 28px;
                        margin-right: 12px;
                    }
                    span {
                        font-size: 28px;
                        font-weight: 400;
                        color: $nav-color;
                    }
                }
            }
            .details_dj_list {
                width: 100%;
                /*padding: 30px;*/
                box-sizing: border-box;
                background: #ffffff;
                display: flex;
                flex-direction: column;
                .details_dj_list_item {
                    display: flex;
                    flex-direction: column;
                    border-bottom: 1px solid #E5E5E5;
                    padding: 30px;
                    /*margin: 30px;*/
                    /*padding-bottom: 30px;*/
                    /*margin-bottom: 30px !important;*/
                    span {
                        &:nth-child(1) {
                            font-size: 28px;
                            font-weight: 400;
                            color: #222222;
                        }
                        &:nth-child(2) {
                            font-size: 24px;
                            font-weight: 400;
                            color: #999999;
                            margin-top: 24px;
                            .bg_list_item_num_item_sr {
                                flex: 1;
                                display: flex;
                                align-items: center;
                                justify-content: flex-end;
                                .color1 {
                                    font-size: 28px;
                                    font-family: PingFangSC-Regular, PingFang SC;
                                    font-weight: 400;
                                    color: #333333;
                                }
                                input::-webkit-input-placeholder {
                                    font-size: 28px;
                                }
                                input {
                                    text-align: right;
                                    width: 180px;
                                    height: 60px;
                                    border-radius: 8px;
                                    border: 1PX solid #E5E5E5;
                                    margin-right: 20px;
                                    font-size: 28px;
                                    font-weight: 400;
                                    color: #333333;
                                    padding: 0 30px
                                }
                                .wulll {
                                    width: 400px;
                                    text-align: right;
                                    overflow: hidden;
                                    white-space: nowrap;
                                    text-overflow: ellipsis;
                                }
                                span {
                                    font-size: 28px;
                                    font-family: PingFangSC-Regular, PingFang SC;
                                    font-weight: 400;
                                    color: #999999;
                                }
                            }
                        }
                    }
                }
@@ -1290,10 +872,27 @@
            bottom: 0;
            left: 0;
            width: 100%;
            z-index: 9;
            padding: 0 30px 60px 30px;
            box-sizing: border-box;
            display: flex;
            align-items: center;
            justify-content: space-between;
            .bg_footer_submit1 {
                width: 334px;
                height: 88px;
                line-height: 88px;
                text-align: center;
                background: #FFFFFF;
                box-shadow: 0px 0px 12px 0px rgba(0,0,0,0.08);
                border-radius: 8px;
                font-size: 30px;
                font-family: PingFangSC-Medium, PingFang SC;
                font-weight: 500;
                color: #305ED5;
            }
            .bg_footer_submit {
                width: 690px;
                width: 334px;
                height: 88px;
                background: $nav-color;
                box-shadow: 0 0 12px 0 rgba(0, 0, 0, 0.08);
@@ -1304,108 +903,6 @@
                display: flex;
                align-items: center;
                justify-content: center;
            }
        }
        .tg {
            width: 100%;
            height: 100%;
            padding: 30px;
            box-sizing: border-box;
            .tg_header {
                width: 100%;
                height: 45px;
                text-align: center;
                line-height: 45px;
                font-size: 30px;
                font-weight: 500;
                color: #222222;
            }
            .tg_table {
                width: 100%;
                margin-top: 40px;
                .tg_table_header {
                    width: 100%;
                    height: 72px;
                    background: #EFF2FC;
                    display: flex;
                    align-items: center;
                    .tg_table_header_item {
                        flex: 1;
                        font-size: 26px;
                        font-weight: 500;
                        color: #333333;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                    }
                }
            }
            .nr {
                max-height: 400px;
                overflow-x: scroll;
                .tg_table_nr {
                    width: 100%;
                    padding: 24px 10px;
                    box-sizing: border-box;
                    display: flex;
                    align-items: center;
                    background: white;
                    box-shadow: inset 0px -2px 0px 0px #E5E5E5;
                    .tg_table_nr_item {
                        flex: 1;
                        font-size: 26px;
                        font-weight: 500;
                        color: #333333;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                    }
                    .tg_table_nr_item1 {
                        flex: 1;
                        font-size: 26px;
                        font-weight: 500;
                        color: #333333;
                        display: flex;
                        align-items: center;
                        justify-content: center;
                    }
                }
            }
        }
        .tg_footer {
            width: calc(100% - 60px);
            position: fixed;
            bottom: 0;
            display: flex;
            justify-content: space-between;
            align-items: center;
            box-sizing: border-box;
            padding-bottom: 40px;
            .tg_footer_fh {
                width: 100%;
                height: 88px;
                display: flex;
                align-items: center;
                justify-content: center;
                background: rgba(66, 117, 252, 0.05);
                border-radius: 8px;
                border: 1PX solid #4275FC;
                font-size: 32px;
                font-weight: 500;
                color: $nav-color;
            }
            .tg_footer_qr {
                width: 100%;
                height: 88px;
                border: none;
                display: flex;
                align-items: center;
                justify-content: center;
                background: $nav-color;
                border-radius: 8px;
                font-size: 32px;
                font-weight: 500;
                color: #FFFFFF;
            }
        }
        .bl {
@@ -1425,21 +922,38 @@
                        font-size: 32px !important;
                    }
                }
                img {
                    width: 28px;
                    height: 28px;
                }
            }
            .bl_footer {
                width: 100%;
                height: 88px;
                line-height: 88px;
                text-align: center;
                background: #305ED5;
                border-radius: 8px;
                font-size: 32px;
                font-family: PingFangSC-Medium, PingFang SC;
                font-weight: 500;
                color: #FFFFFF;
                margin-top: 30px;
            }
            .bl_list {
                width: 100%;
                height: 580px;
                height: 550px;
                overflow-y: scroll;
                margin-top: 30px;
                .bl_list_item {
                    width: 100%;
                    height: 60px;
                    height: 96px;
                    display: flex;
                    align-items: center;
                    justify-content: space-between;
                    margin-bottom: 20px;
                    border-bottom: 1PX solid #E5E5E5;
                    &:last-child {
                        margin-bottom: 0 !important;
                        border: none !important;
                    }
                    .bl_list_item_left {
                        flex: 1;
@@ -1448,6 +962,7 @@
                        input {
                            width: 30px;
                            height: 30px;
                            border: 1PX solid #CCCCCC;
                            margin: 0 !important;
                        }
                        span {
@@ -1464,9 +979,19 @@
                            padding-left: 5px;
                            width: 160px;
                            height: 100%;
                            padding: 0 30px;
                            box-sizing: border-box;
                            text-align: right;
                            font-size: 28px;
                            color: #333333;
                            border-radius: 10px;
                            border: 2px solid #999999
                            border: 1PX solid #CCCCCC;
                            &::-webkit-input-placeholder {
                                font-size: 28px;
                                font-family: PingFangSC-Regular, PingFang SC;
                                font-weight: 400;
                                color: #999999;
                            }
                        }
                    }
                }
h5_standard/src/views/wxLogin.vue
@@ -45,8 +45,8 @@
})
const login = async () => {
    if (!from.openid) return Toast('openid不能为空')
    if (!from.unionid) return Toast('unionid不能为空')
    // if (!from.openid) return Toast('openid不能为空')
    // if (!from.unionid) return Toast('unionid不能为空')
    if (!from.companyId) return Toast('企业代码不能为空')
    if (!from.username) return Toast('手机号不能为空')
    if (!from.password) return Toast('密码不能为空')
server/src/main/java/doumeemes/api/business/SalaryParamController.java
@@ -11,13 +11,21 @@
import doumeemes.dao.ext.dto.SalaryParamDTO;
import doumeemes.service.business.SalaryParamService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
@@ -89,4 +97,24 @@
    public ApiResponse findById(@PathVariable Integer id) {
        return ApiResponse.success(salaryParamService.findById(id));
    }
    @ApiOperation(value = "批量导入计划", notes = "批量导入计划", httpMethod = "POST", position = 6)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "folder", value = "文件夹", required = true, paramType = "query", dataType = "String", dataTypeClass = String.class),
    })
    @PostMapping(value = "/importBatch", headers = "content-type=multipart/form-data")
//    @RequiresPermissions("business:salaryparam:create")
    public ApiResponse importBatch(String folder, HttpServletRequest request, HttpServletResponse response) throws Exception {
        CommonsMultipartResolver multipartResovler = new CommonsMultipartResolver();
        if (multipartResovler.isMultipart(request)) {
            MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            Iterator<String> it = multipartRequest.getFileNames();
            while (it.hasNext()) {
                MultipartFile file = multipartRequest.getFile((String) it.next());
                salaryParamService.importPlans(file);
                break;
            }
        }
        return ApiResponse.success( null);
    }
}
server/src/main/java/doumeemes/api/business/UnqualifiedRecordController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,71 @@
package doumeemes.api.business;
import doumeemes.api.BaseController;
import doumeemes.core.annotation.excel.ExcelExporter;
import doumeemes.core.annotation.pr.PreventRepeat;
import doumeemes.core.model.ApiResponse;
import doumeemes.core.model.PageWrap;
import doumeemes.core.model.PageData;
import doumeemes.dao.business.model.UnqualifiedRecord;
import doumeemes.service.business.UnqualifiedRecordService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
/**
 * @author æ±Ÿè¹„蹄
 * @since 2023/08/16 14:15
 */
@Api(tags = "工单类-报工不良记录类型表")
@RestController
@RequestMapping("/business/unqualifiedRecord")
public class UnqualifiedRecordController extends BaseController {
    @Autowired
    private UnqualifiedRecordService unqualifiedRecordService;
    @PreventRepeat
    @ApiOperation("新建")
    @PostMapping("/create")
    @RequiresPermissions("business:unqualifiedrecord:create")
    public ApiResponse create(@RequestBody UnqualifiedRecord unqualifiedRecord) {
        return ApiResponse.success(unqualifiedRecordService.create(unqualifiedRecord));
    }
    @ApiOperation("根据ID删除")
    @GetMapping("/delete/{id}")
    @RequiresPermissions("business:unqualifiedrecord:delete")
    public ApiResponse deleteById(@PathVariable Integer id) {
        unqualifiedRecordService.deleteById(id);
        return ApiResponse.success(null);
    }
    @ApiOperation("根据ID修改")
    @PostMapping("/updateById")
    @RequiresPermissions("business:unqualifiedrecord:update")
    public ApiResponse updateById(@RequestBody UnqualifiedRecord unqualifiedRecord) {
        unqualifiedRecordService.updateById(unqualifiedRecord);
        return ApiResponse.success(null);
    }
    @ApiOperation("分页查询")
    @PostMapping("/page")
    @RequiresPermissions("business:unqualifiedrecord:query")
    public ApiResponse<PageData<UnqualifiedRecord>> findPage (@RequestBody PageWrap<UnqualifiedRecord> pageWrap) {
        return ApiResponse.success(unqualifiedRecordService.findPage(pageWrap));
    }
    @ApiOperation("根据ID查询")
    @GetMapping("/{id}")
    @RequiresPermissions("business:unqualifiedrecord:query")
    public ApiResponse findById(@PathVariable Integer id) {
        return ApiResponse.success(unqualifiedRecordService.findById(id));
    }
}
server/src/main/java/doumeemes/api/ext/CategoryExtController.java
@@ -154,6 +154,15 @@
        return ApiResponse.success(categoryExtService.findPage(pageWrap));
    }
    @ApiOperation("列表查询")
    @PostMapping("/list")
    @RequiresPermissions("ext:categoryext:query")
    public ApiResponse<List<CategoryExtListVO>> list(@RequestBody QueryCategoryExtDTO queryCategoryExtDTO) {
        queryCategoryExtDTO.setDeleted(Constants.ZERO);
        queryCategoryExtDTO.setRootDepartId(getLoginUser().getRootDepartment().getId());
        return ApiResponse.success(categoryExtService.findList(queryCategoryExtDTO));
    }
    @ApiOperation("导出Excel")
    @PostMapping("/exportExcel")
    @RequiresPermissions("ext:categoryext:exportExcel")
server/src/main/java/doumeemes/api/ext/PlansExtController.java
@@ -223,7 +223,6 @@
        return ApiResponse.success(plansExtService.pageCount(param));
    }
    @ApiOperation("一键报工")
    @PostMapping("/autoWorkReport")
    public ApiResponse autoWorkReport (@RequestBody AutoWorkReportDTO autoWorkReportDTO) {
server/src/main/java/doumeemes/api/ext/SalaryParamExtController.java
@@ -79,7 +79,7 @@
    @ApiOperation("根据对象信息查询")
    @PostMapping("/queryOne")
    @RequiresPermissions("business:salaryparam:query")
    public ApiResponse queryOne(@RequestBody SalaryParam salaryParam) {
    public ApiResponse<SalaryParam> queryOne(@RequestBody SalaryParam salaryParam) {
        SalaryParam data = salaryParamService.findOne(salaryParam);
        return ApiResponse.success(data);
    }
server/src/main/java/doumeemes/config/shiro/ShiroRealm.java
@@ -37,6 +37,7 @@
import java.util.Date;
import java.util.List;
import java.util.Objects;
/**
 * è‡ªå®šä¹‰Realm,处理认证和权限
@@ -130,8 +131,10 @@
            if(com == null){
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"对不起,该账户异常!");
            }
            if(com.getOepnValidDate().before(new Date())){
            if(Constants.equalsInteger( com.getStatus(),Constants.ZERO) ){
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"对不起,该企业已过禁用!");
            }
            if(com.getOepnValidDate() != null && com.getOepnValidDate().before(new Date())){
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"对不起,该企业已过使用有效期!");
            }
            //如果是企业用户
server/src/main/java/doumeemes/core/utils/excel/EasyExcelUtil.java
@@ -87,6 +87,9 @@
    }
    /**
     *
     * titleRows : æ ‡é¢˜å å‡ è¡Œ
     * headerRows : åŒå å‡ è¡Œ
     * excel常规导入(默认只读取第一张sheet工作簿)
     */
    public static <T> List<T> importExcel(MultipartFile file, Integer titleRows, Integer headerRows, Class<T> pojoClass){
@@ -150,4 +153,4 @@
        }
        return list;
    }
}
}
server/src/main/java/doumeemes/dao/business/UnqualifiedRecordMapper.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,12 @@
package doumeemes.dao.business;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import doumeemes.dao.business.model.UnqualifiedRecord;
/**
 * @author æ±Ÿè¹„蹄
 * @since 2023/08/16 14:15
 */
public interface UnqualifiedRecordMapper extends BaseMapper<UnqualifiedRecord> {
}
server/src/main/java/doumeemes/dao/business/dto/AutoWorkReportDTO.java
@@ -33,4 +33,7 @@
    @ApiModelProperty(value = "产出记录")
    private CreateWorkorderRecordDTO createWorkorderRecordDTO;
    @ApiModelProperty(value = "不良品分类记录")
    private List<CreateUnqualifiedDTO> createUnqualifiedDTOList ;
}
server/src/main/java/doumeemes/dao/business/dto/CreateUnqualifiedDTO.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,23 @@
package doumeemes.dao.business.dto;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
/**
 * @author æ±Ÿè¹„蹄
 * @date 2022/05/12 10:18
 */
@Data
public class CreateUnqualifiedDTO {
    @ApiModelProperty(value = "不良类别主键"  )
    private Integer categoryId;
    @ApiModelProperty(value = "检验不合格数量")
    private BigDecimal unQualifiedNum;
}
server/src/main/java/doumeemes/dao/business/model/UnqualifiedRecord.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,79 @@
package doumeemes.dao.business.model;
import doumeemes.core.annotation.excel.ExcelColumn;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import com.fasterxml.jackson.annotation.JsonFormat;
import java.util.Date;
import java.math.BigDecimal;
/**
 * å·¥å•ç±»-报工不良记录类型表
 * @author æ±Ÿè¹„蹄
 * @since 2023/08/16 14:15
 */
@Data
@ApiModel("工单类-报工不良记录类型表")
@TableName("`unqualified_record`")
public class UnqualifiedRecord {
    @TableId(type = IdType.AUTO)
    @ApiModelProperty(value = "主键", example = "1")
    @ExcelColumn(name="主键")
    private Integer id;
    @ApiModelProperty(value = "是否已删除 0未删除 1已删除", example = "1")
    @ExcelColumn(name="是否已删除 0未删除 1已删除")
    private Integer deleted;
    @ApiModelProperty(value = "创建人编码", example = "1")
    @ExcelColumn(name="创建人编码")
    private Integer createUser;
    @ApiModelProperty(value = "创建时间")
    @ExcelColumn(name="创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date createTime;
    @ApiModelProperty(value = "更新人编码", example = "1")
    @ExcelColumn(name="更新人编码")
    private Integer updateUser;
    @ApiModelProperty(value = "更新时间")
    @ExcelColumn(name="更新时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date updateTime;
    @ApiModelProperty(value = "备注")
    @ExcelColumn(name="备注")
    private String remark;
    @ApiModelProperty(value = "主组织编码(关联department表根组织)", example = "1")
    @ExcelColumn(name="主组织编码(关联department表根组织)")
    private Integer rootDepartId;
    @ApiModelProperty(value = "公司级组织编码(关联department表)", example = "1")
    @ExcelColumn(name="公司级组织编码(关联department表)")
    private Integer departId;
    @ApiModelProperty(value = "工单主键", example = "1")
    @ExcelColumn(name="工单主键")
    private Integer workorderId;
    @ApiModelProperty(value = "产出记录主键", example = "1")
    @ExcelColumn(name="产出记录主键")
    private Integer recordId;
    @ApiModelProperty(value = "类别主键", example = "1")
    @ExcelColumn(name="类别主键")
    private Integer categoryId;
    @ApiModelProperty(value = "检验不合格数量", example = "1")
    @ExcelColumn(name="检验不合格数量")
    private BigDecimal unqualifiedNum;
}
server/src/main/java/doumeemes/dao/business/vo/SalaryParamVO.java
@@ -14,14 +14,15 @@
public class SalaryParamVO {
    @ApiModelProperty(value = "主键")
    @ExcelColumn(name="序号",index = 1)
    private Integer id;
    @ApiModelProperty(value = "创建人编码")
    @ExcelColumn(name="创建人编码")
    @ExcelColumn(name="创建人编码",index = 11)
    private String createUserName;
    @ApiModelProperty(value = "创建时间")
    @ExcelColumn(name="创建时间")
    @ExcelColumn(name="创建时间",index = 10, dateFormat = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    @ApiModelProperty(value = "主组织编码(关联department表根组织)")
@@ -39,42 +40,42 @@
    private Integer procedureId;
    @ApiModelProperty(value = "工序编码(关联procedure表)")
    @ExcelColumn(name="工序编码(关联procedure表)")
//    @ExcelColumn(name="工序编码(关联procedure表)")
    @NotEmpty(message = "工序编码不能为空")
    private Integer procedureCode;
    @ApiModelProperty(value = "工序编码(关联procedure表)")
    @ExcelColumn(name="工序编码(关联procedure表)")
    @ExcelColumn(name="工序名称",index =5)
    private String procedureName;
    @ApiModelProperty(value = "产品名称" )
    @Excel(name="产品名称",orderNum ="3")
    @ExcelColumn(name="物料名称",index =3)
    private String materialName;
    @ApiModelProperty(value = "产品编码" )
    @Excel(name="产品编码",orderNum ="4")
    @ExcelColumn(name="物料编码",index =4)
    private String materialCode;
    @ApiModelProperty(value = "物料编码(关联material_distribute表)", example = "1")
    private Integer materialId;
    @ApiModelProperty(value = "工资单价(元)")
    @ExcelColumn(name="工资单价(元)")
    @ExcelColumn(name="工资单价(元)",index =6)
    private BigDecimal salary;
    @ApiModelProperty(value = "标准数量")
    @ExcelColumn(name="标准数量")
    @ExcelColumn(name="标准产出",index =7)
    private Integer num;
    @ApiModelProperty(value = "标准时长(秒)")
    @ExcelColumn(name="标准时长(秒)")
    @ExcelColumn(name="标准时长(秒)",index =8)
    private String times;
    @ApiModelProperty(value = "不良品是否计入 0否 1是")
    @ExcelColumn(name="不良品是否计入 0否 1是")
    @ExcelColumn(name="不良品是否计入 0否 1是",index = 9 ,valueMapping = "0=否;1=是")
    private Integer unqualified;
    @ApiModelProperty(value = "计价方式 0计件 1计时")
    @ExcelColumn(name="计价方式 0计件 1计时")
    @ExcelColumn(name="计价方式",index = 2 ,valueMapping = "0=计件;1=计时")
    private Integer type;
}
server/src/main/java/doumeemes/dao/business/vo/WorkPlansVO.java
@@ -57,7 +57,7 @@
    private Integer factoryId;
    @ApiModelProperty(value = "工厂名称", example = "1")
    @ExcelColumn(name="工厂名称",index = 4,width =15)
    @ExcelColumn(name="工厂名称",index = 5,width =15)
    private String factoryName;
    @ApiModelProperty(value = "来源 0人工创建、1Excel导入", example = "1")
@@ -67,12 +67,12 @@
    @ExcelColumn(name="计划编码",index = 0,width =15)
    private String planCode;
    @ApiModelProperty(value = "计划日期")
    @ExcelColumn(name="计划日期",index = 3,width =15)
    @ApiModelProperty(value = "计划完成日期")
    @ExcelColumn(name="计划日期",index = 4,width =15)
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date planDate;
    @ApiModelProperty(value = "计划开始日期")
    @ExcelColumn(name="计划开始日期",index = 17,width =15)
    @ExcelColumn(name="计划开始日期",index = 3,width =15)
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date startDate;
    @ApiModelProperty(value = "销售单号" )
@@ -94,26 +94,26 @@
    private Integer unitId;
    @ApiModelProperty(value = "单位编码名称", example = "1")
    @ExcelColumn(name="单位名称",index = 6,width =15)
    @ExcelColumn(name="单位名称",index = 7,width =15)
    private String unitName;
    @ApiModelProperty(value = "计划数量", example = "1")
    @ExcelColumn(name="计划数量",index = 5,width =15)
    @ExcelColumn(name="计划数量",index = 6,width =15)
    private Integer num;
    @ApiModelProperty(value = "批次号")
    @ExcelColumn(name="批次号",index = 7,width =15)
    @ExcelColumn(name="批次号",index = 8,width =15)
    private String batch;
    @ApiModelProperty(value = "状态 1=已生成;2=已发布、3已取消、4已分配、5已暂停、6已完工、7已入库、8已关闭", example = "1")
    @ExcelColumn(name="计划状态",valueMapping = "0=已生成;1=执行中;3=已取消;4=已分配;5=已暂停;6=已完工;7=已入库;8=已关闭;",index = 8,width =15)
    @ExcelColumn(name="计划状态",valueMapping = "0=已生成;1=执行中;3=已取消;4=已分配;5=已暂停;6=已完工;7=已入库;8=已关闭;",index = 9,width =15)
    private Integer status;
    @ApiModelProperty(value = "导入批号(关联plan_import表)", example = "1")
    private Integer importId;
    @ApiModelProperty(value = "是否暂停 0未暂停 1已暂停", example = "1")
    @ExcelColumn(name="是否暂停",valueMapping = "0=否;1=是",index = 9,width =15)
    @ExcelColumn(name="是否暂停",valueMapping = "0=否;1=是",index = 10,width =15)
    private Integer paused;
    @ApiModelProperty(value = "计划员编码(与system_user表关联)", example = "1")
@@ -123,31 +123,31 @@
    private Integer urgent;
    @ApiModelProperty(value = "计划员姓名", example = "1")
    @ExcelColumn(name="计划员姓名",index = 14,width =15)
    @ExcelColumn(name="计划员姓名",index = 15,width =15)
    private String userName;
    @ApiModelProperty(value = "计划员手机号", example = "1")
    @ExcelColumn(name="计划员手机号",index = 15,width =15)
    @ExcelColumn(name="计划员手机号",index = 16,width =15)
    private String userMobile;
    @ApiModelProperty(value = "计划发布时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    @ExcelColumn(name="计划发布时间",index = 13,width =15)
    @ExcelColumn(name="计划发布时间",index = 14,width =15)
    private Date publishDate;
    @ApiModelProperty(value = "用户部门名称", example = "1")
    private String userDepartName;
    @ApiModelProperty(value = "完工数量", example = "1")
    @ExcelColumn(name="完工数量" ,index = 10,width =15)
    @ExcelColumn(name="完工数量" ,index = 11,width =15)
    private Integer finishNum;
    @ApiModelProperty(value = "完工合格数量", example = "1")
    @ExcelColumn(name="完工合格数量",index = 11,width =15)
    @ExcelColumn(name="完工合格数量",index = 12,width =15)
    private Integer finishQualifiedNum;
    @ApiModelProperty(value = "完工不良数量", example = "1")
    @ExcelColumn(name="完工不良数量",index = 12,width =15)
    @ExcelColumn(name="完工不良数量",index = 13,width =15)
    private Integer finishUnQualifiedNum;
    @ApiModelProperty(value = "子计划明细信息", example = "1")
server/src/main/java/doumeemes/dao/ext/dto/QueryPlansExtDTO.java
@@ -441,8 +441,8 @@
    private String mixParam;
    @ApiModelProperty(value = "开始时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date startDate;
    private String planDateStartDate;
    @ApiModelProperty(value = "截止时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date endDate;
    private String planDateEndDate;
}
server/src/main/java/doumeemes/dao/ext/dto/QueryUserSalaryListDTO.java
@@ -28,10 +28,10 @@
    private Integer rootDepartId;
    @ApiModelProperty(value = "开始时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date startDate;
    private String startDate;
    @ApiModelProperty(value = "结束时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date endDate;
    private String endDate;
    @ApiModelProperty(value = "数据权限部门编码集合" ,hidden = true)
    private List<Integer> departIds;
server/src/main/java/doumeemes/dao/ext/dto/SalaryParamImportDTO.java
@@ -1,6 +1,7 @@
package doumeemes.dao.ext.dto;
import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.annotation.ExcelTarget;
import io.swagger.annotations.ApiModel;
import lombok.Data;
@@ -12,6 +13,7 @@
 */
@Data
@ApiModel("绩效工资配置导入")
@ExcelTarget("SalaryParamImportDTO")
public class SalaryParamImportDTO {
    @Excel(name="计价方式",orderNum ="1")
@@ -20,10 +22,10 @@
    @Excel(name="工厂名称",orderNum ="2")
    private String departName;
    @Excel(name="产品名称",orderNum ="3")
    @Excel(name="物料名称",orderNum ="3")
    private String materialName;
    @Excel(name="产品编码",orderNum ="4")
    @Excel(name="物料编码",orderNum ="4")
    private String materialCode;
    @Excel(name="工序名称",orderNum ="5")
@@ -33,7 +35,7 @@
    private BigDecimal salary;
    @Excel(name="标准产出",orderNum ="7")
    private Integer NUM;
    private String num;
    @Excel(name="标准工时",orderNum ="8")
    private String timesName;
server/src/main/java/doumeemes/dao/ext/vo/BomExtListVO.java
@@ -60,8 +60,8 @@
    @ExcelColumn(name="公司级组织编码(关联department表)")
    private Integer departId;
    @ApiModelProperty(value = "物料ID(关联material表)", example = "1")
    @ExcelColumn(name="物料ID(关联material表)")
    @ApiModelProperty(value = "物料ID(该字段关联 material_distribute è¡¨ID ï¼ï¼ï¼ï¼ ï¼‰", example = "1")
    @ExcelColumn(name="物料ID(关联material_distribute表)")
    private Integer materialId;
    @ApiModelProperty(value = "版本号")
@@ -157,5 +157,6 @@
    @ApiModelProperty(value = "工序名称")
    private String procedureName;
    @ApiModelProperty(value = "material id")
    private Integer realMaterialId;
}
server/src/main/java/doumeemes/dao/ext/vo/CompanyExtListVO.java
@@ -165,4 +165,7 @@
    @ApiModelProperty(value = "羚羊平台应用参数,json格式存储{app_key:,aes_key:,app_secret:}" )
    private String lingyangInfo;
    @ApiModelProperty(value = "状态 1 å¼€å¯ 0 ç¦ç”¨")
    private Integer status;
}
server/src/main/java/doumeemes/dao/ext/vo/PlansExtListVO.java
@@ -71,7 +71,7 @@
    private Integer lessDistributNum;
    @ApiModelProperty(value = "计划类型 0正常1异常2返工", example = "1")
    @ExcelColumn(name="计划类型",valueMapping = "0=正常;1=异常;2=返工;",index = 11,width =15)
    @ExcelColumn(name="计划类型",valueMapping = "0=正常;1=异常;2=返工;",index = 12,width =15)
    private Integer type;
    @ApiModelProperty(value = "生产工序编码(关联procedures表)", example = "1")
@@ -84,15 +84,15 @@
    private Integer unitId;
    @ApiModelProperty(value = "计划数量", example = "1")
    @ExcelColumn(name="计划数量",index = 6,width =15)
    @ExcelColumn(name="计划数量",index = 7,width =15)
    private Integer num;
    @ApiModelProperty(value = "批次号")
    @ExcelColumn(name="生产批次号",index = 8,width =15)
    @ExcelColumn(name="生产批次号",index = 9,width =15)
    private String batch;
    @ApiModelProperty(value = "优先级(排序码)字段", example = "1")
    @ExcelColumn(name="优先级",index = 9,width =15)
    @ExcelColumn(name="优先级",index = 10,width =15)
    private Integer urgent;
    @ApiModelProperty(value = "导入批号(关联plan_import表)", example = "1")
@@ -102,14 +102,14 @@
    private Integer userId;
    @ApiModelProperty(value = "状态 0已生成、1已发布、2已撤回、3已取消、4已分配、5已暂停、6已完工、7已入库、8已关闭", example = "1")
    @ExcelColumn(name="计划状态",valueMapping = "0=已生成;1=已发布;2=已撤回;3=已取消;4=已分配;5=已暂停;6=已完工;7=已入库;8=已关闭;",index = 10,width =15)
    @ExcelColumn(name="计划状态",valueMapping = "0=已生成;1=已发布;2=已撤回;3=已取消;4=已分配;5=已暂停;6=已完工;7=已入库;8=已关闭;",index = 11,width =15)
    private Integer status;
    @ApiModelProperty(value = "返修申请单号(关联backorder表)", example = "1")
    private Integer backorderId;
    @ApiModelProperty(value = "计划发布时间")
    @ExcelColumn(name="发布日期",index = 15,width =15)
    @ExcelColumn(name="发布日期",index = 16,width =15)
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date publishDate;
@@ -133,20 +133,29 @@
    @ApiModelProperty(value = "已完工数量", example = "0")
    private Integer  doneNum;
    @ApiModelProperty(value = "合格数量", example = "0")
    @ExcelColumn(name="合格数量",index = 13,width =15)
    @ExcelColumn(name="合格数量",index = 14,width =15)
    private Integer  qulifiedNum;
    @ApiModelProperty(value = "不良数量", example = "0")
    @ExcelColumn(name="不良数量",index = 14,width =15)
    @ExcelColumn(name="不良数量",index = 15,width =15)
    private Integer  unqulifiedNum;
    @ApiModelProperty(value = "已分配生产数量", example = "1",hidden = true)
    private Integer distributNum;
    @ApiModelProperty(value = "工单已分配生产数量", example = "1",hidden = true)
    private Integer workorderDistributNum;
    @ApiModelProperty(value = "已分配未完工生产数量", example = "1",hidden = true)
    @ExcelColumn(name="已分配未完工生产数量",index = 12,width =15)
    @ExcelColumn(name="已分配未完工生产数量",index = 13,width =15)
    private Integer distributNoDoneNum;
    @ApiModelProperty(value = "库存是否满足 0不满足 1满足", example = "0")
    private Integer  isStock;
    @ApiModelProperty(value = "是否延期")
    private Boolean hasExpire;
    @ApiModelProperty(value = "成品计划开始日期")
    @ExcelColumn(name="计划日期",index = 4,width =15)
    @JsonFormat(pattern = "yyyy-MM-dd")
    private  Date workPlanPlanDate;
    @ApiModelProperty(value = "成品计划开始日期")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private  Date workPlanStartDate;
    @ExcelColumn(name="物料名称",index = 1,width =15)
@@ -155,16 +164,16 @@
    @ExcelColumn(name="物料编码",index = 2,width =15)
    private String materialCode;
    @ExcelColumn(name="工厂",index = 4,width =15)
    @ExcelColumn(name="工厂",index = 5,width =15)
    private String factoryName;
    @ExcelColumn(name="工序",index = 5,width =15)
    @ExcelColumn(name="工序",index = 6,width =15)
    private String produceName;
    @ExcelColumn(name="计划员",index = 16,width =15)
    @ExcelColumn(name="计划员",index = 17,width =15)
    private String planUserName;
    @ExcelColumn(name="单位名称",index = 7,width =15)
    @ExcelColumn(name="单位名称",index = 8,width =15)
    private String unitName;
    @ExcelColumn(name="成品计划编码")
@@ -173,14 +182,16 @@
    @ExcelColumn(name="销售订单")
    private String salesOrder;
    @ApiModelProperty(value = "成品计划开始时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date workPlanStartDate;
    @ApiModelProperty(value = "成品计划结束时间")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date workPlanEndDate;
    @ApiModelProperty(value = "已生产数量")
    private Integer produceNum;
    @ApiModelProperty(value = "是否有bom配置 0无 1有", example = "1")
    private Integer hasBom;
    @ApiModelProperty(value = "bom投料方式 0推式 1拉式", example = "1")
    private Integer bomType;
}
server/src/main/java/doumeemes/service/business/UnqualifiedRecordService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,97 @@
package doumeemes.service.business;
import doumeemes.core.model.PageData;
import doumeemes.core.model.PageWrap;
import doumeemes.dao.business.model.UnqualifiedRecord;
import java.util.List;
/**
 * å·¥å•ç±»-报工不良记录类型表Service定义
 * @author æ±Ÿè¹„蹄
 * @since 2023/08/16 14:15
 */
public interface UnqualifiedRecordService {
    /**
     * åˆ›å»º
     *
     * @param unqualifiedRecord å®žä½“对象
     * @return Integer
     */
    Integer create(UnqualifiedRecord unqualifiedRecord);
    /**
     * ä¸»é”®åˆ é™¤
     *
     * @param id ä¸»é”®
     */
    void deleteById(Integer id);
    /**
     * åˆ é™¤
     *
     * @param unqualifiedRecord å®žä½“对象
     */
    void delete(UnqualifiedRecord unqualifiedRecord);
    /**
     * æ‰¹é‡ä¸»é”®åˆ é™¤
     *
     * @param ids ä¸»é”®é›†
     */
    void deleteByIdInBatch(List<Integer> ids);
    /**
     * ä¸»é”®æ›´æ–°
     *
     * @param unqualifiedRecord å®žä½“对象
     */
    void updateById(UnqualifiedRecord unqualifiedRecord);
    /**
     * æ‰¹é‡ä¸»é”®æ›´æ–°
     *
     * @param unqualifiedRecords å®žä½“集
     */
    void updateByIdInBatch(List<UnqualifiedRecord> unqualifiedRecords);
    /**
     * ä¸»é”®æŸ¥è¯¢
     *
     * @param id ä¸»é”®
     * @return UnqualifiedRecord
     */
    UnqualifiedRecord findById(Integer id);
    /**
     * æ¡ä»¶æŸ¥è¯¢å•条记录
     *
     * @param unqualifiedRecord å®žä½“对象
     * @return UnqualifiedRecord
     */
    UnqualifiedRecord findOne(UnqualifiedRecord unqualifiedRecord);
    /**
     * æ¡ä»¶æŸ¥è¯¢
     *
     * @param unqualifiedRecord å®žä½“对象
     * @return List<UnqualifiedRecord>
     */
    List<UnqualifiedRecord> findList(UnqualifiedRecord unqualifiedRecord);
    /**
     * åˆ†é¡µæŸ¥è¯¢
     *
     * @param pageWrap åˆ†é¡µå¯¹è±¡
     * @return PageData<UnqualifiedRecord>
     */
    PageData<UnqualifiedRecord> findPage(PageWrap<UnqualifiedRecord> pageWrap);
    /**
     * æ¡ä»¶ç»Ÿè®¡
     *
     * @param unqualifiedRecord å®žä½“对象
     * @return long
     */
    long count(UnqualifiedRecord unqualifiedRecord);
}
server/src/main/java/doumeemes/service/business/impl/CompanyOpenServiceImpl.java
@@ -11,14 +11,18 @@
import doumeemes.dao.business.model.Company;
import doumeemes.dao.business.model.CompanyLog;
import doumeemes.dao.business.model.CompanyOpen;
import doumeemes.dao.ext.vo.CompanyExtListVO;
import doumeemes.service.business.CompanyLogService;
import doumeemes.service.business.CompanyOpenService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import doumeemes.service.ext.DepartmentExtService;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
@@ -43,6 +47,10 @@
    @Autowired
    CompanyLogService companyLogService;
    @Autowired
    @Lazy
    private DepartmentExtService departmentExtService;
    @Override
    public Integer create(CompanyOpen companyOpen) {
@@ -90,7 +98,7 @@
        company.setOepnValidDate(companyOpen.getValidDate());
        company.setOepnType(companyOpen.getOepnType());
        companyMapper.updateById(company);
        Company company1 = companyMapper.selectById(companyOpen.getCompanyId());
        CompanyLog companyLog = new CompanyLog();
        companyLog.setDeleted((byte) Constants.ZERO);
@@ -103,6 +111,15 @@
        companyLog.setUpdateType(Constants.CompanyUpdateType.UPDATE_VAIL_DATE.getKey());
        companyLog.setDetail("有效期从"+format.format(cyResult.getOepnValidDate())+"日调整至"+format.format(companyOpen.getValidDate()));
        companyLogService.create(companyLog);
        initRedisCache(company1);
    }
    private void initRedisCache(Company com) {
        CompanyExtListVO c = new CompanyExtListVO();
        BeanUtils.copyProperties(com,c);
        departmentExtService.loadComDepart(c);
        departmentExtService.initCompnayCodesByCom(com);
    }
    @Override
@@ -131,7 +148,7 @@
        QueryWrapper<CompanyOpen> wrapper = new QueryWrapper<>(companyOpen);
        return companyOpenMapper.selectList(wrapper);
    }
    @Override
    public PageData<CompanyOpen> findPage(PageWrap<CompanyOpen> pageWrap) {
        IPage<CompanyOpen> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
server/src/main/java/doumeemes/service/business/impl/CompanyServiceImpl.java
@@ -14,6 +14,7 @@
import doumeemes.dao.business.model.CompanyLog;
import doumeemes.dao.business.model.Multifiles;
import doumeemes.dao.ext.dto.DingDingConfig;
import doumeemes.dao.ext.vo.CompanyExtListVO;
import doumeemes.service.business.CompanyLogService;
import doumeemes.service.business.CompanyService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
@@ -21,9 +22,12 @@
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import doumeemes.service.business.MultifilesService;
import doumeemes.service.ext.DepartmentExtService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
@@ -46,6 +50,10 @@
    @Autowired
    private CompanyLogService companyLogService;
    @Autowired
    @Lazy
    private DepartmentExtService departmentExtService;
    @Override
@@ -115,36 +123,35 @@
        update.setStatus(company.getStatus());
        update.setDingdingInfo(company.getDingdingInfo());
        companyMapper.updateById(update);
//        æ›´æ–°è®°å½•
        CompanyLog companyLog = new CompanyLog();
        companyLog.setDeleted((byte)Constants.ZERO);
        companyLog.setUpdateUser(principal.getId());
        companyLog.setCreateUser(principal.getId());
        companyLog.setCreateTime(new Date());
        companyLog.setUpdateTime(new Date());
        companyLog.setCompanyId(company.getId());
        if(Objects.nonNull(company.getStatus())){
            CompanyLog companyLog = new CompanyLog();
            companyLog.setDeleted((byte)Constants.ZERO);
            companyLog.setUpdateUser(principal.getId());
            companyLog.setCreateUser(principal.getId());
            companyLog.setCreateTime(new Date());
            companyLog.setUpdateTime(new Date());
            companyLog.setRemark(company.getStatus() == 1 ? "数据启用" : "数据禁用");
            companyLog.setCompanyId(company.getId());
            companyLog.setUpdateType(company.getStatus() == 1 ? Constants.CompanyUpdateType.UPDATE_ENABLE.getKey()
                    : Constants.CompanyUpdateType.UPDATE_DISABLE.getKey());
            companyLog.setDetail(company.getStatus() == 1 ? "数据启用" : "数据禁用");
            companyLogService.create(companyLog);
        }else {
            CompanyLog companyLog = new CompanyLog();
            companyLog.setDeleted((byte)Constants.ZERO);
            companyLog.setUpdateUser(principal.getId());
            companyLog.setCreateUser(principal.getId());
            companyLog.setCreateTime(new Date());
            companyLog.setUpdateTime(new Date());
            companyLog.setRemark("更新企业数据");
            companyLog.setCompanyId(company.getId());
            companyLog.setUpdateType(Constants.CompanyUpdateType.UPDATE_CONTENT.getKey());
            companyLog.setDetail("更新企业数据");
            companyLogService.create(companyLog);
        }
        companyLogService.create(companyLog);
        Company company1 = companyMapper.selectById(company.getId());
        initRedisCache(company1);
    }
    private void initRedisCache(Company com) {
        CompanyExtListVO c = new CompanyExtListVO();
        BeanUtils.copyProperties(com,c);
        departmentExtService.loadComDepart(c);
        departmentExtService.initCompnayCodesByCom(com);
    }
    private Boolean isParseObject(String dingdingInfo){
@@ -185,7 +192,7 @@
        QueryWrapper<Company> wrapper = new QueryWrapper<>(company);
        return companyMapper.selectList(wrapper);
    }
    @Override
    public PageData<Company> findPage(PageWrap<Company> pageWrap) {
        IPage<Company> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
server/src/main/java/doumeemes/service/business/impl/SalaryParamServiceImpl.java
@@ -54,19 +54,24 @@
    @Override
    public Integer create(SalaryParam salaryParam) {
        LoginUserInfo principal = (LoginUserInfo) SecurityUtils.getSubject().getPrincipal();
        SalaryParam insert = new SalaryParam();
        insert.setRootDepartId(salaryParam.getRootDepartId());
        insert.setDepartId(salaryParam.getDepartId());
        insert.setProcedureId(salaryParam.getProcedureId());
        insert.setMaterialId(salaryParam.getMaterialId());
        insert.setDeleted((byte) Constants.ZERO);
        if(findOne(insert) != null){
            throw  new BusinessException(ResponseStatus.DATA_EXISTS.getCode(),"同一个物料在相同工序不能重复配置哦!");
        }
        insert.setCreateUser(principal.getId());
        insert.setCreateTime(new Date());
        insert.setUpdateUser(principal.getId());
        insert.setUpdateTime(new Date());
        insert.setRemark(salaryParam.getRemark());
        insert.setRootDepartId(salaryParam.getRootDepartId());
        insert.setDepartId(salaryParam.getDepartId());
        insert.setProcedureId(salaryParam.getProcedureId());
        insert.setMaterialId(salaryParam.getMaterialId());
        insert.setSalary(salaryParam.getSalary());
        insert.setNum(salaryParam.getNum());
        insert.setTimes(salaryParam.getTimes());
@@ -109,9 +114,9 @@
                .set(SalaryParam::getUpdateTime,new Date())
                .set(SalaryParam::getUpdateUser,principal.getId())
                .set(SalaryParam::getType,salaryParam.getType())
                .set(SalaryParam::getDepartId,salaryParam.getDepartId())
                .set(SalaryParam::getMaterialId,salaryParam.getMaterialId())
                .set(SalaryParam::getProcedureId,salaryParam.getProcedureId())
//                .set(SalaryParam::getDepartId,salaryParam.getDepartId())
//                .set(SalaryParam::getMaterialId,salaryParam.getMaterialId())
//                .set(SalaryParam::getProcedureId,salaryParam.getProcedureId())
                .set(SalaryParam::getSalary,salaryParam.getSalary())
                .set(SalaryParam::getNum,salaryParam.getNum())
                .set(SalaryParam::getTimes,salaryParam.getTimes())
@@ -137,6 +142,7 @@
    @Override
    public SalaryParam findOne(SalaryParam salaryParam) {
        QueryWrapper<SalaryParam> wrapper = new QueryWrapper<>(salaryParam);
        wrapper.last("limit 1");
        return salaryParamMapper.selectOne(wrapper);
    }
@@ -178,7 +184,7 @@
                || Objects.isNull(s.getDepartName())
                || Objects.isNull(s.getMaterialCode())
                || Objects.isNull(s.getProcedureName())
                || Objects.isNull(s.getNUM())){
                || Objects.isNull(s.getNum())){
                throw new BusinessException(ResponseStatus.SERVER_ERROR.getCode(), "导入数据内容有误!");
            }
        });
@@ -214,7 +220,7 @@
            proceduresWrapper.lambda()
                    .eq(Procedures::getName,salaryParamImportDTO.getProcedureName())
                    .eq(Procedures::getRootDepartId,department.getRootId())
                    .eq(Procedures::getDepartId,department.getId())
                    .eq(Procedures::getOrgId,department.getId())
                    .last("limit 1");
            Procedures procedures = proceduresMapper.selectOne(proceduresWrapper);
            if (Objects.isNull(procedures)){
@@ -226,10 +232,8 @@
            salaryParam.setProcedureId(procedures.getId());
            salaryParam.setMaterialId(material.getId());
            salaryParam.setSalary(salaryParamImportDTO.getSalary());
            salaryParam.setNum(new BigDecimal(salaryParamImportDTO.getNUM()));
            salaryParam.setNum(new BigDecimal(salaryParamImportDTO.getNum()));
            salaryParam.setTimes(getIntegerTimes(salaryParamImportDTO.getTimesName()));
            Integer unqualified = Optional.ofNullable(salaryParamImportDTO.getUnqualified()).map(s -> {
                if ("否".equals(s)) {
                    return 0;
@@ -265,7 +269,7 @@
                m = Integer.parseInt(a.substring(hIndex >=0?hIndex+2:0,mIndex));
            }
            if(sIndex > mIndex){
               s = Integer.parseInt(a.substring(mIndex >=0?mIndex+2:0,mIndex));
               s = Integer.parseInt(a.substring(mIndex >= 0 ? mIndex+2 : 0, sIndex));
            }
            return  h*3600+m*60+s;
        }catch (Exception e){
server/src/main/java/doumeemes/service/business/impl/UnqualifiedRecordServiceImpl.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,124 @@
package doumeemes.service.business.impl;
import doumeemes.core.model.PageData;
import doumeemes.core.model.PageWrap;
import doumeemes.core.utils.Utils;
import doumeemes.dao.business.UnqualifiedRecordMapper;
import doumeemes.dao.business.model.UnqualifiedRecord;
import doumeemes.service.business.UnqualifiedRecordService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
/**
 * å·¥å•ç±»-报工不良记录类型表Service实现
 * @author æ±Ÿè¹„蹄
 * @since 2023/08/16 14:15
 */
@Service
public class UnqualifiedRecordServiceImpl implements UnqualifiedRecordService {
    @Autowired
    private UnqualifiedRecordMapper unqualifiedRecordMapper;
    @Override
    public Integer create(UnqualifiedRecord unqualifiedRecord) {
        unqualifiedRecordMapper.insert(unqualifiedRecord);
        return unqualifiedRecord.getId();
    }
    @Override
    public void deleteById(Integer id) {
        unqualifiedRecordMapper.deleteById(id);
    }
    @Override
    public void delete(UnqualifiedRecord unqualifiedRecord) {
        UpdateWrapper<UnqualifiedRecord> deleteWrapper = new UpdateWrapper<>(unqualifiedRecord);
        unqualifiedRecordMapper.delete(deleteWrapper);
    }
    @Override
    public void deleteByIdInBatch(List<Integer> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return;
        }
        unqualifiedRecordMapper.deleteBatchIds(ids);
    }
    @Override
    public void updateById(UnqualifiedRecord unqualifiedRecord) {
        unqualifiedRecordMapper.updateById(unqualifiedRecord);
    }
    @Override
    public void updateByIdInBatch(List<UnqualifiedRecord> unqualifiedRecords) {
        if (CollectionUtils.isEmpty(unqualifiedRecords)) {
            return;
        }
        for (UnqualifiedRecord unqualifiedRecord: unqualifiedRecords) {
            this.updateById(unqualifiedRecord);
        }
    }
    @Override
    public UnqualifiedRecord findById(Integer id) {
        return unqualifiedRecordMapper.selectById(id);
    }
    @Override
    public UnqualifiedRecord findOne(UnqualifiedRecord unqualifiedRecord) {
        QueryWrapper<UnqualifiedRecord> wrapper = new QueryWrapper<>(unqualifiedRecord);
        return unqualifiedRecordMapper.selectOne(wrapper);
    }
    @Override
    public List<UnqualifiedRecord> findList(UnqualifiedRecord unqualifiedRecord) {
        QueryWrapper<UnqualifiedRecord> wrapper = new QueryWrapper<>(unqualifiedRecord);
        return unqualifiedRecordMapper.selectList(wrapper);
    }
    @Override
    public PageData<UnqualifiedRecord> findPage(PageWrap<UnqualifiedRecord> pageWrap) {
        IPage<UnqualifiedRecord> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
        QueryWrapper<UnqualifiedRecord> queryWrapper = new QueryWrapper<>();
        Utils.MP.blankToNull(pageWrap.getModel());
        queryWrapper.lambda()
                .eq(pageWrap.getModel().getId() != null, UnqualifiedRecord::getId, pageWrap.getModel().getId())
                .eq(pageWrap.getModel().getDeleted() != null, UnqualifiedRecord::getDeleted, pageWrap.getModel().getDeleted())
                .eq(pageWrap.getModel().getCreateUser() != null, UnqualifiedRecord::getCreateUser, pageWrap.getModel().getCreateUser())
                .ge(pageWrap.getModel().getCreateTime() != null, UnqualifiedRecord::getCreateTime, Utils.Date.getStart(pageWrap.getModel().getCreateTime()))
                .le(pageWrap.getModel().getCreateTime() != null, UnqualifiedRecord::getCreateTime, Utils.Date.getEnd(pageWrap.getModel().getCreateTime()))
                .eq(pageWrap.getModel().getUpdateUser() != null, UnqualifiedRecord::getUpdateUser, pageWrap.getModel().getUpdateUser())
                .ge(pageWrap.getModel().getUpdateTime() != null, UnqualifiedRecord::getUpdateTime, Utils.Date.getStart(pageWrap.getModel().getUpdateTime()))
                .le(pageWrap.getModel().getUpdateTime() != null, UnqualifiedRecord::getUpdateTime, Utils.Date.getEnd(pageWrap.getModel().getUpdateTime()))
                .eq(pageWrap.getModel().getRemark() != null, UnqualifiedRecord::getRemark, pageWrap.getModel().getRemark())
                .eq(pageWrap.getModel().getRootDepartId() != null, UnqualifiedRecord::getRootDepartId, pageWrap.getModel().getRootDepartId())
                .eq(pageWrap.getModel().getDepartId() != null, UnqualifiedRecord::getDepartId, pageWrap.getModel().getDepartId())
                .eq(pageWrap.getModel().getWorkorderId() != null, UnqualifiedRecord::getWorkorderId, pageWrap.getModel().getWorkorderId())
                .eq(pageWrap.getModel().getRecordId() != null, UnqualifiedRecord::getRecordId, pageWrap.getModel().getRecordId())
                .eq(pageWrap.getModel().getCategoryId() != null, UnqualifiedRecord::getCategoryId, pageWrap.getModel().getCategoryId())
                .eq(pageWrap.getModel().getUnqualifiedNum() != null, UnqualifiedRecord::getUnqualifiedNum, pageWrap.getModel().getUnqualifiedNum())
        ;
        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
            if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
                queryWrapper.orderByDesc(sortData.getProperty());
            } else {
                queryWrapper.orderByAsc(sortData.getProperty());
            }
        }
        return PageData.from(unqualifiedRecordMapper.selectPage(page, queryWrapper));
    }
    @Override
    public long count(UnqualifiedRecord unqualifiedRecord) {
        QueryWrapper<UnqualifiedRecord> wrapper = new QueryWrapper<>(unqualifiedRecord);
        return unqualifiedRecordMapper.selectCount(wrapper);
    }
}
server/src/main/java/doumeemes/service/business/impl/WOutboundServiceImpl.java
@@ -2126,6 +2126,9 @@
            WOutboundInBodyBean wOutboundInBodyBean = wOutboundInBodyBeans.get(Constants.ZERO);
            //累计入库数量
            wOutboundInBodyBean.setNum(wOutboundInBodyBeans.stream().map(s -> s.getNum()).reduce(BigDecimal.ZERO, BigDecimal::add));
            if(wOutboundInBodyBean.getNum().compareTo(BigDecimal.ZERO)<=Constants.ZERO){
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "数量异常,请检查数量!");
            }
            WOutboundDetail wOutboundDetail = new WOutboundDetail();
            //查询物料数据
            MaterialDistribute materialDistribute = materialDistributeMapper.selectById(wOutboundInBodyBean.getMaterialId());
server/src/main/java/doumeemes/service/ext/CategoryExtService.java
@@ -33,4 +33,6 @@
    CategoryExtListVO getByCategoryId(Integer comid, Integer id);
    CategoryExtListVO getByCategoryId(Integer comid, Integer id,List<CategoryExtListVO> allList);
    void loadAll();
    List<CategoryExtListVO> findList(QueryCategoryExtDTO queryCategoryExtDTO);
}
server/src/main/java/doumeemes/service/ext/impl/CategoryExtServiceImpl.java
@@ -49,6 +49,12 @@
    }
    @Override
    public List<CategoryExtListVO> findList(QueryCategoryExtDTO queryCategoryExtDTO) {
        List<CategoryExtListVO> result = categoryExtMapper.selectList(queryCategoryExtDTO);
        return result;
    }
    @Override
    public List<CategoryExtListVO> getListByType(String type,Integer rootDepartId,String cateType,String id) {
        QueryCategoryExtDTO queryCategoryExtDTO=new QueryCategoryExtDTO();
        queryCategoryExtDTO.setDeleted(Constants.ZERO);
server/src/main/java/doumeemes/service/ext/impl/DepartmentExtServiceImpl.java
@@ -37,6 +37,7 @@
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import javax.annotation.PostConstruct;
import java.util.*;
import java.util.stream.Collectors;
@@ -443,6 +444,7 @@
            //加入redis缓存,存储企业信息
            RedisUtil.addObject(redisTemplate,Constants.RedisKeys.COM_DEPART_TREE_KEY+com.getId(),rootDepart);
    }
    @PostConstruct
    @Override
    public  void loadAllDepart() {
        QueryCompanyExtDTO dto = new QueryCompanyExtDTO();
@@ -796,7 +798,7 @@
            for (Department department:departmentList ) {
                this.dealDepartmentData(department,user);
            }
        }
        }
    }
    public void dealDepartmentData(Department department,LoginUserInfo user){
server/src/main/java/doumeemes/service/ext/impl/PlansExtServiceImpl.java
@@ -16,6 +16,8 @@
import doumeemes.core.utils.excel.EasyExcelUtil;
import doumeemes.core.utils.redis.RedisUtil;
import doumeemes.dao.business.PlansMapper;
import doumeemes.dao.business.UnqualifiedRecordMapper;
import doumeemes.dao.business.WorkorderMapper;
import doumeemes.dao.business.dto.*;
import doumeemes.dao.business.model.*;
import doumeemes.dao.ext.*;
@@ -34,6 +36,7 @@
import org.springframework.web.multipart.MultipartFile;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@@ -64,7 +67,8 @@
    private WorkorderHistoryExtMapper workorderHistoryExtMapper;
    @Autowired
    private WorkorderRecordExtMapper workorderRecordExtMapper;
    @Autowired
    private WorkorderMapper workorderMapper;
    @Autowired
    private RouteProcedureExtMapper routeProcedureExtMapper;
    @Autowired
@@ -89,6 +93,8 @@
    private WStockExtService  wStockExtService;
    @Autowired
    private WorkorderRecordStandardService workorderRecordStandardService;
    @Autowired
    private UnqualifiedRecordMapper unqualifiedRecordMapper;
    @Override
    public  PlansExtListVO findById(Integer id){
@@ -139,6 +145,19 @@
//        //统计已完工数量
//        param.setStatus(Constants.WORKORDER_STATUS.done);
//        plan.setDoneNum(workorderExtMapper.sumOrderNum(param));
        QueryBomExtDTO bb = new QueryBomExtDTO();
        bb.setDepartId(plan.getDepartId());
        bb.setDeleted(Constants.ZERO);
        bb.setRootDepartId(user.getRootDepartment().getId());
        bb.setMaterialId(plan.getMaterialId());
        bb.setProcedureId(plan.getProcedureId());
        BomExtListVO versionBom = bomExtMapper.selectByModel( bb);
        if(versionBom == null || StringUtils.isBlank(versionBom.getVersion()) || versionBom.getBomVersionId() == null){
            plan.setHasBom(Constants.ZERO);
        }else {
            plan.setBomType(Constants.formatIntegerNum(versionBom.getType()));
            plan.setHasBom(Constants.ONE);
        }
        return plan;
    }
@@ -197,6 +216,14 @@
//                p.setDistributNum(tp.getDistributNum());
//                p.setDoneNum(tp.getDoneNum());
                p.setIsStock(wStockExtService.isStockForPlan(p));
                p.setHasExpire(false);
                p.setStatus(Constants.formatIntegerNum(p.getStatus()));
                if ( !p.getStatus().equals(Constants.PLAN_STATUS.done) &&
                        !p.getStatus().equals(Constants.PLAN_STATUS.close)){
                    if (Objects.nonNull(p.getPlanDate())){
                        p.setHasExpire(DateUtil.toDateLocalDateTime(p.getWorkPlanPlanDate()).toLocalDate().isBefore(LocalDate.now()));
                    }
                }
            }
        }
        return PageData.from(new PageInfo<>(result));
@@ -592,7 +619,7 @@
        if(Constants.equalsInteger(mp.getPaused(),Constants.ONE)){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "对不起,计划已暂停!");
        }
        if(Constants.formatIntegerNum(mp.getDistributNum())+thisPlanNum > Constants.formatIntegerNum(mp.getNum())){
        if(Constants.formatIntegerNum(mp.getWorkorderDistributNum())+thisPlanNum > Constants.formatIntegerNum(mp.getNum())){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "对不起,累计分配数量大于计划数量!");
        }
        if(!Constants.equalsInteger(mp.getStatus(),Constants.PLAN_STATUS.publish)&&!Constants.equalsInteger(mp.getStatus(),Constants.PLAN_STATUS.distribute)){
@@ -678,9 +705,9 @@
        if(ulist == null){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "对不起,生产人员信息不正确,请刷新页面重试!");
        }
        if(ulist.size() < param.getProUserList().size()){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "对不起,存在生产人员信息不正确,请刷新页面重试!");
        }
//        if(ulist.size() < param.getProUserList().size()){
//            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "对不起,存在生产人员信息不正确,请刷新页面重试!");
//        }
        List<WorkorderUser> userList = new ArrayList<>();
        for(UserDeviceExtListVO uModel : ulist){
            WorkorderUser u = new WorkorderUser();
@@ -1507,7 +1534,7 @@
    }
    /**
     * æ¢å¤è®¡åˆ’
     * @param p
     * @param
     */
    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
    @Override
@@ -1563,7 +1590,7 @@
        if(Objects.isNull(plans)){
            throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"未查询到工序计划数据");
        }
        if(!(plans.getStatus().equals(Constants.PLAN_STATUS.create)||plans.getStatus().equals(Constants.PLAN_STATUS.distribute))){
        if(!(plans.getStatus().equals(Constants.PLAN_STATUS.create)||plans.getStatus().equals(Constants.PLAN_STATUS.publish)||plans.getStatus().equals(Constants.PLAN_STATUS.distribute))){
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"工序计划已流转,无法操作");
        }
        if(plans.getPaused().equals(Constants.ONE)){
@@ -1573,7 +1600,8 @@
            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"参数错误:产出数据");
        }
        //查询工序计划已分配数量
        List<Workorder> workorderList = workorderExtMapper.selectList(new QueryWrapper<Workorder>().eq("PLAN_ID",plans.getId()).notIn("STATUS",7,8));
        List<Workorder> workorderList = workorderMapper.selectList(new QueryWrapper<Workorder>().eq("PLAN_ID",plans.getId())
                .eq("STATUS",Constants.WORKORDER_STATUS.baogong));
        //本次产出数量
        BigDecimal num = autoWorkReportDTO.getCreateWorkorderRecordDTO().getQualifiedNum().add(autoWorkReportDTO.getCreateWorkorderRecordDTO().getUnQualifiedNum());
        if(num.compareTo(BigDecimal.ZERO)<=Constants.ZERO){
@@ -1590,7 +1618,7 @@
        param.setPlanDate(new Date());
        param.setProGroupId(autoWorkReportDTO.getProGroupId());
        param.setProUserList(autoWorkReportDTO.getProUserList());
        param.setPlanNum(plans.getNum());
        param.setPlanNum(num.intValue());
        //生成工单信息
        Workorder workorder = this.distributeDone(user,param,plans.getNum());
        //工单投料记录
@@ -1601,7 +1629,8 @@
            workorderRecordStandardService.createMaterialStandard(createMaterialDTO);
        }
        //工单产出记录
        workorderRecordStandardService.createWorkorderRecord(autoWorkReportDTO.getCreateWorkorderRecordDTO(),user);
        autoWorkReportDTO.getCreateWorkorderRecordDTO().setWorkorderId(workorder.getId());
        WorkorderRecord workorderRecord = workorderRecordStandardService.createWorkorderRecord(autoWorkReportDTO.getCreateWorkorderRecordDTO(),user);
        //工单报工
        workorderRecordStandardService.comfirmDone(workorder);
        //更新工单状态
@@ -1613,8 +1642,35 @@
            }
        }
        plansExtMapper.updateById(plans);
        //存储报工不良项数据
        if(autoWorkReportDTO.getCreateWorkorderRecordDTO().getUnQualifiedNum().compareTo(BigDecimal.ZERO)<=Constants.ZERO){
            if(!Objects.isNull(autoWorkReportDTO.getCreateUnqualifiedDTOList())&&autoWorkReportDTO.getCreateUnqualifiedDTOList().size()>Constants.ZERO){
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"不良项错误:请检查不良项数据");
            }
        }else{
            List<CreateUnqualifiedDTO> createUnqualifiedDTOList = autoWorkReportDTO.getCreateUnqualifiedDTOList();
            BigDecimal unqualified = createUnqualifiedDTOList.stream().map(s -> s.getUnQualifiedNum()).reduce(BigDecimal.ZERO, BigDecimal::add);
            if(unqualified.compareTo(autoWorkReportDTO.getCreateWorkorderRecordDTO().getUnQualifiedNum())!=Constants.ZERO){
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"不良项错误:请检查不良项数据");
            }
            for (CreateUnqualifiedDTO createUnqualifiedDTO:createUnqualifiedDTOList) {
                if(createUnqualifiedDTO.getUnQualifiedNum().compareTo(BigDecimal.ZERO)==Constants.ZERO
                ||Objects.isNull(createUnqualifiedDTO.getCategoryId())){
                    throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"不良项错误:请检查不良项数据");
                }
                UnqualifiedRecord unqualifiedRecord = new UnqualifiedRecord();
                unqualifiedRecord.setDeleted(Constants.ZERO);
                unqualifiedRecord.setCreateUser(user.getId());
                unqualifiedRecord.setCreateTime(new Date());
                unqualifiedRecord.setRootDepartId(plans.getRootDepartId());
                unqualifiedRecord.setDepartId(plans.getDepartId());
                unqualifiedRecord.setWorkorderId(workorder.getId());
                unqualifiedRecord.setRecordId(workorderRecord.getId());
                unqualifiedRecord.setCategoryId(createUnqualifiedDTO.getCategoryId());
                unqualifiedRecord.setUnqualifiedNum(createUnqualifiedDTO.getUnQualifiedNum());
                unqualifiedRecordMapper.insert(unqualifiedRecord);
            }
        }
    }
server/src/main/java/doumeemes/service/ext/impl/WorkPlansExtServiceImpl.java
@@ -175,12 +175,16 @@
                    i.setFinishUnQualifiedNum(Objects.isNull(plansExtListVO.getUnqulifiedNum())?Constants.ZERO:plansExtListVO.getUnqulifiedNum());
                    i.setFinishNum(Objects.isNull(plansExtListVO.getDoneNum())?Constants.ZERO:plansExtListVO.getDoneNum());
                }
                if (Objects.nonNull(i.getPlanDate())){
                    i.setHasExpire(DateUtil.toDateLocalDateTime(i.getPlanDate()).toLocalDate().isBefore(LocalDate.now()));
                }else {
                    i.setHasExpire(false);
                i.setHasExpire(false);
                i.setStatus(Constants.formatIntegerNum(i.getStatus()));
                if ( !i.getStatus().equals(Constants.WORKPLANHISTORY_TYPE.done) &&
                        !i.getStatus().equals(Constants.WORKPLANHISTORY_TYPE.close)){
                    if (Objects.nonNull(i.getPlanDate())){
                        i.setHasExpire(DateUtil.toDateLocalDateTime(i.getPlanDate()).toLocalDate().isBefore(LocalDate.now()));
                    }
                }
            });
        }
        return PageData.from(new PageInfo<>(result));
server/src/main/java/doumeemes/service/ext/impl/WorkorderRecordStandardServiceImpl.java
@@ -669,13 +669,13 @@
            if (bomDetailList == null || bomDetailList.size() == 0) {
                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "对不起,该生产物料的bom配置有误,请联系管理员!");
            }
            for (BomDetailExtListVO i :bomDetailList) {
                //查询是否投料
                if(workorderRecordExtMapper.selectCount(new QueryWrapper<WorkorderRecord>()
                        .eq("DELETED",Constants.ZERO).eq("MATERIAL_ID",i.getMaterialId()).eq("TYPE",Constants.ZERO))<=0){
                    throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"存在未投料BOM物料,无法进行报工");
                }
            }
//            for (BomDetailExtListVO i :bomDetailList) {
//                //查询是否投料
//                if(workorderRecordExtMapper.selectCount(new QueryWrapper<WorkorderRecord>()
//                        .eq("DELETED",Constants.ZERO).eq("MATERIAL_ID",i.getMaterialId()).eq("TYPE",Constants.ZERO))<=0){
//                    throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"存在未投料BOM物料,无法进行报工");
//                }
//            }
        }
        WOutbound outbound = new WOutbound();
@@ -794,6 +794,126 @@
//    private void dealAppliancePro(Workorder mp
//            , LoginUserInfo user
//            , List<WorkorderRecordExtListVO> allRecordList
//            , List<Appliances> updateApplianceList
//            , List<Appliances> updateApplianceProList
//            ,   List<WOutboundDetail> outboundDetailList
//            ,   List<WStock> stockList) {
//        WOutbound outbound = new WOutbound();
//        outbound.setDeleted(Constants.ZERO);
//        outbound.setCreateTime(DateUtil.getCurrentDate());
//        outbound.setDealDate(outbound.getCreateTime());
//        outbound.setValidDate(outbound.getCreateTime());
//        outbound.setCreateUser(user.getId());
//        outbound.setRootDepartId(mp.getRootDepartId());
//        outbound.setDepartId(mp.getDepartId());
//        outbound.setStatus(Constants.WOUTBOUND_STATUS.dealed);
//        outbound.setType(Constants.WOUTBOUND_TYPE.in);
//        //2022å¹´7月1日14:42:41 åŠ å…¥å•æ®ç±»åˆ«
//        outbound.setBillType(Constants.WOUTBOUND_BILLTYPE.workerOrderIn);
//        outbound.setCode(wOutboundService.getNextInCode(user.getCompany().getId()));
//        outbound.setOrigin(Constants.ONE);
//        outbound.setOriginType(Constants.WOUTBOUND_ORIGIN_TYPE.produce);
//        outbound.setOriginCode(mp.getCode());
//        outbound.setOriginId(mp.getId());
//        outbound.setPlanDate(DateUtil.getCurrentDate());
//        outbound.setProcedureId(mp.getProcedureId());
//        outbound.setUserId(user.getId());
//        outbound.setWarehouseId(mp.getFinishWarehouseId());
//        wOutboundService.create(outbound);
//
//        List<WOutboundDetail> detailList = new ArrayList<>();
//        List<WOutboundRecord> recordList = new ArrayList<>();
//        for(WorkorderRecordExtListVO tModel :allRecordList){
//            if(Constants.equalsInteger(tModel.getType(),Constants.WORKORDER_RECORD_TYPE.produce)){
//                if(tModel.getNum().compareTo(BigDecimal.ZERO)<=Constants.ZERO){
//                    continue;
//                }
//                //如果是产出
//                mp.setHasProduceNum(Constants.formatBigdecimal(tModel.getNum()).intValue()+Constants.formatIntegerNum(mp.getHasProduceNum()));
//
//                //物料+批次+工序+质量属性去重
//                WOutboundDetail detail =getWoutbondDetailByList(tModel,detailList);
//                if(detail!=null){
//                    detail.setNum(Constants.formatBigdecimal(detail.getNum()).add(tModel.getNum()));
//                }else{
//                    detail = new WOutboundDetail();
//                    detail.setDeleted(Constants.ZERO);
//                    detail.setCreateTime(DateUtil.getCurrentDate());
//                    detail.setCreateUser(user.getId());
//                    detail.setOutboundId(outbound.getId());
//                    detail.setRootDepartId(outbound.getRootDepartId());
//                    detail.setWarehouseId(outbound.getWarehouseId());
//                    detail.setLocationId(mp.getFinishWarehouseLocationId());
//                    detail.setNum(tModel.getNum());
//                    detail.setStatus(Constants.ONE);
//                    detail.setDoneNum(tModel.getNum());
//                    detail.setDoneDate(new Date());
//                    detail.setUnitId(tModel.getUnitId());
//                    detail.setBatch(tModel.getMaterialBatch());
//                    detail.setProcedureId(tModel.getProcedureId());
//                    detail.setMaterialId(tModel.getMaterialId());
//                    detail.setQualityType(tModel.getDoneType());
//                    detail.setWOutboundRecordInList(new ArrayList<>());
//                    detailList.add(detail);
//                }
//
//                WOutboundRecord record = new WOutboundRecord();
//                record.setDeleted(Constants.ZERO);
//                record.setCreateTime(DateUtil.getCurrentDate());
//                record.setCreateUser(user.getId());
//                record.setAppliancesId(tModel.getAppliancesId());
//                record.setBatch(detail.getBatch());
//                record.setRootDepartId(mp.getRootDepartId());
//                record.setNum(tModel.getNum());
//                record.setOutboundId(detail.getOutboundId());
//                record.setUnitId(detail.getUnitId());
//                record.setWarehouseId(detail.getWarehouseId());
//                record.setMaterialId(detail.getMaterialId());
//                record.setProcedureId(detail.getProcedureId());
//                record.setLocationId(detail.getLocationId());
//                record.setQualityType(detail.getQualityType());
//                detail.getWOutboundRecordInList().add(record);
//
//                WStock stock = getFromStockList(mp.getFinishWarehouseLocationId(),detail.getWarehouseId(),detail.getMaterialId(),detail.getBatch(),
//                        tModel.getProcedureId(),tModel.getDoneType(),stockList);
//                if(stock!=null){
//                    //如果库存对象已存在,直接增加对应的库存量
//                    stock.setNum(Constants.formatBigdecimal(stock.getNum()).add(Constants.formatBigdecimal(tModel.getNum())));
//                }else{
//                    stock = new WStock();
//                    stock.setMaterialId(detail.getMaterialId());
//                    stock.setBatch(detail.getBatch());
//                    stock.setWarehouseId(outbound.getWarehouseId());
//                    stock.setLocationId(mp.getFinishWarehouseLocationId());
//                    stock.setUnitId(detail.getUnitId());
//                    stock.setNum(Constants.formatBigdecimal(tModel.getNum()));
//                    stock.setProcedureId(tModel.getProcedureId());
//                    stock.setQualityType(tModel.getDoneType());
//                    //待更新库存信息
//                    stockList.add(stock);
//                }
//            }
//        }
//        for(WOutboundDetail detail : detailList){
//            wOutboundDetailExtMapper.insert(detail);
//            //记录库存变动记录
//            wStockRecordExtService.saveRecord(Constants.ONE,detail.getId(),user);
//            if(detail.getWOutboundRecordInList()!=null){
//                for(WOutboundRecord r : detail.getWOutboundRecordInList()){
//                    r.setDetailId(detail.getId());
//                    wOutboundRecordExtMapper.insert(r);
//                }
//            }
//        }
//        if(Constants.formatIntegerNum(mp.getHasProduceNum()) >Constants.formatIntegerNum(mp.getPlanNum())){
//            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "对不起,该工单的产出数量不能大于工单计划数量!");
//        }
//    }
    private void dealAppliancePro(Workorder mp
            , LoginUserInfo user
            , List<WorkorderRecordExtListVO> allRecordList
@@ -833,78 +953,10 @@
                }
                //如果是产出
                mp.setHasProduceNum(Constants.formatBigdecimal(tModel.getNum()).intValue()+Constants.formatIntegerNum(mp.getHasProduceNum()));
                if(tModel.getDoneType() == null){
                    throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(), "对不起,工装器具【"+tModel.getAmodel().getCode()+"】产出质量属性为空,无法报工!");
                }
                if(!Constants.equalsInteger(tModel.getDoneType(),Constants.ZERO)){
                    //如果不良,累计工单的不良产出
                    mp.setUnqualifiedNum(Constants.formatIntegerNum(mp.getUnqualifiedNum())+(Constants.formatBigdecimal(tModel.getNum()).intValue()));
                }else{
                    //如果是合格,累计工单的合格数量
                    mp.setQualifiedNum(Constants.formatIntegerNum(mp.getQualifiedNum())+(Constants.formatBigdecimal(tModel.getNum()).intValue()));
                }
                //物料+批次+工序+质量属性去重
                WOutboundDetail detail =getWoutbondDetailByList(tModel,detailList);
                if(detail!=null){
                    detail.setNum(Constants.formatBigdecimal(detail.getNum()).add(tModel.getNum()));
                }else{
                    detail = new WOutboundDetail();
                    detail.setDeleted(Constants.ZERO);
                    detail.setCreateTime(DateUtil.getCurrentDate());
                    detail.setCreateUser(user.getId());
                    detail.setOutboundId(outbound.getId());
                    detail.setRootDepartId(outbound.getRootDepartId());
                    detail.setWarehouseId(outbound.getWarehouseId());
                    detail.setLocationId(mp.getFinishWarehouseLocationId());
                    detail.setNum(tModel.getNum());
                    detail.setStatus(Constants.ONE);
                    detail.setDoneNum(tModel.getNum());
                    detail.setDoneDate(new Date());
                    detail.setUnitId(tModel.getUnitId());
                    detail.setBatch(tModel.getMaterialBatch());
                    detail.setProcedureId(tModel.getProcedureId());
                    detail.setMaterialId(tModel.getMaterialId());
                    detail.setQualityType(tModel.getDoneType());
                    detail.setWOutboundRecordInList(new ArrayList<>());
                    detailList.add(detail);
                }
                WOutboundRecord record = new WOutboundRecord();
                record.setDeleted(Constants.ZERO);
                record.setCreateTime(DateUtil.getCurrentDate());
                record.setCreateUser(user.getId());
                record.setAppliancesId(tModel.getAppliancesId());
                record.setBatch(detail.getBatch());
                record.setRootDepartId(mp.getRootDepartId());
                record.setNum(tModel.getNum());
                record.setOutboundId(detail.getOutboundId());
                record.setUnitId(detail.getUnitId());
                record.setWarehouseId(detail.getWarehouseId());
                record.setMaterialId(detail.getMaterialId());
                record.setProcedureId(detail.getProcedureId());
                record.setLocationId(detail.getLocationId());
                record.setQualityType(detail.getQualityType());
                detail.getWOutboundRecordInList().add(record);
                WStock stock = getFromStockList(mp.getFinishWarehouseLocationId(),detail.getWarehouseId(),detail.getMaterialId(),detail.getBatch(),
                        tModel.getProcedureId(),tModel.getDoneType(),stockList);
                if(stock!=null){
                    //如果库存对象已存在,直接增加对应的库存量
                    stock.setNum(Constants.formatBigdecimal(stock.getNum()).add(Constants.formatBigdecimal(tModel.getNum())));
                }else{
                    stock = new WStock();
                    stock.setMaterialId(detail.getMaterialId());
                    stock.setBatch(detail.getBatch());
                    stock.setWarehouseId(outbound.getWarehouseId());
                    stock.setLocationId(mp.getFinishWarehouseLocationId());
                    stock.setUnitId(detail.getUnitId());
                    stock.setNum(Constants.formatBigdecimal(tModel.getNum()));
                    stock.setProcedureId(tModel.getProcedureId());
                    stock.setQualityType(tModel.getDoneType());
                    //待更新库存信息
                    stockList.add(stock);
                }
                //产出合格
               this.createOutDetail(user,outbound,mp,tModel,Constants.ZERO,detailList,stockList);
               //产出不良
                this.createOutDetail(user,outbound,mp,tModel,Constants.ONE,detailList,stockList);
            }
        }
        for(WOutboundDetail detail : detailList){
@@ -922,6 +974,68 @@
            throw new BusinessException(ResponseStatus.BAD_REQUEST.getCode(), "对不起,该工单的产出数量不能大于工单计划数量!");
        }
    }
    public void createOutDetail(LoginUserInfo user,WOutbound outbound,Workorder mp,WorkorderRecordExtListVO tModel,Integer doneType
            ,List<WOutboundDetail> detailList,List<WStock> stockList ){
        //物料+批次+工序+质量属性去重
        WOutboundDetail detail =  new WOutboundDetail();
        detail.setDeleted(Constants.ZERO);
        detail.setCreateTime(DateUtil.getCurrentDate());
        detail.setCreateUser(user.getId());
        detail.setOutboundId(outbound.getId());
        detail.setRootDepartId(outbound.getRootDepartId());
        detail.setWarehouseId(outbound.getWarehouseId());
        detail.setLocationId(mp.getFinishWarehouseLocationId());
        detail.setNum(BigDecimal.valueOf(doneType.equals(Constants.ZERO)?tModel.getQualifiedNum():tModel.getUnqualifiedNum()));
        detail.setStatus(Constants.ONE);
        detail.setDoneNum(detail.getNum());
        detail.setDoneDate(new Date());
        detail.setUnitId(tModel.getUnitId());
        detail.setBatch(tModel.getMaterialBatch());
        detail.setProcedureId(tModel.getProcedureId());
        detail.setMaterialId(tModel.getMaterialId());
        detail.setQualityType(doneType);
        detail.setWOutboundRecordInList(new ArrayList<>());
        detailList.add(detail);
        WOutboundRecord record = new WOutboundRecord();
        record.setDeleted(Constants.ZERO);
        record.setCreateTime(DateUtil.getCurrentDate());
        record.setCreateUser(user.getId());
        record.setAppliancesId(tModel.getAppliancesId());
        record.setBatch(detail.getBatch());
        record.setRootDepartId(mp.getRootDepartId());
        record.setNum(tModel.getNum());
        record.setOutboundId(detail.getOutboundId());
        record.setUnitId(detail.getUnitId());
        record.setWarehouseId(detail.getWarehouseId());
        record.setMaterialId(detail.getMaterialId());
        record.setProcedureId(detail.getProcedureId());
        record.setLocationId(detail.getLocationId());
        record.setQualityType(detail.getQualityType());
        detail.getWOutboundRecordInList().add(record);
        WStock stock = getFromStockList(mp.getFinishWarehouseLocationId(),detail.getWarehouseId(),detail.getMaterialId(),detail.getBatch(),
                tModel.getProcedureId(),tModel.getDoneType(),stockList);
        if(stock!=null){
            //如果库存对象已存在,直接增加对应的库存量
            stock.setNum(Constants.formatBigdecimal(stock.getNum()).add(Constants.formatBigdecimal(tModel.getNum())));
        }else{
            stock = new WStock();
            stock.setMaterialId(detail.getMaterialId());
            stock.setBatch(detail.getBatch());
            stock.setWarehouseId(outbound.getWarehouseId());
            stock.setLocationId(mp.getFinishWarehouseLocationId());
            stock.setUnitId(detail.getUnitId());
            stock.setNum(Constants.formatBigdecimal(tModel.getNum()));
            stock.setProcedureId(tModel.getProcedureId());
            stock.setQualityType(tModel.getDoneType());
            //待更新库存信息
            stockList.add(stock);
        }
    }
    private WStock initMaterialNum(Integer materialId, BigDecimal num) {
        WStock s = new WStock();
@@ -1247,16 +1361,14 @@
        workorderRecord.setSalaryPrice(salaryParam.getSalary());
        workorderRecord.setSalaryType(salaryParam.getType());
        workorderRecord.setSalaryUnqualified(salaryParam.getUnqualified());
        //计件工资
        if(salaryParam.getType().equals(Constants.ZERO)){
            workorderRecord.setSalaryNum(salaryParam.getNum());
            workorderRecord.setSalary(salaryParam.getSalary().multiply(salaryParam.getUnqualified()==Constants.ZERO?num:createWorkorderRecordDTO.getUnQualifiedNum()));
            workorderRecord.setSalary(salaryParam.getSalary().multiply(salaryParam.getUnqualified()==Constants.ONE?num:createWorkorderRecordDTO.getQualifiedNum()));
        }else{
            workorderRecord.setDuration(createWorkorderRecordDTO.getDuration());
            workorderRecord.setSalary(BigDecimal.valueOf(createWorkorderRecordDTO.getDuration()).multiply(salaryParam.getSalary()).divide(new BigDecimal(3600)));
        }
        //插入工单操作记录,并且判断是否更改为工单的状态【生产中】
        updateOrderInfo(loginUserInfo,workorder,Constants.WORKORDER_HISTORY_STATUS.produce);
        workorderRecordExtMapper.insert(workorderRecord);
server/src/main/resources/mappers/PlansExtMapper.xml
@@ -123,7 +123,7 @@
  <select id="selectByModel" parameterType="doumeemes.dao.ext.dto.QueryPlansExtDTO" resultMap="PlansExtListVO">
  SELECT
  `a`.*
    ,(  SELECT sum( b.PLAN_NUM ) FROM  workorder b  WHERE b.deleted = 0 AND b.PLAN_ID = a.id and b.status !=6) AS workorderDistributNum
    ,ifnull((  SELECT sum( b.PLAN_NUM ) FROM  workorder b  WHERE b.deleted = 0 AND b.PLAN_ID = a.id and b.status not in (7,8) ),0) AS workorderDistributNum
    from plans a
    <where>
    <if test="id != null">
@@ -363,13 +363,13 @@
      `usermodel`.`SYSTEMID` AS USERMODEL_SYSTEMID,
      `usermodel`.`INVALID_TIME` AS USERMODEL_INVALID_TIME,
      `usermodel`.`TYPE` AS USERMODEL_TYPE
    ,(  SELECT sum( b.PLAN_NUM ) FROM  workorder b  WHERE b.deleted = 0 AND b.PLAN_ID = a.id  and b.status !=6) AS workorderDistributNum ,
    , ifnull((  SELECT sum( b.PLAN_NUM ) FROM  workorder b  WHERE b.deleted = 0  AND b.PLAN_ID = a.id  and b.status !=6),0) AS workorderDistributNum ,
    `mmodel`.name as materialName , `mmodel`.code as materialCode ,`fmodel`.name as factoryName , `pmodel`.name as produceName ,
      concat(`usermodel`.realname,' ',`usermodel`.mobile) as planUserName , `umodel`.name as unitName ,
      w.PLAN_CODE as workPlanCode , w.SALESORDER as salesOrder ,
      w.START_DATE as workPlanStartDate  , w.PLAN_DATE as workPlanEndDate,
      w.`PLAN_DATE` as workPlanPlanDate,
      ifnull((select  sum(worder.PLAN_NUM) from workorder worder where worder.PLAN_ID = a.id and worder.STATUS not in (7,8)  ),0) as produceNum
    FROM `plans` `a`
    LEFT JOIN `department` `dmodel` ON a.DEPART_ID=dmodel.ID
    LEFT JOIN `material_distribute` `mdmodel` ON a.MATERIAL_ID=mdmodel.ID
@@ -422,6 +422,12 @@
      </if>
      <if test="planDate != null">
        AND `a`.`PLAN_DATE` = #{planDate}
      </if>
      <if test="planDateStartDate != null and planDateStartDate != ''">
        AND `a`.`PLAN_DATE` >= concat(#{planDateStartDate},' 00:00:00')
      </if>
      <if test="planDateEndDate != null and planDateEndDate != ''">
        AND concat(#{planDateEndDate},' 23:59:59') >= `a`.`PLAN_DATE`
      </if>
      <if test="materialId != null">
        AND `a`.`MATERIAL_ID` = #{materialId}
@@ -765,12 +771,12 @@
      <if test="usermodelInvalidTime != null">
        AND `usermodel`.`INVALID_TIME` = #{usermodelInvalidTime}
      </if>
      <if test="startDate != null">
        AND `a`.`PLAN_DATE` >= #{startDate}
      </if>
      <if test="endDate != null">
        AND   #{endDate} >= `a`.`PLAN_DATE`
      </if>
<!--      <if test="startDate != null">-->
<!--        AND `a`.`PLAN_DATE` >= #{startDate}-->
<!--      </if>-->
<!--      <if test="endDate != null">-->
<!--        AND   #{endDate} >= `a`.`PLAN_DATE`-->
<!--      </if>-->
      <if test="mixParam != null and mixParam!=''">
        AND  (mmodel.name like concat('%',#{mixParam},'%') or mmodel.code like concat('%',#{mixParam},'%') or pmodel.name like concat('%',#{mixParam},'%'))
      </if>
server/src/main/resources/mappers/SalaryParamMapper.xml
@@ -13,14 +13,16 @@
        from
            salary_param sp
        LEFT JOIN procedures p on p.ID = sp.PROCEDURE_ID
        LEFT JOIN material m on m.ID = sp.MATERIAL_ID
        LEFT JOIN material_distribute md on md.ID = sp.MATERIAL_ID
        LEFT JOIN material m on m.ID = md.MATERIAL_ID
        LEFT JOIN `system_user` su  on su.ID = sp.CREATE_USER
        where
        sp.DELETED = 0
        <if test="model.keyWord != null and model.keyWord != ''">
           and  ( p`NAME` like concat('%',#{model.keyWord},'%')
            or   p.`CODE` = #{model.keyWord})</if>
           and  ( m.`NAME` like concat('%',#{model.keyWord},'%')
            or   m.`CODE` = #{model.keyWord})</if>
        <if test="model.procedureName != null and model.procedureName != ''"> and p.`NAME` like concat('%',#{model.procedureName},'%')</if>
        <if test="model.type != null"> and sp.`TYPE` = #{model.type}</if>
        order by sp.CREATE_TIME desc
    </select>
</mapper>
server/src/main/resources/mappers/UserDeviceExtMapper.xml
@@ -201,7 +201,7 @@
        AND `umodel`.`ROOT_DEPART_ID` = #{umodelRootDepartId}
      </if>
      <if test="umodelName != null and umodelName != ''">
        AND `umodel`.`NAME` = #{umodelName}
        AND `umodel`.`NAME` like concat('%', #{umodelName} , '%')
      </if>
      <if test="umodelPhone != null and umodelPhone != ''">
        AND `umodel`.`PHONE` = #{umodelPhone}
server/src/main/resources/mappers/WorkPlansExtMapper.xml
@@ -156,10 +156,10 @@
        AND `a`.`SALESORDER` like concat('%',#{salesorder},'%')
      </if>
      <if test="startDateStart != null and startDateStart != ''">
        AND `a`.`START_DATE` >= concat(#{planDateStart},' 00:00:00')
        AND `a`.`START_DATE` >= concat(#{startDateStart},' 00:00:00')
      </if>
      <if test="startDateEnd != null and startDateEnd != ''">
        AND concat(#{planDateEnd},' 23:59:59') >= `a`.`START_DATE`
        AND concat(#{startDateEnd},' 23:59:59') >= `a`.`START_DATE`
      </if>
      <if test="planDateStart != null and planDateStart != ''">
        AND `a`.`PLAN_DATE` >= concat(#{planDateStart},' 00:00:00')
@@ -168,7 +168,7 @@
        AND concat(#{planDateEnd},' 23:59:59') >= `a`.`PLAN_DATE`
      </if>
    </where>
        order by a.PLAN_DATE desc, a.CREATE_TIME  desc
        order by a.START_DATE desc, a.CREATE_TIME  desc
  </select>
server/src/main/resources/mappers/WorkorderRecordExtMapper.xml
@@ -453,11 +453,11 @@
    <if test="materialName != null and materialName !=''">
      AND  (c.`name` like concat('%', #{materialName},'%') or c.`code` like concat('%', #{materialName},'%'))
    </if>
    <if test="startDate != null">
      AND  a.`CREATE_TIME` >= #{startDate}
    <if test="startDate != null and startDate != ''">
      AND  a.`CREATE_TIME` >= concat(#{startDate},' 00:00:00')
    </if>
    <if test="endDate != null">
      AND   #{endDate} >= a.`CREATE_TIME`
    <if test="endDate != null and endDate != ''">
      AND   concat(#{endDate},' 23:59:59') >= a.`CREATE_TIME`
    </if>
    <if test="userId != null">
      AND  a.`CREATE_USER` = #{userId}
@@ -479,10 +479,10 @@
      AND  `CREATE_USER` = #{userId}
    </if>
    <if test="startDate != null">
      AND  a.`CREATE_TIME` >= #{startDate}
      AND  `CREATE_TIME` >= #{startDate}
    </if>
    <if test="endDate != null">
      AND   #{endDate} >= a.`CREATE_TIME`
      AND   #{endDate} >= `CREATE_TIME`
    </if>
    group by  `CREATE_USER`
   <!-- order by `CREATE_TIME` desc-->