Mr.Zhang
2023-09-15 0411e9f7b2cc909bcdd0b8ef07f11fae804e3f1e
平台端
已添加2个文件
已修改2个文件
1470 ■■■■■ 文件已修改
platform/src/components/business/OperaGoodsWindow.vue 672 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platform/src/components/business/selectProduct.vue 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platform/src/components/business/selectProductItem.vue 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platform/src/views/business/goods.vue 496 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
platform/src/components/business/OperaGoodsWindow.vue
@@ -1,340 +1,350 @@
<template>
    <GlobalWindow
      :title="title"
      :visible.sync="visible"
      :confirm-working="isWorking"
      @confirm="confirm"
    >
      <el-form :model="form" ref="form" :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-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>
          </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-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-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-form-item>
        <el-form-item label="商品主图">
          <el-upload
            :action="action"
            :file-list="form.ztList"
            :data="{ folder: 'projects' }"
            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>
        </el-form-item>
    <el-form-item label="商品图片">
          <el-upload
            :action="action"
            :file-list="form.files"
            :multiple="true"
            :data="{ folder: 'projects' }"
            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>
  <GlobalWindow
    :title="title"
    :visible.sync="visible"
    :confirm-working="isWorking"
    @confirm="confirm"
    width="800px"
  >
    <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-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>
        </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-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-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-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>
      </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>
      <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/>
        </el-form-item>
      </el-form>
    </GlobalWindow>
  </template>
  <script>
  import BaseOpera from '@/components/base/BaseOpera'
  import GlobalWindow from '@/components/common/GlobalWindow'
  import { brand } from '@/api/system/common.js'
  import { findListForGoodsId, create, updateById } from '@/api/business/goods.js'
  export default {
    name: 'OperaGoodsWindow',
    extends: BaseOpera,
    components: { GlobalWindow },
    data () {
      return {
        action: process.env.VUE_APP_API_PREFIX + '/public/uploadLocal',
        name1: '',
        name2: '',
        // è¡¨å•数据
        form: {
          id: null,
          name: '',
          categoryId: '',
          brandId: '',
          zdPrice: '',
          price: '',
          attrFirstIds: [],
          attrFirstNames: '',
          attrSecodIds: [],
          attrSecodNames: '',
          imgurl: '',
          multifileList: [],
          files: [],
          ztList: [],
          goodsParamList: [],
          attrFirstList: [],
          attrSecodList: []
        },
        // éªŒè¯è§„则
        rules: {
          name: [
            { required: true, message: '不能为空', trigger: 'blur' }
          ],
          categoryId: [
            { required: true, message: '请选择', trigger: 'change' }
          ],
          brandId: [
            { required: true, message: '请选择', trigger: 'change' }
          ],
          zdPrice: [
            { required: true, message: '不能为空', trigger: 'blur' }
          ],
          price: [
            { required: true, message: '不能为空', trigger: 'blur' }
          ]
        },
        options: [],
        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)
          }
        }
      </template>
    </el-form>
  </GlobalWindow>
