vue项目开发笔记记录

banner01.png

api接口封装

1.接口函数封装
import request from '@/utils/request'
import apiUrl from '../apiUrl'

// 根据主键获取单条记录
export function itemById(params) {
  return request({
    url: apiUrl.dataSourceApi.getItemById,
    method: 'get',
    params: params
  })
}
2.接口地址封装
export default {
  // 数据来源管理
  dataSourceApi: {
    queryAllData: '/web/bdp/datasourcemanager/datasourceinfo/all/1', // 获取所有来源数据源信息
    getItemById: '/web/bdp/datasourcemanager/datasourceinfo/item', // 根据主键获取单条记录
    getAllData: '/web/bdp/datasourcemanager/databaserelease/all/1', // 获取数据来源已支持的数据库类型
  },
}

vue常用组件

折线图组件

<template>
  <div class="trend-map">
    <div id="tendChart" />
  </div>
</template>

<script>
import echarts from 'echarts'
export default {
  name: 'TrendMap',
  props: {
    objData: {
      type: Object,
      default: function() {
        return {}
      }
    }
  },
  data() {
    return {
      yData: [820, 932, 901, 934, 1290, 1330, 1320],
      xData: [
        '2020-05-11',
        '2020-05-12',
        '2020-05-13',
        '2020-05-14',
        '2020-05-15',
        '2020-05-16',
        '2020-05-17']
    }
  },
  watch: {
    objData: {
      handler(val) {
        // this.queryNetworkBandwith()
      },
      deep: true
    }
  },
  mounted() {
    this.draw() // 临时展示作用
  },
  methods: {
    queryTPSTransation() {
      const params = {
        number: '40',
        period: this.objData.period,
        rtTaskNo: this.objData.rtTaskNo
      }
      queryTPSTransation(params).then(res => {
        if (res.code === 0) {
          this.xData = res.data.time
          this.yData = res.data.data
          this.draw()
        }
      })
    },
    draw() {
      var   option = {
        grid: {
          top: '20%',
          left: '5%',
          right: '5%',
          bottom: '15%'
        },
        title: {
          text: '存储趋势图',
          textStyle: {
            color: '#fff',
            fontSize: 16
          },
          left: '1%',
          top: '3%',
          bottom: '20%'
        },
        color: ['#00a3e5'],
        tooltip: {
          trigger: 'axis',
          padding: [2, 10],
          textStyle: {
            fontSize: 16
          },
          formatter: function(params) {
            var result = params[0].axisValue + '<br/>'
            params.forEach(function(item) {
              result += item.seriesName + ':' + item.value + ' MB</br>'
            })
            return result
          }
        },
        xAxis: [{
          type: 'category',
          axisLine: {
            show: true,
            lineStyle: {
              color: '#fff'
            }
          },
          splitLine: {
            show: false
          },
          boundaryGap: true,
          data: this.xData

        }],
        yAxis: [{
          name: 'MB',
          type: 'value',
          splitLine: {
            show: false
          },
          axisLine: {
            show: true,
            lineStyle: {
              color: '#fff'
            }
          },
          axisLabel: {
            show: true,
            margin: 20,
            textStyle: {
              color: '#fff'
            }
          },
          axisTick: {
            show: true
          }
        }],
        series: [{
          name: '存储趋势图',
          type: 'line',
          smooth: true, // 是否平滑
          showAllSymbol: true,
          symbol: 'none',
          symbolSize: 5,
          lineStyle: {
            normal: {
              color: '#00a3e5',
              width: 2
            }
          },
          data: this.yData
        }]
      }
      // 初始化图表
      const chartObj = echarts.init(document.getElementById('tendChart'))
      chartObj.setOption(option)
      if (option && typeof option === 'object') {
        chartObj.setOption(option)
      }
    }
  }
}
</script>

<style scoped lang="scss">
.trend-map{
  margin-top: 15px;
  background-color: #343d47;
}
#tendChart {
  height: 400px;
}
</style>

柱状图组件

<template>
  <div class="trend-map">
    <div class="occupy-more" @click="navToMoreDetail">更多<i class="fa fa-angle-right fa-fw" /></div>
    <div id="occupyChart" />
  </div>
</template>

<script>
import echarts from 'echarts'
export default {
  name: 'TrendMap',
  props: {
    objData: {
      type: Object,
      default: function() {
        return {}
      }
    }
  },
  data() {
    return {
      yData: Array.from({ length: 10 }, v => Math.random() * 10240000),
      xData: Array.from({ length: 10 }, (v, w) => 'powersi' + w)
    }
  },
  computed: {},
  watch: {
    objData: {
      handler(val) {
        // this.queryNetworkBandwith()
      },
      deep: true
    }
  },
  mounted() {
    this.draw() // 临时展示作用
  },
  methods: {
    queryTPSTransation() {
      const params = {
        number: '40',
        period: this.objData.period,
        rtTaskNo: this.objData.rtTaskNo
      }
      queryTPSTransation(params).then(res => {
        if (res.code === 0) {
          this.xData = res.data.time
          this.yData = res.data.data
          this.draw()
        }
      })
    },
    draw() {
      var option = {
        grid: {
          top: '20%',
          left: '2%',
          right: '5%',
          bottom: '15%',
          containLabel: true
        },
        title: {
          text: '表占用存储Top',
          textStyle: {
            color: '#fff',
            fontSize: 16
          },
          left: '1%',
          top: '3%',
          bottom: '20%'
        },
        tooltip: {
          trigger: 'axis',
          padding: [2, 10],
          textStyle: {
            fontSize: 16
          },
          formatter: function(data) {
            // 格式化为字节并格式化tooltip
            var filesize = data[0].value
            var result = data[0].axisValue + '<br/>'
            if (filesize == null || filesize == '') {
              return '0 Bytes'
            }
            var unitArr = [
              'Bytes',
              'KB',
              'MB',
              'GB',
              'TB',
              'PB',
              'EB',
              'ZB',
              'YB'
            ]
            var index = 0
            var srcsize = parseFloat(filesize)
            index = Math.floor(Math.log(srcsize) / Math.log(1024))
            var size = srcsize / Math.pow(1024, index)
            size = size.toFixed(2) // 保留的小数位数
            result +=
              data[0].seriesName + ':' + size + unitArr[index] + '</br>'
            return result
          }
        },
        color: ['#00a3e5'],
        xAxis: {
          data: this.xData,
          type: 'category',
          boundaryGap: [0, 0.01],
          show: true,
          axisLine: {
            show: true,
            lineStyle: {
              color: '#fff'
            }
          }
        },

        yAxis: {
          type: 'value',
          data: this.yData,
          axisTick: {
            show: true
          },
          axisLine: {
            show: true,
            lineStyle: {
              color: '#fff'
            }
          },
          axisLabel: {
            interval: 0,
            margin: 15
          }
        },
        series: [
          {
            name: '2011年',
            type: 'bar',
            data: this.yData,
            barWidth: 20, // 柱图宽度
            itemStyle: {
              normal: {
                borderRadius: 10,
                label: {
                  show: true, // 开启显示
                  position: 'top', // 在上方显示
                  textStyle: {
                    // 数值样式
                    color: '#fff',
                    fontSize: 16,
                    top: 10
                  },
                  formatter: function(data) {
                    // 格式化为字节
                    var filesize = data.value
                    if (filesize == null || filesize == '') {
                      return '0 Bytes'
                    }
                    var unitArr = [
                      'Bytes',
                      'KB',
                      'MB',
                      'GB',
                      'TB',
                      'PB',
                      'EB',
                      'ZB',
                      'YB'
                    ]
                    var index = 0
                    var srcsize = parseFloat(filesize)
                    index = Math.floor(Math.log(srcsize) / Math.log(1024))
                    var size = srcsize / Math.pow(1024, index)
                    size = size.toFixed(2) // 保留的小数位数
                    return size + unitArr[index]
                  }
                }
              }
            }
          }
        ]
      }
      // 初始化图表
      const chartObj = echarts.init(document.getElementById('occupyChart'))
      chartObj.setOption(option)
      if (option && typeof option === 'object') {
        chartObj.setOption(option)
      }
    },
    navToMoreDetail() {
      this.$router.push('/dataMap/myData')
    }
  }
}
</script>

<style scoped lang="scss" scoped>
.trend-map {
  margin-top: 15px;
  background-color: #343d47;
  position: relative;
}

.occupy-more {
  position: absolute;
  right: 40px;
  top: 10px;
  z-index: 999;
  font-size: 14px;
  cursor: pointer;
  padding: 3px 3px 3px 6px;
  &:hover{
    background-color: #212a33;
    border-radius: 3px;
  }
}
#occupyChart {
  height: 400px;
}
</style>

echart tootip格式化

tooltip: {
  trigger: 'axis',
  padding: [2, 10],
  textStyle: {
    fontSize: 16
  },
  formatter: function (data) { // 格式化为字节并格式化tooltip
    var filesize = data[0].value
    var result = data[0].axisValue + '<br/>'
    if (filesize == null || filesize == '') {
      return '0 Bytes'
    }
    var unitArr = new Array('Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB')
    var index = 0
    var srcsize = parseFloat(filesize)
    index = Math.floor(Math.log(srcsize) / Math.log(1024))
    var size = srcsize / Math.pow(1024, index)
    size = size.toFixed(2) // 保留的小数位数
    result += data[0].seriesName + ':' + size + unitArr[index] + '</br>'
    return result
  }
},

随机生成数据

yData: Array.from({ length: 10 }, v => Math.random() * 10240000),
xData: Array.from({ length: 10 }, (v, w) => 'powersi' + w)

标准头部

[图片上传失败...(image-f5e1f8-1601955925264)]

 <header>
      <span class="title">服务器管理</span>
      <div class="query">
        <el-form :inline="true" class="demo-form-inline">
          <el-form-item>
            <el-input v-model="dbName" clearable placeholder="请输入服务器名称" @keyup.enter.native="getData">
              <template slot="prepend">搜索</template>
              <el-button slot="append" icon="el-icon-search" @click.native.prevent="getData" />
            </el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="el-icon-plus" @click="showDatabase = true">新增服务器</el-button>
          </el-form-item>
        </el-form>
      </div>
    </header>

element-ui表格

[图片上传失败...(image-6e5b8a-1601955925265)]

