Mr.Zhang
2023-09-19 d9c96d153bb5ed761da76f29d715c755f7b5dd32
平台端bug
已添加3个文件
已修改9个文件
683 ■■■■ 文件已修改
platform/.env.development 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platform/.env.staging 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platform/package.json 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
platform/public/template/goods_import_modle.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
platform/src/api/business/goods.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platform/src/components/business/OperaGoodsWindow.vue 325 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platform/src/components/business/selectProduct.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
platform/src/components/common/ImportButton.vue 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platform/src/components/common/ImportWindow.vue 205 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platform/src/components/common/UploadImage.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
platform/src/views/business/goods.vue 87 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platform/vue.config.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platform/.env.development
@@ -1,9 +1,10 @@
# å¼€å‘环境配置
NODE_ENV = 'development'
VUE_APP_CONTEXT_PATH = ''
VUE_APP_API_PREFIX = '/api'
# ä»»åº·
# VUE_APP_API = 'http://192.168.0.15:10017/'
# ç„¦æ¾
VUE_APP_API = 'http://192.168.0.35:10011'
VUE_APP_API = 'http://192.168.0.36:10011'
platform/.env.staging
@@ -1,2 +1,9 @@
# æµ‹è¯•环境配置
NODE_ENV = 'production'
VUE_APP_CONTEXT_PATH = '/preselect_admin'
VUE_APP_API_PREFIX = '/preselect_admin_interface'
# https://dmtest.ahapp.net/preselect_admin_interface/doc.html
VUE_APP_API = 'https://dmtest.ahapp.net/preselect_admin_interface'
platform/package.json
@@ -5,7 +5,7 @@
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "build:staging": "vue-cli-service build --mode staging",
    "build:dev": "vue-cli-service build --mode staging",
    "lint": "vue-cli-service lint",
    "fix": "eslint --ext .js,.vue src --fix"
  },