</template>
<script>
import BaseOpera from '@/components/base/BaseOpera'
import GlobalWindow from '@/components/common/GlobalWindow'
import { brand } from '@/api/system/common.js'
import { findListForGoodsId, create, updateById, companyCreate, companyUpdateById } from '@/api/business/goods.js'
export default {
  name: 'OperaGoodsWindow',
  extends: BaseOpera,
  components: { GlobalWindow },
  data () {
    return {
      action: process.env.VUE_APP_API_PREFIX + '/public/upload',
      name1: '',
      name2: '',
      // è¡¨å•数据
      form: {
        id: null,
        name: '',
        categoryId: '',
        brandId: '',
        zdPrice: '',
        price: '',
        attrFirstIds: [],
        attrFirstNames: '',
        attrSecodIds: [],
        attrSecodNames: '',
        imgurl: '',
        multifileList: [],
        files: [],
        ztList: [],
        goodsParamList: [],
        attrFirstList: [],
        attrSecodList: []
      },
      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: []
            }
          }
        }
      }
    },
    methods: {
      priceCHANEG(val, type) {
        if (!/^[1-9]+[0-9]*$/.test(val)) {
          this.$message.warning('只能输入正整数')
          if (type === 1) {
            this.form.zdPrice = ''
          } else {
            this.form.price = ''
          }
        }
      // éªŒè¯è§„则
      rules: {
        name: [
          { required: true, message: '不能为空', trigger: 'blur' }
        ],
        categoryId: [
          { required: true, message: '请选择', trigger: 'change' }
        ],
        brandId: [
          { required: true, message: '请选择', trigger: 'change' }
        ],
        zdPrice: [
          { required: true, message: '不能为空', trigger: 'blur' }
        ],
        price: [
          { required: true, message: '不能为空', trigger: 'blur' }
        ]
      },
      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) {
              create(this.form)
                .then(() => {
                  this.visible = false
                  this.$tip.apiSuccess('新建成功')
                  this.$emit('success')
                })
                .catch(e => {
                  this.$tip.apiFailed(e)
                })
                .finally(() => {
                  this.isWorking = false
                })
            } else {
              updateById(this.form)
                .then(() => {
                  this.visible = false
                  this.$tip.apiSuccess('编辑成功')
                  this.$emit('success')
                })
                .catch(e => {
                  this.$tip.apiFailed(e)
                })
                .finally(() => {
                  this.isWorking = false
                })
            }
          } else {
            return false;
          }
        });
      },
      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({})
            .then(res => {
              this.brandList = res
            })
        },
        getcategory(type) {
          findListForGoodsId(this.form.id || '')
            .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)
                  }
                })
              }
            })
        }
      options: [],
      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: []
          }
        }
      }
    }
  },
  methods: {
    priceCHANEG(val, type) {
      if (!/^[1-9]+[0-9]*$/.test(val)) {
        this.$message.warning('只能输入正整数')
        if (type === 1) {
          this.form.zdPrice = ''
        } else {
          this.form.price = ''
        }
      }
    },
    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;
        }
      });
    },
    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({})
          .then(res => {
            this.brandList = res
          })
      },
      getcategory(type) {
        findListForGoodsId(this.form.id || '')
          .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)
                }
              })
            }
          })
      }
  }
  </script>
}
</script>
<style lang="scss" scoped>
::v-deep .el-form-item__content {
  .el-input {
    width: 400px;
  }
}
</style>
platform/src/components/business/selectProduct.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,119 @@
<template>
    <GlobalWindow :title="title" :visible.sync="visible" :confirm-working="isWorking" @confirm="confirm">
      <el-form :model="form" ref="form" :rules="rules">
        <el-form-item label="商品类别" prop="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-option>
            </el-select>
        </el-form-item>
        <el-form-item label="商品范围" prop="type">
            <el-radio-group v-model="form.type">
                <el-radio :label="0">全部</el-radio>
                <el-radio :label="1">部分</el-radio>
            </el-radio-group>
        </el-form-item>
        <el-form-item label="加价系数" prop="rate">
          <el-input v-model="form.rate" placeholder="平台采购价*加价系数,作为参考出手价,建议输入大于1的数字" v-trim />
        </el-form-item>
      </el-form>
      <!-- é€‰æ‹©å¹³å°å•†å“ -->
      <selectProductItem ref="selectProductItem" @result="result" />
    </GlobalWindow>
  </template>
  <script>
  import BaseOpera from '@/components/base/BaseOpera'
  import GlobalWindow from '@/components/common/GlobalWindow'
  import selectProductItem from '@/components/business/selectProductItem'
  import { baseCategoryList } from '@/api/business/category.js'
  import { createPlat } from '@/api/business/goods'
  export default {
    name: 'OperaBrandWindow',
    extends: BaseOpera,
    components: { GlobalWindow, selectProductItem },
    data() {
      return {
        categoryList: [],
        // è¡¨å•数据
        form: {
          categoryId: '',
          type: 0,
          rate: ''
        },
        // éªŒè¯è§„则
        rules: {
            categoryId: [
            { required: true, message: '商品类别不能为空', trigger: 'blur' }
          ],
          type: [
            { required: true, message: '商品范围不能为空', trigger: 'blur' }
          ],
          rate: [
            { required: true, message: '加价系数不能为空', trigger: 'blur' }
          ]
        }
      }
    },
    created() {
      this.config({
        api: '/business/anchor',
        'field.id': 'id'
      })
    },
    methods: {
        result() {
          // this.$emit('success')
          this.$emit('result')
          this.visible = false
        },
        confirm() {
            this.$refs.form.validate((valid) => {
                if (!valid) return
                // æ–°å»º
                if (this.form.type == 0) {
                    this.isWorking = true
                    createPlat({
                        categoryId: this.form.categoryId,
                        rate: this.form.rate,
                        type: this.form.type
                    }).then(res => {
                        this.visible = false
                        this.$tip.apiSuccess('操作成功')
                        // this.$emit('success')
                        this.$emit('result')
                    })
                    .catch(e => {
                        this.$tip.apiFailed(e)
                    })
                    .finally(() => {
                        this.isWorking = false
                    })
                } else {
                    this.$refs.selectProductItem.open('选择平台商品', this.form)
                }
            })
        },
        /**
         * æ‰“开窗口
         * @title çª—口标题
         * @target ç¼–辑的对象
         */
        open (title, target) {
            this.title = title
            this.visible = true
            // èŽ·å–åˆ†ç±»åˆ—è¡¨
            baseCategoryList({ type: 1 })
              .then(res => {
                this.categoryList = res
              })
        }
    }
  }
  </script>
