Crunchy
2025-06-14 7e460156de73171f9660ce48f80703e79f8b478d
src/views/add_operation/index.vue
@@ -1,72 +1,38 @@
<template>
  <div class="addOperation">
    <div class="addOperation-main">
      <!-- <el-form v-model="statusType" ref="queryForm" size="small" :inline="true" label-width="68px">
            <el-form-item label="入库状态">
           <el-radio-group v-model="inStatus">
            <el-radio-button label="全部"></el-radio-button>
            <el-radio-button label="已入库"></el-radio-button>
            <el-radio-button label="已出库"></el-radio-button>
          </el-radio-group>
            </el-form-item>
            <el-form-item label="入库类型" prop="phonenumber">
             <el-radio-group v-model="inType">
            <el-radio-button label="条码打印"></el-radio-button>
          </el-radio-group>
          </el-form-item>
          <el-form-item label="条码打印">
            <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">新增条码打印</el-button>
          </el-form-item>
      </el-form> -->
     <el-row type="flex" align="middle" class="main-top">
      <el-col :span="2"><el-button type="primary">新增入库</el-button></el-col>
        <el-col :span="2"><el-button icon="el-icon-plus" type="primary" @click="addOperation">新增入库</el-button></el-col>
      <el-col :span="20">
        <TableSearch></TableSearch>
          <TableSearch :show="true" :excel-name="'入库表'" :file="file" :get-list="getList" :search-data="searchData" :search-params="searchModel" :options="options" />
      </el-col>
      <el-col :span="2"><el-button>条码打印</el-button></el-col>
        <el-col :span="2"><el-button icon="iconfont icon-24px " @click="printFormVisible = true">条码打印</el-button></el-col>
     </el-row>
    <el-table
        :row-class-name="onTableRowClassName"
        :row-style="{height:0+'px'}"
        :cell-style="{padding:8+'px',textAlign: 'center'}"
        :header-cell-style="{borderRight:'0px',textAlign: 'center',background:'#52626F',color:'#fff', height:'10px', padding:'0px'}"
      :stripe="true"
      :data="tableData"
      :cell-style="{ textAlign: 'center' }"
      :header-cell-style="{ textAlign: 'center' }"
      :border="true"
      header-row-class-name="table-header"
    >
      <el-table-column
        prop="date"
        label="序号">
          label="序号"
        >
          <template v-slot="scope">
            {{ (addPageParams.pageNo-1) * addPageParams.pageSize + scope.$index + 1 }}
          </template>
      </el-table-column>
      <el-table-column
        prop="name"
        label="产品编码">
      </el-table-column>
      <el-table-column
        prop="address"
        label="产品名称">
      </el-table-column>
      <el-table-column
        prop="date"
        label="规格型号">
      </el-table-column>
      <el-table-column
        prop="date"
        label="单位">
      </el-table-column>
      <el-table-column
        prop="date"
        label="入库数量">
      </el-table-column>
      <el-table-column
        prop="date"
        label="入库人">
      </el-table-column>
      <el-table-column
        prop="date"
        label="入库日期">
      </el-table-column>
          v-for="(item, index) in getKeys()"
          v-if="item.show"
          :key="index"
          :prop="item.prop"
          :label="item.name"
        />
    </el-table>
    </div>
    <div class="addOperation-foot">
      <el-pagination
      :current-page="searchModel.pageNo"
