记录写过的前端功能(搭配element-ui)--方便以后复用

一.53项目

1.1在表单域中展示图片与上传图片

  1. 处理方式一
    1. 展示图片UI
    2. 上传图片UI
    3. 业务代码
      // 模板内容
      // ref="elForm"用来做校验
      <el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="120px">
          <div class="form-container" style="padding: 12px 34px 40px">
              <el-row>
                  <p class="textTitle">店铺信息</p>
                  <el-col :span="12">
                      // 店铺标志的prop值是动态的,当上传图片组件出现时prop就是为图片,消失时就位‘’
                      <el-form-item label="店铺标志:" :prop="this.disabledTypeProp">
                          <!-- <img :src="formData.shopLogo" v-show="pointer === 1" style="width:200px;height:40px" /> -->
                          <span v-if="pointer === 1">
                              <el-image :src="formData.shopLogo" style="width: 200px; height: 40px">
                                  <div slot="error">
                                      <div>
                                          <i class="el-icon-picture-outline"></i>
                                          <div>暂无图片</div>
                                      </div>
                                  </div>
                              </el-image>
                          </span>
                          <div style="display: flex; align-items: center" v-show="pointer === 2">
                              // 使用上传图片组件
                              // ref="upload"用来获取该组件,以便后续操作
                              
                              <avatar-upload
                                  ref="upload"
                                  :disabledType="disabledType"
                                  class="avatar-uploader_logo"
                                  @ok="handleAvatarSuccess"
                                  :img="formData.shopLogo"
                                  :title="'上传照片'"
                                  :Options="cropperOption"
                                  :fileType="4"
                                  Name="storeLogo"
                              ></avatar-upload>
                              <el-button type="text" style="magin-left: 10px; color: #165dff" @click="backImg">恢复默认</el-button>
                          </div>
                          <div v-if="pointer === 2">
                              <span class="el-icon-warning-outline"></span>
                              <span class="tips">*建议上传长度为200px,高度为40px,背景透明的PNG格式图片</span>
                          </div>
                      </el-form-item>
                      <el-form-item label="店铺名称:" prop="shopName" :rules="pointer === 1 ? [] : rules.shopName">
                          <span v-if="pointer === 1">{{ formData.shopName }}</span>
                          <el-input
                              v-if="pointer === 2"
                              v-model="formData.shopName"
                              placeholder="请输入店铺名称"
                              :maxlength="20"
                              clearable
                              :style="{ width: '80%' }"
                          ></el-input>
                      </el-form-item>
                      <el-form-item label="店铺介绍:" prop="shopDesc" :rules="pointer === 1 ? [] : rules.shopDesc">
                          <span v-if="pointer === 1">{{ formData.shopDesc }}</span>
                          <el-input
                              v-if="pointer === 2"
                              v-model="formData.shopDesc"
                              type="textarea"
                              placeholder="店铺介绍"
                              :autosize="{ minRows: 4, maxRows: 4 }"
                              :style="{ width: '80%' }"
                              :maxlength="500"
                          ></el-input>
                      </el-form-item>
                  </el-col>
              </el-row>
          </div>
      </el-form>
      
      
      ————————————————————————————————————
      
      // 脚本内容
      import avatarUpload from '@/components/avatar-upload';
      import { developerService } from '@/api';
      
      components: { avatarUpload },
      data(){
          return {
              formData: {},
              disabledTypeProp: '',
              pointer: 1,
              disabledType: true,
              cropperOption: {
                  autoCropWidth: '200px',
                  autoCropHeight: '40px',
              },
          }
      },
      mounted() {
          // 获取店铺信息,进入路由页面获取数据进行渲染
          this.getShop();
      },
      methods:{
              handleAvatarSuccess(file) {
                  this.formData.shopLogo = file;
              },
              // 恢复默认,通过ref控制组件的imageUrl属性值为‘’。为表单的shopLogo赋值为‘’,用来做必填校验。
              backImg() {
                  this.$refs.upload.imageUrl = '';
                  this.formData.shopLogo = '';
              },
              // 获取店铺信息
              getShop() {
                  developerService
                      .getShopInfo()
                      .then((res) => {
                          if (res.code !== 0) {
                              return this.$message.error(res.msg);
                          }
                          this.formData = res.data;
                      })
                      .catch(() => {});
              },
              // 点击取消按钮,上传组件禁止点击,上传组件消失
              cancel() {
                  this.disabledType = true;    // 此处可不处理,因为下面控制的上传组件已经消失
                  this.pointer = 1;
              },
              // 点击编辑按钮,上传组件可点击,上传组件出现
              editInfo() {
                  this.disabledType = false;
                  this.disabledTypeProp = 'shopLogo';
                  this.pointer = 2;
              },
              // 提交,校验通过,进行弹窗询问
              submitForm() {
                  this.$refs['elForm'].validate(async (valid) => {
                      if (!valid) {
                          return false;
                      }
                      var message = '提交信息修改后需重新审核,审核中无法使用任何功能';
                      this.$confirm('确定提交信息修改?', '提示', {
                          confirmButtonText: '确定',
                          cancelButtonText: '取消',
                          type: 'warning',
                          center: true,
                      })
                          .then(() => {
                              developerService
                                  .updateShopInfo(this.formData)
                                  .then((res) => {
                                      if (res.code !== 0) {
                                          return this.$message.error(res.msg);
                                      }
                                      this.$message({
                                          message: '提交成功',
                                          type: 'success',
                                          duration: 500,
                                          onClose: () => {
                                              this.disabledType = true;
                                              this.pointer = 1;
                                          },
                                      });
                                  })
                                  .catch(() => {});
                          })
                          .catch(() => {});
                  });
              },
      }
      
      
      ————————————————————————————————————
      
      
      <style lang="scss" rel="stylesheet/scss" scoped>
      
      .form-container {
          min-width: 800px;
          padding: 0 30px 30px 30px;
      
          .my-tip {
              color: #ff9500;
              margin-bottom: 30px;
          }
      }
      .textTitle {
          width: 100%;
          height: 32px;
          font-size: 16px;
          font-family: PingFangSC-Semibold, PingFang SC;
          font-weight: 600;
          color: #1d2129;
          line-height: 24px;
          margin-bottom: 16px;
          position: relative;
          margin-left: 11px;
          &::before {
              content: '';
              position: absolute;
              top: 4px;
              left: -11px;
              width: 4px;
              height: 16px;
              background: #1d74f1;
              border-radius: 3px;
          }
      }
      .avatar-uploader_logo {
          /deep/.avatar-uploader {
              img {
                  width: 200px;
                  height: 40px;
                  border-radius: 4px;
              }
          }
      }
      .el-icon-warning-outline:before {
          content: '\E6C9';
          color: rgb(22, 93, 255);
      }
      
      .tips {
          margin-left: 5px;
          color: rgb(100, 106, 116);
      }
      
      </style>
      1. 引入封装好的上传图片组件,引入模块化api接口。
    4. 上传图片组件说明
      <template>
          <div class="clearfix">
              // auto-upload:默认值为true,当选中文件后立即执行上传。通过为其赋值为false关闭选中文件后立即上传功能。
              // show-file-list:默认值为true,显示已上传文件列表。通过为其赋值为false关闭显示已上传文件的列表。
              // on-change:文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用
              <el-upload
                  class="avatar-uploader"
                  action=""
                  :disabled="disabledType"
                  :auto-upload="false"
                  :show-file-list="false"
                  :on-change="changeUpload"
                  ref="myUpload"
              >
                  <img v-if="imageUrl" :src="imageUrl" class="avatar" :style="fixedSize" />
                  <div v-else class="avatar-uploader-icon">
                      <i class="el-icon-plus"></i>
                      <h3>{{ title }}</h3>
                  </div>
              </el-upload>
              <el-dialog title="图片剪裁" :visible.sync="dialogVisible" append-to-body>
                  <div class="cropper-content">
                      <div class="cropper" style="text-align: center">
                          <vueCropper
                              ref="cropper"
                              :img="option.img"
                              :outputType="option.outputType"
                              :outputSize="option.outputSize"
                              :info="option.info"
                              :full="option.full"
                              :canMove="option.canMove"
                              :canMoveBox="option.canMoveBox"
                              :original="option.original"
                              :autoCrop="option.autoCrop"
                              :fixed="option.fixed"
                              :autoCropWidth="option.autoCropWidth"
                              :autoCropHeight="option.autoCropHeight"
                              :centerBox="option.centerBox"
                              :infoTrue="option.infoTrue"
                              :fixedBox="option.fixedBox"
                          ></vueCropper>
                      </div>
                  </div>
                  <div slot="footer" class="dialog-footer">
                      <el-button @click="dialogVisible = false">取 消</el-button>
                      <el-button type="primary" @click="finish('blob', fileType)" :loading="loading">确认</el-button>
                  </div>
              </el-dialog>
          </div>
      </template>
      <script>
      import { VueCropper } from 'vue-cropper';
      import { getUuid } from '@/utils/index';
      export default {
          props: {
              // 外部传递的图片URL地址
              img: {
                  type: String,
                  default: '',
              },
              // 外部传递的图片描述
              title: {
                  type: String,
                  default: '',
              },
              // 外部传递的图片展示尺寸
              fixedSize: {
                  type: Object,
                  default: () => {},
              },
              // 外部传递的裁切框配置项
              Options: {
                  type: Object,
                  default: () => {},
              },
              // 外部传递的文件名
              Name: {
                  type: String,
                  default: '',
              },
              // 外部传递的是否禁用
              disabledType: {
                  type: Boolean,
                  default: false,
              },
              // 外部传递的上传文件的一个标识,只是53项目的上传接口需要这个标识入参
              fileType: {
                  type: Number,
                  default: 0,
              },
              // 外部传递的上传图片的接口路径
              uploadUrl: {
                  type: String,
                  default: '/server/user/uploadLeImg',
              },
          },
          components: {
              VueCropper,
          },
          data() {
              return {
                  imageUrl: '',
                  dialogVisible: false,
                  option: {
                      img: '', // 图片
                      outputType: 'png', // 输出类型
                      outputSize: 1, // 剪切后的图片质量(0.1-1)
                      full: true, // 输出原图比例截图 props名full
                      info: true,
                      canMove: true, // 是否拖拽裁剪框
                      original: true,
                      canMoveBox: true, // 是否可移动裁剪框
                      autoCrop: true, 
                      autoCropWidth: '300px', // 裁切默认宽度
                      autoCropHeight: '200px', // 裁切默认高度
                      fixedBox: false, // 是否是固定大小盒子
                      centerBox: true, // 截图框是否被限制在图片里面
                      infoTrue: false, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
                  },
                  // 防止重复提交
                  loading: false,
                  fileName: this.Name + getUuid() + '.png',
              };
          },
          watch: {
              // 监听裁切框显示及隐藏
              dialogVisible(val) {
                  if (val) {
                      this.option = Object.assign({}, this.option, this.Options);
                      this.loading = false;
                  }
              },
              // 监听外部传入的图片URL变化
              img: {
                  handler(val) {
                      if (val) {
                          this.imageUrl = val;
                          console.log('选定的图片', val);
                      }
                  },
                  deep: true,
                  immediate: true,
              },
          },
          mounted() {},
          methods: {
              // 没啥用
              sPhoto(value) {
                  this.imageUrl(value);
              },
              // 选中文件
              changeUpload(file) {
                  // 1.0 先校验图片格式
                  const isJPG =
                      file.raw.type === 'image/jpeg' || file.raw.type === 'image/png' || file.raw.type === 'image/jpg' || file.raw.type === 'image/bmp';
                  // 2.0 再校验图片大小
                  const isLt2M = file.size / 1024 / 1024 < 2;
      
                  if (!isJPG) {
                      this.$message.error('上传图片只能是 JPG 格式!');
                      return false;
                  }
                  if (!isLt2M) {
                      this.$message.error('上传图片大小不能超过 2MB!');
                      return false;
                  }
      
                  // 上传成功后将图片地址赋值给裁剪框显示图片
                  console.log(file);
                  this.$nextTick(() => {
                      // 通过window.URL.createObjectURL()方法将图片构建为URL形式赋值给裁切框
                      this.option.img = window.URL.createObjectURL(file.raw);
      
                      this.dialogVisible = true;
                  });
              },
              // 上传图片(点击上传按钮)
              finish(type, fileType) {
                  this.loading = true;
                  let _this = this;
                  let formData = new FormData();
                  // 输出
                  if (type === 'blob') {
                      this.$refs.cropper.getCropBlob((data) => {
                          let img = window.URL.createObjectURL(data);
                          this.model = true;
                          this.imageUrl = img;
                          formData.append('file', data, this.fileName);
                          if (this.uploadUrl === '/server/user/uploadLeImg') {
                              formData.append('type', this.fileType);
                          }
                          this.$http
                              .post(this.uploadUrl, formData)
                              .then((response) => {
                                  this.loading = false;
                                  this.dialogVisible = false;
                                  var res = response.data;
                                  if (res.code === 0) {
                                      // 输出
                                      // _this.$emit('ok', res.data[0].filepath);
                                      _this.$emit('ok', res.data);
                                  }
                              })
                              .catch(() => {
                                  this.loading = false;
                              });
                      });
                  }
                  // else {
                  //   this.$refs.cropper.getCropData((data) => {
                  // this.model = true
                  // this.modelSrc = data
                  // })
                  // }
              },
          },
      };
      </script>
      <style lang="scss" rel="stylesheet/scss" scoped>
      .clearfix {
          /deep/ .avatar-uploader {
              display: inline-block;
          }
          /deep/ .avatar-uploader .el-upload {
              border: 1px dashed #d9d9d9;
              border-radius: 6px;
              cursor: pointer;
              position: relative;
              overflow: hidden;
          }
      
          /deep/ .avatar-uploader .el-upload:hover {
              border-color: #409eff;
          }
          /deep/ .avatar-uploader-icon {
              font-size: 28px;
              color: #8c939d;
              width: 156px;
              height: 156px;
              padding-top: 42px;
              //line-height: 104px;
              text-align: center;
              h3 {
                  font-size: 12px;
              }
          }
          /deep/ .avatar {
              // width: 104px;
              // height: 104px;
              width: 82px;
              height: 82px;
              display: block;
          }
      }
      //图片上传
      
      .card-photo {
          width: 200px;
          float: left;
          /deep/ .avatar-uploader-icon {
              width: 159px !important;
              height: 96px !important;
          }
          /deep/ .avatar {
              width: 159px !important;
              height: 96px !important;
          }
      }
      .big-card-photo {
          width: 16.7vw;
          height: 11.13vw;
          float: left;
          /deep/ .avatar-uploader {
              width: 100%;
              height: 100%;
              .el-upload {
                  width: 100%;
                  height: 100%;
              }
          }
          /deep/ .avatar-uploader-icon {
              width: 100% !important;
              height: 100%;
              padding-top: 20%;
              //height: 80%!important;
          }
          /deep/ .avatar {
              width: 100% !important;
              height: 100%;
              //height: 100% !important;
          }
      }
      .big-square {
          width: 10.5vw;
          height: 10.5vw;
          float: left;
          /deep/ .avatar-uploader {
              width: 100%;
              height: 100%;
              .el-upload {
                  width: 100%;
                  height: 100%;
              }
          }
          /deep/ .avatar-uploader-icon {
              width: 100% !important;
              height: 100%;
              padding-top: 30%;
              //height: 80%!important;
          }
          /deep/ .avatar {
              width: 100% !important;
              height: 100%;
              //height: 100% !important;
          }
      }
      .cropper-content {
          .cropper {
              width: auto;
              height: 500px;
          }
      }
      </style>
      
      <template>
              <avatar-upload
                  class="avatar-uploader"
                  :fixedSize="{ width: '104px', height: '104px' }"
                  :options="{ autoCropWidth: '208px', autoCropHeight: '208px', fixedBox: true }"
                  @ok="handleAvatarSuccess"
                  :img="data.headUrl"
                  :title="'上传头像'"
              >
              </avatar-upload>
              // 上传图片的提示
              <div>
                  <span class="el-icon-warning-outline"></span>
                  <span class="tips">*建议上传长度为104px,高度为104px,背景透明的PNG格式图片</span>
              </div>
      </template>
      
      <script>
      import avatarUpload from '@/components/avatar-upload';
      
      export default {
        components: {
              avatarUpload
          },
      }
      </script>
      1. 上传图片使用规范 

        1.4.1:组件原理说明:对el-upload组件进行了二次封装,对vueCropper组件进行了二次封装。

        在外层引用并使用该组件时,通过给组件传值来控制其功能与展示。

        外部传入的fixedSize属性控制图片的展示,组件<el-upload>的部分样式从fixedSize中取值运行,fixedSize属性默认为空对象,此时图片尺寸等不受限制。fixedSize属性由外部传入时,需要以style类型的样式出现,图片尺寸等受其控制。

        外部传入的Options属性控制截图功能,裁切组件<vueCropper>从Options中取值来运行,Options可以控制裁切组件的初始功能。

        组件<el-upload>完成上传功能后,会去触发引用并使用他的组件身上的ok事件,在他的回调中去修改img的值。

        外部传入的img属性控制组件展示那个图片,组件<el-upload>从img中取值来展示图片,img可以控制组件展示哪张图片。

        1.4.2:上传图片的提示:组件下面补充的提示根据需要来判断是否使用。

        1.4.3:使用场景。

      2. 图片尺寸固定
        1. 类名class="avatar-uploader"是组件自带的,无需改动
        2. 属性fixedSize:控制图片是否需要固定尺寸进行展示、需要什么样的尺寸进行展示。 应用详解  :fixedSize="{ width: '104px', height: '104px' }"控制图片展示的固定尺寸为宽度104px、高度104px,可人为修改
        3. 属性Options:控制图片截图。
          1. 应用详解  :Options="{ autoCropWidth: '104px', autoCropHeight: '104px' ,fixedBox: true}"控制初始截图尺寸为宽度104px、高度104px,无法进行拖拽修改。此配置项可人为修改初始尺寸,也可修改是否固定裁切尺寸
          2. fixedBox控制裁切区域是否可拖拽修改,值为false则可拖拽修改,值为true则不可拖拽修改。
        4. 属性@ok:为图片上传成功以后的回调,无需改动
        5. 属性img:展示的图片,无需改动
        6. 属性title:组件的标题,可人为修改。如图
      3. 图片尺寸非固定
        1. 删除fixedSize属性即可,其他属性无需变化。
    5. 接口文件
