每一年都奔走在自己热爱里

没有人是一座孤岛,总有谁爱着你

elementui步骤条页面开发案例

<template>
  <div id="bdy">
    <div class="tbody">
      <el-steps :active="active" finish-status="success">
        <el-step title="创建项目"></el-step>
        <el-step title="区域基地"></el-step>
        <el-step title="实验对象"></el-step>
        <el-step title="阶段周期"></el-step>
        <el-step title="属性"></el-step>
      </el-steps>
      <!-- 1创建项目 -->
      <el-form :model="form" :rules="projectRules" ref="form" label-width="100px" width="80px" style="margin-top: 30px;">
        <div  class="el-card" v-if="active==1" style="padding: 20px;">
          <el-row>
            <el-col :span="12">
              <el-form-item label="项目名称:" prop="pName">
                <el-input v-model="form.pName" suffix-icon="el-icon-warning-outline" placeholder="请输入实验名"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="运行状态:" prop="baseId">
                <treeselect
                  v-model="form.baseId"
                  :options="baseOptions"
                  :normalizer="normalizer"
                  :show-count="true"
                  placeholder="请选择区域名称(请勿选择主类目)"
                  @select="handleSelect"
                />
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="项目周期(年):" prop="cycle">
                <el-input-number v-model="form.cycle" :min="1" :max="10" style="width: 100%;" placeholder="默认项目周期是1年"/>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="实验对象:" prop="varietiesId">
                <el-select v-model="form.varietiesId" placeholder="请选择实验对象" filterable style="width: 100%">
                  <el-option
                    v-for="item in varietiesOptions"
                    :key="item.varietiesId"
                    :value="item.varietiesId"
                    :label="item.varietiesName">
                  </el-option>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="开始日期:" prop="startDate">
                <el-date-picker v-model="form.startDate" type="date" placeholder="选择项目开始日期" style="width: 100%"/>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="结束日期:" prop="startDate">
                <el-date-picker v-model="form.endDate" type="date" placeholder="选择项目结束日期" style="width: 100%"/>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="负责人:" prop="principalId">
                <el-select v-model="form.principalId" placeholder="请选择负责人" filterable style="width:100%">
                  <el-option
                    v-for="item in userOptions"
                    :key="item.principalId"
                    :value="item.principalId"
                    :label="item.principalName">
                  </el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="状态:" prop="state">
                <el-select v-model="form.state" placeholder="请选择状态" style="width: 100%">
                  <el-option
                    v-for="(dict,index) in dict.type.dict_onoff_type"
                    :key="index"
                    :label="dict.label"
                    :value="dict.value"
                    value-key="index">
                  </el-option>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item label="项目简介:" prop="description">
                <el-input v-model="form.description" type="textarea" suffix-icon="el-icon-warning-outline" :rows="5" maxlength="150" show-word-limit></el-input>
              </el-form-item>
            </el-col>
          </el-row>
        </div>
      </el-form>
      <!-- 2实验基地 -->
      <el-form :model="form2" :rules="projectRules" ref="form2" label-width="100px" width="80px" style="margin-top: 30px">
        <div class="el-card" v-if="active==2" style="padding: 20px;">
          <el-row>
            <el-col :span="12">
              <el-form-item label="实验名称:" prop="pName">
                <el-input v-model="form.pName" suffix-icon="el-icon-warning-outline" placeholder="请输入实验名"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="区域名称:" prop="baseId">
                <treeselect
                  v-model="form.baseId"
                  :options="baseOptions"
                  :normalizer="normalizer"
                  :show-count="true"
                  placeholder="请选择区域名称(请勿选择主类目)"
                  @select="handleSelect"
                />
              </el-form-item>
            </el-col>
          </el-row>
        </div>
      </el-form>
      <!-- 3实验对象 -->
      <el-form :model="form3" :rules="projectRules" ref="form3" label-width="100px" width="80px" style="margin-top: 30px">
        <div class="el-card" v-if="active==3" style="padding: 20px;">
          <el-tag
            :key="tag"
            v-for="tag in dynamicObjectTags"
            closable
            :disable-transitions="false"
            @close="handleClose(tag)">
            {{tag}}
          </el-tag>
          <el-input
            class="input-new-tag"
            v-if="inputVisible"
            v-model="inputValue"
            ref="saveTagInput"
            size="small"
            @keyup.enter.native="handleInputConfirm"
            @blur="handleInputConfirm"
          >
          </el-input>
          <el-button v-else class="button-new-tag" size="small" @click="showInput">+ 新增实验对象</el-button>
        </div>
      </el-form>
      <!-- 4阶段周期 -->
      <el-form :model="form4" :rules="projectRules" ref="form4" label-width="100px" width="80px" style="margin-top: 30px">
        <div class="el-card" v-if="active==4" style="padding: 20px;">
          <el-tag
            :key="tag"
            v-for="tag in dynamicStageTags"
            closable
            :disable-transitions="false"
            @close="handleClose(tag)">
            {{tag}}
          </el-tag>
          <el-input
            class="input-new-tag"
            v-if="inputVisible"
            v-model="inputValue"
            ref="saveTagInput"
            size="small"
            @keyup.enter.native="handleInputConfirm"
            @blur="handleInputConfirm"
          >
          </el-input>
          <el-button v-else class="button-new-tag" size="small" @click="showInput">+ 新增阶段周期</el-button>
        </div>
      </el-form>
      <!-- 5添加记录 -->
      <el-form :model="form5" :rules="projectRules" ref="form5" label-width="100px" width="80px" style="margin-top: 30px">
        <div class="info" v-if="active==5">
          <div class="box-card" shadow="hover">
            <el-card class="box-card" v-for="(item,index) in recordData" :key="index" v-if="item.formShow">
              <div slot="header" class="clearfix">
                <span>{{item.formName}}</span>
                <el-button style="float: right; padding: 3px 0;color:#f56c68;" type="text" @click="taskDelHandle(index)">删除
                </el-button>
              </div>
              <el-form :ref="item.formRef" :key="item.index" label-width="140px" enctype="multipart/form-data">
                <template v-for="(propertys,index2) in (item.formModel)">
                  <el-form-item :label="propertys.propertyName" :prop="propertys.propertyAlias" :key="index2">
                    <el-input style="width:80%" v-model="propertys.propertyValue" size="small"></el-input>
                    <i v-if="propertys.fix" style="padding:0 7px;">
                      <el-button type="danger" @click="remoteItem(index,index2)" size="small" class="el-icon-delete">删除</el-button>
                    </i>
                  </el-form-item>
                  <div v-if="index2 == item.formModel.length-1" style="text-align: center">
                    <el-button type="warning" @click="addCustomAttr(index)" size="small" class="el-icon-user">自定义</el-button>
                  </div>
                </template>
                <!-- 上传图片/视频-->
                <el-form-item label="任务图片/视频">
                  <el-upload
                    class="upload-demo"
                    ref="upload"
                    :action="upload.url"
                    :headers="upload.headers"
                    :on-preview="handlePreview"
                    :on-success="handleSuccess"
                    :on-error="handleError"
                    :on-remove="handleRemove"
                    :before-remove="beforeRemove"
                    :on-change="handleChange"
                    :limit="3"
                    :on-exceed="handleExceed"
                    :file-list="item.fileList"
                    :disabled="upload.isUploading"
                    accept=".jpg,.jpeg,.png,.gif,.bmp,.JPG,.JPEG,.PBG,.GIF,.BMP"
                    list-type="picture">
                    <el-button size="small" type="primary">点击上传</el-button>
                    <span slot="tip" class="el-upload__tip"> 只能上传jpg/png文件,且不超过500kb</span>
                  </el-upload>
                </el-form-item>
              </el-form>
            </el-card>
          </div>
          <div class="bottom-divider">
            <span class="divider-btn">
              <el-button type="success" size="small" icon="el-icon-circle-plus-outline" @click="taskAddHandle()">添加新记录</el-button>
            </span>
          </div>
        </div>
      </el-form>
      <div style="text-align: center">
        <el-button style="margin-top: 12px;" @click="pre" v-if="active>1" type="primary">上一步</el-button>
        <el-button style="margin-top: 12px;" @click="next" v-if="active<5" type="success">下一步</el-button>
        <el-button style="margin-top: 12px;" @click="onSubmit" v-if="active===5" type="success" >提交</el-button>
      </div>
    </div>

    <!--新增自定义填写属性窗口-->
    <el-dialog title="新增自定义填写属性" :visible.sync="dialogVisible" width="500px" :before-close="diyhandleClose">
      <el-form ref="form" :model="customForm" label-width="140px" style="width: 500px">
        <el-row>
          <el-col :span="12">
            <el-form-item label="自定义属性名">
              <el-autocomplete class="inline-input"
                               size="small"
                               v-model="customForm.dynamicName"
                               :fetch-suggestions="querySearch"
                               @select="handleSelect"
                               style="width: 100%">
              </el-autocomplete>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="自定义属性类型">
              <el-select v-model="customForm.dynamicType" size="small" placeholder="请选择" style="width: 100%">
                <el-option
                  v-for="(item,index) in dynamicOption"
                  :key="item.propertyType"
                  :label="item.label"
                  :value="item.propertyType">
                </el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="addDynamicProperty()">确 定</el-button>
      </span>
    </el-dialog>

  </div>