platform/src/components/business/selectProductItem.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,183 @@
<template>
    <GlobalWindow :title="title" width="70%" :visible.sync="visible" :confirm-working="isWorking" @confirm="confirm">
        <div class="head">
            <el-form :inline="true" :model="form" class="demo-form-inline">
                <el-form-item label="商品名称" prop="name">
                    <el-input v-model="form.name" placeholder="请输入商品名称"></el-input>
                </el-form-item>
                <el-form-item label="类别" prop="categoryId">
                    <el-select v-model="form.categoryId" disabled placeholder="请选择">
                        <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>
                    <el-button type="primary" @click="getList">查询</el-button>
                </el-form-item>
            </el-form>
        </div>
        <div class="tab">
            <el-table
            :data="tableData"
            stripe
            border
            @selection-change="handleSelectionChange">
                <el-table-column type="selection" width="55"></el-table-column>
                <el-table-column prop="id" label="商品ID" min-width="100px"></el-table-column>
                <el-table-column prop="name" label="商品名称/型号" show-overflow-tooltip min-width="200px">
                    <template slot-scope="{row}">
                    <div style="display: flex; align-items: center;">
                        <div style="width: 70px; height: 70px; flex-shrink: 0;">
                        <el-image
                            v-if="row.imgurl"
                            style="width: 70px; height: 70px"
                            :src="row.fullImgUrl"
                            fit="cover"></el-image>
                        </div>
                        {{ row.name }}
                    </div>
                    </template>
                </el-table-column>
                <el-table-column prop="brandName" label="品牌" show-overflow-tooltip min-width="100px"></el-table-column>
                <el-table-column prop="categoryName" label="类别" show-overflow-tooltip min-width="100px"></el-table-column>
                <el-table-column prop="zdPrice" label="指导价(元)" show-overflow-tooltip min-width="100px"></el-table-column>
                <el-table-column prop="price" label="采购价(元)" show-overflow-tooltip min-width="100px"></el-table-column>
                <el-table-column label="入手价(元)" show-overflow-tooltip min-width="100px">
                    <template slot-scope="{row}">
                        <el-input v-model="row.purchasePrice" placeholder="请输入"></el-input>
                    </template>
                </el-table-column>
            </el-table>
            <el-pagination
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
                :current-page="page"
                :page-sizes="[10, 20, 30]"
                :page-size="pageSize"
                layout="total, sizes, prev, pager, next, jumper"
                :total="total">
            </el-pagination>
        </div>
    </GlobalWindow>
