huangmp 2 лет назад
Родитель
Сommit
ef3dc4cddf

+ 1 - 0
package.json

@@ -20,6 +20,7 @@
     "jszip": "^3.10.1",
     "lodash": "4.17.5",
     "moment": "^2.29.1",
+    "pdf-lib": "^1.17.1",
     "qrcode": "^1.4.4",
     "vue": "2.6.14",
     "vue-baidu-map": "^0.21.22",

+ 998 - 0
src/components/AudioBox/index.vue

@@ -0,0 +1,998 @@
+<template>
+  <div class="elx-imgbox">
+    <el-dialog
+      title="音频管理器"
+      :visible.sync="visible"
+      class="elx-imgbox-dialog"
+      @close="handleDialogClose"
+      width="900px"
+      :append-to-body="visible"
+    >
+      <el-tabs v-model="options.activeTab" tab-position="top" @tab-click="tabClick">
+        <el-tab-pane
+          label="选择音频"
+          name="pick"
+          class="pick-block"
+        >
+          <div class="elx-img-list-loading" v-if="isLoading">
+            <div class="el-icon-loading"></div>
+          </div>
+          <el-form :inline="true" :model="dataForm" class="demo-form-inline form">
+            <el-form-item>
+              <el-input
+                v-model="fileName"
+                size="medium"
+                :placeholder="this.$i18n.t('videoManager.videoName')"
+                clearable
+              ></el-input>
+            </el-form-item>
+            <el-form-item>
+              <div
+                @click="searchImg"
+                class="primary-btn default-btn"
+              >{{$t("videoManager.query")}}</div>
+              <div
+                class="default-btn primary-btn"
+                @click="options.activeTab='upload'"
+                plain
+                v-if="options.enableUpload"
+                style="margin-left:10px"
+              >上传音频</div>
+            </el-form-item>
+            <!-- <el-form-item>
+              <el-button type="primary" @click="clean">清空</el-button>
+            </el-form-item>-->
+          </el-form>
+          <div class="box">
+            <div class="group">
+              <div :class="['group-item',groupId === 0 ?'active': '']"  @click="clickGroup(0)">
+                <span class="group-name">全部音频</span>
+              </div>
+              <div :class="['group-item',groupId === item.attachFileGroupId ?'active': '']" v-for="(item,index) in groupList" :key="item.attachFileGroupId">
+                <span class="group-name" @click="clickGroup(item.attachFileGroupId)">{{ item.name }}</span>
+              </div>
+            </div>
+            <div class="img-list">
+              <div class="elx-main elx-img-list">
+                <div v-for="(img, itemIndex) in imgRes.records" :key="itemIndex" class="img-item">
+                  <div class="thumb-wp" @click="onClickListImage(img)">
+                    <!-- <img v-if="img.filePath" :src="(img.filePath).indexOf('http')===-1 ? resourcesUrl + img.filePath : img.filePath" alt="img.name" /> -->
+                    <video
+                      :src="resourcesUrl + img.filePath"
+                      controls="controls"
+                      class="showVideo"
+                      style="width:175px;height:87.5px;"
+                    />
+                    </div>
+                    <div class="title" @click="onClickListImage(img)">{{ img.fileName }}</div>
+                    <!-- <div class="label" v-if="img.label">{{img.label}}</div> -->
+                    <span v-if="img.selected" class="selected" @click="onClickListImage(img)">
+                      <span class="icon el-icon-check" />
+                    </span>
+                  </div>
+                </div>
+                <div class="data-tips" v-if="!imgRes.records.length">{{$t("order.noData")}}</div>
+                <el-pagination
+                    layout="total, prev, pager, next"
+                    :current-page="imgRes.current"
+                    :page-size="imgRes.size"
+                    :total="imgRes.total"
+                    @current-change="onPageNumChange"
+                ></el-pagination>
+            </div>
+          </div>
+          <div class="elx-foot">
+            <el-badge :value="images.length" class="item" v-if="!type">
+              <div class="default-btn" @click="visible = false">{{$t("resource.cancel")}}</div>
+              <div
+                :class="[images.length == 0?'disabled-btn':'','default-btn primary-btn']"
+                :disabled="images.length == 0"
+                @click="onConfirm"
+                style="margin-right:3px;"
+              >{{$t("resource.confirm")}}</div>
+            </el-badge>
+            <div
+              :class="[images.length == 0?'disabled-btn':'','default-btn primary-btn']"
+              :disabled="disabled"
+              @click="onConfirm"
+              v-else
+            >{{$t("resource.confirm")}}</div>
+          </div>
+        </el-tab-pane>
+
+        <el-tab-pane
+          label="上传音频"
+          name="upload"
+          class="upload-block"
+          v-if="options.enableUpload"
+        >
+          <div class="elx-upload-main">
+            <div class="upload-title">{{$t("resource.selectGroup")}}:</div>
+            <div class="select-group-box">
+              <div class="select-group-box-item">{{$t("resource.group")}}:</div>
+              <el-select size="small" v-model="selectGroup" clearable :placeholder="$t('resource.selectGroup')" class="select-group-box-item">
+                <el-option
+                  v-for="item in groupList"
+                  :key="item.attachFileGroupId"
+                  :label="item.name"
+                  :value="item.attachFileGroupId">
+                </el-option>
+              </el-select>
+            </div>
+            <div class="upload-title">选择本地音频</div>
+            <!-- 视频预览 -->
+              <div class="upload-video-box">
+                <div v-for="(item, index) in videoList" :key="index" class="video-preview">
+                <video
+                  v-if="item.url"
+                  class="upShowVideo"
+                  :src="item.url"
+                  controls="controls"
+                  style="width:175px;height:87.5px;"
+                />
+                <!-- 显示查看和删除的按钮弹窗 -->
+                <div
+                  class="avatar-uploader-popup"
+                >
+                  <i class="el-icon-delete" @click="preDeleteVideo(index)" />
+                </div>
+              </div>
+            </div>
+            <el-upload
+              ref="upload"
+              class="upload-img-preview"
+              list-type="picture-card"
+              action=""
+              :headers="{Authorization: $cookie.get('Authorization_vs'),locale:lang}"
+              :multiple="true"
+              accept="audio/*"
+              :auto-upload="false"
+              :show-file-list="false"
+              :limit="options.limit"
+              :before-upload="beforeUploadVideo"
+              :http-request="httpRequest"
+              :on-change="onUploadChange"
+              :on-progress="onUploadProgress"
+              :on-success="onUploadSuccess"
+              :on-error="onUploadError"
+              :on-exceed="onUploadExceedTip"
+            >
+              <i class="el-icon-plus"></i>
+            </el-upload>
+
+            <div class="upload-tip">{{ uploadTips() }}</div>
+
+            <div class="elx-upload-foot">
+              <div @click="options.activeTab = 'pick'" class="default-btn">{{$t("shopFeature.edit.back")}}</div>
+              <div
+                class="primary-btn default-btn"
+                @click="onUploadConfirm"
+              >{{$t("videoManager.confirmUpload")}}</div>
+            </div>
+          </div>
+        </el-tab-pane>
+      </el-tabs>
+    </el-dialog>
+  </div>
+</template>
+
+<script type="text/babel">
+export default {
+  name: 'ElxVideobox',
+  data () {
+    return {
+      lang: localStorage.getItem('lang') || 'zh_CN',
+      images: [], // 已选视频
+      fileIds: [], // 已选视频的fileId
+      dataForm: {},
+      uploadFileNum: 0,
+      groupVisible: false,
+      showBatchMove: false,
+      options: {
+        multiple: true, // 是否支持选取多个视频
+        limit: 20, // 最多可选择视频数量
+        maxSize: 2, // 最大尺寸(M)
+        activeTab: 'pick',
+        enableUpload: true, // 是否启用视频上传
+        callback: null
+      },
+      groupList: [], // 分组列表
+      selectGroup: '',
+      showGroupType: 0, // 0:新建分组 1:修改分组
+      newImgName: '',
+      isTrue: true,
+      imageObject: null,
+      errShow: false,
+      picNum: 0,
+      resourcesUrl: process.env.VUE_APP_RESOURCES_URL,
+      changeNameVisible: false,
+      type: 4,
+      fileName: '',
+      isLoading: true,
+      visible: false,
+      disabled: false,
+      notImg: false,
+      uploadSuccessCount: 0,
+      imgRes: {
+        current: 1
+      },
+      videoList: [],
+      isSubmit: false,
+      uploadFlag: 0,
+      selectAll: false,
+      groupId: 0 // 点击分组
+    }
+  },
+
+  methods: {
+    /**
+     * 初始化
+     * type 1:单  2:多
+     */
+    init (type, limit) {
+      this.visible = true
+      this.isLoading = false
+      this.images = []
+      this.fileIds = []
+      this.type = type
+      if (type === 1) {
+        this.type = true
+        this.disabled = true
+      } else {
+        this.type = false
+        this.limit = limit
+      }
+      if (this.$refs.upload) {
+        this.$refs.upload.uploadFiles = []
+      }
+      // 获取产品数据 - 第一页的数据
+      this.loadListImage(1)
+      this.getGroupList()
+    },
+    show () {
+      this.visible = true
+    },
+
+    hide () {
+      this.visible = false
+    },
+
+    onConfirm () {
+      if (this.type) {
+        this.$emit('refreshPic', this.images[0].filePath)
+      } else {
+        let imgPaths = this.images.map(file => {
+          return file.filePath
+        }).join(',')
+        this.$emit('refreshPic', imgPaths)
+      }
+      this.visible = false
+    },
+    /**
+     * 提交修改后的视频名称
+     */
+    submitImgName () {
+      if (!this.isTrue) {
+        return false
+      }
+      this.isTrue = false
+      this.$http({
+        url: this.$http.adornUrl('/admin/file/updateFile'),
+        method: 'put',
+        data: this.$http.adornData({
+          fileId: this.imageObject.fileId,
+          fileName: this.newImgName,
+          attachFileGroupId: this.selectGroup,
+          type: 4
+        })
+      }).then(({ data }) => {
+        this.newImgName = ''
+        this.isTrue = true
+        this.selectGroup = ''
+        this.changeNameVisible = false
+        this.loadListImage(this.imgRes.current)
+      }).catch(({ e }) => {
+        this.isTrue = true
+      })
+    },
+    submitBatchMove () {
+      if (!this.selectGroup) {
+        return
+      }
+      this.$http({
+        url: this.$http.adornUrl('/admin/file/batchMove'),
+        method: 'put',
+        data: this.fileIds,
+        params: {
+          groupId: this.selectGroup
+        }
+      }).then(({ data }) => {
+        this.images = []
+        this.fileIds = []
+        this.showBatchMove = false
+        this.selectAll = false
+        this.loadListImage()
+      })
+    },
+    /**
+     * 点击视频时选中或取消选中视频
+     * @param img object
+     */
+    onClickListImage (img) {
+      // if(!this.uploadNumberLimit()) {
+      //   return this.onUploadExceedTip()
+      // }
+      // 单选图片
+      if (this.type) {
+        this.clearListSelected()
+        this.images = []
+        this.fileIds = []
+        this.disabled = false
+      } else {
+        // 多选图片-如果已选中则取消选中
+        var imgIndex = this.selectedImageIndex(img)
+        if (imgIndex >= 0) {
+          // 取消图片已选状态
+          img.selected = false
+          this.images.splice(imgIndex, 1)
+          this.fileIds.splice(imgIndex, 1)
+          return
+        }
+      }
+      if (this.type && !this.uploadNumberLimit()) {
+        this.message(this.$i18n.t('pictureManager.superiorLimit'))
+        return false
+      }
+      this.images.push(JSON.parse(JSON.stringify(img)))
+      this.fileIds.push(img.fileId)
+      img.selected = true
+    },
+    /**
+     * 清除所有已点击视频样式
+     */
+    clearListSelected () {
+      if (this.type) {
+        let list = this.imgRes.records
+        list.forEach(element => {
+          element.selected = false
+        })
+      }
+    },
+    /**
+         * 按视频名称搜索视频
+         */
+    searchImg () {
+      this.loadListImage(1)
+    },
+    /**
+     * 加载视频列表数据
+     * @param page
+     */
+    loadListImage (current) {
+      this.isLoading = true
+      this.$http({
+        url: this.$http.adornUrl('/admin/file/attachFilePage'),
+        method: 'get',
+        params: this.$http.adornParams({
+          current: current,
+          size: 9,
+          fileName: this.fileName ? this.fileName : null,
+          attachFileGroupId: this.groupId,
+          type: 4
+        })
+      }).then(({ data }) => {
+        this.imgRes = data
+        this.imgRes.records.forEach(img => {
+          img.selected = false
+        })
+        this.isLoading = false
+      })
+    },
+
+    /**
+     * 视频已选则返回下标,未选则返回-1
+     */
+    selectedImageIndex (img) {
+      for (let i = 0; i < this.images.length; i++) {
+        var selectedImg = this.images[i]
+        if (selectedImg.fileId === img.fileId) {
+          return i
+        }
+      }
+      return -1
+    },
+
+    /**
+     * 分页页面变化时刷新数据
+     * @param page
+     */
+    onPageNumChange (page) {
+      this.loadListImage(page)
+    },
+    /**
+     * 获取分组列表
+     */
+    getGroupList () {
+      this.$http({
+        url: this.$http.adornUrl('/admin/fileGroup/list'),
+        method: 'get',
+        params: {
+          type: 4 // 1、视频 2、视频 3、文件 4、音频
+        }
+      }).then(res => {
+        this.groupList = res.data
+      })
+    },
+    /**
+     * 点击分组
+     */
+    clickGroup (id) {
+      this.groupId = id
+      this.loadListImage(1)
+    },
+    /**
+     * 提交上传
+     */
+    onUploadConfirm () {
+      this.notImg = true
+      this.isSubmit = true
+      this.fileIds = []
+      this.uploadFlag = 0
+      this.$refs.upload.submit()
+    },
+
+    onUploadProgress (event, file, fileList) {
+
+    },
+    /**
+     * 上传视频
+     */
+    httpRequest (event) {
+      this.videoList.forEach(item => {
+        if (item.uid === event.file.uid) {
+          this.uploadFile(event)
+          this.notImg = true
+        }
+      })
+    },
+    uploadFile (event) {
+      const file = event.file
+      // 获取本次上传文件的位置
+      const formdata = new FormData()
+      formdata.append('FileName', file.name)
+      formdata.append('file', file)
+      this.$http({
+        url: this.$http.adornUrl('/admin/file/upload/audio'),
+        method: 'post',
+        headers: {
+          'Content-Type': file.type
+        },
+        data: formdata
+      }).then(res => {
+        event.onSuccess(res.data)
+      })
+    },
+    // 视频预上传
+    onUploadChange (file, fileList) {
+      let extend = file.raw.name.split(".")[1]
+      if (["wav", "mp3", "ogg", "acc", "webm", "amr"].indexOf(extend) === -1) {
+        this.$newMessage.error(this.$i18n.t('videoManager.tips2'))
+        return false
+      }
+      if (this.isSubmit) {
+        return
+      }
+      const showVideoList = document.getElementsByClassName('upShowVideo')
+      showVideoList.forEach((item) => {
+        if (!item.paused) { item.pause() }
+      })
+      const videoSrc = URL.createObjectURL(file.raw)
+      this.videoList.push({ url: videoSrc, uid: file.uid })
+    },
+    // 删除预览视频
+    preDeleteVideo (index) {
+      this.videoList.splice(index, 1)
+    },
+    errMsg () {
+      if (this.errShow && this.uploadFileNum === this.picNum) {
+        this.picNum = 0
+        this.message(this.$i18n.t('videoManager.onlyPictures'), true)
+        this.notImg = false
+      }
+    },
+    /**
+     * 上传视频前检查合法性
+     * @param file
+     * @returns {boolean}
+     */
+    beforeUploadVideo (file) {
+      const isLt5M = file.size / 1024 / 1024 < 5
+      if (!isLt5M) {
+        this.$message.error('上传音频大小不能超过5MB哦!')
+        return false
+      }
+      return true
+    },
+
+    uploadNumberLimit () {
+      if (!this.options.multiple) {
+        return 1
+      }
+      return this.options.limit - this.images.length - this.uploadFileNum
+    },
+
+    uploadTypeTip () {
+      return this.$i18n.t('videoManager.onlySupported') + 'wav, mp3, ogg, acc, webm, amr ' + '音频'
+    },
+
+    uploadSizeTip () {
+      return this.$i18n.t('videoManager.notExceed') + '5M'
+    },
+
+    uploadTips () {
+      let tips = [this.uploadTypeTip(), this.uploadSizeTip()]
+
+      if (!this.options.multiple) {
+        return tips.join(',')
+      }
+
+      if (this.images.length > 0) {
+        tips.push(this.$i18n.t('videoManager.alreadyExist') + this.images.length + this.$i18n.t('videoManager.unit'))
+      }
+
+      const uploadFileNum = this.videoList.length
+      if (uploadFileNum > 0) {
+        tips.push(this.$i18n.t('videoManager.soonUpload') + uploadFileNum + this.$i18n.t('videoManager.unit'))
+      }
+      this.uploadFileNum = uploadFileNum
+      tips.push(this.$i18n.t('videoManager.remainder') + (this.options.limit - this.images.length - uploadFileNum) + "个音频" + this.$i18n.t('videoManager.upload'))
+
+      return tips.join(',')
+    },
+
+    /**
+     * 上传错误处理
+     * @param err
+     * @param file
+     * @param fileList
+     */
+    onUploadError (err, file, fileList) {
+      this.message(this.$i18n.t('videoManager.requestError'), true)
+      // console.log(err)
+      throw err
+    },
+
+    /**
+     * 上传成功处理s
+     * @param response
+     * @param file
+     * @param fileList
+     * @returns {boolean}
+     */
+    onUploadSuccess (fileId, file, fileList) {
+      this.uploadFlag ++
+      this.fileIds.push(fileId)
+      if (this.videoList.length === this.uploadFlag) {
+        this.disabled = true
+        this.$refs.upload.uploadFiles = []
+        if (this.selectGroup) {
+          this.submitBatchMove()
+        }
+        this.options.activeTab = 'pick'
+        setTimeout(() => {
+          this.isSubmit = false
+          this.videoList = []
+        })
+        this.loadListImage(1)
+      }
+    },
+
+    /**
+     * 选择上传文件超过限制文件个数提示
+     */
+    onUploadExceedTip () {
+      this.message(this.$i18n.t('videoManager.maxSelect') + this.uploadNumberLimit() + this.$i18n.t('videoManager.unit') + this.$i18n.t('videoManager.upload'))
+    },
+    message (msg, isInfo) {
+      var type = 'error'
+      if (isInfo) {
+        type = 'info'
+      }
+      this.$message({
+        message: msg,
+        type: type,
+        duration: 1500
+      })
+    },
+
+    /**
+     * tab切换事件
+     */
+    tabClick (tab) {
+      this.fileName = ''
+      if (tab.name === 'pick') {
+        this.loadListImage(1)
+      }
+    },
+    /**
+     * 关闭回调
+     */
+    handleDialogClose () {
+      this.fileName = ''
+    }
+  },
+
+  mounted () {
+    this.getGroupList()
+    this.loadListImage()
+  },
+
+  computed: {
+
+  }
+}
+</script>
+
+<style lang="scss">
+.elx-images {
+  .el-upload-list__item,
+  .el-upload--picture-card {
+    width: 78px;
+    height: 78px;
+    line-height: 82px;
+    border-radius: 5px;
+  }
+}
+.elx-head {
+  background: #F7F7F7;
+  height: 40px;
+  width: 100%;
+  line-height: 40px;
+  .text {
+    color: #606266;
+    font-size: 14px;
+    margin-left: 7px;
+    cursor:pointer;
+  }
+}
+.elx-imgbox-dialog {
+  $bg: #f6f6f6;
+  height: 100% !important;
+  .el-badge {
+    vertical-align: bottom;
+  }
+
+  .el-dialog {
+    width: 820px;
+    .el-dialog__header {
+      border-bottom: 1px solid #e8e8e8;
+    }
+
+    .el-dialog__body {
+      padding: 0;
+      background: $bg;
+    }
+  }
+
+  .el-tabs {
+    .el-tabs__header {
+      margin-right: 0;
+      margin-top: 5px;
+      .el-tabs__nav-wrap::after {
+        background: $bg;
+      }
+    }
+    .el-tabs__item.is-active {
+      background: #fff;
+    }
+    .el-tabs--left .el-tabs__nav-wrap {
+      padding-top: 15px;
+    }
+
+    .el-tabs__content {
+      min-height: 740px;
+      // 弹窗高度
+      background: #fff;
+    }
+  }
+
+  .elx-foot {
+    padding: 15px 0 0 10px;
+    text-align: right;
+    margin-right: 30px;
+    .el-button {
+      margin: 0 0 0 10px;
+    }
+  }
+.upload-block {
+    .upload-img-preview {
+      padding: 20px;
+
+      /* 上传视频预览改为使用背景视频按比例缩放方式 */
+      .el-upload--picture-card,
+      .el-upload-list--picture-card .el-upload-list__item,
+      .el-upload-list--picture-card .el-upload-list__item .wp {
+        width: 90px;
+        height: 90px;
+        line-height: 98px;
+        background-size: cover;
+        background-position: 50% 50%;
+      }
+
+      .el-upload-list--picture-card .el-upload-list__item-status-label i {
+        margin-top: 12px;
+        vertical-align: top;
+      }
+    }
+
+    .upload-tip {
+      padding: 0 20px;
+      font-size: 13px;
+      color: #999;
+    }
+
+    .upload-title {
+      font-size: 16px;
+      color: #666;
+      padding: 20px 0 0 20px;
+    }
+  }
+}
+
+.form {
+  padding: 15px 0px 0px 20px;
+}
+
+.el-upload-list__item-actions {
+  a {
+    i {
+      color: #fff;
+    }
+  }
+}
+</style>
+<style lang="scss" scoped>
+.upload-video-box {
+  .video-preview {
+    width: 175px;
+    height: 100px;
+    display: inline-block;
+    text-align: center;
+    -webkit-box-sizing: border-box;
+    box-sizing: border-box;
+    margin-right: 8px;
+    margin-bottom: 5px;
+    margin-top: 20px;
+}
+.avatar-uploader-popup{
+  width: 100%;
+  background: #f6f6f6;
+  height: 18px;
+}
+}
+.group-box {
+  height: 600px;
+  min-width: 200px;
+  overflow:auto;
+}
+.select-group-box {
+  padding: 20px 0 0 20px;
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+  .select-group-box-item {
+    margin-right: 10px;
+  }
+}
+.box {
+  display: flex;
+  justify-content: flex-start;
+  .group {
+    min-width: 200px;
+    padding: 10px;
+    .group-item {
+      height: 38px;
+      line-height: 38px;
+      padding: 0 10px;
+      display: flex;
+      justify-content: space-between;
+      cursor:pointer;
+
+      .group-name {
+        width: 180px;
+      }
+      .sidebar-operate {
+        .el-icon-delete,
+        .el-icon-edit {
+          margin-left: 10px;
+          cursor: pointer;
+        }
+      }
+    }
+    .group-item:hover{
+      background: #F7F7F7;
+    }
+    .active {
+      background: #F7F7F7;
+    }
+  }
+  .img-list {
+    width: 1100px;
+    position: relative;
+    .data-tips {
+      position: absolute;
+      top: 30%;
+      left: 38%;
+    }
+  }
+}
+.pick-block {
+    position: relative;
+    $bg: #f6f6f6;
+    .elx-img-list-loading {
+      position: absolute;
+      top: 60px;
+      z-index: 9;
+      left: 0;
+      right: 0;
+      width: 100%;
+      height: 520px;
+      // 加载层高度
+      background: #fff;
+      text-align: center;
+
+      .el-icon-loading {
+        font-size: 50px;
+        color: #409eff;
+        line-height: 460px;
+      }
+    }
+
+    .elx-img-list {
+      padding: 10px;
+      min-height: 530px;
+      // 视频列表高度
+
+      .img-item {
+        $imgSize: 175px;
+        $size: 179px;
+        float: left;
+        margin: 10px;
+        margin-bottom: 20px;
+        margin-right: 20px;
+        width: $imgSize;
+        cursor: pointer;
+        position: relative;
+        font-size: 12px;
+
+        img {
+          width: $imgSize;
+          height: $imgSize;
+          display: block;
+          object-fit: contain
+        }
+
+        .title {
+          line-height: 24px;
+          height: 24px;
+          display: block;
+          overflow: hidden;
+          background: $bg;
+          padding: 0 5px;
+        }
+
+        .title {
+          line-height: 24px;
+          height: 24px;
+          display: block;
+          overflow: hidden;
+          background: $bg;
+          padding: 0 5px;
+        }
+        .operate {
+          line-height: 24px;
+          height: 24px;
+          display: block;
+          overflow: hidden;
+          // background: $bg;
+          margin-top: 2px;
+          padding: 0 5px;
+          .edit {
+            float: left;
+            padding-left: 5px;
+          }
+          .del {
+            float: right;
+            padding-right: 5px;
+          }
+        }
+
+        .label {
+          position: absolute;
+          z-index: 9;
+          left: 0;
+          bottom: 24px;
+          width: 100%;
+          height: 21px;
+          line-height: 21px;
+          text-align: center;
+          color: #fff;
+
+          &:after {
+            content: " ";
+            position: absolute;
+            left: 0;
+            bottom: 0;
+            width: 100%;
+            height: 21px;
+            background: #000;
+            opacity: 0.3;
+            z-index: -1;
+          }
+        }
+
+        .selected {
+          position: absolute;
+          right: -3px;
+          top: -3px;
+          width: $size;
+          height: 143px;
+          border: 3px solid #409eff;
+          border-radius: 3px;
+          text-align: right;
+          .icon {
+            background: #409eff;
+            text-align: center;
+            height: 24px;
+            width: 24px;
+            line-height: 24px;
+            display: inline-block;
+            font-size: 16px;
+            color: #fff;
+            border-radius: 0 0 0 3px;
+            position: absolute;
+            right: 0;
+            top: 0;
+          }
+        }
+      }
+
+      &::after {
+        content: " ";
+        display: table;
+        height: 0;
+        clear: both;
+        visibility: hidden;
+      }
+    }
+
+    .el-pagination {
+      background: #f9f9f9;
+      position: relative;
+      padding: 5px;
+      // margin: 0 24px 0 20px;
+      text-align: right;
+      float: none;
+
+      * {
+        background: none;
+      }
+    }
+  }
+.elx-upload-main {
+  padding-left: 70px;
+  .elx-upload-foot {
+    padding: 15px 0 0 10px;
+    text-align: left;
+    .el-button {
+      margin: 0 0 0 10px;
+    }
+  }
+}
+
+</style>
+<style scoped>
+div >>> .el-tabs__header{
+  display: none !important;
+}
+</style>

+ 84 - 23
src/components/order-card-item/index.vue

@@ -3,7 +3,7 @@
     <div>
       <div v-if="showFlagBtn">
         <el-radio v-model="mode" label="view">预览模式</el-radio>
-<!--        <el-radio v-model="mode" label="edit">编辑模式</el-radio>-->
+    <el-radio v-model="mode" label="edit">编辑模式</el-radio>
       </div>
 
       <div style="border: 2px solid pink; display: inline-block;margin-right: 5px;" v-for="(item, index) in cardItemList" :key="item.cardItemId">
@@ -13,16 +13,18 @@
               <div style="padding: 3px; text-align: center">
                 <span>正面</span>
               </div>
-              <el-image style="width: 100px; height: 100px;" v-if="mode=='view'" :src="resourcesUrl + item.frontPic" @click="previewPic(item, item.frontPic, item.prodName, 'front')"/>
+              <div v-if="mode=='view'" style="width: 100px;height: auto">
+                <img :src="resourcesUrl + item.frontPic" @click="previewPic(item, item.frontPic, item.prodName, 'front')"/>
+              </div>
               <el-upload v-else
                 class="avatar-uploader"
                 accept="image/jpg"
                 :before-upload="(file, fileList)=>handleBeforeUpload(file, fileList,item)"
                 :action="$http.adornUrl('/admin/file/simpleUpload')"
-                :headers="{Authorization: $cookie.get('Authorization_vs'),locale:lang}"
+                :headers="{Authorization: $cookie.get('Authorization_vp'),locale:lang}"
                 :on-success="(res,file)=>{onFrontUploadSuccess(item,res,file)}"
                 :show-file-list="false">
-                <img v-if="item.frontPic" :src="resourcesUrl + item.frontPic" class="avatar">
+                <img v-if="item.frontPic" style="width: 100px;height: auto" :src="resourcesUrl + item.frontPic" class="avatar">
                 <i v-else class="el-icon-plus avatar-uploader-icon"></i>
               </el-upload>
             </el-card>