</template>

<script>
  //表单js代码
  import Qs from "qs";
  import Treeselect from "@riophae/vue-treeselect";
  import "@riophae/vue-treeselect/dist/vue-treeselect.css";
  import {getToken} from "@/utils/auth";
  import {getStageProperty, addTask} from "@/api/projectmgr/task";
  export default {
    dicts: ['dict_onoff_type'],
    components: {Treeselect},//树组件
    data() {
      return {
        dynamicObjectTags: ['玉米', '向日葵', '黄豆'],
        dynamicStageTags: ['发芽期', '幼苗期', '选种期', '播种期', '现蕾期', '开花期', '成熟期'],
        inputVisible: false,
        inputValue: '',
        active: 1,
        stateOptions: [],
        varietiesOptions: [],
        groupOptions: [],
        areaOptions: [],
        ids: [], // 选中数组
        userOptions: [],//负责人下拉列表
        baseOptions: [], // 基地树选项
        isExpandAll: false, // 是否展开,默认全部折叠
        refreshTable: true, // 重新渲染表格状态
        showSearch: true,  // 显示搜索条件
        loading: true,  // 遮罩层
        open: false,// 是否显示弹出层
        queryParams: {  // 查询参数
          pageNum: 1,
          pageSize: 10,
          pName: null,
          state: null,
        },
        form: {
          area: ['个人成长'],
          checkAll: false,
          cities: cityOptions,
          isIndeterminate: true,
          quality: 0,
          imageUrl: '',
          username: '',
          tell: '',
          indentity: '',
          number: '',
          instroduce: '',
          time: ''
        },
        form2: {
          area: ['个人成长'],
          checkAll: false,
          cities: cityOptions,
          isIndeterminate: true,
          quality: 0,
          imageUrl: '',
          username: '',
          tell: '',
          indentity: '',
          number: '',
          instroduce: '',
          time: ''
        },
        form3: {
          area: ['个人成长'],
          checkAll: false,
          cities: cityOptions,
          isIndeterminate: true,
          quality: 0,
          imageUrl: '',
          username: '',
          tell: '',
          indentity: '',
          number: '',
          instroduce: '',
          time: ''
        },
        form4: {},
        form5: {},
        form6: {},
        projectRules: {
          pName: [
            {required: true, message: '请输入项目名称', trigger: 'blur'},
            {min: 1, max: 10, message: '长度在 1 到 10 个字符', trigger: 'blur'}
          ],
          varietiesId: [
            {required: true, message: '请选择实验对象', trigger: 'change'}
          ],
          description: [
            {required: true, message: '请填写项目简介', trigger: 'blur'}
          ],
          baseId: [
            {required: true, message: '请选择实验基地', trigger: 'change'}
          ],
          area: [
            {required: true, message: '请选择项目具体区域', trigger: 'change'}
          ],
          principalId: [
            {required: true, message: '请选择负责人', trigger: 'change'}
          ]
        },
        recordData: [{
          formModel: [],//表单model
          formRef: 'recordForm',//表单ref
          formShow: true,//表单是否显示的控制
          formName: '记录1',//表单标题
          fileList: [],
        }],
        url: process.env.VUE_APP_BASE_API + "/task/upload",
        minioUrl: process.env.VUE_APP_MINIO,
        // 用户导入参数
        upload: {
          // 是否显示弹出层(用户导入)
          open: false,
          // 弹出层标题(用户导入)
          title: "",
          // 是否禁用上传
          isUploading: false,
          // 是否更新已经存在的用户数据
          updateSupport: 0,
          // 设置上传的请求头部
          headers: {Authorization: "Bearer " + getToken()},
          // 上传的地址
          url: process.env.VUE_APP_BASE_API + "/task/upload", // 上传的图片服务器地址
          minioUrl: process.env.VUE_APP_MINIO // 显示的图片服务器地址
        },
        dialogVisible: false,
        queryParams: {},
        customForm: {
          dynamicName: '',
          dynamicType: '',
        },
        dynamicOption: [
          {
            propertyType: 'datetime',
            label: '时间'
          }, {
            propertyType: 'varchar',
            label: '文字'
          }
        ],
        TaskForm: {  // 表详细信息
          pId: '',
          pName: '',
          baseParentId: '',
          baseParentName: '',
          baseId: '',
          baseName: '',
          varietiesId: '',
          varietiesName: '',
          stageId: '',
          growthStageId: '2',
          stateName: '',
          cycle: '',
          taskId: '',
        },
        formIndex: 2,//添加记录从2开始
        customFormIndex: 0,
        attrLen: 0,

      }
    },
    mounted() {
      let item = {growthStageId: 2}
      this.stagePropertyList(item)
    },
    methods: {
      /** 提交保存*/
      onSubmit() {
        this.$confirm('此操作将保存记录, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          //this.form.checkedCities获取多选框的内容   zxs[this.form.radio]  this.form.imageUrl
          //开始提交 在这里进行跨域请求
          this.axios({
            method: "post",
            url: "/api/PsychoSys/tuser.action",
            data: Qs.stringify(this.form)
          }).then(res => {
            this.$router.push("/tinfo");
          }).catch(function (err) {
            console.log(err);
          });
          /*在这里进行跨域请求*/
          //开始提交
        }).catch(() => {
          this.$message({type: 'info', message: '已取消修改'});
        });
      },
      handleAvatarSuccess(res, file) {
        this.form.imageUrl = URL.createObjectURL(file.raw);
      },
      beforeAvatarUpload(file) {
        const isJPG = file.type === 'image/jpeg';
        const isLt2M = file.size / 1024 / 1024 < 2;
        if (!isJPG) {
          this.$message.error('上传头像图片只能是 JPG 格式!');
        }
        if (!isLt2M) {
          this.$message.error('上传头像图片大小不能超过 2MB!');
        }
        return isJPG && isLt2M;
      },
      handleCheckAllChange(val) {
        this.form.area = val ? cityOptions : [];
        this.isIndeterminate = false;
      },
      handleCheckedCitiesChange(value) {
        let checkedCount = value.length;
        this.checkAll = checkedCount === this.form.cities.length;
        this.isIndeterminate = checkedCount > 0 && checkedCount < this.form.cities.length;
      }, next() {
        if (this.active++ > 5) this.active = 1;
      },
      pre() {
        if (this.active-- < 2) this.active = 1;
      },
      /** 基地树点击点击事件**/
      handleSelect(row) {
        this.projectForm.baseParentId = row.parentId;
      },
      /** 转换部门数据结构 */
      normalizer(node) {
        if (node.children && !node.children.length) {
          delete node.children;
        }
        return {
          id: node.baseId,
          label: node.baseName,
          children: node.children
        };
      },
      /** 文件列表移除文件时的钩子*/
      handleRemove(file, fileList) {
        console.log(file, fileList);
      },
      /** 点击文件列表中已上传的文件时的钩子*/
      handlePreview(file) {
        console.log(file);
      },
      handleChange(file, fileList) {
        if (fileList.length > 1) {
          fileList.shift()
        }
      },
      handleSuccess(response, file, fileList) {
        this.upload.open = false;
        this.upload.isUploading = false;
        this.recordData[0].fileList.push({name: response.newFileName, url: this.upload.minioUrl + response.url});
        this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", {dangerouslyUseHTMLString: true});
      },
      handleError() {
        this.$message.error("图片插入失败");
      },
      /** 文件超出个数限制时的钩子*/
      handleExceed(files, fileList) {
        this.$message.warning(`当前限制选择 2 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
      },
      /** 删除文件之前的钩子*/
      beforeRemove(file, fileList) {
        return this.$confirm(`确定移除 ${file.name}?`);
      },
      handleClose(tag) {
        this.dynamicTags.splice(this.dynamicTags.indexOf(tag), 1);
      },
      showInput() {
        this.inputVisible = true;
        this.$nextTick(_ => {
          this.$refs.saveTagInput.$refs.input.focus();
        });
      },
      handleInputConfirm() {
        let inputValue = this.inputValue;
        if (inputValue) {
          this.dynamicTags.push(inputValue);
        }
        this.inputVisible = false;
        this.inputValue = '';
      },
      /** 查询通用属性列表*/
      stagePropertyList(item) {
        if (item) {
          this.queryParams.growthStageId = item.growthStageId;
          getStageProperty(this.queryParams).then(res => {
            if (res.code == 200) {
              this.$set(this.recordData[0], "formModel", res.data);
              this.attrLen = res.data.length
            }
          });
        }
      },
      /** 自定义属性*/
      addCustomAttr(i) {
        this.customFormIndex = i
        this.dialogVisible = true;
      },
      /** 查询按钮*/
      querySearch(queryString, cb) {
        let stateList = this.stateList;
        //let results = queryString ? stateList.filter(this.createFilter(queryString)) : stateList;
        //cb(results);
      },
      /** 确认关闭按钮*/
      diyhandleClose(done) {
        this.$confirm('确认关闭?').then(_ => {
          done();
        }).catch(_ => {

        });
      },
      /** 添加自定义属性*/
      addDynamicProperty() {
        let i = this.recordData[this.customFormIndex].formModel.length - this.attrLen
        let obj = {
          propertyName: this.customForm.dynamicName,
          propertyType: this.customForm.dynamicType,
          property: 'dynamic' + i,//属性英文名称
          propertyAlias: 'dynamic' + i,//属性中文名称
          vId: 1,
          fix: true,
          propertyCategory: 'custom'
        }
        this.recordData[this.customFormIndex].formModel.push(obj);
        this.dialogVisible = false
      },
      /** 添加新记录*/
      taskAddHandle() {
        if (this.recordData.length == 0) {
          this.formIndex = 1;
        }
        let newRecord = {
          formModel: [],//表单model
          formRef: 'recordForm' + this.formIndex,//表单ref
          formShow: true,//表单是否显示的控制
          formName: '记录' + this.formIndex//表单标题
        }
        let item = {growthStageId: parseInt(this.TaskForm.growthStageId)};
        getStageProperty(item).then(res => {
          if (res.code == 200) {
            this.$set(newRecord, "formModel", res.data);
            this.recordData.push(newRecord);
            this.attrLen = res.data.length
          }
        });
        this.formIndex++;
      },
    },
  }
  //表单js代码
</script>

<style>
  .tbody {
    width: 80%;
    margin-left: 10%;
    margin-top: 1%;
  }

  /* 表单 */
  .avatar-uploader .el-upload {
    border: 1px dashed #d9d9d9;
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
  }

  .avatar-uploader .el-upload:hover {
    border-color: #409EFF;
  }

  .avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    line-height: 178px;
    text-align: center;
  }

  .avatar {
    width: 178px;
    height: 178px;
    display: block;
  }

  .el-tag + .el-tag {
    margin-left: 10px;
  }

  .button-new-tag {
    margin-left: 10px;
    height: 32px;
    line-height: 30px;
    padding-top: 0;
    padding-bottom: 0;
  }

  .input-new-tag {
    width: 90px;
    margin-left: 10px;
    vertical-align: bottom;
  }
</style>

显示效果:

总结:

5个步骤页面各自放到5个不同的form表单,最后提交到后台.向导式步骤页面在elementui官网里查API就知道了,本人代码运行您电脑上很可能报错的情况,因为有些是调后台接口。

posted @ 2022-08-22 09:59  星星之草%  阅读(957)  评论(2编辑  收藏  举报