苍穹应用市场后台管理页面 vue+elementUI 快速开发

一、组件篇html

列表demo文件 /suppler/lamManage/productModelList

图片懒加载

<img v-lazy="'/image/banner/shengtai@2x.png'" />
<div v-lazy:background-image="{src:item.map[1].bannerResUrl}"></div>

组件插槽 用slot

<div class="note"
   slot="label">
   {{ item.introName}}
   <i v-if="item.subIntro">({{item.subIntro}})</i>
</div>

链接加权限

<router-link tag="a"
   tableLink="true"
   v-validate="'btn-view'"
   class="bottomline"
   href="javascript:void(0)"
   :to="`/suppler/lamManage/productModelList/detail?id=${scope.row.appId}&status=1`">
   {{ scope.row.appName  }}
 </router-link>

表格table

        <el-table
          style="width: 700px"
          v-loading="listLoading"
          border
          :data="list"
          default-expand-all
          :element-loading-text="elementLoadingText"
          row-key="path"
          :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
        >
          <el-table-column show-overflow-tooltip type="selection" />
          <el-table-column prop="crtDate"
               label="上传时间"
               width="160"
               align="center">
               <template slot-scope="scope">
                    {{ scope.row.crtDate | dateAllfilter}}
               </template>
          </el-table-column>
          <el-table-column label="重定向" prop="redirect" show-overflow-tooltip align="center"/>
          <el-table-column label="标题" prop="meta.title" show-overflow-tooltip />
          <el-table-column label="图标" show-overflow-tooltip>
            <template #default="{ row }">
              <span v-if="row.meta">
                <vab-icon v-if="row.meta.icon" :icon="['fas', row.meta.icon]" />
              </span>
            </template>
          </el-table-column>
          <el-table-column label="操作" show-overflow-tooltip width="200">
            <template #default="{ row }">
              <el-button type="text" @click="handleEdit(row)">编辑</el-button>
              <el-button type="text" @click="handleDelete(row)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>

弹窗el-dialog

    <el-dialog title="新建产品系列"
               customClass="plusAppNameDialog"
               :visible.sync="dialogVisible"
               :closeOnClickModal="false"
               @close="dialogVisible = false"
               width="500px"   >
      <span slot="footer"
            class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary"
                   @click="handleAddAppSeries('ruleForm')">确 定</el-button>
      </span>
    </el-dialog>

表单form

<el-form :model="formObj" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm" @submit.native.prevent> 
    <el-form-item label="上传附件:"
                      prop="resId">
          <upload-file :fileCustom="fileInfo"
                       @callback="getFileInfo"></upload-file>
    </el-form-item>
    <el-form-item label="研发团队人数:" prop="developmenTeamNum">
      <span v-if="isRead">{{formObj.developmenTeamNum}}</span>
      // 数字
      <el-input v-else   size="small"   
          style="width: 340px"
          v-model.number="formObj.developmenTeamNum"
          maxlength="10"
          placeholder="请输入研发团队人数"
          clearable>
       </el-input>
      // 文字                 
      <el-input size="medium" 
          style="width: 340px" 
          v-model.trim="formObj.appName" 
          placeholder="请输入初步拟定的产品名称" 
          maxlength="20" 
          show-word-limit clearable>
      </el-input>
      
    </el-form-item>
      <span slot="footer"
            class="dialog-footer">
        <el-button  @click="$router.go(-1)">返回</el-button> 
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary"
                   @click="handleComfirmUpdate('ruleForm')">确 定</el-button>
      </span>
</el-form>

输入框input