@@ -32,15 +34,17 @@
               <div style="padding: 3px; text-align: center">
                 <span>背面</span>
               </div>
-              <el-image v-if="mode=='view'" :src="resourcesUrl + item.backPic" style="width: 100px; height: 100px;" @click="previewPic(item, item.backPic, item.prodName, 'back')"/>
+              <div v-if="mode=='view'" style="width: 100px;height: auto">
+                <img :src="resourcesUrl + item.backPic" @click="previewPic(item, item.backPic, item.prodName, 'back')"/>
+              </div>
               <el-upload v-else
                          class="avatar-uploader"
                          :before-upload="(file, fileList)=>handleBeforeUpload(file, fileList,item)"
                          :action="$http.adornUrl('/admin/file/simpleUpload')"
-                         :headers="{Authorization: $cookie.get('Authorization_vs'),locale:lang}"
+                         :headers="{Authorization: $cookie.get('Authorization_vp'),locale:lang}"
                          :on-success="(res,file)=>{onBackUploadSuccess(item,res,file)}"
                          :show-file-list="false">
-                <img v-if="item.backPic" :src="resourcesUrl + item.backPic" class="avatar">
+                <img v-if="item.backPic" style="width: 100px;height: auto" :src="resourcesUrl + item.backPic" class="avatar">
                 <i v-else class="el-icon-plus avatar-uploader-icon"></i>
               </el-upload>
             </el-card>
@@ -50,6 +54,8 @@
           <span v-if="showFlagBtn">
           <el-button v-if="item.flag==0 && mode=='view'" type="success" size="mini" style="margin-right: 20px" @click="handleFlag(item, index)">待标记</el-button>
           <el-button v-if="item.flag==1 && mode=='view'" type="warning" size="mini" style="margin-right: 5px" @click="handleFlag(item, index)">已标记</el-button>
+            <el-button v-if="mode=='view'" type="text" size="mini" @click="openOrgPicForm(item, index)">原图</el-button>
+          <el-button v-if="item.prodName.indexOf('语音') !== -1 && mode=='view'" type="text" size="mini" @click="openYYForm(item, index)">查看语音</el-button>
           <el-button v-if="mode==='edit'" type="primary" size="mini" style="margin-right: 5px" @click="addOrUpdateCardItem(item)">保存</el-button>
           <el-button v-if="mode==='edit' && item.cardItemId" type="danger" size="mini" style="margin-right: 5px" @click="deleteCardItem(item, index)">删除</el-button>
         </span>
@@ -73,13 +79,18 @@
       </div>
     </div>
     <CanvasPreview v-if= "previewPicDialogVisible" ref="canvasPreviewRef"></CanvasPreview>
+    <YuyinPreview ref="yuYinPreviewRef"></YuyinPreview>
+    <OrgPicPreview ref="orgPicPreviewRef"></OrgPicPreview>
+
   </div>
 </template>
 
 <script>
   import CanvasPreview from "../canvas-preview/index";