<div class=" taskOperationMonitoring">
      <!-- 服务器管理 -->
      <div class="data-sourse">
        <el-table :data="tableData" height="650" stripe style="width: 100%;">
          <el-table-column type="index" label="序号" align="center" width="50" />
          <el-table-column prop="ips" label="服务器IP地址" align="center" width="180" />
          <el-table-column prop="port" label="端口" align="center" />
          <el-table-column prop="host" label="主机" align="center" width="180" />
          <el-table-column prop="username" label="用户名" align="center" />
          <el-table-column prop="password" label="密码" align="center" />
          <el-table-column prop="privat" label="私钥" align="center" />
          <el-table-column prop="cpu" label="CPU核数" align="center" />
          <el-table-column prop="storage" label="内存(GB)" align="center" />
          <el-table-column prop="sd" label="磁盘大小(GB)" align="center" />
          <el-table-column prop="isSD" label="是否SSD" align="center">
            <template slot-scope="scope">
              <span v-if="scope.taskStas= '1'" class="success">正常</span>
              <span v-else class="danger">异常</span>
            </template>
          </el-table-column>
          <el-table-column prop="other" label="备注" align="center" />
          <el-table-column label="操作" align="center" width="140">
            <template slot-scope="scope">
              <el-button type="primary" size="mini" @click="details(scope.row)">编辑</el-button>
              <el-button type="primary" size="mini" @click="deleteItem(scope.row)">删除</el-button>
            </template>
          </el-table-column>
        </el-table>
        <el-pagination
          :current-page="currentPage"
          :page-sizes="[10, 20, 30, 40]"
          :page-size="pageSize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
</div>

data() {
    return {
      tableData: Array(15).fill(item),
      currentPage: 1,
      pageSize: 20,
      total: 20
    }
}

页面跳转清除定时器

data() {            
    return {                              
        timer: null  // 定时器名称          
    }        
},
mounted(){
this.timer = (() => {
    // 某些操作
}, 1000)
},
 
//最后在beforeDestroy()生命周期内清除定时器:
 
beforeDestroy() {
    clearInterval(this.timer);        
    this.timer = null;
}
const timer = setInterval(() =>{
    // 某些定时器操作                
}, 500);            
// 通过$once来监听定时器,在beforeDestroy钩子可以被清除。
this.$once('hook:beforeDestroy', () => {            
    clearInterval(timer);                                    
})

vue通用模板

<template>
  <div class="">
    地区间参保覆盖情况分析
  </div>
</template>

<script>
export default {
  name: '',
  components: {},
  mixins: [],
  props: {},
  data() {
    return {}
  },
  computed: {},
  watch: {},
  created() {},
  mounted() {},
  methods: {},
}
</script>

<style scoped lang="scss">
</style>

filters过滤器

引入
import { toThousandFilter, numberToPercent } from '../../../filters'
// import parseTime, formatTime and set to filter
export { parseTime, formatTime } from '@/utils'

/**
 * Show plural label if time is plural number
 * @param {number} time
 * @param {string} label
 * @return {string}
 */
function pluralize(time, label) {
  if (time === 1) {
    return time + label
  }
  return time + label + 's'
}

/**
 * @param {number} time
 */
export function timeAgo(time) {
  const between = Date.now() / 1000 - Number(time)
  if (between < 3600) {
    return pluralize(~~(between / 60), ' minute')
  } else if (between < 86400) {
    return pluralize(~~(between / 3600), ' hour')
  } else {
    return pluralize(~~(between / 86400), ' day')
  }
}

/**
 * Number formatting
 * like 10000 => 10k
 * @param {number} num
 * @param {number} digits
 */
export function numberFormatter(num, digits) {
  const si = [
    { value: 1E18, symbol: 'E' },
    { value: 1E15, symbol: 'P' },
    { value: 1E12, symbol: 'T' },
    { value: 1E9, symbol: 'G' },
    { value: 1E6, symbol: 'M' },
    { value: 1E3, symbol: 'k' }
  ]
  for (let i = 0; i < si.length; i++) {
    if (num >= si[i].value) {
      return (num / si[i].value).toFixed(digits).replace(/\.0+$|(\.[0-9]*[1-9])0+$/, '$1') + si[i].symbol
    }
  }
  return num.toString()
}

/**
 * 10000 => "10,000"
 * @param {number} num
 */
export function toThousandFilter(num) {
  return (+num || 0).toString().replace(/^-?\d+/g, m => m.replace(/(?=(?!\b)(\d{3})+$)/g, ','))
}

/**
 * Upper case first char
 * @param {String} string
 */
export function uppercaseFirst(string) {
  return string.charAt(0).toUpperCase() + string.slice(1)
}

/**
 * money formatting
 * like 10000 => 1万元
 * @param {number | String} value
 */

export function moneyFilter(value) {
  if (!value) return '0元'
  let result = 0
  if (parseFloat(value) >= 10000) {
    result = (value / 10000).toFixed(2) + '万元'
  } else if (parseFloat(value) >= 100000000) {
    result = (value / 100000000).toFixed(2) + '亿元'
  } else {
    result = value + '元'
  }
  return result
}

/**
 * count formatting
 * like 10000 => 1万次
 * @param {number | String} value
 */

export function conutFilter(value) {
  if (!value) return '0次'
  let result = 0
  if (parseFloat(value) >= 10000) {
    result = (value / 10000).toFixed(2) + '万次'
  } else if (parseFloat(value) >= 100000000) {
    result = (value / 100000000).toFixed(2) + '亿次'
  } else {
    result = value + '次'
  }
  return result
}

export function numberToPercent(value, total, fixed) {
  // console.log(value)
  // console.log(total)
  // console.log((value / total * 100).toFixed(fixed) + '%')
  return (value / total * 100).toFixed(fixed) + '%'
}

基本路由配置

{
    path: '/assistDecision',
    component: Layout,
    alwaysShow: true,
    redirect: '/assistDecision/medicalPriceAnalyze',
    meta: {
      title: '数据分析平台',
      icon: 'icon'
    },
    children: [
      {
        path: 'medicalPriceAnalyze',
        component: () => import('@/views/assist-decision/medical-price-analyze/index'),
        name: 'medicalPriceAnalyze',
        meta: { title: '医疗机构费用分析', icon: 'icon', noCache: true }
      }
}

utils公共函数使用

引入

import { deepClone } from '@/utils/index'

获取select的label值

/**
 * 获取select的label值
 * @param value 选中id
 * @param arr   原数组
 * @param idName  id的字段名
 * @param labelName  name的字段名
 * @returns {*}
 */
export function getSelectLabel(value, arr, idName, labelName) {
  return arr.find(item => {
    return item[idName] === value
  })[labelName]
}

时间格式化

/**
 * Parse the time to string
 * @param {(Object|string|number)} time
 * @param {string} cFormat
 * @returns {string | null}
 */
export function parseTime(time, cFormat) {
  if (arguments.length === 0) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if ((typeof time === 'string')) {
      if ((/^[0-9]+$/.test(time))) {
        // support "1548221490638"
        time = parseInt(time)
      } else {
        // support safari
        // https://stackoverflow.com/questions/4310953/invalid-date-in-safari
        time = time.replace(new RegExp(/-/gm), '/')
      }
    }

    if ((typeof time === 'number') && (time.toString().length === 10)) {
      time = time * 1000
    }
    date = new Date(time)
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{([ymdhisa])+}/g, (result, key) => {
    const value = formatObj[key]
    // Note: getDay() returns 0 on Sunday
    if (key === 'a') {
      return ['日', '一', '二', '三', '四', '五', '六'][value]
    }
    return value.toString().padStart(2, '0')
  })
  return time_str
}

时间转几小时前

/**
 * @param {number} time
 * @param {string} option
 * @returns {string}
 */
export function formatTime(time, option) {
  if (('' + time).length === 10) {
    time = parseInt(time) * 1000
  } else {
    time = +time
  }
  const d = new Date(time)
  const now = Date.now()

  const diff = (now - d) / 1000

  if (diff < 30) {
    return '刚刚'
  } else if (diff < 3600) {
    // less 1 hour
    return Math.ceil(diff / 60) + '分钟前'
  } else if (diff < 3600 * 24) {
    return Math.ceil(diff / 3600) + '小时前'
  } else if (diff < 3600 * 24 * 2) {
    return '1天前'
  }
  if (option) {
    return parseTime(time, option)
  } else {
    return (
      d.getMonth() +
      1 +
      '月' +
      d.getDate() +
      '日' +
      d.getHours() +
      '时' +
      d.getMinutes() +
      '分'
    )
  }
}

获取url的参数

/**
 * @param {string} url
 * @returns {Object}
 */
export function getQueryObject(url) {
  url = url == null ? window.location.href : url
  const search = url.substring(url.lastIndexOf('?') + 1)
  const obj = {}
  const reg = /([^?&=]+)=([^?&=]*)/g
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1)
    let val = decodeURIComponent($2)
    val = String(val)
    obj[name] = val
    return rs
  })
  return obj
}

获取字节长度

/**
 * @param {string} input value
 * @returns {number} output value
 */
export function byteLength(str) {
  // returns the byte length of an utf8 string
  let s = str.length
  for (var i = str.length - 1; i >= 0; i--) {
    const code = str.charCodeAt(i)
    if (code > 0x7f && code <= 0x7ff) {
      s++
    } else if (code > 0x7ff && code <= 0xffff) s += 2
    if (code >= 0xDC00 && code <= 0xDFFF) i--
  }
  return s
}

清除数组

/**
 * @param {Array} actual
 * @returns {Array}
 */
export function cleanArray(actual) {
  const newArray = []
  for (let i = 0; i < actual.length; i++) {
    if (actual[i]) {
      newArray.push(actual[i])
    }
  }
  return newArray
}

json转数组

/**
 * @param {Object} json
 * @returns {Array}
 */
export function param(json) {
  if (!json) return ''
  return cleanArray(
    Object.keys(json).map(key => {
      if (json[key] === undefined) return ''
      return encodeURIComponent(key) + '=' + encodeURIComponent(json[key])
    })
  ).join('&')
}

字符串转对象

/**
 * @param {string} url
 * @returns {Object}
 */
