Kaynağa Gözat

页面级组件

喻文俊 3 yıl önce
ebeveyn
işleme
1b27f4ca68

+ 162 - 0
src/views/components/authCardTemplate.vue

@@ -0,0 +1,162 @@
+<template>
+  <el-radio-group v-model="radio" size="mini" class="auth-card-template" @change="handleRadioChange">
+    <el-row :gutter="16">
+      <el-col :span="8">
+        <img class="cover" :src="authCard1" alt="">
+        <div class="footer">
+          <el-radio :label="1">模板一</el-radio>
+          <el-button type="primary" size="mini" round @click="preview(1)">预览</el-button>
+        </div>
+      </el-col>
+      <el-col :span="8">
+        <img class="cover" :src="authCard2" alt="">
+        <div class="footer">
+          <el-radio :label="2">模板二</el-radio>
+          <el-button type="primary" size="mini" round @click="preview(2)">预览</el-button>
+        </div>
+      </el-col>
+      <el-col :span="8">
+        <img class="cover" :src="authCard3" alt="">
+        <div class="footer">
+          <el-radio :label="3">模板三</el-radio>
+          <el-button type="primary" size="mini" round @click="preview(3)">预览</el-button>
+        </div>
+      </el-col>
+    </el-row>
+
+    <el-dialog :visible.sync="dialogVisible">
+      <div class="preview">
+        <img :src="previewUrl" alt="">
+        <img v-show="showQrcode" class="qrcode" :class="['type' + previewType]" :src="qrcodeUrl">
+      </div>
+    </el-dialog>
+  </el-radio-group>
+</template>
+
+<script>
+import QRCode from 'qrcode'
+import authCard1 from '@/assets/img/auth-card-placeholder-01.png'
+import authCard2 from '@/assets/img/auth-card-placeholder-02.png'
+import authCard3 from '@/assets/img/auth-card-placeholder-03.png'
+export default {
+  model: {
+    event: 'change',
+    prop: 'radio'
+  },
+  props: {
+    imageList: {
+      type: Array,
+      default: () => []
+    },
+    showQrcode: {
+      type: Boolean,
+      default: true
+    },
+    radio: {
+      type: Number,
+      default: 1
+    }
+  },
+  data() {
+    return {
+      authCard1,
+      authCard2,
+      authCard3,
+      previewUrl: '',
+      dialogVisible: false,
+      previewType: -1,
+      qrcodeUrl: ''
+    }
+  },
+  computed: {
+    drawImage() {
+      return this.imageList[0].url
+    }
+  },
+  created() {
+    this.drawQrcode()
+  },
+  methods: {
+    handleRadioChange() {
+      this.$emit('change', this.radio)
+    },
+
+    async drawQrcode() {
+      const options = {
+        width: 192,
+        height: 192,
+        margin: 1
+      }
+
+      this.qrcodeUrl = await QRCode.toDataURL('undefined', options)
+
+      console.log(this.qrcodeUrl)
+    },
+
+    preview(type) {
+      this.previewType = type
+      this.dialogVisible = true
+      this.previewUrl = this.drawImage
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.auth-card-template{
+  width: 100%;
+
+  .cover{
+    width: 100%;
+    display: block;
+  }
+
+  .footer{
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-top: 16px;
+    padding:0 8px;
+  }
+}
+
+.preview{
+  max-width: 920px;
+  max-height: 690px;
+  position: relative;
+  overflow: hidden;
+  img{
+    width: 100%;
+    max-height: 100%;
+    display: block;
+    position: relative;
+    z-index: 5;
+  }
+  .qrcode{
+    width: 100px;
+    height: 100px;
+    position: absolute;
+
+    z-index: 9;
+
+    background: red;
+
+    &.type1{
+      bottom: 70px;
+      left: 70px;
+    }
+
+    &.type3{
+      top: 50%;
+      transform: translateY(-50%);
+      left: 70px;
+    }
+
+    &.type2{
+      top: 50%;
+      transform: translateY(-50%);
+      right: 70px;
+    }
+  }
+}
+</style>

+ 164 - 0
src/views/components/deviceSection.vue

@@ -0,0 +1,164 @@
+<template>
+  <div class="device-section">
+    <div v-for="formData in formDataList" :key="formData.key" class="section">
+      <i v-if="formDataList.length > 1" class="el-icon-close remove" title="移除该项" @click="removeOne(formData)" />
+      <el-form :ref="'form' + formData.uuid" label-width="90px" :model="formData" :rules="rules">
+        <el-form-item label="设备名称:" prop="equipmentName">
+          <el-input v-model="formData.equipmentName" placeholder="设备名称" :maxlength="50" type="text" />
+        </el-form-item>
+        <el-form-item label="所属品牌:" prop="brand">
+          <el-input v-model="formData.brand" placeholder="所属品牌" />
+        </el-form-item>
+        <el-form-item label="设备图片:" prop="image">
+          <el-input v-show="false" v-model="formData.image" placeholder="设备图片" />
+          <upload-image
+            tip="建议尺寸:542px * 542px"
+            :image-list="formData.imageList"
+            :before-upload="beforeImageUpload"
+            @success="uploadImageSuccess($event, formData)"
+            @remove="handleImageRemove($event, formData)"
+          />
+        </el-form-item>
+      </el-form>
+    </div>
+    <el-button type="primary" size="mini" round @click="insertOne">添加设备</el-button>
+  </div>
+</template>
+
+<script>
+import UploadImage from '@/components/UploadImage'
+export default {
+  name: 'DeviceSection',
+  components: {
+    UploadImage
+  },
+  props: {
+    list: {
+      type: Array,
+      default: () => []
+    }
+  },
+  data() {
+    return {
+      uuid: 0, // key
+      formDataList: [],
+      rules: {
+        equipmentName: [{ required: true, message: '设备名称不能为空', trigger: ['blur', 'change'] }],
+        brand: [{ required: true, message: '所属品牌不能为空', trigger: ['blur', 'change'] }],
+        image: [{ required: true, message: '请上传设备图片', trigger: 'change' }]
+      }
+    }
+  },
+  created() {
+    this.init()
+  },
+  methods: {
+    init() {
+      // 监听表单数据列表边变化
+      this.$watch(
+        () => this.formDataList,
+        newVal => {
+          this.$emit('change', newVal)
+        }, { deep: true }
+      )
+      // 初始化表单列表
+      this.initFormData()
+    },
+    // 表单验证
+    valideAllForm() {
+      const validateList = []
+      for (const key in this.$refs) {
+        if (key.indexOf('form') > -1 && Object.hasOwnProperty.call(this.$refs, key)) {
+          const form = this.$refs[key][0]
+          if (form) {
+            validateList.push(form.validate())
+          }
+        }
+      }
+      return Promise.all(validateList)
+    },
+    // 初始化表单
+    initFormData() {
+      if (this.list.length <= 0) {
+        this.insertOne()
+      } else {
+        this.formDataList = this.makeUuid(this.list)
+      }
+    },
+    // 出入一条表单数据
+    insertOne() {
+      this.uuid++
+      this.formDataList.push({
+        uuid: this.uuid,
+        equipmentName: '',
+        brand: '',
+        image: '',
+        imageList: []
+      })
+    },
+    // 删除一条表单数据
+    removeOne(formData) {
+      const findIndex = this.formDataList.findIndex(item => item.uuid === formData.uuid)
+      this.formDataList.splice(findIndex, 1)
+      console.log(this.formDataList)
+    },
+    // 初始化列表uuid
+    makeUuid(list = []) {
+      return list.map((item, index) => {
+        const obj = { uuid: index, imageList: [], ...item }
+        if (item.image) {
+          obj.imageList.push({ name: '', url: item.image })
+        }
+        return obj
+      })
+    },
+    // 设备图片上传
+    uploadImageSuccess({ response, file, fileList }, current) {
+      current.image = response.data
+      current.imageList.splice(0, current.imageList.length, ...fileList)
+    },
+    // 设备图片移除
+    handleImageRemove({ file, fileList }, current) {
+      current.image = ''
+      current.imageList.splice(0, current.imageList.length, ...fileList)
+    },
+    // 上传图片限制
+    beforeImageUpload(file) {
+      const flag = file.size / 1024 / 1024 < 1
+      if (!flag) {
+        this.$message.error('上传banner图片大小不能超过 1MB!')
+      }
+      return flag
+    }
+  }
+}
+</script>
+
+<style scoped lang="scss">
+.device-section {
+  .section {
+    position: relative;
+    border: 1px solid #eee;
+    padding: 25px 25px 0 16px;
+    margin-bottom: 16px;
+    .remove {
+      position: absolute;
+      right: 6px;
+      top: 6px;
+      font-size: 14px;
+      cursor: pointer;
+      background: #f56c6c;
+      color: #fff;
+      padding: 2px;
+      border-radius: 50%;
+      transition: all 0.2s;
+      &:hover {
+        background: red;
+      }
+    }
+  }
+  .el-form-item {
+    padding-bottom: 25px;
+  }
+}
+</style>

+ 108 - 0
src/views/components/uploadFile.vue

@@ -0,0 +1,108 @@
+<template>
+  <div>
+    <el-upload
+      ref="upload"
+      class="upload-demo"
+      :limit="1"
+      :data="params"
+      :action="action"
+      :file-list="fileList"
+      :auto-upload="false"
+      :headers="headers"
+      :on-success="success"
+      :accept="accept"
+      :before-upload="beforeUpload"
+      :on-remove="remove"
+      :on-change="change"
+    >
+      <el-button slot="trigger" size="mini" type="primary">选取文件</el-button>
+      <!-- <el-button style="margin-left: 10px;" size="mini" type="success" @click="uploadFile">上传</el-button> -->
+      <div slot="tip" class="el-upload__tip">{{ tipTitle }}</div>
+    </el-upload>
+  </div>
+</template>
+
+<script>
+import { mapGetters } from 'vuex'
+export default {
+  props: {
+    fileList: {
+      type: Array,
+      default: () => []
+    },
+    authUserId: {
+      type: Number,
+      default: -1
+    },
+    brandId: {
+      type: [Number, String],
+      default: 0
+    },
+    tipTitle: {
+      type: String,
+      default: '只能上传.doc/.ppt/.pdf文件,建议大小在10M内'
+    }
+  },
+
+  data() {
+    return {
+      // 文件上传接口
+      action: process.env.VUE_APP_UPLOAD_API + '/shop/upload/file',
+      accept: '.doc,.ppt,.pdf',
+      // 请求参数
+      // params: {
+      //   authUserId: null,
+      //   brandId: this.brandId || 0
+      // },
+      headers: {
+        'X-Token': ''
+      },
+      showUpload: true
+    }
+  },
+  computed: {
+    ...mapGetters(['token']),
+    params() {
+      return {
+        authUserId: null,
+        brandId: this.brandId || 0
+      }
+    }
+  },
+  created() {
+    this.headers['X-Token'] = this.token
+  },
+  methods: {
+    success(response) {
+      this.$emit('success', response)
+    },
+    error(err, file, fileList) {
+      this.$emit('error', err, file, fileList)
+    },
+    uploadFile() {
+      this.params.authUserId = this.authUserId || -1
+      this.$refs.upload.submit()
+    },
+    // 文件上传之前的钩子
+    beforeUpload(file) {
+      this.params.authUserId = this.authUserId || -1
+      const size = file.size
+      if (size > 1024 * 5000) {
+        const h = this.$createElement
+        this.$notify.info({
+          title: '上传文件过大',
+          message: h('p', { style: 'color: #333' }, '文件上传保存需要一定的时间,请您耐心等待,在此期间请勿执执行其他操作,以免影响文件上传失败!'),
+          duration: 5000
+        })
+      }
+    },
+    remove() {
+      this.$emit('remove')
+    },
+    change() {
+      this.$emit('change')
+    }
+  }
+}
+</script>
+

+ 101 - 0
src/views/components/uploadImage.vue

@@ -0,0 +1,101 @@
+<template>
+  <div class="img-upload-box">
+    <el-upload
+      ref="upload"
+      :action="action"
+      :headers="headers"
+      list-type="picture-card"
+      :on-preview="handlePictureCardPreview"
+      :before-upload="beforeUpload"
+      :limit="1"
+      :accept="accept"
+      :auto-upload="true"
+      :on-success="success"
+      :on-remove="remove"
+      :file-list="fileList"
+    >
+      <!-- :class="{hidden:(hasUpload && fileList===[]) || !hasUpload}" -->
+      <div slot="tip" class="el-upload__tip">建议尺寸:{{ tipTitle }}</div>
+      <i class="el-icon-picture-outline" />
+    </el-upload>
+    <el-dialog :visible.sync="dialogVisible">
+      <img width="100%" :src="dialogImageUrl" alt="">
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+// import { uploadImage } from '@/api/upload'
+import { mapGetters } from 'vuex'
+export default {
+  props: {
+    fileList: {
+      type: Array,
+      default: () => []
+    },
+    tipTitle: {
+      type: String,
+      default: '128px*88px'
+    }
+  },
+  data() {
+    return {
+      dialogImageUrl: '',
+      dialogVisible: false,
+      // 文件上传请求接口
+      action: process.env.VUE_APP_UPLOAD_API + '/upload/image',
+      headers: {
+        'X-Token': ''
+      },
+      accept: '.jpg,.png,.gif'
+    }
+  },
+  computed: {
+    ...mapGetters(['token'])
+  },
+  created() {
+    this.headers['X-Token'] = this.token
+  },
+  methods: {
+    // 预览图片
+    handlePictureCardPreview(file) {
+      this.dialogImageUrl = file.url
+      this.dialogVisible = true
+    },
+    // 图片上传成功
+    success(response, file, fileList) {
+      this.$emit('success', response)
+    },
+    // 图片上传失败
+    error(err, file, fileList) {
+      this.$emit('error', err, file, fileList)
+    },
+    // 图片上传之前的钩子
+    beforeUpload(file) {
+      const size = file.size
+      if (size > 1024 * 1000) {
+        this.$message.warning('文件上传大小超出限制(≤1MB)')
+        return false
+      }
+    },
+    remove() {
+      this.$emit('remove')
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.img-upload-box{
+  width:150px;
+  height:180px;
+  overflow: hidden
+}
+.img-upload-box>div{
+  white-space: nowrap;
+}
+.img-upload-box .el-upload-list{
+  height: 150px;
+  display: inline-block;
+}
+</style>