</template>
<script>
import BaseOpera from '@/components/base/BaseOpera'
import GlobalWindow from '@/components/common/GlobalWindow'
import { baseCategoryList } from '@/api/business/category.js'
import { pageT } from '@/api/business/goods'
import { createPlat } from '@/api/business/goods'
export default {
    name: 'OperaBrandWindow',
    extends: BaseOpera,
    components: { GlobalWindow },
    data() {
        return {
            // è¡¨å•数据
            form: {
                categoryId: '',
                type: 0,
                rate: '',
                name: '',
                goodsParamList: []
            },
            pageSize: 10,
            page: 1,
            total: 0,
            tableData: [],
            categoryList: []
        }
    },
    created() {
        this.config({
            api: '/business/anchor',
            'field.id': 'id'
        })
    },
    methods: {
        getList() {
            pageT({
                capacity: this.pageSize,
                model: {
                    categoryId: this.form.categoryId,
                    name: this.form.name
                },
                page: this.page
            }).then(res => {
                res.records.forEach(item => {
                    item.purchasePrice = item.price * this.form.rate
                })
                this.tableData = res.records
                this.total = res.total
            })
        },
        handleCurrentChange(e) {
            this.page = e
            this.getList()
        },
        handleSizeChange(e) {
            this.pageSize = e
            this.getList()
        },
        handleSelectionChange(e) {
            let arr = []
            e.forEach(item => {
                arr.push({ goodsId: item.id, price: item.purchasePrice })
            })
            this.form.goodsParamList = arr
            console.log(arr)
        },
        confirm() {
            // è°ƒç”¨æ–°å»ºæŽ¥å£
            this.isWorking = true
            createPlat({
                categoryId: this.form.categoryId,
                goodsParamList: this.form.goodsParamList,
                rate: this.form.rate,
                type: this.form.type
            }).then(res => {
                this.visible = false
                this.$tip.apiSuccess('操作成功')
                // this.$emit('success')
                this.$emit('result')
            })
            .catch(e => {
                this.$tip.apiFailed(e)
            })
            .finally(() => {
                this.isWorking = false
            })
        },
        /**
         * æ‰“开窗口
         * @title çª—口标题
         * @target ç¼–辑的对象
         */
        open(title, target) {
            this.title = title
            this.visible = true
            this.form.categoryId = target.categoryId
            this.form.rate = Number(target.rate)
            this.form.type = target.type
            // èŽ·å–åˆ†ç±»åˆ—è¡¨
            baseCategoryList({})
                .then(res => {
                    this.categoryList = res
                })
            this.getList()
        }
    }
}
</script>
<style lang="scss" scoped>
    .head {
        width: 100%;
    }