export function param2Obj(url) {
  const search = url.split('?')[1]
  if (!search) {
    return {}
  }
  return JSON.parse(
    '{"' +
    decodeURIComponent(search)
      .replace(/"/g, '\\"')
      .replace(/&/g, '","')
      .replace(/=/g, '":"')
      .replace(/\+/g, ' ') +
    '"}'
  )
}

富文本过滤成普通文本

/**
 * @param {string} val
 * @returns {string}
 */
export function html2Text(val) {
  const div = document.createElement('div')
  div.innerHTML = val
  return div.textContent || div.innerText
}

对象克隆

/**
 * Merges two objects, giving the last one precedence
 * @param {Object} target
 * @param {(Object|Array)} source
 * @returns {Object}
 */
export function objectMerge(target, source) {
  if (typeof target !== 'object') {
    target = {}
  }
  if (Array.isArray(source)) {
    return source.slice()
  }
  Object.keys(source).forEach(property => {
    const sourceProperty = source[property]
    if (typeof sourceProperty === 'object') {
      target[property] = objectMerge(target[property], sourceProperty)
    } else {
      target[property] = sourceProperty
    }
  })
  return target
}

toggle效果

/**
 * @param {HTMLElement} element
 * @param {string} className
 */
export function toggleClass(element, className) {
  if (!element || !className) {
    return
  }
  let classString = element.className
  const nameIndex = classString.indexOf(className)
  if (nameIndex === -1) {
    classString += '' + className
  } else {
    classString =
      classString.substr(0, nameIndex) +
      classString.substr(nameIndex + className.length)
  }
  element.className = classString
}

获取当前时间

/**
 * @param {string} type
 * @returns {Date}
 */
export function getTime(type) {
  if (type === 'start') {
    return new Date().getTime() - 3600 * 1000 * 24 * 90
  } else {
    return new Date(new Date().toDateString())
  }
}

防抖函数

/**
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
export function debounce(func, wait, immediate) {
  let timeout, args, context, timestamp, result

  const later = function() {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp

    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last)
    } else {
      timeout = null
      // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args)
        if (!timeout) context = args = null
      }
    }
  }

  return function(...args) {
    context = this
    timestamp = +new Date()
    const callNow = immediate && !timeout
    // 如果延时不存在,重新设定延时
    if (!timeout) timeout = setTimeout(later, wait)
    if (callNow) {
      result = func.apply(context, args)
      context = args = null
    }

    return result
  }
}

深克隆

/**
 * This is just a simple version of deep copy
 * Has a lot of edge cases bug
 * If you want to use a perfect deep copy, use lodash's _.cloneDeep
 * @param {Object} source
 * @returns {Object}
 */
export function deepClone(source) {
  if (!source && typeof source !== 'object') {
    throw new Error('error arguments', 'deepClone')
  }
  const targetObj = source.constructor === Array ? [] : {}
  Object.keys(source).forEach(keys => {
    if (source[keys] && typeof source[keys] === 'object') {
      targetObj[keys] = deepClone(source[keys])
    } else {
      targetObj[keys] = source[keys]
    }
  })
  return targetObj
}

数组去重

/**
 * @param {Array} arr
 * @returns {Array}
 */
export function uniqueArr(arr) {
  return Array.from(new Set(arr))
}

创建唯一ID

/**
 * @returns {string}
 */
export function createUniqueString() {
  const timestamp = +new Date() + ''
  const randomNum = parseInt((1 + Math.random()) * 65536) + ''
  return (+(randomNum + timestamp)).toString(32)
}

判断元素受否有该class

/**
 * Check if an element has a class
 * @param {HTMLElement} elm
 * @param {string} cls
 * @returns {boolean}
 */
export function hasClass(ele, cls) {
  return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
}

元素添加class

/**
 * Add class to element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
export function addClass(ele, cls) {
  if (!hasClass(ele, cls)) ele.className += ' ' + cls
}

获取hasClass

/**
 * Remove class from element
 * @param {HTMLElement} elm
 * @param {string} cls
 */
export function removeClass(ele, cls) {
  if (hasClass(ele, cls)) {
    const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')
    ele.className = ele.className.replace(reg, ' ')
  }
}

时间格式化,不包含时分秒

/**
 * 时间格式化,不包含时分秒
 * @param _date
 * @returns {string}
 * @constructor
 */
export function FormatDateNoTime(_date) {
  if (_date === '' || _date === null || _date === undefined) {
    return ''
  } else {
    const now = new Date(_date)
    const year = now.getFullYear()
    const month = now.getMonth() + 1 < 10 ? '0' + (now.getMonth() + 1) : now.getMonth() + 1
    const date = now.getDate() < 10 ? '0' + now.getDate() : now.getDate()
    return year + '/' + month + '/' + date
  }
}

生成年份

<el-form-item label="统计年度" prop="opspTrtCode">
    <el-select v-model="searchForm.opspTrtCode" clearable placeholder="请选择统计年度" allow-create style="width:100%"
        :fetch-suggestions="searchType" :trigger-on-focus="false">
        <el-option label="全部" value="" />
        <el-option v-for="item in initSelectYear()" :key="item.value" :label="item.label" :value="item.value" />
    </el-select>
</el-form-item>
initSelectYear() {
  var myDate = new Date()
  var year = myDate.getFullYear() // 获取当前年
  var years = []
  for (let i = 0; i < 30; i++) {
    years.push({ value: year - i, label: year - i + '年' })
  }
  return years
}

地图组件标点

<template>
  <div class="interzone-map">
    <div id="interzoneMap" />
  </div>
</template>
<script>
import echarts from 'echarts'
import './map/js/china'
// import './map/js/province/anhui'
// import './map/js/province/zhejiang'
// import './map/js/province/aomen'
// import './map/js/province/xianggang'
// import './map/js/province/guangdong'
// import './map/js/province/jiangxi'
// import './map/js/province/jiangsu'
// import './map/js/province/fujian'
// import './map/js/province/gansu'
// import './map/js/province/guizhou'
// import './map/js/province/sichuan'
// import './map/js/province/hubei'
export default {
  name: 'EchartMap',
  components: {},
  mixins: [],
  props: {},
  data() {
    return {
      myChart: null,
      map_name: 'china', // 地图
      mapData: [],
      geoCoordMap: {}
    }
  },
  computed: {},
  watch: {},
  created() {},
  mounted() {
    this.myChart = echarts.init(document.getElementById('interzoneMap'))
    window.onresize = () => {
      // 根据窗口大小调整曲线大小
      this.myChart.resize()
    }
    this.init_map() // 地图初始化
  },
  methods: {
    init_map() {
      var data = [
        { name: '海门', value: 88.76 },
        { name: '鄂尔多斯', value: 88.6 },
        { name: '招远', value: 39.21 },
        { name: '舟山', value: 87.54 },
        { name: '齐齐哈尔', value: 19.64 },
        { name: '盐城', value: 54.2 }
      ]
      var geoCoordMap = {
        海门: [121.15, 31.89],
        鄂尔多斯: [109.781327, 39.608266],
        招远: [120.38, 37.35],
        舟山: [122.207216, 29.985295],
        齐齐哈尔: [123.97, 47.33],
        盐城: [120.13, 33.38]
      }
      // 获取数据和坐标
      var convertData = function(data) {
        var res = []
        for (var i = 0; i < data.length; i++) {
          var geoCoord = geoCoordMap[data[i].name]
          if (geoCoord) {
            res.push({
              name: data[i].name,
              value: geoCoord.concat(data[i].value)
            })
          }
        }
        return res
      }

      var optionMap = {
        backgroundColor: '#FFFFFF',
        title: {
          text: '全国参保覆盖情况',
          subtext: '2020年',
          x: 'center'
        },
        // 提示框
        tooltip: {
          trigger: 'item',
          formatter: function(params) {
            // 添加数字,否则为坐标
            return (
              params.name +
              '<br>' +
              '参保覆盖率' +
              '' +
              ':' +
              '' +
              params.value[2] +
              '' +
              '%'
            )
          },
          padding: [
            5, // 上
            10, // 右
            5, // 下
            10 // 左
          ],
          textStyle: {
            color: '#fff',
            fontSize: '13'
          }
        },
        // 左侧小导航图标
        visualMap: {
          show: false
        },
        // 地图
        geo: {
          map: 'china',
          roam: false,
          itemStyle: {
            // 正常状态下
            normal: {
              areaColor: '#ffe7b2',
              borderColor: '#111'
            },
            // 选定某一区域下 相当于 hover
            emphasis: {
              areaColor: '#ff6341'
            }
          },
          z: 1
        },
        // 配置属性
        series: [
          {
            name: '参保覆盖率',
            type: 'scatter',
            coordinateSystem: 'geo',
            data: convertData(data),
            roam: false,
            label: {
              normal: {
                show: true // 省份名称
              },
              emphasis: {
                show: false
              }
            },
            symbolSize: function(val) {
              return val[2] / 8 // 也可以根据这里的数值更改大小  val[2] / x  x越小,标点越大
            }
          },
          {
            name: '参保覆盖率',
            type: 'effectScatter',
            coordinateSystem: 'geo',
            data: convertData(
              data
                .sort(function(a, b) {
                  // 这里是多个数据比较大小
                  return b.value - a.value
                })
                .slice(0, 1000)
            ), // slice里面的数可以是0 ,意思是全部显示  0,1000 意思是显示这组数据中最大前1000组
            symbolSize: function(val) {
              return val[2] / 5
            },
            showEffectOn: 'render',
            rippleEffect: {
              brushType: 'stroke'
            },
            hoverAnimation: true,
            label: {
              normal: {
                formatter: '{b}',
                position: 'right',
                show: false
              },
              emphasis: {
                show: false
              }
            }
          }
        ]
      }
      // 使用制定的配置项和数据显示图表
      this.myChart.setOption(optionMap)
      this.myChart.on('click', (params) => {
        console.log(params)
      })
    }
  }
}
</script>
<style scoped lang="scss">
.interzone-map {
  width: 100%;
  height: 100%;
  #interzoneMap {
    width: 100%;
    height: 100%;
  }
}
</style>

Echart组件封装

<template>
  <div class="My_Charts_Wrapper">
    <div :id="id" :class="className" class="My_Charts" :style="{height:height,width:width}" />
  </div>
</template>

<script>
import echarts from 'echarts'
require('echarts/theme/macarons')
import resize from './mixins/resize'

export default {
  name: 'MyCharts',
  components: {},
  mixins: [resize],
  props: {
    id: {
      type: String,
      default: 'myCharts'
    },
    className: {
      type: String,
      default: 'chart'
    },
    width: {
      type: String,
      default: '100%'
    },
    height: {
      type: String,
      default: '100%'
    },
    options: {
      type: Object,
      default: function() {
        return {}
      }
    }
  },
  data() {
    return {
      chart: null,
      defaultOptions: {
        grid: { left: '3%', right: '4%', bottom: '3%', top: '30', containLabel: true },
        tooltip: {
          trigger: 'axis',
          axisPointer: { type: 'shadow' }
        }
      }
    }
  },
  computed: {},
  watch: {
    options: {
      deep: true,
      handler(val) {
        this.setOptions(Object.assign(val, this.options))
      }
    }
  },
  created() {
  },
  mounted() {
    this.$nextTick(() => {
      this.init()
    })
  },
  beforeDestroy() {
    if (!this.chart) {
      return
    }
    this.chart.dispose()
    this.chart = null
  },
  methods: {
    init() {
      this.chart = echarts.init(document.getElementById(this.id), 'macarons')
      this.setOptions()
    },
    setOptions() {
      this.chart.setOption(Object.assign(this.defaultOptions, this.options))
    }
  }
}
</script>

<style scoped lang="scss">
  .My_Charts_Wrapper {
    width: 100%;
    height: 100%;
  }
  .My_Charts {
    >div {
      margin: 0 auto;
    }
    /deep/ .charts-table {
      width: 100%;
      border: 1px solid #dfe6ec;
      text-align: center;
      border-collapse: collapse;
      >thead{
        >tr{
          >th{
            height: 40px;
            background: #F0F2F5;
            border-right: 1px solid #cecece;
            border-bottom: 1px solid #dfe6ec;
            &:last-child {
              border-right: none;
            }
          }
        }
      }
      >tbody {
        >tr{
          >td{
            height: 40px;
            border-right: 1px solid #cecece;
            border-bottom: 1px solid #dfe6ec;
            &:last-child {
              border-right: none;
            }
          }
          &:last-child {
            >td {
              border-bottom: none;
            }
          }
        }
      }
    }
  }
