guoyuji
2024-10-14 fcc92299eb3fb49835fa6975c67730018b451803
north-glass-erp/northglass-erp/src/views/mm/ingredientStock/CreateOutBound.vue
New file
@@ -0,0 +1,608 @@
<!--物料出库-->
<script setup>
import {onMounted, reactive, ref} from "vue";
import {Search} from "@element-plus/icons-vue";
import {useRoute, useRouter} from "vue-router"
import request from "@/utils/request"
import deepClone from "@/utils/deepClone"
import VXETable from "vxe-table";
import useUserInfoStore from "@/stores/userInfo";
import {ElMessage} from "element-plus";
import {addListener,toolbarButtonClickEvent} from "@/hook/mouseMove";
import { useI18n } from 'vue-i18n'
import {changeFilterEvent,filterChanged} from "@/hook"
const { t } = useI18n()
const router = useRouter()
const route = useRoute()
const userStore = useUserInfoStore()
const username = userStore.user.userName
const userid = userStore.user.userId
let produceList = ref([])
let cellArea = ref()
const getTableRow = (row,type) =>{
  switch (type) {
    case 'edit' :{
      alert('我接收到子组件传送的编辑信息')
      router.push({path: '/main/trader/CreateTrader', query: { id: row.id }})
      break
    }
    case 'delete':{
      alert('我接收到子组件传送的删除信息')
      break
    }
  }
}
const hasDecimal=(value)=>{
  const regex=/\./ // 定义正则表达式,查找小数点
  return regex.test(value) //返回true/false
}
const hasDecimalhtml=(item,row)=>{
  let aa=item.split('.').length
  if (aa===2){
    return row[item.split('.')[0]][item.split('.')[1]]
  }else if(aa===3){
    return row[item.split('.')[0]][item.split('.')[1]][item.split('.')[2]]
  }
}
//定义接收加载表头下拉数据
const titleSelectJson = ref({
  outboundType:""
})
// 定义表头上传数据
let titleUploadData = ref({
  outboundType:'',
  materialOutboundId:'',
  materialRequisitionPersonnel:'',
  materialRequisitionTeam:'',
  orderId:'',
  materialRequisitionDate:'',
  reviewedState:'',
  reviewed:'',
  warehouseManager:userStore.user.userName
})
let filterData = ref({
})
let optimizeUse = ref({
  id:0
})
let BasicData = ref([])
let materialStore= ref([])
let arr = [
  //{type:'expand',fixed:"left",slots: { content:'content' },width: '60'},
  {field: 'select',type: 'checkbox',fixed:"left", title: t('basicData.check'), width: '80' },
  { type: 'seq',fixed:"left", title: t('basicData.Number'), width: '80' },
  {field: 'inventoryOrganization', width:'150', title: t('ingredientsStock.inventoryOrganization'), sortable: true,filters:[{ data: '' }],slots: { filter: 'num1_filter' },filterMethod:filterChanged },
  {field: 'materialCode', width: '150',title: t('ingredients.materialCode'), sortable: true,showOverflow:"ellipsis" ,filters:[{ data: '' }],slots: { filter: 'num1_filter' },filterMethod:filterChanged},
  {field: 'producer', width: '100',title: t('ingredientsStock.producer'), sortable: true,filters:[{ data: '' }],slots: { filter: 'num1_filter' },filterMethod:filterChanged},
  {field: 'projectNo', width: '100',title: t('ingredientsStock.projectNo'), sortable: true,filters:[{ data: '' }],slots: { filter: 'num1_filter' },filterMethod:filterChanged},
  {field: 'inventoryQuantity',width: '100', title: t('productStock.inventoryQuantity'), sortable: true,filters:[{ data: '' }],slots: { filter: 'num1_filter' },filterMethod:filterChanged},
  {field: 'availableQuantity', width: '100',title: t('productStock.availableQuantity'), sortable: true,filters:[{ data: '' }],slots: { filter: 'num1_filter' },filterMethod:filterChanged},
  {field: 'outboundQuantity', width:'150', title: t('ingredientsStock.outboundQuantity'), sortable: true,editRender: { name: 'input', attrs: { placeholder: '' } }},
  {field: 'singlePieceArea', width: '100',title: t('productStock.singlePieceArea'), sortable: true,filters:[{ data: '' }],slots: { filter: 'num1_filter' },filterMethod:filterChanged},
  {field: 'dateOfManufacture',width: '100', title: t('ingredientsStock.dateOfManufacture'), sortable: true},
  {field: 'inventoryArea',width: '100', title: t('productStock.inventoryArea'), sortable: true,filters:[{ data: '' }],slots: { filter: 'num1_filter' },filterMethod:filterChanged},
  {field: 'remarks',width: '80', title: t('basicData.remarks'), sortable: true,editRender: { name: 'input', attrs: { placeholder: '' } }},
]
//页面第一次加载
request.get(`/BasicWarehouse/BasicWarehouseTypes/`+t('ingredientsStock.materialOutboundType')).then((res) => {
  if(res.code==200){
    titleSelectJson.value=deepClone(res.data)
    const today = new Date
    today.setTime(today.getTime() + (15 * 24 * 60 * 60 * 1000))
    titleUploadData.value.materialRequisitionDate = today.getFullYear() +
        '-' + ("0" + (today.getMonth() + 1)).slice(-2)
        + '-' + ("0" + today.getDate()).slice(-2)
    getWork()
  }else{
    ElMessage.warning(res.msg)
  }
})
//列查询
const getWork = () => {
  request.get(`/BasicWarehouse/BasicWarehouseType/`+t('ingredients.originalFilm')+'|'+t('ingredients.accessories')).then((res) => {
    if(res.code==200){
      gridOptions.columns=[]
      BasicData.value = res.data
      //添加列
      gridOptions.columns=arr.slice()
      for (let i=0;i<BasicData.value.length;i++){
        let column={field: "json."+BasicData.value[i].OperateType,
          width: '150',title: BasicData.value[i].OperateTypeName,
          sortable: true,showOverflow:'ellipsis' ,
          filters:[{ data: '' }],
          slots: { filter: 'num1_filter' },
          filterMethod:filterChanged}
        gridOptions.columns.push(column)
      }
    }else{
      ElMessage.warning(res.msg)
    }
  })
}
const  number = ref();
onMounted(()=>{
  //启用表格拖动选中
  addListener(xGrid.value,gridOptions,cellArea.value)
  //出库新增
  const id = route.query.id
  const type = route.query.type
  if (typeof id !== 'undefined' && id !== null && id !== '' && id !== '\n' && id !== '\r'){
    if(type===t('ingredientsStock.inventory')){
      filterData.value.stockId=id
      number.value=id
      request.post("/materialInventory/getSelectMaterialInventory/1/100",filterData.value).then((res) => {
        if(res.code==200){
          titleUploadData.value.warehouseManager=userStore.user.userName
          titleUploadData.value.outboundType = titleSelectJson.value.outboundType[0].operateTypeName
          materialStore.value=[]
          for (let i=0;i<res.data.data.length;i++){
            materialStore.value[i]=(res.data.data[i])
            materialStore.value[i].json=(JSON.parse(res.data.data[i].json))
          }
          produceList = deepClone(materialStore.value)
          xGrid.value.loadData(produceList)
          //禁用按钮
          gridOptions.toolbarConfig.buttons[1].disabled  = true
          gridOptions.toolbarConfig.buttons[2].disabled = true
          //显示复选框
          xGrid.value.showColumn("select")
          gridOptions.loading=false
        }else{
          ElMessage.warning(res.msg)
        }
      })
    }else{
      optimizeUse.value.rawStockCode=id
      number.value=id
      request.post("/materialInventory/getSelectMaterialInventoryEngineering/1/100",optimizeUse.value).then((res) => {
        if(res.code==200){
          titleUploadData.value.warehouseManager=userStore.user.userName
          titleUploadData.value.outboundType = titleSelectJson.value.outboundType[0].operateTypeName
          materialStore.value=[]
          for (let i=0;i<res.data.data.length;i++){
            materialStore.value[i]=(res.data.data[i])
            materialStore.value[i].json=(JSON.parse(res.data.data[i].json))
          }
          produceList = deepClone(materialStore.value)
          xGrid.value.loadData(produceList)
          //禁用按钮
          gridOptions.toolbarConfig.buttons[1].disabled  = true
          gridOptions.toolbarConfig.buttons[2].disabled = true
          //显示复选框
          xGrid.value.showColumn("select")
          gridOptions.loading=false
        }else{
          ElMessage.warning(res.msg)
        }
      })
    }
  }
//出库编辑
  const str = route.query.materialOutboundId
  if (typeof str != 'undefined' && str != null && str !== '' && str !== '\n' && str !== '\r'){
      filterData.value.materialOutboundId=str
      //第一次调用
      request.post("/materialInventory/getSelectMaterialOutbound/1/100",filterData.value).then((res) => {
        if(res.code==200){
          titleUploadData.value=deepClone(res.data.materialOutbound)
          //根据审核状态显示审核按钮或者是反审按钮
          if(titleUploadData.value.reviewedState!==0){
            gridOptions.toolbarConfig.buttons[1].disabled = true
            gridOptions.toolbarConfig.buttons[0].disabled = true
          }
          if(titleUploadData.value.reviewedState===0){
            gridOptions.toolbarConfig.buttons[2].disabled = true
          }
          materialStore.value=[]
          for (let i=0;i<res.data.data.length;i++){
            materialStore.value[i]=(res.data.data[i])
            materialStore.value[i].json=(JSON.parse(res.data.data[i].json))
          }
          produceList = deepClone(materialStore.value)
          xGrid.value.loadData(produceList)
          //隐藏复选框
          /*xGrid.value.hideColumn("select")
          gridOptions.loading=false*/
          xGrid.value.showColumn("select")
          gridOptions.loading=false
        }else{
          ElMessage.warning(res.msg)
        }
      })
  }
})
const gridEvents = {
  async toolbarButtonClick({code}) {
    const $grid = xGrid.value
    if ($grid) {
      switch (code) {
        case 'add': {
          const selectRecords = $grid.getCheckboxRecords()
          if (selectRecords.length === 0) {
            ElMessage.warning(t('productStock.unselectedData'))
            return
          }
          const errMap = await $grid.validate(selectRecords)
          if (errMap) {
            ElMessage.warning(t('productStock.dataVerificationFailed'))
            return
          }
          //表头数据校验
          const outboundType = titleUploadData.value.outboundType
          if(outboundType === null || outboundType === undefined || outboundType === ''){
            ElMessage.error(t('ingredientsStock.pleaseOutboundType'))
            return
          }
          const materialRequisitionPersonnel = titleUploadData.value.materialRequisitionPersonnel
          if(materialRequisitionPersonnel === null || materialRequisitionPersonnel === undefined || materialRequisitionPersonnel === ''){
            ElMessage.error(t('ingredientsStock.pleaseMaterialRequisitionPersonnel'))
            return
          }
          /*const materialRequisitionTeam = titleUploadData.value.materialRequisitionTeam
          if(materialRequisitionTeam === null || materialRequisitionTeam === undefined || materialRequisitionTeam === ''){
            ElMessage.error(t('ingredientsStock.pleaseMaterialRequisitionTeam'))
            return
          }*/
          /*const orderId = titleUploadData.value.orderId
          if(orderId === null || orderId === undefined || orderId === ''){
            ElMessage.error(t('ingredientsStock.pleaseOrderId'))
            return
          }*/
          let flowData = ref({
            materialOutboundDetail: selectRecords,
            title: titleUploadData.value,
            materialOutboundId: route.query.materialOutboundId
          })
          request.post("/materialInventory/saveMaterialOutbound", flowData.value).then((res) => {
            if(res.code==200 && res.data==="true"){
              ElMessage.success(t('basicData.msg.saveSuccess'))
              router.push({path: '/main/ingredientsStock/MaterialOutbound', query:{random:Math.random()}})
            }else if(res.data==="false1"){
              ElMessage.warning("数量错误,请刷新再保存")
            }else{
              ElMessage.warning(t('basicData.msg.saveFail'))
            }
          }).catch((err)=>{
            ElMessage.error(t('basicData.msg.ServerConnectionError'))
            router.push("/login")
          })
          break
        }
        case 'toExamine': {
          let flowData = ref({
            materialOutboundId: route.query.materialOutboundId,
            reviewed:userStore.user.userName,
            type: 1
          })
          request.post("/materialInventory/updateMaterialOutboundToExamine", flowData.value).then((res) => {
            if (res.code == 200 && res.data===true) {
              ElMessage.success(t('basicData.msg.ReviewSuccess'))
              router.push({path: '/main/ingredientsStock/MaterialOutbound', query:{random:Math.random()}})
            } else {
              ElMessage.warning(t('basicData.msg.reviewFail'))
            }
          }).catch((err)=>{
            ElMessage.error(t('basicData.msg.ServerConnectionError'))
            router.push("/login")
          })
          break
        }
        case 'CounterExamination': {
          let flowData = ref({
            materialOutboundId: route.query.materialOutboundId,
            type: 0
          })
          request.post("/materialInventory/updateMaterialOutboundToExamine", flowData.value).then((res) => {
            if (res.code == 200 && res.data===true) {
              ElMessage.success(t('basicData.msg.cancelReviewSuccess'))
              router.push({path: '/main/ingredientsStock/MaterialOutbound', query:{random:Math.random()}})
            } else {
              ElMessage.warning(t('basicData.msg.cancelReviewFail'))
            }
          }).catch((err)=>{
            ElMessage.error(t('basicData.msg.ServerConnectionError'))
            router.push("/login")
          })
          break
        }
      }
    }
  },
  menuClick ({ menu, row, column }) {
    const $grid = xGrid.value
    if ($grid) {
      switch (menu.code) {
        case 'copyChecked' :{
          let result = toolbarButtonClickEvent()
          if(result){
            const dataList = xGrid.value.getTableData().visibleData
            let firstVal=null;
            if(result.cell.indexOf('.')>-1){
              firstVal = eval("dataList["+result.start +"]."+result.cell)
            }else {
              firstVal=dataList[result.start][result.cell];
            }
            dataList.forEach((item,index) =>{
              if(index>=result.start && index<=result.end){
                if(result.cell.indexOf('.')>-1){
                  const  columnArr = result.cell.split('.')
                  item[columnArr[0]][columnArr[1]]  = firstVal
                }else{
                  item[result.cell]  = firstVal
                }
              }
            })
          }
          break
        }
      }
    }
  }
}
//子组件接收参数
const  xGrid = ref();
const gridOptions = reactive({
  border:  "full",//表格加边框
  keepSource: true,//保持源数据
  align: 'center',//文字居中
  stripe:true,//斑马纹
  rowConfig: {isCurrent: true, isHover: true,height: 30},//鼠标移动或选择高亮
  id: 'CreateOutBound',
  showFooter: true,//显示脚
  printConfig: {},
  importConfig: {},
  exportConfig: {},
  scrollY:{ enabled: true },//开启虚拟滚动
  showOverflow:true,
  columnConfig: {
    resizable: true,
    useKey: true
  },
  filterConfig: {   //筛选配置项
    //remote: true
  },
  customConfig: {
    storage: true
  },
  editConfig: {
    trigger: 'click',
    mode: 'row',
    showStatus: true
  },//表头参数
  columns:[
  ],//表头按钮
  toolbarConfig: {
    buttons: [
      {'code': 'add', 'name': t('basicData.save'),status: 'primary',icon: 'vxe-icon-save'},
      {'code': 'toExamine', 'name': t('basicData.review'),status: 'primary'},
      {'code': 'CounterExamination', 'name': t('basicData.cancelReview'),status: 'primary'}
    ],
    /*import: false,
    export: true,
    print: true,*/
    zoom: true,
    custom: true
  },
  data:  [
  ],//table body实际数据
  footerMethod ({ columns, data }) {//页脚函数
    return[
      columns.map((column, columnIndex) => {
        if (columnIndex === 0) {
          return '合计:'
        }
        // if (props.tableProp.footList.includes(column.field)) {
        //   return sumNum(data, column.field)
        // }
        return ''
      })
    ]
  }
})
/*数据校验*/
const validRules = ref({
  outboundQuantity: [{
    validator (e) {
      if (e.row.outboundQuantity > e.row.availableQuantity) {
        return new Error(t('ingredientsStock.theOutboundQuantityCannotBeGreaterThanTheAvailableQuantity'))
      }else if (e.row.outboundQuantity ==="") {
        return new Error(t('ingredientsStock.theOutboundQuantityCannotBeEmptyOrEqualTo0'))
      }
      const regex = /^[1-9]\d*$/g
      if ( !regex.test(e.row.outboundQuantity) ) {
        return new Error(t('productStock.pleaseEnterAPositiveInteger'))
      }
    }
  }]
})
</script>
<template>
  <div class="main-div">
  <div class="order-primary" style="background-color: white">
    <el-row>
      <el-col  :span="2"><el-text>{{$t('ingredientsStock.materialRequisitionDate')}}:</el-text></el-col>
      <el-col  :span="3"><el-input  v-model="titleUploadData.materialRequisitionDate" :readonly="true" ></el-input></el-col>
      <el-col  :span="2"><el-text>{{$t('ingredientsStock.materialRequisitionPersonnel')}}:</el-text></el-col>
      <el-col  :span="3"><el-input v-model="titleUploadData.materialRequisitionPersonnel" /></el-col>
      <el-col  :span="2"><el-text>{{$t('ingredientsStock.materialRequisitionTeam')}}:</el-text></el-col>
      <el-col  :span="3"><el-input v-model="titleUploadData.materialRequisitionTeam" /></el-col>
    </el-row>
    <el-row>
      <el-col  :span="2"><el-text>{{$t('ingredientsStock.outboundType')}}:</el-text></el-col>
      <el-col  :span="3">
        <el-select v-model="titleUploadData.outboundType"  clearable placeholder=""  >
          <el-option
              v-for="item in titleSelectJson['outboundType']"
              :key="item.id"
              :label="item.operateTypeName"
              :value="item.operateTypeName"
          />
        </el-select>
      </el-col>
      <el-col  :span="2"><el-text>{{$t('order.orderId')}}:</el-text></el-col>
      <el-col  :span="3"><el-input v-model="titleUploadData.orderId" /></el-col>
      <el-col  :span="2"><el-text>{{$t('ingredientsStock.warehouseManager')}}:</el-text></el-col>
      <el-col  :span="3"><el-input v-model="titleUploadData.warehouseManager" :readonly="true" /></el-col>
    </el-row>
  </div>
  <div class="main-div-customer">
    <vxe-grid
        max-height="100%"
        class="mytable-scrollbar"
        ref="xGrid"
        v-bind="gridOptions"
        v-on="gridEvents"
        :edit-rules="validRules"
    >
      <!--      @toolbar-button-click="toolbarButtonClickEvent"-->
      <!--      下拉显示所有信息插槽-->
      <template #content="{ row}">
        <ul class="expand-wrapper">
          <li  v-for="(item,key,index) in row">
            <span style="font-weight: bold">{{key+':  '}}</span>
            <span>{{ item }}</span>
          </li>
        </ul>
      </template>
      <!--左边固定显示的插槽-->
      <template #button_slot="{ row }">
        <el-button @click="getTableRow(row,'edit')" link type="primary" size="small">{{$t('basicData.edit')}}</el-button>
        <el-button @click="getTableRow(row,'delete')" link type="primary" size="small">{{$t('basicData.delete')}}</el-button>
      </template>
      <template #num1_filter="{ column, $panel }">
        <div>
          <div v-for="(option, index) in column.filters" :key="index">
            <input type="type" v-model="option.data" @keyup.enter.native="$panel.confirmFilter()" @input="changeFilterEvent($event, option, $panel)"/>
          </div>
        </div>
      </template>
    </vxe-grid>
  </div>
  </div>
</template>
<style scoped>
.main-div {
  width: 100%;
  height: 100%;
}
.el-col{
  border: #181818 1px solid;
}
:deep(.el-input__wrapper) {
  box-shadow: 0 0 0 0 var(--el-input-border-color, var(--el-border-color)) inset;
  cursor: default;
  border: none !important;
  background-color: transparent;
}
.order-primary{
  width: 100%;
}
.main-div-customer{
  width: 100%;
  height: 70%;
}
.vxe-grid {
  /* 禁用浏览器默认选中 */
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
</style>