import axios from '@/utils/newRequestHttp';

const developerService = {
    // async getApplicationList(data) {
    //     return axios({
    //         url: '/server/item/list',
    //         method: 'post',
    //         data
    //     })
    // },
    // 查看数据表
    async queryTableNames (id) {
        return axios({
            url: `/server/dataSource/queryTableNames?sourceId=${id}`,
            method: 'get',
        })
    },
    // 新建应用
    async addNewApp (data) {
        return axios({
            url: `/server/item/create`,
            method: 'post',
            data
        })
    },
    // 首页--热门资产表
    async querySource (data) {
        return axios({
            url: `/server/item/queryOrderByNum`,
            method: 'post',
            data
        })
    },

    // 首页应用统计
    async queryApp (data) {
        return axios({
            url: `/server/item/queryApplicationNum`,
            method: 'post',
            data
        })
    },

    // 首页交易数据
    async queryTradeNum (data) {
        return axios({
            url: `/server/item/queryTradeNum`,
            method: 'post',
            data
        })
    },

    // 店铺浏览量
    async queryShop (data) {
        return axios({
            url: `/server/item/queryStoreViewNum`,
            method: 'post',
            data
        })
    },
    // 关联资产
    async queryPageItem (data) {
        return axios({
            url: `/server/item/queryPageRelateSources`,
            method: 'post',
            data
        })
    },

    // 预览
    async getPreview (id) {
        return axios({
            url: `/server/item/dataApplicationPreview?itemId=${id}`,
            method: 'get',
        })
    },
    // 新增数据源
    async addSources (data) {
        return axios({
            url: '/server/item/dataSourceAdd',
            method: 'post',
            data
        })
    },

    // 修改数据源
    async updateSources (data) {
        return axios({
            url: '/server/item/dataSourceUpdate',
            method: 'post',
            data
        })
    },
    // 获取数据资产表
    async getSources (data) {
        return axios({
            url: '/server/dataSource/querySourcesPage',
            method: 'post',
            data
        })
    },

    // 数据资产表详情查看
    async getSourcesDetail (id) {
        return axios({
            url: `/server/dataSource/querySourceDetail?sourceId=${id}`,
            method: 'post',
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
            },
        })
    },
    // 获取数据应用关联资产-表数据
    async getSourcesTable (data) {
        return axios({
            url: '/server/dataSource/queryRelateSources',
            method: 'post',
            data
        })
    },
    // 配置数据源sql测试
    async testSql (data) {
        return axios({
            url: '/server/item/connectionTestSql',
            method: 'post',
            data
        })
    },
    // 修改商品
    async updateGoods (data) {
        return axios({
            url: '/server/item/update',
            method: 'post',
            data
        })
    },
    // 获取店铺信息
    async getShopInfo () {
        return axios({
            url: '/server/user/queryShopInfo',
            method: 'post',
        })
    },
    // 获取公司信息
    async getEnterpriseInfo () {
        return axios({
            url: '/server/user/queryEnterpriseInfo',
            method: 'post',
        })
    },
    // 编辑店铺信息
    async updateShopInfo (data) {
        return axios({
            url: '/server/user/updateShopInfo',
            method: 'post',
            data
        })
    },
    // 订单管理--查看详情
    async getOrderDetail (id) {
        return axios({
            url: `/server/order/orderDetailByseller/${id}`,
            headers: {
                'content-type': 'application/x-www-form-urlencoded'
            },
            method: 'post',
        })
    },
    // 查看数据源详情
    async getDataSourceDetail (data) {
        return axios({
            url: '/server/item/dataSourceDetail',
            method: 'post',
            data
        })
    },
    // 查看源数据字典
    async getDataDictionary (data) {
        return axios({
            url: '/server/dataSource/queryRelateSources',
            method: 'post',
            data
        })
    },
    //    上传应用图片
    async uploadImg (data) {
        return axios({
            url: '/server/item/uploadApplicationImgPath',
            method: 'post',
            data
        })
    },

    // 上传附件
    async uploadFile (data) {
        return axios({
            url: '/server/item/uploadApplicationDemoFilePath',
            method: 'post',
            data
        })
    },

    // 批量删除数据源
    async deleteDataSource (data) {
        return axios({
            url: '/server/item/dataSourceBatchDelete',
            method: 'post',
            data
        })
    },

    // 批量导入输入源
    async batchImport (url, data) {
        return axios({
            url: url,
            method: 'post',
            data
        })
    },

    // 批量导入输出源
    async batchDown (data) {
        return axios({
            url: '/server/item/uploadOutputExcel',
            method: 'post',
            data
        })
    },
    // 校验能否下架
    async checkItemOff (data) {
        return axios({
            url: '/server/item/checkItemOff',
            method: 'post',
            data
        })
    },
    // 上下架
    async putOnApplication (data) {
        return axios({
            url: '/server/item/statusChange',
            method: 'post',
            data
        })
    },
    // 查看应用详情
    async getApplicationDetail (id) {
        return axios({
            url: `/server/item/itemDetail?itemId=${id}`,
            method: 'get',
        })
    },
    // 删除订单
    // async deleteOrder(id) {
    //     return axios({
    //         url: `/server/order?orderId=${id}`,
    //         method: 'delete',
    //     })
    // },
    // 获取数据源字典列表
    async getDataSourceDictionaryList(data){
        return axios({
            url: '/server/dataSource/queryPageDataDictionary',
            method: 'post',
            data
        })
    }
}