</style>

引入码表字段

import { getInsutype } from '@/api/PaymentInAdvance/PaymentInAdvanceManage/Request'
import { CHK_STAS } from '@/utils/constant'

获取码表对应字段,塞入下拉

import { getCodeTableDetailConvergence } from '@/api/Common/Request'
// 查码表
getCodeTableDetailConvergence() {
  const codeType = CHK_STAS
  getCodeTableDetailConvergence({ codeType }).then(res => {
    this.$set(this.itemsDatas[2], 'options', res.data[CHK_STAS])
  })
}

引入colunms

import Columns from './columns'

标准参考页面

<!-- 单位待转金查询 -->
<template>
  <normal-layer
    :search-number="itemsDatas.length"
    title-name="单位待转金查询列表"
    title-need-handle
  >
    <template slot="search-header">
      <form-items :items-datas="itemsDatas" :form-datas="queryForm">
        <el-button @click="reset">重置</el-button>
        <el-button type="primary" @click="search">查询</el-button>
      </form-items>
    </template>
    <template slot="title-btns">
      <el-button type="primary" @click="printClick">打印</el-button>
    </template>
    <my-table-view
      v-loading="loading"
      :data="tableData"
      :columns="columns"
    />
    <Pagination />
  </normal-layer>
</template>
<script>
import NormalLayer from '@/views/components/PageLayers/normalLayer'
import FormItems from '@/views/components/PageLayers/form-items'
import PageHandle from '@/mixins/pageHandle'
import Columns from './listCloumns'
export default {
  components: {
    NormalLayer,
    FormItems
  },
  mixins: [PageHandle],
  data() {
    return {
      loading: false,
      itemsDatas: [
        { label: '单位编号', prop: 'xxx', type: 'input' },
        { label: '单位名称', prop: 'xxx', type: 'input' },
        { label: '单位类型', prop: 'xxx', type: 'select' }
      ],
      queryForm: {
        xxx: ''
      },
      columns: Columns,
      tableData: [
        { name: '白兰花', code: 'xxx', nameCode: 'xxx' },
        { name: '白兰花', code: 'xxx', nameCode: 'xxx' }
      ]
    }
  },
  watch: {
  },
  methods: {
    printClick() {
      window.print()
    }
  }
}
</script>
<style lang='scss' scoped>
</style>

审核和批量审核弹窗

<audit-dialog v-model="showAuditDialog" dialog-title="单位注销审核" @submit="submit" @closeAll="AuditDialogIsShow" />
import AuditDialog from '@/views/components/AuditDialog'
// 批量审核
    batchAuditClick() {
      if (this.multipleSelection.length <= 0) {
        this.$msgConfirm('请选择')
      } else {
        this.showAuditDialog = true
      }
    },

表格详情弹窗

 <!-- 详情弹窗 -->
    <Details :show="DetaVisible" @update:show="DetaIsShow" />
DetaIsShow() {
 this.DetaVisible = false
}

<my-table-view
      v-loading="loading"
      :data="tableData"
      :columns="columns"
      :multiple-selection.sync="multipleSelection"
    >
      <template slot="operation" slot-scope="scope">
        <my-button icon="detail" @click="detailsClick(scope.row)" />
        <my-button icon="audit" @click="review(scope.row)" />
      </template>
    </my-table-view>
detailsClick(row) {
      this.DetaVisible = true
    }

获取查询条件

search() {
    let params = {}
    params = Object.assign({}, this.searchForm)
    console.log('查询条件', params)
}

常用字段

'formCode':'表格编码'
'formNum':'金额'
'formDepart':'制表部门'
'formTime':'制表时间'
'formDealer':'经办人'
'status':'状态'
'operation':'操作'

获取银行类型

import { BANK_TYPE_CODE } from '@/utils/constant'
import { getCodeTableDetailConvergence } from '@/api/Common/Request'

getTableCode() {
    getCodeTableDetailConvergence({ codeType: BANK_TYPE_CODE }).then(res => {
        this.$set(this.itemsDatas[2], 'options', res.data[BANK_TYPE_CODE])
    })
}

搜索重置

<template slot="search-header">
    <form-items ref="queryForm" :items-datas="itemsDatas" :form-datas="queryForm" :rules="rules" :model="queryForm">
        <el-button @click="reset('queryForm')">重置</el-button>
        <el-button type="primary" @click="search">查询</el-button>
    </form-items>
</template>
reset(formName) {
    this.$refs[formName]['elForm'].resetFields()
}

批量审核

<template slot="title-btns">
    <el-button type="primary" @click="addClick">批量审核</el-button>
</template>
addClick(row) {
    if (this.multipleSelection.length > 0) {
        this.showAuditDialog = true
    } else {
        this.$msgError('请至少选择一行!')
    }
}
submit(v) {
    const params = {
        rchkFlag: v.data.statue,
        memo: v.data.content,
        taxItrcEvtId: this.multipleSelection.map(item => item.taxItrcEvtId)
    }
    // 保存灵活就业征集信息发送审核
    Api.saveTaxFlexiblePaySendAud(params).then(res => {
        if (res.code === 0) {
            v.fn()
            this.search()
        } else {
            this.$msgError(res.message)
        }
    })
}

搜索条件

search() {
    if (this.queryForm.optTime.length > 0) {
        this.queryForm.optTimeBegn = this.queryForm.optTime[0]
        this.queryForm.optTimeEnd = this.queryForm.optTime[1]
    }
    this.$refs.queryForm['elForm'].validate(valid => {
        if (valid) {
            // 查询灵活就业征集信息发送审核列表
            Api.listTaxFlexiblePaySendAud(Object.assign(this.queryForm, this.paginationQuery)).then(res => {
                if (res.code === 0) {
                    this.tableData = res.data.data
                    this.setPaginationQuery(res.data)
                } else {
                    this.$msgError(res.message)
                }
            })
        }
    })
}

form-items的配置和码表查询

input
number
textarea
select
codeTable codeKey: 'XXX_XXX',告诉组件加载什么码值
radio
checkbox
cascader 级联选择器
date 选择日期
dateMoon 选择月份
dateYear 选择年份
dateRange 开始日期-结束日期
dateTime 选择日期时间
dateTimeRange 开始时间-结束时间
monthRange 开始月份-结束月份
file
switch
custom
component
<!-- 需要prop, componentName, folder or allPath -->
<!-- 注意: 仅支持v-model传参 以及change事件 的组件-->

码表查询:
{ label: '状态', prop: 'status', type: 'codeTable', codeKey: 'CAPT_DFR_TAB_STAS', options: [] }

查询接口

// 查询接口
listMidCancLog() {
    const params = {
        accrym: this.queryForm.date || '',
        certNo: this.queryForm.peopleInfo.certNo || '',
        name: this.queryForm.peopleInfo.psnName || '',
        psnNo: this.queryForm.peopleInfo.psnNo || ''
    }
    listMidCancLog(params).then(res => {
        if (res.code === 0) {
            this.tableData = res.data.data
            this.$set(this.paginationQuery, 'total', res.data.recordCounts)
            this.$set(this.paginationQuery, 'startRow', res.data.startRow)
            this.$set(this.paginationQuery, 'endRow', res.data.endRow)
            this.loading = false
        }
    })
}

分页组件

import PageHandle from '@/mixins/pageHandle'
<Pagination :data="paginationQuery" @refresh="pageChange" />
this.setPaginationQuery(res.data)

this.$set(this.paginationQuery, 'total', res.data.recordCounts)
this.$set(this.paginationQuery, 'startRow', res.data.startRow)
this.$set(this.paginationQuery, 'endRow', res.data.endRow)

审核组件

<audit-dialog v-model="showAuditDialog" dialog-title="城乡大病资金拨付列表" @submit="submitAudit" />
auditAppropriationTable(params).then((res) => {
   v.fn()
   this.multipleSelection = []
   this.search()
}).catch((err) => {
   v.fn('error', err.message)
})

格式化年月

import moment from 'moment'
{ label: '对应款项属期', prop: 'accrym', type: 'dateMoon' ,valueFormat: 'yyyyMM'}
queryForm: {
   accrym: moment().format('yyyyMM'),
},

人员编码

00000000000000000000000144
00000000000000000000000152
00000000000000000000000155
00000000000000000000000171
00000000000000000000000176
00000000000000000000000178
00000000000000000000000191
00000000000000000000000193
00000000000000000000000206
00000000000000000000000208
00000000000000000000000211
00000000000000000000000214

00000000000000000000000193

查询人员详细信息

itemsDatas: [
{ label: '查询条件', 
prop: 'psnInfo',
type: 'component',
componentName: 'Personal',
folder: 'Common',
fn: (v) => { this.qryPsnInfo(v) } },
]

import { queryPsnInsuInfo } from '@/api/Common/Request'
qryPsnInfo(v) {
      // 查询人员参保信息
      const vm = this
      if (typeof v === 'object') {
        vm.queryForm = {
          psnInfo: v,
          psnNo: v.psnNo,
          psnName: v.psnName,
          gendName: v.gendName,
          certno: v.certno,
          psnCertTypeName: v.psnCertTypeName,
          brdy: v.brdy,
          fstPatcJobDate: v.fstPatcJobDate
        }
        queryPsnInsuInfo({ psnNo: v.psnNo }).then(res => {
          const data = res.data !== null && res.data.length > 0 ? res.data[0] : {}
          vm.queryForm = {
            ...vm.queryForm,
            empNo: data.empNo,
            empName: data.empName,
            psnInsuStasName: data.psnInsuStasName
          }
        })
      }
}

人员编码

00000000000000000000000144
00000000000000000000000152
00000000000000000000000155
00000000000000000000000171
00000000000000000000000176
00000000000000000000000178
00000000000000000000000191
00000000000000000000000193
00000000000000000000000206
00000000000000000000000208
00000000000000000000000211
00000000000000000000000214
1001 个人电脑号
00000000000000000000000193

查询人员详细信息

itemsDatas: [
{ label: '查询条件', 
prop: 'psnInfo',
type: 'component',
componentName: 'Personal',
folder: 'Common',
fn: (v) => { this.qryPsnInfo(v) } },
]

import { queryPsnInsuInfo } from '@/api/Common/Request'
qryPsnInfo(v) {
      // 查询人员参保信息
      const vm = this
      if (typeof v === 'object') {
        vm.queryForm = {
          psnInfo: v,
          psnNo: v.psnNo,
          psnName: v.psnName,
          gendName: v.gendName,
          certno: v.certno,
          psnCertTypeName: v.psnCertTypeName,
          brdy: v.brdy,
          fstPatcJobDate: v.fstPatcJobDate
        }
        queryPsnInsuInfo({ psnNo: v.psnNo }).then(res => {
          const data = res.data !== null && res.data.length > 0 ? res.data[0] : {}
          vm.queryForm = {
            ...vm.queryForm,
            empNo: data.empNo,
            empName: data.empName,
            psnInsuStasName: data.psnInsuStasName
          }
        })
      }
}

