Przeglądaj źródła

完成 vue 的添加/修改表单部分的模板

YunaiV 4 lat temu
rodzic
commit
ab09b7c67e

+ 179 - 0
ruoyi-ui/src/components/FileUpload/index.vue

@@ -0,0 +1,179 @@
+<template>
+  <div class="upload-file">
+    <el-upload
+      :action="uploadFileUrl"
+      :before-upload="handleBeforeUpload"
+      :file-list="fileList"
+      :limit="1"
+      :on-error="handleUploadError"
+      :on-exceed="handleExceed"
+      :on-success="handleUploadSuccess"
+      :show-file-list="false"
+      :headers="headers"
+      class="upload-file-uploader"
+      ref="upload"
+    >
+      <!-- 上传按钮 -->
+      <el-button size="mini" type="primary">选取文件</el-button>
+      <!-- 上传提示 -->
+      <div class="el-upload__tip" slot="tip" v-if="showTip">
+        请上传
+        <template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
+        <template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
+        的文件
+      </div>
+    </el-upload>
+
+    <!-- 文件列表 -->
+    <transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
+      <li :key="file.uid" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in list">
+        <el-link :href="file.url" :underline="false" target="_blank">
+          <span class="el-icon-document"> {{ getFileName(file.name) }} </span>
+        </el-link>
+        <div class="ele-upload-list__item-content-action">
+          <el-link :underline="false" @click="handleDelete(index)" type="danger">删除</el-link>
+        </div>
+      </li>
+    </transition-group>
+  </div>
+</template>
+
+<script>
+import { getToken } from "@/utils/auth";
+
+export default {
+  props: {
+    // 值
+    value: [String, Object, Array],
+    // 大小限制(MB)
+    fileSize: {
+      type: Number,
+      default: 5,
+    },
+    // 文件类型, 例如['png', 'jpg', 'jpeg']
+    fileType: {
+      type: Array,
+      default: () => ["doc", "xls", "ppt", "txt", "pdf"],
+    },
+    // 是否显示提示
+    isShowTip: {
+      type: Boolean,
+      default: true
+    }
+  },
+  data() {
+    return {
+      uploadFileUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
+      headers: {
+        Authorization: "Bearer " + getToken(),
+      },
+      fileList: [],
+    };
+  },
+  computed: {
+    // 是否显示提示
+    showTip() {
+      return this.isShowTip && (this.fileType || this.fileSize);
+    },
+    // 列表
+    list() {
+      let temp = 1;
+      if (this.value) {
+        // 首先将值转为数组
+        const list = Array.isArray(this.value) ? this.value : [this.value];
+        // 然后将数组转为对象数组
+        return list.map((item) => {
+          if (typeof item === "string") {
+            item = { name: item, url: item };
+          }
+          item.uid = item.uid || new Date().getTime() + temp++;
+          return item;
+        });
+      } else {
+        this.fileList = [];
+        return [];
+      }
+    },
+  },
+  methods: {
+    // 上传前校检格式和大小
+    handleBeforeUpload(file) {
+      // 校检文件类型
+      if (this.fileType) {
+        let fileExtension = "";
+        if (file.name.lastIndexOf(".") > -1) {
+          fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
+        }
+        const isTypeOk = this.fileType.some((type) => {
+          if (file.type.indexOf(type) > -1) return true;
+          if (fileExtension && fileExtension.indexOf(type) > -1) return true;
+          return false;
+        });
+        if (!isTypeOk) {
+          this.$message.error(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);
+          return false;
+        }
+      }
+      // 校检文件大小
+      if (this.fileSize) {
+        const isLt = file.size / 1024 / 1024 < this.fileSize;
+        if (!isLt) {
+          this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`);
+          return false;
+        }
+      }
+      return true;
+    },
+    // 文件个数超出
+    handleExceed() {
+      this.$message.error(`只允许上传单个文件`);
+    },
+    // 上传失败
+    handleUploadError(err) {
+      this.$message.error("上传失败, 请重试");
+    },
+    // 上传成功回调
+    handleUploadSuccess(res, file) {
+      this.$message.success("上传成功");
+      this.$emit("input", res.url);
+    },
+    // 删除文件
+    handleDelete(index) {
+      this.fileList.splice(index, 1);
+      this.$emit("input", '');
+    },
+    // 获取文件名称
+    getFileName(name) {
+      if (name.lastIndexOf("/") > -1) {
+        return name.slice(name.lastIndexOf("/") + 1).toLowerCase();
+      } else {
+        return "";
+      }
+    }
+  },
+  created() {
+    this.fileList = this.list;
+  },
+};
+</script>
+
+<style scoped lang="scss">
+.upload-file-uploader {
+  margin-bottom: 5px;
+}
+.upload-file-list .el-upload-list__item {
+  border: 1px solid #e4e7ed;
+  line-height: 2;
+  margin-bottom: 10px;
+  position: relative;
+}
+.upload-file-list .ele-upload-list__item-content {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  color: inherit;
+}
+.ele-upload-list__item-content-action .el-link {
+  margin-right: 10px;
+}
+</style>

+ 100 - 0
ruoyi-ui/src/components/ImageUpload/index.vue

@@ -0,0 +1,100 @@
+<template>
+  <div class="component-upload-image">
+    <el-upload
+      :action="uploadImgUrl"
+      list-type="picture-card"
+      :on-success="handleUploadSuccess"
+      :before-upload="handleBeforeUpload"
+      :on-error="handleUploadError"
+      name="file"
+      :show-file-list="false"
+      :headers="headers"
+      style="display: inline-block; vertical-align: top"
+    >
+      <el-image v-if="!value" :src="value">
+        <div slot="error" class="image-slot">
+          <i class="el-icon-plus" />
+        </div>
+      </el-image>
+      <div v-else class="image">
+        <el-image :src="value" :style="`width:150px;height:150px;`" fit="fill"/>
+        <div class="mask">
+          <div class="actions">
+            <span title="预览" @click.stop="dialogVisible = true">
+              <i class="el-icon-zoom-in" />
+            </span>
+            <span title="移除" @click.stop="removeImage">
+              <i class="el-icon-delete" />
+            </span>
+          </div>
+        </div>
+      </div>
+    </el-upload>
+    <el-dialog :visible.sync="dialogVisible" title="预览" width="800" append-to-body>
+      <img :src="value" style="display: block; max-width: 100%; margin: 0 auto;">
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { getToken } from "@/utils/auth";
+
+export default {
+  data() {
+    return {
+      dialogVisible: false,
+      uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
+      headers: {
+        Authorization: "Bearer " + getToken(),
+      },
+    };
+  },
+  props: {
+    value: {
+      type: String,
+      default: "",
+    },
+  },
+  methods: {
+    removeImage() {
+      this.$emit("input", "");
+    },
+    handleUploadSuccess(res) {
+      this.$emit("input", res.url);
+      this.loading.close();
+    },
+    handleBeforeUpload() {
+      this.loading = this.$loading({
+        lock: true,
+        text: "上传中",
+        background: "rgba(0, 0, 0, 0.7)",
+      });
+    },
+    handleUploadError() {
+      this.$message({
+        type: "error",
+        message: "上传失败",
+      });
+      this.loading.close();
+    },
+  },
+  watch: {},
+};
+</script>
+
+<style scoped lang="scss">
+.image {
+  position: relative;
+  .mask {
+    opacity: 0;
+    position: absolute;
+    top: 0;
+    width: 100%;
+    background-color: rgba(0, 0, 0, 0.5);
+    transition: all 0.3s;
+  }
+  &:hover .mask {
+    opacity: 1;
+  }
+}
+</style>

+ 25 - 49
src/main/resources/codegen/vue/views/index.vue.vm

@@ -20,7 +20,7 @@
         <el-select v-model="queryParams.${javaField}" placeholder="请选择${comment}" clearable size="small">
     #if ("" != $dictType)## 设置了 dictType 数据字典的情况
           <el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
-                       :key="parseInt(dict.dictValue)" :label="dict.dictLabel" :value="parseInt(dict.dictValue)"/>
+                       :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue"/>
     #else## 未设置 dictType 数据字典的情况
           <el-option label="请选择字典生成" value="" />
     #end
@@ -116,80 +116,56 @@
           <el-input v-model="form.${javaField}" placeholder="请输入${comment}" />
         </el-form-item>
   #end
-#elseif($column.htmlType == "imageUpload")
+#elseif($column.htmlType == "imageUpload")## 图片上传
         <el-form-item label="${comment}">
           <imageUpload v-model="form.${javaField}"/>
         </el-form-item>
-#elseif($column.htmlType == "fileUpload")
+#elseif($column.htmlType == "fileUpload")## 文件上传
         <el-form-item label="${comment}">
           <fileUpload v-model="form.${javaField}"/>
         </el-form-item>
-#elseif($column.htmlType == "editor")
+#elseif($column.htmlType == "editor")## 文本编辑器
         <el-form-item label="${comment}">
           <editor v-model="form.${javaField}" :min-height="192"/>
         </el-form-item>
-#elseif($column.htmlType == "select" && "" != $dictType)
-        <el-form-item label="${comment}" prop="${javaField}">
-          <el-select v-model="form.${javaField}" placeholder="请选择${comment}">
-            <el-option
-              v-for="dict in ${javaField}Options"
-              :key="dict.dictValue"
-              :label="dict.dictLabel"
-              #if($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.dictValue)"#else:value="dict.dictValue"#end
-
-            ></el-option>
-          </el-select>
-        </el-form-item>
-#elseif($column.htmlType == "select" && $dictType)
+#elseif($column.htmlType == "select")## 下拉框
         <el-form-item label="${comment}" prop="${javaField}">
           <el-select v-model="form.${javaField}" placeholder="请选择${comment}">
+    #if ("" != $dictType)## 有数据字典
+            <el-option v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
+                       :key="dict.value" :label="dict.label" #if ($column.javaType == "Integer" || $column.javaType == "Long"):value="parseInt(dict.value)"#else:value="dict.value"#end />
+    #else##没数据字典
             <el-option label="请选择字典生成" value="" />
+    #end
           </el-select>
         </el-form-item>
-#elseif($column.htmlType == "checkbox" && "" != $dictType)
-        <el-form-item label="${comment}">
-          <el-checkbox-group v-model="form.${javaField}">
-            <el-checkbox
-              v-for="dict in ${javaField}Options"
-              :key="dict.dictValue"
-              :label="dict.dictValue">
-              {{dict.dictLabel}}
-            </el-checkbox>
-          </el-checkbox-group>
-        </el-form-item>
-#elseif($column.htmlType == "checkbox" && $dictType)
+#elseif($column.htmlType == "checkbox")## 多选框
         <el-form-item label="${comment}">
           <el-checkbox-group v-model="form.${javaField}">
+    #if ("" != $dictType)## 有数据字典
+            <el-checkbox v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
+                         :key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-checkbox>
+    #else##没数据字典
             <el-checkbox>请选择字典生成</el-checkbox>
+    #end
           </el-checkbox-group>
         </el-form-item>
-#elseif($column.htmlType == "radio" && "" != $dictType)
-        <el-form-item label="${comment}">
-          <el-radio-group v-model="form.${javaField}">
-            <el-radio
-              v-for="dict in ${javaField}Options"
-              :key="dict.dictValue"
-              #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.dictValue)"#else:label="dict.dictValue"#end
-
-            >{{dict.dictLabel}}</el-radio>
-          </el-radio-group>
-        </el-form-item>
-#elseif($column.htmlType == "radio" && $dictType)
+#elseif($column.htmlType == "radio")## 单选框
         <el-form-item label="${comment}">
           <el-radio-group v-model="form.${javaField}">
+    #if ("" != $dictType)## 有数据字典
+            <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.$dictType.toUpperCase())"
+                      :key="dict.value" #if($column.javaType == "Integer" || $column.javaType == "Long"):label="parseInt(dict.value)"#else:label="dict.value"#end>{{dict.label}}</el-radio>
+    #else##没数据字典
             <el-radio label="1">请选择字典生成</el-radio>
+    #end
           </el-radio-group>
         </el-form-item>
-#elseif($column.htmlType == "datetime")
+#elseif($column.htmlType == "datetime")## 时间框
         <el-form-item label="${comment}" prop="${javaField}">
-          <el-date-picker clearable size="small"
-            v-model="form.${javaField}"
-            type="date"
-            value-format="yyyy-MM-dd"
-            placeholder="选择${comment}">
-          </el-date-picker>
+          <el-date-picker clearable size="small" v-model="form.${javaField}" type="date" value-format="yyyy-MM-dd" placeholder="选择${comment}" />
         </el-form-item>
-#elseif($column.htmlType == "textarea")
+#elseif($column.htmlType == "textarea")## 文本框
         <el-form-item label="${comment}" prop="${javaField}">
           <el-input v-model="form.${javaField}" type="textarea" placeholder="请输入内容" />
         </el-form-item>