export default developerService;

1.2 在表单域中上传图片并且进行图片必填校验

  1. <el-form-item label="应用图标:" prop="images">
        // 隐藏表单input框
        <el-input v-show="false" v-model="formData.images" />
        <el-tooltip placement="right" effect="light">
            <div slot="content">
                <div class="img-desc">
                    <h3>支持图片格式:jpg/jpeg/png/bmp格式;</h3>
                </div>
            </div>
            // 使用组件
            <avatar-upload
                class="avatar-uploader"
                uploadUrl="/server/item/uploadApplicationImgPath"
                :fixedSize="{ width: '156px', height: '156px' }"
                :Options="{ autoCropWidth: '208px', autoCropHeight: '208px' }"
                @ok="handleAvatarSuccess"
                :img="formData.images"
                :title="'上传照片'"
            ></avatar-upload>
        </el-tooltip>
    </el-form-item>
    
    
    ————————————————————————————
    
    
    // 上传照片
    handleAvatarSuccess(file) {
        this.imageUrl = this.formData.images = file;
    },

1.3在表单域上传附件

  1.  
    <el-form-item prop="uploadAttachment">
        <el-input v-show="false" v-model="formData.uploadAttachment" />
        // drag:是否启用拖拽上传
        <el-upload
            class="upload-demo"
            drag
            :before-upload="beforeUpload"
            action="#"
            :http-request="uploadFile"
            :on-remove="handleRemove"
            :limit="1"
            accept=".zip"
            :on-exceed="handleExceed"
        >
            <i class="el-icon-plus"></i>
            <div class="el-upload__text">
                <div>点击此处或拖拽文件到此处上传文件</div>
                支持zip格式文件,单个文件最大为10M
            </div>
        </el-upload>
    </el-form-item>
    
    
    ——————————————————————————————————————
    
    
    // 附件上传前校验
    beforeUpload(file) {
        const sizeLimit = file.size / 1024 / 1024 > 10;
        if (sizeLimit) {
            this.$message.warning('上传文件大小不能超过 10MB!');
        }
        const fileFamart = file.name.split('.')[file.name.split('.').length - 1];
        if (fileFamart !== 'zip') {
            this.$message.warning('必须上传zip格式的文件!');
        }
        return !sizeLimit && fileFamart === 'zip';
    },
    // 附件上传
    uploadFile(item) {
        const fileObj = item.file;
        let formData = new FormData();
        formData.append('file', fileObj);
        developerService
            .uploadFile(formData)
            .then((res) => {
                if (res.code === 0) {
                    this.$message.success('上传成功!');
                    this.formData.uploadAttachment = res.data;
                    this.formData.uploadAttachmentName = item.file.name;
                }
            })
            .catch(() => {});
    },
    // 移除文件
    handleRemove() {
        this.formData.uploadAttachment = '';
    },
    // 上传个数限制
    handleExceed(files, fileList) {
        this.$message.warning(`当前限制选择 1个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
    },

2.时间查询

  1. 处理方式一
    1. <el-form-item label="创建时间:">
          <el-date-picker
              v-model="dataForm.dateRange"
              type="daterange"
              value-format="yyyy-MM-dd HH:mm:ss"
              :range-separator="$t('datePicker.range')"
              start-placeholder="开始时间"
              end-placeholder="结束时间"
          >
          </el-date-picker>
      </el-form-item>
      
      ——————————————————————————
      
      // 脚本
      dataForm: {
          type: 'DATA_APPLICATION',
          categoryId: '',
          categoryName: '',
          code: '',
          name: '',
          dateRange: [],
      },
      
      
      // 点击查询,先看时间是否有值,有值的话就是数组中2个元素。第一个就是开始时间,第二个就是结束时间
      getList() {
          if (this.dataForm.dateRange) {
              var array = this.dataForm.dateRange;
              // 将开始时间赋值给startTime,将结束时间赋值给endTime
              if (array.length === 2) {
                  this.dataForm.startTime = array[0];
                  this.dataForm.endTime = array[1];
              } else {
              // 时间不为2个元素的数组时,将开始时间与结束时间都置空
                  this.dataForm.startTime = '';
                  this.dataForm.endTime = '';
              }
          } else {
              // 无时间时,将开始时间与结束时间都置空
              this.dataForm.startTime = '';
              this.dataForm.endTime = '';
          }
          // 将当前页置为1
          this.current = 1;
          // 发起请求
          this.getDataList();
      },
      // 重置,将表单的每一项单独的重置为空。开始时间与结束时间在每次查询时再进行处理。
      clearData() {
          this.dataForm.dateRange = [];
          this.current = 1;
          this.getList();
      },

        2.处理方式二 

<el-form-item label="录入时间:" prop="createDate">
    <el-date-picker
        v-model="dataForm.createDate"
        @change="changeTime"
        type="daterange"
        value-format="yyyy-MM-dd HH:mm:ss"
        :range-separator="$t('datePicker.range')"
        start-placeholder="开始时间"
        end-placeholder="结束时间"
    >
    </el-date-picker>
</el-form-item>




————————————————————————————————————



// 表单域数据
dataForm: {
    startTime: '', // 数据库查询开始时间
    endTime: '', // 数据库查询结束时间
},



// 查询时间(开始时间、结束时间)
async changeTime(e) {
    if (!e) {
        this.dataForm.startTime = '';
        this.dataForm.endTime = '';
        return;
    }
    this.dataForm.startTime = e[0];
    this.dataForm.endTime = e[1];
},

// 重置表单域
clearData() {
    this.$refs['elForm'].resetFields();
    this.dataForm.startTime = '';
    this.dataForm.endTime = '';
    this.getDataList();
},

3.选择框单选 

  1. 处理方式一
    1. <el-form-item label="订单状态:">
          <el-select v-model="dataForm.status" clearable placeholder="请选择订单状态">
              <el-option v-for="item in statusList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
          </el-select>
      </el-form-item>
      
      
      ——————————————————————————————
      
      
      // 脚本
      dataForm: {
          status: '',
      },
      statusList: [
          {
              label: '待支付',
              value: 'TO_PAY',
          },
          {
              label: '已支付',
              value: 'PAY_SUCCESS',
          },
          {
              label: '已失效',
              value: 'CANCEL',
          },
      ],

4. 表格格式化处理

  1.  处理方式一
    1. <el-table v-loading="dataListLoading" :data="dataList" style="width: 100%">
          // show-overflow-tooltip:当内容过长被隐藏时显示 tooltip
          <el-table-column prop="orderId" label="订单编号" header-align="left" align="left" show-overflow-tooltip></el-table-column>
          // 表格的插槽技术
          <el-table-column prop="status" label="订单状态" header-align="left" align="left">
              <template slot-scope="scope">
                  <span :class="getColumnClass(scope.row.status)">
                      {{ scope.row.statusDesc }}
                  </span>
              </template>
          </el-table-column>
          // 插槽内部使用全局过滤器
          <el-table-column label="下单时间" show-overflow-tooltip header-align="left" align="left" width="150px;" prop="createDate">
              <template slot-scope="scope">{{ scope.row.createDate | dateformat('YYYY-MM-DD HH:mm:ss') }}</template>
          </el-table-column>
          <el-table-column label="完成时间" header-align="left" align="left" width="150px;" show-overflow-tooltip prop="orderPayment">
              <template slot-scope="scope" v-if="scope.row.orderPayment.payDate">
                  <span v-if="scope.row.orderPayment.payDate"> {{ scope.row.orderPayment.payDate | dateformat('YYYY-MM-DD HH:mm:ss') }}</span>
                  <span v-else>-</span>
              </template>
          </el-table-column>
          <el-table-column prop="itemId" label="应用编号" header-align="left" align="left" show-overflow-tooltip></el-table-column>
          <el-table-column prop="itemName" label="应用名称" header-align="left" align="left" show-overflow-tooltip></el-table-column>
          <el-table-column prop="itemCount" label="应用数量" header-align="left" align="left"></el-table-column>
          <el-table-column prop="totalAmount" label="订单金额" header-align="left" align="left">
              <template slot-scope="scope">
                  <!-- {{ $moneyFormat(scope.row.totalAmount) }} -->
                  {{ scope.row.totalAmount }}
              </template>
          </el-table-column>
          <el-table-column prop="userName" label="消费者账号" header-align="left" align="left"></el-table-column>
          <el-table-column prop="blockchainId" label="区块链交易码" header-align="left" align="left" show-overflow-tooltip>
              <template slot-scope="scope">
                  {{ scope.row.blockchainId || '-' }}
              </template>
          </el-table-column>
          <el-table-column :label="$t('handle')" fixed="right" header-align="left" align="left">
              <template slot-scope="scope">
                  <el-button type="text" size="" @click="detail(scope.row.orderId)">查看</el-button>
                  <!-- <el-button type="text" size="" @click="del(scope.row.orderId)">删除</el-button> -->
              </template>
          </el-table-column>
      </el-table>
      
      
      ——————————————————————————————
      
      
      
      
      全局过滤器在main.js内部使用
      import moment from 'moment';
      
      Vue.filter('dateformat', function (dataStr, pattern = 'YYYY-MM-DD HH:mm:ss') {
          if (dataStr) {
              return moment(dataStr).format(pattern);
          } else {
              return '';
          }
      });

5.表单域校验图片必填 

  1. 处理方式一
    1. <el-form-item label="应用图标:" prop="images">
          <el-input v-show="false" v-model="formData.images" />
          <el-tooltip placement="right" effect="light">
              <div slot="content">
                  <div class="img-desc">
                      <h3>支持图片格式:jpg/jpeg/png/bmp格式;</h3>
                  </div>
              </div>
              <avatar-upload
                  class="avatar-uploader"
                  uploadUrl="/server/item/uploadApplicationImgPath"
                  :fixedSize="{ width: '156px', height: '156px' }"
                  :Options="{ autoCropWidth: '208px', autoCropHeight: '208px' }"
                  @ok="handleAvatarSuccess"
                  :img="formData.images"
                  :title="'上传照片'"
              ></avatar-upload>
          </el-tooltip>
      </el-form-item>
      
      
      ————————————————————————————
      
      
      隐藏表单input框

 6.表单域标签必填校验

  1. <el-form-item label="标签:" prop="tags" class="tbgswidth">
        <el-input v-show="false" v-model="formData.tags" />
        <span v-for="(item, index) in sourceTags" :key="index" class="showTagsBtn">
            {{ item.tagName }} &nbsp;<i @click="deltag(item)" class="el-icon-arrow-right el-icon-close"></i>
        </span>
        <span class="pushTagsBtn" @click="addTags"><i class="el-icon-arrow-right el-icon-plus"></i>&nbsp; 添加标签</span>
        &nbsp;
        <span v-show="isHasTags" class="noHasTags">该分类下暂无标签,请重新选择分类</span>
    </el-form-item>
    
    
    
    <!-- 标签弹层 -->
    <el-dialog title="添加标签" :visible.sync="dialogVisible" width="30%">
        <el-tabs tab-position="left" style="height: 200px; margin-top: 12px">
            <el-tab-pane :label="paneLabel">
                <el-tag v-for="(item, index) in tagschild" :key="index" @click="pushTags(item)">
                    {{ item.tagName }}
                </el-tag>
            </el-tab-pane>
        </el-tabs>
    </el-dialog>
    
    
    
    ————————————————————————————————————
    
    
    dialogVisible: false,
    sourceTags: [],
    
    
    // 新增标签
    addTags() {
        if (!this.formData.categoryId) {
            this.$message.error('请先选择应用分类');
            return;
        } else {
            this.dialogVisible = true;
        }
    },
    // 推送标签
    pushTags(obj) {
        if (this.sourceTags.length >= 4) {
            return this.$message.error('标签不得超过4个');
        }
        let temp = this.sourceTags.some((item) => item == obj);
        if (temp) {
            return this.$message.error('请勿重复添加标签!');
        }
        this.sourceTags.push(obj);
        let arr = []; // 收集标签id
        this.sourceTags.forEach((item) => {
            arr.push(item.id);
        });
        this.formData.tags = JSON.stringify(arr); // 此处转为字符串,做表单校验用
    },
    // 删除标签
    deltag(obj) {
        this.sourceTags = this.sourceTags.filter((item) => item !== obj);
        let arr = []; // 收集标签id
        this.sourceTags.forEach((item) => {
            arr.push(item.id);
        });
        this.formData.tags = JSON.stringify(arr) === '[]' ? '' : JSON.stringify(arr); // 此处转为字符串,做表单校验用
    },

7.表单无数据,新增参数可添加 ,可批量删除,可批量导入

 

 

  1.  
    <el-table
        ref="multipleTable"
        :data="dataList"
        @selection-change="dataListSelectionChangeHandle"
        :header-cell-class-name="DisableSelection ? 'cellClass' : ''"
        style="color: #202328; margin: 20px 0px"
    >
        <el-table-column type="selection" width="50" :selectable="isSelectable"> </el-table-column>
        <el-table-column prop="fieldName" label="参数名称" header-align="left" align="left"></el-table-column>
        <el-table-column prop="fieldType" label="数据类型" header-align="left" align="left"></el-table-column>
        <el-table-column prop="description" label="定义说明" header-align="left" align="left"></el-table-column>
        <el-table-column prop="algorithmType" label="加密类型">
            <template slot-scope="scope">{{ getType(scope.row.algorithmType) }}</template>
        </el-table-column>
    </el-table>
    
    
    
    
    <!-- 新增参数 -->
    <el-dialog title="新增参数" :visible.sync="addNewVisible" width="30%" :before-close="handleClose">
        <el-form label-width="100px" :model="formLabelAlign" ref="formLabelAlign" style="margin: 20px" :rules="formRules">
            <el-form-item label="参数名称:" prop="fieldName">
                <el-input v-model="formLabelAlign.fieldName"></el-input>
            </el-form-item>
            <el-form-item label="数据类型:" prop="fieldType">
                <el-input v-model="formLabelAlign.fieldType"></el-input>
            </el-form-item>
            <el-form-item label="定义说明:" prop="description">
                <el-input v-model="formLabelAlign.description"></el-input>
            </el-form-item>
            <el-form-item label="加密类型:" prop="algorithmType">
                <el-select v-model="formLabelAlign.algorithmType" placeholder="请选择加密类型" clearable :style="{ width: '100%' }">
                    <el-option v-for="item in algorithmType" :key="item.id" :label="item.name" :value="item.id"></el-option>
                </el-select>
            </el-form-item>
        </el-form>
        <span slot="footer" class="dialog-footer">
            <el-button @click="resetForm('formLabelAlign')" class="cancelBtn">返回</el-button>
            <el-button type="primary" @click="addNewBtn('formLabelAlign')">确认</el-button>
        </span>
    </el-dialog>
    
    
    <!-- 批量导入 -->
    <el-dialog title="批量导入" :visible.sync="importVisible" width="50%" :before-close="handleClose">
        // 使用组件
        <batch-import
            ref="batchImport"
            @closeDialog="closeDialog"
            :batchType="batchType"
            :batchdownloadUrl="batchdownloadUrl"
            :batchImportUrl="batchImportUrl"
        ></batch-import>
        <span slot="footer" class="dialog-footer">
            <el-button @click="importVisible = false" class="cancelBtn">返回</el-button>
            <el-button type="primary" @click="newUpload">确定</el-button>
        </span>
    </el-dialog>
    
    
    
    __________________________________
    
    
    
    
    // 数据
    dataList: [],
    outSelectedList: [], // 所勾选的数据定义
    batchType: '',
    importVisible: false,
    batchdownloadUrl: '/server/item/downloadInputTempGYS',
    batchImportUrl: '/server/item/uploadInputExcelGYS',
    
    
    // 方法
    
    // 新增参数--确认
    addNewBtn(formLabelAlign) {
        this.$refs[formLabelAlign].validate((valid) => {
            if (valid) {
                const newForm = {
                    fieldName: this.formLabelAlign.fieldName,
                    fieldType: this.formLabelAlign.fieldType,
                    description: this.formLabelAlign.description,
                    algorithmType: this.formLabelAlign.algorithmType,
                    dataSourceProvider: 2,
                };
                this.dataList.unshift(newForm);
    
                // 做复选框回显
                this.$nextTick(() => {
                    this.toggleSelection();
                });
                this.addNewVisible = false;
    
                // 重置表单域字段
                this.$refs[formLabelAlign].resetFields();
            } else {
                console.log('error submit!!');
                return false;
            }
        });
    },
    // 做复选框回显
     toggleSelection(rows) {
         if (rows) {
             rows.forEach((row) => {
                 this.$refs.multipleTable.toggleRowSelection(row);
             });
         } else {
             this.$refs.multipleTable.clearSelection();
         }
     },
    // 用于保存选中的行
    dataListSelectionChangeHandle(val) {
        this.outSelectedList = val;
    },
    // 批量删除
    deleteSelected() {
        if (this.outSelectedList.length > 0) {
            this.$confirm('此操作将批量删除, 是否继续?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning',
            }).then(() => {
                let val = this.outSelectedList; //选中的值
                if (val) {
                    val.forEach((val, index) => {
                        this.dataList.forEach((v, i) => {
                            if (val.fieldName === v.fieldName) {
                                this.dataList.splice(i, 1);
                            }
                        });
                    });
                }
                this.$message.success('删除成功');
            });
        } else {
            this.$message.error('请选择删除项!');
        }
    },
    // 批量导入
    batchImport() {
        this.importVisible = true;
        this.batchType = 'in';
    },
    
    closeDialog(data) {
        // list数组去除相同参数数据,以导入的表格数据为准
        let newList = this.dataList.filter((item) => !data.some((ele) => ele.fieldName === item.fieldName));
        this.dataList = data.concat(newList);
    },

    上传与下载组件

    <template>
        <div class="uploadBox">
            <el-upload
                class="upload-demo"
                :before-upload="beforeAvatarUpload"
                :on-change="changeData"
                action="#"
                :http-request="downLoad"
                :on-error="uploadFalse"
                :on-remove="handleRemove"
                accept=".xlsx"
                :file-list="fileList"
            >
                <el-button size="small" type="primary">上传文件</el-button>
                <div slot="tip" class="el-upload__tip">支持拓展名: .xlsx<el-button type="text" @click="downloadFile">下载模板</el-button></div>
            </el-upload>
        </div>
    </template>
    
    <script>
    import { developerService, operationService } from '@/api';
    import { readFile } from 'vxe-table';
    export default {
        data() {
            return {
                fileList: [],
                fileListTemp: [],
            };
        },
        props: {
            batchType: String,
            batchdownloadUrl: String,
            batchImportUrl: String,
        },
        methods: {
            // 下载模板
            async downloadFile() {
                if (this.batchType === 'in') {
                    operationService
                        .downloadFileIn(this.batchdownloadUrl)
                        .then(async (res) => {
                            if (res.data.type == 'application/json') {
                                const readF = new FileReader();
                                readF.readAsText(res, 'utf-8');
                                readF.onload = () => {
                                    const { msg } = JSON.parse(readF.result);
                                    this.$message.error(msg);
                                };
                            }
    
                            const disposition = res.headers['content-disposition'];
                            const matches = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(disposition);
                            const filename = matches[1].replace(/['"]/g, '');
                            const rfilename = decodeURI(filename);
    
                            const blob = new Blob([res.data], {
                                type: 'application/vnd.ms-excel',
                            });
                            const url = window.URL.createObjectURL(blob);
                            const link = document.createElement('a');
                            link.style.display = 'none';
                            link.href = url;
                            link.download = `${rfilename}`;
                            document.body.appendChild(link);
                            link.click();
                            document.body.removeChild(link);
                            this.$message({
                                type: 'success',
                                message: '下载模板成功!',
                            });
                        })
                        .catch(() => {});
                } else if ((this.batchType = 'out')) {
                    operationService
                        .downloadFileOut()
                        .then((res) => {
                            if (res.data.type == 'application/json') {
                                const readF = new FileReader();
                                readF.readAsText(res, 'utf-8');
                                readF.onload = () => {
                                    const { msg } = JSON.parse(readF.result);
                                    this.$message.error(msg);
                                };
                            }
    
                            const disposition = res.headers['content-disposition'];
                            const matches = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(disposition);
                            const filename = matches[1].replace(/['"]/g, '');
                            const rfilename = decodeURI(filename);
    
                            const blob = new Blob([res.data], {
                                type: 'application/vnd.ms-excel',
                            });
                            const url = window.URL.createObjectURL(blob);
                            const link = document.createElement('a');
                            link.style.display = 'none';
                            link.href = url;
                            link.download = `${rfilename}`;
                            document.body.appendChild(link);
                            link.click();
                            document.body.removeChild(link);
                            this.$message({
                                type: 'success',
                                message: '下载模板成功!',
                            });
                        })
                        .catch(() => {});
                }
                // const a = document.createElement('a');
                // a.href = this.uploadAddress;
                // a.click();
                // window.URL.revokeObjectURL(this.uploadAddress);
            },
            // 上传
            downLoad(item) {
                console.log(this.batchType);
                const fileObj = item.file;
                let formData = new FormData();
                formData.append('file', fileObj);
                if (this.batchType === 'in') {
                    developerService
                        .batchImport(this.batchImportUrl, formData)
                        .then((res) => {
                            if (res.code !== 0) {
                                this.fileList = [];
                                return this.$message.error(res.msg);
                            }
                            if (res.code === 0) {
                                this.$message.success('上传成功!');
                                let data = res.data;
                                this.fileList = this.fileListTemp;
                                this.$emit('closeDialog', data);
                            }
                        })
                        .catch(() => {});
                } else if ((this.batchType = 'out')) {
                    developerService
                        .batchImport(this.batchImportUrl, formData)
                        .then((res) => {
                            if (res.code !== 0) {
                                this.fileList = [];
                                return this.$message.error(res.msg);
                            }
                            if (res.code === 0) {
                                this.$message.success('上传成功!');
                                let data = res.data;
                                this.fileList = this.fileListTemp;
                                this.$emit('closeDialog', data);
                            }
                        })
                        .catch(() => {});
                }
            },
            // 上传失败时的钩子
            uploadFalse(response, file, fileList) {
                this.$message({
                    message: 'excel文件上传失败!',
                    type: 'error',
                });
            },
            // 移除文件
            handleRemove() {
                this.fileList = [];
            },
            // 上传前对文件的大小的判断
            beforeAvatarUpload(file) {
                const isLt10M = file.size / 1024 / 1024 > 10;
                const extension = file.name.split('.')[1] === 'xlsx';
                if (isLt10M) {
                    this.$message.warning('上传模板大小不能超过 10MB!');
                }
                if (!extension) {
                    this.$message.warning('上传模板只能是xlsx格式!');
                }
                return extension || isLt10M;
            },
            // 文件变化执行
            changeData(file, fileList) {
                this.fileList = [];
                // 再次上传覆盖之前的文件
                if (fileList.length > 1) {
                    fileList.splice(0, 1);
                }
                this.fileListTemp = fileList;
            },
        },
    };
    </script>
    
    <style lang="scss" scoped>
    /deep/.el-upload__tip {
        font-size: 14px;
    }
    .uploadBox {
        padding: 30px;
    }
    </style>
    

    引入模块化URL

    import axios from '@/utils/newRequestHttp';
    
    const developerService = {
        // async getApplicationList(data) {
        //     return axios({
        //         url: '/server/item/list',
        //         method: 'post',
        //         data
        //     })
        // },
        // 查看数据表
        async queryTableNames (id) {
            return axios({
                url: `/server/dataSource/queryTableNames?sourceId=${id}`,
                method: 'get',
            })
        },
        // 新建应用
        async addNewApp (data) {
            return axios({
                url: `/server/item/create`,
                method: 'post',
                data
            })
        },
        // 首页--热门资产表
        async querySource (data) {
            return axios({
                url: `/server/item/queryOrderByNum`,
                method: 'post',
                data
            })
        },
    
        // 首页应用统计
        async queryApp (data) {
            return axios({
                url: `/server/item/queryApplicationNum`,
                method: 'post',
                data
            })
        },
    
        // 首页交易数据
        async queryTradeNum (data) {
            return axios({
                url: `/server/item/queryTradeNum`,
                method: 'post',
                data
            })
        },
    
        // 店铺浏览量
        async queryShop (data) {
            return axios({
                url: `/server/item/queryStoreViewNum`,
                method: 'post',
                data
            })
        },
        // 关联资产
        async queryPageItem (data) {
            return axios({
                url: `/server/item/queryPageRelateSources`,
                method: 'post',
                data
            })
        },
    
        // 预览
        async getPreview (id) {
            return axios({
                url: `/server/item/dataApplicationPreview?itemId=${id}`,
                method: 'get',
            })
        },
        // 新增数据源
        async addSources (data) {
            return axios({
                url: '/server/item/dataSourceAdd',
                method: 'post',
                data
            })
        },
    
        // 修改数据源
        async updateSources (data) {
            return axios({
                url: '/server/item/dataSourceUpdate',
                method: 'post',
                data
            })
        },
        // 获取数据资产表
        async getSources (data) {
            return axios({
                url: '/server/dataSource/querySourcesPage',
                method: 'post',
                data
            })
        },
    
        // 数据资产表详情查看
        async getSourcesDetail (id) {
            return axios({
                url: `/server/dataSource/querySourceDetail?sourceId=${id}`,
                method: 'post',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
            })
        },
        // 获取数据应用关联资产-表数据
        async getSourcesTable (data) {
            return axios({
                url: '/server/dataSource/queryRelateSources',
                method: 'post',
                data
            })
        },
        // 配置数据源sql测试
        async testSql (data) {
            return axios({
                url: '/server/item/connectionTestSql',
                method: 'post',
                data
            })
        },
        // 修改商品
        async updateGoods (data) {
            return axios({
                url: '/server/item/update',
                method: 'post',
                data
            })
        },
        // 获取店铺信息
        async getShopInfo () {
            return axios({
                url: '/server/user/queryShopInfo',
                method: 'post',
            })
        },
        // 获取公司信息
        async getEnterpriseInfo () {
            return axios({
                url: '/server/user/queryEnterpriseInfo',
                method: 'post',
            })
        },
        // 编辑店铺信息
        async updateShopInfo (data) {
            return axios({
                url: '/server/user/updateShopInfo',
                method: 'post',
                data
            })
        },
        // 订单管理--查看详情
        async getOrderDetail (id) {
            return axios({
                url: `/server/order/orderDetailByseller/${id}`,
                headers: {
                    'content-type': 'application/x-www-form-urlencoded'
                },
                method: 'post',
            })
        },
        // 查看数据源详情
        async getDataSourceDetail (data) {
            return axios({
                url: '/server/item/dataSourceDetail',
                method: 'post',
                data
            })
        },
        // 查看源数据字典
        async getDataDictionary (data) {
            return axios({
                url: '/server/dataSource/queryRelateSources',
                method: 'post',
                data
            })
        },
        //    上传应用图片
        async uploadImg (data) {
            return axios({
                url: '/server/item/uploadApplicationImgPath',
                method: 'post',
                data
            })
        },
    
        // 上传附件
        async uploadFile (data) {
            return axios({
                url: '/server/item/uploadApplicationDemoFilePath',
                method: 'post',
                data
            })
        },
    
        // 批量删除数据源
        async deleteDataSource (data) {
            return axios({
                url: '/server/item/dataSourceBatchDelete',
                method: 'post',
                data
            })
        },
    
        // 批量导入输入源
        async batchImport (url, data) {
            return axios({
                url: url,
                method: 'post',
                data
            })
        },
    
        // 批量导入输出源
        async batchDown (data) {
            return axios({
                url: '/server/item/uploadOutputExcel',
                method: 'post',
                data
            })
        },
        // 校验能否下架
        async checkItemOff (data) {
            return axios({
                url: '/server/item/checkItemOff',
                method: 'post',
                data
            })
        },
        // 上下架
        async putOnApplication (data) {
            return axios({
                url: '/server/item/statusChange',
                method: 'post',
                data
            })
        },
        // 查看应用详情
        async getApplicationDetail (id) {
            return axios({
                url: `/server/item/itemDetail?itemId=${id}`,
                method: 'get',
            })
        },
        // 删除订单
        // async deleteOrder(id) {
        //     return axios({
        //         url: `/server/order?orderId=${id}`,
        //         method: 'delete',
        //     })
        // },
        // 获取数据源字典列表
        async getDataSourceDictionaryList(data){
            return axios({
                url: '/server/dataSource/queryPageDataDictionary',
                method: 'post',
                data
            })
        }
    }
    
    export default developerService;
    import axios from '@/utils/requestHttp';
    
    const operationService = {
        // 下载输入附件
        async downloadFileIn(url) {
            return axios({
                url: url,
                method: 'get',
                responseType: 'blob',
            });
        },
    
        // 下载输出附件
        async downloadFileOut() {
            return axios({
                url: '/server/item/downloadOutputTemp',
                method: 'get',
                responseType: 'blob',
            });
        },
        // 消費者列表
        async getApplicationList(data) {
            return axios({
                url: '/server/item/list',
                method: 'post',
                data,
            });
        },
        // 更换u盾
        async updateStatus(data) {
            return axios({
                url: '/server/user/updateUShield',
                method: 'post',
                data,
            });
        },
        // 更新额度
        async updateQuota(data) {
            return axios({
                url: '/server/user/updateQuota',
                method: 'post',
                data,
            });
        },
        // 查看额度明细
        async queryQuotaDetail(data) {
            return axios({
                url: '/server/user/queryQuotaByPage',
                method: 'post',
                data,
            });
        },
    
        // 修改用户状态--启用/禁用
        async updateUser(data) {
            return axios({
                url: '/server/user/updateUserStatus',
                method: 'post',
                data,
            });
        },
    
        // 查看详情
        async getApplicationDetail(id) {
            return axios({
                url: `/server/user/queryConsumerDetail?id=${id}`,
                method: 'get',
            });
        },
    
        //订单管理--使用明细
        async useDetail(data) {
            return axios({
                url: `/server/order/orderUserDetail/${data}`,
                method: 'post',
            });
        },
    
        // 查询资产/商品分类列表
        async getAssetsList(data) {
            return axios({
                url: `/server/sourceClassification/queryAll?classify=${data}`,
                method: 'get',
            });
        },
        // 查询资产/商品分页查询
        async querySourceClassification(data) {
            return axios({
                url: `/server/sourceClassification/querySourceClassification`,
                method: 'post',
                data,
            });
        },
    
        // 查询资产/商品分类详情
        async getAssetsDetail(data) {
            return axios({
                url: `/server/sourceClassification/queryTagsByParentId`,
                method: 'post',
                data,
            });
        },
    
        // 新增资产/商品分类
        async addAssets(data) {
            return axios({
                url: `/server/sourceClassification/addSourceClassification`,
                method: 'post',
                data,
            });
        },
    
        // 修改资产/商品分类
        async updateAssets(data) {
            return axios({
                url: `/server/sourceClassification/updateSourceClassification`,
                method: 'post',
                data,
            });
        },
    
        // 分页查询资产/商品分类
        async queryAssets(data) {
            return axios({
                url: `/server/sourceClassification/querySourceClassification`,
                method: 'post',
                data,
            });
        },
    
        // 删除资产/商品分类
        async deleteAssets(data) {
            return axios({
                url: `/server/sourceClassification/deleteSourceClassification?id=${data}`,
                method: 'delete',
            });
        },
    
        //新增标签
        async addTags(data) {
            return axios({
                url: `/server/sourceClassification/addTag`,
                method: 'post',
                data,
            });
        },
    
        // 删除标签
        async deleteTags(data) {
            return axios({
                url: `/server/sourceClassification/deleteTag?id=${data}`,
                method: 'delete',
            });
        },
    
        // 修改标签
        async updateTags(data) {
            return axios({
                url: `/server/sourceClassification/updateTag`,
                method: 'POST',
                data,
            });
        },
    };
    
    export default operationService;
    

8.下载解析 

import { operationService } from '@/api';

// 接口请求
operationService.downloadFileIn(this.batchdownloadUrl)
    .then(async (res) => {
        // 返回流文件,如果流文件的data中的type为json,那么返回的信息我们要解析出来看看是不是报错了
        if (res.data.type == 'application/json') {
            const readF = new FileReader();
            readF.readAsText(res, 'utf-8');
            readF.onload = () => {
                const { msg } = JSON.parse(readF.result);
                this.$message.error(msg);
            };
        }

        // 在返回的信息headers中读取content-disposition,再通过正则找到文件名
        const disposition = res.headers['content-disposition'];
        const matches = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(disposition);
        const filename = matches[1].replace(/['"]/g, '');
        const rfilename = decodeURI(filename);

        // 将流文件解析成具体的文件并下载
        const blob = new Blob([res.data], {
            type: 'application/vnd.ms-excel',
        });
        const url = window.URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.style.display = 'none';
        link.href = url;
        link.download = `${rfilename}`;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        this.$message({
            type: 'success',
            message: '下载模板成功!',
        });
    })
    .catch(() => {});

src / api / index.js

import operationService from './operationService';


export { operationService };

src / api / operationService.js

import axios from '@/utils/requestHttp';

const operationService = {
    // 下载输入附件
    async downloadFileIn(url) {
        return axios({
            url: url,
            method: 'get',
            responseType: 'blob',
        });
    },
};

export default operationService;

9.代码编辑器 

<div class="editorExample">
    <div class="editor">
        <editor-box
            :value="JSON.parse(JSON.stringify(codeValue, null, '\t'))"
            language="dockerfile"
            :optionsP="options"
            @change="change"
        ></editor-box>
    </div>
</div>


___________________



codeValue: '',
options: {
    enableBasicAutocompletion: true, // 启用基本自动完成
    enableSnippets: true, // 启用代码段
    enableLiveAutocompletion: true, // 启用实时自动完成
    printMarginColumn: 30,
    displayIndentGuides: false, // 显示参考线
    enableEmmet: true, // 启用Emmet
    tabSize: 6, // 标签大小
    fontSize: 14, // 设置字号
    useWorker: true, // 使用辅助对象
    showPrintMargin: false, // 去除编辑器里的竖线
    enableMultiselect: true, //     选中多处
    readOnly: false, // 是否只读
    showFoldWidgets: true, // 显示折叠部件
    fadeFoldWidgets: true, // 淡入折叠部件
    wrap: this.iswrap === 'yes' ? true : false, // 换行
},



// 接收codevalue数据
change(val) {
    let value = val;
    this.codeValue = JSON.parse(JSON.stringify(value));
},

 代码编辑器:使用vue2-ace-editor库

<template>
    <div class="echart-pie-wrap">
        <div class="myEditorTop"></div>
        <editor ref="myEditor" @init="editorInit" :value="value" width="100%" :lang="language" theme="monokai" :options="options"></editor>
    </div>
</template>

<script>
import '@/utils/archives/flexible';
import Editor from 'vue2-ace-editor';
// 主题
import 'brace/theme/monokai';
// 代码片段
import 'brace/snippets/javascript';
import 'brace/snippets/dockerfile';
import 'brace/snippets/python';
import 'brace/snippets/php';
import 'brace/snippets/html';
import 'brace/snippets/css';
import 'brace/snippets/ruby';
// 代码语言
import 'brace/mode/javascript';
import 'brace/mode/dockerfile';
import 'brace/mode/python';
import 'brace/mode/php';
import 'brace/mode/html';
import 'brace/mode/ruby';
import 'brace/mode/css';
// 语言扩展
import 'brace/ext/language_tools';
import 'brace/ext/emmet';
import 'brace/ext/beautify';
import 'brace/ext/searchbox';
import 'brace/ext/chromevox';
import 'brace/ext/error_marker';
import 'brace/ext/keybinding_menu';
import 'brace/ext/linking';
import 'brace/ext/modelist';
import 'brace/ext/old_ie';
import 'brace/ext/settings_menu';
import 'brace/ext/spellcheck';
import 'brace/ext/split';
import 'brace/ext/static_highlight';
import 'brace/ext/statusbar';
import 'brace/ext/whitespace';
import 'brace/ext/textarea';
import 'brace/ext/themelist';
export default {
    components: {
        Editor,
    },

    props: {
        title: { type: String, default: '编辑器' },
        value: { type: String, default: '' },
        language: { type: String, default: 'html' },
        iswrap: { type: String, default: 'no' },
        optionsP: { type: Object, default: {} },
    },

    model: {
        prop: 'value',
        event: 'change',
    },
    data() {
        return {
            options: {
                enableBasicAutocompletion: true, // 启用基本自动完成
                enableSnippets: true, // 启用代码段
                enableLiveAutocompletion: true, // 启用实时自动完成
                printMarginColumn: 30,
                displayIndentGuides: false, // 显示参考线
                enableEmmet: true, // 启用Emmet
                tabSize: 6, // 标签大小
                fontSize: 14, // 设置字号
                useWorker: true, // 使用辅助对象
                showPrintMargin: false, // 去除编辑器里的竖线
                enableMultiselect: true, //     选中多处
                readOnly: true, // 是否只读
                showFoldWidgets: true, // 显示折叠部件
                fadeFoldWidgets: true, // 淡入折叠部件
                wrap: this.iswrap === 'yes' ? true : false, // 换行
            },
        };
    },
    watch: {
        optionsP: {
            handler(newVal) {
                this.options = newVal;
            },
            deep: true,
            immediate: true,
        },
    },
    methods: {
        editorInit: function (editor) {
            editor.getSession().on('change', (val) => {
                let data = editor.getValue();
                this.$emit('change', data);
            });
        },
        format() {
            const ace = require('brace');
            const editor = this.$refs.codeEditor.editor;
            const beautify = ace.acequire('ace/ext/beautify');
            beautify.beautify(editor.session);
        },
    },
};
</script>

<style lang="scss" scoped>
.echart-pie-wrap {
    width: 100%;
    height: 100%;
    margin-bottom: 0.475rem;
    .myEditorTop {
        height: 0.3125rem;
        display: flex;
        align-items: center;
        background-color: #333;
        padding-left: 0.625rem;
        color: rgb(241, 238, 8);
        font-weight: bold;
    }
}
</style>

10.laoding的使用,表格格式化

<!-- 表格 -->
<el-table
    v-loading="dataListLoading"
    :data="dataList"
    @selection-change="dataListSelectionChangeHandle"
    style="width: 100%"
    :header-cell-style="{ 'font-weight': '600' }"
>
    <!-- <el-table-column type="selection" header-align="left" align="left" width="50"></el-table-column> -->
    <el-table-column prop="id" label="数据库编号" header-align="left" align="left"></el-table-column>
    <el-table-column prop="baseName" label="数据库名称" header-align="left" align="left"></el-table-column>
    // 表格数据的解析
    <el-table-column prop="baseType" label="数据库类型" :formatter="typeDataTable" header-align="left" align="left"></el-table-column>
    <el-table-column prop="createTime" label="录入时间" header-align="left" align="left"></el-table-column>
    <el-table-column prop="nodeIp" label="节点IP" header-align="left" align="left"></el-table-column>
    // 表格数据解析,通过函数返回值的形式
    <el-table-column prop="nodeStatus" label="节点状态" header-align="left" align="left">
        <template slot-scope="scope">
            <span :class="typeSpotClass(scope.row)" style="width: 7px; height: 7px; border-radius: 50%; display: inline-block"></span>
            <span :class="typeDataClass(scope.row)">{{ nodeStatusType(scope.row) }}</span>
        </template>
    </el-table-column>
    <el-table-column :label="$t('handle')" fixed="right" header-align="left" align="left" width="160">
        <template slot-scope="scope">
            <el-button class="table-operate-btn" type="text" size="small" @click="toInfo(scope.row)"> 查看 </el-button>
            <el-button class="table-operate-btn" type="text" size="small" @click="toUpdata(scope.row)"> 编辑 </el-button>
            <el-tooltip placement="right" content="删除数据库,需输入PIN码">
                <el-button class="table-operate-btn" type="text" size="small" @click="deleteHandle(scope.row)">
                    {{ $t('deleteBatch') }}
                </el-button>
            </el-tooltip>
        </template>
    </el-table-column>
</el-table>



————————————————————————————————



dataListLoading: false, // 数据列表,loading状态




// 获取数据列表
query() {
    this.dataListLoading = true;
    axios
        .post(this.mixinViewModuleOptions.getDataListURL, {
            current: this.mixinViewModuleOptions.getDataListIsPage ? this.current : 1, // 当前页码
            size: this.mixinViewModuleOptions.getDataListIsPage ? this.size : 10, // 每页多少条
            ...this.dataForm
        })
        .then(({ data }) => {
            this.dataListLoading = false;
            if (data.code !== 0) {
                this.dataList = [];
                this.total = 0;
                return;
            }
            this.dataList = this.mixinViewModuleOptions.getDataListIsPage ? data.data.records || data.data.list : [data.data];
            this.total = this.mixinViewModuleOptions.getDataListIsPage ? parseInt(data.data.total) : 0;
        })
        .catch(() => {
            this.dataListLoading = false;
            this.dataList = [];
            this.total = 0;
            this.$message.error('服务器异常,请联系管理员');
        });
},


// 数据库类型格式
typeDataTable(row) {
    if (row.baseType === 'MYSQL5.7' || row.baseType === '1' || row.baseType === 'MYSQL') {
        return 'MYSQL5.7';
    } else if (row.baseType === 'POSTGRE' || row.baseType === '2') {
        return 'POSTGRE';
    } else {
        return '';
    }
},
// 节点前的原点
typeSpotClass(row) {
    if (row.nodeStatus == 1) {
        return 'tobe-reviewed-spot';
    } else if (row.nodeStatus == 2) {
        return 'success-spot';
    } else {
        return '';
    }
},
// 节点状态颜色
typeDataClass(row) {
    if (row.nodeStatus == 1) {
        return 'tobe-reviewed';
    } else if (row.nodeStatus == 2) {
        return 'success';
    } else {
        return '';
    }
},
// 节点状态内容格式
nodeStatusType(row) {
    if (row.nodeStatus == 1) {
        return '等待部署';
    } else if (row.nodeStatus == 2) {
        return '在线';
    } else {
        return '';
    }
},

11.表单域文字描述前缀插槽

 

<el-form-item>
    <span slot="label">
        <span class="span-box">
            <span class="avatar">密码 :</span>
            <i class="el-icon-dish-1 ico-eye" v-if="!isShowPassword" @click="switchStatus"></i>
            <i class="el-icon-dish-1 ico-pre" v-else @click="switchStatus"></i>
        </span>
    </span>
    <span v-if="!isShowPassword">**********</span>
    <span v-else>{{ toInfoData.password }}</span>
</el-form-item>


——————————————————————————


isShowPassword: false,


switchStatus() {
    this.isShowPassword = !this.isShowPassword;
},

 12.按钮自点击

<!-- 表格 -->
<el-table
    v-loading="dataListLoading"
    ref="multipleTable"
    :data="dataList"
    @selection-change="dataListSelectionChangeHandle"
    style="width: 100%"
    :header-cell-style="{ 'font-weight': '600' }"
>
    <el-table-column prop="id" label="节点编号" header-align="left" align="left"></el-table-column>
    <el-table-column prop="nodeName" label="节点名称" header-align="left" align="left"></el-table-column>
    <el-table-column prop="nodeIp" label="节点IP" header-align="left" align="left"></el-table-column>
    <el-table-column prop="nodeCreateTime" label="创建时间" header-align="left" align="left"></el-table-column>
    <el-table-column prop="nodeUpdateTime" label="更新时间" header-align="left" align="left"></el-table-column>
    <el-table-column prop="status" label="节点状态" header-align="left" align="left">
        <template slot-scope="scope">
            <span
                :class="typeSpotClass(scope.row.status)"
                style="width: 7px; height: 7px; border-radius: 50%; display: inline-block"
            ></span>
            <span :class="typeDataClass(scope.row.status)">{{ typeData(scope.row) }}</span>
            <el-button v-show="false" id="selectedNode" type="text" size="small" @click="saveNOdeInfo(scope.row)">
                查看
            </el-button>
        </template>
    </el-table-column>
</el-table>



————————————————————————————————————————


// 下一步
async nextStep() {
    if (this.dataList[0].status != 2) {
        return this.$message.warning('请先部署好节点,再新建数据库');
    }
    if (this.currentStep === 0) {
        const btn = document.getElementById('selectedNode');
        btn.click();
    }
    this.currentStep++;
},

 13.动态表单域

 

后端返回的数据

// label-position="right":字段描述位于label内部右边位置
<el-form label-position="right" :model="databaseForm" :rules="dataRule" ref="databaseFormRef" label-width="380px">
    <el-form-item label="数据库类型:" prop="databaseType">
        <el-select
            v-model="databaseForm.databaseType"
            placeholder="请选择数据库类型"
            @change="getInfo"
            :style="{ width: '90%' }"
            clearable
        >
            <el-option
                v-for="(item, index) in typeOptions"
                :key="index"
                :label="item.label"
                :value="item.value"
                :disabled="item.disabled"
            ></el-option>
        </el-select>
    </el-form-item>
    <el-form-item label="数据库名称:" :rules="requiredType" prop="baseName">
        <el-input
            v-model="databaseForm.baseName"
            placeholder="请输入数据库名称"
            :style="{ width: '90%' }"
            clearable
        ></el-input>
    </el-form-item>
    <el-form-item label="数据库实例名称:" :rules="requiredType" prop="databaseName">
        <el-input
            v-model="databaseForm.databaseName"
            placeholder="请输入数据库名称"
            :style="{ width: '90%' }"
            clearable
        ></el-input>
        &nbsp;&nbsp;&nbsp;
        <el-popover placement="right" width="400" trigger="hover">
            <span slot="reference" :style="{ cursor: 'pointer' }">
                <i class="el-icon-warning-outline"></i>
            </span>
            <p v-html="encryptionAgreement"></p>
        </el-popover>
    </el-form-item>

    // rules是el-form-item上的一个属性,用来做表单验证规则。此处以函数返回值的方式处理。
    <el-form-item v-for="item in inputList" :key="item.key" :label="item.desc" :rules="inputBoxCheck(item)" :prop="item.key">
        // :show-password="item.key == 'password'":当对象的key是‘password’时启动密码框
        // autocomplete="new-password":关闭密码框自动与chrome联动的功能
        <el-input
            :show-password="item.key == 'password'"
            autocomplete="new-password"
            v-model="databaseForm[item.key]"
            :placeholder="item.defaultValue"
            :style="{ width: '90%' }"
            clearable
        ></el-input>
    </el-form-item>
</el-form>




————————————————————————————————————






// 选择数据库录入模块的表单
databaseForm: {
    current: 1,
    databaseType: '',
    baseName: '',
    databaseName: '',
    size: 10,
},
// 数据库类型下拉选项
typeOptions: [
    {
        label: 'MYSQL5.7',
        value: 1,
    },
    {
        label: 'POSTGRE',
        value: 2,
    },
],
requiredType: [{ required: true, message: this.$t('validate.required'), trigger: 'blur' }], // 必填校验
inputList: [], // 输入列表
numberType: [
    {
        validator: function (rule, value, callback) {
            if (/^[0-9]*$/.test(value) === false) {
                callback(new Error('请输入数字'));
            } else {
                // 校验通过
                callback();
            }
        },
        trigger: 'blur',
    },
],
booleanType: [
    {
        validator: function (rule, value, callback) {
            if (value !== 'false' && value !== 'true') {
                callback(new Error('请输入布尔值true或false'));
            } else {
                // 校验通过
                value = value === 'true' ? true : false;
                callback();
            }
        },
        trigger: 'blur',
    },
],




// 监听数据库类型
watch: {
    'databaseForm.databaseType'(newVal) {
        if (!newVal) {
            this.inputList = [];
        }
    },
},



// 计算属性内也可以放数据-校验规则
computed: {
    dataRule() {
        return {
            databaseType: [{ required: true, message: this.$t('validate.required'), trigger: 'change' }],

    },
},




// 选择数据库类型
async getInfo(code) {
    try {
        const { data } = await supplierService.queryDatabaseTemplate({ templateDatabaseType: code });
        data.data.templateInfoList.forEach((item) => {
            item.defaultValue = item.defaultValue == false ? 'false' : item.defaultValue;
            item.defaultValue = item.defaultValue == true ? 'true' : item.defaultValue;
            this.$set(this.databaseForm, item.key, item.defaultValue);
        });
        this.inputList = data.data.templateInfoList;
    } catch (error) {
        this.inputList = [];
    }
},
// 输入框核验
inputBoxCheck(item) {
    if (item.required === 'true') {
        if (item.type == 'string') {
            return this.requiredType;
        } else if (item.type == 'number') {
            return [...this.requiredType, ...this.numberType];
        } else if (item.type == 'boolean') {
            return this.booleanType;
        }
    } else {
        if (item.type == 'string') {
            return [];
        } else if (item.type == 'number') {
            return this.numberType;
        } else if (item.type == 'boolean') {
            return this.booleanType;
        }
    }
},

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值