列表返回处理

if (res.code === 0) {
  const temp = res.data || {}
  this.tableData = temp.data
  this.setPaginationQuery(res.data)
}

审核处理

submitAudit(v) {
  const listInfo = []
  this.multipleSelection.map(item => {
    const { acctIncDetlId, exchDataLotnum } = item
    listInfo.push({
      'acctIncDetlId': acctIncDetlId,
      'exchDataLotnum': exchDataLotnum
    })
  })
  const params = {
    'memo': v.data.content,
    'auditFlag': v.data.statue,
    'personAccountCrtfDTOList': listInfo,
    'exchDataLotnum': this.queryForm.exchDataLotnum.value || '100003'
  }
  updateBatchApplyAcctCrtfs(params).then((res) => {
    v.fn()
    this.multipleSelection = []
    this.search()
  }).catch((err) => {
    v.fn('error', err.message)
  })
}

列表返回处理

if (res.code === 0) {
  const temp = res.data || {}
  this.tableData = temp.data
  this.setPaginationQuery(res.data)
}

审核处理

submitAudit(v) {
  const listInfo = []
  this.multipleSelection.map(item => {
    const { acctIncDetlId, exchDataLotnum } = item
    listInfo.push({
      'acctIncDetlId': acctIncDetlId,
      'exchDataLotnum': exchDataLotnum
    })
  })
  const params = {
    'memo': v.data.content,
    'auditFlag': v.data.statue,
    'personAccountCrtfDTOList': listInfo,
    'exchDataLotnum': this.queryForm.exchDataLotnum.value || '100003'
  }
  updateBatchApplyAcctCrtfs(params).then((res) => {
    v.fn()
    this.multipleSelection = []
    this.search()
  }).catch((err) => {
    v.fn('error', err.message)
  })
}

acpType: "0"
admdvs: ""
bizStas: ""
endAccrym: ""
endTime: ""
isPage: ""
name: ""
pageNum: 1
pageSize: 15
pageType: "0"
psnNo: ""
startAccrym: ""
startTime: ""

// target: 'http://172.18.20.182:20001', // 和宇云地址
// target: 'http://172.18.20.178:8080', // 测试ip地址
// target: 'http://172.16.74.187:8888',
// target: 'http://172.16.75.103:8888',
// target: 'http://172.16.72.164:8888', // 麻超宇
// target: 'http://172.16.75.21:8888', // 罗忠伟
target: 'http://172.16.73.247:8888', // 曾楷轩
// target: 'http://172.16.39.58:8888', // 胡自强
// target: 'http://172.16.43.156:8888', // 李彩

更新父级页面表单

this.$emit('update-table')


//父级
 @update-table="updateTable"
 
 updateTable() {
      this.showDetailDialog = false
      this.search()
    },

分页处理

:data="paginationQuery" @refresh="pageChange"

paginationQuery: {
 pageNum: 1,
 pageSize: 15,
 total: 10,
 startRow: 1,
 endRow: 10
},   
pageChange(data) {
 this.paginationQuery = data.pagination
 this.search()
},

编辑详情

detail:{}
editClick(row) {
  this.dialogTitle = '数据库维护修改'
  this.showDetailDialog = true
  this.detail = row
}
detail: {
  type: Object,
  default: function() {
    return {}
  }
}

<edit-dialog v-model="showEditDialog" :dialog-title="dialogTitle" @update-table="updateTable" />
 watch: {
    detail: {
      handler(newVal) {
        console.log(newVal)
        if (newVal) {
          this.dataForm = newVal
        }
      },
      deep: true
  }
}

查询企业信息

{ label: '查询条件', prop: 'empInfo', type: 'component', componentName: 'EmpInfo', folder: 'Common',
          fn: (v) => {
            this.queryForm = {
              empInfo: v,
              empNo: v.empNo,
              empName: v.empName
            }
          }
        }

分页处理

:data="paginationQuery" @refresh="pageChange"

paginationQuery: {
 pageNum: 1,
 pageSize: 15,
 total: 10,
 startRow: 1,
 endRow: 10
},   
pageChange(data) {
 this.paginationQuery = data.pagination
 this.search()
},

编辑详情

detail:{}
editClick(row) {
  this.dialogTitle = '数据库维护修改'
  this.showDetailDialog = true
  this.detail = row
}
detail: {
  type: Object,
  default: function() {
    return {}
  }
}

<edit-dialog v-model="showEditDialog" :dialog-title="dialogTitle" @update-table="updateTable" />
 watch: {
    detail: {
      handler(newVal) {
        console.log(newVal)
        if (newVal) {
          this.dataForm = newVal
        }
      },
      deep: true
  }
}

输入框设置默认值

infoForm1: {
    empNo: '',
    insutype: INSU_TYPE_BASIC,
    year: CURRENT_YEAR,
    rchkFlag: RCHK_FLAG_F,
    date: [CURRENT_DAY, CURRENT_DAY],
}

form-items细节处理

{ label: '年度', prop: 'year', type: 'dateYear', clearable: false },

{ label: '险种类型', prop: 'insutype', type: 'select', options: [{ dataVal: '310', dispVal: '职工基本医疗保险' }], clearable: false },

import { CURRENT_YEAR, RCHK_FLAG_F, INSU_TYPE_BASIC, PAGE_SIZE, CALC_RULES_PS } from '@/utils/constant'

paginationQuery1: { pageSize: PAGE_SIZE, pageNum: 1, total: 0, startRow: 0, endRow: 0 }

// 处理平均工资输入金额
changeAveSalary(row) {
    this.$set(row, 'empMonsAvesalNew', handleInputPrice(row.empMonsAvesalNew))
},

{ label: '台账类型', prop: 'ledType', type: 'codeTable', codeKey: 'LED_TYPE', events: { change: this.selLedType }, clearable: false },


过滤审核状态

{ label: '审核标志', prop: 'rchkFlagName', type: 'custom', slotName: 'handleStatus' },

filters: {
    filtersStatus: function(val) {
        switch (val) {
            case '0':
                return 'nostart'
            case '1':
                return 'pass'
            case '2':
                return 'nopass'
        }
    }
},

处理单位信息

{ label: '单位信息', prop: 'empNo', type: 'component', componentName: 'EmpInfo', folder: 'Common', fn: this.change },

resetForm处理

resetForm() {
    this.reset()
    this.queryForm.rchkFlag = RCHK_FLAG_F
    this.queryForm.date = [CURRENT_DAY, CURRENT_DAY]
},
resetForm() {
    this.reset()
    this.infoForm1.insutype = INSU_TYPE_BASIC
    this.infoForm1.year = CURRENT_YEAR
    this.infoForm1.rchkFlag = RCHK_FLAG_F
},

审核

<AuditDialog :is-dialog-visible="reviewDialogVisible" :dialog-title="reviewDialogTitle" @closeAll="closeAuditDialog" @submit="submitAudit" />

submitAudit(v) {
    const params = {
        empAvesalDclaIdList: this.empAvesalDclaIdList,
        rchkFlag: v.data.statue,
        rchkOpnn: v.data.content
    }
    saveRchkEmpAvesalDcla(params).then(() => {
        v.fn()
        this.search()
    }).catch(() => {
        v.fn('', 'fail')
    })
},

批量审核

// 点击批量审核按钮
batchReview() {
    if (this.multipleSelection.length > 0) {
        this.empAvesalDclaIdList = this.multipleSelection.map(item => item.empAvesalDclaId)
        this.reviewDialogVisible = true
        this.reviewDialogTitle = '单位平均工资维护审核'
    } else {
        this.$msgInfo('请选择所需操作项')
    }
},

获取列表数据

// 获取列表数据
listEmpAvgWagDetlApply() {
    const params = {
        rchkFlag: this.queryForm.rchkFlag,
        opterFitr: this.queryForm.opterFitr,
        empNo: this.queryForm.empNo ? this.queryForm.empNo.empNo : '',
        optBeginTime: Array.isArray(this.queryForm.date) ? this.queryForm.date[0] : '',
        optEndTime: Array.isArray(this.queryForm.date) ? this.queryForm.date[1] : '',
        pageSize: this.paginationQuery.pageSize,
        pageNum: this.paginationQuery.pageNum
    }
    this.loading = true
    listEmpAvgWagDetlApply(params).then(res => {
        this.tableData = res.data.data
        this.setPaginationQuery(res.data)
        this.loading = false
    }).catch(() => {
        this.loading = false
    })
}

表格里面自定义插槽

<template slot="handleStatus" slot-scope="scope">
    <StateTag :title="scope.row.rchkFlagName" :tag-type="scope.row.rchkFlag | filtersStatus" />
</template>

{ label: '审核状态', prop: 'rchkFlagName', type: 'custom', slotName: 'handleStatus' },

<template slot="rchkFlag" slot-scope="scope">
    <state-tag v-if="scope.row.rchkFlag === '0'" :title="scope.row.rchkFlagName" tag-type="nostart" />
    <state-tag v-if="scope.row.rchkFlag === '1'" :title="scope.row.rchkFlagName" tag-type="pass" />
    <state-tag v-if="scope.row.rchkFlag === '2'" :title="scope.row.rchkFlagName" tag-type="nopass" />
</template>

弹窗详情接收数据监听

props: {
    isDialogVisible: {
        type: Boolean,
      default: false
    }
},
watch: {
    isDialogVisible: function(val) {
        if (val) {
            this.getDetails()
        }
    }
},

区保医划处理

  { label: '医保区划', prop: 'admdvs', type: 'component', componentName: 'MedicalArea', folder: 'Common', fn: (v) => {
          this.queryForm.admdvs = getArrayLast(v)
        } },

引入pageSize

import { PAGE_SIZE } from '@/utils/constant'

下拉选择框条件判断处理

itemsDatas: [
    { label: '台账类型', prop: 'ledType', type: 'codeTable', codeKey: 'LED_TYPE', events: { change: this.selLedType }, clearable: false },
    {
        label: '单位信息', prop: 'empInfo', type: 'component', componentName: 'EmpInfo', folder: 'Common', hidden: false, fn: (v) => {
            console.log(v)
        }
    }
],

// 切换台账类型的回调
selLedType(v) {
    switch (v) {
        case '1':
            this.itemsDatas[1] = {
                label: '单位信息',
                prop: 'objCodg',
                type: 'component',
                componentName: 'EmpInfo',
                folder: 'Common',
                fn: (v) => {
                    this.queryForm.objCodg = v.empNo
                }
            }
            break
        case '2':
            this.itemsDatas[1] = {
                label: '人员信息',
                prop: 'objCodg',
                type: 'component',
                componentName: 'Personal',
                folder: 'Common',
                fn: (v) => {
                    this.queryForm.objCodg = v.psnNo
                }
            }
            break
        case '3':
            this.itemsDatas[1] = {
                label: '医疗机构',
                prop: 'objCodg',
                type: 'component',
                componentName: 'MedicalInstitutionsSelect/index',
                folder: 'Common',
                fn: (v) => {
                    this.queryForm.objCodg = v
                }
            }
            break
        case '4':
            this.itemsDatas[1] = {
                label: '药店信息',
                prop: 'objCodg',
                type: 'component',
                componentName: 'DrugstoreSelect/index',
                folder: 'Common',
                fn: (v) => {
                    this.queryForm.objCodg = v
                }
            }
            break
    }
}

