ZZJ
2022-04-02 45faaf27722588e92050e2e3eace9b3704377048
首页接口
38个文件已修改
2个文件已添加
2个文件已删除
8078 ■■■■ 已修改文件
src/App.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/Pool/TreeData.ts 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/algorithm.ts 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/area.ts 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/clusterManage.ts 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/device.js 36 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/login.js 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/login.ts 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/product.ts 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Connect.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/IndexHeader.vue 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/Price.vue 71 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/giantTree/zTree/ztree_v3/jquery.ztree.all.js 3036 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/scripts/httpRequest.ts 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/connectUs/components/consult.vue 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/connectUs/index.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/equipmentDetail/components/UnbindBox.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/hashrate/AlgManage/components/AlgCard.vue 45 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/hashrate/AlgManage/index.vue 242 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/hashrate/CameraManage/index.vue 50 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/hashrate/index.vue 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/index/components/banner.vue 44 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/index/components/commendContent.vue 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/index/components/price.vue 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/index/components/productLeft.vue 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/index/components/rightColumn.vue 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/index/components/rightForm.vue 37 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/index/components/rightRrid.vue 31 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/index/components/rightTabs.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/index/index.vue 266 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/manageCenter/index.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/product/components/ProductContent.vue 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/product/components/productCard.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productDetail/components/ConfirmOrder.vue 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productDetail/components/OffpayInstruct.vue 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productDetail/components/PayCard.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productDetail/components/UploadBox.vue 349 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productDetail/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/register/components/ResetPassword.vue 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/search/components/giantTree/zTree/ztree_v3/jquery.ztree.all.js 3032 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test.html 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
vue.config.js 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/App.vue
@@ -152,6 +152,18 @@
  }
}
.limitRow2 {
  word-wrap: break-word;
  // 只要超过宽度就换行,不论中文还是英文
  word-break: break-all;
  // 让文本只能展示两行
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  text-overflow: ellipsis;
}
.gutter {
  background-color: rgb(233, 235, 238);
  padding: 1px;
src/Pool/TreeData.ts
@@ -11,6 +11,8 @@
  getCameraBaseImage
} from '@/api/area'
import {getClusterDevList} from '@/api/clusterManage'
export default class TreeDataPool {
  public openeds: Array<boolean>
  public activeTreeData: Array<object>
@@ -63,6 +65,8 @@
  public cameraNameForBaseImage: string
  public gb28181CameraBaseImage: string
  public baseImageLoading: boolean
  public clusterId: string
  public devId: string
  constructor() {
    this.openeds = [true, true, false]
@@ -102,6 +106,23 @@
    this.cameraNameForBaseImage = ""
    this.gb28181CameraBaseImage = ""
    this.baseImageLoading = false
    this.clusterId = ""
    this.devId = ""
    this.getId()
  }
 async getId(){
      //先拿集群id或设备id
    const res:any = await getClusterDevList()
    if(res.data.clusterList.length > 0) {
      this.clusterId = res.data.clusterList[0].cluster_id
    }
    else {
      this.devId = res.data.devList[0].devId
    }
  }
  setVideoArr(index: number, value: object, vue: any): void {
@@ -338,17 +359,22 @@
  async fetchLocalTree() {
    let params: any = {
      parentId:"",
      searchType: this.searchCamType,
      cameraName: this.searchInput
      cameraName: this.searchInput,
      clusterId:this.clusterId,
      devId:this.devId
      //isPlatform: 1
    }
    if (this.searchFrom == 'cluster') {
      params.isPlatform = 1
    }
    const rsp: any = await getLocalCameraTree(params)
    if (rsp && rsp.success) {
      this.treeData = rsp.data ? rsp.data : []
      this.treeData = rsp.data.treeMenu ? rsp.data.treeMenu : []
      if (this.treeData && this.treeData.length > 0) {
        this.sortTreeData(this.treeData)
      }
src/api/algorithm.ts
@@ -115,4 +115,11 @@
    url: '/saas/api-s/sdk/unInstall',
    method: 'post',
    data
})
// 设备卸载全部算法
export const unInstallAll = (data) => request({
    url: '/saas/api-s/sdk/downloadOrUpgradeAll',
    method: 'post',
    data
})
src/api/area.ts
@@ -1,11 +1,11 @@
import request from "@/scripts/httpRequest";
import qs from "qs";
export const getLocalCameraTree = (query: any) => {
export const getLocalCameraTree = (data: any) => {
  return request({
    url: "/data/api-v/area/localmenu",
    method: "get",
    params: query
    url: "/saas/api-s/area/localmenu",
    method: "post",
    data: data
  });
};
src/api/clusterManage.ts
@@ -127,4 +127,12 @@
    method: "post",
    data
  })
}
//获取集群列表
export const getClusterDevList  = () => {
  return request({
    url: "/saas/api-s/area/getClusterDevList",
    method: "get",
  })
}
src/api/device.js
@@ -7,7 +7,7 @@
*/
export const addDevice = (params) => {
  return request({
    url: "/data/api-d/device/addDevice",
    url: "/sass/api-d/device/addDevice",
    method: "post",
    data: params,
  });
@@ -25,7 +25,7 @@
*/
export const findDevList = (params) => {
  return request({
    url: "/data/api-d/device/findDeviceList",
    url: "/saas/api-d/device/findDeviceListByUser",
    method: "post",
    data: params,
  });
@@ -37,7 +37,7 @@
*/
export const findDevListByUser = () => {
  return request({
    url: "/data/api-d/device/getAllDeviceMenu",
    url: "/saas/api-d/device/getAllDeviceMenu",
    method: "get",
  });
};
@@ -49,7 +49,7 @@
*/
export const unbind = (params) => {
  return request({
    url: "/data/api-d/device/unbind",
    url: "/sass/api-d/device/unbind",
    method: "post",
    data: params,
  });
@@ -58,7 +58,7 @@
// 显示设备详情
export const findDevDetail = (data) => {
  return request({
    url: "/data/api-d/device/show",
    url: "/sass/api-d/device/show",
    method: "post",
    data,
  });
@@ -67,7 +67,7 @@
//回填重启日期
export const getRestartTask = (data) => {
  return request({
    url: "/data/api-d/device/getRestartTask",
    url: "/sass/api-d/device/getRestartTask",
    method: "post",
    data,
  });
@@ -76,7 +76,7 @@
// 设置重启日期
export const setRestartTask = (data) => {
  return request({
    url: "/data/api-d/device/setRestartTask",
    url: "/sass/api-d/device/setRestartTask",
    method: "post",
    data,
  });
@@ -85,7 +85,7 @@
// 设置重启日期
export const restart = (data) => {
  return request({
    url: "/data/api-d/device/restart",
    url: "/sass/api-d/device/restart",
    method: "post",
    data,
  });
@@ -94,7 +94,7 @@
// 检查最新版本
export const checkVersion = (data) => {
  return request({
    url: "/data/api-d/device/checkVersion",
    url: "/sass/api-d/device/checkVersion",
    method: "post",
    data,
  });
@@ -103,7 +103,7 @@
// 更新最新版本
export const updateVersion = (data) => {
  return request({
    url: "/data/api-d/device/updateVersion",
    url: "/sass/api-d/device/updateVersion",
    method: "post",
    data,
  });
@@ -112,7 +112,7 @@
// 获取应用
export const findAllApp = (data) => {
  return request({
    url: "/data/api-d/device/findAllApp",
    url: "/sass/api-d/device/findAllApp",
    method: "post",
    data,
  });
@@ -121,7 +121,7 @@
// 获取算法
export const findAllSdk = (data) => {
  return request({
    url: "/data/api-d/device/findAllSdk",
    url: "/sass/api-d/device/findAllSdk",
    method: "post",
    data,
  });
@@ -130,7 +130,7 @@
// 获取设备性能
export const showSystemStates = (data) => {
  return request({
    url: "/data/api-d/device/showSystemStates",
    url: "/sass/api-d/device/showSystemStates",
    method: "post",
    data,
  });
@@ -139,7 +139,7 @@
// 获取算法资源
export const showProcesses = (data) => {
  return request({
    url: "/data/api-d/device/showProcesses",
    url: "/sass/api-d/device/showProcesses",
    method: "post",
    data,
  });
@@ -148,7 +148,7 @@
// 卸载算法
export const unInstallSdk = (data) => {
  return request({
    url: "/data/api-d/device/unInstallSdk",
    url: "/sass/api-d/device/unInstallSdk",
    method: "post",
    data,
  });
@@ -157,7 +157,7 @@
// 卸载应用
export const unInstallApp = (data) => {
  return request({
    url: "/data/api-d/device/unInstallApp",
    url: "/sass/api-d/device/unInstallApp",
    method: "post",
    data,
  });
@@ -166,7 +166,7 @@
// 升级算法应用
export const installAppSdk = (data) => {
  return request({
    url: "/data/api-d/device/installAppSdk",
    url: "/sass/api-d/device/installAppSdk",
    method: "post",
    data,
  });
@@ -175,7 +175,7 @@
// 获取时间
export const clockInfo = (data) => {
  return request({
    url: "/data/api-d/device/clockInfo",
    url: "/sass/api-d/device/clockInfo",
    method: "post",
    data,
  });
src/api/login.js
@@ -1,11 +1,11 @@
import request from "./index";
import request from "@/scripts/httpRequest";
import qs from "qs";
// 登录
export const tologin = (query) => {
  // let query = 'username=' + user.loginName + '&password=' + user.password
  return request({
    url: "/saas/api-u/user/login",
    url: "/cloud/api-u/user/login",
    method: "post",
    data: qs.stringify(query),
  });
@@ -15,17 +15,17 @@
export const logout = () => {
  // let token = sessionStorage.getItem('loginedInfo') && JSON.parse(sessionStorage.getItem('loginedInfo')).access_token
  return request({
    url: "/saas/api-u/user/logout",
    url: "/cloud/api-u/user/logout",
    method: "post",
  });
};
// 获取验证码
export const getVerifyCode = (query) => {
export const getVerifyCode = (data) => {
  return request({
    url: "/saas/api-u/user/makeVerifyCode",
    method: "get",
    params: query,
    url: "/saas/api-i/saasIndex/sendVerifyCode",
    method: "post",
    data,
  });
};
@@ -125,3 +125,12 @@
    data: qs.stringify(query),
  });
};
//联系我们
export const saveConnectUs = (data) => {
  return request({
    url: "/saas/api-i/saasIndex/saveConnectUs",
    method: "post",
    data,
  });
};
src/api/login.ts
File was deleted
src/api/product.ts
@@ -1,4 +1,4 @@
import request from "./index"
import request from "@/scripts/httpRequest";
import qs from "qs";
// 查询产品中心列表
@@ -41,11 +41,10 @@
// 获取标签字典
// param:type
export const findDicByType = (params: any) => {
export const findDicByType = () => {
    return request({
        url: "/data/api-s/dic/findDicByType",
        url: "/saas/api-s/saasProduct/getProductType?scope=",
        method: "get",
        params: params
    });
};
@@ -80,7 +79,7 @@
*/
export const findAllCenterProduct = (params: any) => {
    return request({
        url: "/data/api-s/product/findAllCenterProduct",
        url: "/saas/api-s/saasProduct/findAllCenterProduct",
        method: "post",
        data: params
    })
@@ -120,7 +119,7 @@
*/
export const getReleaseProduct = (params: any) => {
    return request({
        url: "/data/api-s/product/getAllProductMenu",
        url: "/saas/api-s/saasProduct/getAllProductMenu",
        method: "get",
        params: params
    })
@@ -261,3 +260,37 @@
        params: params
    })
}
//获取轮播图
export const getIndexPics = () => {
    return request({
        url: `/saas/api-i/saasIndex/getIndexPics`,
        method: 'get',
    })
}
//获取产品详情
export const selectProductById = (data: any) => {
    return request({
        url: `/saas/api-s/saasProduct/selectProductById`,
        method: 'post',
        data,
    })
}
//获取推荐算法
export const getIndexModelRecommend = (data: any) => {
    return request({
        url: `/saas/api-i/saasIndex/getIndexModelRecommend`,
        method: 'post',
        data,
    })
}
//获取首页模块
export const getModelList = () => {
    return request({
        url: `/saas/api-i/saasIndex/getModelList`,
        method: 'get',
    })
}
src/components/Connect.vue
@@ -130,12 +130,14 @@
    margin-top: 6px;
    margin-left: 34px;
    color: #0065ff;
    font-size: 12px;
  }
  .des {
    margin-top: 6px;
    margin-left: 34px;
    color: #666666;
    font-size: 12px;
  }
}
@@ -153,6 +155,7 @@
  border-radius: 22px;
  text-align: center;
  line-height: 20px;
  font-size: 14px;
  cursor: pointer;
  &:hover {
src/components/IndexHeader.vue
@@ -3,14 +3,20 @@
    <div class="header" :class="{ showBox: isShow, disOpacity: !opacity }">
      <!-- 右侧 -->
      <div class="left">
        <img class="logo" src="/images/index/LOGO.png" alt="" />
        <div class="title">工业物联网平台</div>
        <router-link to="/">
          <img class="logo" src="/images/index/LOGO.png" alt="" />
        </router-link>
        <router-link to="/">
          <div class="title">工业物联网平台</div>
        </router-link>
        <div class="label"><router-link to="/">首页</router-link></div>
        <div class="label">云服务</div>
        <div class="label">
          <router-link to="/manageCenter">管理中心</router-link>
        </div>
        <div class="label">应用商城</div>
        <div class="label">
          <router-link to="/product">应用商城</router-link>
        </div>
      </div>
      <!-- 左侧 -->
@@ -224,10 +230,12 @@
    .logo {
      margin: 0 7px 0 20px;
      cursor: pointer;
    }
    .title {
      margin-right: 10px;
      cursor: pointer;
    }
    .label {
@@ -334,8 +342,8 @@
  &.showBox .right .el-input {
    position: absolute;
    z-index: 4;
    top: 0;
    right: 158px;
    top: -7px;
    right: 88px;
    width: 300px;
    background-color: #fff;
    ::v-deep input {
@@ -355,7 +363,8 @@
  box-sizing: border-box;
  position: absolute;
  top: 62px;
  right: 158px;
  right: 88px;
  // right: -158px;
  padding: 12px 20px 8px 20px;
  width: 300px;
  background-color: #fff;
@@ -463,8 +472,12 @@
  .logOut {
    margin-top: 20px;
    font-size: 16px;
    color: #0065ff;
    color: #3d3d3d;
    cursor: pointer;
    &:hover {
      color: #0065ff;
    }
  }
}
</style>
src/components/Price.vue
@@ -1,9 +1,10 @@
<template>
  <div class="Price">
    ¥<span class="newPrice">{{ priceNew1 }}</span
    >.00/年
    <span class="oldPrice">¥{{ priceOld1 }}.00/年</span>
  <div class="Price" v-if="priceNew">
    ¥<span class="newPrice">{{ priceN1 }}</span
    >{{ priceN2 }}/年
    <span class="iconSave" v-if="showIcon">省</span>
    <span class="oldPrice">¥{{ priceO1 }}{{ priceO2 }}/年</span>
  </div>
</template>
@@ -11,23 +12,35 @@
export default {
  props: {
    priceNew: {},
    priceOld: {},
    showIcon: {
      default: false,
    },
  },
  computed: {
    priceNew1() {
      if (this.priceNew) {
        return this.priceNew;
      } else {
        return 0;
      }
    },
    priceOld1() {
      if (this.priceOld) {
        return this.priceOld;
      } else {
        return this.priceNew1 * 2;
      }
    },
  data() {
    return {
      priceN1: "",
      priceN2: "",
      priceO1: "",
      priceO2: "",
    };
  },
  created() {
    const priceO = (this.priceNew * 1.2 + "").split(".");
    const priceN = (this.priceNew + "").split(".");
    if (priceN.length > 1) {
      this.priceN1 = priceN[0];
      this.priceN2 = "." + priceN[1];
    } else {
      this.priceN1 = priceN[0];
      this.priceN2 = ".00";
    }
    if (priceO.length > 1) {
      this.priceO1 = priceO[0];
      this.priceO2 = "." + priceO[1];
    } else {
      this.priceO1 = priceO[0];
      this.priceO2 = ".00";
    }
  },
};
</script>
@@ -37,6 +50,12 @@
  margin: 0 20px 0 20px;
  font-size: 14px;
  text-align: left;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  .newPrice {
    font-size: 30px;
@@ -50,5 +69,17 @@
    color: #999999;
    text-decoration: line-through;
  }
  .iconSave {
    display: inline-block;
    width: 18px;
    height: 18px;
    font-size: 12px;
    color: #fff;
    line-height: 18px;
    text-align: center;
    background: #ff6000;
    border-radius: 2px;
  }
}
</style>
src/components/giantTree/zTree/ztree_v3/jquery.ztree.all.js
Diff too large
src/scripts/httpRequest.ts
@@ -2,7 +2,7 @@
import axios from 'axios'
import qs from 'qs'
import { Notification } from 'element-ui'
// import router from '@/router'
 import router from '@/router'
const Axios = axios.create({
  responseType: 'json',
@@ -99,10 +99,9 @@
        case 401:
          errJson.status = error.response.status
          errJson.message = '未授权,请重新登录(401)'
          window.parent.postMessage({
            msg: "logout"
          }, '*')
          // console.log("标志位:",AuthData.isLoginout)
          router.push({
             path: '/login'
           })
          // if (!AuthData.isLoginout) {
          //   Notification({
          //     title:"",
src/views/connectUs/components/consult.vue
@@ -17,8 +17,8 @@
        label-position="left"
        label-width="100px"
      >
        <el-form-item prop="name" label="您的姓名">
          <el-input v-model="formData.name"></el-input>
        <el-form-item prop="username" label="您的姓名">
          <el-input v-model="formData.username"></el-input>
        </el-form-item>
        <el-form-item prop="phoneNum" label="您的手机号">
@@ -41,37 +41,49 @@
          >
        </el-form-item>
        <el-form-item prop="mail" label="您的邮箱">
          <el-input v-model="formData.mail"> </el-input>
        <el-form-item prop="email" label="您的邮箱">
          <el-input v-model="formData.email"> </el-input>
        </el-form-item>
        <el-form-item label="您的公司">
          <el-input v-model="formData.company"> </el-input>
        </el-form-item>
        <el-form-item prop="detail" label="您想了解什么">
          <el-input v-model="formData.detail" type="textarea" :rows="4">
        <el-form-item prop="contents" label="想了解什么">
          <el-input v-model="formData.contents" type="textarea" :rows="4">
          </el-input>
        </el-form-item>
        <div class="button">提交</div>
        <div class="button" @click="submit">提交</div>
      </el-form>
    </div>
  </div>
</template>
<script>
import { getVerifyCode } from "@/api/login";
import { getVerifyCode, saveConnectUs } from "@/api/login";
export default {
  data() {
    return {
      formData: {
        name: "",
        username: "",
        phoneNum: "",
        verifyCode: "",
        mail: "",
        email: "",
        company: "",
        detail: "",
        contents: "",
      },
      rules: {},
      rules: {
        username: [{ required: true, message: "请输入姓名", trigger: "blur" }],
        phoneNum: [
          { required: true, message: "请输入手机号", trigger: "blur" },
        ],
        verifyCode: [
          { required: true, message: "请输入验证码", trigger: "blur" },
        ],
        email: [{ required: true, message: "请输入邮箱", trigger: "blur" }],
        contents: [
          { required: true, message: "请输入您想了解什么", trigger: "blur" },
        ],
      },
      codeDisabled: false,
      countdown: 60,
      codeMsg: "获取验证码",
@@ -95,18 +107,32 @@
    },
    //获取验证码
    getCode() {
      let loginName = JSON.parse(sessionStorage.getItem("userInfo")).username;
      this.codeDisabled = true;
      this.getValidStr();
      this.timer = setInterval(this.getValidStr, 1000);
      getVerifyCode({ phoneNum: this.formData.phoneNum, type: 1 })
        .then(() => {
          this.gotCode = true;
        })
        .catch((err) => {
          if (err.data) {
            console.log(err);
      getVerifyCode({
        phoneNum: this.formData.phoneNum,
        username: loginName,
      }).then(() => {
        this.gotCode = true;
      });
    },
    submit() {
      this.$refs["userForm"].validate(async (valid) => {
        if (valid) {
          const res = await saveConnectUs(this.formData);
          if (res.success) {
            this.$notify({
              type: "success",
              message: "提交成功!",
            });
          }
        });
        } else {
          return false;
        }
      });
    },
  },
};
src/views/connectUs/index.vue
@@ -8,7 +8,7 @@
          class="navItem"
          :key="index"
          :class="{ active: activeNav == index }"
          @click="activeNav = index"
          @click="jump(index)"
        >
          {{ item }}
        </div>
@@ -31,6 +31,14 @@
  components: {
    consult,
  },
  methods: {
    jump(index) {
      this.activeNav = index;
      if (index == 0) {
        this.$router.push("/");
      }
    },
  },
};
</script>
src/views/equipmentManagement/equipmentDetail/components/UnbindBox.vue
@@ -141,7 +141,7 @@
    position: absolute;
    top: 10px;
    right: 10px;
    font-size: 12px;
    font-size: 1px;
    color: 187, 187, 187;
    cursor: pointer;
  }
src/views/hashrate/AlgManage/components/AlgCard.vue
@@ -1,17 +1,17 @@
<template>
  <div class="AlgCard">
    <img :src="alg.img" alt="" />
    <div class="name">{{ alg.name }}</div>
    <div class="dot" v-if="alg.hasNewVersion"></div>
    <img :src="alg.iconBlob" alt="" />
    <div class="name">{{ alg.sdk_name }}</div>
    <div class="dot" v-if="alg.isUpgrade"></div>
    <!-- 悬停遮罩层 -->
    <div class="version">
      <!-- 有新版本 -->
      <div class="isOld" v-if="alg.hasNewVersion">
      <div class="isOld" v-if="alg.isUpgrade">
        <div class="row">当前版本: {{ alg.version }}</div>
        <div class="row">最新版本: {{ alg.newVersion }}</div>
        <div class="row">最新版本: {{ alg.remoteVersion }}</div>
        <div class="btns">
          <div class="button update">升级</div>
          <div class="button update" @click="update">升级</div>
          <div class="button delete">卸载</div>
        </div>
      </div>
@@ -20,7 +20,7 @@
        <div class="row">当前为最新版本</div>
        <div class="row">{{ alg.version }}</div>
        <div class="btns">
          <div class="button delete">卸载</div>
          <div class="button delete" @click="unInstall">卸载</div>
        </div>
      </div>
    </div>
@@ -28,9 +28,40 @@
</template>
<script>
import { downloadOrUpgrade, unInstall } from "@/api/algorithm";
export default {
  props: {
    alg: {},
    devId: {},
  },
  methods: {
    async update() {
      const res = await downloadOrUpgrade({
        nodeId: this.devId,
        path: this.alg.id,
        userId: JSON.parse(sessionStorage.getItem("userInfo")).id,
      });
      if (res && res.success) {
        this.$notify({
          type: "success",
          message: "操作成功,请稍后",
        });
      }
    },
    async unInstall() {
      const res = await unInstall({
        nodeId: this.devId,
        sdkId: this.alg.id,
        userId: JSON.parse(sessionStorage.getItem("userInfo")).id,
      });
      if (res && res.success) {
        this.$emit("unInstall");
        this.$notify({
          type: "success",
          message: "卸载成功",
        });
      }
    },
  },
};
</script>
src/views/hashrate/AlgManage/index.vue
@@ -6,7 +6,7 @@
      <!-- 收费算法列表 -->
      <div class="label">收费算法</div>
      <div class="payList">
      <div class="payList scroll">
        <div class="algCard" v-for="(item, index) in payAlg" :key="index">
          <img :src="item.logoUrl" alt="" draggable="false" />
          <div class="name">{{ item.productName }}</div>
@@ -15,7 +15,7 @@
      </div>
      <!-- 免费算法列表 -->
      <div class="label">
      <div class="label freeLabel">
        免费算法 <span class="des">从此处拖拽算法图标安装到设备</span>
      </div>
      <div class="freeList">
@@ -40,30 +40,35 @@
    <!-- 右侧算法管理 -->
    <div class="rightList">
      <div class="title">算法管理</div>
      <div class="button update">全部更新</div>
      <div class="button update" @click="updateAll">全部更新</div>
      <!-- 设备 -->
      <div class="equipment" v-for="(item, index) in equipmentArr" :key="index">
        <div class="name">{{ item.name }}</div>
        <div class="name">{{ item.devName }}</div>
        <!-- 算法列表 -->
        <div class="algList">
          <!-- 算法card -->
          <Card
            v-for="(alg, index) in item.algs"
            v-for="(alg, index) in item.sdkList"
            :key="index"
            :alg="alg"
            :devId="item.devId"
            @unInstall="item.sdkList.splice(index, 1)"
          ></Card>
          <!-- 拖拽存放box -->
          <div
            class="dropBox"
            v-if="dragAlg"
            @dragover="dragover($event)"
            @drop="drop(item.algs)"
            @drop="drop(item.sdkList, item.devId)"
          >
            请拖动到此处
          </div>
          <!-- 空算法情况 -->
          <div class="empty" v-if="item.algs.length === 0 && !dragAlg">
          <div
            class="empty"
            v-if="item.sdkList && item.sdkList.length === 0 && !dragAlg"
          >
            <img src="/images/hashrate/算法管理空页面.png" alt="" />
            <div class="des">
              暂未安装算法,从左侧算法中心拖到算法到此处,即可安装
@@ -98,13 +103,14 @@
<script>
import Card from "./components/AlgCard";
import {
  getAllCenterProduct,
  getSdkConfigInfo,
  saveSdkConfig,
  findAllSdk,
  downloadOrUpgrade,
  unInstall,
  unInstallAll,
} from "@/api/algorithm";
export default {
  components: {
@@ -121,148 +127,7 @@
      setting: false,
      payAlg: [],
      freeAlg: [],
      equipmentArr: [
        {
          name: "设备1",
          algs: [
            {
              img: "/images/index/1仰卧检测.png",
              name: "仰卧检测",
              version: "v1.0.0",
              newVersion: "v1.0.0",
              hasNewVersion: false,
            },
            {
              img: "/images/index/11滞留.png",
              name: "滞留",
              version: "v1.0.0",
              newVersion: "v1.0.0",
              hasNewVersion: false,
            },
            {
              img: "/images/index/15戴口罩.png",
              name: "戴口罩",
              version: "v1.0.0",
              newVersion: "v1.0.2",
              hasNewVersion: true,
            },
            {
              img: "/images/index/1仰卧检测.png",
              name: "仰卧检测",
              version: "v1.0.0",
              newVersion: "v1.0.0",
              hasNewVersion: false,
            },
            {
              img: "/images/index/11滞留.png",
              name: "滞留",
              version: "v1.0.0",
              newVersion: "v1.0.0",
              hasNewVersion: false,
            },
            {
              img: "/images/index/15戴口罩.png",
              name: "戴口罩",
              version: "v1.0.0",
              newVersion: "v1.0.2",
              hasNewVersion: true,
            },
            {
              img: "/images/index/1仰卧检测.png",
              name: "仰卧检测",
              version: "v1.0.0",
              newVersion: "v1.0.0",
              hasNewVersion: false,
            },
            {
              img: "/images/index/11滞留.png",
              name: "滞留",
              version: "v1.0.0",
              newVersion: "v1.0.0",
              hasNewVersion: false,
            },
            {
              img: "/images/index/15戴口罩.png",
              name: "戴口罩",
              version: "v1.0.0",
              newVersion: "v1.0.2",
              hasNewVersion: true,
            },
            {
              img: "/images/index/1仰卧检测.png",
              name: "仰卧检测",
              version: "v1.0.0",
              newVersion: "v1.0.0",
              hasNewVersion: false,
            },
            {
              img: "/images/index/11滞留.png",
              name: "滞留",
              version: "v1.0.0",
              newVersion: "v1.0.0",
              hasNewVersion: false,
            },
            {
              img: "/images/index/15戴口罩.png",
              name: "戴口罩",
              version: "v1.0.0",
              newVersion: "v1.0.2",
              hasNewVersion: true,
            },
            {
              img: "/images/index/1仰卧检测.png",
              name: "仰卧检测",
              version: "v1.0.0",
              newVersion: "v1.0.0",
              hasNewVersion: false,
            },
            {
              img: "/images/index/11滞留.png",
              name: "滞留",
              version: "v1.0.0",
              newVersion: "v1.0.0",
              hasNewVersion: false,
            },
            {
              img: "/images/index/15戴口罩.png",
              name: "戴口罩",
              version: "v1.0.0",
              newVersion: "v1.0.2",
              hasNewVersion: true,
            },
          ],
        },
        {
          name: "设备2",
          algs: [
            {
              img: "/images/index/1仰卧检测.png",
              name: "仰卧检测",
              version: "v1.0.0",
              newVersion: "v1.0.0",
              hasNewVersion: false,
            },
            {
              img: "/images/index/11滞留.png",
              name: "滞留",
              version: "v1.0.0",
              newVersion: "v1.0.0",
              hasNewVersion: false,
            },
            {
              img: "/images/index/15戴口罩.png",
              name: "戴口罩",
              version: "v1.0.0",
              newVersion: "v1.0.2",
              hasNewVersion: true,
            },
          ],
        },
        {
          name: "设备3",
          algs: [],
        },
      ],
      equipmentArr: [],
      dragAlg: null,
    };
  },
@@ -275,7 +140,7 @@
        variable: "sdkManageConfig",
      });
      if (res && res.success) {
        if (res.data.value === "") {
        if (!res.data.value || res.data.value == "off") {
          this.showSettingBox = true;
        } else {
          this.setting = res.data.value === "on" ? true : false;
@@ -287,16 +152,18 @@
    async getProduct() {
      const res = await getAllCenterProduct({
        page: 1,
        size: 100000,
        size: 1000000,
        inputText: "",
        archType: "",
        gpuType: "",
        productType: 3,
        publishStatus: 1,
        productLabelId: "d0aabaee-8edd-492d-8f43-6b0e0bb6e2dd",
      });
      if (res && res.success) {
        res.data.list.forEach((item) => {
          if (item.productName == "趴伏") {
            console.log(item);
          }
          item.logoUrl = "/httpImage/" + item.logoUrl;
          if (item.priceBase === 0) {
            this.freeAlg.push(item);
@@ -310,6 +177,9 @@
    //获取右侧设备列表
    async getEquipment() {
      const res = await findAllSdk();
      if (res && res.success) {
        this.equipmentArr = res.data;
      }
    },
    //拖拽开始
    dragStart(alg) {
@@ -320,14 +190,24 @@
    dragover(e) {
      e.preventDefault();
    },
    drop(algArr) {
    async drop(algArr, devId) {
      algArr.push({
        img: this.dragAlg.img,
        name: this.dragAlg.name,
        version: "v1.0.0",
        newVersion: "v1.0.0",
        hasNewVersion: false,
        iconBlob: this.dragAlg.logoUrl,
        sdk_name: this.dragAlg.productName,
      });
      const res = await downloadOrUpgrade({
        nodeId: devId,
        path: this.dragAlg.productBaseId,
        userId: JSON.parse(sessionStorage.getItem("userInfo")).id,
      });
      if (res && res.success) {
        this.$notify({
          type: "success",
          message: "操作成功,请稍后",
        });
      }
      this.dragAlg = null;
    },
    async closeSettingBox() {
@@ -345,7 +225,35 @@
        this.$notify.success({
          message: "配置成功",
        });
        this.showSettingBox = false;
        if (this.setting) {
          this.showSettingBox = false;
        }
      }
    },
    async updateAll() {
      let devArr = [];
      this.equipmentArr.forEach((dev) => {
        let devObj = {};
        let sdkIds = [];
        devObj.devId = dev.devId;
        dev.sdkList.forEach((sdk) => {
          if (sdk.isUpgrade) {
            sdkIds.push(sdk.id);
          }
        });
        devObj.sdkIds = sdkIds;
        devArr.push(devObj);
      });
      const res = await unInstallAll({
        userId: JSON.parse(sessionStorage.getItem("userInfo")).id,
        devSdkIds: devArr,
      });
      if (res && res.success) {
        this.$notify({
          type: "success",
          message: "操作成功",
        });
      }
    },
  },
@@ -401,8 +309,14 @@
      }
    }
    .freeLabel {
      margin-top: 20px;
    }
    .payList,
    .freeList {
      max-height: 320px;
      overflow: auto;
      display: flex;
      flex-wrap: wrap;
@@ -410,7 +324,7 @@
        box-sizing: border-box;
        margin-right: 10px;
        margin-bottom: 16px;
        width: 95px;
        width: 90px;
        height: 144px;
        border: 1px solid #e9ebee;
        border-radius: 5px;
@@ -621,7 +535,7 @@
  .mask {
    position: absolute;
    top: 0;
    top: 62px;
    left: 0;
    right: 0;
    bottom: 0;
src/views/hashrate/CameraManage/index.vue
@@ -2,7 +2,7 @@
  <div class="CameraManage">
    <div class="cluster">
      <div class="title">集群选择</div>
      <el-select v-model="cluster" placeholder="请选择">
      <el-select v-model="cluster" placeholder="请选择" @change="selectCluster">
        <el-option
          v-for="item in clusterArr"
          :key="item.value"
@@ -51,6 +51,8 @@
import CameraRules from "./CameraRules";
import VideoRuleData from "@/Pool/VideoRuleData";
import { getClusterDevList } from "@/api/clusterManage";
import bus from "@/plugin/bus";
export default {
  components: {
@@ -62,16 +64,7 @@
  data() {
    return {
      activeTab: "信息维护",
      clusterArr: [
        {
          value: 0,
          label: "集群一",
        },
        {
          value: 1,
          label: "集群二",
        },
      ],
      clusterArr: [],
      cluster: "",
      intervalTimer: null,
      leftWith: 0,
@@ -130,6 +123,7 @@
    },
  },
  created() {
    this.getCluster();
    this.PollData.statistics();
    this.TreeDataPool.readonly = false;
@@ -194,6 +188,40 @@
        }
      }
    },
    async getCluster() {
      const res = await getClusterDevList();
      console.log(res);
      if (res && res.success) {
        res.data.clusterList.forEach((item) => {
          this.clusterArr.push({
            label: item.cluster_name,
            value: "0$$" + item.cluster_id,
          });
        });
        res.data.devList.forEach((item) => {
          this.clusterArr.push({
            label: item.devName,
            value: "1$$" + item.devId,
          });
        });
        this.cluster = this.clusterArr[0].value;
      }
    },
    selectCluster(val) {
      const arr = val.split("$$");
      console.log(arr);
      if (arr[0] == "0") {
        this.TreeDataPool.clusterId = arr[1];
        this.TreeDataPool.devId = "";
      }
      if (arr[0] == "1") {
        this.TreeDataPool.devId = arr[1];
        this.TreeDataPool.clusterId = "";
      }
      this.TreeDataPool.fetchTreeData();
    },
  },
};
</script>
src/views/hashrate/index.vue
@@ -12,6 +12,7 @@
import Banner from "@/views/hashrate/components/Banner";
import Flow from "@/views/hashrate/components/Flow";
import Footer from "@/components/Footer";
export default {
  components: {
    IndexHeader,
@@ -23,11 +24,13 @@
</script>
<style lang="scss" scoped>
.hashrate {
  .IndexHeader {
    ::v-deep .header {
      position: absolute;
    }
.IndexHeader {
  ::v-deep .header {
    position: fixed;
    z-index: 2;
    top: 0;
    right: 0;
    left: 0;
  }
}
</style>
src/views/index/components/banner.vue
@@ -7,14 +7,19 @@
      arrow="never"
      ref="banner"
    >
      <el-carousel-item v-for="item in 4" :key="item">
        <div class="banner_content">
          <div class="banner_text">
            <div class="banner_title_en">SmartAI</div>
            <div class="banner_title_zh">人工智能操作系统</div>
            <div class="banner_des">为行业客户量身打造的企业级AI操作系统</div>
          </div>
      <el-carousel-item v-for="(item, index) in bannerList" :key="index">
        <div
          class="banner_content"
          :style="{
            // backgroundImage: 'url(' + baseImg + ')',
            backgroundImage: 'url(' + (item.pic ? item.pic : baseImg) + ')',
            backgroundSize: '100% 100%',
            backgroundRepeat: 'no-repeat',
          }"
        >
          <div class="banner_text" v-html="item.name"></div>
        </div>
        <div class="link"></div>
      </el-carousel-item>
    </el-carousel>
  </div>
@@ -23,6 +28,14 @@
<script>
export default {
  name: "Banner",
  props: {
    bannerList: {},
  },
  data() {
    return {
      baseImg: "/images/index/banner.png",
    };
  },
  methods: {
    toggleBanner(i) {
      this.$refs["banner"].setActiveItem(i);
@@ -41,29 +54,12 @@
  top: -62px;
  .banner_content {
    height: 100%;
    background-image: url("/images/index/banner.png");
    padding: 183px 0 0 0;
    .banner_text {
      margin: 0 auto;
      width: 1280px;
      color: #fff;
      .banner_title_en {
        font-size: 24px;
        line-height: 60px;
      }
      .banner_title_zh {
        font-size: 36px;
        font-weight: 700;
        line-height: 48px;
      }
      .banner_des {
        font-size: 14px;
        line-height: 60px;
      }
    }
  }
src/views/index/components/commendContent.vue
@@ -1,24 +1,24 @@
<template>
  <div class="commendContent">
    <div class="refresh"><span class="icon iconfont">&#xe606;</span>换一批</div>
    <div class="refresh" @click="refresh">
      <span class="icon iconfont">&#xe606;</span>换一批
    </div>
    <div
      class="commendTabsItem"
      v-for="(item, index) in commendData"
      :key="index"
    >
      <div class="icon">
        <img :src="item.img" alt="" />
      </div>
      <div class="title">{{ item.title }}</div>
      <div class="des">{{ item.des }}</div>
      <price :priceNew="item.priceNew" :priceOld="item.priceOld"></price>
      <img :src="'http:/' + item.logoUrl" alt="" />
      <div class="title">{{ item.productName }}</div>
      <div class="des limitoRow2">{{ item.description }}</div>
      <price :priceNew="item.priceBase"></price>
      <div class="button">立即购买</div>
    </div>
  </div>
</template>
<script>
import price from "./price.vue";
import price from "@/components/Price.vue";
export default {
  props: {
@@ -28,6 +28,11 @@
  },
  components: {
    price,
  },
  methods: {
    refresh() {
      this.$emit("refresh");
    },
  },
};
</script>
@@ -40,6 +45,9 @@
  margin: 0 auto;
  .commendTabsItem {
    position: relative;
    max-width: 302px;
    height: 332px;
    flex: 1;
    padding-top: 20px;
    text-align: center;
@@ -50,7 +58,8 @@
      margin-right: 0;
    }
    .icon img {
    img {
      height: 96px;
      width: 96px;
    }
@@ -62,13 +71,16 @@
    }
    .des {
      height: 38px;
      margin: 0 20px 20px 20px;
      color: #666666;
      font-size: 14px;
    }
    .button {
      margin-top: 25px;
      position: absolute;
      bottom: 0;
      right: 0;
      width: 100%;
      height: 40px;
      box-shadow: 0px 2px 8px rgba(0, 43, 106, 0.12);
src/views/index/components/price.vue
File was deleted
src/views/index/components/productLeft.vue
@@ -1,14 +1,21 @@
<template>
  <div class="productLeft" :style="{ background: ` url(${data.img})` }">
  <div
    class="productLeft"
    :style="{
      background: ` url(${data.pic})`,
      backgroundSize: '100% 100%',
      backgroundRepeat: 'no-repeat',
    }"
  >
    <div class="inner">
      <div class="title">
        {{ data.title }}
        {{ data.name }}
      </div>
      <div class="des">
        {{ data.des }}
        {{ data.desc }}
      </div>
      <div class="button">
        <router-link :to="data.router">查看全部</router-link>
        <router-link to="/product">查看全部</router-link>
      </div>
    </div>
  </div>
src/views/index/components/rightColumn.vue
@@ -1,26 +1,26 @@
<template>
  <div class="rightColumn">
    <div class="columnItem" v-for="(item, index) in data.product" :key="index">
    <div class="columnItem" v-for="(item, index) in product" :key="index">
      <div class="title">
        <img :src="item.icon" alt="" />
        {{ item.title }}
        <img :src="'/httpImage/' + item.logoUrl" alt="" />
        {{ item.modelName }}
      </div>
      <div class="des">
        {{ item.des }}
      <div class="des limitRow2">
        {{ item.summary }}
      </div>
      <ul class="list">
        <li v-for="(v, i) in item.menu" :key="i">
          <span class="icon iconfont">&#xe60c;</span>{{ v }}
      <ul class="list scroll">
        <li>
          <span class="icon iconfont">&#xe60c;</span>{{ item.description }}
        </li>
      </ul>
      <price :priceNew="item.priceNew" :priceOld="item.priceOld"></price>
      <price :priceNew="item.priceBase"></price>
      <div class="button">立即购买</div>
    </div>
  </div>
</template>
<script>
import price from "@/views/index/components/price";
import price from "@/components/Price.vue";
export default {
  props: {
@@ -30,6 +30,18 @@
  },
  components: {
    price,
  },
  data() {
    return {
      product: [],
    };
  },
  created() {
    if (this.data.product.length > 3) {
      this.product = this.data.product.slice(0, 3);
    } else {
      this.product = this.data.product;
    }
  },
};
</script>
@@ -70,13 +82,16 @@
    }
    .des {
      height: 38px;
      font-size: 14px;
      color: #999;
    }
    .list {
      margin-top: 33px;
      height: 150px;
      margin-top: 10px;
      margin-bottom: 10px;
      height: 170px;
      overflow-y: auto;
      li {
        font-size: 14px;
        color: #666666;
@@ -91,7 +106,7 @@
      }
    }
    .price {
    .Price {
      margin-bottom: 10px;
      margin-left: 0;
    }
src/views/index/components/rightForm.vue
@@ -47,10 +47,12 @@
      </div>
      <div class="price">
        <price :priceOld="priceOld" :priceNew="priceNew"></price>
        <price
          :priceOld="priceOld"
          :priceNew="priceNew"
          :showIcon="true"
        ></price>
      </div>
      <div class="iconSave">省</div>
      <div class="button">立即购买</div>
      <div class="info">
@@ -64,7 +66,7 @@
</template>
<script>
import price from "@/views/index/components/price";
import price from "@/components/Price.vue";
export default {
  props: {
@@ -162,6 +164,17 @@
          width: 44px;
          background-color: #fff;
        }
        ::v-deep
          .el-input-number__increase:hover:not(.is-disabled)
          ~ .el-input
          .el-input__inner:not(.is-disabled),
        ::v-deep
          .el-input-number__decrease:hover:not(.is-disabled)
          ~ .el-input
          .el-input__inner:not(.is-disabled) {
          border-color: #0065ff;
        }
      }
    }
@@ -224,7 +237,6 @@
    .button {
      margin-top: 25px;
      width: 449px;
      height: 40px;
      border: 1px solid #ff6a00;
      font-size: 14px;
@@ -244,6 +256,7 @@
          #ffba4a 100%
        );
        color: #fff;
        border-color: #fff;
      }
    }
@@ -262,20 +275,6 @@
        text-decoration: underline;
        cursor: pointer;
      }
    }
    .iconSave {
      position: absolute;
      top: 218px;
      left: 150px;
      width: 18px;
      height: 18px;
      font-size: 12px;
      color: #fff;
      line-height: 18px;
      text-align: center;
      background: #ff6000;
      border-radius: 2px;
    }
  }
}
src/views/index/components/rightRrid.vue
@@ -1,21 +1,21 @@
<template>
  <div class="rightRrid">
    <div class="gridItem" v-for="(item, index) in data.product" :key="index">
    <div class="gridItem" v-for="(item, index) in product" :key="index">
      <div class="title">
        <img :src="item.icon" alt="" />
        {{ item.title }}
        <img :src="'/httpImage/' + item.logoUrl" alt="" />
        {{ item.modelName }}
      </div>
      <div class="des">
        {{ item.des }}
      <div class="des limitRow2">
        {{ item.description }}
      </div>
      <price :priceNew="item.priceNew" :priceOld="item.priceOld"></price>
      <price :priceNew="item.priceBase"></price>
      <div class="button">立即购买</div>
    </div>
  </div>
</template>
<script>
import price from "@/views/index/components/price";
import price from "@/components/Price.vue";
export default {
  props: {
@@ -25,6 +25,18 @@
  },
  components: {
    price,
  },
  data() {
    return {
      product: [],
    };
  },
  created() {
    if (this.data.product.length > 6) {
      this.product = this.data.product.slice(0, 6);
    } else {
      this.product = this.data.product;
    }
  },
};
</script>
@@ -72,12 +84,13 @@
    .des {
      margin-bottom: 10px;
      height: 35px;
      font-size: 14px;
      color: #666666;
    }
    .price {
      margin-bottom: 10px;
    .Price {
      margin-bottom: 16px;
      margin-left: 0;
    }
src/views/index/components/rightTabs.vue
@@ -230,6 +230,7 @@
        &:hover {
          color: #fff;
          border-color: #fff;
          background: linear-gradient(
            90.78deg,
            #ffba4a 0%,
src/views/index/index.vue
@@ -3,12 +3,21 @@
    <!-- 表头 -->
    <IndexHeader></IndexHeader>
    <!-- 轮播图 -->
    <Banner ref="Banner"></Banner>
    <Banner ref="Banner" :bannerList="bannerList"></Banner>
    <div class="bannerLink" @click="jump"></div>
    <!-- 轮播图控制器 -->
    <ul class="bannerControl">
      <li v-for="i in 4" :key="i" @click="toggleBanner(i)">
        <button class="inner" :class="{ active: activeBanner == i }"></button>
      <li
        v-for="(item, index) in bannerList"
        :key="index"
        @click="toggleBanner(index + 1)"
      >
        <button
          class="inner"
          :class="{ active: activeBanner == index + 1 }"
        ></button>
      </li>
    </ul>
@@ -27,8 +36,8 @@
      <div class="tabs">
        <div
          class="tabItem"
          :class="{ active: activeCommend === 0 }"
          @click="activeCommend = 0"
          :class="{ active: activeCommend === 3 }"
          @click="selecTab(3)"
        >
          <img src="/images/index/算法.png" alt="" />
          <div class="label">算法</div>
@@ -36,8 +45,8 @@
        <div
          class="tabItem"
          :class="{ active: activeCommend === 1 }"
          @click="activeCommend = 1"
          :class="{ active: activeCommend === 4 }"
          @click="selecTab(4)"
        >
          <img src="/images/index/应用.png" alt="" />
          <div class="label">应用</div>
@@ -46,7 +55,10 @@
    </div>
    <!-- tab内容 -->
    <div class="commendTabsContent">
      <commendContent :commendData="commendData"></commendContent>
      <commendContent
        :commendData="commendData"
        @refresh="getRecommend"
      ></commendContent>
    </div>
    <!-- 热门产品 -->
@@ -56,16 +68,28 @@
        class="productItem"
        v-for="(item, index) in productData"
        :key="index"
        :class="{ short: item.type == 1 || item.type == 2 }"
        :class="{ short: item.typeId == 4 || item.typeId == 1 }"
      >
        <productLeft :data="item"></productLeft>
        <rightRrid v-if="item.type == 0" :data="item"></rightRrid>
        <rightColumn v-if="item.type == 1" :data="item"></rightColumn>
        <rightForm v-if="item.type == 2" :data="item"></rightForm>
        <rightTabs v-if="item.type == 3" :data="item"></rightTabs>
        <rightRrid v-if="item.typeId == 3" :data="item"></rightRrid>
        <rightColumn v-if="item.typeId == 4" :data="item"></rightColumn>
        <rightForm v-if="item.typeId == 1" :data="item"></rightForm>
        <rightTabs v-if="item.typeId == 2" :data="item"></rightTabs>
      </div>
      <div
        class="productItem"
        v-for="(item, index) in productData1"
        :key="index"
        :class="{ short: item.typeId == 4 || item.typeId == 1 }"
      >
        <productLeft :data="item"></productLeft>
        <rightForm v-if="item.typeId == 1" :data="item"></rightForm>
        <rightTabs v-if="item.typeId == 2" :data="item"></rightTabs>
      </div>
    </div>
    <Connect></Connect>
    <Connect v-if="showConnect"></Connect>
    <!-- 页尾 -->
    <Footer></Footer>
@@ -86,6 +110,12 @@
import Connect from "@/components/Connect";
import Footer from "@/components/Footer";
import {
  getIndexPics,
  getIndexModelRecommend,
  getModelList,
} from "@/api/product";
export default {
  name: "Index",
  components: {
@@ -102,7 +132,15 @@
    Connect,
    Footer,
  },
  created() {
    this.getBanner();
    this.getRecommend();
    this.getModule();
    window.addEventListener("scroll", this.scrollListener);
  },
  destroyed() {
    window.removeEventListener("scroll", this.scrollListener);
  },
  data() {
    return {
      commendCardData: [
@@ -126,140 +164,16 @@
        },
      ], //推荐卡片数据
      activeBanner: 1, //选中的banner
      activeCommend: 0, //选中的推荐tabs
      commendData: [
        {
          img: "/images/index/15戴口罩.png",
          title: "戴口罩",
          des: "对火车驾驶舱的监控视频进行检测,当驾驶人员出现趴伏现象时,将结果记录下来",
          priceNew: "540.00",
          priceOld: "900.00",
        },
        {
          img: "/images/index/1仰卧检测.png",
          title: "仰卧检测",
          des: "对火车驾驶舱的监控视频进行检测,当驾驶人员出现趴伏现象时,将结果记录下来",
          priceNew: "540.00",
          priceOld: "900.00",
        },
        {
          img: "/images/index/11滞留.png",
          title: "滞留",
          des: "对火车驾驶舱的监控视频进行检测,当驾驶人员出现趴伏现象时,将结果记录下来",
          priceNew: "540.00",
          priceOld: "900.00",
        },
        {
          img: "/images/index/34跌倒.png",
          title: "跌倒",
          des: "对火车驾驶舱的监控视频进行检测,当驾驶人员出现趴伏现象时,将结果记录下来",
          priceNew: "540.00",
          priceOld: "900.00",
        },
      ], //推荐tab的数据
      productData: [
        {
          router: "/product",
          type: 0,
          img: "/images/index/AI爆款.png",
          title: "AI爆款",
          des: "精心挑选的热门算法及应用,总有一款适合你",
          product: [
            {
              icon: "/images/index/20睡岗.png",
              title: "睡岗",
              des: "对火车驾驶舱的监控视频进行检测,当驾驶人员出现趴伏现象时,将结果记录下来",
              priceNew: "540.00",
              priceOld: "900.00",
            },
            {
              icon: "/images/index/13滞留.png",
              title: "滞留",
              des: "对火车驾驶舱的监控视频进行检测,当驾驶人员出现趴伏现象时,将结果记录下来",
              priceNew: "540.00",
              priceOld: "900.00",
            },
            {
              icon: "/images/index/1仰卧检测.png",
              title: "仰卧检测",
              des: "对火车驾驶舱的监控视频进行检测,当驾驶人员出现趴伏现象时,将结果记录下来",
              priceNew: "540.00",
              priceOld: "900.00",
            },
            {
              icon: "/images/index/34跌倒.png",
              title: "跌倒",
              des: "对火车驾驶舱的监控视频进行检测,当驾驶人员出现趴伏现象时,将结果记录下来",
              priceNew: "540.00",
              priceOld: "900.00",
            },
            {
              icon: "/images/index/15戴口罩.png",
              title: "戴口罩",
              des: "对火车驾驶舱的监控视频进行检测,当驾驶人员出现趴伏现象时,将结果记录下来",
              priceNew: "540.00",
              priceOld: "900.00",
            },
            {
              icon: "/images/index/28玩手机.png",
              title: "玩手机",
              des: "对火车驾驶舱的监控视频进行检测,当驾驶人员出现趴伏现象时,将结果记录下来",
              priceNew: "540.00",
              priceOld: "900.00",
            },
          ],
        },
      activeCommend: 3, //选中的推荐tabs
      commendData: [], //推荐tab的数据
      productData: [],
      productData1: [
        {
          router: "/",
          type: 1,
          img: "/images/index/管理中心.png",
          title: "管理中心",
          des: "性价比超高的管理中心,刚需产品一键购齐,不仅省钱还省心",
          product: [
            {
              icon: "/images/index/比对库管理.png",
              title: "比对库管理",
              des: "对所有联网的设备进行全方位管理",
              menu: [
                "支持设备的基本信息、硬件信息、资源情况、安装的算法/应用等功能监管",
                "支持对设备进行重启、系统清理等操作",
              ],
              priceNew: "540.00",
              priceOld: "900.00",
            },
            {
              icon: "/images/index/数据推送.png",
              title: "数据推送",
              des: "对所有联网的设备进行全方位管理",
              menu: [
                "支持设备的基本信息、硬件信息、资源情况、安装的算法/应用等功能监管",
                "支持对设备进行重启、系统清理等操作",
                "支持对设备进行重启、系统清理等操作",
              ],
              priceNew: "540.00",
              priceOld: "900.00",
            },
            {
              icon: "/images/index/统计查询.png",
              title: "统计查询",
              des: "对所有联网的设备进行全方位管理",
              menu: [
                "支持设备的基本信息、硬件信息、资源情况、安装的算法/应用等功能监管",
                "支持对设备进行重启、系统清理等操作",
              ],
              priceNew: "540.00",
              priceOld: "900.00",
            },
          ],
        },
        {
          router: "/",
          type: 2,
          img: "/images/index/云服务.png",
          title: "云服务",
          des: "一键购买,开启AI应用之旅",
          typeId: 1,
          pic: "/images/index/云服务.png",
          name: "云服务",
          desc: "一键购买,开启AI应用之旅",
          product: {
            title: "AI-0",
            menu: [
@@ -296,10 +210,10 @@
        {
          router: "/",
          type: 3,
          img: "/images/index/边缘计算设备.png",
          title: "边缘计算设备",
          des: "一种部署在近场侧的高可用的软硬一体产品,提升应用程序的快速响应能力、节省带宽流量成本",
          typeId: 2,
          pic: "/images/index/边缘计算设备.png",
          name: "边缘计算设备",
          desc: "一种部署在近场侧的高可用的软硬一体产品,提升应用程序的快速响应能力、节省带宽流量成本",
          product: [
            {
              name: "边缘计算设备1",
@@ -450,6 +364,8 @@
      ], // 热门产品数据
      timer: null, //向上回滚动画
      ConnectTimer: null, // 控制弹层的定时器
      bannerList: [],
      showConnect: false, //显示联系我们与回到顶部
    };
  },
  methods: {
@@ -457,6 +373,46 @@
    toggleBanner(i) {
      this.activeBanner = i;
      this.$refs["Banner"].toggleBanner(i);
    },
    //获取轮播图
    async getBanner() {
      const res = await getIndexPics();
      if (res.success) {
        this.bannerList = res.data.lists;
      }
    },
    //轮播图跳转连接
    jump() {
      window.open(this.bannerList[this.activeBanner - 1].url);
    },
    //获取推荐列表
    async getRecommend() {
      const res = await getIndexModelRecommend({ typeId: this.activeCommend });
      this.commendData = res.data.productList;
    },
    // 获取产品列表
    async getModule() {
      const res = await getModelList();
      if (res && res.success) {
        this.productData = res.data.modelList;
      }
    },
    //选择推荐tab
    selecTab(id) {
      this.activeCommend = id;
      this.getRecommend();
    },
    //添加滚动监听
    scrollListener() {
      //页面滑动触发事件 (滚动条移动则调用是否显示返回顶部按钮事件)
      if (document.documentElement.scrollTop < 1100) {
        this.showConnect = false;
      } else {
        this.showConnect = true;
      }
      //检查滚动条是否在顶部,控制返回顶部按钮的隐藏和显示
    },
  },
};
@@ -505,6 +461,14 @@
    }
  }
  .bannerLink {
    top: 60px;
    position: absolute;
    width: 100%;
    height: 410px;
    cursor: pointer;
  }
  .overCard {
    position: absolute;
    top: 394px;
src/views/manageCenter/index.vue
@@ -19,11 +19,10 @@
            class="productItem"
            v-for="(item, index) in productList"
            :key="index"
            @click="jump(item.path)"
          >
            <router-link :to="item.path">
              <img :src="item.icon" alt="" />
              <div class="name">{{ item.name }}</div>
            </router-link>
            <img :src="item.icon" alt="" />
            <div class="name">{{ item.name }}</div>
          </div>
        </div>
      </div>
@@ -852,6 +851,9 @@
      let myChart = echarts.init(pieDom);
      myChart.setOption(this.pieOption);
    },
    jump(path) {
      this.$router.push(path);
    },
    refrash() {},
    handleSizeChange() {},
  },
src/views/product/components/ProductContent.vue
@@ -13,9 +13,9 @@
            size="mini"
            v-for="(item, index) in types"
            :key="index + 't'"
            :class="productLabelId == item.id ? 'selected' : ''"
            :class="productLabelId == item.productType ? 'selected' : ''"
            class="type-label"
            @click="selectType(item.id)"
            @click="selectType(item.productType)"
            >{{ item.name }}</el-button
          >
        </div>
@@ -59,7 +59,7 @@
        :data="item"
        v-for="(item, index) in dataList"
        :key="index"
        :labels="getLabel(item.productLabelId)"
        :labels="getLabel(item.productType)"
      >
      </productCard>
    </div>
@@ -76,15 +76,7 @@
</template>
<script>
import {
  findAllCenterProduct,
  findDicByType,
  // getReleaseProduct,
} from "@/api/product";
// import { activeByCode, showDetail } from "../api/code";
// import { findDevListByUser } from "../api/device";
// import { addShopcartProd, resumeOrder } from "../api/shopcart";
// import request from "../api/index";
import { findAllCenterProduct, findDicByType } from "@/api/product";
import productCard from "@/views/product/components/productCard";
export default {
  mounted() {
@@ -106,7 +98,7 @@
        { id: "bitmain", name: "bitmain" },
      ],
      targetPlatformId: "all",
      productLabelId: "",
      productLabelId: 0,
      elvChip: "all",
      size: 12,
      publishStatus: 1,
@@ -121,27 +113,14 @@
  },
  methods: {
    getDic() {
      findDicByType()
        .then((res) => {
          let dics = res.data.dics.filter(
            (item) => item.type === "PRODUCTLABEL"
          );
          this.types = dics;
          this.types.unshift({
            id: "",
            name: "全部",
          });
          this.labelDics = res.data.dics;
        })
        .catch((err) => {
          console.log(err);
          this.$notify({
            type: "error",
            message: "标签获取失败",
            duration: 2500,
            offset: 57,
          });
      findDicByType().then((res) => {
        this.types = res.data.list;
        this.types.unshift({
          productType: 0,
          name: "全部",
        });
        this.labelDics = res.data.list;
      });
    },
    selectType(id) {
      this.productLabelId = id;
@@ -156,7 +135,6 @@
      this.getProductList();
    },
    getProductList(v) {
      console.log("--------------");
      let param = {
        page: v === 1 ? 1 : this.page,
        size: this.size,
@@ -164,7 +142,7 @@
        archType: this.targetPlatformId == "all" ? "" : this.targetPlatformId,
        gpuType: this.elvChip == "all" ? "" : this.elvChip,
        publishStatus: this.publishStatus,
        productLabelId: this.productLabelId,
        productType: this.productLabelId,
      };
      findAllCenterProduct(param)
        .then((res) => {
@@ -189,14 +167,12 @@
          });
        });
    },
    getLabel(ids) {
    getLabel(id) {
      let arr = [];
      ids.forEach((id) => {
        let obj = this.labelDics.filter((item) => item.id == id);
        if (obj.length > 0) {
          arr.push(obj[0].name);
        }
      });
      let obj = this.labelDics.filter((item) => item.productType == id);
      if (obj.length > 0) {
        arr.push(obj[0].name);
      }
      return arr;
    },
    refresh(page) {
src/views/product/components/productCard.vue
@@ -40,7 +40,7 @@
      this.$router.push({
        path: "/productDetail",
        query: {
          name: this.data.productName,
          id: this.data.id,
        },
      });
    },
src/views/productDetail/components/ConfirmOrder.vue
@@ -182,15 +182,40 @@
        </div>
      </div>
    </el-dialog>
    <div class="offerpay" v-if="showOffpayInstruct || showUploadBox">
      <OffpayInstruct
        v-if="showOffpayInstruct"
        @close="showOffpayInstruct = false"
        :offerData="{ username: username, sum: sum, orderId: orderId }"
        @confirm="confirmOrder"
      ></OffpayInstruct>
      <UploadBox
        :orderId="orderId"
        @close="showUploadBox = false"
        @back="back"
        v-if="showUploadBox"
      >
      </UploadBox>
    </div>
    <div class="mask" v-if="showOffpayInstruct || showUploadBox"></div>
  </div>
</template>
<script>
import { getOrderById } from "@/api/product";
import { resumePay } from "@/api/order";
import OffpayInstruct from "@/views/productDetail/components/OffpayInstruct";
import UploadBox from "@/views/productDetail/components/UploadBox";
export default {
  props: {
    orderId: {},
  },
  components: {
    OffpayInstruct,
    UploadBox,
  },
  data() {
    return {
@@ -202,6 +227,8 @@
      username: "",
      offPayInstruVisible: false,
      onlinePayVisible: false,
      showOffpayInstruct: false,
      showUploadBox: false,
    };
  },
  computed: {
@@ -232,13 +259,20 @@
      this.payWay = payway;
    },
    forPay() {
      if (!this.policyChecked) {
        this.$notify({
          type: "error",
          message: "请确认用户条款",
        });
        return;
      }
      let orderId = this.orderId;
      let payMethod = this.payWay;
      let _this = this;
      if (this.orderInfo.orderMoney == 0) {
        resumePay({ orderId, payMethod: 5 }).then((res) => {
          if (res.success) {
            this.$router.replace("/Layout/ManageOrder");
            //  this.$router.replace("/Layout/ManageOrder");
          }
        });
        return;
@@ -255,7 +289,7 @@
        resumePay({ orderId, payMethod: 1 })
          .then((res) => {
            if (res.success) {
              this.offPayInstruVisible = true;
              this.showOffpayInstruct = true;
            }
          })
          .catch((e) => {
@@ -278,6 +312,14 @@
    },
    close() {
      this.$emit("close");
    },
    confirmOrder() {
      this.showOffpayInstruct = false;
      this.showUploadBox = true;
    },
    back() {
      this.showOffpayInstruct = true;
      this.showUploadBox = false;
    },
  },
};
@@ -399,6 +441,54 @@
      }
    }
  }
  .btns {
    position: absolute;
    right: 20px;
    bottom: 20px;
    display: flex;
    justify-content: end;
    text-align: center;
    line-height: 40px;
    .confirm {
      margin-left: 10px;
      width: 104px;
      height: 40px;
      background: #0065ff;
      color: #fff;
    }
    .cancel {
      width: 104px;
      height: 40px;
      border: 1px solid #0065ff;
      color: #0065ff;
    }
  }
  .offerpay {
    position: fixed;
    top: 50%;
    left: 50%;
    margin-top: -331px;
    margin-left: -223px;
    width: 446px;
    height: 662px;
    background: #ffffff;
    z-index: 2;
  }
  .mask {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: #000000;
    opacity: 0.2;
    z-index: 1;
  }
}
</style>
src/views/productDetail/components/OffpayInstruct.vue
New file
@@ -0,0 +1,165 @@
<template>
  <div class="OffpayInstruct">
    <div class="title">线下汇款说明</div>
    <div class="close iconfont" @click="close">&#xe60f;</div>
    <el-tooltip placement="left">
      <div slot="content">
        说明:<br />
        ·点击关闭按钮,关闭此信息弹窗,在确认<br />订单页面可以选择其他付款方式继续付款;<br />
        ·如果不选择其他付款方式,关闭确认订单<br />页面,在我的订单中可以看到此订单状态为<br />“未付款”,支付方式为“汇款”;<br />
        ·如果重新选择了支付宝,则订单中的支付<br />方式更新为支付宝。
      </div>
      <div class="tip iconfont">&#xe631;</div>
    </el-tooltip>
    <div class="content">
      <p>请将款项汇入以下银行账户</p>
      <div class="info">
        <div class="itfoRow">
          <div class="label">开户银行:</div>
          <div class="data">北京银行太阳宫支行</div>
        </div>
        <div class="itfoRow">
          <div class="label">账户:</div>
          <div class="data">2000 0031 2025 0000 9136 746</div>
        </div>
        <div class="itfoRow">
          <div class="label">开户行行号:</div>
          <div class="data">3131 0000 1792</div>
        </div>
        <div class="itfoRow">
          <div class="label">款项:</div>
          <div class="data">北京银行太阳宫支行</div>
        </div>
      </div>
      <div class="userInfo">您的登录用户名:{{ offerData.username }}</div>
      <div class="userInfo">您的订单号:{{ offerData.orderId }}</div>
      <div class="des">
        <div class="label">注意事项:</div>
        <div>1.请在转账是务必提供用户名和订单编号;</div>
        <div>
          2.转账后,请务必点击“上传凭证”按钮提交转账信息,以便财务确认,财务确
          认时间为提交后额1~3个工作日;
        </div>
        <div>3.您可以在“我的订单”点击【提交付款凭证】,查看本页中的内容</div>
      </div>
    </div>
    <div class="btns">
      <div class="button cancel" @click="close">取消</div>
      <div class="button confirm" @click="confirm">上传凭证</div>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    offerData: {},
  },
  methods: {
    close() {
      this.$emit("close");
    },
    confirm() {
      this.$emit("confirm");
    },
  },
};
</script>
<style lang="scss" scoped >
.OffpayInstruct {
  .title {
    box-sizing: border-box;
    padding: 20px;
    height: 64px;
    border-bottom: 1px solid #e9ebee;
    font-size: 18px;
    font-weight: 700;
  }
  .close {
    position: absolute;
    top: 20px;
    right: 20px;
    font-size: 16px;
    color: #666;
    cursor: pointer;
  }
  .tip {
    position: absolute;
    top: 20px;
    right: 40px;
    font-size: 16px;
    color: #dbdbdb;
    cursor: pointer;
  }
  .content {
    box-sizing: border-box;
    padding: 30px 20px 20px 20px;
    font-size: 14px;
    p {
      font-size: 16px;
      margin-bottom: 16px;
    }
    .info {
      box-sizing: border-box;
      margin-bottom: 16px;
      padding: 20px 20px 4px 20px;
      background: #f3f3f3;
      .itfoRow {
        display: flex;
        margin-bottom: 16px;
        .label {
          width: 108px;
          color: #666666;
        }
      }
    }
    .userInfo {
      margin-top: 8px;
    }
    .des {
      margin-top: 30px;
      padding: 30px 0;
      color: #ff4a32;
      line-height: 20px;
      border-top: 1px solid #e9ebee;
      border-bottom: 1px solid #e9ebee;
    }
  }
  .btns {
    position: absolute;
    right: 20px;
    bottom: 20px;
    display: flex;
    justify-content: end;
    text-align: center;
    line-height: 40px;
    .confirm {
      margin-left: 10px;
      width: 112px;
      height: 40px;
      background: #0065ff;
      color: #fff;
    }
    .cancel {
      width: 80px;
      height: 40px;
      border: 1px solid #0065ff;
      color: #0065ff;
    }
  }
}
</style>
src/views/productDetail/components/PayCard.vue
@@ -143,16 +143,6 @@
      >
        <div class="label">授权数量</div>
        <el-input-number
          v-model="cartItem.chCount"
          @change="handleChangeCh"
          :disabled="!data.hasChUnitPrice"
          size="small"
          :min="1"
          :max="16"
          label="描述文字"
        ></el-input-number>
        <span class="desText">最大支持16路</span>
        <el-input-number
          v-model="cartItem.authCount"
          @change="handleChangeAuth"
          :disabled="!data.hasAuthPrice"
src/views/productDetail/components/UploadBox.vue
New file
@@ -0,0 +1,349 @@
<template>
  <div class="UploadBox">
    <div class="title">线下汇款说明</div>
    <div class="close iconfont" @click="close">&#xe60f;</div>
    <div class="content">
      <el-form
        :model="certificateForm"
        ref="certificateForm"
        label-width="118px"
      >
        <div
          v-for="(item, index) in certificateForm.list"
          :key="index"
          class="form-area"
        >
          <div class="text-right" v-if="index != 0">
            <div class="devide-dash"></div>
            <el-button class="btn-remove" @click="removeItem(index)"
              >删除此付款信息</el-button
            >
          </div>
          <el-form-item
            label="付款单位/姓名"
            :prop="`list[${index}].payUser`"
            :rules="[
              {
                required: true,
                message: '请输入付款单位/姓名',
                trigger: 'blur',
              },
            ]"
          >
            <el-input class="h32" v-model="item.payUser"></el-input>
          </el-form-item>
          <el-form-item
            label="付款账号"
            :prop="`list[${index}].payAccount`"
            :rules="[
              { required: true, message: '请输入付款账号', trigger: 'blur' },
            ]"
          >
            <el-input class="h32" v-model="item.payAccount"></el-input>
          </el-form-item>
          <el-form-item
            label="付款金额(元)"
            :prop="`list[${index}].payMoney`"
            :rules="[
              { required: true, message: '请输入付款金额', trigger: 'blur' },
              {
                type: 'number',
                min: 0,
                message: '请输入大于零的数字',
                trigger: 'blur',
              },
            ]"
          >
            <el-input class="h32" v-model.number="item.payMoney">
              <!-- <template slot="append">元</template> -->
            </el-input>
          </el-form-item>
          <el-form-item label="备注" prop="reserved">
            <el-input type="textarea" v-model="item.reserved"></el-input>
          </el-form-item>
          <el-form-item label="付款凭证" prop="pic">
            <el-upload
              class="upload-demo"
              drag
              action="https://jsonplaceholder.typicode.com/posts/"
              :http-request="(param) => definedUpload(param, index)"
              :show-file-list="false"
            >
              <el-image
                class="preview"
                v-if="item.appendix"
                :src="`/httpImage/${item.appendix}`"
                fit="contain"
              ></el-image>
              <div class="el-upload__text">
                <i class="el-icon-plus"></i>
                <span class="words">
                  <em>点击上传</em>
                </span>
              </div>
            </el-upload>
            <i
              class="el-icon-error remove"
              v-if="item.appendix"
              @click="item.appendix = ''"
            ></i>
          </el-form-item>
          <!-- <div class="text-left" v-if="index!=0">
            <el-button
              icon="el-icon-remove"
              type="text"
              style="color:#f90;"
              @click="removeItem(index)"
            >移除</el-button>
          </div>-->
        </div>
        <el-button class="btn-add" @click="addPayInfo">添加付款信息</el-button>
      </el-form>
      <div class="btns">
        <div class="button cancel" @click="back">取消</div>
        <div class="button confirm" @click="saveCertificate">上传凭证</div>
      </div>
    </div>
  </div>
</template>
<script>
import { saveOrderCertificate } from "@/api/order";
import request from "@/scripts/httpRequest";
export default {
  props: {
    offerId: {},
  },
  mounted() {
    this.certificateForm.orderId = this.offerId;
  },
  data() {
    return {
      certificateForm: {
        orderId: "",
        list: [
          {
            id: "",
            payUser: "",
            payAccount: "",
            payMoney: "",
            reserved: "",
            appendix: "",
          },
        ],
      },
      certificateRule: {
        payUser: [
          { required: true, message: "请输入付款单位/姓名", trigger: "blur" },
        ],
        payAccount: [
          { required: true, message: "请输入付款账号", trigger: "blur" },
        ],
        payMoney: [
          { required: true, message: "请输入付款金额", trigger: "blur" },
        ],
      },
    };
  },
  methods: {
    close() {
      this.$emit("close");
    },
    back() {
      this.$emit("back");
    },
    removeItem(index) {
      this.certificateForm.list.splice(index, 1);
    },
    definedUpload(param, index) {
      let _this = this;
      const fd = new FormData();
      fd.append("file", param.file);
      request({
        method: "post",
        url: `/data/api-s/file/upload`,
        data: fd,
      })
        .then((res) => {
          _this.certificateForm.list[index].appendix = res.data.picUrl;
        })
        .catch((err) => {
          this.$notify({
            type: "error",
            message: "上传失败",
            duration: 2500,
            offset: 57,
          });
        });
    },
    saveCertificate() {
      this.$refs["certificateForm"].validate((valid) => {
        if (valid) {
          //校验成功提交凭证
          saveOrderCertificate(this.certificateForm)
            .then((res) => {
              if (res.success) {
                this.$notify({
                  type: "success",
                  message: "保存成功",
                  duration: 2500,
                  offset: 57,
                });
                this.certificateSubmitVisible = false;
                this.close();
              }
            })
            .catch((e) => {
              this.$notify({
                type: "error",
                message: "保存失败,请稍后重试",
                duration: 2500,
                offset: 57,
              });
            });
        } else {
          return false;
        }
      });
    },
    addPayInfo(e) {
      this.certificateForm.list.push(this.newPayInfo());
    },
    newPayInfo() {
      return {
        id: "",
        payUser: "",
        payAccount: "",
        payMoney: "",
        reserved: "",
        appendix: "",
      };
    },
  },
};
</script>
<style lang="scss" scoped >
.UploadBox {
  .title {
    box-sizing: border-box;
    padding: 20px;
    height: 64px;
    border-bottom: 1px solid #e9ebee;
    font-size: 18px;
    font-weight: 700;
  }
  .close {
    position: absolute;
    top: 20px;
    right: 20px;
    font-size: 16px;
    color: #666;
    cursor: pointer;
  }
  .tip {
    position: absolute;
    top: 20px;
    right: 40px;
    font-size: 16px;
    color: #dbdbdb;
    cursor: pointer;
  }
  .content {
    box-sizing: border-box;
    padding: 30px 20px 20px 20px;
    font-size: 14px;
  }
  .btns {
    position: absolute;
    right: 20px;
    bottom: 20px;
    display: flex;
    justify-content: end;
    text-align: center;
    line-height: 40px;
    .confirm {
      margin-left: 10px;
      width: 112px;
      height: 40px;
      background: #0065ff;
      color: #fff;
    }
    .cancel {
      width: 80px;
      height: 40px;
      border: 1px solid #0065ff;
      color: #0065ff;
    }
  }
  .h32 {
    height: 32px;
    line-height: 32px;
    ::v-deep input {
      height: 32px;
    }
    .el-icon-arrow-up {
      line-height: 32px;
    }
    ::v-deep .el-icon-arrow-up {
      height: 32px;
    }
  }
  .btn-add {
    margin-left: 120px;
    width: 88px;
    height: 24px;
    border-radius: 3px;
    background: #0064ff;
    color: #fff;
    padding: 3px 8px;
    font-size: 12px;
  }
}
</style>
<style lang="scss">
.el-upload-dragger {
  width: 120px;
  height: 120px;
  border: 1px dashed #c0c5cc !important;
  border-radius: 3px;
  background: #e9ebee;
  .el-upload__text {
    margin-top: 35px;
    display: flex;
    flex-direction: column;
    i {
      font-size: 28px;
      margin-bottom: 10px;
    }
    .words {
      margin: 0 auto;
      width: 84px;
      height: 34px;
      font-size: 12px;
      font-family: PingFangSC-Regular, PingFang SC;
      font-weight: 400;
      color: #888888;
      line-height: 17px;
    }
    em {
      color: #999;
    }
  }
}
</style>
src/views/productDetail/index.vue
@@ -51,11 +51,12 @@
      let param = {
        page: 1,
        size: 1,
        inputText: this.$route.query.name,
        inputText: "",
        id: this.$route.query.id,
        archType: "",
        gpuType: "",
        publishStatus: 1,
        productLabelId: "",
        productType: 0,
      };
      findAllCenterProduct(param)
        .then((res) => {
src/views/register/components/ResetPassword.vue
@@ -90,7 +90,7 @@
</template>
<script>
import { getVerifyCode } from "@/api/login";
import { getVerifyCode, forgetPwd } from "@/api/login";
import { isPhone, validPassword } from "@/scripts/validate"; // 正则文件
export default {
@@ -181,7 +181,17 @@
        }
      });
    },
    submit() {
    async submit() {
      const res = await forgetPwd({
        phoneNum: this.formData.phoneNum,
        newPwd: this.formData.password,
      });
      if (res && res.success) {
        this.$notify({
          type: "success",
          message: "重置成功",
        });
      }
      this.isReseted = true;
    },
  },
src/views/search/components/giantTree/zTree/ztree_v3/jquery.ztree.all.js
Diff too large
test.html
@@ -37,7 +37,13 @@
    </div>
    
    <script>
   let obj = {
       a:{
           b:{
               c:'c'
           }
       }
   }
    </script>
</body>
</html>
vue.config.js
@@ -33,17 +33,17 @@
        changeOrigin: true,
      },
      "/api": {
        target: "http://192.168.20.10:7004",
        //  target: "http://192.168.20.117:7080",
        // target: "http://192.168.20.10:7004",
        target: "http://192.168.20.174:7070",
        // secure: false,
        changeOrigin: true,
      },
      "/httpImage": {
        //target: "http://bsic.asuscomm.com:7003",
        // target: "http://222.128.87.51:7003",
        //   target: "http://192.168.20.10:7009",
        target: "http://192.168.20.117:7080",
        target: "http://192.168.20.10:7009",
        //  target: "http://192.168.20.117:7080",
        // target: "http://192.168.20.189:7009",
        // target: "http://192.168.20.117:7080",