zxl
2 天以前 aa5973abc2272df6892703cde8c78ee184ad714b
Merge remote-tracking branch 'origin/dev' into dev

# Conflicts:
# manager/src/views/goods/goods-info/goods.vue
6个文件已修改
2个文件已添加
693 ■■■■■ 已修改文件
buyer/public/config.js 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manager/public/config.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manager/src/api/goods.js 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manager/src/api/goodsBanner.js 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manager/src/views/goods/goods-info/goods.vue 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manager/src/views/goodsBanner/index.vue 505 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
manager/src/views/video/VideoList.vue 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
seller/public/config.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
buyer/public/config.js
@@ -3,15 +3,15 @@
   * @description api请求基础路径
   */
  API_DEV: {
    common: "http://127.0.0.1:8890",
    buyer: "http://127.0.0.1:8888",
    seller: "http://127.0.0.1:8889",
    manager: "http://127.0.0.1:8887",
    common: "http://1.95.67.54:888",
    buyer: "http://1.95.67.54:888",
    seller: "http://1.95.67.54:888",
    manager: "http://1.95.67.54:888",
  },
  API_PROD: {
    common: "https://common-api.pickmall.cn",
    buyer: "https://buyer-api.pickmall.cn",
    seller: "https://store-api.pickmall.cn",
    manager: "https://admin-api.pickmall.cn"
    common: "http://1.95.67.54:888",
    buyer: "http://1.95.67.54:888",
    seller: "http://1.95.67.54:888",
    manager: "http://1.95.67.54:888",
  },
};
manager/public/config.js
@@ -7,12 +7,16 @@
    buyer: "http://127.0.0.1:8888",
    seller: "http://127.0.0.1:8889",
    manager: "http://127.0.0.1:8887",
    // seller: "https://myk.9village.cn",
    // common: "https://myk.9village.cn",
    // buyer: "https://myk.9village.cn",
    // manager: "https://myk.9village.cn",
  },
  API_PROD: {
    common: "https://common-api.pickmall.cn",
    buyer: "https://buyer-api.pickmall.cn",
    seller: "https://store-api.pickmall.cn",
    manager: "https://admin-api.pickmall.cn"
    common: "http://1.95.67.54:888",
    buyer: "http://1.95.67.54:888",
    seller: "http://1.95.67.54:888",
    manager: "http://1.95.67.54:888",
  },
  /**
   * @description // 跳转买家端地址 pc端
manager/src/api/goods.js
@@ -1,6 +1,7 @@
// 统一请求路径前缀在libs/axios.js中修改
import { getRequest, postRequest, putRequest, deleteRequest} from '@/libs/axios';
import service from "@/libs/axios";
import {managerUrl} from '@/libs/axios';
//  获取商品品牌分页列表
export const getManagerBrandPage = (params) => {
    return getRequest('/goods/brand/getByPage', params)
@@ -16,6 +17,19 @@
export const addBrand = (params) => {
    return postRequest('/goods/brand', params)
}
//  商品排序
// export const goodsSort = (params) => {
//   return postRequest('/goods/goods/goods/sort', params)
// }
export const goodsSort = (params) => {
  return service({
    baseURL: managerUrl,
    url: "/goods/goods/goods/sort",
    method: "POST",
    data: params
  })
}
// 修改品牌设置
export const updateBrand = (params) => {
    return putRequest(`/goods/brand/${params.id}`, params)
manager/src/api/goodsBanner.js
New file
@@ -0,0 +1,35 @@
// 统一请求路径前缀在libs/axios.js中修改
import service from "@/libs/axios";
import {managerUrl} from '@/libs/axios';
export const add = (params) => {
  return service({
    baseURL: managerUrl,
    url: "/lmk/goods-banner",
    method: "POST",
    data: params
  })
}
export const page = (params) => {
  return service({
    baseURL: managerUrl,
    url: "/lmk/goods-banner/page",
    method: "GET",
    params: params
  })
}
export const update = (params) => {
  return service({
    baseURL: managerUrl,
    url: "/lmk/goods-banner",
    method: "PUT",
    data: params
  })
}
export const deleteBanner = (id) => {
  return service({
    baseURL: managerUrl,
    url: `/lmk/goods-banner/${id}`,
    method: "DELETE",
  })
}
manager/src/views/goods/goods-info/goods.vue
@@ -180,11 +180,30 @@
        >
      </div>
    </Modal>
    <Modal
      title="设置商品排序"
      v-model="showSort"
      :mask-closable="false"
      :width="500"
    >
      <Form ref="underForm" :model="sortForm" :label-width="100">
        <FormItem label="商品排序" prop="reason">
          <InputNumber v-model="sortForm.sort" :min="0" :max="999" clearable style="width: 100%" />
        </FormItem>
      </Form>
      <div slot="footer">
        <Button type="text" @click="showSort= false">取消</Button>
        <Button type="primary" :loading="submitLoading" @click="submitSort"
        >提交</Button
        >
      </div>
    </Modal>
  </div>
</template>
<script>
import { getGoodsListData, upGoods, lowGoods ,getGoodsFirstSkuId,queryExportGoods } from "@/api/goods";
import { getGoodsListData, upGoods, lowGoods ,getGoodsFirstSkuId,queryExportGoods,goodsSort } from "@/api/goods";
import {getSts} from '@/api/file'
import vueQr from "vue-qr";
import {getTags} from "@/api/tag";
@@ -197,6 +216,12 @@
  name: "goods",
  data() {
    return {
      sortForm:{
        goodsId:'',
        sort:0
      },
      showSort:false,
      tagForm:{
        selectTagIds:[],
        goodsId:'',
@@ -317,7 +342,7 @@
          key: "action",
          align: "center",
          fixed: "right",
          width: 220,
          width: 400,
          render: (h, params) => {
            if (params.row.marketEnable == "DOWN") {
              return h("div", [
@@ -359,6 +384,9 @@
                h(
                  "Button",
                  {
                    style: {
                      marginRight: "5px",
                    },
                    props: {
                      type: "info",
                      size: "small",
@@ -444,6 +472,20 @@
                    },
                  },
                  "生成二维码"
                ),                h(
                  "Button",
                  {
                    props: {
                      type: "error",
                      size: "small",
                    },
                    on: {
                      click: () => {
                        this.goodsSort(params.row);
                      },
                    },
                  },
                  "设置商品排序"
                ),h(
                  "Button",
                  {
@@ -472,6 +514,24 @@
    };
  },
  methods: {
    cancelSort(){
      console.log('点击了取消')
      this.showSort = false;
    },
   async submitSort(){
    const response =  await goodsSort(this.sortForm)
    console.log(response)
     this.showSort = false;
     this.getDataList();
    },
    goodsSort(row){
      // this.sortForm = {
      //
      // }
      this.sortForm.goodsId = row.id;
      this.sortForm.sort = row.goodsSort
      this.showSort = true;
    },
    saveTag(){
      this.showUpdateTag = false;
      const form = {
manager/src/views/goodsBanner/index.vue
New file
@@ -0,0 +1,505 @@
<template>
  <div class="activity-management">
    <Card>
      <!-- 搜索表单 -->
      <Form
        ref="searchForm"
        @keydown.enter.native="handleSearch"
        :model="searchForm"
        inline
        :label-width="80"
        class="search-form"
      >
        <FormItem label="商品名称" prop="activityName">
          <Input
            type="text"
            v-model="searchForm.goodsName"
            placeholder="请输入商品名称"
            clearable
            @on-clear="handleSearch"
            style="width: 180px"
          />
        </FormItem>
        <Button
          @click="handleSearch"
          type="primary"
          icon="ios-search"
          class="search-btn"
        >搜索
        </Button>
        <Button
          @click="resetSearch"
          icon="md-refresh"
          style="margin-left: 8px"
        >重置
        </Button>
      </Form>
      <Row class="operation">
        <Button @click="openGoodsBanner" type="primary" icon="md-add">添加推荐</Button>
      </Row>
      <!-- 活动表格 -->
      <Table
        :loading="loading"
        border
        :columns="goodsBannerColum"
        :data="goodsBannerList"
        ref="table"
        class="activity-table"
      >
        <template slot-scope="{ row, index }" slot="canShow">
          <div v-if="row.canShow">
            显示
          </div>
          <div v-else>
            不显示
          </div>
        </template>
        <template slot-scope="{ row, index }" slot="showBannerUrl">
          <img :src="row.showBannerUrl" style="width: 100%">
        </template>
        <!-- 操作按钮插槽 -->
        <template slot-scope="{ row }" slot="action">
          <div class="action-btns">
<!--            <Button-->
<!--              type="primary"-->
<!--              size="small"-->
<!--              @click="showBanner(row, row.canShow ? '取消推荐' : '推荐')"-->
<!--              :loading="row.recommendLoading"-->
<!--            >-->
<!--              {{ row.canShow ? '取消推荐' : '推荐' }}-->
<!--            </Button>-->
            <Button
              type="info"
              size="small"
              @click="openEdit(row)"
            >编辑
            </Button>
            <Button
              type="error"
              size="small"
              @click="delBanner(row)"
            >删除
            </Button>
          </div>
        </template>
      </Table>
      <Page
        :current="searchForm.pageNumber"
        :total="total"
        :page-size="searchForm.pageSize"
        @on-change="changePage"
        @on-page-size-change="changePageSize"
        :page-size-opts="[10, 20, 50]"
        size="small"
        show-total
        show-elevator
        show-sizer
      ></Page>
    </Card>
    <Modal
      v-model="goodsBannerShow"
      :title="goodsBannerForm.id?'编辑推荐商品':'添加推荐商品'"
      @on-cancel="goodsBannerShow=false"
      width="1000"
      class="members-modal"
    >
      <Form
        ref="goodsForm"
        :model="goodsBannerForm"
        inline
        :label-width="80"
      >
        <Row :gutter="24">
          <Col span="12">
            <FormItem label="封面上传">
              <div>
                <Upload
                  :before-upload="handleBeforeUpload"
                  action="#">
                  <Button icon="ios-cloud-upload-outline">上传封面</Button>
                </Upload>
              </div>
            </FormItem>
          </Col>
          <Col span="12">
            <div v-if="uploadImg !== null||goodsBannerForm.bannerUrl!=null" style="width: 200px">
              <span v-if="uploadImg!=null" style="text-wrap: nowrap">已上传封面:{{ uploadImg.name }}</span>
              <Button @click="preImg">预览图片</Button>
            </div>
          </Col>
        </Row>
        <Row :gutter="24">
          <Col span="12">
            <FormItem label="是否显示">
              <RadioGroup v-model="goodsBannerForm.canShow">
                <Radio label="true">
                  <span>显示</span>
                </Radio>
                <Radio label="false">
                  <span>不显示</span>
                </Radio>
              </RadioGroup>
            </FormItem>
          </Col>
          <Col span="12">
            <FormItem label="排序">
              <InputNumber v-model="goodsBannerForm.sort" :max="999" :min="0"/>
            </FormItem>
          </Col>
        </Row>
        <Row :gutter="24">
          <Col span="12">
            <FormItem label="商品列表" :label-width="80">
              <Input v-model="searchGoodsForm.keyword" style="width:200px" @on-change="searchGoodsList"></Input>
              <div style="height: 400px;overflow: auto;">
                <div v-for="item in goodsData" :key="item.id" style="display: flex;
                          align-items: center;justify-content: flex-start;border: 1px solid gray;margin-top: 10px;
                          padding: 10px;border-radius: 20px" @click="chooseGoods(item.id)">
                  <div>
                    <img :src="endpoint+'/'+item.thumbnail" style="width: 80px;height: 80px">
                  </div>
                  <div style="display: flex;flex-direction: column;margin-left: 20px">
                    <div style="font-size: 1.5em;font-weight: bold">{{ item.goodsName }}</div>
                    <div style="color: #ff6f6f">
                      ¥{{ item.price }}
                    </div>
                  </div>
                </div>
              </div>
              <Page
                :current="searchGoodsForm.pageNumber"
                :total="goodsTotal"
                :page-size="searchGoodsForm.pageSize"
                @on-change="goodsChangePage"
                @on-page-size-change="goodsChangePageSize"
                :page-size-opts="[10, 20, 50]"
                size="small"
                show-total
              ></Page>
            </FormItem>
          </Col>
          <Col span="12">
            <FormItem label="选中商品" :label-width="80">
              <div style="height: 130px;overflow: hidden;" v-if="goodsBannerForm.skuId">
                <div style="display: flex;
                          align-items: center;justify-content: flex-start;border: 1px solid gray;margin-top: 10px;
                          padding: 10px;border-radius: 20px">
                  <div>
                    <img :src="endpoint+'/'+goodsBannerForm.thumbnail" style="width: 80px;height: 80px">
                  </div>
                  <div style="display: flex;flex-direction: column;margin-left: 20px">
                    <div style="font-size: 1.5em;font-weight: bold">{{ goodsBannerForm.goodsName }}</div>
                    <div style="color: #ff6f6f">
                      ¥{{ goodsBannerForm.price }}
                    </div>
                  </div>
                </div>
              </div>
            </FormItem>
          </Col>
        </Row>
        <Input v-model="flushDom" v-show="false"></Input>
      </Form>
      <div slot="footer">
        <Button @click="goodsBannerShow = false">取消</Button>
        <Button type="primary" :loading="submitLoading" @click="saveOrUpdateGoodsBanner">提交</Button>
      </div>
    </Modal>
    <Modal title="图片预览" v-model="visible">
      <img :src="tempUrl" v-if="visible" style="width: 100%">
    </Modal>
  </div>
</template>
<script>
import {getSts} from "@/api/file";
import COS from "cos-js-sdk-v5";
import {getFileKey} from "@/utils/file";
import {videoGoodsEsPage} from "@/api/videoTag";
import {add, page,update,deleteBanner} from '@/api/goodsBanner'
export default {
  data() {
    return {
      total: 0,
      flushDom: '',
      endpoint: '',
      goodsData: [],
      goodsTotal: 0, // 表单数据总数
      tempUrl: '',
      uploadImg: null,
      fileLoading: false,
      visible: false,
      goodsBannerShow: false,
      submitLoading: false,
      goodsBannerList: [],
      loading: false,
      searchForm: {
        goodsName: '',
        pageSize: 10,
        pageNumber: 1
      },
      goodsBannerForm: {
        id: null,
        goodsId: null,
        skuId: null,
        sort: 0,
        canShow: 'true',
        bannerUrl: null
      },
      searchGoodsForm: {
        // 搜索框初始化对象
        pageNumber: 1, // 当前页数
        pageSize: 10, // 页面大小
        keyword: '',
        searchFromSelfStore: false
      },
      goodsBannerColum: [
        {
          type: 'selection',
          width: 60,
          align: 'center'
        },
        {
          title: '封面图',
          key: 'showBannerUrl',
          slot: 'showBannerUrl',
          minWidth: 100
        },
        {
          title: '商品名称',
          key: 'goodsName',
          minWidth: 120
        }, {
          title: '排序',
          key: 'sort',
          minWidth: 120
        }, {
          title: '是否显示',
          key: 'canShow',
          slot: 'canShow',
          minWidth: 120
        },
        {
          title: '操作',
          slot: 'action',
          width: 280,
          align: 'center',
          fixed: 'right'
        }
      ],
    }
  },
  methods: {
    openEdit(row){
      this.uploadImg = null;
      this.goodsBannerShow = true;
      this.goodsBannerForm = row
      this.goodsBannerForm.canShow  = this.goodsBannerForm.canShow.toString()
      console.log(this.goodsBannerForm,row)
      this.tempUrl = row.showBannerUrl
      this.getGoodsDataList();
    },
    showBanner(row,index){
      console.log(row,index)
    },
   async delBanner(row,index){
     this.$Modal.confirm({
       title: "删除",
       content: "<p>确定要删除吗?</p>",
       onOk: () => {
         deleteBanner(row.id).then((res) => {
           if (res.code==200) {
             this.$Message.success("删除成功");
             this.getGoodsBannerList();
           }
         });
       },
       onCancel: () => {},
     });
    },
    chooseGoods(id) {
      const goods = this.goodsData.find(item => {
        return item.id === id;
      })
      this.flushDom = new Date().toString();
      console.log(goods)
      this.goodsBannerForm.goodsId = goods.goodsId;
      this.goodsBannerForm.skuId = goods.id;
      this.goodsBannerForm.goodsName = goods.goodsName;
      this.goodsBannerForm.thumbnail = goods.thumbnail
      this.goodsBannerForm.price = goods.price
    },
    // 获取列表数据
    getGoodsDataList() {
      let search = this.searchGoodsForm;
      console.log('-------------------------->', this.searchGoodsForm)
      if (search.pageNumber > 0) {
        search.pageNumber = search.pageNumber - 1;
      }
      videoGoodsEsPage(search).then((res) => {
        console.log(res)
        this.loading = false;
        if (res.code == 200) {
          this.goodsData = res.data;
          getSts().then(res => {
            this.endpoint = res.data.endpoint
          })
          this.goodsTotal = res.total;
        }
      });
    },
    searchGoodsList() {
      this.searchGoodsForm.pageNumber = 1;
      this.getGoodsDataList();
    },
    // 分页 改变页码
    goodsChangePage(v) {
      console.log('-------------------------->分页', v);
      this.searchGoodsForm.pageNumber = v;
      this.getGoodsDataList();
    },
    // 分页 改变页数
    goodsChangePageSize(v) {
      this.searchGoodsForm.pageNumber = 1;
      this.searchGoodsForm.pageSize = v;
      this.getGoodsDataList();
    },
    preImg() {
      this.visible = true;
    },
    // 分页 改变页码
    changePage(v) {
      this.searchForm.pageNumber = v;
      this.getGoodsBannerList();
    },
    // 分页 改变页数
    changePageSize(v) {
      this.searchForm.pageNumber = 1;
      this.searchForm.pageSize = v;
      this.getGoodsBannerList();
    },
    async uploadFile() {
      try {
        // this.upLoadVideoLoading = true;
        // 获取文件上传临时密钥
        const sts = await getSts();
        const cos = new COS({
          getAuthorization: async function (options, callback) {
            callback({
              TmpSecretId: sts.data.tmpSecretId,
              TmpSecretKey: sts.data.tmpSecretKey,
              SecurityToken: sts.data.sessionToken,
              // 建议返回服务器时间作为签名的开始时间,避免客户端本地时间偏差过大导致签名错误
              StartTime: sts.data.stsStartTime, // 时间戳,单位秒,如:1580000000
              ExpiredTime: sts.data.stsEndTime,// 时间戳,单位秒,如:1580000000
              ScopeLimit: true, // 细粒度控制权限需要设为 true,会限制密钥只在相同请求时重复使用
            });
          }
        })
        const fileKey = getFileKey(this.uploadImg.name)
        const upData = await cos.uploadFile({
          Bucket: sts.data.bucket,
          Region: sts.data.region,
          Key: fileKey,
          Body: this.uploadImg, // 要上传的文件对象。
          SliceSize: 1024 * 1024 * 5,
          onProgress: function (progressData) {
            console.log('上传进度:', progressData);
          },
        });
        this.goodsBannerForm.bannerUrl = fileKey
        console.log("上传成功", upData)
      } catch (e) {
        console.log("上传失败", e)
      } finally {
        // this.upLoadVideoLoading = false;
      }
      // this.fileLoading = true;
      // this.uploadImg = null;
      // this.fileLoading = false;
      // this.$Message.success('Success')
      console.log("执行文件上次1")
    },
    handleBeforeUpload(file) {
      this.uploadImg = file;
      this.tempUrl = URL.createObjectURL(file);
      console.log(this.tempUrl);
      return false;
    },
    async saveOrUpdateGoodsBanner() {
      if (this.uploadImg){
        await this.uploadFile()
      }
      console.log(this.goodsBannerForm)
      if (!this.goodsBannerForm.skuId) {
        this.$Message.error('请选择商品');
        return;
      }
      if (!this.goodsBannerForm.bannerUrl) {
        this.$Message.error('请上传图片');
        return;
      }
      if (this.goodsBannerForm.id){
        const result = await update(this.goodsBannerForm)
        if (result.code == 200) {
          this.goodsBannerShow = false;
        }
      }else {
        const result = await add(this.goodsBannerForm)
        if (result.code == 200) {
          this.goodsBannerShow = false;
        }
      }
      await  this.getGoodsBannerList();
    },
    openGoodsBanner() {
      this.goodsBannerForm = {
        id: null,
        goodsId: null,
        skuId: null,
        sort: 999,
        canShow: 'true',
        bannerUrl: null
      }
      this.goodsBannerShow = true;
      this.tempUrl = null;
      this.visible = false;
      this.uploadImg = null;
      this.getGoodsDataList();
    },
    async getGoodsBannerList() {
      const pageData = await page(this.searchForm)
      if (pageData.code == 200) {
        this.goodsBannerList = pageData.data
        this.total = pageData.total
      }
    },
    // 重置搜索
    async resetSearch() {
      this.$refs.searchForm.resetFields()
      this.searchForm.pageNumber = 1
      await this.getGoodsBannerList()
    },
    async handleSearch() {
      this.searchForm.pageNumber = 1
      await this.getGoodsBannerList()
    }
  },
  async created() {
    await this.getGoodsBannerList();
  },
}
</script>
<style scoped>
.operation {
  margin-top: 10px;
}
</style>
manager/src/views/video/VideoList.vue
@@ -402,6 +402,9 @@
          <Button type="primary" size="small" style="margin-right: 5px" v-if="row.status === '99'"
                  @click="openAuditing(row)">审核
          </Button>
<!--          <Button type="primary" size="small" style="margin-right: 5px"-->
<!--                  @click="editVideo(row)">编辑-->
<!--          </Button>-->
          <Button type="error" size="small" style="margin-right: 5px" v-if="row.status === '1'"
                  @click="openVideoDown(row)">下架
          </Button>
@@ -704,6 +707,36 @@
    this.getTags('')
  },
  methods: {
    editVideo(row){
      // this.uploadVideoForm = {};
      // this.uploadVideoForm = row;
      // this.showUploadVideoShow = true;
      console.log('------------------->编辑',JSON.stringify(row));
      this.upLoadVideoShow = true;
      this.videoTagList = []
      this.chooseTag = row.tagList
      this.uploadVideoForm = {
        id: '',
        title: '',
        cover: "",
        videoFileKey: "",
        videoDuration: 0,
        videoFit: "cover",
        videoContentType: 'video',
        videoImgs: [],
        showListImages: [],
        tags: [],
        fileInfo: {},
        goodsList: []
      }
      this.uploadVideoForm = row
      recommend({
        searchType: "HOT"
      }).then(res => {
        this.videoTagList = res.data;
      })
      this.searchGoodsList();
    },
    closeGeneralQrCode(){
      this.showGeneralQrCode = false;
      this.QRCodeUrl = '';
seller/public/config.js
@@ -7,12 +7,16 @@
    buyer: "http://127.0.0.1:8888",
    seller: "http://127.0.0.1:8889",
    manager: "http://127.0.0.1:8887",
    // common: "http://1.95.67.54:888",
    // buyer: "http://1.95.67.54:888",
    // seller: "http://1.95.67.54:888",
    // manager: "http://1.95.67.54:888",
  },
  API_PROD: {
    common: "https://common-api.pickmall.cn",
    buyer: "https://buyer-api.pickmall.cn",
    seller: "https://store-api.pickmall.cn",
    manager: "https://admin-api.pickmall.cn",
    common: "http://1.95.67.54:888",
    buyer: "http://1.95.67.54:888",
    seller: "http://1.95.67.54:888",
    manager: "http://1.95.67.54:888",
  },
  /**
   * @description // 跳转买家端地址 pc端