码值过滤

filterFn:(v)=>{ return v.filter(item.dispVal.indexOf('住院')>-1)}

export const items = [
  {
    label: '人员类别',
    prop: 'psnide',
    span: 8,
    type: 'codeTable',
    codeKey: 'INSU_IDET_TYPE',
    filterFn: (v) => { return v.filter(item => item.dispVal.indexOf('在职人员') > -1) },
    filterable: true,
    options: []
  }
]

重置表单

:model="queryForm"
ref="queryForm"

resetForm() {
    this.reset()
    this.$refs.queryForm.elForm.resetFields()
},

一次性引入

import * as Api from '@/api/PaymentInAdvance/PaymentInAdvanceManage/Request'

经办日期处理

import { ACP_DATATYPE, CURRENT_DAY, CURRENT_MONTH_FIRST } from '@/utils/constant'
dateRange: [
  moment().startOf('month').format('YYYY-MM-DD'),
  moment().endOf('month').format('YYYY-MM-DD')
]      
sendDate: [CURRENT_MONTH_FIRST, CURRENT_DAY],
     
optTimeBegn: Array.isArray(this.queryForm.sendDate) ? this.queryForm.sendDate[0] : '',
optTimeEnd: Array.isArray(this.queryForm.sendDate) ? this.queryForm.sendDate[1] : '',

码值过滤