@@ -76,15 +42,123 @@
      :total="total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      >
    </el-pagination>
        />
    </div>
    </div>
    <el-dialog title="新增入库" :visible.sync="addFormVisible" @close="addFormClose">
      <el-form :model="addParams" label-position="left">
        <el-table
          :height="250"
          :max-height="250"
          :row-class-name="onTableRowClassName"
          :row-style="{height:0+'px'}"
          :cell-style="{padding:8+'px',textAlign: 'center'}"
          :header-cell-style="{borderRight:'0px',textAlign: 'center',background:'#52626F',color:'#fff', height:'10px', padding:'0px'}"
          :stripe="true"
          :border="true"
          header-row-class-name="table-header"
          :data="this.addTable.slice(0, addPageParams.pageSize)"
        >
          <!-- <el-table-column property="addPerson" label="序号" >
          </el-table-column> -->
          <el-table-column property="productCode" label="产品编码" />
          <el-table-column property="productName" label="产品名称" />
          <el-table-column property="productModel" label="规格型号" />
          <el-table-column property="unit" label="单位" />
          <el-table-column property="incomingQuantity" label="入库数量" />
          <el-table-column property="addPerson" label="入库人" />
          <!-- <el-table-column property="address" label="入库日期"></el-table-column> -->
        </el-table>
        <div :style="{display: 'flex',justifyContent:'center',marginTop: '10px'}">
          <el-pagination
            :current-page="addPageParams.pageNo"
            :page-sizes="[3, 4, 5, 6]"
            :page-size="addPageParams.pageSize"
            layout="->, total, sizes, prev, pager, next, jumper"
            :total="addTable.length"
            @size-change="inHandleSizeChange"
            @current-change="inHandleCurrentChange"
          />
        </div>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="storage">确 定</el-button>
        <el-button @click="addFormVisible = false">取 消</el-button>
      </div>
    </el-dialog>
    <el-dialog title="条码打印" :visible.sync="printFormVisible">
      <el-form :model="printParams" label-position="left">
        <el-row :gutter="20">
          <el-col>
            <el-form-item label="产品名称/规格:" :label-width="formLabelWidth">
              <el-cascader
                v-model="chooseTypeName"
                :options="scanTypeNameOptions"
                @change="handleChange"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col>
            <el-form-item label="产品编码:" :label-width="formLabelWidth">
              <el-input :value="printParams.productCode" :disabled="true" autocomplete="off" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="单位:" :label-width="formLabelWidth">
              <el-input v-model="printParams.unit" autocomplete="off" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="入库数量:" :label-width="formLabelWidth">
              <el-input v-model="printParams.incomingQuantity" type="number" autocomplete="off" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="print">确 定</el-button>
        <el-button @click="printFormVisible = false">取 消</el-button>
      </div>
    </el-dialog>
    <el-dialog :visible.sync="printVisible" @close="printFormClose">
      <div class="printMian">
        <div id="printMe">
          <vue-barcode :height="50" :width="2" :value="code" />
          <div>
            <div>{{ printParams.productName }}</div>
            <div>{{ printParams.incomingQuantity }}</div>
            <div>{{ printParams.unit }}</div>
          </div>
          <div>
            <div :style="{flex:'2', paddingRight:'1px'}">2022-01-01 10:00</div>
            <div>{{ printParams.productModel }}</div>
          </div>
        </div>
      </div>
      <div class="btn" :style="{display: 'flex',justifyContent: 'center'}">
        <el-button v-print="printObj" :style="{width:'8cm',margin:'10px'}" type="primary">打印</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