+  import YuyinPreview from "../yuyin-preview/index";
+  import OrgPicPreview from "../org-pic-preview/index";
   export default {
-    components: {CanvasPreview},
+    components: {CanvasPreview, YuyinPreview,OrgPicPreview},
     data () {
       return {
         lang: localStorage.getItem('lang') || 'zh_CN',
@@ -87,6 +98,7 @@
         previewPicUrl: null,
         prodType: null,
         previewPicDialogVisible: false,
+        previewYuyinDialogVisible: false,
         side:null,
         resourcesUrl: process.env.VUE_APP_RESOURCES_URL,
         mode: 'view',
@@ -111,6 +123,16 @@
       })
     },
     methods: {
+      openYYForm(item, index){
+        this.$nextTick(() =>{
+          this.$refs.yuYinPreviewRef.init(item)
+        })
+      },
+      openOrgPicForm(item, index){
+        this.$nextTick(() =>{
+          this.$refs.orgPicPreviewRef.init(item)
+        })
+      },
       previewLoad(event){
         this.previewWidth = event.srcElement.clientWidth;
         this.previewHeight = event.srcElement.clientHeight;
@@ -128,27 +150,33 @@
         let height = 1087;
         let prodName = item.prodName;
         isSize = new Promise(function(resolve, reject) {
-          if(prodName.indexOf("小卡") !== -1 || prodName.indexOf("仿拍立得") !== -1){
+          if(prodName.indexOf("小卡") !== -1 || prodName.indexOf("3寸花式拍立得") !== -1 || prodName.indexOf("3寸仿拍立得") !== -1){
             width = 709;
             height = 1087;
           }else if(prodName.indexOf("票根") !== -1){
             width = 780;
             height = 1489;
           }else if(prodName.indexOf("直拍封面") !== -1){
-            width = 697;
-            height = 1217;
-          }else if(prodName.indexOf("明信片") !== -1){
+            width = 732;
+            height = 1252;
+          }else if(prodName.indexOf("二宫格") !== -1){
             width = 1252;
-            height = 1819;
+            height = 732;
+          }else if(prodName.indexOf("明信片") !== -1){
+            width = 1229;
+            height = 1796;
           }else if(prodName.indexOf("三宫格") !== -1){
             width = 673;
             height = 1547;
-          }else if(prodName.indexOf("流砂书签") !== -1){
+          }else if(prodName.indexOf("书签") !== -1){
             width = 638;
-            height = 1819;
+            height = 1796;
+          }else if(prodName.indexOf("小方卡") !== -1){
+            width = 709;
+            height = 709;
           }else if(prodName.indexOf("方卡") !== -1){
-            width = 1217;
-            height = 1217;
+            width = 1229;
+            height = 1229;
           }else if(prodName.indexOf("手幅") !== -1){
             width = 1252;
             height = 3614;
@@ -161,9 +189,24 @@
           }else if(prodName.indexOf("手幅") !== -1){
             width = 1252;
             height = 3614;
+          }else if(prodName.indexOf("4寸花式拍立得") !== -1 || prodName.indexOf("4寸仿真拍立得") !== -1){
+            width = 921;
+            height = 1087;
+          }else if(prodName.indexOf("5寸花式拍立得") !== -1 || prodName.indexOf("5寸仿真拍立得") !== -1){
+            width = 1346;
+            height = 1087;
+          }else if(prodName.indexOf("长方形贴纸") !== -1){
+            width = 780;
+            height = 1134;
           }else if(prodName.indexOf("方形贴纸") !== -1){
             width = 662;
             height = 662;
+          }else if(prodName.indexOf("撕拉") !== -1){
+            width = 768;
+            height = 768;
+          }else if(prodName.indexOf("5寸直角卡") !== -1){
+            width = 1087;
+            height = 1347;
           }
           let _URL = window.URL || window.webkitURL;
           let img = new Image();
@@ -273,28 +316,46 @@
         this.side = side;
         if(prodName.indexOf('小卡') != -1){
           this.prodType = '小卡';
-        } else if(prodName.indexOf('仿拍立得') != -1){
-          this.prodType = '仿拍立得';
+        } else if(prodName.indexOf('3寸花式拍立得') != -1){
+          this.prodType = '3寸花式拍立得';
+        }else if(prodName.indexOf('4寸花式拍立得') != -1){
+          this.prodType = '4寸花式拍立得';
+        }else if(prodName.indexOf('4寸仿真拍立得') != -1){
+          this.prodType = '4寸仿真拍立得';
+        }else if(prodName.indexOf('5寸花式拍立得') != -1){
+          this.prodType = '5寸花式拍立得';
+        }else if(prodName.indexOf('5寸仿真拍立得') != -1){
+          this.prodType = '5寸仿真拍立得';
         }else if(prodName.indexOf('直拍封面') != -1){
           this.prodType = '直拍封面';
         }else if(prodName.indexOf('票根') != -1){
           this.prodType = '票根';
         }else if(prodName.indexOf('明信片') != -1){
           this.prodType = '明信片';
+        }else if(prodName.indexOf('小方卡') != -1){
+          this.prodType = '小方卡';
         }else if(prodName.indexOf('方卡') != -1){
           this.prodType = '方卡';
-        }else if(prodName.indexOf('流砂书签') != -1){
-          this.prodType = '流砂书签';
+        }else if(prodName.indexOf('书签') != -1){
+          this.prodType = '书签';
         }else if(prodName.indexOf('徽章') != -1){
           this.prodType = '徽章';
         }else if(prodName.indexOf('手幅') != -1){
           this.prodType = '手幅';
         }else if(prodName.indexOf('毛绒徽章') != -1){
           this.prodType = '毛绒徽章';
-        }else if(prodName.indexOf('方形贴纸') != -1){
-          this.prodType = '方形贴纸';
         }else if(prodName.indexOf('三宫格') != -1){
           this.prodType = '三宫格';
+        }else if(prodName.indexOf('长方形贴纸') != -1){
+          this.prodType = '长方形贴纸';
+        }else if(prodName.indexOf('方形贴纸') != -1){
+          this.prodType = '方形贴纸';
+        }else if(prodName.indexOf('二宫格') != -1){
+          this.prodType = '二宫格';
+        }else if(prodName.indexOf('撕拉') != -1){
+          this.prodType = '撕拉';
+        }else if(prodName.indexOf('5寸直角卡') != -1){
+          this.prodType = '5寸直角卡';
         }
         this.$nextTick(() =>{
           this.$refs.canvasPreviewRef.init(cardItem, this.resourcesUrl + picUrl, this.prodType, side)

+ 137 - 0
src/components/order-pdf-generate/index.vue

@@ -0,0 +1,137 @@
+<template>
+  <el-dialog
+    title="生成打印PDF"
+    :modal="false"
+    top="200px"
+    :close-on-click-modal="false"
+    :visible.sync="visible"
+  >
+    <el-form
+      :model="dataForm"
+      ref="dataForm"
+      label-width="80px"
+    >
+      <el-form-item label="打印渠道" prop="printChannel">
+        <el-select v-model="dataForm.printChannel" clearable filterable @change="handlePrintChannelChange">
+          <el-option key="GSART" label="广森数码" value="GSART"></el-option>
+          <el-option key="WoNiu" label="蜗牛数码" value="WoNiu"></el-option>
+          <el-option key="KuaiYin" label="快印数码" value="KuaiYin"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="打印产品" prop="prodType">
+        <el-select v-model="dataForm.prodType" clearable filterable @change="handleProdTypeChange">
+          <el-option v-for="(node, index) in prodTypeList"
+                     :key="node.prodType"
+                     :label="node.prodName"
+                     :value="node.prodType">
+          </el-option>
+        </el-select>
+      </el-form-item>
+    </el-form>
+    <span slot="footer">
+      <el-button type="info" @click="visible = false">{{$t("crud.filter.cancelBtn")}}</el-button>
+      <el-button :loading="generatePdfLoading" type="primary" @click="dataFormSubmit">{{$t("crud.filter.submitBtn")}}</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+export default {
+  data () {
+    return {
+      visible: false,
+      provinceList: [],
+      cityList: [],
+      areaList: [],
+      dataForm: {
+        orderNumber: null,
+        printChannel: "GSART",
+        shopId: null,
+        prodType: null,
+        thirdSkuId: null,
+      },
+      dataRule: {
+      },
+      isTrue: false,
+      errorInfo: '',
+      dataListLoading: false,
+      thirdSkuIdList: [],
+      prodTypeList: [],
+      dataList: [],
+      generatePdfLoading: false,
+      resourcesUrl: process.env.VUE_APP_RESOURCES_URL,
+    }
+  },
+  methods: {
+    // 获取数据列表
+    init (data) {
+      let printOrder = Object.assign({}, data)
+      this.visible = true
+      this.dataForm.shopId = printOrder.shopId
+      this.dataForm.orderNumber = printOrder.orderNumber
+      this.dataListLoading = false;
+      this.$http({
+        url: this.$http.adornUrl(`/prod/thirdPrintSku/list`),
+        method: 'get',
+        params: this.$http.adornParams()
+      }).then(({ data }) => {
+        this.dataList = data;
+        this.handlePrintChannelChange(this.dataForm.printChannel);
+      })
+    },
+    /**
+     *  生成作品打印PDF
+     */
+    generatePrintPdf () {
+
+    },
+    // 确定事件
+    dataFormSubmit () {
+      this.generatePdfLoading = true;
+      this.$http({
+        url: this.$http.adornUrl('/order/thirdPrintOrder/generatePrintPdf'),
+        method: 'post',
+        data: this.$http.adornData(this.dataForm),
+      }).then(({ data }) => {
+        if(data.status === "success"){
+          this.generatePdfLoading = false;
+          window.open(this.resourcesUrl + data.result.worksUrl);
+        }else{
+          this.generatePdfLoading = false;
+          this.$message({
+            message: data.msg,
+            type: 'error'
+          })
+        }
+      })
+    },
+    handlePrintChannelChange(val){
+      let tempProdTypeList = [];
+      tempProdTypeList = this.dataList.filter(item =>{
+          return item.printChannel === val
+        });
+       let temp = [];
+       this.prodTypeList = tempProdTypeList.filter(item => {
+         if(temp.indexOf(item.prodType) == -1){
+           temp.push(item.prodType);
+           return item;
+         }
+       });
+    },
+    handleProdTypeChange(val){
+      this.thirdSkuIdList = this.dataList.filter(item =>{
+        return item.printChannel === this.dataForm.printChannel && item.prodType === val;
+      });
+    }
+  }
+}
+</script>
+<style scoped>
+.prods-select-body {
+  height: auto;
+  overflow: auto;
+  border-top: 1px solid #eeeeee;
+  border-right: 1px solid #eeeeee;
+  border-bottom: 1px solid #eeeeee;
+}
+</style>

+ 157 - 0
src/components/order-print-create/index.vue

@@ -0,0 +1,157 @@
+<template>
+  <el-dialog
+    title="确认打印订单"
+    :modal="false"
+    top="200px"
+    :close-on-click-modal="false"
+    :visible.sync="visible"
+  >
+    <el-form
+      :model="dataForm"
+      ref="dataForm"
+      label-width="80px"
+    >
+      <el-form-item label="打印渠道" prop="printChannel">
+        <el-select v-model="dataForm.printChannel" clearable filterable @change="handlePrintChannelChange">
+          <el-option key="GSART" label="广森数码" value="GSART"></el-option>
+          <el-option key="Lightning" label="闪电打印" value="Lightning"></el-option>
+          <el-option key="WoNiu" label="蜗牛数码" value="WoNiu"></el-option>
+          <el-option key="KuaiYin" label="快印数码" value="KuaiYin"></el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="打印产品" prop="prodType">
+        <el-select v-model="dataForm.prodType" clearable filterable @change="handleProdTypeChange">
+          <el-option v-for="(node, index) in prodTypeList"
+                     :key="node.prodType"
+                     :label="node.prodName"
+                     :value="node.prodType">
+          </el-option>
+        </el-select>
+      </el-form-item>
+      <el-form-item label="产品规格" prop="thirdSkuId">
+        <el-select v-model="dataForm.thirdSkuId" clearable filterable>
+          <el-option v-for="(node, index) in thirdSkuIdList"
+                     :key="node.thirdSkuId"
+                     :label="node.thirdSkuName"
+                     :value="node.thirdSkuId">
+          </el-option>
+        </el-select>
+      </el-form-item>
+    </el-form>
+    <span slot="footer">
+      <el-button type="info" @click="visible = false">{{$t("crud.filter.cancelBtn")}}</el-button>
+      <el-button :loading="orderCreateLoading" type="primary" @click="dataFormSubmit">{{$t("crud.filter.submitBtn")}}</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+export default {
+  data () {
+    return {
+      visible: false,
+      provinceList: [],
+      cityList: [],
+      areaList: [],
+      dataForm: {
+        orderNumber: null,
+        printChannel: "GSART",
+        shopId: null,
+        prodType: null,
+        thirdSkuId: null,
+      },
+      dataRule: {
+      },
+      isTrue: false,
+      errorInfo: '',
+      dataListLoading: false,
+      thirdSkuIdList: [],
+      prodTypeList: [],
+      dataList: [],
+      orderCreateLoading: false
+    }
+  },
+  methods: {
+    // 获取数据列表
+    init (data) {
+      let printOrder = Object.assign({}, data)
+      this.visible = true
+      this.dataForm.shopId = printOrder.shopId
+      this.dataForm.orderNumber = printOrder.orderNumber
+      this.dataListLoading = false;
+      this.$http({
+        url: this.$http.adornUrl(`/prod/thirdPrintSku/list`),
+        method: 'get',
+        params: this.$http.adornParams({})
+      }).then(({ data }) => {
+        this.dataList = data;
+        this.handlePrintChannelChange(this.dataForm.printChannel);
+      })
+    },
+    // 确定事件
+    dataFormSubmit () {
+      this.orderCreateLoading = true;
+      this.$refs['dataForm'].validate(valid => {
+        if (valid) {
+          this.$http({
+            url: this.$http.adornUrl(`/order/thirdPrintOrder/createOrder`),
+            method: 'post',
+            data: this.$http.adornData(this.dataForm)
+          }).then(({ data }) => {
+            this.orderCreateLoading = false;
+            if(data.status === "success"){
+              this.$message({
+                message: "下单成功",
+                type: 'success',
+                duration: 500,
+                onClose: () => {
+                  this.visible = false
+
+                }
+              })
+            }else{
+              this.$message({
+                message: data.msg,
+                type: 'error',
+                duration: 500,
+                onClose: () => {
+                  this.visible = false
+                }
+              })
+            }
+          }).catch(() => {
+            this.visible = false
+          })
+        }
+      })
+    },
+    handlePrintChannelChange(val){
+      let tempProdTypeList = [];
+      tempProdTypeList = this.dataList.filter(item =>{
+          return item.printChannel === val
+        });
+       let temp = [];
+       this.prodTypeList = tempProdTypeList.filter(item => {
+         if(temp.indexOf(item.prodType) == -1){
+           temp.push(item.prodType);
+           return item;
+         }
+       });
+    },
+    handleProdTypeChange(val){
+      this.thirdSkuIdList = this.dataList.filter(item =>{
+        return item.printChannel === this.dataForm.printChannel && item.prodType === val;
+      });
+    }
+  }
+}
+</script>
+<style scoped>
+.prods-select-body {
+  height: auto;
+  overflow: auto;
+  border-top: 1px solid #eeeeee;
+  border-right: 1px solid #eeeeee;
+  border-bottom: 1px solid #eeeeee;
+}
+</style>

+ 118 - 0
src/components/order-remark-update/index.vue

@@ -0,0 +1,118 @@
+<template>
+  <el-dialog
+    :title="this.$i18n.t('components.modifyUseAddress')"
+    :modal="false"
+    top="200px"
+    :close-on-click-modal="false"
+    :visible.sync="visible"
+  >
+    <el-form
+      :model="dataForm"
+      :rules="dataRule"
+      ref="dataForm"
+      @keyup.enter.native="dataFormSubmit()"
+      label-width="80px"
+    >
+      <el-form-item :label="this.$i18n.t('components.userComments')" prop="remarks">
+        <el-input
+          v-model="dataForm.remarks"
+          disabled
+          :placeholder="this.$i18n.t('components.pleaseEnterRemarks')"
+          type="textarea"
+          :autosize="{ minRows: 2, maxRows: 10 }"
+          maxlength="250"
+          show-word-limit
+        ></el-input>
+      </el-form-item>
+      <el-form-item :label="this.$i18n.t('order.sellerNote')" prop="shopRemarks">
+        <el-input
+          v-model="dataForm.shopRemarks"
+          :placeholder="this.$i18n.t('components.pleaseEnterRemarks')"
+          type="textarea"
+          :autosize="{ minRows: 2, maxRows: 10 }"
+          maxlength="250"
+          show-word-limit
+        ></el-input>
+      </el-form-item>
+    </el-form>
+    <span slot="footer">
+      <el-button type="primary" @click="visible = false">{{$t("crud.filter.cancelBtn")}}</el-button>
+      <el-button type="primary" @click="submitProds()">{{$t("crud.filter.submitBtn")}}</el-button>
+    </span>
+  </el-dialog>
+</template>
+
+<script>
+export default {
+  data () {
+    return {
+      visible: false,
+      provinceList: [],
+      cityList: [],
+      areaList: [],
+      dataForm: {
+        orderId: '',
+        remarks: '',
+        shopRemarks: '',
+        orderNumber: ''
+      },
+      dataRule: {
+      },
+      isTrue: false,
+      errorInfo: '',
+      dataListLoading: false
+    }
+  },
+  methods: {
+    // 获取数据列表
+    init (order) {
+      let orderInfo = Object.assign({}, order)
+      this.visible = true
+      this.dataListLoading = true
+      this.dataForm.orderId = orderInfo.orderId
+      this.dataForm.orderNumber = orderInfo.orderNumber
+      this.dataForm.remarks = orderInfo.remarks
+      this.dataForm.shopRemarks = orderInfo.shopRemarks
+      this.dataListLoading = false
+    },
+    // 确定事件
+    submitProds () {
+      this.$refs['dataForm'].validate(valid => {
+        if (valid) {
+          this.$http({
+            url: this.$http.adornUrl(`/order/order/changeOrderRamark`),
+            method: 'put',
+            data: this.$http.adornData(this.dataForm)
+          }).then(({ data }) => {
+            this.$message({
+              message: this.$i18n.t('publics.operation'),
+              type: 'success',
+              duration: 1500,
+              onClose: () => {
+                this.visible = false
+                this.$emit('refreshUserRemarkOrder')
+              }
+            })
+          })
+        }
+      })
+    },
+    errorMsg (message) {
+      this.$message({
+        message: message,
+        type: 'error',
+        duration: 1500
+      })
+    }
+  }
+}
+</script>
+<style scoped>
+.prods-select-body {
+  height: auto;
+  overflow: auto;
+  border-top: 1px solid #eeeeee;
+  border-right: 1px solid #eeeeee;
+  border-bottom: 1px solid #eeeeee;
+}
+</style>

+ 64 - 0
src/components/org-pic-preview/index.vue

@@ -0,0 +1,64 @@
+<template>
+  <el-dialog
+    :visible.sync="visible"
+    :append-to-body="false"
+    :modal="false"
+    title="原图预览"
+    top="5vh"
+    width="60%"
+    @close="closeDialog"
+    v-if="visible">
+    <el-form
+      :model="dataForm"
+      size="small">
+      <el-row>
+        <el-col :span="12">
+          <el-form-item label="正面原图">
+            <el-image
+              style="width: 421px; height: 645px"
+              :src="dataForm.frontOrgPic.indexOf('https://') !== -1? dataForm.frontOrgPic : resourcesUrl + dataForm.frontOrgPic"
+              v-if="dataForm.frontOrgPic"/>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item label="背面原图">
+            <el-image
+              style="width: 421px; height: 645px"
+              :src="dataForm.backOrgPic.indexOf('https://') !== -1? dataForm.backOrgPic : resourcesUrl + dataForm.backOrgPic"
+              v-if="dataForm.backOrgPic"/>
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+  </el-dialog>
+
+</template>
+
+<script>
+  export default {
+    name: "YuyinPreview",
+    data() {
+      return {
+        visible: false,
+        dataForm:{},
+        resourcesUrl: process.env.VUE_APP_RESOURCES_URL,
+      };
+    },
+    mounted() {
+    },
+    methods: {
+      init(cardItem){
+        this.dataForm = cardItem;
+        this.visible = true;
+      },
+      closeDialog(){
+        this.visible = false
+        this.dataForm = {}
+      }
+    },
+  }
+</script>
+
+<style scoped>
+
+</style>

+ 231 - 0
src/components/yuyin-preview/index.vue

@@ -0,0 +1,231 @@
+<template>
+  <el-dialog
+    :visible.sync="visible"
+    :append-to-body="false"
+    :close-on-click-modal="false"
+    :modal="false"
+    title="语音预览"
+    top="5vh"
+    width="40%"
+    @close="closeDialog"
+    v-if="visible">
+    <el-form
+      :model="dataForm"
+      size="small">
+      <el-form-item label="昵称">
+        <el-button size="mini" @click="authorNameEdit = !authorNameEdit">编辑</el-button>
+        <el-input v-model="dataForm.cardNote.authorName" :disabled="authorNameEdit"></el-input>
+      </el-form-item>
+      <el-form-item label="祝福的话语">
+        <el-button size="mini" @click="personalSignEdit = !personalSignEdit">编辑</el-button>
+        <el-input v-model="dataForm.cardNote.personalSign" type="textarea" :disabled="personalSignEdit"></el-input>
+      </el-form-item>
+      <el-form-item label="训练原文" v-if="dataForm.cardNote.type == 'AI'">
+        <el-button v-if="dataForm.cardNote.type === 'AI'" type="success" size="mini" :loading="transLoading" @click="translateTxt">翻译</el-button>
+        <el-input v-model="dataForm.cardNote.trainPersonalSign" type="textarea"></el-input>
+      </el-form-item>
+      <el-form-item label="翻译文本" v-if="dataForm.cardNote.type == 'AI'">
+        <el-button type="primary" size="mini" :loading="transLoading" @click="tts">生成语音</el-button>
+        <el-button type="danger" size="mini" :loading="transLoading" @click="syncTTS">同步语音</el-button>
+        <el-input v-model="dataForm.cardNote.foreignTxt" type="textarea"></el-input>
+      </el-form-item>
+      <el-form-item label="声音模型" v-if="dataForm.cardNote.type == 'AI'">
+        <span style="color:red">{{dataForm.cardNote.modelName}}</span>
+      </el-form-item>
+      <el-row>
+        <el-col :span="dataForm.cardNote.type === 'AI' ? 12 : 8">
+          <el-form-item label="二维码" align="center">
+            <el-image
+              style="width: 300px; height: 300px"
+              :src="resourcesUrl + dataForm.qrNoteMapping.qrCodeUrl"
+              v-if="dataForm.qrNoteMapping.qrCodeUrl"/>
+          </el-form-item>
+        </el-col>
+        <el-col :span="dataForm.cardNote.type === 'AI' ? 12 : 8">
+          <el-form-item label="语音内容">
+            <el-button size="mini" @click="changeAudio">更换音频</el-button>
+            <br/>
+            <video v-if="dataForm.cardNote.audioUrl"
+                   style="width: 300px; height: 210px"
+                   :src="resourcesUrl + dataForm.cardNote.audioUrl"
+                   controls="controls"/>
+          </el-form-item>
+        </el-col>
+        <el-col :span="dataForm.cardNote.type === 'AI' ? 12 : 8" v-if="newAudioUrl">
+          <el-form-item label="新语音内容">
+            <br/>
+            <video
+              style="width: 300px; height: 210px"
+              :src="resourcesUrl + newAudioUrl"
+              controls="controls"/>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-form-item>
+        <div style="width: 100%; text-align: center;">
+          <el-button v-if="!(dataForm.cardNote.type === 'AI')" type="primary" size="large" @click="repairVideo">转换语音</el-button>
+          <el-button type="success" size="large" @click="confirmChangeVideo">确认更换</el-button>
+          <el-button type="success" size="large" @click="onSave">保存</el-button>
+        </div>
+      </el-form-item>
+    </el-form>
+    <audio-box v-if="audioBoxVisible" ref="audioBox" @refreshPic="refreshAudio"></audio-box>
+  </el-dialog>
+</template>
+
+<script>
+  import AudioBox from '@/components/AudioBox'
+  export default {
+    components: {
+      AudioBox
+    },
+    name: "YuyinPreview",
+    data() {
+      return {
+        authorNameEdit: true,
+        personalSignEdit: true,
+        audioBoxVisible: false,
+        visible: false,
+        dataForm:{cardNote:{}, qrNoteMapping:{}},
+        newAudioUrl: null,
+        resourcesUrl: process.env.VUE_APP_RESOURCES_URL,
+        transLoading: false
+      };
+    },
+    mounted() {
+    },
+    methods: {
+      changeAudio(){
+        this.audioBoxVisible = true
+        this.$nextTick(() => {
+          this.$refs.audioBox.init(1)
+        })
+      },
+      refreshAudio(filePath){
+        this.newAudioUrl = filePath;
+      },
+      onSave(){
+        this.$http({
+          url: this.$http.adornUrl('/platform/cardNote'),
+          method: 'PUT',
+          data: this.$http.adornData(this.dataForm.cardNote)
+        }).then(({ data }) =>{
+          if(data){
+            this.visible = false;
+            this.$message.success("保存成功")
+          }else{
+            this.$message.error("保存失败")
+          }
+        })
+      },
+      syncTTS(){
+        this.$http({
+          url: this.$http.adornUrl('/platform/qrNoteMapping/getAIAudio'),
+          method: 'POST',
+          data: this.$http.adornData(this.dataForm.qrNoteMapping)
+        }).then(({ data }) =>{
+          if(data){
+            this.dataForm.cardNote.audioUrl = data
+          }else{
+            this.$message.error("同步失败")
+          }
+        })
+      },
+      tts(){
+        this.$http({
+          url: this.$http.adornUrl('/platform/qrNoteMapping/createAIAudio'),
+          method: 'POST',
+          data: this.$http.adornData(this.dataForm.qrNoteMapping)
+        }).then(({ data }) =>{
+          if(data){
+            this.$message.success("下发成功,请稍后回来查看语音")
+          }else{
+
+          }
+        })
+      },
+      translateTxt(){
+        this.$http({
+          url: this.$http.adornUrl('/cardNote/translate'),
+          method: 'POST',
+          data: this.$http.adornData(this.dataForm.cardNote)
+        }).then(({ data }) =>{
+          if(data){
+            this.dataForm.cardNote.foreignTxt = data
+          }else{
+
+          }
+        })
+      },
+      openCanvas(){
+        this.initCanvas();
+        this.drawImage();
+        this.addMouseListeners();
+      },
+      init(cardItem){
+        this.getQrInfo(cardItem);
+        this.visible = true;
+      },
+      getQrInfo(cardItem) {
+        this.$http({
+          url: this.$http.adornUrl('/platform/qrNoteMapping/getYuyinInfoByCardItemId/' + cardItem.cardItemId),
+          method: 'GET',
+        }).then(({ data }) =>{
+          if(data){
+            this.dataForm = data
+            this.dataForm.cardNote.trainPersonalSign = data.cardNote.personalSign
+          }else{
+
+          }
+        })
+      },
+      repairVideo() {
+        this.$confirm('确定要修复语音吗?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.$http({
+            url: this.$http.adornUrl('/platform/qrNoteMapping/repairVideo'),
+            method: 'POST',
+            data: this.dataForm.cardNote
+          }).then(({ data }) =>{
+            if(data){
+              this.newAudioUrl = data.newAudioUrl
+            }
+          })
+        });
+      },
+      confirmChangeVideo(){
+        this.dataForm.cardNote.audioUrl = this.newAudioUrl;
+        /*this.$confirm('确定要保存新语音吗?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.dataForm.cardNote.newAudioUrl = this.newAudioUrl;
+          this.$http({
+            url: this.$http.adornUrl('/qrNoteMapping/changeVideo'),
+            method: 'POST',
+            data: this.dataForm.cardNote
+          }).then(({ data }) =>{
+            if(data){
+              this.$message.success("转换成功")
+            }else{
+              this.$message.error("转换失败")
+            }
+          })
+        });*/
+      },
+      closeDialog(){
+        this.visible = false
+        this.dataForm = {cardNote:{}, qrNoteMapping:{}}
+        this.newAudioUrl = null
+      }
+    },
+  }
+</script>
+
+<style scoped>
+
+</style>

+ 26 - 0
src/utils/pdf.js

@@ -0,0 +1,26 @@
+/**
+ * 下载pdf
+ * @param {blob} fileArrayBuffer 文件流
+ * @param {String} filename 文件名称
+ */
+import { saveAs } from 'file-saver';
+
+export const downloadPdf = (fileArrayBuffer, filename) => {
+
+  let data = new Blob([fileArrayBuffer], {type: 'application/pdf'});
+  if (typeof window.chrome !== 'undefined') {
+    // Chrome
+    var link = document.createElement('a');
+    link.href = window.URL.createObjectURL(data);
+    link.download = filename;
+    link.click();
+  } else if (typeof window.navigator.msSaveBlob !== 'undefined') {
+    // IE
+    var blob = new Blob([data], {type: 'application/force-download'});
+    window.navigator.msSaveBlob(blob, filename);
+  } else {
+    // Firefox
+    var file = new File([data], filename, {type: 'application/force-download'});
+    window.open(URL.createObjectURL(file));
+  }
+}

+ 9 - 3
src/views/common/home.vue

@@ -4,7 +4,7 @@
     <p class="content">亚米商城专业版并非一个开源软件,作者保留全部的权利。 擅自窃用,即属严重侵权行为,与盗窃无异。产生的一切任何后果责任由侵权者自负。
       擅自窃用,必将追究法律责任!!!</p> -->
 
-    <div v-if="shopStatusInfo.shopStatus !== null && shopStatusInfo.shopStatus !== 1 && userId !== 12 && userId !== 13" class="shop-inf-imperfect-tips">
+    <div v-if="shopStatusInfo.shopStatus !== null && shopStatusInfo.shopStatus !== 1 && userId !== 12 && userId !== 13 &&userId !== 14 && userId !== 15" class="shop-inf-imperfect-tips">
       <div v-if="shopStatusInfo.shopStatus === 2">
         <div>
           <i class="el-icon-warning" />
@@ -30,7 +30,7 @@
       </div>
     </div>
 
-    <div v-if="userId !== 12 && userId !== 13">
+    <div v-if="userId !== 12 && userId !== 13 && userId !== 14 && userId !== 15" >
       <!-- 数据 -->
       <!-- 基本信息 -->
       <div class="order-all-num white-basic">
@@ -320,10 +320,16 @@
       </div>
       <!-- /底部流量走势图 -->
     </div>
-    <div v-else>
+    <div v-if="userId === 12 || userId === 13">
       <h1 style="text-align: center; font-size: 100px">合作平台二</h1>
       <h1 style="text-align: center; font-size: 50px">(玲珑 吃货堂 番茄 中二)</h1>
     </div>
+    <div v-if="userId === 14">
+      <h1 style="text-align: center; font-size: 100px">易卡定制</h1>
+    </div>
+    <div v-if="userId === 15">
+      <h1 style="text-align: center; font-size: 100px">蜗牛定制</h1>
+    </div>
   </div>
 </template>
 

+ 5 - 3
src/views/modules/afterSales/thirdAfterSales.vue

@@ -138,11 +138,11 @@
             </template>
           </el-table-column>
           <!-- 退款金额 -->
-          <!--<el-table-column label="退款金额(按成本)" prop="refundAmount" align="center" width="80px">
+          <el-table-column label="退款金额(按成本)" prop="refundAmount" align="center" width="80px">
             <template slot-scope="scope">
               <span>{{ scope.row.costAmount}}</span>
             </template>
-          </el-table-column>-->
+          </el-table-column>
           <el-table-column label="退款金额" prop="refundAmount" align="center" width="50px">
             <template slot-scope="scope">
               <span>{{ scope.row.refundAmount}}</span>
@@ -337,7 +337,7 @@ export default {
         }else{
           this.orderRefundQueryInfo
         }
-        this.openWxRefundDialog()
+        // this.openWxRefundDialog()
       })
       this.wxRefundBalanceVisible = true;
     },
@@ -350,6 +350,7 @@ export default {
         this.wxRefundData.orderNumber = row.orderNumber
       }
       this.queryWxRefundInfo()
+      this.wxRefundVisible = true
     },
     updateRow(){
       this.refoundRow.status = 1
@@ -381,6 +382,7 @@ export default {
         }).then(({data}) => {
           this.wxRefundBalanceVisible = false;
           this.wxRefundVisible = false;
+          this.wxRefundVisible2 = false;
           this.wxRefundData = {};
           if(updateRow){
             this.updateRow()

+ 193 - 15
src/views/modules/order/order.vue

@@ -52,6 +52,10 @@
               <el-option key="0" label="待审阅" value="0"></el-option>
             </el-select>
           </el-form-item>
+          <el-form-item :label="this.$i18n.t('order.contactTel') + ':'">
+            <el-input v-model="dataForm.mobile" :placeholder="this.$i18n.t('order.pleaseEnterNumber')" clearable
+                      type="number" size="small" class="myinput-appearance"></el-input>
+          </el-form-item>
           <el-form-item label="是否推广:" :label-width="lang === 'en' ? '145px' : '85px'">
             <el-select v-model="dataForm.isPromotion" clearable placeholder="是否推广" size="small">
               <el-option key="1" label="是" value="1"></el-option>
@@ -94,10 +98,6 @@
             </el-select>
           </el-form-item>-->
           <!-- &nbsp;&nbsp;&nbsp; -->
-          <el-form-item :label="this.$i18n.t('order.contactTel') + ':'">
-            <el-input v-model="dataForm.mobile" :placeholder="this.$i18n.t('order.pleaseEnterNumber')" clearable
-                      type="number" size="small" class="myinput-appearance"></el-input>
-          </el-form-item>
           <el-form-item :label="this.$i18n.t('order.theRecipientSName') + ':'">
             <el-input v-model="dataForm.receiver" :placeholder="this.$i18n.t('order.pleaseEnRecipName')" clearable
               size="small"></el-input>
@@ -131,6 +131,9 @@
               size="small"></el-input>
           </el-form-item>-->
           <!-- &nbsp;&nbsp;&nbsp; -->
+          <el-form-item label="张数:" :label-width=" lang === 'en' ? '145px' : '85px'">
+            <InputNumberRange v-model="productNumsRange"></InputNumberRange>
+          </el-form-item>
           <el-form-item :label="this.$i18n.t('order.createTime') + ':'">
             <el-date-picker size="small" v-model="dateRange" type="datetimerange" range-separator="—"
               value-format="yyyy-MM-dd HH:mm:ss" :start-placeholder="this.$i18n.t('date.start')"
@@ -148,7 +151,7 @@
             <div class="default-btn" @click="setDateRange(4)">近5天</div>
             <div class="default-btn primary-btn" @click="searchChange(true)">{{ $t("order.query") }}</div>
             <div class="default-btn" @click="getSoldExcel()">{{ $t("order.export") }}</div>
-            <div class="default-btn" @click="clear()">{{ $t("product.reset") }}</div>
+            <div class="default-btn" @click="clear()">重置</div>
           </el-form-item>
         </div>
         <!-- <div class="operation-box">
@@ -220,9 +223,24 @@
                    @click="mergeOrder">
           合并订单
         </el-button>
-        <el-button style="margin-left: 20px" size="small" type="primary" :loading="exportDeliveryLoading" @click="handleExportDelivery">
+        <el-button style="margin-left: 20px;margin-right: 20px" size="small" type="primary" :loading="exportDeliveryLoading" @click="handleExportDelivery">
           导出发货信息
         </el-button>
+        <div
+          class="default-btn"
+          @click="openGeneratePrintPdfBatchDialog">
+          批量生成PDF
+        </div>
+        <div
+          class="default-btn"
+          @click="openCreateOrderBatchDialog">
+          批量推送订单
+        </div>
+        <div
+          class="default-btn"
+          @click="deliveryThirdBatch">
+          批量发货
+        </div>
 
         <!-- 列标题 -->
         <div :class="['tit', showHeadScroll ? 'fixed-top' : '']">
@@ -560,12 +578,62 @@
       ref="orderAmountUpdate"
       @refreshOrderAmountUpdate="userId === 1? getDataList: getWaitPrintDeliveryPage"
     ></orderAmount-update>
-    <order-info ref="orderInfo"></order-info>
+    <order-info ref="orderInfo" @orderAuditStatusUpdate="handleOrderAuditStatusUpdate"></order-info>
     <order-delivery-update
       v-if="devyVisible"
       ref="orderDeliveryUpdate"
       @refreshOrderDeliveryUpdate="userId === 1? getDataList: getWaitPrintDeliveryPage"
     ></order-delivery-update>
+    <el-dialog
+      title="批量生成PDF"
+      :modal="false"
+      top="200px"
+      :close-on-click-modal="false"
+      :visible.sync="generatePrintPdfBatchVisible">
+      <el-form
+        ref="dataForm"
+        label-width="80px">
+        <el-form-item label="打印渠道" prop="printChannel">
+          <el-select v-model="printChannel" clearable filterable>
+            <!--          <el-option key="GSART" label="广森" value="GSART"></el-option>-->
+            <!--          <el-option key="WoNiu" label="蜗牛" value="WoNiu"></el-option>-->
+            <el-option key="KuaiYin" label="快印" value="KuaiYin"></el-option>
+            <el-option key="Lightning" label="闪电" value="Lightning"></el-option>
+            <el-option key="WoNiu" label="蜗牛" value="WoNiu"></el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <span slot="footer">
+      <el-button type="info" @click="visible = false">{{$t("crud.filter.cancelBtn")}}</el-button>
+      <el-button type="primary" @click="generatePrintPdfBatch">{{$t("crud.filter.submitBtn")}}</el-button>
+    </span>
+    </el-dialog>
+    <el-dialog
+      title="确认打印订单"
+      :modal="false"
+      top="200px"
+      :close-on-click-modal="false"
+      :visible.sync="orderCreateBatchVisible">
+      <el-form
+        :model="dataForm"
+        ref="dataForm"
+        label-width="80px"
+      >
+        <el-form-item label="打印渠道" prop="printChannel">
+          <el-select v-model="printChannel" clearable filterable>
+            <!--<el-option key="GSART" label="广森" value="GSART"></el-option>
+            <el-option key="WoNiu" label="蜗牛" value="WoNiu"></el-option>-->
+            <el-option key="KuaiYin" label="快印" value="KuaiYin"></el-option>
+            <el-option key="Lightning" label="闪电" value="Lightning"></el-option>
+            <el-option key="WoNiu" label="蜗牛" value="WoNiu"></el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <span slot="footer">
+      <el-button type="info" @click="visible = false">{{$t("crud.filter.cancelBtn")}}</el-button>
+      <el-button :loading="orderCreateBatchLoading" type="primary" @click="createOrderBatch">{{$t("crud.filter.submitBtn")}}</el-button>
+    </span>
+    </el-dialog>
   </div>
 </template>
 
@@ -577,9 +645,16 @@ import OrderDeliveryUpdate from './order-delivery-update'
 import moment from 'moment'
 import ProdPic from '@/components/prod-pic'
 import {downloadXls} from "@/utils/excel"
+import InputNumberRange from '@/components/input-number-range'
 export default {
   data() {
     return {
+      printChannel:null,
+      orderCreateBatchLoading: false,
+      deliveryThirdBatch: false,
+      generatePrintPdfBatchVisible: false,
+      orderCreateBatchVisible: false,
+      productNumsRange:[],
       userId: this.$store.state.user.id,
       devyVisible: false,
       skuList: [{key: 'yxk', label: '圆角小卡', value: '圆角小卡'},
@@ -602,7 +677,8 @@ export default {
       dataForm: {},
       dateRange: [],
       status: null,
-      options: [{
+      options: [
+        {
         value: 1,
         label: this.$i18n.t('order.pendingPayment')
       },
@@ -639,7 +715,8 @@ export default {
           label: '普通待发货'
         }
       ],
-      refund: [{
+      refund: [
+        {
         value: 0,
         label: this.$i18n.t('order.noAfterSales')
       },
@@ -659,7 +736,8 @@ export default {
         value: 4,
         label: this.$i18n.t('order.refundFailed')
       }],
-      orderType: [{
+      orderType: [
+        {
         value: 0,
         label: this.$i18n.t('order.normalOrder')
       }, {
@@ -669,14 +747,16 @@ export default {
         value: 2,
         label: this.$i18n.t('order.spikeOrder')
       }],
-      orderMold: [{
+      orderMold: [
+        {
         value: 0,
         label: this.$i18n.t('order.physicalOrder')
       }, {
         value: 1,
         label: this.$i18n.t('order.virtualOrder')
       }],
-      dvyType: [{
+      dvyType: [
+        {
         value: 1,
         label: this.$i18n.t('order.expressDelivery')
       },
@@ -692,7 +772,8 @@ export default {
         value: 4,
         label: this.$i18n.t('order.sameCityDelivery')
       }],
-      payType: [{
+      payType: [
+        {
         value: 0,
         label: this.$i18n.t('order.pointsPayment')
       }, {
@@ -722,7 +803,7 @@ export default {
       lang: localStorage.getItem('lang') || 'zh_CN',
       orderAmountUpdateVisible: false,
       exportDeliveryLoading: false,
-      oldPar: {}
+      oldPar: {},
     }
   },
   computed: {
@@ -737,7 +818,8 @@ export default {
     ConsignmentInfo,
     ProdPic,
     OrderAmountUpdate,
-    OrderDeliveryUpdate
+    OrderDeliveryUpdate,
+    InputNumberRange
   },
   created() {
     // 首页跳转状态参数
@@ -770,6 +852,100 @@ export default {
     // window.addEventListener('scroll', this.scrollToTop)
   },
   methods: {
+    openGeneratePrintPdfBatchDialog(){
+      this.generatePrintPdfBatchVisible = true;
+    },
+    openCreateOrderBatchDialog(){
+      this.orderCreateBatchVisible = true;
+    },
+    handleOrderAuditStatusUpdate(auditStatusReturn){
+      let it = this;
+      this.dataList.forEach((item, index) => {
+        if(item.orderNumber === auditStatusReturn.orderNumber){
+          it.$set(item,'auditStatus',auditStatusReturn.auditStatus)
+          return;
+        }
+      })
+    },
+    /**
+     *  批量生成打印订单PDF
+     */
+    generatePrintPdfBatch(){
+      let dataBody = {"orderNumberList": [...this.dataListSelections], "printChannel":this.printChannel};
+      this.$http({
+        url: this.$http.adornUrl('/platform/order/thirdPrintOrder/generatePrintPdfBatch'),
+        method: 'post',
+        data: this.$http.adornData(dataBody)
+      }).then(({ data }) => {
+        if(data.status === "success"){
+          console.log("发送showTask")
+          this.$Bus.$emit('showTask', true)
+        }else{
+          this.$message({
+            message: data.msg,
+            type: 'error'
+          })
+        }
+      })
+    },
+    /**
+     * 批量推送打印订单P
+     */
+    createOrderBatch(){
+      this.orderCreateBatchLoading = true;
+      let dataBody = {"orderNumberList": [...this.dataListSelections], "printChannel":this.printChannel};
+      this.$http({
+        url: this.$http.adornUrl('/platform/order/thirdPrintOrder/createOrderBatch'),
+        method: 'post',
+        data: this.$http.adornData(dataBody)
+      }).then(({ data }) => {
+        this.orderCreateBatchLoading = false;
+        if(data.status === "success"){
+          this.$message({
+            message: data.msg,
+            type: 'success'
+          })
+        }else{
+          this.$message({
+            message: data.msg,
+            type: 'error'
+          })
+        }
+      }).catch(()=>{
+        this.orderCreateBatchLoading = false;
+      })
+    },
+    /**
+     *  批量第三方发货
+     */
+    deliveryThirdBatch(){
+      let deliveryOrderItemParamList = [];
+      this.dataListSelections.forEach(item =>{
+        let deliveryOrderItemParam = {};
+        deliveryOrderItemParam.orderNumber = item;
+        deliveryOrderItemParam.deliveryType = 1
+        deliveryOrderItemParamList.push(deliveryOrderItemParam);
+      })
+      let dataBody = {"deliveryOrderItemParamList": deliveryOrderItemParamList};
+      this.$http({
+        url: this.$http.adornUrl('/platform/delivery/orderItemsDeliveryThirdBatch'),
+        method: 'PUT',
+        data: this.$http.adornData(dataBody)
+      }).then(({ data }) => {
+        this.dataListSelections = new Set();
+        if(data.status === "success"){
+          this.$message({
+            message: "发货成功",
+            type: 'success'
+          })
+        }else{
+          this.$message({
+            message: data.msg,
+            type: 'danger'
+          })
+        }
+      })
+    },
     shopColor (name) {
       if (name.indexOf('玲珑') > -1) {
         return '#51d99d'
@@ -994,6 +1170,8 @@ export default {
           'refundStatus': this.dataForm.refundStatus,
           'startTime': this.dateRange === null ? null : this.dateRange[0], // 开始时间
           'endTime': this.dateRange === null ? null : this.dateRange[1], // 结束时间
+          'startProductNums': this.productNumsRange === null ? null : this.productNumsRange[0], // 最低张数
+          'endProductNums': this.productNumsRange === null ? null : this.productNumsRange[1], // 最高张数
           'auditStatus': this.dataForm.auditStatus, // 审阅状态
           'prodName': this.dataForm.prodName, // 产品名称,
           'dvyFlowId': this.dataForm.dvyFlowId, //快递单号

+ 29 - 4
src/views/modules/order/orderInfo.vue

@@ -444,7 +444,7 @@
                   <div class="text">PDF文件:</div>
                   <el-link v-if="!!pdfInfo && !!pdfInfo.pdfUrl" type="primary" :underline="false"
                     :href="resourcesUrl + pdfInfo.pdfUrl" target="_blank">查看文件</el-link>
-                  <el-button type="primary" size="mini" @click="generatePdf">生成PDF</el-button>
+                  <el-button type="primary" size="mini" @click="choosePrintChannel2GeneratePdf">生成PDF</el-button>
                 </div>
               </el-col>
               <el-col :span="8">
@@ -639,6 +639,26 @@
         <el-button type="primary" @click="modifyOrderCreateTime()">确认</el-button>
       </div>
     </el-dialog>
+    <el-dialog
+      :append-to-body="true"
+      title="选择PDF渠道"
+      :visible.sync="choosePrintChannleVisible"
+      v-if="choosePrintChannleVisible"
+      width="30%"
+      left
+      :close-on-click-modal="false"
+      :close-on-press-escape="false">
+      <el-form :model="dataForm" label-position="right">
+        <el-select v-model="dataForm.printChannel" clearable filterable>
+          <el-option key="KuaiYin" label="快印" value="KuaiYin"></el-option>
+          <el-option key="Lightning" label="闪电" value="Lightning"></el-option>
+          <el-option key="WoNiu" label="蜗牛" value="WoNiu"></el-option>
+        </el-select>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="generatePdf(dataForm.printChannel)">确认</el-button>
+      </div>
+    </el-dialog>
   </el-dialog>
     <!-- 弹窗, 新增 / 修改 -->
 
@@ -660,6 +680,7 @@ export default {
   name: 'order-info',
   data() {
     return {
+      choosePrintChannleVisible: false,
       visible: false,
       virtualRemarkList: [],
       pdfInfo: {},
@@ -738,6 +759,9 @@ export default {
     // this.init()
   },
   methods: {
+    choosePrintChannel2GeneratePdf(){
+      this.choosePrintChannleVisible = true;
+    },
     handleAuditStatus(orderNumber){
       this.$http({
         url: this.$http.adornUrl('/platform/order/auditStatus/' + orderNumber),
@@ -822,16 +846,17 @@ export default {
     /**
      *  生成作品打印PDF
      */
-     generatePdf () {
+     generatePdf (printChannel) {
       this.generatePdfLoading = true;
       this.$http({
         url: this.$http.adornUrl('/platform/order/generatePdf'),
         method: 'post',
         data: this.$http.adornData({
-          orderNumber: this.dataForm.orderNumber
+          orderNumber: this.dataForm.orderNumber,
+          printChannel: printChannel
         }),
       }).then(({ data }) => {
-        this.generatePdfLoading = false;
+        this.choosePrintChannleVisible = false;
         if(data){
           this.$message({
             message: data,

+ 140 - 0
src/views/modules/print/express-bill-upload.vue

@@ -0,0 +1,140 @@
+<template>
+  <!-- 发货信息,用于导出代发货订单的excel交给快递公司 -->
+  <el-dialog
+    :modal="false"
+    :title="this.$i18n.t('product.uploadTips')"
+    :close-on-click-modal="false"
+    :visible.sync="visible"
+    @close="handleClose"
+    width="38%">
+    <el-form :model="detectMatch" label-position="right">
+      <el-form-item label="导入订单数量">
+        <span autocomplete="off">{{detectMatch.detectNum}}</span>
+      </el-form-item>
+      <el-form-item label="匹配订单数量">
+        <span autocomplete="off">{{detectMatch.matchNum}}</span>
+      </el-form-item>
+    </el-form>
+    <el-upload
+      class="upload-demo"
+      ref="upload"
+      :action="$http.adornUrl('/wave/wave/detectMatchExpressBill/'+ waveId)"
+      :headers="{ Authorization: $cookie.get('Authorization_vs'),locale:lang }"
+      :limit="1"
+      name="file"
+      :on-preview="handlePreview"
+      :on-remove="handleRemove"
+      :on-error="uploadFalse"
+      :on-success="uploadSuccess"
+      :file-list="files"
+      :auto-upload="true"
+      :before-upload="beforeAvatarUpload">
+      <div slot="tip" class="el-upload__tip"></div>
+      <el-button slot="trigger" size="small" icon="el-icon-upload2" style="margin-right: 20px">上传</el-button>
+      <el-button size="small" type="primary" @click="submitUpload" :loading="uploading">提 交</el-button>
+    </el-upload>
+  </el-dialog>
+</template>
+<script>
+export default {
+  data () {
+    return {
+      lang: localStorage.getItem('lang') || 'zh_CN',
+      visible: false,
+      uploading: false,
+      waveId: null,
+      files: [],
+      detectMatch:{},
+    }
+  },
+  methods: {
+    uploadSuccess (detectMatch, file, fileList) {
+      this.detectMatch = detectMatch;
+      this.files = fileList;
+    },
+    uploadFalse (response) {
+      alert(this.$i18n.t('product.fileUploadFail'))
+    },
+    init (waveId) {
+      this.visible = true
+      this.waveId = waveId
+    },
+    // 上传前对文件的大小的判断
+    beforeAvatarUpload (file) {
+      this.upload = true
+      const extension = file.name.split('.')[1] === 'xls'
+      const extension2 = file.name.split('.')[1] === 'xlsx'
+      if (!extension && !extension2) {
+        alert(this.$i18n.t('product.downloadTemplateTips1'))
+        return extension || extension2
+      }
+      return extension || extension2
+    },
+    submitUpload () {
+      if(this.detectMatch.detectNum == null || (this.detectMatch.detectNum != this.detectMatch.matchNum)){
+        this.$message({
+          message: "导入订单数量与匹配订单数量不一致,提交失败",
+          type: 'error'
+        })
+        return;
+      }
+      this.uploading = true;
+      let file = this.files[0].raw;
+      let formData = new FormData();
+      formData.append('file', file);
+      this.$http({
+        url: this.$http.adornUrl(`/wave/wave/importExpressBill/` + this.waveId),
+        method: 'POST',
+        data: formData,
+        headers: {
+          'Content-Type': 'multipart/form-data'
+        }
+      }).then(({data}) => {
+        if(data){
+          this.uploading = false;
+          this.visible = false;
+          this.$message({
+            message: "提交成功",
+            type: 'success'
+          })
+          this.$emit("refreshDataList");
+        }else{
+          this.$message({
+            message: "提交失败",
+            type: 'error'
+          })
+        }
+      }).catch((error) => {
+        this.uploading = false;
+      })
+    },
+    handleRemove (file) {
+
+    },
+    handlePreview (file) {
+      // debugger
+      // if (file.response.status) {
+      //   alert(this.$i18n.t('product.fileSuccess'))
+      //   this.$emit('refreshDataList')
+      // } else {
+      //   alert(this.$i18n.t('product.fileFail'))
+      // }
+    },
+    handleClose(){
+      this.detectMatch = {};
+      this.files = [];
+    }
+  }
+}
+</script>
+<style scoped>
+.download-btn {
+  margin-left: 12px;
+}
+div >>> .el-dialog__body {
+  padding-top: 10px;
+}
+.upload-demo {
+  display: inline-block;
+}
+</style>

+ 872 - 0
src/views/modules/print/print-order-info.vue

@@ -0,0 +1,872 @@
+<template>
+   <el-dialog
+      :title="
+        !dataForm.orderNumber
+          ? this.$i18n.t('crud.addTitle')
+          : this.$i18n.t('order.orderDetail')
+      "
+      :close-on-click-modal="false"
+      :visible.sync="visible"
+      :append-to-body="true"
+      width="80%"
+      @close="closeDialog"
+      v-if="visible"
+      top="1vh"
+   >
+    <div class="new-page-title">
+      <div class="line" />
+      <div class="text">
+        {{
+          !dataForm.orderNumber
+          ? this.$i18n.t('crud.addTitle')
+          : this.$i18n.t('order.orderDetail')
+        }}
+      </div>
+    </div>
+      <el-form
+        :model="dataForm"
+        ref="dataForm"
+        label-width="auto"
+      >
+        <div class="mod-order-orderInfo">
+          <div class="content">
+            <div class="order-number">
+              <div class="number">
+                <span class="text">{{ $t("order.number") }}:</span>
+                {{ dataForm.orderNumber }}
+              </div>
+              <div class="time">
+                <span class="text">{{ $t("order.createTime") }}:</span>
+                {{ dataForm.createTime }}
+              </div>
+              <div class="item">
+                <div class="text">{{ $t("order.orderRemarks") }}:</div>
+                <div class="res">{{ dataForm.remark }}<el-button type="text" @click="buyerRemarkVisible=true">修改</el-button></div>
+              </div>
+            </div>
+            </div>
+            <div :class="['order-info',$t('language') === 'English'?'flex-wrap':'']">
+              <div :class="['info-item',$t('language') === 'English'?'small-width':'']" v-if="dataForm.userAddrOrder && dataForm.userAddrOrder !== null">
+                <div class="item-tit">
+                  {{ $t("order.recipientInformation") }}
+                </div>
+                <div class="item">
+                  <div class="text">
+                    {{
+                      dataForm.dvyType === 2
+                        ? $t("order.deliveryPerson")
+                        : $t("publics.addressee")
+                    }}:
+                  </div>
+                  <div class="res">{{ dataForm.userAddrOrder.receiver }}</div>
+                </div>
+                <div class="item">
+                  <div class="text">{{ $t("shop.contactTel") }}:</div>
+                  <div class="res">{{ dataForm.userAddrOrder.mobile }}</div>
+                </div>
+                <div class="item" v-if="dataForm.dvyType !== 2">
+                  <div class="text">{{ $t("publics.deliveryAddr") }}:</div>
+                  <div class="res">
+                    {{ dataForm.userAddrOrder.province
+                    }}{{ dataForm.userAddrOrder.city
+                    }}{{ dataForm.userAddrOrder.area
+                    }}{{ dataForm.userAddrOrder.street
+                    }}{{ dataForm.userAddrOrder.addr }}
+                  </div>
+                </div>
+              </div>
+            </div>
+            <div class="goods-list">
+              <el-table
+                :data="prodList"
+                :default-expand-all="true"
+                header-cell-class-name="table-header"
+                row-class-name="table-row">
+                <el-table-column type="expand">
+                  <template slot-scope="scope">
+                    <OrderCardItem :orderItem="scope.row" :showFlagBtn="false"/>
+                  </template>
+                </el-table-column>
+                <el-table-column prop="" :label="this.$i18n.t('home.product')">
+                  <template slot-scope="scope">
+                    <!-- 商品信息 -->
+                    <div class="df">
+                      <prod-pic
+                        width="60"
+                        :pic="scope.row.pic"
+                        class="prod-pic"
+                      ></prod-pic>
+                      <div class="name">
+                        <div>
+                          <span v-if="scope.row.giveawayOrderItemId" class="gift-icon">{{ $t("order.giveawayPord") }}</span>
+                          <span>{{ scope.row.prodName }}</span>
+                        </div>
+                        <div
+                          class="order-status"
+                          v-if="
+                            scope.row.returnMoneySts &&
+                            scope.row.returnMoneySts < 5 &&
+                            scope.row.returnMoneySts > 0
+                          "
+                        >
+                          {{
+                              $t("order.refunding")
+                          }}
+                        </div>
+                        <div
+                          class="order-status"
+                          v-if="
+                            scope.row.returnMoneySts &&
+                            scope.row.returnMoneySts === 5
+                          "
+                        >
+                          {{
+                              $t("order.refundsuccessfully")
+                          }}
+                        </div>
+                      </div>
+                    </div>
+                    <!-- / 商品信息 -->
+                  </template>
+                </el-table-column>
+                <el-table-column
+                  prop="count"
+                  :label="this.$i18n.t('order.quantity')"
+                  width="180"
+                  align="center"
+                >
+                  <template slot-scope="scope">
+                    <span>{{ scope.row.prodCount }}</span>
+                  </template>
+                </el-table-column>
+                <el-table-column
+                  prop="count"
+                  label=""
+                  width="180"
+                  align="center"
+                >
+                </el-table-column>
+                <el-table-column
+                  prop="totalPrice"
+                  label=""
+                  width="180"
+                  align="center"
+                >
+                </el-table-column>
+              </el-table>
+              <!--<div class="goods-total">
+                <div class="text-box">
+                  <div class="item">
+                    <div class="text">{{ $t("order.prodTotalPrice") }}:</div>
+                    <div class="number">¥{{ dataForm.total }}</div>
+                  </div>
+                  <div class="item" v-if="dataForm.reduceAmount">
+                    <div class="text">{{ $t("marketing.discountedPrice") }}:</div>
+                    <div class="number">¥{{ dataForm.reduceAmount }}</div>
+                  </div>
+                  <div class="item" v-if="dataForm.freightAmount">
+                    <div class="text">{{ $t("order.shippingFees") }}:</div>
+                    <div class="number">¥{{ dataForm.freightAmount }}</div>
+                  </div>
+                  <div class="item act-price">
+                    <div class="text">{{ $t("order.actualAmount") }}:</div>
+                    <div class="number">¥{{ dataForm.actualTotal }}{{ dataForm.score?" + "+ dataForm.score +$t("order.integral"):''}}</div>
+                  </div>
+                </div>
+              </div>-->
+            </div>
+          </div>
+        </div>
+      </el-form>
+     <el-dialog
+       :append-to-body="true"
+       title="修改买家备注"
+       :visible.sync="buyerRemarkVisible"
+       v-if="buyerRemarkVisible"
+       width="30%"
+       left
+       :close-on-click-modal="false"
+       :close-on-press-escape="false">
+       <el-form :model="dataForm" label-position="right">
+         <el-form-item label="备注" label-width="70px">
+           <el-input v-model="dataForm.remark" autocomplete="off"></el-input>
+         </el-form-item>
+       </el-form>
+       <div slot="footer" class="dialog-footer">
+         <el-button type="primary" @click="modifyBuyerRemarks()">确认</el-button>
+       </div>
+     </el-dialog>
+   </el-dialog>
+</template>
+
+<script>
+import OrderAddrUpdate from '@/components/order-addr-update'
+import OrderRemarkUpdate from '@/components/order-remark-update'
+import ProdPic from '@/components/prod-pic'
+import OrderCardItem from '@/components/order-card-item'
+import OrderPrintCreate from '@/components/order-print-create'
+export default {
+  name: 'order-info',
+  data () {
+    return {
+      buyerRemarkVisible: false,
+      visible: false,
+      dataForm: {
+        orderId: 0,
+        virtualRemark: '',
+        orderNumber: '',
+        remarks: '',
+        shopRemarks: '',
+        total: 0,
+        deliveryExpresses: [],
+        actualTotal: 0,
+        dvyType: '',
+        status: 1,
+        addrOrderId: 0,
+        nickName: '',
+        orderItems: [],
+        orderTime: '',
+        updateTime: '',
+        payTime: '',
+        dvyTime: '',
+        finallyTime: '',
+        cancelTime: '',
+        orderType: '',
+        userAddrOrder: {},
+        shopId:null,
+        auditStatus: 0
+      },
+      resourcesUrl: process.env.VUE_APP_RESOURCES_URL,
+      // 商品列表
+      prodList: [],
+    }
+  },
+  components: {
+    OrderAddrUpdate,
+    ProdPic,
+    OrderCardItem,
+
+  },
+  watch: {
+
+  },
+  created () {
+  },
+  methods: {
+    modifyBuyerRemarks(){
+      this.$http({
+        url: this.$http.adornUrl('/platform/printOrder/modifyRemarks'),
+        method: 'post',
+        data: this.$http.adornData({
+          orderNumber: this.dataForm.orderNumber,
+          remark: this.dataForm.remark
+        }),
+      }).then(({ data }) => {
+        this.buyerRemarkVisible = false
+        if(data){
+          this.$message({
+            message: "修改成功",
+            type: 'success'
+          })
+        }else{
+          this.$message({
+            message: "修改失败",
+            type: 'error'
+          })
+        }
+      })
+    },
+    closeDialog(){
+      this.visible = false;
+      this.$emit('printOrderClose');
+    },
+    init (params) {
+      this.dataForm.orderNumber = params.orderNumber || 0
+      this.dataForm.shopId = params.shopId || null
+      this.orderStatus = params.status || null
+
+      this.visible = true
+      this.$nextTick(() => {
+        this.$refs['dataForm'].resetFields()
+      })
+      if (this.dataForm.orderNumber) {
+        // 修改
+        this.$http({
+          url: this.$http.adornUrl(`/printOrder/printOrder/findPrintOrderInfo`),
+          method: 'GET',
+          params: this.$http.adornParams({orderNumber: this.dataForm.orderNumber})
+        }).then(({ data }) => {
+          this.dataForm = data
+          // 处理商品列表
+          this.prodList = data.orderItemList
+          if (data.orderItemList.length === 1 &&
+              data.orderItemList[0].giveawayList &&
+              data.orderItemList[0].giveawayList.length) {
+            // 单个商品且有赠品时,将主商品和赠品放在同一级列表中展示
+            this.prodList = [...data.orderItemList, ...data.orderItemList[0].giveawayList]
+          }
+        })
+      }
+    },
+  }
+}
+</script>
+
+
+<style>
+.detail-dialog .el-dialog {
+  min-width: 950px;
+  margin-top: 10vh !important;
+}
+
+.detail-dialog .goods-list .has-gutter th.is-leaf {
+  background: #f7f8fa;
+  color: #333;
+  border-bottom: 1px solid #ebeef5;
+  font-weight: 400;
+  border-right: 0;
+}
+
+.detail-dialog .goods-list .el-table td {
+  border-right: 0;
+}
+.left-line {
+  /* padding-left: 30px;
+  padding-bottom: 10px;
+  padding-top: 15px;
+  margin-left: -30px;
+  margin-top: -10px !important;
+  background-color: #fff; */
+  border-left: 1px solid #fff !important;
+}
+</style>
+
+<style lang="scss" scoped>
+.mod-order-orderInfo {
+  height: 100%;
+  width: 100%;
+  font: 14px Arial, "PingFang SC", "Hiragino Sans GB", STHeiti,
+    "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif;
+  color: #333;
+
+  .order-number {
+    display: flex;
+    align-items: center;
+    font-size: 14px;
+    margin-left: 20px;
+  }
+
+  .order-number .text {
+    color: #999;
+  }
+
+  .order-number .number,
+  .order-number .time {
+    display: flex;
+    align-items: center;
+  }
+
+  .order-number .time {
+    margin: 0 15px;
+  }
+
+  .order-state {
+    position: relative;
+    margin-top: 15px;
+    border: 1px solid #eee;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+  }
+
+  .order-state .state-box {
+    padding: 20px 15px;
+    width: 40%;
+    border-right: 1px solid #eee;
+  }
+
+  .order-state .state-box .state {
+    font-size: 20px;
+    font-weight: 700;
+    line-height: 28px;
+  }
+
+  .order-state .state-box .state-des {
+    margin-top: 10px;
+    color: #999;
+  }
+
+  .order-state .state-box .actions {
+    margin-top: 15px;
+  }
+
+  .order-state .state-box .actions .item {
+    display: flex;
+    align-items: center;
+  }
+
+  .order-state .state-box .actions .item .el-button--text {
+    cursor: pointer;
+  }
+
+  .order-state .state-box .actions .item .item-btn {
+    padding: 3px 10px;
+    border: 1px solid #eee;
+    border-radius: 2px;
+  }
+
+  .order-state .state-steps {
+    flex: 1;
+    // margin-left: -80px;
+    padding-bottom: 10px;
+  }
+
+  .order-state .state-steps .el-form-item {
+    margin-bottom: 0;
+  }
+
+  .packages {
+    margin-top: 15px;
+  }
+
+  .packages .p-tab {
+    display: flex;
+    align-items: center;
+    width: 100%;
+    background: #F7F8FA;
+    border: 1px solid #E8E9EC;
+    border-bottom: none;
+    height: 44px;
+  }
+
+  .packages .p-tab .item {
+    background: #F7F8FA;
+    // border: 1px solid #EAEAEA;
+    margin-right: -1px;
+    margin-bottom: -1px;
+    position: relative;
+    text-align: center;
+    line-height: 44px;
+    width: 90px;
+    cursor: pointer;
+    font-size: 12px;
+    font-weight: bold;
+    height: 44px;
+    // border-right: 1px solid #EAEAEA;
+  }
+
+  .packages .p-tab .item:first-child {
+    // border-radius: 3px 0 0 0;
+    border-left: none;
+  }
+
+  .packages .p-tab .item:last-child {
+    // border-radius: 0 3px 0 0;
+    border-left: none;
+  }
+
+  .packages .p-tab .item.active {
+    background: #fff;
+    // border: 1px solid #E8E9EC;
+  }
+
+  .packages .p-con {
+    border: 1px solid #eee;
+    padding: 20px;
+    display: flex;
+  }
+
+  .packages .p-con .deliver-msg {
+    width: 40%;
+    min-width: 430px;
+  }
+
+  .packages .p-con .deliver-msg .d-item {
+    display: flex;
+    align-items: center;
+    margin-bottom: 10px;
+  }
+
+  .packages .p-con .deliver-msg .d-item .text {
+    width: 80px;
+  }
+
+  .packages .p-con .deliver-msg .d-goods {
+    position: relative;
+    width: 340px;
+    margin: 30px 0 0;
+  }
+
+  .packages .p-con .deliver-msg .d-goods.over {
+    margin: 30px 32px 0;
+  }
+
+  .packages .p-con .deliver-msg .d-goods .arrow {
+    position: absolute;
+    top: 28px;
+    width: 22px;
+    height: 22px;
+    background: #eee;
+    border-radius: 50%;
+    cursor: pointer;
+    display: none;
+  }
+
+  .packages .p-con .deliver-msg .d-goods .arrow.disable {
+    opacity: 0.5;
+    cursor: not-allowed;
+  }
+
+  .packages .p-con .deliver-msg .d-goods.over .arrow {
+    display: block;
+  }
+
+  .packages .p-con .deliver-msg .d-goods .arrow.prev {
+    left: -32px;
+  }
+
+  .packages .p-con .deliver-msg .d-goods .arrow.next {
+    right: -32px;
+    -webkit-transform: rotate(180deg);
+    -moz-transform: rotate(180deg);
+    transform: rotate(180deg);
+  }
+
+  .packages .p-con .deliver-msg .d-goods .arrow::before {
+    position: absolute;
+    left: 9px;
+    top: 8px;
+    display: block;
+    width: 5px;
+    height: 5px;
+    content: " ";
+    font-size: 0;
+    border: 1px solid #666;
+    border-width: 1px 1px 0 0;
+    -webkit-transform: rotate(225deg);
+    -moz-transform: rotate(225deg);
+    transform: rotate(225deg);
+  }
+
+  .packages .p-con .deliver-msg .d-goods .item-goods {
+    position: relative;
+    width: 340px;
+    height: 80px;
+    overflow: hidden;
+  }
+
+  .packages .p-con .deliver-msg .d-goods .goods-box {
+    position: absolute;
+    left: 0;
+    display: flex;
+    margin-top: 0;
+    -webkit-transition: all 0.3s;
+    -moz-transition: all 0.3s;
+    transition: all 0.3s;
+  }
+
+  .packages .p-con .deliver-msg .d-goods .goods-box .item {
+    margin-right: 10px;
+    font-size: 12px;
+    cursor: pointer;
+  }
+
+  .packages .p-con .deliver-msg .d-goods .goods-box .item:last-child {
+    margin: 0;
+  }
+
+  .packages .p-con .deliver-msg .d-goods .goods-box .item .img {
+    width: 60px;
+    height: 60px;
+    font-size: 0;
+    margin-bottom: 4px;
+    position: relative;
+  }
+
+  .packages .p-con .deliver-msg .d-goods .goods-box .item .img img {
+    width: 100%;
+    height: 100%;
+  }
+
+  .packages .p-con .deliver-msg .d-goods .goods-box .item .img .number {
+    position: absolute;
+    bottom: 0;
+    right: 0;
+    background: rgba(0, 0, 0, 0.3);
+    color: #fff;
+    border-radius: 6px 0 6px 0;
+    font-size: 12px;
+    height: 16px;
+    line-height: 16px;
+    padding: 0 5px;
+  }
+
+  .packages .p-con .deliver-msg .d-goods .goods-box .item .name {
+    width: 60px;
+    height: 16px;
+    line-height: 16px;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    color: #999;
+  }
+
+  .packages .p-con .logistics {
+    flex: 1;
+  }
+
+  .packages .p-con .logistics .l-tit {
+    display: flex;
+  }
+
+  .packages .p-con .logistics .l-tit .l-state {
+    color: #155BD4;
+  }
+
+  .packages .p-con .logistics .logistics-box {
+    height: 175px;
+    overflow-y: scroll;
+    position: relative;
+    margin-top: 15px;
+  }
+
+  .packages .p-con .logistics .logistics-box::before {
+    position: absolute;
+    left: 0;
+    top: 0;
+    display: block;
+    width: 10px;
+    height: 10px;
+    content: " ";
+    font-size: 0;
+    background: #fff;
+    z-index: 1;
+  }
+
+  .packages .p-con .logistics .logistics-box::after {
+    position: absolute;
+    left: 6px;
+    top: 0;
+    display: block;
+    // width: 1px;
+    height: 100%;
+    content: " ";
+    font-size: 0;
+    background: #eee;
+    z-index: 0;
+  }
+
+  .packages .p-con .logistics .logistics-box .item {
+    padding: 0px 0 40px 25px;
+    position: relative;
+    margin-left: 6px;
+    border-left: 1px solid #eee;
+  }
+
+  .packages .p-con .logistics .logistics-box .item::before {
+    position: absolute;
+    left: -10px;
+    top: 0px;
+    display: block;
+    width: 19px;
+    height: 19px;
+    border-radius: 50%;
+    content: " ";
+    font-size: 0;
+    background: #ccc;
+    border: 5px solid #fff;
+    z-index: 2;
+  }
+
+  .packages .p-con .logistics .logistics-box .item:first-child:before {
+    background: #c00;
+  }
+
+  .packages .p-con .logistics .logistics-box .item .time {
+    color: #999;
+  }
+
+  .packages .p-con .logistics .logistics-box .item .text {
+    margin-top: 5px;
+    width: 400px;
+  }
+
+  .order-info {
+    background: #f7f8fa;
+    margin-top: 15px;
+    display: flex;
+    padding: 20px;
+  }
+
+  .order-info .info-item {
+    width: 25%;
+    padding-right: 30px;
+  }
+
+  .order-info .info-item .item-tit {
+    font-weight: 600;
+  }
+
+  .order-info .info-item .item {
+    margin-top: 10px;
+    display: flex;
+    line-height: 20px;
+  }
+  .order-info .info-item .item .res{
+    word-break: break-word;
+  }
+
+  .order-info .info-item .item .text {
+    // width: 75px;
+    white-space: nowrap;
+  }
+
+  .goods-list {
+    margin-top: 15px;
+  }
+
+  .goods-list .df {
+    display: flex;
+    align-items: center;
+  }
+
+  .goods-list .df .prod-img {
+    display: block;
+    width: 60px !important;
+    height: 60px !important;
+    margin-right: 5px;
+  }
+
+  .goods-list .df .prod-pic {
+    max-width: 60px;
+    margin-right: 6px;
+    flex: 1;
+  }
+
+  .goods-list .df .name {
+    line-height: 20px;
+    flex: 1;
+  }
+
+  .goods-list .df .gift-icon {
+    display: inline-block;
+    min-width: 34px;
+    max-height: 21px;
+    text-align: center;
+    padding: 4px;
+    border-radius: 4px;
+    background: #e43130;
+    color: #fff;
+    font-size: 13px;
+    line-height: 1em;
+    margin-right: 5px;
+  }
+
+  .goods-list .goods-total {
+    display: flex;
+    justify-content: flex-end;
+    margin-top: 20px;
+  }
+
+  .goods-list .goods-total .item {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    color: #999;
+    margin-top: 5px;
+  }
+
+  .goods-list .goods-total .item .text {
+    max-width: 220px;
+    text-align: right;
+  }
+
+  .goods-list .goods-total .item .number {
+    width: 150px;
+    text-align: center;
+  }
+
+  .goods-list .goods-total .item.act-price {
+    margin-top: 20px;
+    color: #333;
+    font-weight: 600;
+  }
+
+  .goods-list .goods-total .item.act-price .number {
+    color: #c00;
+  }
+
+  .order-log {
+    margin-top: 20px;
+    border-top: 1px dashed #e9eaec;
+    padding: 20px 10px;
+  }
+
+  .order-log .log-title {
+    height: 30px;
+    width: 100%;
+    line-height: 30px;
+    font-weight: bold;
+  }
+
+  .order-log .log-cont {
+    color: #666666;
+    margin-top: 10px;
+  }
+  .order-status {
+    display: inline-block;
+    width: auto;
+    text-align: center;
+    margin-top: 5px;
+    padding: 0px 4px;
+    border: 1px solid #e43130;
+    border-radius: 2px;
+    color: #e43130;
+    font-size: 12px;
+  }
+}
+// .el-step.is-horizontal .el-step__line {
+//   top: 19px !important;
+// }
+div ::v-deep .el-step.is-center .el-step__head {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+}
+
+// 赠品
+.gift-prod .item {
+  margin-top: 5px;
+  line-height: 1em;
+  .name {
+    display: inline-block;
+    margin-right: 15px;
+    line-height: 20px;
+    // max-width: 400px;
+    // overflow: hidden;
+    // text-overflow: ellipsis;
+    // white-space: nowrap;
+  }
+}
+
+// 小屏样式适配
+.flex-wrap {
+  flex-wrap: wrap;
+}
+.small-width {
+  width: 50% !important;
+  margin-bottom: 10px;
+}
+.remarkSpan{
+  display: inline-block;
+  line-height: 24px;
+  padding: 5px 0;
+  margin-right: 10px;
+  word-wrap: break-word;
+  word-break: break-all;
+  overflow: hidden;
+}
+</style>
+
+
+

+ 1516 - 0
src/views/modules/print/print-order.vue

@@ -0,0 +1,1516 @@
+<template>
+  <div class="mod-order-order">
+    <div class="search-bar">
+      <el-form
+        :inline="true"
+        :model="dataForm"
+        @keyup.enter.native="getDataList(this.page)"
+        size="small">
+        <div class="input-row">
+          <el-form-item :label="this.$i18n.t('order.number') + ':'" :label-width=" lang === 'en' ? '145px' : '85px'">
+            <el-input
+              v-model="dataForm.orderNumber"
+              :placeholder="this.$i18n.t('order.number')"
+              clearable
+              size="small"
+            ></el-input>
+          </el-form-item>
+          <el-form-item label="店铺" :label-width=" lang === 'en' ? '145px' : '85px'">
+            <el-select v-model="dataForm.shopId" :clearable="true">
+              <el-option v-for="shop in shopPrintChannel.shopList" :key="shop.shopId" :label="shop.shopName" :value="shop.shopId"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="三方单号" :label-width=" lang === 'en' ? '145px' : '85px'">
+            <el-input
+              v-model="dataForm.orderNo"
+              placeholder="请输入三方单号"
+              clearable
+              size="small"
+            ></el-input>
+          </el-form-item>
+          <el-form-item label="订单状态"  :label-width=" lang === 'en' ? '145px' : '85px'">
+            <el-select
+              v-model="dataForm.status"
+              clearable
+              placeholder="请选择订单状态"
+              size="small"
+              @change="orderStatus">
+              <el-option
+                v-for="item in options"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              ></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="产品名称"  :label-width=" lang === 'en' ? '145px' : '85px'">
+            <template>
+              <el-select
+                v-model="dataForm.prodName"
+                size="small"
+                clearable
+                placeholder="产品名称">
+                <el-option key="yjxk" label="圆角小卡" value="圆角小卡"></el-option>
+                <el-option key="zjxk" label="直角小卡" value="直角小卡"></el-option>
+                <el-option key="egg" label="二宫格" value="二宫格"></el-option>
+                <el-option key="sgg" label="四宫格" value="四宫格"></el-option>
+                <el-option key="pld" label="拍立得" value="拍立得"></el-option>
+                <el-option key="zpfm" label="直拍封面" value="直拍封面"></el-option>
+                <el-option key="sq" label="书签" value="书签"></el-option>
+                <el-option key="mxp" label="明信片" value="明信片"></el-option>
+                <el-option key="fk" label="方卡" value="方卡"></el-option>
+                <el-option key="hz" label="徽章" value="徽章"></el-option>
+                <el-option key="sf" label="手幅" value="手幅"></el-option>
+              </el-select>
+            </template>
+          </el-form-item>
+          <el-form-item label="覆膜工艺"  :label-width=" lang === 'en' ? '145px' : '85px'">
+            <template>
+              <el-select
+                v-model="dataForm.skuName"
+                size="small"
+                clearable
+                placeholder="覆膜工艺">
+                <el-option key="lm" label="镜面膜" value="镜面"></el-option>
+                <el-option key="ym" label="哑膜" value="哑膜"></el-option>
+                <el-option key="ls" label="镭射" value="镭射"></el-option>
+                <el-option key="mtx" label="满天星" value="满天星"></el-option>
+                <el-option key="axm" label="爱心膜" value="爱心膜"></el-option>
+<!--                <el-option key="bls" label="玻璃碎" value="玻璃碎"></el-option>-->
+<!--                <el-option key="zgz" label="珠光" value="珠光"></el-option>-->
+                <el-option key="xx" label="星星" value="星星"></el-option>
+                <el-option key="szxs" label="十字星闪" value="十字星闪"></el-option>
+                <el-option key="wjx" label="五角旗星" value="五角旗星"></el-option>
+                <el-option key="yhm" label="烟花膜" value="烟花膜"></el-option>
+              </el-select>
+            </template>
+          </el-form-item>
+          <el-form-item :label="this.$i18n.t('order.theRecipientSName') + ':'"  :label-width=" lang === 'en' ? '145px' : '100px'">
+            <el-input
+              v-model="dataForm.receiverName"
+              :placeholder="this.$i18n.t('order.pleaseEnRecipName')"
+              clearable
+              size="small"
+            ></el-input>
+          </el-form-item>
+          <el-form-item label="运单号:" :label-width=" lang === 'en' ? '145px' : '85px'">
+            <el-input
+              v-model="dataForm.deliveryNo"
+              placeholder="运单号"
+              clearable
+              size="small"></el-input>
+          </el-form-item>
+          <el-form-item :label="this.$i18n.t('shop.contactTel') + ':'"  :label-width=" lang === 'en' ? '145px' : '85px'">
+            <el-input
+              v-model="dataForm.receiverMobile"
+              :placeholder="this.$i18n.t('order.pleaseEnterNumber')"
+              clearable
+              size="small"
+            ></el-input>
+          </el-form-item>
+          <el-form-item label="客服备注"  :label-width=" lang === 'en' ? '145px' : '85px'">
+            <el-input
+              v-model="dataForm.remark"
+              placeholder="客服备注"
+              clearable
+              size="small"
+            ></el-input>
+          </el-form-item>
+          <el-form-item label="色数"  :label-width=" lang === 'en' ? '145px' : '85px'">
+            <template>
+              <el-select
+                v-model="dataForm.colorPrint"
+                clearable
+                size="small">
+                <el-option key="1" label="影像级" value="8"></el-option>
+                <el-option key="2" label="六色" value="6"></el-option>
+                <el-option key="3" label="四色" value="4"></el-option>
+              </el-select>
+            </template>
+          </el-form-item>
+          <el-form-item label="克数"  :label-width=" lang === 'en' ? '145px' : '85px'">
+            <template>
+              <el-select
+                v-model="dataForm.gram"
+                clearable
+                size="small">
+                <el-option key="1" label="400g" value="400g"></el-option>
+                <el-option key="2" label="350g" value="350g"></el-option>
+              </el-select>
+            </template>
+          </el-form-item>
+          <el-form-item label="张数:" :label-width=" lang === 'en' ? '145px' : '85px'">
+            <InputNumberRange v-model="productNumsRange"></InputNumberRange>
+          </el-form-item>
+          <el-form-item :label="this.$i18n.t('order.createTime') + ':' "   :label-width=" lang === 'en' ? '145px' : '85px'">
+            <el-date-picker
+              size="small"
+              v-model="dateRange"
+              type="datetimerange"
+              :default-time="['00:00:00', '23:59:59']"
+              :range-separator="this.$i18n.t('time.tip')"
+              value-format="yyyy-MM-dd HH:mm:ss"
+              :start-placeholder="this.$i18n.t('time.start')"
+              :end-placeholder="this.$i18n.t('time.end')"
+            ></el-date-picker
+            >
+          </el-form-item>
+          <el-form-item>
+            <div v-for="(item, index) in numList" class="default-btn" style="margin-left: 1px;font-size: 15px;" :class="{ 'is-active': numActive === index }"
+                 @click="setNumRange(index)">{{item}}</div>
+          </el-form-item>
+          <el-form-item>
+            <div class="default-btn" :class="{ 'is-active': timeActive === 1 }" @click="setDateRange(1)">{{
+              $t("time.t")
+              }}</div>
+            <div class="default-btn" :class="{ 'is-active': timeActive === 2 }" @click="setDateRange(2)">{{
+              $t("time.y")
+              }}</div>
+            <div class="default-btn" :class="{ 'is-active': timeActive === 3 }" @click="setDateRange(3)">近3天</div>
+            <div class="default-btn" :class="{ 'is-active': timeActive === 4 }" @click="setDateRange(4)">近5天</div>
+            <div class="default-btn primary-btn" @click="searchChange(true)">{{ $t("order.query") }}</div>
+            <div class="default-btn" @click="clear()">{{ $t("shop.resetMap") }}</div>
+          </el-form-item>
+        </div>
+      </el-form>
+    </div>
+    <div class="main">
+      <div class="content">
+        <div style="margin-bottom: 20px">
+          <el-checkbox @change="checked=>handleSelectAll(checked)" class="all-check-btn" v-model="selectAll">全选 </el-checkbox>
+          <span v-if="dataListSelections.size" class="had-selected">已选 {{dataListSelections.size}}</span>
+          <span v-if="dataListSelections.size" class="had-selected" style="font-weight: bold;color: red;font-size: 20px"> {{selectSheets}}张</span>
+          <el-button size="small" type="primary" icon="el-icon-plus" @click="openGenerateWaveDialog">生成波次</el-button>
+          <el-button size="small" icon="el-icon-upload2" @click="openAddToWaveDialog">添加已有波次</el-button>
+<!--          <el-button size="small" type="success" @click="checkAndAutoCreateWave">自动生成波次</el-button>-->
+        </div>
+        <!-- 列标题 -->
+        <div :class="['tit', showHeadScroll ? 'fixed-top' : '']">
+          <el-row style="width: 100%">
+            <el-col :span="5" id="prod-info-title">
+              <span class="item product">订单信息</span>
+            </el-col>
+            <el-col :span="4" class="column-title">
+              <span class="item">产品材质</span>
+            </el-col>
+            <el-col :span="2" class="column-title">
+              <span class="item">张数</span>
+            </el-col>
+            <el-col :span="2" class="column-title">
+              <span class="item">色数</span>
+            </el-col>
+            <el-col :span="2" class="column-title">
+              <span class="item">克数</span>
+            </el-col>
+            <el-col :span="2" class="column-title">
+              <span class="item">买家/收货人</span>
+            </el-col>
+            <el-col :span="2" class="column-title">
+              <span class="item">订单状态</span>
+            </el-col>
+            <el-col :span="2" class="column-title">
+              <span class="item">客服备注</span>
+            </el-col>
+            <el-col :span="3" class="column-title">
+              <span class="item">{{ $t("publics.operating") }}</span>
+            </el-col>
+          </el-row>
+        </div>
+        <div
+          class="prod"
+          v-for="(order, index) in dataList"
+          :key="order.printOrderId">
+          <div class="prod-tit">
+            <el-checkbox v-model="order.checkStatus" :ref="'checkbox' + index" @change="checked=>handleSelectionChange(checked, order)"></el-checkbox>
+            <span class="order-number">{{ $t("order.number") }}:{{ order.orderNumber }}</span>
+            <span class="order-time">用户下单时间:{{ order.orderTime }}</span>
+            <span class="order-time">推送时间:{{ order.createTime }}</span>
+            <span class="order-time">店铺:{{ order.shopName }}</span>
+            <span class="order-time">运单号:{{ order.deliveryNo }}</span>
+          </div>
+          <div class="prod-cont">
+            <el-row style="width: 100%">
+              <el-col :span="5" style="height: 100%">
+                <div class="item prod-item">
+                  <!-- 订单信息 -->
+                  <div class=" items name">
+                    <div class="order-prod-item-info">
+                      <div class="info">
+                        <div class="prod-image">
+                          <prod-pic
+                            height="60"
+                            width="60"
+                            :pic="order.pic"
+                          ></prod-pic>
+                        </div>
+                        <div class="prod-name">
+                          <div class="prod-con">
+                            <div class="prod-name-txt">
+                              {{ order.prodName }}
+                            </div>
+                            <div class="order-status" v-if="order.waveNo" style="cursor: pointer" @click="jumpToWave(order.orderNumber, order.waveId)">
+                              所属波次号: {{order.waveNo}}
+                            </div>
+                          </div>
+                        </div>
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </el-col>
+              <el-col :span="4" style="height: 100%">
+                <div class="item prod-item">
+                  <span>{{order.prodName}}</span>
+                  <!--<el-tooltip placement="top">
+                    <div
+                      slot="content"
+                      style="font-size: 8px"
+                      v-for="orderItem in order.orderItemList"
+                      :key="orderItem.orderItemId">
+                      <div>{{orderItem.prodName}}</div>
+                    </div>
+                    <span v-if="order.orderItemList.length > 1">{{order.orderItemList[0].prodName}} <br/>......</span>
+                    <span v-else>{{order.orderItemList[0].prodName}}</span>
+                  </el-tooltip>-->
+                </div>
+              </el-col>
+              <!-- 张数 -->
+              <el-col :span="2" style="height: 100%">
+                <div class="item">
+                  <span style="font-size: 24px; color: red">{{order.prodNums}} 张</span>
+                </div>
+              </el-col>
+              <!-- 打印色数 -->
+              <el-col :span="2" style="height: 100%">
+                <div class="item">
+<!--                  <el-tag v-if="order.colorPrint === '四色'" type="success">{{order.colorPrint }}</el-tag>-->
+<!--                  <el-tag v-if="order.colorPrint === '影像级'" type="danger">{{order.colorPrint }}</el-tag>-->
+<!--                  <el-tag v-if="order.colorPrint === '六色'" type="warning">{{order.colorPrint }}</el-tag>-->
+                  <span style="font-size: 24px; color: green" v-if="order.colorPrint === '4'">四色</span>
+                  <span style="font-size: 24px; color: orange" v-if="order.colorPrint === '6'">六色</span>
+                  <span style="font-size: 24px; color: red" v-if="order.colorPrint === '8'">影像级</span>
+                </div>
+              </el-col>
+              <!-- 打印克数 -->
+              <el-col :span="2" style="height: 100%">
+                <div class="item">
+                  <span style="font-size: 24px; color: red">{{order.gram}}</span>
+                </div>
+              </el-col>
+              <!-- 买家信息 -->
+              <el-col :span="2" style="height: 100%">
+                <div class="item">
+                  <div class="buyer-info">
+                    <div>
+                      <el-tooltip placement="top">
+                        <div slot="content" style="font-size: 8px">
+                          <span>{{order.userAddrOrder.province }}</span>
+                          <span>{{order.userAddrOrder.city }}</span>
+                          <span>{{order.userAddrOrder.area }}</span>
+                          <span>{{order.userAddrOrder.street }}</span>
+                          <span>{{order.userAddrOrder.addr }}</span>
+                        </div>
+                        <div>
+                          <span>{{order.userAddrOrder.receiver }}</span>
+                          <br/>
+                          <span>{{order.userAddrOrder.mobile }}</span>
+                        </div>
+                      </el-tooltip>
+                    </div>
+                    <!--<div class="buyer-name">{{ order.receiverName }}</div>
+                    <div class="buyer-phone">{{ order.receiverMobile }}</div>-->
+                  </div>
+                </div>
+              </el-col>
+              <!-- 订单状态 -->
+              <el-col :span="2" style="height: 100%">
+                <div class="item">
+                  <span>
+                    <el-tag
+                      v-if="order.status === 1"
+                      type="primary"
+                    >待打印</el-tag
+                    >
+                    <el-tag
+                      v-else-if="order.status === 2"
+                      type="danger"
+                    >待发货</el-tag
+                    >
+                    <el-tag
+                      v-else-if="order.status === 3"
+                      type="success"
+                    >已发货</el-tag>
+                    <el-tag
+                      v-else-if="order.status === 4"
+                      type="warning"
+                    >异常</el-tag>
+                    <el-tag
+                      v-else-if="order.status === 11"
+                      type="info"
+                    >已取消</el-tag>
+                  </span>
+                </div>
+              </el-col>
+              <el-col :span="2" style="height: 100%">
+                <div class="item">
+                  <el-tooltip placement="top" v-if="order.remark">
+                    <div slot="content" style="font-size: 16px">
+                      <span>{{ order.remark }}</span>
+                    </div>
+                    <div>
+                      <div class="buyer-name" style="color:red;overflow: hidden; width: 100px; text-overflow:ellipsis">{{ order.remark }}</div>
+                    </div>
+                  </el-tooltip>
+                  <span v-else>暂无备注</span>
+                </div>
+              </el-col>
+              <el-col :span="3" style="height: 100%">
+                <div class="item">
+                  <div class="operate">
+                    <div
+                      class="default-btn text-btn operate-btn"
+                      @click="openPrintOrderDialog(order.orderNumber)">详情</div>
+                    <div
+                      class="default-btn text-btn operate-btn"
+                      @click="updateStatus(order, 4)"
+                      v-if="order.status === 1">标记异常</div>
+                    <div
+                      class="default-btn text-btn operate-btn"
+                      @click="updateStatus(order, 1)"
+                      v-if="order.status === 4">标记正常</div>
+                    <div
+                      class="default-btn text-btn operate-btn"
+                      @click="updateStatus(order, 11)">取消订单
+                    </div>
+                  </div>
+                </div>
+              </el-col>
+            </el-row>
+          </div>
+        </div>
+        <!--<div class="empty" v-if="!dataList.length">
+          {{ $t("order.noData") }}
+        </div>-->
+      </div>
+    </div>
+    <el-pagination
+      ref="orderListTable"
+      v-if="dataList.length"
+      @size-change="sizeChangeHandle"
+      @current-change="currentChangeHandle"
+      :current-page="page.currentPage"
+      :page-sizes="[10, 20, 50, 100]"
+      :page-size="page.pageSize"
+      :total="page.total"
+      layout="total, sizes, prev, pager, next, jumper"
+    ></el-pagination>
+
+    <!-- 生成波次弹窗 -->
+    <el-dialog
+      v-if="generateWaveDialogVisible"
+      title="生成波次"
+      :visible.sync="generateWaveDialogVisible"
+      width="40%"
+      center
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+    >
+      <el-form :model="wave">
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="打印渠道" label-width="100px">
+              <el-select v-if="shopPrintChannel.printChannelList.length > 1" v-model="wave.printChannel" @change="getLatestWaveNo">
+                <el-option key="KuaiYin" label="快印" value="KuaiYin"></el-option>
+                <el-option key="Lightning" label="闪电" value="Lightning"></el-option>
+              </el-select>
+              <div v-else>
+                <span v-if="shopPrintChannel.printChannelList[0] === 'KuaiYin'">快印</span>
+                <span v-if="shopPrintChannel.printChannelList[0] === 'Lightning'">闪电</span>
+              </div>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="店铺" label-width="100px">
+              <el-select v-if="shopPrintChannel.shopList.length > 1" v-model="wave.shopId" @change="getLatestWaveNo">
+                <el-option v-for="shop in shopPrintChannel.shopList" :key="shop.shopId" :label="shop.shopName" :value="shop.shopId"></el-option>
+              </el-select>
+              <span v-else>{{shopPrintChannel.shopList[0].shopName}}</span>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="波次号" label-width="100px">
+          <span autocomplete="off">{{wave.waveNo}}</span>
+        </el-form-item>
+        <el-form-item label="备注名" label-width="100px">
+          <el-input v-model="wave.waveName" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="订单数" label-width="100px">
+          <span autocomplete="off">{{dataListSelections.size}}</span>
+        </el-form-item>
+        <el-form-item label="色数" label-width="100px">
+          <el-select v-model="wave.colorPrint">
+            <el-option key="YX" label="影像级" value="8"></el-option>
+            <el-option key="LS" label="六色" value="6"></el-option>
+            <el-option key="SS" label="四色" value="4"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="克数" label-width="100px">
+          <el-select v-model="wave.gram">
+            <el-option key="1" label="400g" value="400g"></el-option>
+            <el-option key="2" label="350g" value="350g"></el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="createWave">生 成</el-button>
+      </div>
+    </el-dialog>
+    <!-- 添加到已有波次弹窗 -->
+    <el-dialog
+      title="添加到已有波次"
+      v-if="addToWaveDialogVisible"
+      :visible.sync="addToWaveDialogVisible"
+      width="40%"
+      center
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+      @close="handleAddToWaveDialogClose"
+    >
+      <el-form :model="wave">
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="打印渠道" label-width="100px">
+              <el-select v-if="shopPrintChannel.printChannelList.length > 1" v-model="wave.printChannel" @change="getLatestWave">
+                <el-option key="KuaiYin" label="快印" value="KuaiYin"></el-option>
+                <el-option key="Lightning" label="闪电" value="Lightning"></el-option>
+              </el-select>
+              <div v-else>
+                <span v-if="shopPrintChannel.printChannelList[0] === 'KuaiYin'">快印</span>
+                <span v-if="shopPrintChannel.printChannelList[0] === 'Lightning'">闪电</span>
+              </div>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="店铺" label-width="100px">
+              <el-select v-if="shopPrintChannel.shopList.length > 1" v-model="wave.shopId" @change="getLatestWave">
+                <el-option v-for="shop in shopPrintChannel.shopList" :key="shop.shopId" :label="shop.shopName" :value="shop.shopId"></el-option>
+              </el-select>
+              <span v-else>{{shopPrintChannel.shopList[0].shopName}}</span>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="波次" label-width="100px">
+          <el-select v-model="wave.selectWaveId" clearable placeholder="请选择波次" @change="handleWaveChange" style="width: 300px">
+            <el-option-group
+              label="波次号|备注名">
+              <el-option
+                v-for="(item, index) in wave.latestWaveList"
+                :key="item.waveId"
+                :label="item.waveNo + '|' + item.waveName"
+                :value="item.waveId">
+              </el-option>
+            </el-option-group>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="原订单数" label-width="100px">
+          <span autocomplete="off">{{wave.orderNum}}</span>
+        </el-form-item>
+        <el-form-item label="添加数" label-width="100px">
+          <span autocomplete="off">{{dataListSelections.size}}</span>
+        </el-form-item>
+        <el-form-item label="色数" label-width="100px">
+          <span autocomplete="off">{{wave.colorPrint}}</span>
+        </el-form-item>
+        <el-form-item label="克数" label-width="100px">
+          <span autocomplete="off">{{wave.gram}}</span>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="addToWave">添 加</el-button>
+      </div>
+    </el-dialog>
+    <!-- 订单详情 -->
+    <print-order-info ref="printOrderInfo" v-if="printOrderDialogVisible" @printOrderClose="printOrderClose"></print-order-info>
+    <!-- 波次订单 -->
+    <wave-print-order ref="wavePrintOrder"></wave-print-order>
+
+  </div>
+</template>
+
+<script>
+  import ProdPic from '@/components/prod-pic'
+  import InputNumberRange from '@/components/input-number-range';
+  import PrintOrderInfo from './print-order-info';
+  import WavePrintOrder from './wave-print-order';
+  import moment from 'moment'
+
+  export default {
+    data () {
+      return {
+        shopList: [],
+        // 是否全选
+        shopId: this.$store.state.user.shopId,
+        selectAll: false,
+        showHeadScroll: false, // 修改物流相关
+        logVisible: false,
+        radio: '1',
+        logisticsInfo: [],  // 包裹列表
+        logDataForm: {
+          dvyId: '', // 当前物流公司id
+          dvyFlowId: '',  // 物流单号
+          dvyNames: []  // 物流公司列表
+        },
+        uploadVisible: false,
+        lang: localStorage.getItem('lang'),
+        errorNum: 0,
+        // 确认修改弹窗
+        isReviseLog: true,  // 是否正在修改物流信息
+        confirmList: [],  // 确认修改信息
+        dataForm: {status:1},
+        sts: 0,
+        dateRange: [],
+        productNumsRange:[],
+        status: null,
+        options: [
+          {
+          value: 1,
+          label: "待打印"
+          },
+          {
+            value: 2,
+            label: "待发货"
+          },
+          {
+            value: 3,
+            label: "已发货"
+          },
+          {
+            value: 4,
+            label: "异常"
+          },
+          {
+            value: 11,
+            label: "已取消"
+          },
+          ],
+        refund: [
+          {
+          value: 0,
+          label: this.$i18n.t('order.noAfterSales')},
+          {
+            value: 1,
+            label: this.$i18n.t('order.requestARefund')
+          },
+          {
+            value: 2,
+            label: this.$i18n.t('order.refundsuccessfully')
+          },
+          {
+            value: 3,
+            label: this.$i18n.t('order.partialRefundSucc')
+          },
+          {
+            value: 4,
+            label: this.$i18n.t('order.refundFailed')
+          }],
+        resourcesUrl: process.env.VUE_APP_RESOURCES_URL,
+        dataList: [],
+        page: {
+          total: 0, // 总页数
+          currentPage: 1, // 当前页数
+          pageSize: 50 // 每页显示多少条
+        },
+        numList: [10, 20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240,250,260,270,280,290,300,'更多'],
+        dataListLoading: false,
+        dataListSelections: new Set(),
+        selectSheets: 0,
+        generateWaveDialogVisible: false,
+        timeActive: null,
+        numActive: null,
+        priceWidth: '109px',
+        infoWidth: '400px',
+        orderCreateBatchVisible: false,
+        orderCreateBatchLoading: false,
+        wavePrintOrderVisible: false,
+        newWaveNo: null,
+        wave:{
+          waveNo:null,
+          waveName:null,
+          orderNumberList: null,
+          latestWaveList: null,
+          selectWaveId: null,
+          orderNum: 0,
+          sheets:0,
+          printChannel: null,
+        },
+        shopPrintChannel: {printChannelList:[], shopList:[]},
+        addToWaveDialogVisible: false,
+        printOrderDialogVisible: false
+      }
+    },
+    components: {
+      ProdPic,
+      InputNumberRange,
+      PrintOrderInfo,
+      WavePrintOrder
+    },
+    computed: {
+      // 二级菜单折叠状态
+      sidebarFold: {
+        get () { return this.$store.state.common.sidebarFold },
+        set (val) { this.$store.commit('common/updateSidebarFold', val) }
+      }
+    },
+    created () {
+    // 请求物流公司
+      this.getShopPrintChannel()
+      // 携带参数查询
+      this.getDataList(this.page, this.$route.query)
+    },
+    activated () {
+      // 携带参数查询
+      var query = this.$route.query
+      if (Object.keys(query).length > 0) {
+        this.getDataList(this.page, query)
+      }
+    },
+    mounted () {
+      // 监听页面滚动
+      // window.addEventListener('scroll', this.scrollToTop)
+    },
+    watch: {
+
+    },
+    methods: {
+      getLatestWaveNo(){
+        this.$http({
+          url: this.$http.adornUrl(`/platform/wave/getLatestWaveNo`),
+          method: 'GET',
+          params: this.$http.adornParams({printChannel: this.wave.printChannel, shopId: this.wave.shopId})
+        }).then(({data}) => {
+          if(data.status == "success"){
+            this.wave.waveNo = data.result;
+          }
+        })
+      },
+      getLatestWave(){
+        this.$http({
+          url: this.$http.adornUrl(`/platform/wave/getLatestWave`),
+          method: 'GET',
+          params: this.$http.adornParams({printChannel: this.wave.printChannel, shopId: this.wave.shopId, queryLimit: 30})
+        }).then(({data}) => {
+          if(data.status == "success"){
+            this.addToWaveDialogVisible = true;
+            this.wave.latestWaveList = data.result;
+          }
+        })
+      },
+      getShopPrintChannel(){
+        this.$http({
+          url: this.$http.adornUrl(`/platform/shopPrintChannel/list`),
+          method: 'GET',
+          params: this.$http.adornParams({})
+        }).then(({data}) => {
+          this.shopPrintChannel = data;
+          this.wave.printChannel = this.shopPrintChannel.printChannelList[0]
+          this.wave.shopId = this.shopPrintChannel.shopList[0].shopId
+        })
+      },
+      printOrderClose(){
+        this.printOrderDialogVisible = false;
+      },
+
+      wavePrintOrderClose(){
+        this.wavePrintOrderVisible = false;
+      },
+      jumpToWave(orderNumber, waveId){
+        this.$refs.wavePrintOrder.openAndQueryPrintOrder({orderNumber: orderNumber, waveId: waveId})
+      },
+      openPrintOrderDialog(orderNumber){
+        this.printOrderDialogVisible = true;
+        this.$nextTick(() => {
+          this.$refs.printOrderInfo.init({
+            orderNumber: orderNumber,
+          })
+        });
+      },
+      openGenerateWaveDialog(){
+        if(this.dataListSelections.size === 0){
+          this.$message.error("请至少选择一个订单");
+          return ;
+        }
+        this.getLatestWaveNo();
+        this.generateWaveDialogVisible = true;
+      },
+      openAddToWaveDialog(){
+        if(this.dataListSelections.size === 0){
+          this.$message.error("请至少选择一个订单");
+          return ;
+        }
+        this.getLatestWave();
+        this.addToWaveDialogVisible = true;
+      },
+      checkAndAutoCreateWave(){
+        this.$confirm('确定要自动生成波次吗?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.$http({
+            url: this.$http.adornUrl(`/platform/wave/checkAndAutoCreateWave`),
+            method: 'POST',
+            data: this.$http.adornData()
+          }).then(({data}) => {
+            if(data){
+              this.$message({
+                type: "success",
+                message: "波次生成成功"
+              })
+            }else{
+              this.$message({
+                type: "warning",
+                message: "无波次生成"
+              })
+            }
+          }).catch(() => {
+            this.$message({
+              type: "error",
+              message: "波次生成失败"
+            })
+          })
+        });
+
+      },
+      handleWaveChange(val){
+        this.wave.latestWaveList.forEach(item =>{
+          if(item.waveId == val){
+            this.wave.orderNum = item.orderNum;
+            this.wave.colorPrint = item.colorPrint;
+            this.wave.gram = item.gram;
+            return;
+          }
+        })
+      },
+      handleAddToWaveDialogClose(){
+        this.wave.selectWaveId = null;
+        this.wave.orderNum = 0;
+        this.wave.colorPrint = null;
+        this.wave.gram = null;
+      },
+      updateStatus(row, status){
+        this.$http({
+          url: this.$http.adornUrl(`/platform/printOrder/updateStatus`),
+          method: 'POST',
+          data: this.$http.adornData({printOrderId: row.printOrderId, status: status})
+        }).then(({data}) => {
+          if(data){
+            this.$message({
+              message: "标记成功",
+              type: 'success'
+            })
+            this.getDataList(this.page, null, false);
+          }else{
+            this.$message({
+              message: "标记失败",
+              type: 'error'
+            })
+          }
+        })
+      },
+      createWave(){
+        let dataBody = {colorPrint: this.wave.colorPrint, gram: this.wave.gram, waveName: this.wave.waveName, "orderNumberList": [...this.dataListSelections], "printChannel": this.printChannel};
+        this.$http({
+          url: this.$http.adornUrl(`/platform/wave/create`),
+          method: 'POST',
+          data: this.$http.adornData(dataBody)
+        }).then(({data}) => {
+          if(data){
+            this.generateWaveDialogVisible = false;
+            this.$message({
+              message: "生成波次成功",
+              type: 'success'
+            })
+            this.getDataList(this.page);
+            let it = this;
+            this.dataList.forEach((item, index) => {
+              it.$set(item,'checkStatus',false)
+              it.dataListSelections.delete(item.orderNumber);
+              it.selectAll = false;
+            })
+          }else{
+            this.$message({
+              message: "生成波次失败",
+              type: 'error'
+            })
+          }
+        })
+      },
+      addToWave(){
+        if(!this.wave.selectWaveId){
+          this.$message({
+            message: "请选择波次",
+            type: 'error'
+          })
+          return;
+        }
+        let dataBody = {waveId: this.wave.selectWaveId, "orderNumberList": [...this.dataListSelections], "printChannel": this.printChannel};
+        this.$http({
+          url: this.$http.adornUrl(`/platform/wave/addToWave`),
+          method: 'POST',
+          data: this.$http.adornData(dataBody)
+        }).then(({data}) => {
+          if(data.status == "success"){
+            this.addToWaveDialogVisible = false;
+            this.$message({
+              message: data.msg,
+              type: 'success'
+            })
+            this.getDataList(this.page);
+            let it = this;
+            this.dataList.forEach((item, index) => {
+              it.$set(item,'checkStatus',false)
+              it.dataListSelections.delete(item.orderNumber);
+              it.selectAll = false;
+              });
+          }else{
+            this.$message({
+              message: data.msg,
+              type: 'error'
+            })
+          }
+        })
+      },
+      openCreateOrderBatchDialog(){
+        this.orderCreateBatchVisible = true;
+      },
+      handleOrderAuditStatusUpdate(auditStatusReturn){
+        let it = this;
+        this.dataList.forEach((item, index) => {
+          if(item.orderNumber == auditStatusReturn.orderNumber){
+            it.$set(item,'auditStatus',auditStatusReturn.auditStatus)
+            return;
+          }
+        })
+      },
+      /**
+       * 全选按钮
+       */
+      handleSelectAll (checked) {
+        let it = this;
+        it.selectSheets = 0;
+        if(checked){
+          it.selectAll = true;
+          this.dataList.forEach((item, index) => {
+            it.$set(item,'checkStatus',true)
+            it.dataListSelections.add(item.orderNumber);
+            it.selectSheets = it.selectSheets + item.prodNums;
+          })
+        }else{
+          this.dataList.forEach((item, index) => {
+            it.$set(item,'checkStatus',false)
+            it.dataListSelections.delete(item.orderNumber);
+          })
+          it.selectAll = false;
+          this.selectSheets = 0;
+        }
+
+      },
+      handleSelectionChange(checked, order){
+        if(checked){
+          this.dataListSelections.add(order.orderNumber);
+          this.selectSheets = this.selectSheets + order.prodNums;
+          if(this.dataListSelections.size === this.dataList.length){
+            this.selectAll = true;
+          }
+        }else{
+          this.dataListSelections.delete(order.orderNumber);
+          this.selectSheets = this.selectSheets - order.prodNums;
+          if(this.dataListSelections.size == 0){
+            this.selectAll = false;
+            this.selectSheets = 0;
+          }
+        }
+      },
+      /**
+       * 页面滚动事件
+       */
+      scrollToTop () {
+        // let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
+        // this.showHeadScroll = scrollTop > 400
+      },
+
+
+
+      /**
+       * 获取数据列表
+       */
+      getDataList (page, params, newData = false) {
+        page = (page === undefined ? this.page : page)
+        this.dataListLoading = true
+        if (newData || !this.theData) {
+          this.theData = {
+            current: page == null ? this.page.currentPage : page.currentPage,
+            size: page == null ? this.page.pageSize : page.pageSize,
+            'orderNumber': this.dataForm.orderNumber,
+            'receiverName': this.dataForm.receiverName,
+            'receiverMobile': this.dataForm.receiverMobile,
+            'status': this.dataForm.status,
+            'refundStatus': this.dataForm.refundStatus,
+            'startTime': this.dateRange === null ? null : this.dateRange[0], // 开始时间
+            'endTime': this.dateRange === null ? null : this.dateRange[1], // 结束时间
+            'startProductNums': this.productNumsRange === null ? null : this.productNumsRange[0], // 订购数量起
+            'endProductNums': this.productNumsRange === null ? null : this.productNumsRange[1], // 订购数量起
+            'prodName': this.dataForm.prodName, // 产品名称
+            'isMerge': this.dataForm.isMerge, // 是否合单
+            'printChannel': this.printChannel,
+            'skuName': this.dataForm.skuName,
+            'prodNums': this.dataForm.prodNums,
+            'deliveryNo': this.dataForm.deliveryNo,
+            'isPromotion': this.dataForm.isPromotion,
+            'orderNo': this.dataForm.orderNo,
+            'remark': this.dataForm.remark,
+            'colorPrint': this.dataForm.colorPrint,
+            'gram': this.dataForm.gram,
+            'shopId': this.dataForm.shopId
+          }
+        } else {
+          this.theData.current = page == null ? this.page.currentPage : page.currentPage
+          this.theData.size = page == null ? this.page.pageSize : page.pageSize
+          this.theData.status = this.dataForm.status
+        }
+        this.$http({
+          url: this.$http.adornUrl('/platform/printOrder/page'),
+          method: 'get',
+          params: this.$http.adornParams(
+            Object.assign(this.theData, params
+            ), false
+          )
+        }).then(({ data }) => {
+          this.dataList = data.records;
+          this.page.total = data.total
+          this.sts = !this.status ? 0 : this.status
+          this.dataListLoading = false
+          this.activeName = !this.status ? '0' : this.status + '';
+          let it = this;
+          this.dataList.forEach((item, index) => {
+            it.$set(item,'checkStatus',false)
+            it.dataListSelections.delete(item.orderNumber);
+          })
+          this.dataListSelections = new Set();
+          this.selectAll = false;
+          this.selectSheets = 0;
+        })
+      },
+      // 每页数
+      sizeChangeHandle (val) {
+        this.page.pageSize = val
+        this.page.currentPage = 1
+        this.getDataList(this.page)
+      },
+      // 当前页
+      currentChangeHandle (val) {
+        this.dataListSelections = new Set();
+        this.page.currentPage = val
+        this.getDataList(this.page, null, false);
+      },
+
+      // 多选
+      selectionChangeHandle (val) {
+        this.dataListSelections = val
+      },
+      orderStatus (val) {
+        this.status = val
+        this.activeName = val + ''
+        this.getDataList(this.page)
+      },
+      /**
+       * 根据选项设置时间
+       * 1:今天 2:昨天 3: 近七天 4:近30天 5:近60天
+       */
+      setDateRange (val) {
+        this.timeActive = val
+        var startDay = null
+        var endDay = null
+        if (val === 1) {
+          startDay = 0
+          endDay = 0
+        } else if (val === 2) {
+          startDay = -1
+          endDay = -1
+        } else if (val === 3) {
+          startDay = -3
+          endDay = -1
+        } else if (val === 4) {
+          startDay = -5
+          endDay = -1
+        } else {
+          return
+        }
+        // 开始时间
+        let startTime = moment().add(startDay, 'days').startOf('days').format('LL')
+        // 结束时间
+        let endTime = moment().add(endDay, 'days').endOf('days').format('LL')
+        this.dateRange = [startTime, endTime]
+      },
+      setNumRange(val){
+        this.numActive = val;
+        if(val == this.numList.length - 1){
+          this.dataForm.prodNums = -1;
+        }else{
+          this.dataForm.prodNums = this.numList[val];
+        }
+        this.getDataList(this.page, null, true);
+      },
+      // 查看订单
+      addOrUpdateHandle (orderNumber, shopId, status) {
+        this.$refs.orderInfo.init({
+          orderNumber: orderNumber,
+          shopId: shopId,
+          status: status
+        })
+      },
+      // 删除
+      deleteHandle (id) {
+        var ids = id ? [id] : this.dataListSelections.map(item => {
+          return item.orderId
+        })
+        this.$confirm(`${this.$i18n.t('sys.makeSure')}[${id ? this.$i18n.t('text.delBtn') : this.$i18n.t('sys.batchDelete')}]${this.$i18n.t('text.menu')}?`, this.$i18n.t('text.tips'), {
+          confirmButtonText: this.$i18n.t('crud.filter.submitBtn'),
+          cancelButtonText: this.$i18n.t('crud.filter.cancelBtn'),
+          type: 'warning'
+        }).then(() => {
+          this.$http({
+            url: this.$http.adornUrl(`/prod/spec/${ids}`),
+            method: 'delete',
+            data: this.$http.adornData(ids, false)
+          }).then(({ data }) => {
+            this.$message({
+              message: this.$i18n.t('publics.operation'),
+              type: 'success',
+              duration: 1500,
+              onClose: () => {
+                this.getDataList(this.page)
+              }
+            })
+          })
+        }).catch(() => { })
+      },
+      // 清空按钮
+      clear () {
+        this.dataForm = {};
+        this.dateRange = [];
+        this.status = null;
+        this.timeActive = null;
+        this.numActive = null;
+        this.getDataList(this.page, null, false)
+      },
+      // 搜索查询
+      searchChange (newData = false) {
+        this.page.currentPage = 1;
+        this.getDataList(this.page, null, newData)
+      },
+    },
+    destroyed () {
+      // 页面销毁时移除监听
+      window.removeEventListener('scroll', this.handleScroll)
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  .mod-order-order {
+    .search-bar {
+      .input-row {
+        .select-time-btn {
+          margin-right: 20px;
+          display: inline-block;
+          color: #AAAAAA;
+          font-size: 14px;
+          cursor:pointer;
+          &:last-child {
+            margin-right: 0;
+          }
+        }
+        .select-time-btn.is-active {
+          color: #155BD4;
+        }
+
+      }
+    }
+    .main {
+      .content {
+        .all-check-btn {
+          margin-right: 10px;
+        }
+        .had-selected {
+          font-size: 12px;
+          margin-right: 10px;
+        }
+      }
+      .order-status-nav {
+        position: relative;
+        display: block;
+        width: 100%;
+        margin-bottom: 15px;
+        height: 40px;
+        line-height: 40px;
+        border-bottom: 1px solid #ddd;
+        ul,
+        li {
+          list-style: none;
+          padding: 0;
+          margin: 0;
+        }
+        .nav-item {
+          float: left;
+          height: 40px;
+          line-height: 40px;
+          background: #f7f8fa;
+          border: 1px solid #ddd;
+          padding: 0 20px;
+          margin: 0 -1px -1px 0;
+          cursor: pointer;
+        }
+
+        .selected {
+          background: #fff;
+          border-bottom: 1px solid #fff;
+        }
+      }
+      .status-nav {
+        ::v-deep .el-tabs__item {
+          padding: 0 20px ;
+          min-width: 68px;
+          width: auto;
+          text-align: center;
+        }
+        ::v-deep .el-tabs__nav-wrap::after{
+          height: 1px;
+        }
+      }
+      .tit {
+        display: flex;
+        align-items: center;
+        margin-bottom: 15px;
+        background: #F7F8FA;
+        z-index: 11;
+        height: 57px;
+        font-weight: bold;
+        .column-title {
+          text-align: center;
+        }
+        .item {
+          padding: 0 10px;
+          width: 10%;
+          text-align: center;
+        }
+        .product {
+          width: 25%;
+          margin-bottom: 15px;
+          text-align: left !important;
+        }
+      }
+      .fixed-top {
+        position: fixed;
+        width: calc(83.5% + var(--tit-width-incremental));
+        top: 90px;
+      }
+      .prod {
+        margin-bottom: 15px;
+        .prod-tit {
+          padding: 10px;
+          background: #F7F8FA;
+          height: 49px;
+          display: flex;
+          align-items: center;
+          border-left: 1px solid #EBEDF0;
+          border-top: 1px solid #EBEDF0;
+          border-right: 1px solid #EBEDF0;
+          .order-number{
+            color: #333333;
+            font-size: 14px
+          }
+          .order-index{
+            color: red;
+            font-size: 14px;
+            font-weight: bold;
+          }
+          .order-time{
+            color: #999999;
+            font-size: 14px
+          }
+          span {
+            margin-right: 15px;
+          }
+        }
+        .prod-cont {
+          display: flex;
+          border: 1px solid #EBEDF0;
+          color: #495060;
+          .item {
+            display: flex;
+            display: -webkit-flex;
+            align-items: center;
+            padding: 10px;
+            text-align: center;
+            justify-content: center !important;
+            height: 100%;
+            border-right: 1px solid #eee;
+            .totalprice {
+              color: #ff4141;
+              margin-bottom: 10px;
+            }
+            .operate {
+              color: #2d8cf0;
+              .operate-btn {
+                margin: 0 !important;
+                height: auto;
+              }
+              .default-btn + .default-btn {
+                display: block;
+                margin-top: 10px;
+                margin-left: 0;
+              }
+            }
+            .buyer-info {
+              .buyer-name {
+                margin-bottom: 4px;
+              }
+            }
+            span {
+              display: block;
+            }
+          }
+          .prod-item {
+            padding: 0;
+            display: flex;
+            flex-direction: column !important;
+            height: 100%;
+            border-right: 1px solid #eee;
+            .items.name {
+              width: 100%;
+              display: flex;
+              align-items: center;
+              border-bottom: 1px solid #EBEDF0;
+              padding: 10px !important;
+              text-align: left;
+              &:last-child {
+                border-bottom: none;
+              }
+              .order-prod-item-info {
+                width: 100%;
+                display: flex;
+                flex-direction: column;
+                .info {
+                  display: flex;
+                  align-items: center;
+                  .prod-image {
+                    min-height: 80px;
+                    width: 80px;
+                    height: auto;
+                    margin-right: 20px;
+                    padding: 0;
+                    line-height: 80px;
+                    img {
+                      width: 100%;
+                      height: 100%;
+                      object-fit: contain;
+                    }
+                  }
+                  .prod-name {
+                    width: 100% !important;
+                    .prod-con {
+                      width: 85% !important;
+                      display: block;
+                      padding: 0 !important;
+                      .prod-name-txt {
+                        padding-right: 10px;
+                        box-sizing: border-box;
+                        display: -webkit-box;
+                        -webkit-box-orient: vertical;
+                        -webkit-line-clamp: 2;
+                        overflow: hidden;
+                      }
+                      .order-status {
+                        display: inline-block;
+                        margin-top: 15px;
+                        margin-right: 10px;
+                        padding: 2px 4px;
+                        border: 1px solid #e43130;
+                        border-radius: 2px;
+                        color: #e43130;
+                        font-size: 14px;
+                      }
+                    }
+                  }
+                }
+                // 赠品盒子
+                .order-prod-item-give-con {
+                  width: 100%;
+                  padding: 10px 50px 0 10px;
+                  box-sizing: border-box;
+                  .giveaway-item {
+                    display: flex;
+                    margin-bottom: 10px;
+                    &:last-child {
+                      margin-bottom: 0;
+                    }
+                  }
+                  .giveaway-item-name {
+                    box-sizing: border-box;
+                    display: -webkit-box;
+                    -webkit-box-orient: vertical;
+                    -webkit-line-clamp: 1;
+                    overflow: hidden;
+                  }
+                  .giveaway-item-sku-count {
+                    margin-left: 10px;
+                    color: #999;
+                    width: 20px;
+                  }
+                }
+              }
+              .prod-price {
+                width: 28%;
+                display: flex;
+                justify-content: flex-start;
+                flex-direction: column;
+                overflow: hidden;
+                position: relative;
+                right: 0 !important;
+                span {
+                  display: block;
+                  text-align: left;
+                  word-break: keep-all;
+                  &:first-child {
+                    margin-bottom: 10px;
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+      .empty {
+        display: block;
+        height: 200px;
+        line-height: 200px;
+        text-align: center;
+        color: #aaa;
+      }
+      .transaction-price {
+        text-align: center;
+      }
+    }
+    // 修改物流弹窗
+    .change-logistics {
+      color: #333;
+      padding: 0 20px;
+      .warning {
+        padding: 10px;
+        border: 1px solid #f1924e;
+        background: #fff5ed;
+      }
+      .log-list {
+        max-height: 600px;
+        margin-top: 30px;
+        overflow-y: auto;
+        .item {
+          padding-bottom: 20px;
+          .i-tit {
+            display: flex;
+            align-items: center;
+            .big {
+              font-weight: 600;
+              margin-right: 15px;
+            }
+          }
+          .item-goods {
+            position: relative;
+            width: 100%;
+            height: 110px;
+            overflow-x: auto;
+            .goods-box {
+              position: absolute;
+              left: 0;
+              display: flex;
+              margin-top: 0;
+              -webkit-transition: all 0.3s;
+              -moz-transition: all 0.3s;
+              transition: all 0.3s;
+              .item {
+                margin-right: 10px;
+                font-size: 12px;
+                cursor: pointer;
+                .img {
+                  width: 60px;
+                  height: 60px;
+                  font-size: 0;
+                  margin-bottom: 4px;
+                  margin-top: 4px;
+                  position: relative;
+                  img {
+                    width: 100%;
+                    height: 100%;
+                  }
+                  .number {
+                    position: absolute;
+                    bottom: 0;
+                    right: 0;
+                    background: rgba(0, 0, 0, 0.3);
+                    color: #fff;
+                    border-radius: 6px 0 6px 0;
+                    font-size: 12px;
+                    height: 16px;
+                    line-height: 16px;
+                    padding: 0 5px;
+                  }
+                }
+                .name {
+                  width: 60px;
+                  height: 16px;
+                  line-height: 16px;
+                  white-space: nowrap;
+                  overflow: hidden;
+                  text-overflow: ellipsis;
+                  color: #999;
+                }
+              }
+              .item:last-child {
+                margin: 0;
+              }
+
+            }
+          }
+          .info-int {
+            &.el-form-item__content,
+            &.el-form-item__label,
+            .el-input__suffix-inner,
+            .el-input__icon {
+              height: 32px;
+              line-height: 32px;
+            }
+            display: flex;
+            .form-item {
+              margin-right: 15px;
+            }
+          }
+        }
+      }
+      .log-info-table {
+        margin-top: 20px;
+        max-height: 600px;
+        overflow-y: auto;
+      }
+    }
+    @media (max-width:1660px) {
+      .fixed-top {
+        width: calc(79.5% + var(--tit-width-incremental)) !important;
+      }
+    }
+    @media (max-width:1360px) {
+      .fixed-top {
+        width: calc(75.5% + var(--tit-width-incremental)) !important;
+      }
+    }
+  }
+</style>

+ 1377 - 0
src/views/modules/print/wave-print-order.vue

@@ -0,0 +1,1377 @@
+<template>
+  <el-dialog
+    title="波次详情"
+    :close-on-click-modal="false"
+    :visible.sync="visible"
+    v-if="visible"
+    :fullscreen="true"
+    @close="dialogClose">
+    <!-- 搜索栏 -->
+    <div class="search-bar">
+      <el-form :inline="true" class="search-form" ref="searchForm" :model="searchForm" label-width="auto" size="small">
+        <div class="input-row">
+          <el-form-item label="订单编号" class="search-form-item">
+            <el-input v-model="searchForm.orderNumber" placeholder="请输入订单编号" :clearable="true"></el-input>
+          </el-form-item>
+          <el-form-item label="收件人" class="search-form-item">
+            <el-input type="text" v-model="searchForm.receiverName" placeholder="请输入收件人" :clearable="true"></el-input>
+          </el-form-item>
+          <el-form-item label="运单号" class="search-form-item">
+            <el-input type="text" v-model="searchForm.deliveryNo" placeholder="请输入运单号" :clearable="true"></el-input>
+          </el-form-item>
+          <el-form-item label="PDF生成状态" class="search-form-item">
+            <el-select type="text" v-model="searchForm.workStatus" placeholder="请选择PDF生成状态" :clearable="true">
+              <el-option label="未生成" value="0"></el-option>
+              <el-option label="已生成" value="2"></el-option>
+              <el-option label="失败" value="11"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <div class="default-btn primary-btn" @click="searchChange(true)">{{$t('crud.searchBtn')}}</div>
+            <div class="default-btn" @click="resetSearchForm()">{{$t('shop.resetMap')}}</div>
+          </el-form-item>
+        </div>
+      </el-form>
+    </div>
+    <div class="mod-order-order">
+      <div class="main">
+        <div class="content">
+          <div style="margin-bottom: 20px">
+            <div style="margin: 0px 20px 20px 0">
+              <span>波次号</span><span style="margin-left: 30px; font-weight: bold;font-size: 20px;color: red">{{wave.waveNo}}</span>
+              <span style="margin-left: 100px">订单数量</span><span style="margin-left: 20px; font-weight: bold;font-size: 20px;color: red">{{wave.orderNum}}</span>
+              <span v-if="wave.printChannel === 'KuaiYin'" style="margin-left: 100px">总张数</span>
+              <span v-if="wave.printChannel === 'WoNiu'" style="margin-left: 100px">总张数(含识别页)</span>
+              <span v-if="wave.printChannel === 'KuaiYin'" style="margin-left: 20px; font-weight: bold;font-size: 20px;color: red">{{wave.sheets}}</span>
+              <span v-if="wave.printChannel === 'WoNiu'" style="margin-left: 20px; font-weight: bold;font-size: 20px;color: red">{{wave.sheets + wave.orderNum}}</span>
+              <span style="margin-left: 100px" v-if="wave.printChannel === 'KuaiYin'">消耗纸张(按72张大纸)约</span><span v-if="wave.printChannel === 'KuaiYin'" style="margin-left: 20px; font-weight: bold;font-size: 20px;color: red">
+              {{((wave.sheets + wave.sheets / 10) / 72).toFixed(2) }}</span>
+              <span style="margin-left: 100px" v-if="wave.printChannel === 'WoNiu'">消耗纸张(按64张大纸)约</span><span v-if="wave.printChannel === 'WoNiu'" style="margin-left: 20px; font-weight: bold;font-size: 20px;color: red">
+              {{((wave.sheets + wave.orderNum) / 64).toFixed(2) }}</span>
+              <span style="margin-left: 100px">生成时间</span><span style="margin-left: 30px">{{wave.createTime}}</span>
+              <span style="margin-left: 100px" >更新时间</span>
+              <span style="margin-left: 30px" v-if="!wave.updateTime">-</span>
+              <span style="margin-left: 30px" v-if="wave.updateTime">{{wave.updateTime}}</span>
+            </div>
+            <el-button size="small" @click="generatePdfCombinationBatch" :disabled="wave.productionStatus == 0" :loading="wavePrintOrderPdfDownloadLoading">批量生成PDF</el-button>
+            <el-button size="small" v-if="wave.printChannel === 'WoNiu'" @click="downloadPdfBatch" :disabled="wave.productionStatus == 0" :loading="wavePrintOrderPdfDownloadLoading">批量下载ZIP</el-button>
+            <el-button size="small" v-if="wave.printChannel === 'Lightning'" @click="downloadPdfBatch" :disabled="wave.productionStatus == 0" :loading="wavePrintOrderPdfDownloadLoading">批量下载ZIP</el-button>
+            <el-button size="small" v-if="wave.printChannel === 'KuaiYin' && wave.shopId === 1"@click="mergeAndDownloadPDF" :disabled="wave.productionStatus == 0" :loading="wavePrintOrderPdfDownloadLoading">合并PDF并下载</el-button>
+            <el-button size="small" v-if="wave.printChannel === 'KuaiYin' && wave.shopId === 2"@click="downloadPdfBatch" :disabled="wave.productionStatus == 0" :loading="wavePrintOrderPdfDownloadLoading">压缩包下载</el-button>
+            <el-button size="small" v-if="wave.printChannel === 'KuaiYin' && wave.shopId === 2"@click="mergeAndDownloadPDF" :disabled="wave.productionStatus == 0" :loading="wavePrintOrderPdfDownloadLoading">大PDF下载</el-button>
+<!--            <el-button size="small" @click="downloadPrintOrderPdfZip" :disabled="wave.productionStatus == 0" :loading="wavePrintOrderPdfDownloadLoading">批量下载PDF</el-button>-->
+            <el-button size="small" v-if="wave.printChannel === 'KuaiYin'" :loading="wavePrintOrderInfoDownloadLoading" @click="downloadWavePrintOrderInfo" :disabled="wave.productionStatus == 0">下载订单信息</el-button>
+            <el-button size="small" @click="openScanDialog" :disabled="wave.productionStatus == 0">扫描发货</el-button>
+            <el-button size="small" @click="onKeyDelivery" v-if="wave.printChannel === 'KuaiYin' && wave.productionStatus === 1" :loading="onKeyDeliveryLoading">一键发货</el-button>
+            <el-divider direction="vertical" content-position="center"/>
+            <el-button size="small" @click="productionLockConfirm" v-if="wave.productionStatus === 0">生产锁定</el-button>
+            <el-button size="small" @click="productionLockCancel" v-if="wave.productionStatus === 1">取消锁定</el-button>
+            <el-button size="small" v-if="wave.printChannel === 'KuaiYin'" @click.stop="getUpload()" :disabled="wave.expressBillStatus === 1 || wave.productionStatus === 0">导入运单号</el-button>
+            <el-divider direction="vertical" content-position="center"/>
+            <el-button type="text" @click="deleteWave" :disabled="wave.expressBillStatus == 1 || wave.productionStatus == 1 || wave.scanStatus == 1">删除波次</el-button>
+            <el-button type="text" icon="el-icon-refresh-left" @click="getDataList(page, null, false)" >刷新</el-button>
+            <el-button size="small" style="color: #2da641;font-weight: bold" @click="openWaveStatDialog(wave.waveId)" >材质小计</el-button>
+          </div>
+          <!-- 表格 -->
+          <div class="table-con transport-table">
+            <el-table
+              border
+              ref="transportTable"
+              :data="dataList"
+              header-cell-class-name="table-header"
+              row-class-name="table-row-low"
+              @selection-change="selectionChangeHandle"
+              @expand-change="handleTableExpandChange"
+              style="width: 100%">
+              <!--<el-table-column type="expand">
+                <template slot-scope="props">
+                  <el-form label-position="left">
+                    <el-form-item label="收件地址">
+                      <span class="expand-detail">{{ props.row.userAddrOrder.province }} </span>
+                      <span class="expand-detail">{{ props.row.userAddrOrder.city }} </span>
+                      <span class="expand-detail">{{ props.row.userAddrOrder.area }} </span>
+                      <span class="expand-detail">{{ props.row.userAddrOrder.addr }} </span>
+                      <span class="expand-detail">{{ props.row.userAddrOrder.receiverName }} </span>
+                      <span class="expand-detail">{{ props.row.userAddrOrder.receiverMobile }} </span>
+                    </el-form-item>
+                  </el-form>
+                </template>
+              </el-table-column>-->
+<!--              <el-table-column-->
+<!--                type="selection">-->
+<!--              </el-table-column>-->
+              <el-table-column
+                align="center"
+                prop="serialNo"
+                width="65"
+                label="序号">
+                <template slot-scope="scope">
+                  <span class="table-cell-text">{{ scope.row.serialNo }}</span>
+                </template>
+              </el-table-column>
+              <el-table-column
+                label="订单号"
+                width="180"
+                align="center"
+                prop="orderNumber">
+                <template slot-scope="scope">
+                  <span>{{scope.row.orderNumber }}</span>
+                </template>
+              </el-table-column>
+              <el-table-column
+                label="第三方单号"
+                width="100"
+                align="center"
+                v-if="wave.printChannel === 'KuaiYin' && wave.printChannel === 'Lightning'"
+                prop="orderNo">
+                <template slot-scope="scope">
+                  <span>{{scope.row.orderNo }}</span>
+                </template>
+              </el-table-column>
+              <el-table-column
+                label="下单时间"
+                align="center"
+                prop="orderTime">
+                <template slot-scope="scope">
+                  <span>{{scope.row.orderTime }}</span>
+                </template>
+              </el-table-column>
+              <el-table-column
+                label="收件人"
+                align="center"
+                prop="receiverName">
+                <template slot-scope="scope">
+                  <div>
+                    <el-tooltip placement="top">
+                      <div slot="content" style="font-size: 8px">
+                        <span>{{scope.row.userAddrOrder.province }}</span>
+                        <span>{{scope.row.userAddrOrder.city }}</span>
+                        <span>{{scope.row.userAddrOrder.area }}</span>
+                        <span>{{scope.row.userAddrOrder.street }}</span>
+                        <span>{{scope.row.userAddrOrder.addr }}</span>
+                      </div>
+                      <div>
+                        <span>{{scope.row.userAddrOrder.receiver }}</span>
+                        <br/>
+                        <span>{{scope.row.userAddrOrder.mobile }}</span>
+                      </div>
+                    </el-tooltip>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column
+                label="产品名"
+                width="300"
+                align="center"
+                prop="prodName">
+                <template slot-scope="scope">
+                  <span>{{scope.row.prodName }}</span>
+                  <!--<el-tooltip placement="top">
+                    <div
+                      slot="content"
+                      style="font-size: 8px"
+                      v-for="orderItem in scope.row.orderItemList"
+                      :key="orderItem.orderItemId">
+                      <div>{{orderItem.prodName}}</div>
+                    </div>
+                    <span v-if="scope.row.orderItemList.length > 1">{{scope.row.orderItemList[0].prodName}} <br/>......</span>
+                    <span v-else>{{scope.row.orderItemList[0].prodName}}</span>
+                  </el-tooltip>-->
+                </template>
+              </el-table-column>
+              <el-table-column
+                align="center"
+                prop="prodNums"
+                width="65"
+                label="数量">
+                <template slot-scope="scope">
+                  <span>{{scope.row.prodNums }}</span>
+                </template>
+              </el-table-column>
+              <!--<el-table-column
+                align="center"
+                prop="isMerge"
+                width="65"
+                label="合单">
+                <template slot-scope="scope">
+                  <el-tag type="info" effect="dark" v-if="scope.row.isMerge == 1">否</el-tag>
+                  <el-tag type="danger" effect="dark" v-if="scope.row.isMerge == 2">是</el-tag>
+                </template>
+              </el-table-column>-->
+              <el-table-column
+                align="center"
+                prop="deliveryName"
+                width="110"
+                label="快递">
+                <template slot-scope="scope">
+                  <span>{{scope.row.deliveryName }}</span>
+                </template>
+              </el-table-column>
+              <el-table-column
+                align="center"
+                label="快递单号"
+                prop="deliveryNo">
+                <template slot-scope="scope">
+                  <span>{{scope.row.deliveryNo }}</span>
+                </template>
+              </el-table-column>
+              <el-table-column
+                align="center"
+                prop="expressBillTime"
+                label="运单号时间">
+                <template slot-scope="scope">
+                  <span>{{scope.row.expressBillTime }}</span>
+                </template>
+              </el-table-column>
+              <el-table-column
+                align="center"
+                prop="scanTime"
+                label="发货时间">
+                <template slot-scope="scope">
+                  <span>{{scope.row.deliveryTime }}</span>
+                </template>
+              </el-table-column>
+              <el-table-column
+                align="center"
+                prop="status"
+                width="90"
+                label="状态">
+                <template slot-scope="scope">
+                  <span v-if="scope.row.status == 1">待打印</span>
+                  <span v-if="scope.row.status == 2">待发货</span>
+                  <span v-if="scope.row.status == 3">已发货</span>
+                  <span v-if="scope.row.status == 11">已取消</span>
+                </template>
+              </el-table-column>
+              <el-table-column
+                align="center"
+                prop="workStatus"
+                width="80"
+                label="生成状态">
+                <template slot-scope="scope">
+                  <el-tooltip placement="top" v-if="scope.row.remark">
+                    <div slot="content" style="font-size: 8px" >
+                      <span>{{scope.row.remark }}</span>
+                    </div>
+                    <div>
+                      <el-tag type="success" v-if="scope.row.workStatus == 2" effect="dark">已生成</el-tag>
+                      <el-tag type="info" v-if="scope.row.workStatus == 0" effect="dark">未生成</el-tag>
+                      <el-tag type="danger" v-if="scope.row.workStatus == 3" effect="dark">失败</el-tag>
+                    </div>
+                  </el-tooltip>
+                  <div v-else>
+                    <el-tag type="success" v-if="scope.row.workStatus == 2" effect="dark">已生成</el-tag>
+                    <el-tag type="info" v-if="scope.row.workStatus == 0" effect="dark">未生成</el-tag>
+                    <el-tag type="danger" v-if="scope.row.workStatus == 3" effect="dark">失败</el-tag>
+                  </div>
+                </template>
+              </el-table-column>
+              <el-table-column
+                align="center"
+                prop="remark"
+                width="140"
+                label="备注">
+                <template slot-scope="scope">
+                  <span style="color:red;overflow: hidden; width: 100px; text-overflow:ellipsis">{{scope.row.remark}}</span>
+                </template>
+              </el-table-column>
+              <el-table-column
+                align="center"
+                :label="$t('crud.menu')"
+                width="240"
+              >
+                <template slot-scope="scope">
+                  <div style="display: inline-block;float: left;">
+                    <el-button v-if="scope.row.workStatus === 0 || scope.row.workStatus == 3" size="mini" @click="generatePdfCombination(scope.row)" :disabled="wave.productionStatus == 0">生成PDF</el-button>
+                    <el-button size="mini" @click="openModifyExpressBillDialog(scope.row)">修改运单号</el-button>
+                    <el-button key="removeFromWaveBtn" size="mini" type="text" v-if="wave.productionStatus == 0 || scope.row.status != 3" :disabled="wave.productionStatus == 1" @click="removeFromWave(scope.row)">移出波次</el-button>
+                    <el-button size="mini" type="text" v-if="scope.row.status == 3" @click="cancelDelivery(scope.row)">取消发货</el-button>
+                    <el-button size="mini" type="text" @click="showModifyRemark(scope.row)">备注</el-button>
+                  </div>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+
+          <!-- 分页 -->
+          <el-pagination
+            v-if="dataList.length"
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+            :current-page="page.currentPage"
+            :page-sizes="[61, 200, 400, 600]"
+            :page-size="page.pageSize"
+            layout="total, sizes, prev, pager, next, jumper"
+            :total="page.total">
+          </el-pagination>
+        </div>
+      </div>
+    </div>
+    <el-dialog
+      :append-to-body="true"
+      title="修改运单号"
+      :visible.sync="modifyExpressBillVisible"
+      width="30%"
+      left
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+    >
+      <el-form :model="wave" label-position="right">
+        <el-form-item label="">
+          <span autocomplete="off">订单号:{{printOrder.orderNumber}}</span>
+          <span autocomplete="off" style="margin-left: 30px">旧运单号:{{printOrder.oldDeliveryNo}}</span>
+        </el-form-item>
+        <el-form-item label="快递代号" label-width="70px">
+          <el-select v-model="printOrder.deliveryCode" :clearable="true" @change="handleDeliveryChange">
+            <el-option key="ZTO" label="中通快递" value="ZTO"></el-option>
+            <el-option key="YUNDA" label="韵达速递" value="YUNDA"></el-option>
+            <el-option key="STO" label="申通快递" value="STO"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="快递名称" label-width="70px">
+          <el-input v-model="printOrder.deliveryName" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="新运单号" label-width="70px">
+          <el-input v-model="printOrder.deliveryNo" autocomplete="off"></el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="modifyExpressBill(wave.waveId, printOrder)">确认</el-button>
+      </div>
+    </el-dialog>
+    <order-scan-delivery ref="orderScanDelivery" @refreshDataList="getDataList(page, null, false)"></order-scan-delivery>
+    <express-bill-upload
+      v-if="uploadVisible"
+      ref="expressBillUpload"
+      @refreshDataList="getWaitingConsignmentExcel">
+    </express-bill-upload>
+    <el-dialog
+      :append-to-body="true"
+      title="客服备注"
+      :visible.sync="buyerRemarkVisible"
+      v-if="buyerRemarkVisible"
+      width="30%"
+      left
+      :close-on-click-modal="false"
+      :close-on-press-escape="false">
+      <el-form :model="printOrder" label-position="right">
+        <el-form-item label="备注" label-width="70px">
+          <el-input v-model="printOrder.remark" autocomplete="off"></el-input>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="modifyBuyerRemarks(printOrder)">确认</el-button>
+      </div>
+    </el-dialog>
+    <wave-stat ref="waveStatRef"></wave-stat>
+  </el-dialog>
+
+</template>
+
+<script>
+  import {PDFDocument}  from 'pdf-lib';
+  import ProdPic from '@/components/prod-pic';
+  import InputNumberRange from '@/components/input-number-range';
+  import ExpressBillUpload from './express-bill-upload';
+  import OrderScanDelivery from '@/components/order-scan-delivery';
+  import moment from 'moment';
+  import {downloadPdf} from "@/utils/pdf";
+  import {downloadXls} from "@/utils/excel";
+  import {downloadZip} from "@/utils/zip";
+  import { saveAs } from 'file-saver';
+  import JSzip from 'jszip';
+  import axios from 'axios'
+  import WaveStat from './wave-stat';
+
+  export default {
+    data () {
+      return {
+        // 是否全选
+        selectAll: false,
+        showHeadScroll: false, // 修改物流相关
+        logVisible: false,
+        radio: '1',
+        logisticsInfo: [],  // 包裹列表
+        logDataForm: {
+          dvyId: '', // 当前物流公司id
+          dvyFlowId: '',  // 物流单号
+          dvyNames: []  // 物流公司列表
+        },
+        searchForm: {},
+        uploadVisible: false,
+        lang: localStorage.getItem('lang'),
+        errorNum: 0,
+        buyerRemarkVisible: false,
+        // 确认修改弹窗
+        isReviseLog: true,  // 是否正在修改物流信息
+        confirmList: [],  // 确认修改信息
+        dataForm: {},
+        sts: 0,
+        dateRange: [],
+        waveStat:[],
+        productNumsRange:[],
+        status: null,
+        options: [
+          {
+          value: 1,
+          label: "待打印"
+          },
+          {
+            value: 2,
+            label: "待发货"
+          },
+          {
+            value: 3,
+            label: "待收货"
+          },
+          {
+            value: 4,
+            label: "交易完成"
+          }
+          ],
+        refund: [
+          {
+          value: 0,
+          label: this.$i18n.t('order.noAfterSales')},
+          {
+            value: 1,
+            label: this.$i18n.t('order.requestARefund')
+          },
+          {
+            value: 2,
+            label: this.$i18n.t('order.refundsuccessfully')
+          },
+          {
+            value: 3,
+            label: this.$i18n.t('order.partialRefundSucc')
+          },
+          {
+            value: 4,
+            label: this.$i18n.t('order.refundFailed')
+          }],
+        resourcesUrl: process.env.VUE_APP_RESOURCES_URL,
+        dataList: [],
+        page: {
+          total: 0, // 总页数
+          currentPage: 1, // 当前页数
+          pageSize: 61 // 每页显示多少条
+        },
+        dataListLoading: false,
+        dataListSelections: new Set(),
+        generateWaveDialogVisible: false,
+        timeActive: null,
+        priceWidth: '109px',
+        infoWidth: '400px',
+        newWaveNo: null,
+        visible: false,
+        wave:{},
+        printChannel: "WoNiu",
+        addToWaveDialogVisible: false,
+        wavePrintOrderInfoDownloadLoading:false,
+        onKeyDeliveryLoading: false,
+        operDisabled: false,
+        productionLockDisabled: false,
+        wavePrintOrderPdfDownloadLoading: false,
+        modifyExpressBillVisible: false,
+        waveStatVisible: false,
+        printOrder:{},
+        expandRowDetail:{}
+      }
+    },
+    components: {
+      ProdPic,
+      InputNumberRange,
+      ExpressBillUpload,
+      OrderScanDelivery,
+      WaveStat
+    },
+    computed: {
+
+    },
+    created () {
+
+    },
+    activated () {
+      // 携带参数查询
+      var query = this.$route.query
+      if (Object.keys(query).length > 0) {
+        this.getDataList(this.page, query)
+      }
+    },
+    mounted () {
+
+    },
+    watch: {
+
+    },
+    methods: {
+      handleDeliveryChange(delivery){
+        if(delivery === 'ZTO'){
+          this.printOrder.deliveryName = '中通快递';
+        }else if(delivery === 'YUNDA'){
+          this.printOrder.deliveryName = '韵达速递';
+        }else if(delivery === 'STO'){
+          this.printOrder.deliveryName = '申通快递';
+        }
+      },
+      openWaveStatDialog(waveId){
+        this.$refs.waveStatRef.init(waveId)
+      },
+      showModifyRemark(row){
+        this.printOrder = row
+        this.buyerRemarkVisible = true
+      },
+      modifyBuyerRemarks(printOrder){
+        this.$http({
+          url: this.$http.adornUrl('/platform/printOrder/modifyRemarks'),
+          method: 'post',
+          data: this.$http.adornData({
+            orderNumber: this.printOrder.orderNumber,
+            remark: this.printOrder.remark
+          }),
+        }).then(({ data }) => {
+          this.buyerRemarkVisible = false
+          if(data){
+            this.$message({
+              message: "修改成功",
+              type: 'success'
+            })
+          }else{
+            this.$message({
+              message: "修改失败",
+              type: 'error'
+            })
+          }
+        })
+      },
+      onKeyDelivery(){
+        this.$confirm('确定要一键发货吗?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.onKeyDeliveryLoading = true;
+          this.$http({
+            url: this.$http.adornUrl(`/platform/printOrder/onKeyDelivery`),
+            method: 'POST',
+            data: this.$http.adornData(this.wave)
+          }).then(({data}) => {
+            this.onKeyDeliveryLoading = false;
+            this.$message({
+              message: "发货成功",
+              type: 'success'
+            })
+            this.getDataList(this.page, null, true)
+          }).catch((e) => {
+            this.onKeyDeliveryLoading = false;
+            this.$message({
+              message: "发货失败",
+              type: 'error'
+            })
+          })
+        });
+
+      },
+      openAndQueryPrintOrder(params){
+        this.visible = true;
+        this.$nextTick(() =>{
+          this.getWave(params.waveId);
+          this.searchForm.orderNumber = params.orderNumber;
+          this.getDataList(this.page, false, null);
+        })
+
+      },
+      init (wave) {
+        this.wave = wave
+        this.visible = true;
+        this.getWave(this.wave.waveId);
+        // 携带参数查询
+        this.getDataList(this.page, null, true)
+      },
+      getWave(waveId){
+        // 修改
+        this.$http({
+          url: this.$http.adornUrl(`/platform/wave/findWave/${waveId}`),
+          method: 'GET',
+          params: this.$http.adornParams()
+        }).then(({ data }) => {
+          this.wave = data
+        })
+      },
+      deleteWave(){
+        this.$confirm('确定要删除波次吗?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.$http({
+            url: this.$http.adornUrl(`/platform/wave/deleteWave`),
+            method: 'POST',
+            data: this.$http.adornData(this.wave)
+          }).then(({data}) => {
+            if(data){
+              this.$message({
+                message: "删除成功",
+                type: 'success'
+              })
+              this.$emit('refressWaveList', null);
+              this.dialogClose();
+            }else{
+              this.$message({
+                message: "删除失败",
+                type: 'error'
+              })
+            }
+          })
+        })
+      },
+      openGenerateWaveDialog(){
+        if(this.dataListSelections.size == 0){
+          this.$message.error("请至少选择一个订单");
+          return ;
+        }
+        this.$http({
+          url: this.$http.adornUrl(`/platform/wave/getLatestWaveNo`),
+          method: 'GET',
+          params: this.$http.adornParams({printChannel:this.printChannel})
+        }).then(({data}) => {
+          if(data.status == "success"){
+            this.generateWaveDialogVisible = true;
+            this.wave.waveNo = data.result;
+            this.wave.orderNum = data
+          }
+        })
+      },
+      openAddToWaveDialog(){
+        if(this.dataListSelections.size == 0){
+          this.$message.error("请至少选择一个订单");
+          return ;
+        }
+        this.$http({
+          url: this.$http.adornUrl(`/platform/wave/getLatestWave`),
+          method: 'GET',
+          params: this.$http.adornParams({shopId: this.$store.state.user.shopId, printChannel:this.printChannel, queryLimit: 30})
+        }).then(({data}) => {
+          if(data.status == "success"){
+            this.addToWaveDialogVisible = true;
+            this.wave.latestWaveList = data.result;
+          }
+        })
+      },
+      openScanDialog(){
+        this.$refs.orderScanDelivery.init(this.wave);
+      },
+      handleWaveChange(val){
+        this.wave.latestWaveList.forEach(item =>{
+          if(item.waveId == val){
+            this.wave.orderNum = item.orderNum;
+            return;
+          }
+        })
+      },
+      handleAddToWaveDialogClose(){
+        this.wave.selectWaveId = null;
+        this.wave.orderNum = 0;
+      },
+      handleScanDialogClose(){
+        this.theData = null;
+        this.dataList = [];
+        this.scanOrderNumber = null;
+        this.waitScan = {};
+        this.matchPrintOrder = {};
+      },
+      createWave(){
+        let dataBody = {waveName: this.wave.waveName, "orderNumberList": [...this.dataListSelections], "printChannel": this.printChannel};
+        this.$http({
+          url: this.$http.adornUrl(`/platform/wave/create`),
+          method: 'POST',
+          data: this.$http.adornData(dataBody)
+        }).then(({data}) => {
+          if(data.status == "success"){
+            this.generateWaveDialogVisible = false;
+            this.$message({
+              message: data.msg,
+              type: 'success'
+            })
+            this.getDataList(this.page);
+          }else{
+            this.$message({
+              message: data.msg,
+              type: 'error'
+            })
+          }
+        })
+      },
+      handleTableExpandChange(row){
+        // this.expandRowDetail = {};
+        // 修改
+        this.$http({
+          url: this.$http.adornUrl(`/platform/printOrder/findWavePrintOrderAddr`),
+          method: 'GET',
+          params: this.$http.adornParams({waveId: row.waveId, orderNumber: row.orderNumber})
+        }).then(({ data }) => {
+          // this.expandRowDetail = data;
+        })
+      },
+      removeFromWave(row){
+        this.$confirm('确定要移出波次吗?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.$http({
+            url: this.$http.adornUrl(`/platform/wave/removeFromWave`),
+            method: 'POST',
+            data: this.$http.adornData(row)
+          }).then(({data}) => {
+            if(data.status == "success"){
+              this.$message({
+                message: data.msg,
+                type: 'success'
+              })
+              this.getWave(this.wave.waveId);
+              this.getDataList(this.page);
+            }else{
+              this.$message({
+                message: data.msg,
+                type: 'error'
+              })
+            }
+          })
+        });
+      },
+      //批量下载订单信息
+      downloadWavePrintOrderInfo(){
+        this.wavePrintOrderInfoDownloadLoading = true;
+        this.$http({
+          url: this.$http.adornUrl('/platform/wave/downloadWavePrintOrderInfo'),
+          method: 'get',
+          params: this.$http.adornParams({waveId: this.wave.waveId, printChannel: this.printChannel }),
+          responseType: 'blob'
+        }).then(({data}) => {
+          this.wavePrintOrderInfoDownloadLoading = false;
+          let fileName = this.wave.waveNo + "_" + this.wave.waveName + "_订单信息";
+          downloadXls(data, fileName + ".xlsx");
+        }).catch((error) => {
+          this.wavePrintOrderInfoDownloadLoading = false;
+        })
+      },
+      generatePdfCombination(row){
+        this.$http({
+          url: this.$http.adornUrl('/platform/printOrder/generatePdfCombination'),
+          method: 'post',
+          data: this.$http.adornParams(row),
+        }).then(({data}) => {
+          this.$message({
+            message: "开始生成PDF,请刷新等待结果",
+            type: 'success'
+          })
+        }).catch((error) => {
+          this.$message({
+            message: "生成PDF失败",
+            type: 'error'
+          })
+        })
+      },
+      generatePdfCombinationBatch(){
+        // if(this.dataListSelections.size == 0){
+        //   this.$message.error("请至少选择一个订单");
+        //   return ;
+        // }
+        this.$confirm('确定要批量生成PDF吗?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.wavePrintOrderPdfDownloadLoading = true;
+          // let orderNumberList = this.dataListSelections.map(item=>item['orderNumber'])
+          // let dataBody = {"printChannel": this.printChannel, "waveId": this.wave.waveId, orderNumberList: orderNumberList};
+          if(!this.wave.colorPrint || !this.wave.gram){
+            this.$message({
+              message: "波次的色数和克数未设置",
+              type: 'error'
+            })
+            this.wavePrintOrderPdfDownloadLoading = false;
+            return;
+          }
+          let dataBody = {"printChannel": this.printChannel, "waveId": this.wave.waveId, "colorPrint": this.wave.colorPrint, "gram": this.wave.gram};
+          this.$http({
+            url: this.$http.adornUrl('/platform/printOrder/generatePdfCombinationBatch'),
+            method: 'post',
+            data: this.$http.adornParams(dataBody),
+          }).then(({data}) => {
+            this.wavePrintOrderPdfDownloadLoading = false;
+            this.$message({
+              message: "批量生成PDF启动,请刷新等待结果",
+              type: 'success'
+            })
+          }).catch((error) => {
+            this.wavePrintOrderPdfDownloadLoading = false;
+            // this.$message({
+            //   message: "批量生成PDF启动失败",
+            //   type: 'error'
+            // })
+          })
+        });
+      },
+      downloadPrintOrderPdfZip(){
+        this.wavePrintOrderPdfDownloadLoading = true;
+        let orderNumberList = this.dataListSelections.map(item=>item['orderNumber'])
+        let dataBody = {"printChannel": this.printChannel, "waveId": this.wave.waveId, orderNumberList: orderNumberList};
+        this.$http({
+          url: this.$http.adornUrl('/platform/wave/downloadWavePrintOrderPdf'),
+          method: 'get',
+          params: this.$http.adornParams(dataBody),
+          responseType: 'blob'
+        }).then(({data}) => {
+          this.wavePrintOrderPdfDownloadLoading = false;
+          let fileName = this.wave.waveNo + "_" + this.wave.waveName + ".zip";
+          const blob = new Blob([data], {
+            type: 'application/zip'
+          })
+          saveAs(blob, fileName)
+        }).catch((error) => {
+          this.wavePrintOrderPdfDownloadLoading = false;
+        })
+      },
+      getPdfStream (url) {
+        return new Promise((resolve, reject) => {
+          let xmlhttp = new XMLHttpRequest();
+          xmlhttp.open("GET", url, true);
+          xmlhttp.responseType = "blob";
+          xmlhttp.onload = function () {
+            if (this.status == 200) {
+              resolve(this.response);
+            }else{
+              reject(this.status);
+            }
+          }
+          xmlhttp.send();
+        });
+      },
+      getPdfFile (url) {
+        return new Promise((resolve, reject) => {
+          let xmlhttp = new XMLHttpRequest();
+          xmlhttp.open("GET", url, true);
+          xmlhttp.responseType = "blob";
+          xmlhttp.onload = function () {
+            if (this.status == 200) {
+              resolve(this.response);
+            }else{
+              reject(this.status);
+            }
+          }
+          xmlhttp.send();
+        });
+      },
+      getPdfFile2 (url) {
+        return new Promise((resolve, reject) => {
+          try {
+            let xmlhttp = new XMLHttpRequest();
+            xmlhttp.open("GET", url, true);
+            xmlhttp.responseType = "arraybuffer";
+            xmlhttp.onload = function () {
+              if (this.status == 200) {
+                resolve(this.response);
+              }else{
+                reject(this.status);
+              }
+            }
+            xmlhttp.send();
+          } catch (ignored) {}
+        });
+      },
+      downloadPdfBatch () {
+        // if(this.dataListSelections.size == 0){
+        //   this.$message.error("请至少选择一个订单");
+        //   return ;
+        // }
+        this.wavePrintOrderPdfDownloadLoading = true;
+        // 获取pdf链接集合
+        // let orderNumberList = this.dataListSelections.map(item=>item['orderNumber'])
+        this.$http({
+          url: this.$http.adornUrl(`/platform/printOrder/getPrintPdfBatch`),
+          method: 'POST',
+          // data: this.$http.adornData({printChannel: this.wave.printChannel, waveId: this.wave.waveId, orderNumberList: orderNumberList})
+          data: this.$http.adornData({printChannel: this.wave.printChannel, waveId: this.wave.waveId})
+        }).then(({ data }) => {
+          let printOrderList = data;
+          // const arr = [{fileDownUrl:'地址', fileDownName:'文件名'}] // 需要下载打包的路径, 可以是本地相对路径, 也可以是跨域的全路径
+          const zip = new JSzip()
+          const cache = {}
+          const promises = []
+          printOrderList.forEach((printOrder, i) => {
+            let pdfList = printOrder.pdfList;
+            pdfList.forEach((pdf, j) => {
+              let randomStr = Math.floor(Math.random()*100000).toString();
+              const promise = this.getPdfFile2(this.resourcesUrl + pdf.pdfUrl + "?a="+randomStr).then(data => {
+                // 下载文件, 并存成blob对象
+                const fileName = pdf.pdfFolderName + "/" + pdf.pdfName; // 获取文件名,一定要包含文件的后缀名(因为重复的文件名只会下载一个,故需要加入下标 不同名)
+                // zip.folder(pdf.pdfFolderName).file(pdf.pdfName, data);
+                zip.file(pdf.pdfName, data);
+                cache[fileName] = data
+              })
+              promises.push(promise)
+            });
+          });
+          Promise.all(promises).then(() => {
+            zip.generateAsync({ type: "blob" }).then(content => {
+              // 生成二进制流   然后保存文件(如果这个下载不了 也可以将下方这一行换成a标签下载逻辑)
+              if(this.wave.printChannel === 'KuaiYin'){
+                saveAs(content, this.wave.waveNo + "_" + this.wave.waveName + ".zip") // 利用file-saver保存文件  自定义文件名
+              }else{
+                saveAs(content, this.wave.waveNo + "_" + this.wave.waveName + ".zip") // 利用file-saver保存文件  自定义文件名
+              }
+              this.wavePrintOrderPdfDownloadLoading = false;
+            })
+          })
+        });
+      },
+
+      /*//合并并下载PDF
+      async mergeAndDownloadPDF(){ // urlList 单个PDF文件的URL
+        try{
+          this.wavePrintOrderPdfDownloadLoading = true;
+          // 获取pdf链接集合
+          this.getPrintPdfBatch().then(async (list)=>{
+            let pdfUrlList = [];
+            for(let i=0 ; i <list.length; i++){
+              let pdfList = list[i].pdfList;
+              for(let j=0 ; j <pdfList.length; j++){
+                pdfUrlList.push(this.resourcesUrl + pdfList[j].pdfUrl);
+              }
+            }
+            let promises = [];
+            pdfUrlList.forEach(url =>{
+              let promise = this.getPdfFile2(url);
+              promises.push(promise);
+            })
+            let pdfBuffers = await Promise.all(promises);
+            let newPdf = await PDFDocument.create();
+            for (let k=0 ; k<pdfBuffers.length; k++) {
+              let pdfDocument = await PDFDocument.load(pdfBuffers[k]);
+              let contentPages = await newPdf.copyPages(pdfDocument, pdfDocument.getPageIndices());
+              for (let l=0; l<contentPages.length; l++) {
+                newPdf.addPage(contentPages[l]);
+              }
+            }
+            let uint8Array = await newPdf.save();
+            let mergeBuffer = Buffer.from(uint8Array);
+            downloadPdf(mergeBuffer, this.wave.waveNo + "_" + this.wave.waveName + ".pdf");
+            this.wavePrintOrderPdfDownloadLoading = false;
+          });
+        }catch (error) {
+          this.wavePrintOrderPdfDownloadLoading = false;
+        }
+
+      },*/
+
+      //合并并下载PDF
+      async mergeAndDownloadPDF(){ // urlList 单个PDF文件的URL
+        try{
+          this.wavePrintOrderPdfDownloadLoading = true;
+          // 获取pdf链接集合
+          this.getPrintPdfBatch().then(async (list)=>{
+            let newPdf = await PDFDocument.create();
+            let pageWidth = 0;
+            let pageHeight = 0;
+            for(let i=0 ; i <list.length; i++){
+              let pdfList = list[i].pdfList;
+              for(let j=0 ; j <pdfList.length; j++){
+                let randomStr = Math.floor(Math.random()*100000).toString();
+                let pdfBuffer = await this.getPdfFile2(this.resourcesUrl + pdfList[j].pdfUrl+"?u="+randomStr);
+                let pdfDocument = await PDFDocument.load(pdfBuffer);
+                let contentPages = await newPdf.copyPages(pdfDocument, pdfDocument.getPageIndices());
+                for (let l=0; l<contentPages.length; l++) {
+                  newPdf.addPage(contentPages[l]);
+                  if(pageWidth == 0){
+                    pageWidth = contentPages[l].getWidth();
+                    pageHeight = contentPages[l].getHeight();
+                  }
+                }
+              }
+            }
+            //如果是圆角,就补充空白页
+            if(this.wave.printChannel === "KuaiYin"){
+              if(this.wave.waveName.indexOf("圆角") != -1){
+                let allPageSize = newPdf.getPageCount();
+                let totalPage = 144
+                if(this.wave.colorPrint === '四色'){
+                  totalPage = 120
+                }
+                let mod = allPageSize % totalPage;
+                if(mod != 0){
+                  let diff = totalPage - mod;
+                  for(let i = 1; i <= diff; i++){
+                    newPdf.addPage([pageWidth, pageHeight]);
+                  }
+                }
+              }
+            }
+            let uint8Array = await newPdf.save();
+            let mergeBuffer = Buffer.from(uint8Array);
+            if(this.wave.printChannel === "KuaiYin"){
+              downloadPdf(mergeBuffer, this.wave.waveNo + "_" + this.wave.colorPrint + "_" + this.wave.gram + "_" + this.wave.waveName
+                + ".pdf");
+            }else{
+              downloadPdf(mergeBuffer, this.wave.waveNo + "_" + this.wave.waveName
+                + ".pdf");
+            }
+            this.wavePrintOrderPdfDownloadLoading = false;
+          });
+        }catch (error) {
+          this.wavePrintOrderPdfDownloadLoading = false;
+        }
+
+      },
+
+      /**
+       *  获取打印订单的所有PDF文件
+       */
+      getPrintPdfBatch(){
+        // if(this.dataListSelections.size == 0){
+        //   this.$message.error("请至少选择一个订单");
+        //   return ;
+        // }
+        return new Promise((resolve, reject) => {
+          // 获取pdf链接集合
+          // let orderNumberList = this.dataListSelections.map(item=>item['orderNumber'])
+          this.$http({
+            url: this.$http.adornUrl(`/platform/printOrder/getPrintPdfBatch`),
+            method: 'POST',
+            // data: this.$http.adornData({printChannel: this.wave.printChannel, waveId: this.wave.waveId, orderNumberList: orderNumberList})
+            data: this.$http.adornData({printChannel: this.wave.printChannel, waveId: this.wave.waveId})
+          }).then(({ data }) => {
+            resolve(data);
+          });
+        })
+
+      },
+
+      // 跳转至导入选择
+      getUpload () {
+        this.uploadVisible = true
+        this.$nextTick(() => {
+          this.$refs.expressBillUpload.init(this.wave.waveId)
+        })
+      },
+      // 刷新数据
+      getWaitingConsignmentExcel () {
+        this.getDataList(this.page);
+        // 修改
+        this.$http({
+          url: this.$http.adornUrl(`/platform/wave/info/${this.wave.waveId}`),
+          method: 'GET',
+          params: this.$http.adornParams()
+        }).then(({ data }) => {
+          this.wave = data
+        })
+      },
+      productionLockConfirm(){
+        this.$confirm('你确定要锁定并转为生产中吗?一旦锁定将无法增删订单', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.$http({
+            url: this.$http.adornUrl(`/platform/wave/confirmProductionLock`),
+            method: 'POST',
+            data: this.$http.adornData({waveId: this.wave.waveId, printChannel: this.printChannel})
+          }).then(({data}) => {
+            if(data.status == "success"){
+              this.$message({
+                message: data.msg,
+                type: 'success'
+              })
+              this.getWave(this.wave.waveId);
+              this.getDataList(this.page);
+            }else{
+              this.$message({
+                message: data.msg,
+                type: 'error'
+              })
+            }
+          })
+        }).catch(() => {
+
+        });
+      },
+      productionLockCancel(){
+        this.$confirm('你确定要取消锁定吗?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.$http({
+            url: this.$http.adornUrl(`/platform/wave/cancelProductionLock`),
+            method: 'POST',
+            data: this.$http.adornData({waveId: this.wave.waveId, printChannel: this.printChannel})
+          }).then(({data}) => {
+            if(data){
+              this.$message({
+                message: "取消成功",
+                type: 'success'
+              })
+              this.getWave(this.wave.waveId);
+              this.getDataList(this.page, null, false);
+            }else{
+              this.$message({
+                message: "取消失败",
+                type: 'error'
+              })
+            }
+          })
+        }).catch(() => {
+
+        });
+      },
+      downloadPrintOrderPdf(printOrder){
+        this.wavePrintOrderPdfDownloadLoading = true;
+        let dataBody = {printChannel: printOrder.printChannel, orderNumber: printOrder.orderNumber, waveId: printOrder.waveId};
+        this.$http({
+          url: this.$http.adornUrl('/platform/printOrder/downloadPrintOrderPdf'),
+          method: 'get',
+          params: this.$http.adornParams(dataBody),
+          responseType: 'blob'
+        }).then(({data}) => {
+          this.wavePrintOrderPdfDownloadLoading = false;
+          let pdfName = printOrder.orderNumber + "_" + printOrder.receiverName + "_" + printOrder.prodName + ".pdf";
+          // downloadPdf(data, pdfName + ".pdf");
+          const blob = new Blob([data], {
+            type: 'application/pdf'
+          })
+          saveAs(blob, pdfName);
+        }).catch((error) => {
+          this.wavePrintOrderPdfDownloadLoading = false;
+        })
+      },
+      openModifyExpressBillDialog(row){
+        this.printOrder.waveId = row.waveId;
+        this.printOrder.orderNumber = row.orderNumber;
+        this.printOrder.oldDeliveryNo = row.deliveryNo;
+        this.modifyExpressBillVisible = true;
+      },
+      modifyExpressBill(waveId, printOrder){
+        let dataBody = {waveId: waveId, orderNumber: printOrder.orderNumber,
+          deliveryNo: printOrder.deliveryNo,
+          deliveryName: printOrder.deliveryName,
+          deliveryCode: printOrder.deliveryCode};
+        this.$http({
+          url: this.$http.adornUrl(`/platform/printOrder/modifyExpressBill`),
+          method: 'POST',
+          data: this.$http.adornData(dataBody)
+        }).then(({data}) => {
+          if(data){
+            this.modifyExpressBillVisible = false;
+            this.$message({
+              message: "修改成功",
+              type: 'success'
+            })
+            this.getDataList(this.page);
+          }else{
+            this.$message({
+              message: "修改失败",
+              type: 'error'
+            })
+          }
+        })
+      },
+      /**
+       * 页面滚动事件
+       */
+      scrollToTop () {
+        let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
+        this.showHeadScroll = scrollTop > 400
+      },
+
+      dialogClose(){
+        this.wave = {},
+        this.visible = false
+        this.theData = null;
+        this.dataList = [];
+        this.visible = false;
+        this.dataForm = {};
+        this.page = {
+          total: 0, // 总页数
+            currentPage: 1, // 当前页数
+            pageSize: 61 // 每页显示多少条
+        },
+        this.$emit("refressWaveList", null);
+      },
+      resetSearchForm(){
+        this.searchForm = {};
+      },
+
+      /**
+       * 获取数据列表
+       */
+      getDataList (page, params, newData = false) {
+        page = (page === undefined ? this.page : page)
+        this.dataListLoading = true
+        if (newData || !this.theData) {
+          this.theData = {
+            current: page == null ? this.page.currentPage : page.currentPage,
+            size: page == null ? this.page.pageSize : page.pageSize,
+            'orderNumber': this.searchForm.orderNumber,
+            'receiverName': this.searchForm.receiverName,
+            'deliveryNo': this.searchForm.deliveryNo,
+            'waveId': this.wave.waveId,
+            'workStatus': this.searchForm.workStatus
+          }
+        } else {
+          this.theData.current = page == null ? this.page.currentPage : page.currentPage
+          this.theData.size = page == null ? this.page.pageSize : page.pageSize
+          this.theData.status = this.status
+        }
+        this.$http({
+          url: this.$http.adornUrl('/platform/printOrder/page'),
+          method: 'get',
+          params: this.$http.adornParams(
+            Object.assign(this.theData, params
+            ), false
+          )
+        }).then(({ data }) => {
+          this.dataList = data.records
+          this.page.total = data.total
+          this.sts = !this.status ? 0 : this.status
+          this.dataListLoading = false
+        })
+      },
+      // 每页数
+      sizeChangeHandle (val) {
+        this.page.pageSize = val
+        this.page.currentPage = 1
+        this.getDataList(this.page)
+      },
+
+      // 多选
+      selectionChangeHandle (val) {
+        this.dataListSelections = val
+      },
+
+      /**
+       * 根据选项设置时间
+       * 1:今天 2:昨天 3: 近七天 4:近30天 5:近60天
+       */
+      setDateRange (val) {
+        this.timeActive = val
+        var startDay = null
+        var endDay = null
+        if (val === 1) {
+          startDay = 0
+          endDay = 0
+        } else if (val === 2) {
+          startDay = -1
+          endDay = -1
+        } else if (val === 3) {
+          startDay = -7
+          endDay = -1
+        } else if (val === 4) {
+          startDay = -30
+          endDay = -1
+        } else {
+          return
+        }
+        // 开始时间
+        let startTime = moment().add(startDay, 'days').startOf('days').format('LL')
+        // 结束时间
+        let endTime = moment().add(endDay, 'days').endOf('days').format('LL')
+        this.dateRange = [startTime, endTime]
+      },
+      // 删除
+      deleteHandle (id) {
+        var ids = id ? [id] : this.dataListSelections.map(item => {
+          return item.orderId
+        })
+        this.$confirm(`${this.$i18n.t('sys.makeSure')}[${id ? this.$i18n.t('text.delBtn') : this.$i18n.t('sys.batchDelete')}]${this.$i18n.t('text.menu')}?`, this.$i18n.t('text.tips'), {
+          confirmButtonText: this.$i18n.t('crud.filter.submitBtn'),
+          cancelButtonText: this.$i18n.t('crud.filter.cancelBtn'),
+          type: 'warning'
+        }).then(() => {
+          this.$http({
+            url: this.$http.adornUrl(`/prod/spec/${ids}`),
+            method: 'delete',
+            data: this.$http.adornData(ids, false)
+          }).then(({ data }) => {
+            this.$message({
+              message: this.$i18n.t('publics.operation'),
+              type: 'success',
+              duration: 1500,
+              onClose: () => {
+                this.getDataList(this.page)
+              }
+            })
+          })
+        }).catch(() => { })
+      },
+      // 清空按钮
+      clear () {
+        this.dataForm = {}
+        this.dateRange = []
+        this.status = null
+        this.timeActive = null
+      },
+      // 搜索查询
+      searchChange (newData = false) {
+        this.page.currentPage = 1
+        this.getDataList(this.page, null, newData)
+      },
+      handleCurrentChange (val) {
+        this.page.currentPage = val
+        this.getDataList()
+      },
+      handleSizeChange (val) {
+        this.page.pageSize = val
+        this.getDataList()
+      },
+      cancelDelivery(row) {
+        this.$confirm('确定取消发货吗?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.$http({
+            url: this.$http.adornUrl(`/platform/printOrder/cancelDelivery/` + row.printOrderId),
+            method: 'POST',
+            data: this.$http.adornData()
+          }).then(({data}) => {
+            if (data) {
+              this.getDataList(this.page, false);
+              this.$message({
+                message: "取消发货成功",
+                type: 'success'
+              })
+            } else {
+              this.$message({
+                message: "取消发货失败",
+                type: 'error'
+              })
+            }
+          }).catch(() => {
+          })
+        })
+      },
+    },
+    destroyed () {
+      // 页面销毁时移除监听
+      window.removeEventListener('scroll', this.handleScroll)
+    },
+  }
+</script>
+<style lang="scss" scoped>
+  .expand-detail{
+    font-size: 18px;
+  }
+  expand-detail-title{
+    font-size: 18px;
+    font-weight: bold;
+  }
+  .el-divider--vertical {
+    display: inline-block;
+    width: 1px;
+    height: 30px;
+    margin: 0 16px;
+    vertical-align: middle;
+    position: relative;
+  }
+</style>

+ 110 - 0
src/views/modules/print/wave-stat.vue

@@ -0,0 +1,110 @@
+<template>
+  <el-dialog
+    title="波次材质统计"
+    :close-on-click-modal="false"
+    append-to-body
+    top="5vh"
+    width="80%"
+    :visible.sync="visible"
+    >
+    <div class="mod-print-prodAssistRecord">
+      <div class="main-container">
+        <div class="table-con spec-table">
+          <el-table
+            ref="specListTable"
+            :data="dataList"
+            header-cell-class-name="table-header"
+            row-class-name="table-row"
+            border
+            height="600"
+            style="width: 100%">
+            <el-table-column
+              type="index"
+              label="序号">
+            </el-table-column>
+            <!-- 产品类型 -->
+            <el-table-column label="产品类型" prop="prodType" align="center">
+              <template slot-scope="scope">
+                <span>{{ scope.row.prodType}}</span>
+              </template>
+            </el-table-column>
+            <!-- 尺寸大小 -->
+            <el-table-column label="尺寸大小" prop="pdfSize" align="center">
+              <template slot-scope="scope">
+                <span>{{ scope.row.pdfSize}}</span>
+              </template>
+            </el-table-column>
+            <!-- 助力用户 -->
+            <el-table-column label="覆膜工艺" prop="skuName" align="center">
+              <template slot-scope="scope">
+                <span>{{ scope.row.skuName}}</span>
+              </template>
+            </el-table-column>
+            <!-- 助力电量 -->
+            <el-table-column label="张数" prop="nums" align="center">
+              <template slot-scope="scope">
+                <span>{{ scope.row.nums}}</span>
+              </template>
+            </el-table-column>
+            <!-- 助力时间 -->
+            <el-table-column label="色数" prop="colorPrint" align="center">
+              <template slot-scope="scope">
+                <span>{{ scope.row.colorPrint}}</span>
+              </template>
+            </el-table-column>
+            <!-- 助力时间 -->
+            <el-table-column label="克数" prop="gram" align="center">
+              <template slot-scope="scope">
+                <span>{{ scope.row.gram}}</span>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </div>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+export default {
+  data () {
+    return {
+      dataList: [],
+      visible: false,
+      searchForm: {}, // 搜索
+      dataListLoading: false,
+      addOrUpdateVisible: false
+    }
+  },
+  components: {
+
+  },
+  created () {
+
+  },
+  mounted () {
+  },
+  methods: {
+    init(waveId){
+      this.visible = true;
+      this.$nextTick(() => {
+        this.searchForm.waveId = waveId;
+        this.getDataList()
+      })
+    },
+    getDataList () {
+      this.dataListLoading = true
+      this.$http({
+        url: this.$http.adornUrl('/platform/wave/statOrder/' + this.searchForm.waveId),
+        method: 'GET',
+      }).then(({data}) => {
+        this.dataList = data;
+      })
+    },
+  }
+}
+</script>
+<style lang="scss">
+.mod-print-wave-stat {
+}
+</style>

+ 468 - 0
src/views/modules/print/wave.vue

@@ -0,0 +1,468 @@
+<template>
+  <div class="mod-transport">
+    <!-- 搜索栏 -->
+    <div class="search-bar">
+      <el-form :inline="true" class="search-form" ref="searchForm" :model="searchForm" label-width="auto" size="small">
+        <div class="input-row">
+          <el-form-item label="波次号" class="search-form-item">
+            <el-input type="text" v-model="searchForm.waveNo" placeholder="请输入波次号"></el-input>
+          </el-form-item>
+          <el-form-item label="备注名" class="search-form-item">
+            <el-input type="text" v-model="searchForm.waveName" placeholder="请输入备注名"></el-input>
+          </el-form-item>
+          <el-form-item label="生产状态"  :label-width=" lang === 'en' ? '145px' : '85px'">
+            <el-select
+              v-model="searchForm.productionStatus"
+              clearable
+              placeholder="请选择生产状态"
+              size="small">
+              <el-option key="0" label="未生成" value="0"></el-option>
+              <el-option key="1" label="已生产" value="1"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="发货状态"  :label-width=" lang === 'en' ? '145px' : '85px'">
+            <el-select
+              v-model="searchForm.scanStatus"
+              clearable
+              placeholder="请选择发货状态"
+              size="small">
+              <el-option key="0" label="未发货" value="0"></el-option>
+              <el-option key="1" label="部分发货" value="1"></el-option>
+              <el-option key="2" label="全部发货" value="2"></el-option>
+            </el-select>
+          </el-form-item>
+          <el-form-item label="运单号状态"  :label-width=" lang === 'en' ? '145px' : '85px'">
+            <el-select
+              v-model="searchForm.expressBillStatus"
+              clearable
+              placeholder="请选择运单号状态"
+              size="small">
+              <el-option key="0" label="未获取" value="0"></el-option>
+              <el-option key="1" label="已获取" value="1"></el-option>
+            </el-select>
+          </el-form-item>
+          <!--<el-form-item label="发货状态"  :label-width=" lang === 'en' ? '145px' : '85px'">
+            <el-select
+              v-model="searchForm.scanStatus"
+              clearable
+              placeholder="请选择发货状态"
+              size="small">
+              <el-option key="0" label="未扫描" value="0"></el-option>
+              <el-option key="1" label="部分扫描" value="1"></el-option>
+              <el-option key="2" label="全部已扫描" value="2"></el-option>
+            </el-select>
+          </el-form-item>-->
+          <el-form-item label="生成时间"   :label-width=" lang === 'en' ? '145px' : '85px'">
+            <el-date-picker
+              size="small"
+              v-model="dateRange"
+              type="datetimerange"
+              :range-separator="this.$i18n.t('time.tip')"
+              value-format="yyyy-MM-dd HH:mm:ss"
+              :start-placeholder="this.$i18n.t('time.start')"
+              :end-placeholder="this.$i18n.t('time.end')"
+            ></el-date-picker>
+          </el-form-item>
+          <el-form-item>
+            <div class="default-btn primary-btn" @click="searchChange(true)">{{$t('crud.searchBtn')}}</div>
+            <div class="default-btn" @click="resetSearchForm('searchForm')">{{$t('shop.resetMap')}}</div>
+          </el-form-item>
+        </div>
+      </el-form>
+    </div>
+
+    <div class="main-container">
+      <!-- 表格 -->
+      <div class="table-con transport-table">
+        <el-table
+          ref="waveTable"
+          :data="dataList"
+          border
+          header-cell-class-name="table-header"
+          row-class-name="table-row-low"
+          style="width: 100%">
+          <el-table-column
+            align="center"
+            prop="waveNo"
+            width="200px"
+            label="波次号">
+            <template slot-scope="scope">
+              <span class="table-cell-text">{{ scope.row.waveNo }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            label="备注名"
+            align="center"
+            prop="waveName">
+            <template slot-scope="scope">
+              <span>{{scope.row.waveName }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            width="100px"
+            label="店铺名"
+            align="center"
+            prop="shopName">
+            <template slot-scope="scope">
+              <span>{{scope.row.shopName }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            width="100px"
+            label="生产状态"
+            align="center"
+            prop="productionStatus">
+            <template slot-scope="scope">
+              <span v-if="scope.row.productionStatus == 0">未生产</span>
+              <span v-else-if="scope.row.productionStatus == 1">已生产</span>
+              <span v-else>未知</span>
+            </template>
+          </el-table-column>
+
+          <el-table-column
+            align="center"
+            prop="orderNum"
+            width="100px"
+            label="订单数量"
+          >
+            <template slot-scope="scope">
+              <span>{{scope.row.orderNum }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="orderNum"
+            width="100px"
+            label="打印色数"
+          >
+            <template slot-scope="scope">
+              <el-tag v-if="scope.row.colorPrint === '4'" type="success">四色</el-tag>
+              <el-tag v-if="scope.row.colorPrint === '8'" type="danger">影像级</el-tag>
+              <el-tag v-if="scope.row.colorPrint === '6'" type="warning">六色</el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="orderNum"
+            width="100px"
+            label="打印克数"
+          >
+            <template slot-scope="scope">
+              <span>{{scope.row.gram }}</span>
+            </template>
+          </el-table-column>
+
+          <el-table-column
+            align="center"
+            label="生成时间"
+            prop="createTime"
+          >
+            <template slot-scope="scope">
+              <span>{{scope.row.createTime }}</span>
+            </template>
+          </el-table-column>
+
+          <el-table-column
+            width="100px"
+            align="center"
+            prop="expressBillStatus"
+            label="运单号状态"
+          >
+            <template slot-scope="scope">
+              <span v-if="scope.row.expressBillStatus == 0">未获取</span>
+              <span v-else-if="scope.row.expressBillStatus == 1">已获取</span>
+              <span v-else>未知</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            width="140px"
+            align="center"
+            prop="scanStatus"
+            label="发货状态"
+          >
+            <template slot-scope="scope">
+              <span v-if="scope.row.scanStatus == 0">未发货</span>
+              <span v-else-if="scope.row.scanStatus == 1">部分发货({{scope.row.scanNum}}/{{scope.row.orderNum}})</span>
+              <span v-else-if="scope.row.scanStatus == 2">全部已发货</span>
+              <span v-else>未知</span>
+            </template>
+          </el-table-column>
+
+          <el-table-column
+            align="center"
+            :label="$t('crud.menu')"
+            width="150"
+          >
+            <template slot-scope="scope">
+              <div style="display: inline-block;float: left;">
+<!--                  <el-button size="mini" @click="downloadWavePrintOrderPdf(scope.row)" :loading="wavePrintOrderPdfDownloadLoading" :disabled="scope.row.productionStatus == 0">下载PDF包</el-button>-->
+<!--                  <el-button size="mini" :loading="wavePrintOrderInfoDownloadLoading" @click="downloadWavePrintOrderInfo(scope.row)" :disabled="scope.row.productionStatus == 0">下载订单信息</el-button>-->
+<!--                  <el-button size="mini" @click="openScanDialog(scope.row)" :disabled="scope.row.productionStatus == 0">扫描发货</el-button>-->
+              </div>
+              <div
+                class="default-btn text-btn operate-btn"
+                @click="openWaveDetailDialog(scope.row)">详情</div>
+              <div
+                class="default-btn text-btn"
+                @click="openWaveModifyDialog(scope.row)">
+                编辑
+              </div>
+            </template>
+          </el-table-column>
+        </el-table>
+      </div>
+
+      <!-- 分页 -->
+      <el-pagination
+        v-if="dataList.length"
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+        :current-page="page.currentPage"
+        :page-sizes="[10, 20, 50, 100]"
+        :page-size="page.pageSize"
+        layout="total, sizes, prev, pager, next, jumper"
+        :total="page.total">
+      </el-pagination>
+    </div>
+    <!-- 波次详情 -->
+    <wave-print-order ref="wavePrintOrder" @refressWaveList="getDataList"></wave-print-order>
+
+<!--    <order-scan-delivery ref="orderScanDelivery" @refreshDataList="getDataList"></order-scan-delivery>-->
+
+    <!-- 修改波次 -->
+    <el-dialog
+      title="修改波次"
+      :visible.sync="modifyVisible"
+      v-if="modifyVisible"
+      width="40%"
+      center
+      :close-on-click-modal="false"
+      :close-on-press-escape="false"
+    >
+      <el-form :model="modifyWave">
+        <el-form-item label="波次号" label-width="100px">
+          <span autocomplete="off">{{modifyWave.waveNo}}</span>
+        </el-form-item>
+        <el-form-item label="备注名" label-width="100px">
+          <el-input v-model="modifyWave.waveName" autocomplete="off"></el-input>
+        </el-form-item>
+        <el-form-item label="色数" label-width="100px">
+          <el-select v-model="modifyWave.colorPrint">
+            <el-option key="1" label="影像级" value="8"></el-option>
+            <el-option key="2" label="六色" value="6"></el-option>
+            <el-option key="3" label="四色" value="4"></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="克数" label-width="100px">
+          <el-select v-model="modifyWave.gram">
+            <el-option key="1" label="400g" value="400g"></el-option>
+            <el-option key="2" label="350g" value="350g"></el-option>
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="modifyHandle(modifyWave)">确 认</el-button>
+      </div>
+    </el-dialog>
+
+  </div>
+</template>
+
+<script>
+  import WavePrintOrder from './wave-print-order'
+  import {downloadXls} from "@/utils/excel";
+  import {downloadZip} from "@/utils/zip";
+  import OrderScanDelivery from '@/components/order-scan-delivery';
+  export default {
+    components: {WavePrintOrder,OrderScanDelivery},
+    data () {
+      return {
+        theData: null, // 保存上次点击查询的请求条件
+
+        dataForm: {
+          transName: ''
+        },
+        dataList: [],
+        dataListLoading: false,
+        dataListSelections: [],
+        modifyVisible: false,
+        modifyWave: {},
+        lang: localStorage.getItem('lang'),
+        page: {
+          total: 0, // 总页数
+          currentPage: 1, // 当前页数
+          pageSize: 10 // 每页显示多少条
+        },
+        searchForm: {shopId: this.$store.state.user.shopId},
+        dateRange: [],
+        selectAll: false,
+        wavePrintOrderInfoDownloadLoading: false,
+        wavePrintOrderPdfDownloadLoading: false,
+        wavePrintOrderVisible: false
+
+      }
+    },
+    created () {
+      this.getDataList()
+    },
+    methods: {
+      // 获取数据列表
+      getDataList (page, newData = false) {
+        this.dataListLoading = true
+        if (newData || !this.theData) {
+          this.searchForm.startTime = this.dateRange === null ? null : this.dateRange[0], // 开始时间
+          this.searchForm.endTime = this.dateRange === null ? null : this.dateRange[1], // 结束时间
+          this.theData = JSON.parse(JSON.stringify(this.searchForm))
+        }
+        this.$http({
+          url: this.$http.adornUrl('/platform/wave/page'),
+          method: 'get',
+          params: this.$http.adornParams(
+            Object.assign(
+              {
+                current: page == null ? this.page.currentPage : page.currentPage,
+                size: page == null ? this.page.pageSize : page.pageSize
+              },
+              this.theData
+            )
+          )
+        }).then(({data}) => {
+          this.dataList = data.records
+          this.page.total = data.total
+          this.dataListLoading = false
+        })
+      },
+      // 新增 / 修改
+      openWaveDetailDialog (wave) {
+        this.$refs.wavePrintOrder.init(wave)
+      },
+      openWaveModifyDialog (wave) {
+        this.modifyVisible = true;
+        this.modifyWave = wave;
+      },
+      downloadWavePrintOrderInfo(wave){
+        this.wavePrintOrderInfoDownloadLoading = true;
+        this.$http({
+          url: this.$http.adornUrl('/platform/wave/downloadWavePrintOrderInfo'),
+          method: 'get',
+          params: this.$http.adornParams({waveId: wave.waveId, printChannel: wave.printChannel}),
+          responseType: 'blob'
+        }).then(({data}) => {
+          this.wavePrintOrderInfoDownloadLoading = false;
+          let fileName = wave.waveNo + "_" + wave.waveName + "_订单信息";
+          downloadXls(data, fileName + ".xlsx");
+        }).catch((error) => {
+          this.wavePrintOrderInfoDownloadLoading = false;
+        })
+      },
+      downloadWavePrintOrderPdf(wave){
+        this.wavePrintOrderPdfDownloadLoading = true;
+        let dataBody = {"printChannel": wave.printChannel, "waveId": wave.waveId};
+        this.$http({
+          url: this.$http.adornUrl('/platform/wave/downloadWavePrintOrderPdf'),
+          method: 'get',
+          params: this.$http.adornParams(dataBody),
+          responseType: 'blob'
+        }).then(({data}) => {
+          this.wavePrintOrderPdfDownloadLoading = false;
+          let fileName = wave.waveNo + "_" + wave.waveName;
+          downloadZip(data, fileName + ".zip");
+        }).catch((error) => {
+          this.wavePrintOrderPdfDownloadLoading = false;
+        })
+      },
+      /**
+       * 全选按钮
+       */
+      handleSelectAll () {
+        if (this.$refs.transportTable.selection.length < this.dataList.length) {
+          this.selectAll = true
+        } else {
+          this.selectAll = false
+        }
+        this.$refs.waveTable.toggleAllSelection()
+      },
+      // 修改
+      modifyHandle (row) {
+        this.$http({
+          url: this.$http.adornUrl(`/platform/wave/modify`),
+          method: 'POST',
+          data: this.$http.adornData(row)
+        }).then(({data}) => {
+          this.modifyVisible = false;
+          if(data){
+            this.$message({
+              message: "修改成功",
+              type: 'success'
+            })
+            this.getDataList(this.page);
+          }else{
+            this.$message({
+              message: "修改失败",
+              type: 'error'
+            })
+          }
+        })
+      },
+      // 删除
+      deleteHandle (row) {
+        this.$confirm('确定要删除波次吗?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning'
+        }).then(() => {
+          this.$http({
+            url: this.$http.adornUrl(`/platform/wave/deleteWave`),
+            method: 'POST',
+            data: this.$http.adornData(row)
+          }).then(({data}) => {
+            if(data){
+              this.$message({
+                message: "删除成功",
+                type: 'success'
+              })
+              this.getDataList(this.page);
+            }else{
+              this.$message({
+                message: "删除失败",
+                type: 'error'
+              })
+            }
+          })
+        })
+      },
+
+      // 条件查询
+      searchChange (newData = false) {
+        this.page.currentPage = 1
+        this.getDataList(this.page, newData)
+      },
+      openScanDialog(row){
+        this.$refs.orderScanDelivery.init(row);
+      },
+
+      /**
+       * 重置表单
+       * @param {String} formName 表单名称
+       */
+      resetSearchForm (formName) {
+        this.$refs[formName].resetFields()
+        this.searchForm = {};
+        this.theData = {};
+        this.getDataList(this.page, false)
+      },
+      handleSizeChange (val) {
+        this.page.pageSize = val
+        this.getDataList()
+      },
+      handleCurrentChange (val) {
+        this.page.currentPage = val
+        this.getDataList()
+      },
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 20 - 2
src/views/modules/prod/prodComm-add-or-update.vue

@@ -46,7 +46,13 @@
         <!-- 评论图片 -->
         <el-form-item :label="this.$i18n.t('productComm.pics')" prop="userName">
           <div v-if="!pics">{{$t("productComm.no")}}</div>
-          <imgs-upload v-model="pics" :disabled="true" :modal="false" :prompt="false" />
+          <span v-for="pic in picUrlArr">
+            <video style="width: 150px;height: 150px" :src="resourcesUrl + pic" v-if="pic.slice(pic.lastIndexOf('.') + 1) !== 'jpg' && pic.slice(pic.lastIndexOf('.') + 1) !== 'png'" controls="controls"></video>
+            <el-image @click="previewPic(pic.indexOf('poster') != -1? resourcesUrl + pic.substring(7, pic.length) : resourcesUrl + pic)" style="margin-left: 20px;width: 150px;height: 150px"
+                      :src="pic.indexOf('poster') != -1? resourcesUrl + pic.substring(7, pic.length) : resourcesUrl + pic"
+                      v-if="pic.slice(pic.lastIndexOf('.') + 1) === 'jpg' || pic.slice(pic.lastIndexOf('.') + 1) === 'png'"></el-image>
+          </span>
+<!--          <imgs-upload v-for="pic in picUrlArr" v-model="pic" :disabled="true" :modal="false" :prompt="false" />-->
         </el-form-item>
         <!-- 是否匿名 -->
         <el-form-item :label="this.$i18n.t('productComm.isAnonymous')" size="mini" prop="isAnonymous">
@@ -73,7 +79,11 @@
       <div class="default-btn" @click="visible = false">{{$t("crud.filter.cancelBtn")}}</div>
       <div class="default-btn primary-btn" v-if="isEdit" @click="dataFormSubmit()">{{$t("crud.filter.submitBtn")}}</div>
     </span>
+    <el-dialog :visible.sync="previewPicDialogVisible" :modal="false" title="图片预览" width="30%" top="3vh">
+      <el-image :src="previewPicUrl" alt=""  style="width: 100%; height: 100%"/>
+    </el-dialog>
   </el-dialog>
+
 </template>
 
 <script>
@@ -89,6 +99,8 @@ export default {
       }
     }
     return {
+      previewPicUrl: null,
+      previewPicDialogVisible: false,
       isEdit: false,
       visible: false,
       dataForm: {
@@ -109,6 +121,7 @@ export default {
         status: 1
       },
       pics: '',
+      picUrlArr: [],
       dataRule: {
         replyContent: [{validator: validateReplyContent}]
       },
@@ -134,6 +147,7 @@ export default {
           }).then(({ data }) => {
             this.dataForm = data
             var imgs = ''
+            this.picUrlArr = this.dataForm.picsArray
             this.dataForm.picsArray.forEach(element => {
               imgs = imgs + element + ','
             })
@@ -164,7 +178,11 @@ export default {
           })
         }
       })
-    }
+    },
+    previewPic(pic){
+      this.previewPicUrl = pic
+      this.previewPicDialogVisible = true;
+    },
   }
 }
 </script>

+ 16 - 1
src/views/modules/prod/prodComm.vue

@@ -109,13 +109,28 @@
             prop="score"
             :label="$t('productComm.score')">
           </el-table-column>
-          <el-table-column
+          <!--<el-table-column
             align="center"
             prop="isAnonymous"
             :label="$t('productComm.isAnonymous')">
             <template slot-scope="scope">
               <div class="tag-text">{{[$t('publics.no'), $t('publics.yes')][scope.row.isAnonymous]}}</div>
             </template>
+          </el-table-column>-->
+          <el-table-column
+            align="center"
+            prop="shopId"
+            label="店铺">
+            <template slot-scope="scope">
+              <div class="tag-text">
+                <span v-if="scope.row.shopId === 1">易卡定制</span>
+                <span v-if="scope.row.shopId === 2">娱糖小卡</span>
+                <span v-if="scope.row.shopId === 3">玲珑小卡</span>
+                <span v-if="scope.row.shopId === 5">吃货堂</span>
+                <span v-if="scope.row.shopId === 6">番茄定制</span>
+                <span v-if="scope.row.shopId === 9">中二小卡</span>
+              </div>
+            </template>
           </el-table-column>
           <!--          <el-table-column-->
           <!--            align="left"-->