platform/public/template/goods_import_modle.xlsx
Binary files differ
platform/src/api/business/goods.js
@@ -30,7 +30,7 @@
// ä¿®æ”¹
export function updateById (data) {
  return request.post('/business/baseGoods/updateById', data)
  return request.post('/business/baseGoods/update', data)
}
// åˆ é™¤
@@ -62,5 +62,5 @@
// æ ¹æ®ID查询
export function queryById (id) {
  return request.get(`business/baseGoods/${id}`)
  return request.get(`/business/baseGoods/${id}`)
}
platform/src/components/business/OperaGoodsWindow.vue
@@ -1,94 +1,46 @@
<template>
  <GlobalWindow
    :title="title"
    :visible.sync="visible"
    :confirm-working="isWorking"
    @confirm="confirm"
    width="800px"
  >
  <GlobalWindow :title="title" :visible.sync="visible" :confirm-working="isWorking" @confirm="confirm" width="800px"
    v-loading="isUploading">
    <el-form :model="form" ref="form" label-width="120px" :rules="rules">
      <div style="font-size: 18px;font-weight: bold;">基本信息</div>
      <el-form-item label="商品名称" prop="name">
        <el-input v-model="form.name" maxlength="50" placeholder="请输入商品名称,不超过50个字" v-trim/>
        <el-input v-model="form.name" maxlength="50" placeholder="请输入商品名称,不超过50个字" v-trim />
      </el-form-item>
      <el-form-item label="商品品牌" prop="brandId">
        <el-select v-model="form.brandId" placeholder="请选择,单选">
          <el-option
            v-for="item in brandList"
            :key="item.id"
            :label="item.name"
            :value="item.id">
          <el-option v-for="item in brandList()" :key="item.id" :label="item.name" :value="item.id">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="商品类别" prop="categoryId">
        <!-- @change="changeCategory(form.categoryId)" -->
        <el-select v-model="form.categoryId" placeholder="请选择,单选">
          <el-option
            v-for="item in categoryList"
            :key="item.id"
            :label="item.name"
            :value="item.id">
        <el-select v-model="form.categoryId" placeholder="请选择,单选" @change="categorySelect">
          <el-option v-for="item in categoryList()" :key="item.id" :label="item.name" :value="item.id">
          </el-option>
        </el-select>
      </el-form-item>
      <!-- <el-form-item :label="name1" prop="attrFirstIds" v-if="name1">
        <el-select v-model="form.attrFirstIds" multiple placeholder="请选择,支持多选">
          <el-option
            v-for="item in form.attrFirstList"
            :key="item.id"
            :label="item.name"
            :value="item.id">
          </el-option>
        </el-select>
      </el-form-item>
      <el-form-item :label="name2" prop="attrSecodIds" v-if="name2">
        <el-select v-model="form.attrSecodIds" multiple placeholder="请选择,支持多选">
          <el-option
            v-for="item in form.attrSecodList"
            :key="item.id"
            :label="item.name"
            :value="item.id">
          </el-option>
        </el-select>
      </el-form-item> -->
      <el-form-item label="指导价(元)" prop="zdPrice">
        <el-input v-model="form.zdPrice" @input="priceCHANEG(form.zdPrice, 1)" type="number" placeholder="建议录入整数,单位元" v-trim/>
        <el-input v-model="form.zdPrice" @input="priceCHANEG(form.zdPrice, 1)" type="number" placeholder="建议录入整数,单位元"
          v-trim />
      </el-form-item>
      <el-form-item label="入手价(元)" prop="price">
        <el-input v-model="form.price" @input="priceCHANEG(form.price, 2)" type="number" placeholder="建议录入整数,单位元" v-trim/>
        <el-input v-model="form.price" @input="priceCHANEG(form.price, 2)" type="number" placeholder="建议录入整数,单位元"
          v-trim />
      </el-form-item>
      <el-form-item label="商品主图">
        <el-upload
          :action="action"
          :file-list="form.ztList"
          :data="{ folder: 'goods_img' }"
          list-type="picture-card"
          :limit="1"
          :on-success="fileSuccess"
          :on-exceed="exceed"
          :on-remove="handleRemove">
          <i class="el-icon-plus"></i>
          <div slot="tip" class="el-upload__tip">只能上传图片格式,png格式,建议尺寸140*140px</div>
        </el-upload>
        <UploadAvatarImage :file="{ 'imgurlfull': form.imgfullurl, 'imgurl': form.imgurl }" :uploadData="uploadData"
          tipsLabel="" @uploadSuccess="uploadReverseSuccess" @uploadEnd="isUploading = false"
          @uploadBegin="isUploading = true" />
        åªèƒ½ä¸Šä¼ å›¾ç‰‡æ ¼å¼ï¼Œpng格式,建议尺寸140px*140px
      </el-form-item>
  <el-form-item label="商品图片">
        <el-upload
          :action="action"
          :file-list="form.files"
          :multiple="true"
          :data="{ folder: 'goods_img' }"
          list-type="picture-card"
          :on-success="fileSuccess1"
          :on-remove="handleRemove1">
          <i class="el-icon-plus"></i>
          <div slot="tip" class="el-upload__tip">只能上传图片格式,png格式,建议尺寸600*600px</div>
        </el-upload>
      <el-form-item label="商品图片">
        <UploadImage :fileList="form.multifileList" :uploadData="uploadData" @beginUpload="isUploading = true" @endUpload="isUploading = false" />
        åªèƒ½ä¸Šä¼ å›¾ç‰‡æ ¼å¼ï¼Œpng格式,建议尺寸600*600px
      </el-form-item>
      <template v-if="form.goodsParamList && form.goodsParamList.length > 0">
        <div style="font-size: 18px;font-weight: bold;">参数属性值配置 <span style="font-size: 13px; font-weight: 500;">按需配置当前商品的产品参数值,单个参数值不超过30个字</span></div>
        <el-form-item :label="item.name" v-for="(item, index) in form.goodsParamList" :key="index">
          <el-input v-model="item.val" maxlength="30" type="text" placeholder="请输入" v-trim/>
      <template v-if="form.baseGoodsParamList && form.baseGoodsParamList.length > 0">
        <div style="font-size: 18px;font-weight: bold;">参数属性值配置 <span
            style="font-size: 13px; font-weight: 500;">按需配置当前商品的产品参数值,单个参数值不超过30个字</span></div>
        <el-form-item :label="item.name" v-for="(item, index) in form.baseGoodsParamList" :key="index">
          <el-input v-model="item.val" maxlength="30" type="text" placeholder="请输入" v-trim />
        </el-form-item>
      </template>
    </el-form>