import { getList } from '@/api/table'
import { getList, file, addCache, selectCache, add } from '@/api/addOperation'
import { selectAllName } from '@/api/productName'
import { selectAllModel } from '@/api/productModel'
import { mapGetters } from 'vuex'
import TableSearch from '@/components/TableSearch'
import VueBarcode from 'vue-barcode'
export default {
  filters: {
    statusFilter(status) {
@@ -98,86 +172,278 @@
  },
  data() {
    return {
      pickerOptions: {
          shortcuts: [{
            text: '最近一周',
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
              picker.$emit('pick', [start, end]);
            }
          }, {
            text: '最近一个月',
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
              picker.$emit('pick', [start, end]);
            }
          }, {
            text: '最近三个月',
            onClick(picker) {
              const end = new Date();
              const start = new Date();
              start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
              picker.$emit('pick', [start, end]);
            }
          }]
      printObj: {
        id: 'printMe', // 打印的区域
        // preview: false, // 预览工具是否启用
        previewTitle: '打印条码', // 预览页面的标题
        popTitle: '', // 打印页面的页眉
        previewBeforeOpenCallback(vue) {
          console.log('正在加载预览窗口')
        },
      inType: '',
      inStatus: '',
      deptName: '',
      statusType: {},
      queryParams: {
        encode: '',
        type: '',
        depositor: ''
        previewOpenCallback(vue) {
          console.log('已经加载完预览窗口')
      },
        clickMounted: (vue) => {
          console.log('触发点击打印回调')
          // vue.isShowPrint = true // 弹框显示条码
        },
        beforeOpenCallback(vue) {
          console.log('打开之前', vue.barcodeNum)
        },
        openCallback(vue) {
          // vue.isShowPrint = false // 关闭条码显示弹框
          // 清空条码打印数据
          vue.printFormVisible = false
          vue.printVisible = false
          vue.chooseTypeName = ''
          for (const key in vue.printParams) {
            vue.printParams[key] = ''
          }
          console.log('执行了打印', vue.barcodeNum)
        }
      },
      printVisible: false,
      file,
      getList,
      options: [],
      chooseTypeName: {},
      scanData: {},
      scanTypeNameOptions: [],
      total: 0,
      searchModel: {
        pageNo: 1,
        pageSize: 10
        pageSize: 10,
        endTime: '',
        productModel: '',
        startTime: ''
      },
      tableData: [{
        date: '2016-05-02',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1518 弄'
      }, {
        date: '2016-05-04',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1517 弄'
      }, {
        date: '2016-05-01',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1519 弄'
      }, {
        date: '2016-05-03',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1516 弄'
      }, {
        date: '2016-05-03',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1516 弄'
      }, {
        date: '2016-05-03',
        name: '王小虎',
        address: '上海市普陀区金沙江路 1516 弄'
      }]
      tableData: [],
      addFormVisible: false,
      printFormVisible: false,
      printParams: {
        addPerson: '',
        incomingQuantity: '',
        productModelId: '',
        productNameId: '',
        unit: '',
        productCode: ''
      },
      showAddTable: [],
      addTable: [],
      addCodeTable: [],
      addParams: {
        name: '', // 产品名称
        specs: '', // 产品规格
        unit: '', // 单位
        number: '', // 数量
        depositor: '', // 入库人,可以为入库人id
        date: '' // 时间
      },
      formLabelWidth: '120px',
      addPageParams: {
        pageNo: 1,
        pageSize: 3
      },
      code: ''
    }
  },
  computed: {
    ...mapGetters([
      'sidebar',
      'avatar',
      'name',
      'addTab'
    ])
  },
  watch: {
    addFormVisible(to) {
      if (!to) {
        this.addTable = []
        this.addCodeTable = []
        window.document.onkeypress = undefined
      }
    }
  },
  created() {
    this.fetchData()
    this.setOptions()
    // console.log(this.$route,this.$router)
  },
  components: {
    TableSearch
    TableSearch,
    VueBarcode
  },
  mounted() {
    console.log(this.addTab[0])
  },
  beforeDestroy() {
    window.document.onkeypress = null
  },
  methods: {
    getKeys() {
      return this.$store.state.tableKey.allTab[0].keys
    },
    addScanMonitor() {
      window.document.onkeypress = e => {
        console.log(e)
        if (window.event) { // IE
          this.nextCode = e.keyCode
        } else if (e.which) { // Netscape/Firefox/Opera
          this.nextCode = e.which
        }
        if (e.which === 13) { // 键盘回车事件
          console.log(new Date().getTime())
          if (new Date().getTime() - this.lastTime > 40) {
            return this.$message.error('扫码时不可通过键盘输入')
          }
          // if (this.code.length < 3) return // 扫码枪的速度很快,手动输入的时间不会让code的长度大于2,所以这里不会对扫码枪有效
          console.log('扫码结束,条形码:', this.code)
          // 发送请求
          if (this.addCodeTable.includes(this.code)) {
            this.$message.error('请勿重复扫描')
            this.handleSubmitScanning()
            return
          }
          selectCache({ code: this.code }).then(res => {
            // 通过扫描条码查询产品信息加入入库数组中
            this.$message.success(`${this.code}扫描成功`)
            res.data.addPerson = this.name
            console.log(res, this.addCodeTable)
            this.addTable.push(res.data)
            this.addCodeTable.push(this.code)
          })
          this.scanningForm.scanCode = this.code
          this.lastCode = ''
          this.lastTime = ''
          this.handleSubmitScanning()
          return
        }
        this.nextTime = new Date().getTime()
        if (!this.lastTime && !this.lastCode) {
          this.code = '' // 清空上次的条形码
          // 继续扫描一下条前关闭弹窗
          // this.handleCloseTipsVisible()
          this.code = this.code + '' + e.key
          console.log('扫码开始---', this.code)
        }
        if (this.lastCode && this.lastTime && this.nextTime - this.lastTime > 500) { // 当扫码前有keypress事件时,防止首字缺失
          this.code = e.key
          console.log('防止首字缺失。。。', this.code)
        } else if (this.lastCode && this.lastTime) {
          this.code = this.code + '' + e.key
          console.log('扫码中。。。', this.code)
        }
        this.lastCode = this.nextCode
        this.lastTime = this.nextTime
      }
    },
    // 关闭扫描入库弹窗
    addFormClose() {
      console.log('清空数据')
      // 清空数据
      this.addTable = []
      this.addCodeTable = []
    },
    // 点击新增入库
    addOperation() {
      this.addFormVisible = true
      this.addScanMonitor()
    },
    printFormClose() {
      for (const key in this.printParams) {
        this.printParams[key] = ''
      }
      this.chooseTypeName = ''
    },
    async setOptions() {
      const { data: nameRes } = await selectAllName()
      // console.log(nameRes)
      const nameArr = nameRes.productNames.map(item => {
        return { value: item.id, label: item.productName }
      })
      for (const nameItem of nameArr) {
        const { data } = await selectAllModel({ productNameId: nameItem.value })
        // console.log(data)
        this.options = [...this.options, ...data.models]
        nameItem.children = data.models.map(item => {
          return { value: item.id, label: item.productModel, productCode: item.productCode }
        })
      }
      this.options = this.options.map(item => {
        return { label: item.productModel, value: item.productModel, productCode: item.productCode }
      })
      this.scanTypeNameOptions = nameArr
      // console.log(this.options)
      // console.log(nameArr)
    },
    searchData(res) {
      console.log(res)
      const { row, total, productModel, startTime, endTime } = res
      this.tableData = row
      this.total = total
      this.searchModel.productModel = productModel
      this.searchModel.startTime = startTime
      this.searchModel.endTime = endTime
    },
    handleChange(value) {
      console.log(value)
      this.printParams.productNameId = value[0]
      this.printParams.productModelId = value[1]
      console.log(this.scanTypeNameOptions)
      const nameObj = this.scanTypeNameOptions.filter(item => item.value === value[0])
      console.log(nameObj[0].label)
      this.printParams.productName = nameObj[0].label
      const children = nameObj[0].children
      this.printParams.productCode = children.filter(item => item.value === value[1])[0].productCode
      console.log(children.filter(item => item.value === value[1])[0].label)
      this.printParams.productModel = children.filter(item => item.value === value[1])[0].label
    },
    onTableRowClassName({ row, rowIndex }) {
      if (rowIndex % 2 != 0) {
        return 'onAcitve'
      } else {
        return ''
      }
    },
    storage() {
      // 输出入库参数
      if (this.addCodeTable.length === 0) return this.$message.error('请先扫描数据入库')
      add({ code: this.addCodeTable, addPerson: this.name }).then(() => {
        this.addTable = []
        this.addCodeTable = []
        this.fetchData()
        this.addFormVisible = false
        this.$message.success('入库成功')
      })
    },
    async print() {
      console.log('生成条码')
      this.printParams.addPerson = this.name
      console.log(this.printParams)
      const res = await addCache(this.printParams)
      this.code = res.message
      this.printFormVisible = false
      // for( key in this.printParams){
      //   this.printParams[key] = ''
      // }
      this.printVisible = true
    },
    fetchData() {
      this.listLoading = true
      getList().then(response => {
        this.list = response.data.items
      const obj = {}
      const arr = Object.keys(this.searchModel).filter(key => this.searchModel[key])
      arr.forEach(item => obj[item] = this.searchModel[item])
      console.log(obj)
      getList(obj).then(response => {
        this.tableData = response.data.row
        this.total = response.data.total
        this.listLoading = false
        // console.log(this.tableData)
      })
    },
    handleSizeChange(val) {
@@ -185,31 +451,110 @@
    },
    handleCurrentChange(val) {
      console.log(`当前页: ${val}`)
      this.searchModel.pageNo = val
      this.fetchData()
    },
    inHandleSizeChange(val) {
      console.log(`每页 ${val} 条`)
    },
    inHandleCurrentChange(val) {
      console.log(`当前页: ${val}`)
      this.addPageParams.pageNo = val
      // console.log(this.addTable.slice((this.addPageParams.pageSize * (val - 1)), (this.addPageParams.pageSize * (val - 1)) + this.addPageParams.pageSize))
    }
  }
}
</script>
<style lang="scss" scoped>
.printMian{
  display: flex;
  justify-content: center;
  .btn{
    width: 100%;
    display: flex;
    justify-content: center;
    .el-button{
      width: 100%;
    }
  }
}
@import '../../styles/variables.scss';
  #printMe{
  // height: 4cm;
  // visibility:hidden;
  width: 8cm;
  display: flex;
  flex-direction: column;
  text-align: center;
  img{
    align-items: center;
    display: inline-block;
    text-align: center;
    width: 8cm;
    height: 1.5cm;
  }
  >div{
    width: 100%;
    display: flex;
    >div{
      flex: 1;
      // height: 30px;
      border: 1px solid #ddd;
      padding: 2px;
    }
  }
}
@media print {
  @page {
    size: 8cm 4cm !important;
    // margin: 0cm;
    // padding: 0cm;
    // size: portrait;
    // border: 1px solid #ddd;
  }
  }
.addOperation {
 min-height: calc(100vh - 50px);
 min-height: calc(100vh - 100px);
 max-height: calc(100vh - 100px);
 padding: 25px;
// margin: 25px;
 background: $mainBg;
 display: flex;
 flex-direction: column;
 .dialog-footer{
  text-align: center;
 }
 .addOperation-main{
  background: #fff;
  padding: 20px;
  flex: 80%;
  display: flex;
  flex-direction: column;
  .main-top{}
  .table-header{
    background: #6095FB;
  }
  ::v-deep .el-table{
    flex: 1;
   ::v-deep .onAcitve td{
    background-color: #F2F2F2 !important;
  }
 }
 .addOperation-foot{
    // flex: 20%;
  margin-top: 25px;
  .el-pagination{
    display: flex;
    justify-content: center;
      justify-content: right;
  }
 }
}
}
</style>