第一个输入框可以设置一个指令 v-focus属性,提前聚焦,也可以加上 tabindex="1" (https://blog.csdn.net/cui_angel/article/details/7677491

<el-input v-model.trim="form.username" v-focus placeholder="请输入用户名" 
tabindex="1" type="text" />
  <el-input 
         size="medium"
         style="width: 340px"
         v-model.trim="formObj.appName"
         placeholder="请输入初步拟定的产品名称"
         maxlength="20"
         show-word-limit
         clearable>
  </el-input>
  
   <span><span> 详情展示 设置css属性  white-space: pre-wrap
  
   <el-input 
         type="textarea"
         :rows="5"
         size="small"
         style="width: 340px"
         v-model.trim="formObj.appName"
         placeholder="请输入初步拟定的产品名称"
         maxlength="100"
         show-word-limit
         clearable>
  </el-input>

选择框radio/checkbox/select

  <el-radio-group v-model="formObj.productFormId">
              <el-radio v-for="(obj,index) in productForm"
                       :label="obj.fid" :key="index + 'productFormt'">{{ obj.fname }}
              </el-radio>
  </el-radio-group>
  
  <el-radio-group v-model="formObj.hasCustomer">
              <el-radio label="0">否</el-radio>
              <el-radio label="1">是</el-radio>
  </el-radio-group>
  
 <el-checkbox-group v-model="ruleForm.type">
     <el-checkbox label="美食/餐厅线上活动" name="type"></el-checkbox> 
     <el-checkbox label="地推活动" name="type"></el-checkbox> 
     <el-checkbox label="线下主题活动" name="type"></el-checkbox> 
     <el-checkbox label="单纯品牌曝光" name="type"></el-checkbox> 
 </el-checkbox-group>
 
<el-select size="small"
                       style="width: 90%"
                       v-else
                       v-model="formObj.position"
                       placeholder="请选职务(必填)"
                       clearable>
   <el-option label="总经理" value="1"></el-option>
   <el-option label="业务负责人" value="2"></el-option>
   <el-option label="其他" value="3"></el-option>
</el-select>
  

封装组件上传

// category: 'docs',       // 上传时的组件样式分类 (图片,文档,头像 )与class一一对应
// type: '',               // 上传文件类型(pdf,png)
// unlimitType: true       // 上传不限制类型
// size: 100,              // 上传大小 单位兆
// name: '上传安装包',      // 组件展示的文字
// class: 'docs-uploader', // 上传时的组件样式class
// list: [],               // 上传的列表
// cat: 'xxx',             // 在服务端保存的文件夹名字
// subfolder: id ,        // 在服务端保存的子文件夹名字

// cat: 'package/:id', 上传文件包
// cat: 'applogo'  上传应用logo
// cat: 'samplecust'  上传样板客户里面的图片
// cat: 'contract',  上传购买合同 , 里程上传凭证,卖家上传委托书
// cat: 'idCard'     上传身份证验证图片
// cat: 'transferVoucher'   客户转账凭证
// cat: 'PDLogo'   上传test

[图片上传失败...(image-58ee57-1734332820905)]

[图片上传失败...(image-21fb7d-1734332820905)]

:customeDelete="true"  是否删除文件
<upload-file :customeDelete="true" :fileCustom="fileInfo" @callback="getFileInfo"></upload-file>
    
fileInfo: {
    category: 'docs',
    type: 'ppt/pptx',
    size: 100,
    name: '上传文件',
    class: 'agreement-uploader',
    list: [],
    cat: 'contract',
    unlimitType: false,
}, 

getFileInfo (name, id, _url) {
    this.formObj.roadmapResId = id
    this.$refs['formName'].clearValidate('roadmapResId')
},

el-upload上传

<el-upload :action="`/api/app/uploadPassAppPatchObjects?cat=lamManage`"
     :data="{deploymentType:'DT003',appId:formObj.appId}"
     :on-success="handleSuccess"
     :on-remove="handleRemove"
     accept=".xml,.xls,.xlsx"
     :multiple="false"
     :limit="0"
     :file-list="fileList">
      <el-button size="small"
       type="primary">点击上传</el-button>
</el-upload>

handleRemove (file, fileList) {
  // console.log(file, fileList)
  this.formObj.productModelJsonId = ''
  this.fileList = []
},
handleSuccess (file, fileList) {
  let { fileName, productModelJsonId } = file?.data
  console.log(file, fileList)
  if (file.code === 0) {
    this.$refs['ruleForm'].clearValidate('resId')
    this.formObj.productModelJsonId = productModelJsonId
    this.fileList = [{ name: fileName, id: productModelJsonId }]
      } else {
    this.fileList = []
    this.$message.warning(file.msg)
  }
},

下载

<p @click="getDocDownloadInfo(dataInfo.initRoadmapUrl)">下载模板</p>
getDocDownloadInfo (url) {
    if (url) {
        this.layerglobal.downfile(url)
    } else {
        this.$message.warning('下载资源不存在,请上传模板后再下载')
    }
},

日期date

                <el-form-item label="许可授权日期:"
                              prop="flicenseTime">
                  <el-date-picker type="daterange"
                                  range-separator="-"
                                  style="width:340px"
                                  format="yyyy-MM-dd"
                                  value-format="timestamp"
                                  v-model="formObj.flicenseTime"
                                  start-placeholder="开始日期"
                                  end-placeholder="结束日期"
                                  :picker-options="pickerOptions"
                                  clearable
                                  @change="onChangeLicenseTime"
                                  :disabled="isDisabled">
                  </el-date-picker>         
                </el-form-item>

pickerOptions: {
    disabledDate (time) {
        return time.getTime() < Date.now() - 3600 * 24 * 1000
    }
},
    pickerOptions () {
      let obj = {
        disabledDate: (time) => {
          if (this.formObj.flicenseTime && this.formObj.flicenseTime) {
            return time.getTime() < this.formObj.flicenseTime[0] || time.getTime() > this.formObj.flicenseTime[1]
          } else {
            return false
          }
        },
      }
      return obj
    },

计数器

                      <el-input-number v-if="isUpdate || !status"
                                       v-model="obj.totalUserNum"
                                       :min="1"
                                       :step="1"
                                       :step-strictly="true"
                                       size="small"
                                       label="描述文字">
                       </el-input-number>

二、参数方法

rules

行内校验

        <el-form-item label="开发团队:"
                      prop="developmenTeam"
                      :rules="[{ required: true, message: '请选择开发团队', trigger: 'blur' }]">
          <el-select v-model="formObjContent.developmenTeam"
                     placeholder="请选择开发团队"
                     style="width:300px"
                     size="medium"
                     @change="handleChangeSuppler"
                     clearable>
            <el-option v-for="item in supplerList"
                       :key="item.tid"
                       :label="item.name"
                       :value="item.tid">
            </el-option>
          </el-select>
        </el-form-item>
      rules: {
        customerNumber: [
          { required: true, message: "请输入企业人数", trigger: "blur" },
          { type: 'number', message: '人数必须为数字值'}
          { pattern: /^[1-9]\d*$/, message: '企业人数必须为正整数', trigger: 'blur' },
          { type: 'email', message: '账户名应为邮箱格式', trigger: ['blur', 'change'] },
          { pattern: /^(\d+)((?:\.\d+)?)$/, message: '请输入合法金额数字',trigger: "blur" },
        ],
        appName: [
          { required: true, message: "请输入产品名称", trigger: "blur" },
          { min: 3, max: 5, message: '长度在 3 到 5 个字符', trigger: 'blur' }
        ],
        电话为手机号或座机0745-1234567(8)
        contactPhone: [
          { required: true, message: "请输入联系电话", trigger: "blur" },
          { pattern: /^(1\d{10}|(\d{4}-)(\d{8}|\d{7}))$/, message: "请填写正确的", trigger: "blur" },
        ],
        domainIdList: [
          { required: true, message: "请选择领域", trigger: "change" },
        ],
        plannedReleaseTime: [
          { type: 'date', required: true, message: "请选择计划发布日期", trigger: "change" },
        ],
        hasCustomer: [
          { required: true, message: "请选择是否有原型客户", trigger: "blur" },
        ],
        type: [
            { type: 'array', required: true, message: '请至少选择一个活动性质', trigger: 'change' }
        ],
        这是image文件类型
        roadmapResId: [
          { required: true, message: "请上传产品规划方案", trigger: "change" }
        ],

新增

    handleAddFeature () {
      this.$refs['featureForm']?.resetFields()
      this.dialogVisibleFeature = true
      this.formObj = {
        modelName: '',
        modelNumber: '',
        priceType: 'PIT001'
      }
    },

编辑

    handleEditFeature (obj, val, index) {
      this.$refs['featureForm']?.clearValidate()
      this.operate = val
      this.dialogVisibleFeature = true
      this.featureObj = _.cloneDeep(obj)
      this.editFeatureIndex = index
    },

删除

    handleDeleteGroup (index, name) {
      this.$confirm(`确定删除分组【${name}】及对应模块?`, "删除提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
        closeOnClickModal: false,
      }).then(() => {
        this.groupList.splice(index, 1)
      })
    },

基本请求方法

    handleSoldOutProduct (obj) {
      this.$confirm(`确定作废产品【${obj.appName}】?`, "作废提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
        closeOnClickModal: false,
      }).then(() => {
        this.supplierDownPassApp({ appId: obj.appId }).then((res) => {
          this.partnerGetclick()
          this.$message.success('产品作废成功')
        }).catch((res) => {
          this.$store.dispatch("VerifiFailure", { data: res, offset: "offsetIndex", })
        })
      }).catch(() => { })
    },

