sf
jiangping
2025-04-30 dcdb0231034810232f2542f3865666ebf72daf11
platform/src/views/business/goods.vue
@@ -1,260 +1,227 @@
<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:basegoods: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: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> -->
        <li v-permissions="['business:basegoods:exportExcel', 'business:goods:delete']">
          <ImportButton text="导入" template-name="goods_import_modle.xlsx"
            template-path="/template/goods_import_modle.xlsx" action="/business/baseGoods/importExcel"
            @success="search" />
        </li>
        <li>
          <el-button type="primary" :loading="isWorking.export" @click="bulkOperation(0)">批量上架</el-button>
        </li>
        <li>
          <el-button type="primary" :loading="isWorking.export" @click="bulkOperation(1)">批量下架</el-button>
        </li>
        <li v-permissions="['business:goods:delete']">
          <el-button type="danger" @click="deleteByIdInBatch">批量删除</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.fullImgUrl"
                  :preview-src-list="[row.fullImgUrl]" 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 }
        ]
              <span style="margin-left: 15px">{{ row.name }}</span>
            </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="zdPrice" label="指导价(元)" min-width="100px"></el-table-column>
        <el-table-column prop="jdPrice" 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" v-if="containPermissions(['business:basegoods:update'])" 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: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:basegoods:update']">编辑</el-button>
            <el-button type="text" @click="deleteById(row)" icon="el-icon-delete"
              v-permissions="['business:basegoods:delete']">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
      <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 ImportButton from '@/components/common/ImportButton'
import { brand, baseCategory } 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, ImportButton },
  data() {
    return {
      // 搜索
      searchForm: {
        id: '',
        name: '',
        status: '',
        categoryId: '',
        brandId: ''
      },
      ids: '',
      idList: [],
      categoryList: [],
      brandList: [],
      statusList: [
        { name: '启用', id: 0 },
        { name: '禁用', id: 1 }
      ]
    }
  },
  provide() {
    return {
      brandList: () => this.brandList,
      categoryList: () => this.categoryList
    }
  },
  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(',')
    //   this.idList = arr;
    // },
    // 批量上下架
    bulkOperation(type) {
      if (this.tableData.selectedRows.length === 0) {
        this.$tip.warning('请至少选择一条数据')
        return
      }
    },
    created () {
      this.config({
        module: '商品',
        api: '/business/goods',
        'field.id': 'id',
        'field.main': 'name'
      let idList = this.tableData.selectedRows.map(item => item.id)
      updateStatus({
        idList,
        status: type
      }).then(res => {
        this.$tip.apiSuccess('操作成功');
        // this.$message.success({ message:res.message })
        this.handlePageChange()
      })
      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";
    },
    edit(id) {
      queryById(id)
        .then(res => {
          this.$refs.operaGoodsWindow.open('编辑商品', res)
        })
    },
    changeStatus(item) {
      updateStatus({
        idList: [item.id],
        status: item.status
      }).then(res => {
        this.$tip.apiSuccess('更新成功')
      })
        .catch (err => {
          this.$message.error(err)
        } )
      .finally(() => {
        this.handlePageChange()
      })
    },
    getbrand() {
      brand({ type: 1 })
        .then(res => {
          this.brandList = res
        })
    },
    getcategory() {
      baseCategory({})
        .then(res => {
          this.categoryList = res
        })
    }
  }
  </script>
}
</script>