{ label: '业务办理情形', prop: 'bizStas', type: 'codeTable', codeKey: 'PH_BIZ_STAS', options: [], filterFn: (v) => {
    return v.filter(item => ['-1', '0', '2'].includes(item.dataVal) === true)
}     

监听码值变化,切换

 queryForm: {
        personInfo: {},
        name: '',
        certno: '',
        empNo: '',
        empName: '',
        acpType: ACP_DATATYPE,
        dateRange: [
          moment().startOf('month').format('YYYY-MM'),
          moment().endOf('month').format('YYYY-MM')
        ],
        sendDate: [CURRENT_MONTH_FIRST, CURRENT_DAY]
},
acpType: '0',

  watch: {
    queryForm: {
      handler: function(newVal) {
        if (newVal.personInfo) {
          this.queryForm.psnNo = newVal.personInfo.psnNo
          this.queryForm.certno = newVal.personInfo.certno
          this.queryForm.name = newVal.personInfo.psnName
          this.queryForm.empNo = newVal.personInfo.empNo
        }
        this.acpType = newVal.acpType
        if (this.acpType) {
          this.changeAcpType(this.acpType)
        }
      },
      deep: true
    }
  },


changeAcpType(v) {
      if (v === '0') {
        this.itemsDatas.forEach(item => {
          if (item.prop === 'empNo' || item.prop === 'empName') {
            this.$set(item, 'hidden', true)
          }
          if (item.prop === 'certno' || item.prop === 'name') {
            this.$set(item, 'hidden', false)
          }
        })
      } else {
        this.itemsDatas.forEach(item => {
          if (item.prop === 'empNo' || item.prop === 'empName') {
            this.$set(item, 'hidden', false)
          }
          if (item.prop === 'certno' || item.prop === 'name') {
            this.$set(item, 'hidden', true)
          }
        })
      }
    },

校验

rules: {
  insutype: { required: true, message: '请选择险种', trigger: 'change' }
},
ref="queryForm" :model="queryForm" :rules="rules"

this.$refs.queryForm.elForm.validate((valid) => {
   if (valid) {
      this.getList()
    } else {
      return false
    }
})

手机号校验

conerMob: [{ required: true, message: '请输入正确的手机号', validator: validator, regexp: 'phone', trigger: 'blur' }]
import validator from '@/utils/el-validator'

表格常用操作图标

注意: type和icon二选一,不能混合使用

type:
蓝色按钮类型: search 查询, submit 提交,save 保存,import 导入, export 导出,print 打印 , sure 确定,audit 审核(初审), batchAudit 批量审核以及其他 other
绿色按钮类型: add 新增(新增,添加,新建)
黄色按钮类型: edit 修改,review 复审
红色按钮类型: delete 删除, batchDelete 批量删除,cancel 取消,disable 禁用
白色按钮类型: reset 重置, close 关闭, back 返回,以及默认白色

icon: 这种基本用于表格操作里面的图标按钮
edit 修改,
maintenance 维护, 
detail 详情,
audit 审核, 
review 复审, 
cancelAudit 取消审核, 
delete 删除,
print 打印,
export 导出
cancel 取消,
stop 停止,
upload 上传, 
calculate 计算, 
check 核查, 
replace 替换 
save 保存, 
submit 提交, 
exit 退出
accept 受理, 
historicalRecord 历史记录, 
adjust 调整, 
send 发起/发送, 
invitation 邀请函, 
supplement 补充材料
personnel 人员

具体使用:
operationTypeArr: [
  { type: 'search', title: '查询', eleType: 'primary' },
  { type: 'submit', title: '提交', eleType: 'primary' },
  { type: 'save', title: '保存', eleType: 'primary' },
  { type: 'import', title: '导入', eleType: 'primary' },
  { type: 'export', title: '导出', eleType: 'primary' },
  { type: 'sure', title: '确定', eleType: 'primary' },
  { type: 'audit', title: '审核', eleType: 'primary' },
  { type: 'batchAudit', title: '批量审核', eleType: 'primary' },
  { type: 'other', title: '其他', eleType: 'primary' },
  { type: 'add', title: '新增', eleType: 'success' },
  { type: 'edit', title: '修改', eleType: 'warning' },
  { type: 'review', title: '复审', eleType: 'warning' },
  { type: 'delete', title: '删除', eleType: 'danger' },
  { type: 'batchDelete', title: '批量删除', eleType: 'danger' },
  { type: 'cancel', title: '取消', eleType: 'danger' },
  { type: 'disable', title: '禁用', eleType: 'danger' },
  { type: 'print', title: '打印', eleType: 'primary' },
  { type: 'reset', title: '重置', eleType: '' },
  { type: 'close', title: '关闭', eleType: '' },
  { type: 'back', title: '返回', eleType: '' }
],
iconArr: [
  { icon: 'edit', title: '修改', iconSvg: 'el-icon-edit', isFontSize: true, eleType: 'warning' },
  { icon: 'delete', title: '删除', iconSvg: 'el-icon-delete', isFontSize: true, eleType: 'danger' },
  { icon: 'detail', title: '详情', iconSvg: 'el-icon-view', isFontSize: true, eleType: 'primary' },
  { icon: 'upload', title: '上传', iconSvg: 'el-icon-upload2', isFontSize: true, eleType: 'success' },
  { icon: 'preview', title: '预览', iconSvg: 'el-icon-view', isFontSize: true, eleType: 'primary' },
  { icon: 'lookover', title: '查看', iconSvg: 'el-icon-view', isFontSize: true, eleType: 'primary' },
  { icon: 'setting', title: '设置', iconSvg: 'el-icon-setting', isFontSize: true, eleType: 'warning' },
  { icon: 'config', title: '配置', iconSvg: 'el-icon-setting', isFontSize: true, eleType: 'warning' },
  { icon: 'sure', title: '确认', iconSvg: 'el-icon-check', isFontSize: true, eleType: 'success' },

  { icon: 'save', title: '保存', iconSvg: 'save', eleType: 'primary' },
  { icon: 'submit', title: '提交', iconSvg: 'submit', eleType: 'primary' },
  { icon: 'maintenance', title: '维护', iconSvg: 'maintenance', eleType: 'warning' },
  { icon: 'audit', title: '审核', iconSvg: 'aduit', eleType: 'primary' },
  { icon: 'review', title: '复审', iconSvg: 'aduit', eleType: 'warning' },
  { icon: 'cancelAudit', title: '取消审核', iconSvg: 'cancelAduit', eleType: 'danger' },
  { icon: 'print', title: '打印', iconSvg: 'el-icon-printer', isFontSize: true, eleType: 'primary' },
  { icon: 'export', title: '导出', iconSvg: 'el-icon-download', isFontSize: true, eleType: 'primary' },
  { icon: 'cancel', title: '取消', iconSvg: 'cancel', eleType: 'danger' },
  { icon: 'stop', title: '停止', iconSvg: 'stop', eleType: 'danger' },
  { icon: 'calculate', title: '计算', iconSvg: 'count', eleType: 'primary' },
  { icon: 'recall', title: '撤回', iconSvg: 'recall', eleType: 'danger' },
  { icon: 'exit', title: '退出', iconSvg: 'exit', eleType: 'danger' },
  { icon: 'check', title: '核查', iconSvg: 'check', eleType: 'warning' },
  { icon: 'replace', title: '替换', iconSvg: 'replace', eleType: 'warning' },
  { icon: 'analysis', title: '分析', iconSvg: 'analysis', eleType: 'warning' },
  { icon: 'apply', title: '申请', iconSvg: 'apply', eleType: 'primary' },
  { icon: 'duizhang', title: '对账', iconSvg: 'duizhang', eleType: 'primary' },
  { icon: 'accept', title: '受理', iconSvg: 'accept', eleType: 'primary' },
  { icon: 'historicalRecord', title: '历史记录', iconSvg: 'historicalRecord', eleType: 'primary' },
  { icon: 'adjust', title: '调整', iconSvg: 'adjust', eleType: 'warning' },
  { icon: 'send', title: '发起/发送', iconSvg: 'send', eleType: 'primary' },
  { icon: 'invitation', title: '邀请函', iconSvg: 'invitation', eleType: 'primary' },
  { icon: 'supplement', title: '补充材料', iconSvg: 'supplement', eleType: 'primary' },
  { icon: 'personnel', title: '人员', iconSvg: 'personnel', eleType: 'primary' }
]

监听码值变化,切换

 queryForm: {
        personInfo: {},
        name: '',
        certno: '',
        empNo: '',
        empName: '',
        acpType: ACP_DATATYPE,
        dateRange: [
          moment().startOf('month').format('YYYY-MM'),
          moment().endOf('month').format('YYYY-MM')
        ],
        sendDate: [CURRENT_MONTH_FIRST, CURRENT_DAY]
},
acpType: '0',

  watch: {
    queryForm: {
      handler: function(newVal) {
        if (newVal.personInfo) {
          this.queryForm.psnNo = newVal.personInfo.psnNo
          this.queryForm.certno = newVal.personInfo.certno
          this.queryForm.name = newVal.personInfo.psnName
          this.queryForm.empNo = newVal.personInfo.empNo
        }
        this.acpType = newVal.acpType
        if (this.acpType) {
          this.changeAcpType(this.acpType)
        }
      },
      deep: true
    }
  },


changeAcpType(v) {
      if (v === '0') {
        this.itemsDatas.forEach(item => {
          if (item.prop === 'empNo' || item.prop === 'empName') {
            this.$set(item, 'hidden', true)
          }
          if (item.prop === 'certno' || item.prop === 'name') {
            this.$set(item, 'hidden', false)
          }
        })
      } else {
        this.itemsDatas.forEach(item => {
          if (item.prop === 'empNo' || item.prop === 'empName') {
            this.$set(item, 'hidden', false)
          }
          if (item.prop === 'certno' || item.prop === 'name') {
            this.$set(item, 'hidden', true)
          }
        })
      }
    },

校验

rules: {
  insutype: { required: true, message: '请选择险种', trigger: 'change' }
},
ref="queryForm" :model="queryForm" :rules="rules"

this.$refs.queryForm.elForm.validate((valid) => {
   if (valid) {
      this.getList()
    } else {
      return false
    }
})

手机号校验

conerMob: [{ required: true, message: '请输入正确的手机号', validator: validator, regexp: 'phone', trigger: 'blur' }]
import validator from '@/utils/el-validator'

表格常用操作图标

注意: type和icon二选一,不能混合使用

type:
蓝色按钮类型: search 查询, submit 提交,save 保存,import 导入, export 导出,print 打印 , sure 确定,audit 审核(初审), batchAudit 批量审核以及其他 other
绿色按钮类型: add 新增(新增,添加,新建)
黄色按钮类型: edit 修改,review 复审
红色按钮类型: delete 删除, batchDelete 批量删除,cancel 取消,disable 禁用
白色按钮类型: reset 重置, close 关闭, back 返回,以及默认白色

icon: 这种基本用于表格操作里面的图标按钮
edit 修改,
maintenance 维护, 
detail 详情,
audit 审核, 
review 复审, 
cancelAudit 取消审核, 
delete 删除,
print 打印,
export 导出
cancel 取消,
stop 停止,
upload 上传, 
calculate 计算, 
check 核查, 
replace 替换 
save 保存, 
submit 提交, 
exit 退出
accept 受理, 
historicalRecord 历史记录, 
adjust 调整, 
send 发起/发送, 
invitation 邀请函, 
supplement 补充材料
personnel 人员

具体使用:
operationTypeArr: [
  { type: 'search', title: '查询', eleType: 'primary' },
  { type: 'submit', title: '提交', eleType: 'primary' },
  { type: 'save', title: '保存', eleType: 'primary' },
  { type: 'import', title: '导入', eleType: 'primary' },
  { type: 'export', title: '导出', eleType: 'primary' },
  { type: 'sure', title: '确定', eleType: 'primary' },
  { type: 'audit', title: '审核', eleType: 'primary' },
  { type: 'batchAudit', title: '批量审核', eleType: 'primary' },
  { type: 'other', title: '其他', eleType: 'primary' },
  { type: 'add', title: '新增', eleType: 'success' },
  { type: 'edit', title: '修改', eleType: 'warning' },
  { type: 'review', title: '复审', eleType: 'warning' },
  { type: 'delete', title: '删除', eleType: 'danger' },
  { type: 'batchDelete', title: '批量删除', eleType: 'danger' },
  { type: 'cancel', title: '取消', eleType: 'danger' },
  { type: 'disable', title: '禁用', eleType: 'danger' },
  { type: 'print', title: '打印', eleType: 'primary' },
  { type: 'reset', title: '重置', eleType: '' },
  { type: 'close', title: '关闭', eleType: '' },
  { type: 'back', title: '返回', eleType: '' }
],
iconArr: [
  { icon: 'edit', title: '修改', iconSvg: 'el-icon-edit', isFontSize: true, eleType: 'warning' },
  { icon: 'delete', title: '删除', iconSvg: 'el-icon-delete', isFontSize: true, eleType: 'danger' },
  { icon: 'detail', title: '详情', iconSvg: 'el-icon-view', isFontSize: true, eleType: 'primary' },
  { icon: 'upload', title: '上传', iconSvg: 'el-icon-upload2', isFontSize: true, eleType: 'success' },
  { icon: 'preview', title: '预览', iconSvg: 'el-icon-view', isFontSize: true, eleType: 'primary' },
  { icon: 'lookover', title: '查看', iconSvg: 'el-icon-view', isFontSize: true, eleType: 'primary' },
  { icon: 'setting', title: '设置', iconSvg: 'el-icon-setting', isFontSize: true, eleType: 'warning' },
  { icon: 'config', title: '配置', iconSvg: 'el-icon-setting', isFontSize: true, eleType: 'warning' },
  { icon: 'sure', title: '确认', iconSvg: 'el-icon-check', isFontSize: true, eleType: 'success' },

  { icon: 'save', title: '保存', iconSvg: 'save', eleType: 'primary' },
  { icon: 'submit', title: '提交', iconSvg: 'submit', eleType: 'primary' },
  { icon: 'maintenance', title: '维护', iconSvg: 'maintenance', eleType: 'warning' },
  { icon: 'audit', title: '审核', iconSvg: 'aduit', eleType: 'primary' },
  { icon: 'review', title: '复审', iconSvg: 'aduit', eleType: 'warning' },
  { icon: 'cancelAudit', title: '取消审核', iconSvg: 'cancelAduit', eleType: 'danger' },
  { icon: 'print', title: '打印', iconSvg: 'el-icon-printer', isFontSize: true, eleType: 'primary' },
  { icon: 'export', title: '导出', iconSvg: 'el-icon-download', isFontSize: true, eleType: 'primary' },
  { icon: 'cancel', title: '取消', iconSvg: 'cancel', eleType: 'danger' },
  { icon: 'stop', title: '停止', iconSvg: 'stop', eleType: 'danger' },
  { icon: 'calculate', title: '计算', iconSvg: 'count', eleType: 'primary' },
  { icon: 'recall', title: '撤回', iconSvg: 'recall', eleType: 'danger' },
  { icon: 'exit', title: '退出', iconSvg: 'exit', eleType: 'danger' },
  { icon: 'check', title: '核查', iconSvg: 'check', eleType: 'warning' },
  { icon: 'replace', title: '替换', iconSvg: 'replace', eleType: 'warning' },
  { icon: 'analysis', title: '分析', iconSvg: 'analysis', eleType: 'warning' },
  { icon: 'apply', title: '申请', iconSvg: 'apply', eleType: 'primary' },
  { icon: 'duizhang', title: '对账', iconSvg: 'duizhang', eleType: 'primary' },
  { icon: 'accept', title: '受理', iconSvg: 'accept', eleType: 'primary' },
  { icon: 'historicalRecord', title: '历史记录', iconSvg: 'historicalRecord', eleType: 'primary' },
  { icon: 'adjust', title: '调整', iconSvg: 'adjust', eleType: 'warning' },
  { icon: 'send', title: '发起/发送', iconSvg: 'send', eleType: 'primary' },
  { icon: 'invitation', title: '邀请函', iconSvg: 'invitation', eleType: 'primary' },
  { icon: 'supplement', title: '补充材料', iconSvg: 'supplement', eleType: 'primary' },
  { icon: 'personnel', title: '人员', iconSvg: 'personnel', eleType: 'primary' }
]

日期选择器时,默认显示当天日期

<el-form-item label="交易数据">
            <el-date-picker
              type="date"
              placeholder="选择日期"
              v-model="searchFormField.date"
              style="width: 100%;"
              value-format="yyyy-MM-dd"
            ></el-date-picker>
</el-form-item>
        
     
 methods: {
    getNowTime() {
       var now = new Date();
       var year = now.getFullYear(); //得到年份
       var month = now.getMonth(); //得到月份
       var date = now.getDate(); //得到日期
       month = month + 1;
       month = month.toString().padStart(2, "0");
       date = date.toString().padStart(2, "0");
       var defaultDate = `${year}-${month}-${date}`;
       this.$set(this.searchFormField, "date", defaultDate);
   },
 }

状态为tag标签

<template slot="valiFlagName" slot-scope="scope">
        <State-tag :tag-type="scope.row.valiFlagName === '有效'? 'pass' : 'nopass'" :title="scope.row.valiFlagName" />
</template>

{
  label: '有效标志',
  prop: 'valiFlagName',
  align: 'center',
  type: 'custom',
  slotName: 'valiFlagName',
},

文件预览

import PreviewImage from '@/components/Preview'
<PreviewImage
      ref="ImgPreview"
      :viewer-visible.sync="viewerVisible"
      :img-data-list.sync="imgDataList"
      :img-index.sync="imgIndex"
/>

viewerVisible: false,
imgDataList: [],
imgIndex: 0,

 // 预览
showUploadPreview(data) {
      // this.isInnerVisible = true
      // this.currentPreview = data
 this.imgDataList = [{ title: data.filename, url: data.filePath, id: data.fileId }]
 this.viewerVisible = true
}

解决弹窗高度滚动条问题

/deep/.pf-table {
  min-height: 430px;
  /deep/.el-table {
    min-height: 430px !important;
  }
}

>>>.el-table--small th, >>>.el-table--small td {
    padding: 7px 0;
}
>>>.el-table thead th .cell {
    height: 32px;
    line-height: 32px;
}

弹窗关闭与打开

<EditDialog
:dialog-title="dialogTitle"
:administrative-domain-form="administrativeDomainForm"
:is-dialog-visible="isDialogVisible"
@saveAddministrativeDomain="saveAddministrativeDomain"
@update:isShow="isShow"
@search="search"
/>

isDialogVisible: false,

this.isDialogVisible = true


isShow(v) {
  this.isDialogVisible = v
},
//子组件
 <form-dialog size="middle" :title="dialogTitle" :is-show="isDialogVisible" @update:isShow="isShow" @resetForm="resetForm">

props: {
    isDialogVisible: {
      type: Boolean,
      default: false
    },
}
isShow(v) {
   this.$emit('update:isShow', v)
},
closeDialog() {
   this.$emit('update:isShow', false)
},

<el-button @click="closeDialog()">取消</el-button>

正则图片校验

isImage(str) {
      var reg = /\.(png|jpg|gif|jpeg|webp)$/
      return reg.test(str)
    },

文件下载

/* 文件下载处理 */
export function funDownload(href, filename) {
  var a = document.createElement('a')
  var e = document.createEvent('MouseEvents')
  e.initEvent('click', false, false)
  a.href = href
  a.download = filename
  a.dispatchEvent(e)
}

限制input框只能输入整数

onkeyup="this.value = this.value.replace(/[^\d.]/g,'');"

校验是否为正整数

1.首先在vue文件的methods()中添加校验方法,这里校验方法命名为isNumber用自带的.test方法进行正则校验

 methods: {
   isNumber(rule, value, callback) {
      if (value === '') {
        return callback();
      }  //这是用来判断如果不是必须输入的,则直接跳出
      const r = /^\+?[1-9][0-9]*$/; // 正整数
      // 如果判断不符合正则,则不是正整数不能提交
      if (!r.test(value)) {
        return callback(new Error('数量必须为正整数'));
      } else {
        return callback();
      }
    },
}

2.在data()中定义的rules里使用校验规则
rules: {
  size: [{ validator: this.isNumber, trigger: 'blur' }],
},

vue打包war

cnpm install --save folder-zip-sync

"build:war": "npm run build:prod && node ./build/war.js",

添加war.js

Cascader 级联选择器清除选中

<el-cascader
    v-model="value"
    :options="options"
    ref="cascader">
</el-cascader>

// 清空级联选择器选中状态
this.$refs.cascader.$refs.panel.clearCheckedNodes()
// 清除高亮
this.$refs.cascader.$refs.panel.activePath = []

重置表格选中状态


clearSelection() {
  this.$refs['pf-table'].clearSelection() // 清除多选
}
ref="multipleTable"

this.$refs.multipleTable.clearSelection()

病案首页处理

import Modal from '@/views/expert-review-sys/components/Medical/modal'

//modal.vue
<el-row :gutter="10">
      <el-col :span="isFold && !isFold2 ?24:10" style="height: 100%">
      
<Group-plan v-bind="this.$attrs" @handle-fold="handleFold" />
      
<transition name="fade" model="out-in">
    <el-col v-if="!isFold" :span="!isFold && isFold2 ?24:14">
      <Details v-bind="this.$attrs" @handle-fold2="handleFold2" />
    </el-col>
</transition>

isFold: false,
isFold2: false

handleFold(v) {
  this.isFold = v
},
handleFold2(v) {
  this.isFold2 = v
}

//detailsRight.vue
<section class="layer pf-item" :class="isFold2?'audiut-box':''">

<div class="audiut-boxs" style="height: 100%;width: 100%;padding: 0 15px;">
      <div class="box-header handle">
        <span class="box-title box-title1">信息评审项</span>
        <div class="box-tools">
          <i class="fold" :class="isFold2?'el-icon-s-unfold':'el-icon-s-fold'" :title="isFold2?'折叠':'展开'" @click="foldClick" />
        </div>
      </div>
isFold2: false,

foldClick() {
  this.isFold2 = !this.isFold2
  this.$emit('handle-fold2', this.isFold2)
}

//baxq.vue
<i :class="isFold?'el-icon-s-fold folded':'el-icon-s-unfold fold'" :title="isFold?'折叠':'展开'" @click="foldClick" />
    <section class="layer" :class="isFold?'medical-homePage':''">

setDate(value) {
  if (value) {
    return moment(value).format('YYYY/MM/DD')
  } else {
    return ''
  }
}
return '\u3000\u3000\u3000\u3000\u3000\u3000'

import moment from 'moment'
isFold: false
 
foldClick() {
  this.isFold = !this.isFold
  this.$emit('handle-fold', this.isFold)
}
    

当前年份

(new Date()).getFullYear() + ''

区保医划

 <template slot="search-header">
      <form-items ref="form" :model="queryForm" :items-datas="itemsDatas" :form-datas="queryForm" :rules="rules">
        <my-button type="reset" title="重置" @click="resetForm" />
        <my-button type="search" title="查询" @click="search" />
      </form-items>
    </template>
    
itemsDatas: [
        {
          label: '医保区划',
          prop: 'admdvs',
          type: 'component',
          componentName: 'MedicalArea',
          folder: 'Common'
        },
        { label: '抽样日期', prop: 'datetimerange', type: 'dateRange' }
],

form-items中使用模板

<template slot="applFlagName" slot-scope="scope">
          <State-tag :tag-type="scope.row.applFlagName === '申诉'? 'pass' : 'nopass'" :title="scope.row.applFlagName" />
        </template>

分页处理

  this.table.total = res.data.pageInfo.recordCounts
            this.table.pageNum = res.data.pageInfo.pageNum
            this.table.pageSize = res.data.pageInfo.pageSize
            
            
            this.table1.total = res.data.recordCounts
            this.table1.startRow = res.data.startRow
            this.table1.endRow = res.data.endRow

原生分页处理

<el-pagination :current-page="table.pageNum" :page-sizes="[15, 30, 50, 100]" :page-size="table.pageSize" :total="table.total" layout="slot, sizes, prev, pager, next, jumper" @current-change="handleCurrentChange" @size-change="handleSizeChange">
            <template slot>
              <span class="el-pagination__total">{{ `总共${table.total}条 显示${table.startRow}-${table.endRow}条` }}</span>
            </template>
          </el-pagination>

table: {
        tableData: [],
        loading: false,
        pageNum: 1,
        pageSize: 15,
        total: 10,
        height: 555,
        startRow: 0,
        endRow: 0
      },
      
 handleCurrentChange(val) {
      this.table.pageNum = val
      this.getCmiKpiAnalysisList()
    },
    handleSizeChange(val) {
      this.table1.pageSize = val
      this.getCmiKpiAnalysisList()
    },


this.table.tableData = res.data.rows
            this.table.pageNum = res.data.pageInfo.pageNum
            this.table.pageSize = res.data.pageInfo.pageSize
            this.table.total = res.data.pageInfo.recordCounts
            this.table.startRow = res.data.pageInfo.startRow
            this.table.endRow = res.data.pageInfo.endRow
      
      

button颜色

>>>.el-table .el-button {
    color: #1B65B9;
    width: auto;
}

.el-table >>>.el-button {
    color: #1B65B9;
    width: auto;
}

医院名称组件

itemsDatas: [
        {
          label: '医保区划',
          prop: 'admdvs',
          type: 'component',
          componentName: 'MedicalArea',
          folder: 'Common'
        },
        {
          label: '医院名称',
          prop: 'medinsCodg',
          type: 'component',
          componentName: 'MedicalInstitutionsSelect/index',
          folder: 'Common',
          params: { bindType: 'name', fixFlag: '0', queCont: '1' }
        }
      ],


亿万过滤器

filters: {
        numberFormat: function (value) {
                   let unit = '';
                   var k = 10000,
                   sizes = ['', '万', '亿', '万亿'],
                   i;
                   if(value < k){
                       value =value;
                   }else{
                       i = Math.floor(Math.log(value) / Math.log(k));
                       value = ((value / Math.pow(k, i))).toFixed(2);
                       unit = sizes[i];
                   }
                   return value+unit;
             }
},

操作按钮

<my-button icon="detail" title="详情" @click="showDetail(scope.row)" />
        <my-button icon="delete" title="删除" @click="delRule(scope.row)" />

统计年度宽度

>>>.el-date-editor.el-input, >>>.el-date-editor.el-input__inner {
    width: 100%;
}

分页

this.paginationQuery.pageSize

自定义图标

<my-button title="退回" @click="giveUp(scope.row)">
    <svg-icon icon-class="back" class="backss" />
</my-button>

svg图标放在icons->svg文件夹下面

reset

reset() {
      this.$refs.form.elForm.resetFields()
},
 <el-tab-pane label="病案首页" name="first">
        <Group-plan :rew-task-detl="medcasInfo" />
      </el-tab-pane>
      <el-tab-pane label="出院小结" name="second">
        <Hospital :dscg-end="medcasInfo" />
      </el-tab-pane>
      <el-tab-pane label="检查报告" name="third" />
      <el-tab-pane label="细菌结果" name="fourth">
        <Bacteria :bacteria-rslt="medcasInfo" />
      </el-tab-pane>
      <el-tab-pane label="申诉信息" name="fifth">
        <GriInfo :appl-info="medcasInfo" />
      </el-tab-pane>
      <el-tab-pane label="长期医嘱单" name="sixth">
        <Orders :drord-records="medcasInfo" />
      </el-tab-pane>
      <el-tab-pane label="检验结果" name="seventh">
        <DschaSumma :test-rslt="medcasInfo" />
      </el-tab-pane>
无右边的

有右边的


<el-tab-pane label="病案首页" name="first">
          <Group-plan :rew-task-detl="rewTaskDetl" />
        </el-tab-pane>
        <el-tab-pane label="出院小结" name="second">
          <Hospital :dscg-end="rewTaskDetl" />
        </el-tab-pane>
        <el-tab-pane label="检查报告" name="third" />
        <el-tab-pane label="细菌结果" name="fourth">
          <Bacteria :bacteria-rslt="rewTaskDetl" />
        </el-tab-pane>
        <el-tab-pane label="申诉信息" name="fifth">
          <GriInfo :appl-info="rewTaskDetl" />
        </el-tab-pane>
        <el-tab-pane label="长期医嘱单" name="sixth">
          <Orders :drord-records="rewTaskDetl" />
        </el-tab-pane>
        <el-tab-pane label="检验结果" name="seventh">
          <DschaSumma :test-rslt="rewTaskDetl" />
        </el-tab-pane>

fixmedinsCode: rewTaskDetl.medinsCodg,
medcasno: rewTaskDetl.medcasno

展示错误内容

<el-dialog title="错误内容" :visible.sync="errorShow" :modal-append-to-body="true" :append-to-body="true" size="big">
      <section>
        <my-table-view :columns="errorColumns" :data="errorData" :is-configheader="false" />
      </section>
      <span slot="footer" class="dialog-footer">
        <my-button type="close" title="关闭" @click="errorShow = false" />
      </span>
    </el-dialog>


this.$msgWarning('部分费用信息保存失败!')
this.errorShow = true

this.errorShow = true
this.errorData = res.data.errorList

2020092901

默认时间处理

//月初到今天
/**
 * 获取本月第一天
 * @param {number} format
 */
export function getFirstDay(format) {
  if (format) {
    return parseTime((new Date()).setDate(1), format)
  } else {
    return parseTime((new Date()).setDate(1), '{y}-{m}-{d}')
  }
}

/**
 * 获取当前天
 * @param {string}
 */
export function getToday(format) {
  if (format) {
    return parseTime(new Date(), format)
  } else {
    return parseTime(new Date(), '{y}-{m}-{d}')
  }
}

import { getToday, getFirstDay } from '@/utils/index'

this.queryForm.queryDate = [getFirstDay(), getToday()]

state

const state = {
  bizParaValInfo: {
    isDiseSpdrug: false,
    isPrescription: false,
    isAddManually: false,
    isOpspDise: false,
    isOutPatient: false
  }
}

mutations

SET_BIZPARAVAL_INFO: (state, info) => {
    state.bizParaValInfo = info
}

actions

const actions = {
  setBizParaValInfo({ commit }, info) {
    commit('SET_BIZPARAVAL_INFO', info)
  }
}

getters

const getters = {
  bizParaValInfo: state => state.virtualSettlement.bizParaValInfo,
}
export default getters

触发状态管理

this.$store.dispatch('realSettlement/setBizParaValInfo', { ...data })

医保区划


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

推荐阅读更多精彩内容