init

    init (supplierId, id) {
      this.basicDataWithValidInfo({ supplierId }).then((res) => {
        this.basicData = res.data
        this.getProjectApprovalDetail({ id }).then((res) => {
          this.dataInfo = res.data
          // 编辑
          if (id) {
            this.formObj.id = res.data.id
            let { roadmapName: name, roadmapResId, roadmapResUrl: _url } = res.data
            if (id && roadmapResId) {
              this.fileInfo.list = [{ name, id: roadmapResId, _url }]
              this.formObj.roadmapResId = roadmapResId
            }
          }
        }).catch((res) => {
          this.$store.dispatch("VerifiFailure", { data: res, offset: "offsetCustom", })
        })
      }).catch((res) => {
        this.$store.dispatch("VerifiFailure", { data: res, offset: "offsetCustom", })
      })
    },

编辑弹窗取消逻辑

      close() {
        this.$refs['form']?.resetFields()
        this.form = this.$options.data().form
        this.dialogFormVisible = false
      },
      save() {
        this.$refs['form'].validate(async (valid) => {
          if (valid) {
            const { msg } = await doEdit(this.form)
            this.$baseMessage(msg, 'success')
            this.$emit('fetch-data')
            this.close()
          } else {
            return false
          }
        })
      },      

提交保存

    submitForm (auditStatus) {
      this.$message.closeAll()
      let obj = { ...this.formObj }
      if (this.formObj.hasCustomer === '0') {
        delete obj.customerName
      }
      if (auditStatus === 'save') {
        this.btnloading.savebtn = true
        this.saveProjectApproval(obj).then((res) => {
          if (res.code === 0) {
            this.btnloading.savebtn = false
            this.$message.success('保存成功')
            this.$router.push('/suppler/projectManagement/list')
          }
        }).catch((res) => {
          this.btnloading.savebtn = false
          this.$store.dispatch("VerifiFailure", { data: res, offset: "offsetCustom", })
        })
      } else {
        this.$refs["formName"].validate((valid) => {
          if (valid) {
            this.btnloading.savebtn = true
            this.submitProjectApproval(obj).then((res) => {
              if (res.code === 0) {
                this.btnloading.savebtn = false
                this.$message.success('提交成功')
                this.$router.push('/suppler/projectManagement/list')
              }
            }).catch((res) => {
              this.btnloading.savebtn = false
              this.$store.dispatch("VerifiFailure", { data: res, offset: "offsetCustom", })
            })
          }
        })
      }
    },