</style>
platform/src/views/business/goods.vue
@@ -1,260 +1,254 @@
<template>
    <TableLayout :permissions="['business:goods:query']">
      <!-- æœç´¢è¡¨å• -->
      <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
        <el-form-item label="商品名称" prop="name">
          <el-input v-model="searchForm.name" placeholder="请输入商品名称" @keypress.enter.native="search"></el-input>
        </el-form-item>
        <el-form-item label="商品ID" prop="id">
          <el-input v-model="searchForm.id" placeholder="请输入商品ID" @keypress.enter.native="search"></el-input>
        </el-form-item>
        <el-form-item label="类别" prop="categoryId">
            <el-select v-model="searchForm.categoryId" clearable placeholder="请选择">
                <el-option
                    v-for="item in categoryList"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id">
                </el-option>
            </el-select>
          <!-- <el-input v-model="searchForm.categoryId" placeholder="请输入所属品类编码" @keypress.enter.native="search"></el-input> -->
        </el-form-item>
        <el-form-item label="品牌" prop="brandId">
            <el-select v-model="searchForm.brandId" clearable placeholder="请选择">
                <el-option
                    v-for="item in brandList"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id">
                </el-option>
            </el-select>
          <!-- <el-input v-model="searchForm.brandId" placeholder="请输入所属品牌编码" @keypress.enter.native="search"></el-input> -->
        </el-form-item>
        <el-form-item label="状态" prop="status">
            <el-select v-model="searchForm.status" clearable placeholder="请选择">
                <el-option
                    v-for="item in statusList"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id">
                </el-option>
            </el-select>
          <!-- <el-input v-model="searchForm.status" placeholder="请输入状态 0启用 1禁用" @keypress.enter.native="search"></el-input> -->
        </el-form-item>
        <section>
          <el-button type="primary" @click="search">搜索</el-button>
          <el-button @click="reset">重置</el-button>
        </section>
      </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>
          <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><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:goods:delete']">删除</el-button></li> -->
        </ul>
        <el-table
          v-loading="isWorking.search"
          :data="tableData.list"
          stripe
          border
          :header-cell-style="rowStyle"
          :cell-style="rowStyle"
        >
          <el-table-column prop="id" label="商品ID" min-width="100px"></el-table-column>
          <el-table-column prop="name" label="商品名称/型号" min-width="200px">
            <template slot-scope="{row}">
              <div style="display: flex; align-items: center;">
                <div style="width: 70px; height: 70px; flex-shrink: 0;">
                  <el-image
                  v-if="row.imgurl"
                  style="width: 70px; height: 70px"
                  :src="row.prefixUrl + row.imgurl"
                  :preview-src-list="[row.prefixUrl + row.imgurl]"
                  fit="cover"></el-image>
                </div>
              {{ row.name }}
  <TableLayout :permissions="['business:goods:query']">
    <!-- æœç´¢è¡¨å• -->
    <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
      <el-form-item label="商品名称" prop="name">
        <el-input v-model="searchForm.name" placeholder="请输入商品名称" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="商品ID" prop="id">
        <el-input v-model="searchForm.id" placeholder="请输入商品ID" @keypress.enter.native="search"></el-input>
      </el-form-item>
      <el-form-item label="类别" prop="categoryId">
        <el-select v-model="searchForm.categoryId" clearable placeholder="请选择">
          <el-option v-for="item in categoryList" :key="item.id" :label="item.name" :value="item.id">
          </el-option>
        </el-select>
        <!-- <el-input v-model="searchForm.categoryId" placeholder="请输入所属品类编码" @keypress.enter.native="search"></el-input> -->
      </el-form-item>
      <el-form-item label="品牌" prop="brandId">
        <el-select v-model="searchForm.brandId" clearable placeholder="请选择">
          <el-option v-for="item in brandList" :key="item.id" :label="item.name" :value="item.id">
          </el-option>
        </el-select>
        <!-- <el-input v-model="searchForm.brandId" placeholder="请输入所属品牌编码" @keypress.enter.native="search"></el-input> -->
      </el-form-item>
      <el-form-item label="状态" prop="status">
        <el-select v-model="searchForm.status" clearable placeholder="请选择">
          <el-option v-for="item in statusList" :key="item.id" :label="item.name" :value="item.id">
          </el-option>
        </el-select>
        <!-- <el-input v-model="searchForm.status" placeholder="请输入状态 0启用 1禁用" @keypress.enter.native="search"></el-input> -->
      </el-form-item>
      <section>
        <el-button type="primary" @click="search">搜索</el-button>
        <el-button @click="reset">重置</el-button>
      </section>
    </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>
        <!-- <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>
        <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> -->
      </ul>
      <el-table v-loading="isWorking.search" :data="tableData.list" stripe border :header-cell-style="rowStyle"
        :cell-style="rowStyle" @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55"></el-table-column>
        <el-table-column prop="id" label="商品ID" min-width="100px"></el-table-column>
        <el-table-column prop="name" label="商品名称/型号" min-width="200px">
          <template slot-scope="{row}">
            <div style="display: flex; align-items: center;">
              <div style="width: 70px; height: 70px; flex-shrink: 0;">
                <el-image v-if="row.imgurl" style="width: 70px; height: 70px" :src="row.prefixUrl + row.imgurl"
                  :preview-src-list="[row.prefixUrl + row.imgurl]" fit="cover"></el-image>
              </div>
            </template>
          </el-table-column>
          <el-table-column prop="brandName" label="品牌" min-width="100px"></el-table-column>
          <el-table-column prop="categoryName" label="类别" min-width="100px"></el-table-column>
          <el-table-column prop="attrFirstNames" label="属性1" min-width="100px"></el-table-column>
          <el-table-column prop="attrSecodNames" label="属性2" min-width="100px"></el-table-column>
          <el-table-column prop="zdPrice" label="指导价(元)" min-width="100px"></el-table-column>
          <el-table-column prop="price" label="入手价(元)" min-width="100px"></el-table-column>
          <el-table-column prop="createDate" label="创建时间" min-width="100px"></el-table-column>
          <el-table-column prop="status" label="状态" min-width="100px">
            <template slot-scope="{row}">
                <el-switch
                    v-model="row.status"
                    @change="changeStatus(row)"
                    active-color="#13ce66"
                    inactive-color="#ff4949"
                    :active-value="0"
                    :inactive-value="1">
                </el-switch>
            </template>
          </el-table-column>
          <el-table-column
            v-if="containPermissions(['business:goods:update', 'business:goods: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>
              <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:goods: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>
      <!-- æ–°å»º/修改 -->
      <OperaGoodsWindow ref="operaGoodsWindow" @success="handlePageChange"/>
    </TableLayout>
  </template>
  <script>
  import BaseTable from '@/components/base/BaseTable'
  import TableLayout from '@/layouts/TableLayout'
  import Pagination from '@/components/common/Pagination'
  import OperaGoodsWindow from '@/components/business/OperaGoodsWindow'
  import { brand, category, importExcel } from '@/api/system/common.js'
  import { updateDisableById, queryById, exportDoc } from '@/api/business/goods.js'
  export default {
    name: 'Goods',
    extends: BaseTable,
    components: { TableLayout, Pagination, OperaGoodsWindow },
    data () {
      return {
        // æœç´¢
        searchForm: {
          id: '',
          name: '',
          status: '',
          categoryId: '',
          brandId: ''
        },
        categoryList: [],
        brandList: [],
        statusList: [
            { name: '启用', id: 0 },
            { name: '禁用', id: 1 }
        ]
              {{ row.name }}
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="brandName" label="品牌" min-width="100px"></el-table-column>
        <el-table-column prop="categoryName" label="类别" min-width="100px"></el-table-column>
        <el-table-column prop="baseZdPrice" label="指导价(元)" min-width="100px"></el-table-column>
        <el-table-column prop="basePrice" label="采购价(元)" min-width="100px"></el-table-column>
        <el-table-column prop="price" label="入手价(元)" min-width="100px"></el-table-column>
        <el-table-column prop="createDate" label="创建时间" min-width="100px"></el-table-column>
        <el-table-column prop="status" label="状态" min-width="100px">
          <template slot-scope="{row}">
            <el-switch v-model="row.status" @change="changeStatus(row)" active-color="#13ce66" inactive-color="#ff4949"
              :active-value="0" :inactive-value="1">
            </el-switch>
          </template>
        </el-table-column>
        <el-table-column v-if="containPermissions(['business:goods:update', 'business:goods: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>
            <el-button type="text" @click="deleteById(row)" icon="el-icon-delete"
              v-permissions="['business:goods: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>
    <!-- æ–°å»º/修改 -->
    <OperaGoodsWindow ref="operaGoodsWindow" @success="handlePageChange" />
    <!-- é€‰æ‹©å¹³å°å•†å“ -->
    <selectProduct ref="selectProduct" @success="handlePageChange" @result="search" />
  </TableLayout>
</template>
<script>
import BaseTable from '@/components/base/BaseTable'
import TableLayout from '@/layouts/TableLayout'
import Pagination from '@/components/common/Pagination'
import OperaGoodsWindow from '@/components/business/OperaGoodsWindow'
import selectProduct from '@/components/business/selectProduct'
import { brand, category, importExcel } from '@/api/system/common.js'
import { updateDisableById, queryById, exportDoc, batchUpdateDisableById } from '@/api/business/goods.js'
export default {
  name: 'Goods',
  extends: BaseTable,
  components: { TableLayout, Pagination, OperaGoodsWindow, selectProduct },
  data() {
    return {
      // æœç´¢
      searchForm: {
        id: '',
        name: '',
        status: '',
        categoryId: '',
        brandId: ''
      },
      ids: '',
      categoryList: [],
      brandList: [],
      statusList: [
        { name: '启用', id: 0 },
        { name: '禁用', id: 1 }
      ]
    }
  },
  created() {
    this.config({
      module: '商品',
      api: '/business/goods',
      'field.id': 'id',
      'field.main': 'name'
    })
    this.search()
    this.getbrand()
    this.getcategory()
  },
  methods: {
    handleSelectionChange(e) {
      let arr = e.map(item => item.id)
      this.ids = arr.join(',')
      console.log(this.ids)
    },
    // æ‰¹é‡ä¸Šä¸‹æž¶
    bulkOperation(type) {
      if (!this.ids) {
        this.$message.warning({ message: '至少选择一项内容' })
        return
      }
    },
    created () {
      this.config({
        module: '商品',
        api: '/business/goods',
        'field.id': 'id',
        'field.main': 'name'
      batchUpdateDisableById({
        ids: this.ids,
        status: type
      }).then(res => {
        this.$message.success({ message: res })
        this.search()
      })
      this.search()
      this.getbrand()
      this.getcategory()
    },
    methods: {
      downloadFile() {
        // window.open(`${process.env.VUE_APP_API_PREFIX}/business/goods/export`)
        exportDoc({})
          .then(response => {
            this.download(response)
          })
          .catch(e => {
            this.$tip.apiFailed(e)
          })
      },
      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)
          })
      },
      changeStatus(item) {
        updateDisableById({
          id: item.id,
          status: item.status
        }).then(res => {
          this.$tip.apiSuccess('更新成功')
        }).finally(() => {
          // this.search()
    downloadFile() {
      exportDoc({})
        .then(response => {
          this.download(response)
        })
      },
      turnNum (nums) {
          for(let i=0;i<nums.length;i++){
            nums[i] = parseInt(nums[i])
          }
          return nums;
        },
        getbrand() {
            brand({})
                .then(res => {
                    this.brandList = res
                })
        },
        getcategory() {
            category({})
                .then(res => {
                    this.categoryList = res
                })
        }
        .catch(e => {
          this.$tip.apiFailed(e)
        })
    },
    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)
        })
    },
    changeStatus(item) {
      updateDisableById({
        id: item.id,
        status: item.status
      }).then(res => {
        this.$tip.apiSuccess('更新成功')
      }).finally(() => {
        // this.search()
      })
    },
    turnNum(nums) {
      for (let i = 0; i < nums.length; i++) {
        nums[i] = parseInt(nums[i])
      }
      return nums;
    },
    getbrand() {
      brand({})
        .then(res => {
          this.brandList = res
        })
    },
    getcategory() {
      category({})
        .then(res => {
          this.categoryList = res
        })
    }
  }
  </script>
}
</script>