@@ -98,18 +50,21 @@
<script>
import BaseOpera from '@/components/base/BaseOpera'
import GlobalWindow from '@/components/common/GlobalWindow'
import { baseCategory,brand } from '@/api/system/common.js'
import {  create, updateById, companyCreate, companyUpdateById } from '@/api/business/goods.js'
import UploadAvatarImage from '@/components/common/UploadAvatarImage.vue'
import UploadImage from '@/components/common/UploadImage.vue'
import { baseCategory, brand } from '@/api/system/common.js'
import { companyCreate, companyUpdateById } from '@/api/business/goods.js'
export default {
  name: 'OperaGoodsWindow',
  extends: BaseOpera,
  components: { GlobalWindow },
  data () {
  components: { GlobalWindow, UploadAvatarImage, UploadImage },
  data() {
    return {
      action: process.env.VUE_APP_API_PREFIX + '/public/upload',
      name1: '',
      name2: '',
      // è¡¨å•数据
      isUploading: false,
      form: {
        id: null,
        name: '',
@@ -117,17 +72,13 @@
        brandId: '',
        zdPrice: '',
        price: '',
        attrFirstIds: [],
        attrFirstNames: '',
        attrSecodIds: [],
        attrSecodNames: '',
        imgurl: '',
        imgfullurl: '',
        multifileList: [],
        files: [],
        ztList: [],
        goodsParamList: [],
        attrFirstList: [],
        attrSecodList: []
        baseGoodsParamList: [],
      },
      uploadData: {
        folder: 'goods_img'
      },
      // éªŒè¯è§„则
      rules: {
@@ -147,77 +98,42 @@
          { required: true, message: '不能为空', trigger: 'blur' }
        ]
      },
      options: [],
      categoryList: [],
      brandList: []
      options: []
    }
  },
  created () {
  inject: ['categoryList', 'brandList'],
  created() {
    this.config({
      api: '/business/goods',
      'field.id': 'id'
    })
    this.getbrand()
    this.getcategory()
  },
  watch: {
    'form.categoryId': {
      immediate: true,
      handler(news, old) {
        if (news) {
          this.name1 = ''
          this.name2 = ''
          if (old) {
            this.form.attrFirstIds = []
            this.form.attrSecodIds = []
            this.form.goodsParamList = []
          }
          this.categoryList.forEach(item => {
            if (item.id === news) {
              this.name1 = item.attrFirst
              this.name2 = item.attrSecond
              this.form.attrFirstList = item.attrFirstList.length > 0 ? item.attrFirstList : []
              this.form.attrSecodList = item.attrSecondList.length > 0 ? item.attrSecondList : []
              this.form.goodsParamList = JSON.parse(JSON.stringify(item.paramList))
              this.form.goodsParamList.forEach(item => {
                item.pramaId = item.id
              })
              console.log(this.form.goodsParamList)
            }
          })
          this.getcategory(1)
        }
      }
    },
    visible: {
      handler(news, old) {
        if (!news) {
          this.name1 = ''
          this.name2 = ''
          this.form = {
            id: null,
            name: '',
            categoryId: '',
            brandId: '',
            zdPrice: '',
            price: '',
            attrFirstIds: [],
            attrFirstNames: '',
            attrSecodIds: [],
            attrSecodNames: '',
            imgurl: '',
            multifileList: [],
            files: [],
            ztList: [],
            goodsParamList: [],
            attrFirstList: [],
            attrSecodList: []
          }
        }
      }
    }
    // this.getbrand()
    // this.getcategory()
  },
  methods: {
    open(title, target) {
      this.title = title
      this.visible = true
      // æ–°å»º
      if (target == null) {
        this.$nextTick(() => {
          this.$refs.form.resetFields()
          this.form.multifileList = []
          this.form.baseGoodsParamList = []
          this.form[this.configData['field.id']] = null
        })
        return
      }
      // ç¼–辑
      this.$nextTick(() => {
        for (const key in this.form) {
          this.form[key] = target[key]
        }
        this.form.multifileList.forEach(item => {
          item.url = item.filefullurl
        })
      })
    },
    priceCHANEG(val, type) {
      if (!/^[1-9]+[0-9]*$/.test(val)) {
        this.$message.warning('只能输入正整数')
@@ -228,115 +144,20 @@
        }
      }
    },
    confirm() {
      this.$refs.form.validate((valid) => {
        if (valid) {
          if (this.form.attrFirstIds.length > 0) {
            let arr = []
            this.form.attrFirstIds.forEach(element => {
              this.form.attrFirstList.forEach(item => {
                if (element === item.id) {
                  arr.push(item.name)
                }
              })
            })
            this.form.attrFirstNames = arr.join(',')
            this.form.attrFirstIds = this.form.attrFirstIds.join(',')
          } else {
            this.form.attrFirstNames = ''
            this.form.attrFirstIds = ''
          }
          if (this.form.attrSecodIds.length > 0) {
            let arr = []
            this.form.attrSecodIds.forEach(element => {
              this.form.attrSecodList.forEach(item => {
                if (element === item.id) {
                  arr.push(item.name)
                }
              })
            })
            this.form.attrSecodNames = arr.join(',')
            this.form.attrSecodIds = this.form.attrSecodIds.join(',')
          } else {
            this.form.attrSecodNames = ''
            this.form.attrSecodIds = ''
          }
          if (!this.form.id) {
            companyCreate({...this.form, type: 0})
              .then(() => {
                this.visible = false
                this.$tip.apiSuccess('新建成功')
                this.$emit('success')
              })
              .catch(e => {
                this.$tip.apiFailed(e)
              })
              .finally(() => {
                this.isWorking = false
              })
          } else {
            companyUpdateById({...this.form, type: 0})
              .then(() => {
                this.visible = false
                this.$tip.apiSuccess('编辑成功')
                this.$emit('success')
              })
              .catch(e => {
                this.$tip.apiFailed(e)
              })
              .finally(() => {
                this.isWorking = false
              })
          }
        } else {
          return false;
    categorySelect(v) {
      this.categoryList().forEach(item => {
        if (item.id === v) {
          this.form.baseGoodsParamList = JSON.parse(JSON.stringify(item.baseCateParamList))
          this.form.baseGoodsParamList.forEach(item => {
            item.pramaId = item.id
          })
        }
      });
    },
    exceed() {
      this.$message.warning({
        message: '只能上传一个图标'
      })
    },
    fileSuccess1(response, file, fileList) {
      this.form.files = fileList
      this.form.multifileList.push({ fileurl: response.data.imgaddr, name: response.data.imgname, url: response.data.url })
    },
    handleRemove1(file, fileList) {
      this.form.files = fileList
      this.form.multifileList = fileList
    },
    fileSuccess(response) {
      this.form.ztList.push({ imgaddr: response.data.imgaddr, url: response.data.url })
      this.form.imgurl = response.data.imgaddr
    },
    handleRemove() {
      this.form.ztList = []
      this.form.imgurl = ''
    },
      getbrand() {
        brand({status:0})
          .then(res => {
            this.brandList = res
          })
      },
      getcategory(type) {
        baseCategory({status:0 , type:1})
          .then(res => {
            this.categoryList = res
            if (type === 1) {
              this.categoryList.forEach(item => {
                if (item.id === this.form.categoryId) {
                  this.form.goodsParamList = JSON.parse(JSON.stringify(item.paramList))
                  this.form.goodsParamList.forEach(item => {
                    item.pramaId = item.id
                  })
                  console.log(this.form.goodsParamList)
                }
              })
            }
          })
      }
    uploadReverseSuccess(file) {
      this.form.imgurl = file.imgurl;
      this.form.imgfullurl = file.imgurlfull;
    }
  }
}
</script>
platform/src/components/business/selectProduct.vue
@@ -62,7 +62,7 @@
    },
    created() {
      this.config({
        api: '/business/anchor',
        api: '/business/goods',
        'field.id': 'id'
      })
    },
platform/src/components/common/ImportButton.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
<template>
  <div class="import-button">
    <el-button type="primary" @click="$refs.importWindow.open(text)">{{text}}</el-button>
    <ImportWindow :action="action" :template-path="templatePath" :template-name="templateName" ref="importWindow" @success="handleSuccess"/>
  </div>
</template>
<script>
import ImportWindow from './ImportWindow'
export default {
  name: 'ImportButton',
  components: { ImportWindow },
  props: {
    // æŒ‰é’®æ–‡æ¡ˆ
    text: {
      default: '导入'
    },
    // æ¨¡ç‰ˆåœ°å€
    templatePath: {
      required: true
    },
    // ä¸‹è½½åŽçš„æ¨¡ç‰ˆæ–‡ä»¶åç§°
    templateName: {
      required: true
    },
    // å¯¼å…¥æŽ¥å£åœ°å€
    action: {
      required: true
    }
  },
  methods: {
    handleSuccess () {
      this.$emit('success')
    }
  }
}
</script>
platform/src/components/common/ImportWindow.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,205 @@
<template>
  <el-dialog
    width="500px"
    :title="title"
    :visible.sync="visible"
    append-to-body
    custom-class="eva-dialog import-window"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    :show-close="false"
  >
    <el-form>
      <el-form-item>
        <el-upload
          drag
          :show-file-list="false"
          action="none"
          accept=".xlsx, .xls"
          :before-upload="handleBeforeUpload"
        >
          <template v-if="form.file == null">
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
          </template>
          <template v-else>
            <i class="el-icon-files"></i>
            <div class="el-upload__text">{{form.file.name}}<em></em></div>
          </template>
        </el-upload>
      </el-form-item>
    </el-form>
    <div slot="footer" class="import-window__footer">
      <!-- <div class="sync-exists">
        <el-checkbox v-model="form.sync"/><span>同步已存在的数据</span>
      </div> -->
      <div class="opera">
        <a href=""></a>
        <el-button type="text" icon="el-icon-download" @click="downloadTemplate">下载模版</el-button>
        <el-button @click="cancel">{{cancelText}}</el-button>
        <el-button type="primary" @click="confirm" :loading="isWorking">{{confirmText}}</el-button>
      </div>
    </div>
  </el-dialog>
</template>
<script>
import request from '@/utils/request'
export default {
  name: 'ImportWindow',
  props: {
    // å¯¼å…¥æŽ¥å£åœ°å€
    action: {
      required: true
    },
    // ç¡®è®¤æŒ‰é’®æ–‡æ¡ˆ
    confirmText: {
      type: String,
      default: '导入'
    },
    // å–消按钮文案
    cancelText: {
      type: String,
      default: '取消'
    },
    // æ¨¡ç‰ˆåœ°å€
    templatePath: {
      required: true
    },
    // ä¸‹è½½åŽçš„æ¨¡ç‰ˆæ–‡ä»¶åç§°
    templateName: {
      required: true
    }
  },
  data () {
    return {
      visible: false,
      isWorking: false,
      title: '导入数据',
      form: {
        sync: false,
        file: false,
        categoryId: ''
      }
    }
  },
  methods: {
    /**
     * æ‰“开窗口
     *
     * @param title çª—口标题
     */
    open (title) {
      this.visible = true
      this.title = title
      this.form.sync = false
      this.form.file = null
    },
    /**
     * ç¡®å®šå¯¼å…¥
     */
    confirm () {
      if (this.form.file == null) {
        this.$message.warning('请选择文件')
        return
      }
      this.isWorking = true
      const param = new FormData()
      param.set('file', this.form.file)
      request.post(this.action, param, {
        headers: {
          'Content-Type': 'multipart/form-data;charset=UTF-8'
        }
      })
        .then(() => {
          this.$message.success('导入成功')
          this.visible = false
          this.$emit('success')
        })
        .catch(e => {
          this.$message.error(e)
        })
        .finally(() => {
          this.isWorking = false
        })
    },
    /**
     * å–消
     */
    cancel () {
      this.visible = false
    },
    /**
     * ä¸‹è½½æ¨¡ç‰ˆ
     */
    downloadTemplate () {
      const link = document.createElement('a')
      link.setAttribute('download', this.templateName) //下载的文件名
      // console.log(`window.location.origin`, window.location.origin);
      // console.log(`process.env.VUE_APP_CONTEXT_PATH`, process.env.VUE_APP_CONTEXT_PATH);
      // console.log(`this.templatePath`, this.templatePath);
      link.href = `${window.location.origin}${process.env.VUE_APP_CONTEXT_PATH}${this.templatePath}`  //文件url
      link.click()
    },
    /**
     * æ–‡ä»¶ä¸Šä¼ å‰å­˜å‚¨ä¸Šä¼ çš„æ–‡ä»¶
     *
     * @param file éœ€å¯¼å…¥çš„æ–‡ä»¶
     */
    handleBeforeUpload (file) {
      this.form.file = file
      return false
    }
  }
}
</script>
<style lang="scss">
@import "../../assets/style/variables";
.import-window {
  .el-upload {
    width: 100%;
    .el-upload-dragger {
      width: 100%;
      .el-icon-upload, .el-icon-files {
        font-size: 67px;
        color: #C0C4CC;
        margin: 40px 0 16px;
        line-height: 50px;
      }
    }
  }
  .import-window__footer {
    display: flex;
    .sync-exists {
      width: 200px;
      flex-shrink: 0;
      text-align: left;
      font-size: 13px;
      display: flex;
      align-items: center;
      .el-checkbox {
        margin-right: 10px;
      }
      & > * {
        vertical-align: middle;
      }
    }
    .opera {
      flex-grow: 1;
      a {
        font-size: 12px;
        margin-right: 10px;
        text-decoration: none;
        .el-icon-download {
          font-size: 15px;
          position: relative;
          top: 2px;
        }
      }
    }
  }
}
</style>
platform/src/components/common/UploadImage.vue
@@ -59,7 +59,7 @@
  },
  data() {
    return {
      uploadImgUrl: process.env.VUE_APP_API_PREFIX + '/public/uploadLocal',
      uploadImgUrl: process.env.VUE_APP_API_PREFIX + '/public/upload',
      
      realList: [],
      srcList: [],
platform/src/views/business/goods.vue
@@ -1,6 +1,6 @@
<template>
  <TableLayout :permissions="['business:goods:query']">
  <TableLayout :permissions="['business:basegoods:query']">
    <!-- æœç´¢è¡¨å• -->
    <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
      <el-form-item label="商品名称" prop="name">
@@ -37,15 +37,17 @@
    </el-form>
    <!-- è¡¨æ ¼å’Œåˆ†é¡µ -->
    <template v-slot:table-wrap>
      <ul class="toolbar" v-permissions="['business:goods:create', 'business:goods:delete']">
        <li><el-button type="primary" @click="$refs.operaGoodsWindow.open('新建商品')" icon="el-icon-plus"
            v-permissions="['business:goods:create']">新建</el-button></li>
      <ul class="toolbar" v-permissions="['business:basegoods:create', 'business:basegoods:delete']">
        <li v-permissions="['business:basegoods:create']">
          <el-button type="primary" @click="$refs.operaGoodsWindow.open('新建商品')" icon="el-icon-plus">新建</el-button>
        </li>
        <!-- <el-button type="primary" :loading="isWorking.export"
          @click="$refs.selectProduct.open('选择平台商品')">选择平台商品</el-button> -->
        <el-button type="primary" :loading="isWorking.export" v-permissions="['business:goods:exportExcel']"
          @click="importFile">导入</el-button>
        <el-button type="primary" :loading="isWorking.export" @click="downloadFile">下载模板</el-button>
        <li v-permissions="['business:basegoods:exportExcel']">
          <ImportButton text="导入" template-name="goods_import_modle.xlsx"
            template-path="/template/goods_import_modle.xlsx" action="/business/baseGoods/importExcel"
            @success="search" />
        </li>
        <el-button type="primary" :loading="isWorking.export" @click="bulkOperation(0)">批量上架</el-button>
        <el-button type="primary" :loading="isWorking.export" @click="bulkOperation(1)">批量下架</el-button>
        <!-- <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:goods:delete']">删除</el-button></li> -->
@@ -77,17 +79,16 @@
            </el-switch>
          </template>
        </el-table-column>
        <el-table-column v-if="containPermissions(['business:goods:update', 'business:goods:delete'])" label="操作"
        <el-table-column v-if="containPermissions(['business:basegoods:update', 'business:basegoods:delete'])" label="操作"
          min-width="120" fixed="right">
          <template slot-scope="{row}">
            <el-button type="text" @click="edit(row.id)" icon="el-icon-edit"
              v-permissions="['business:goods:update']">编辑</el-button>
              v-permissions="['business:basegoods:update']">编辑</el-button>
            <el-button type="text" @click="deleteById(row)" icon="el-icon-delete"
              v-permissions="['business:goods:delete']">删除</el-button>
              v-permissions="['business:basegoods:delete']">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <input type="file" ref="upload" style="display: none;" @change="uplaodFile" />
      <pagination @size-change="handleSizeChange" @current-change="handlePageChange" :pagination="tableData.pagination">
      </pagination>
    </template>
@@ -104,12 +105,13 @@
import Pagination from '@/components/common/Pagination'
import OperaGoodsWindow from '@/components/business/OperaGoodsWindow'
import selectProduct from '@/components/business/selectProduct'
import ImportButton from '@/components/common/ImportButton'
import { brand, baseCategory, importExcel } from '@/api/system/common.js'
import { updateStatus, queryById, exportDoc } from '@/api/business/goods.js'
export default {
  name: 'Goods',
  extends: BaseTable,
  components: { TableLayout, Pagination, OperaGoodsWindow, selectProduct },
  components: { TableLayout, Pagination, OperaGoodsWindow, selectProduct, ImportButton },
  data() {
    return {
      // æœç´¢
@@ -130,6 +132,12 @@
      ]
    }
  },
  provide() {
    return {
      brandList: () => this.brandList,
      categoryList: () => this.categoryList
    }
  },
  created() {
    this.config({
      module: '商品',
@@ -146,7 +154,6 @@
      let arr = e.map(item => item.id)
      this.ids = arr.join(',')
      this.idList = arr;
      console.log(this.ids)
    },
    // æ‰¹é‡ä¸Šä¸‹æž¶
    bulkOperation(type) {
@@ -175,52 +182,10 @@
    rowStyle() {
      return "text-align:center";
    },
    importFile() {
      this.$refs.upload.click()
    },
    uplaodFile(e) {
      const FORMDATE = new FormData()
      FORMDATE.append('file', e.target.files[0])
      // è¯·æ±‚接口
      importExcel(FORMDATE)
        .then(res => {
          console.log(res)
          this.search()
        })
        .catch((err) => {
          this.$message.error(err.message)
        })
      this.$refs.upload.value = null
    },
    edit(id) {
      queryById(id)
        .then(res => {
          let obj = {
            id: res.id,
            name: res.name,
            categoryId: res.categoryId,
            brandId: res.brandId,
            zdPrice: res.zdPrice,
            price: res.price,
            attrFirstIds: res.attrFirstIds ? this.turnNum(res.attrFirstIds.split(',')) : [],
            attrFirstNames: res.attrFirstNames,
            attrSecodIds: res.attrSecodIds ? this.turnNum(res.attrSecodIds.split(',')) : [],
            attrSecodNames: res.attrSecodNames,
            imgurl: res.imgurl,
            multifileList: [],
            files: [],
            ztList: res.imgurl ? [{ url: res.prefixUrl + res.imgurl }] : [],
            pzList: [],
            attrFirstList: [],
            attrSecodList: []
          }
          if (res.multifileList.length > 0) {
            res.multifileList.forEach(item => {
              obj.multifileList.push({ fileurl: item.fileurl, name: item.name, url: res.prefixUrl + item.fileurl })
              obj.files.push({ fileurl: item.fileurl, name: item.name, url: res.prefixUrl + item.fileurl })
            })
          }
          this.$refs.operaGoodsWindow.open('编辑商品', obj)
          this.$refs.operaGoodsWindow.open('编辑商品', res)
        })
    },
    changeStatus(item) {
@@ -233,14 +198,8 @@
        // this.search()
      })
    },
    turnNum(nums) {
      for (let i = 0; i < nums.length; i++) {
        nums[i] = parseInt(nums[i])
      }
      return nums;
    },
    getbrand() {
      brand({type:1})
      brand({ type: 1 })
        .then(res => {
          this.brandList = res
        })
platform/vue.config.js
@@ -1,9 +1,8 @@
// è¯¦ç»†é…ç½®è¯·å‚考https://cli.vuejs.org/zh/config/#vue-config-js
// const outputDir = process.env.VUE_APP_CONTEXT_PATH.substring(1, process.env.VUE_APP_CONTEXT_PATH.length - 1)
// outputDir === '/' ? 'dist' : outputDir
const outputDir = process.env.VUE_APP_CONTEXT_PATH.substring(1, process.env.VUE_APP_CONTEXT_PATH.length)
module.exports = {
  publicPath: process.env.VUE_APP_CONTEXT_PATH,
  outputDir: 'dist',
  publicPath: './',
  outputDir: outputDir,
  assetsDir: 'static',
  lintOnSave: false,
  devServer: {