提交弹窗

this.$confirm(`<p style="font-size:15px;margin-top:20px;">请先前往开发者门户获取开发商标识,
再新建产品!</p>`, "提示",
            {
              customClass: 'confirmMessagePop',
              confirmButtonText: "获取会员资质",
              cancelButtonText: "取消",
              type: "warning",//不要icon可以删除这个
              closeOnClickModal: false,
              dangerouslyUseHTMLString: true,
              width: 600
            }
          ).then(() => {
               this.$router.push({ name: "supplierInfo", query: { isneedskipmemberinfo: true } })
          }).catch(() => { })
          

      this.$prompt(``, '驳回变更申请', {
        customClass: "delayDevlicensePop",//报错提示居左,去掉就居中
        dangerouslyUseHTMLString: true,
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        closeOnClickModal: false,
        center: true,//标题居中
        inputType: 'textarea',
        inputPattern: /^.{1,50}$/,
        inputErrorMessage: '延期理由应在1~50个字内!',
        inputPlaceholder: '请输入延期理由,不超过50个字符'
      }).then((obj) => {
        const { id } = this.$route.params
        this.kingdeeOperateAppChange({ appChangeId: id, auditStatus: 'AS004', refuseReason: obj.value }).then(res => {
          this.$router.push('/amk/amkAppChangeList')
        }).catch(res => {
          this.$store.dispatch('VerifiFailure', { 'data': res, offset: 'offsetCustom' })
        })
      })
          

css

左右布局,左边固定,右边自适应

        span {
          display flex
          padding 0.08rem 0.2rem
          width calc(100% - 0.4rem)
          >b {
            display inline-block
            line-height 0.22rem
            width 0.9rem
            font-size 0.14rem
          }
          >i {
            flex 1
            font-size 0.14rem
            line-height 0.22rem  //与label对齐
            word-break break-word //换行
          }
        }

过渡动画

transition margin-top 0.2s
-webkit-transition margin-top 0.2s

多文本框(textarea)处理换行问题

  回显文本样式设置
  white-space pre-wrap

一行省略

.textoverflow {
  white-space nowrap
  overflow hidden
  text-overflow ellipsis
}

多行省略

.textoverflow2 {
  overflow hidden
  text-overflow ellipsis
  word-break break-all
  display -webkit-box
  -webkit-line-clamp 2
  -webkit-box-orient vertical
}

checkbox 阻止冒泡事件(要包一层div才有效果)

   <!-- 包一层div阻止冒泡事件 -->
   <div v-on:click.stop="">
      <el-checkbox v-model="checkboxList[index]"></el-checkbox>
   </div>

[图片上传失败...(image-5ecb1c-1734332820905)]

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,313评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,369评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,916评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,333评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,425评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,481评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,491评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,268评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,719评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,004评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,179评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,832评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,510评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,153评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,402评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,045评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,071评论 2 352

推荐阅读更多精彩内容