mirror of
https://github.com/bufanyun/hotgo.git
synced 2026-04-24 20:14:29 +08:00
tt
This commit is contained in:
269
hotgo-web/src/utils/aidex.js
Normal file
269
hotgo-web/src/utils/aidex.js
Normal file
@@ -0,0 +1,269 @@
|
||||
import storage from 'store'
|
||||
import { ACCESS_TOKEN } from '@/store/mutation-types'
|
||||
|
||||
/**
|
||||
* 通用js方法封装处理
|
||||
* Copyright (c) 2019 aidex
|
||||
*/
|
||||
|
||||
const baseURL = process.env.VUE_APP_BASE_API
|
||||
|
||||
// 日期格式化
|
||||
export function parseTime (time, pattern) {
|
||||
if (arguments.length === 0 || !time) {
|
||||
return null
|
||||
}
|
||||
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
|
||||
let date
|
||||
if (typeof time === 'object') {
|
||||
date = time
|
||||
} else {
|
||||
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
|
||||
time = parseInt(time)
|
||||
} else if (typeof time === 'string') {
|
||||
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 timeStr = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
|
||||
let value = formatObj[key]
|
||||
// Note: getDay() returns 0 on Sunday
|
||||
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
|
||||
if (result.length > 0 && value < 10) {
|
||||
value = '0' + value
|
||||
}
|
||||
return value || 0
|
||||
})
|
||||
return timeStr
|
||||
}
|
||||
|
||||
// 表单重置
|
||||
export function resetForm (refName) {
|
||||
if (this[refName]) {
|
||||
this[refName].resetFields()
|
||||
}
|
||||
}
|
||||
|
||||
// 添加日期范围
|
||||
export function addDateRange (params, dateRange, propName) {
|
||||
var search = params
|
||||
// search.params = {}
|
||||
if (dateRange !== null && dateRange !== '' && dateRange.length === 2) {
|
||||
if (typeof (propName) === 'undefined') {
|
||||
search.start_time = dateRange[0]
|
||||
search.end_time = dateRange[1]
|
||||
} else {
|
||||
const startTime = propName + '_start_time'
|
||||
const endTime = propName + '_end_time'
|
||||
search[startTime] = dateRange[0]
|
||||
search[endTime] = dateRange[1]
|
||||
}
|
||||
}
|
||||
return search
|
||||
}
|
||||
|
||||
// 回显数据字典
|
||||
export function selectDictLabel (datas, value) {
|
||||
var actions = []
|
||||
Object.keys(datas).some((key) => {
|
||||
if (datas[key].value === ('' + value)) {
|
||||
actions.push(datas[key].label)
|
||||
return true
|
||||
}
|
||||
})
|
||||
return actions.join('')
|
||||
}
|
||||
|
||||
// 回显数据字典(字符串数组)
|
||||
export function selectDictLabels (datas, value, separator) {
|
||||
var actions = []
|
||||
var currentSeparator = undefined === separator ? ',' : separator
|
||||
var temp = value.split(currentSeparator)
|
||||
Object.keys(value.split(currentSeparator)).some((val) => {
|
||||
Object.keys(datas).some((key) => {
|
||||
if (datas[key].value === ('' + temp[val])) {
|
||||
actions.push(datas[key].label + currentSeparator)
|
||||
}
|
||||
})
|
||||
})
|
||||
return actions.join('').substring(0, actions.join('').length - 1)
|
||||
}
|
||||
|
||||
// 通用导出下载
|
||||
export function exportDownload(path, params) {
|
||||
let url = baseURL + path + '?'
|
||||
params.authorization = storage.get(ACCESS_TOKEN)
|
||||
for (const propName of Object.keys(params)) {
|
||||
const value = params[propName]
|
||||
var part = encodeURIComponent(propName) + '='
|
||||
// 修改漏洞
|
||||
if (value != null && typeof (value) !== 'undefined') {
|
||||
if (typeof value === 'object') {
|
||||
for (const key of Object.keys(value)) {
|
||||
const params = propName + '[' + key + ']'
|
||||
var subPart = encodeURIComponent(params) + '='
|
||||
url += subPart + encodeURIComponent(value[key]) + '&'
|
||||
}
|
||||
} else {
|
||||
url += part + encodeURIComponent(value) + '&'
|
||||
}
|
||||
}
|
||||
}
|
||||
url = url.slice(0, -1)
|
||||
window.location.href = url
|
||||
}
|
||||
|
||||
// 通用下载方法
|
||||
export function download (fileName, delFlag) {
|
||||
if (delFlag === undefined) {
|
||||
delFlag = true
|
||||
}
|
||||
window.location.href = baseURL + '/common/download?fileName=' + encodeURI(fileName) + '&delete=' + delFlag
|
||||
}
|
||||
// 通用下载方法
|
||||
export function downloadByPath (filePath, delFlag) {
|
||||
if (delFlag === undefined) {
|
||||
delFlag = true
|
||||
}
|
||||
window.location.href = baseURL + '/common/downloadByPath?filePath=' + encodeURI(filePath) + '&delete=' + delFlag
|
||||
}
|
||||
// 通用下载到导出任务中心
|
||||
export function downloadTask () {
|
||||
this.$router.push({
|
||||
name: 'SysDownloadFiles',
|
||||
params: {
|
||||
key: new Date().toLocaleString()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 字符串格式化(%s )
|
||||
export function sprintf (str) {
|
||||
var args = arguments
|
||||
var flag = true
|
||||
var i = 1
|
||||
str = str.replace(/%s/g, function () {
|
||||
var arg = args[i++]
|
||||
if (typeof arg === 'undefined') {
|
||||
flag = false
|
||||
return ''
|
||||
}
|
||||
return arg
|
||||
})
|
||||
return flag ? str : ''
|
||||
}
|
||||
|
||||
// 转换字符串,undefined,null等转化为''
|
||||
export function praseStrEmpty (str) {
|
||||
if (!str || str === 'undefined' || str === 'null') {
|
||||
return ''
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造树型结构数据
|
||||
* @param {*} data 数据源
|
||||
* @param {*} id id字段 默认 'id'
|
||||
* @param {*} parentId 父节点字段 默认 'parentId'
|
||||
* @param {*} children 孩子节点字段 默认 'children'
|
||||
* @param {*} rootId 根Id 默认 0
|
||||
*/
|
||||
export function handleTree (data, id, parentId, children, rootId) {
|
||||
id = id || 'id'
|
||||
parentId = parentId || 'parentId'
|
||||
children = children || 'children'
|
||||
rootId = rootId || '0'
|
||||
// 对源数据深度克隆
|
||||
const cloneData = JSON.parse(JSON.stringify(data))
|
||||
// 循环所有项
|
||||
const treeData = cloneData.filter(father => {
|
||||
var branchArr = cloneData.filter(child => {
|
||||
// 返回每一项的子级数组
|
||||
return father[id] === child[parentId]
|
||||
})
|
||||
|
||||
if (branchArr.length > 0) {
|
||||
father.children = branchArr
|
||||
} else {
|
||||
father.children = ''
|
||||
}
|
||||
// 返回第一层
|
||||
return father[parentId] === rootId
|
||||
})
|
||||
return treeData !== '' && treeData == null ? treeData : data
|
||||
}
|
||||
/**
|
||||
* 从树中移除指定节点
|
||||
* @param {Object} list
|
||||
* @param {Object} node
|
||||
*/
|
||||
export function removeTreeNode (list, node) {
|
||||
console.log('node:' + JSON.stringify(node))
|
||||
const parentList = list
|
||||
// const parentIds = node.pid.split('/')
|
||||
const parentIds = node.pid
|
||||
const currentNodeId = node.id
|
||||
deleteTreeNode(parentList, list, parentIds, currentNodeId)
|
||||
}
|
||||
export function deleteTreeNode (parentList, list, parentIds, currentNodeId) {
|
||||
for (let s = 0; s < list.length; s++) {
|
||||
if (list[s].id === currentNodeId) {
|
||||
list.splice(s, 1)
|
||||
return
|
||||
} else if (list[s].children && list[s].children.length > 0) { // 递归条件
|
||||
// parentIds.splice(0, 1)
|
||||
deleteTreeNode(list[s], list[s].children, parentIds, currentNodeId)
|
||||
} else {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
export function appendTreeNode (node, data) {
|
||||
// if (node.treeLeaf === 'y') {
|
||||
// // 如果节点是叶子节点则直接改为非叶子节点
|
||||
// node.treeLeaf = 'n'
|
||||
// node.children.push(data)
|
||||
// } else {
|
||||
// const children = node.children
|
||||
// if (children.length > 0) {
|
||||
// // 有子节点则直接push数据,否则不做操作等待异步加载
|
||||
// node.children.push(data)
|
||||
// }
|
||||
// }
|
||||
// console.log('node,' + JSON.stringify(node))
|
||||
// console.log('data,' + JSON.stringify(data))
|
||||
const children = node.children
|
||||
if (children.length > 0) {
|
||||
// 有子节点则直接push数据,否则不做操作等待异步加载
|
||||
node.children.push(data)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 按展开几层展开树
|
||||
* @param {Object} nodes
|
||||
* @param {Object} expandLevel
|
||||
* @param {Object} expandedRowKeys 记录展开key
|
||||
*/
|
||||
export function expandTree (nodes, expandLevel, expandedRowKeys) {
|
||||
if (expandLevel > 1) {
|
||||
// 最后一层不展开
|
||||
nodes.forEach(node => {
|
||||
expandedRowKeys.push(node.id)
|
||||
expandLevel = expandLevel - 1
|
||||
return expandTree(node.children, expandLevel, expandedRowKeys)
|
||||
})
|
||||
}
|
||||
}
|
||||
35
hotgo-web/src/utils/axios.js
Normal file
35
hotgo-web/src/utils/axios.js
Normal file
@@ -0,0 +1,35 @@
|
||||
const VueAxios = {
|
||||
vm: {},
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
install (Vue, instance) {
|
||||
if (this.installed) {
|
||||
return
|
||||
}
|
||||
this.installed = true
|
||||
|
||||
if (!instance) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('You have to install axios')
|
||||
return
|
||||
}
|
||||
|
||||
Vue.axios = instance
|
||||
|
||||
Object.defineProperties(Vue.prototype, {
|
||||
axios: {
|
||||
get: function get () {
|
||||
return instance
|
||||
}
|
||||
},
|
||||
$http: {
|
||||
get: function get () {
|
||||
return instance
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
VueAxios
|
||||
}
|
||||
21
hotgo-web/src/utils/domUtil.js
Normal file
21
hotgo-web/src/utils/domUtil.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import config from '@/config/defaultSettings'
|
||||
|
||||
export const setDocumentTitle = function (title) {
|
||||
document.title = title
|
||||
const ua = navigator.userAgent
|
||||
// eslint-disable-next-line
|
||||
const regex = /\bMicroMessenger\/([\d\.]+)/
|
||||
if (regex.test(ua) && /ip(hone|od|ad)/i.test(ua)) {
|
||||
const i = document.createElement('iframe')
|
||||
i.src = '/favicon.ico'
|
||||
i.style.display = 'none'
|
||||
i.onload = function () {
|
||||
setTimeout(function () {
|
||||
i.remove()
|
||||
}, 9)
|
||||
}
|
||||
document.body.appendChild(i)
|
||||
}
|
||||
}
|
||||
|
||||
export const domTitle = config.title
|
||||
95
hotgo-web/src/utils/drag.js
Normal file
95
hotgo-web/src/utils/drag.js
Normal file
@@ -0,0 +1,95 @@
|
||||
const draggable = {
|
||||
install (Vue) {
|
||||
Vue.directive('drag', {
|
||||
inserted (el, binding) {
|
||||
if (window.Element && !Element.prototype.closest) {
|
||||
Element.prototype.closest = function (s) {
|
||||
const matches = (this.document || this.ownerDocument).querySelectorAll(s)
|
||||
let i
|
||||
let el = this
|
||||
do {
|
||||
i = matches.length
|
||||
} while (i < 0 && (el = el.parentElement))
|
||||
return el
|
||||
}
|
||||
}
|
||||
let overWin = false // 拖动是否能超出屏幕,默认不能
|
||||
if (binding.value) {
|
||||
overWin = binding.value.over || false
|
||||
}
|
||||
|
||||
const moveTitle = el.parentNode.parentNode.parentNode.querySelector('.ant-modal-header')
|
||||
|
||||
el.style.width = '100%'
|
||||
el.style.height = moveTitle.offsetHeight + 'px'
|
||||
el.style.position = 'absolute'
|
||||
el.style.left = 0
|
||||
el.style.top = 0
|
||||
el.style.cursor = 'move'
|
||||
|
||||
const odiv = el // 获取当前元素操作区
|
||||
const moveDom = el.closest('.ant-modal') // 位移元素,当前只对a-modal生效
|
||||
|
||||
odiv.onmousedown = e => {
|
||||
const moveDomLeft = moveDom.offsetLeft // 位移元素初始横轴位置
|
||||
const moveDomTop = moveDom.offsetTop // 位移元素初始纵轴位置
|
||||
const moveDomW = moveDom.offsetWidth // 位移元素初始宽
|
||||
const moveDomH = moveDom.offsetHeight // 位移元素初始高
|
||||
const winWidth = document.body.clientWidth // 父容器初始宽
|
||||
const winHeight = document.body.clientHeight // 父容器初始高
|
||||
|
||||
// 设置位移元素可移动
|
||||
moveDom.style.position = 'absolute'
|
||||
moveDom.style.top = moveDomTop + 'px'
|
||||
moveDom.style.left = moveDomLeft + 'px'
|
||||
|
||||
// 算出鼠标相对元素的位置
|
||||
const disX = e.clientX
|
||||
const disY = e.clientY
|
||||
|
||||
document.onmousemove = e => {
|
||||
// 用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
|
||||
const left = e.clientX - disX // X轴相对位移量
|
||||
const top = e.clientY - disY // Y轴相对位移量
|
||||
let toMoveTop = 0 // 纵轴最终坐标
|
||||
let toMoveLeft = 0 // 横轴最终坐标
|
||||
|
||||
if (!overWin) {
|
||||
// 不可超出屏幕时计算移动边界
|
||||
if (moveDomTop + top + moveDomH > winHeight) {
|
||||
toMoveTop = winHeight - moveDomH
|
||||
} else if (moveDomTop + top < 0) {
|
||||
// 解决漏洞toMoveTop默认为0这里无需重复赋值
|
||||
// toMoveTop = 0
|
||||
} else {
|
||||
toMoveTop = moveDomTop + top
|
||||
}
|
||||
if (moveDomLeft + left < 0) {
|
||||
// 解决漏洞toMoveLeft默认为0这里无需重复赋值
|
||||
// toMoveLeft = 0
|
||||
} else if (moveDomLeft + left + moveDomW > winWidth) {
|
||||
toMoveLeft = winWidth - moveDomW
|
||||
} else {
|
||||
toMoveLeft = moveDomLeft + left
|
||||
}
|
||||
} else {
|
||||
// 让弹窗飞
|
||||
toMoveTop = moveDomTop + top
|
||||
toMoveLeft = moveDomLeft + left
|
||||
}
|
||||
|
||||
// 移动当前元素
|
||||
moveDom.style.top = toMoveTop + 'px'
|
||||
moveDom.style.left = toMoveLeft + 'px'
|
||||
}
|
||||
document.onmouseup = () => {
|
||||
// 注销事件
|
||||
document.onmousemove = null
|
||||
document.onmouseup = null
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
export default draggable
|
||||
7
hotgo-web/src/utils/errorCode.js
Normal file
7
hotgo-web/src/utils/errorCode.js
Normal file
@@ -0,0 +1,7 @@
|
||||
export default {
|
||||
'0': '操作成功!',
|
||||
'401': '认证失败,无法访问系统资源',
|
||||
'403': '当前操作没有权限',
|
||||
'404': '访问资源不存在',
|
||||
'default': '系统未知错误,请反馈给管理员'
|
||||
}
|
||||
20
hotgo-web/src/utils/filter.js
Normal file
20
hotgo-web/src/utils/filter.js
Normal file
@@ -0,0 +1,20 @@
|
||||
import Vue from 'vue'
|
||||
import moment from 'moment'
|
||||
import 'moment/locale/zh-cn'
|
||||
moment.locale('zh-cn')
|
||||
|
||||
Vue.filter('NumberFormat', function (value) {
|
||||
if (!value) {
|
||||
return '0'
|
||||
}
|
||||
const intPartFormat = value.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,') // 将整数部分逢三一断
|
||||
return intPartFormat
|
||||
})
|
||||
|
||||
Vue.filter('dayjs', function (dataStr, pattern = 'YYYY-MM-DD HH:mm:ss') {
|
||||
return moment(dataStr).format(pattern)
|
||||
})
|
||||
|
||||
Vue.filter('moment', function (dataStr, pattern = 'YYYY-MM-DD HH:mm:ss') {
|
||||
return moment(dataStr).format(pattern)
|
||||
})
|
||||
29
hotgo-web/src/utils/highlight.js
Normal file
29
hotgo-web/src/utils/highlight.js
Normal file
@@ -0,0 +1,29 @@
|
||||
// src/utils/highlight.js 文件路径,纯属自定义
|
||||
|
||||
// highlight.js 代码高亮指令
|
||||
import Hljs from 'highlight.js'
|
||||
import 'highlight.js/styles/vs.css' // 代码高亮风格,选择更多风格需导入 node_modules/hightlight.js/styles/ 目录下其它css文件
|
||||
|
||||
const Highlight = {}
|
||||
// 自定义插件
|
||||
Highlight.install = function (Vue) {
|
||||
// 自定义指令 v-highlight
|
||||
Vue.directive('highlight', {
|
||||
// 被绑定元素插入父节点时调用
|
||||
inserted: function (el) {
|
||||
const blocks = el.querySelectorAll('pre code')
|
||||
for (let i = 0; i < blocks.length; i++) {
|
||||
Hljs.highlightBlock(blocks[i])
|
||||
}
|
||||
},
|
||||
// 指令所在组件的 VNode 及其子 VNode 全部更新后调用
|
||||
componentUpdated: function (el) {
|
||||
const blocks = el.querySelectorAll('pre code')
|
||||
for (let i = 0; i < blocks.length; i++) {
|
||||
Hljs.highlightBlock(blocks[i])
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export default Highlight
|
||||
385
hotgo-web/src/utils/pt/layout/baseMouldStyles.js
Normal file
385
hotgo-web/src/utils/pt/layout/baseMouldStyles.js
Normal file
@@ -0,0 +1,385 @@
|
||||
/**
|
||||
* 控制表单列数布局
|
||||
* @param layout 列布局: 1,2,3,4
|
||||
*/
|
||||
const formColLayout = function (layout, colSetting, fixedSetting) {
|
||||
if (layout && layout === '1') {
|
||||
// 1列
|
||||
return {
|
||||
cols: colSetting && colSetting.cols ? colSetting.cols : { xs: 24, sm: 24, lg: 24, xl: 24 },
|
||||
labelCol:
|
||||
colSetting && colSetting.labelCol ? colSetting.labelCol : { xs: 6, sm: 6, lg: 6, xl: 6 },
|
||||
wrapperCol:
|
||||
colSetting && colSetting.wrapperCol
|
||||
? colSetting.wrapperCol
|
||||
: { xs: 18, sm: 18, lg: 18, xl: 18 },
|
||||
fixed: {
|
||||
cols: { xs: 24, sm: 24, lg: 24, xl: 24 },
|
||||
labelCol:
|
||||
fixedSetting && fixedSetting.labelCol
|
||||
? fixedSetting.labelCol
|
||||
: { xs: 6, sm: 6, lg: 6, xl: 6 },
|
||||
wrapperCol:
|
||||
fixedSetting && fixedSetting.wrapperCol
|
||||
? fixedSetting.wrapperCol
|
||||
: { xs: 18, sm: 18, lg: 18, xl: 18 }
|
||||
}
|
||||
}
|
||||
} else if (layout && layout === '2') {
|
||||
// 2列
|
||||
return {
|
||||
cols: colSetting && colSetting.cols ? colSetting.cols : { xs: 12, sm: 12, lg: 12, xl: 12 },
|
||||
labelCol:
|
||||
colSetting && colSetting.labelCol ? colSetting.labelCol : { xs: 8, sm: 8, lg: 8, xl: 8 },
|
||||
wrapperCol:
|
||||
colSetting && colSetting.wrapperCol
|
||||
? colSetting.wrapperCol
|
||||
: { xs: 16, sm: 16, lg: 16, xl: 16 },
|
||||
fixed: {
|
||||
cols: { xs: 24, sm: 24, lg: 24, xl: 24 },
|
||||
labelCol:
|
||||
fixedSetting && fixedSetting.labelCol
|
||||
? fixedSetting.labelCol
|
||||
: { xs: 4, sm: 4, lg: 4, xl: 4 },
|
||||
wrapperCol:
|
||||
fixedSetting && fixedSetting.wrapperCol
|
||||
? fixedSetting.wrapperCol
|
||||
: { xs: 20, sm: 20, lg: 20, xl: 20 }
|
||||
}
|
||||
}
|
||||
} else if (layout && layout === '3') {
|
||||
// 3列
|
||||
return {
|
||||
cols: colSetting && colSetting.cols ? colSetting.cols : { xs: 8, sm: 8, lg: 8, xl: 8 },
|
||||
labelCol:
|
||||
colSetting && colSetting.labelCol ? colSetting.labelCol : { xs: 9, sm: 9, lg: 9, xl: 9 },
|
||||
wrapperCol:
|
||||
colSetting && colSetting.wrapperCol
|
||||
? colSetting.wrapperCol
|
||||
: { xs: 15, sm: 15, lg: 15, xl: 15 },
|
||||
fixed: {
|
||||
cols: { xs: 24, sm: 24, lg: 24, xl: 24 },
|
||||
labelCol:
|
||||
fixedSetting && fixedSetting.labelCol
|
||||
? fixedSetting.labelCol
|
||||
: { xs: 3, sm: 3, lg: 3, xl: 3 },
|
||||
wrapperCol:
|
||||
fixedSetting && fixedSetting.wrapperCol
|
||||
? fixedSetting.wrapperCol
|
||||
: { xs: 21, sm: 21, lg: 21, xl: 21 }
|
||||
}
|
||||
}
|
||||
} else if (layout && layout === '4') {
|
||||
// 4列
|
||||
return {
|
||||
cols: colSetting && colSetting.cols ? colSetting.cols : { xs: 6, sm: 6, lg: 6, xl: 6 },
|
||||
labelCol:
|
||||
colSetting && colSetting.labelCol ? colSetting.labelCol : { xs: 8, sm: 8, lg: 8, xl: 8 },
|
||||
wrapperCol:
|
||||
colSetting && colSetting.wrapperCol
|
||||
? colSetting.wrapperCol
|
||||
: { xs: 16, sm: 16, lg: 16, xl: 16 },
|
||||
fixed: {
|
||||
cols: { xs: 24, sm: 24, lg: 24, xl: 24 },
|
||||
labelCol:
|
||||
fixedSetting && fixedSetting.labelCol
|
||||
? fixedSetting.labelCol
|
||||
: { xs: 2, sm: 2, lg: 2, xl: 2 },
|
||||
wrapperCol:
|
||||
fixedSetting && fixedSetting.wrapperCol
|
||||
? fixedSetting.wrapperCol
|
||||
: { xs: 22, sm: 22, lg: 22, xl: 22 }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 默认1列
|
||||
return {
|
||||
cols: { xs: 24, sm: 24, lg: 24, xl: 24 },
|
||||
labelCol: { xs: 4, sm: 4, lg: 4, xl: 4 },
|
||||
wrapperCol: { xs: 20, sm: 20, lg: 20, xl: 20 },
|
||||
fixed: {
|
||||
cols: { xs: 24, sm: 24, lg: 24, xl: 24 },
|
||||
labelCol: { xs: 4, sm: 4, lg: 4, xl: 4 },
|
||||
wrapperCol: { xs: 20, sm: 20, lg: 20, xl: 20 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 控制详情页表单列数布局
|
||||
* @param layout 列布局: 1,2,3,4
|
||||
*/
|
||||
const flowformColLayout = function (layout, colSetting, fixedSetting) {
|
||||
if (layout && layout === '1') {
|
||||
// 1列
|
||||
return {
|
||||
cols: colSetting && colSetting.cols ? colSetting.cols : { xs: 24, sm: 24, lg: 24, xl: 24 },
|
||||
labelCol:
|
||||
colSetting && colSetting.labelCol
|
||||
? colSetting.labelCol
|
||||
: { xs: 22, sm: 22, lg: 22, xl: 22 },
|
||||
wrapperCol:
|
||||
colSetting && colSetting.wrapperCol
|
||||
? colSetting.wrapperCol
|
||||
: { xs: 22, sm: 22, lg: 22, xl: 22 },
|
||||
fixed: {
|
||||
cols: { xs: 24, sm: 24, lg: 24, xl: 24 },
|
||||
labelCol:
|
||||
fixedSetting && fixedSetting.labelCol
|
||||
? fixedSetting.labelCol
|
||||
: { xs: 24, sm: 24, lg: 24, xl: 24 },
|
||||
wrapperCol:
|
||||
fixedSetting && fixedSetting.wrapperCol
|
||||
? fixedSetting.wrapperCol
|
||||
: { xs: 20, sm: 20, lg: 20, xl: 20 }
|
||||
}
|
||||
}
|
||||
} else if (layout && layout === '2') {
|
||||
// 2列
|
||||
return {
|
||||
cols: colSetting && colSetting.cols ? colSetting.cols : { xs: 12, sm: 12, lg: 12, xl: 12 },
|
||||
labelCol:
|
||||
colSetting && colSetting.labelCol ? colSetting.labelCol : { xs: 6, sm: 6, lg: 6, xl: 6 },
|
||||
wrapperCol:
|
||||
colSetting && colSetting.wrapperCol
|
||||
? colSetting.wrapperCol
|
||||
: { xs: 18, sm: 18, lg: 18, xl: 18 },
|
||||
fixed: {
|
||||
cols: { xs: 24, sm: 24, lg: 24, xl: 24 },
|
||||
labelCol:
|
||||
fixedSetting && fixedSetting.labelCol
|
||||
? fixedSetting.labelCol
|
||||
: { xs: 3, sm: 3, lg: 3, xl: 3 },
|
||||
wrapperCol:
|
||||
fixedSetting && fixedSetting.wrapperCol
|
||||
? fixedSetting.wrapperCol
|
||||
: { xs: 21, sm: 21, lg: 21, xl: 21 }
|
||||
}
|
||||
}
|
||||
} else if (layout && layout === '3') {
|
||||
// 3列
|
||||
return {
|
||||
cols: colSetting && colSetting.cols ? colSetting.cols : { xs: 8, sm: 8, lg: 8, xl: 8 },
|
||||
labelCol:
|
||||
colSetting && colSetting.labelCol ? colSetting.labelCol : { xs: 6, sm: 6, lg: 6, xl: 6 },
|
||||
wrapperCol:
|
||||
colSetting && colSetting.wrapperCol
|
||||
? colSetting.wrapperCol
|
||||
: { xs: 18, sm: 18, lg: 18, xl: 18 },
|
||||
fixed: {
|
||||
cols: { xs: 24, sm: 24, lg: 24, xl: 24 },
|
||||
labelCol:
|
||||
fixedSetting && fixedSetting.labelCol
|
||||
? fixedSetting.labelCol
|
||||
: { xs: 2, sm: 2, lg: 2, xl: 2 },
|
||||
wrapperCol:
|
||||
fixedSetting && fixedSetting.wrapperCol
|
||||
? fixedSetting.wrapperCol
|
||||
: { xs: 22, sm: 22, lg: 22, xl: 22 }
|
||||
}
|
||||
}
|
||||
} else if (layout && layout === '4') {
|
||||
// 4列
|
||||
return {
|
||||
cols: colSetting && colSetting.cols ? colSetting.cols : { xs: 6, sm: 6, lg: 6, xl: 6 },
|
||||
labelCol:
|
||||
colSetting && colSetting.labelCol
|
||||
? colSetting.labelCol
|
||||
: { xs: 24, sm: 24, lg: 24, xl: 24 },
|
||||
wrapperCol:
|
||||
colSetting && colSetting.wrapperCol
|
||||
? colSetting.wrapperCol
|
||||
: { xs: 24, sm: 24, lg: 24, xl: 24 },
|
||||
fixed: {
|
||||
cols: { xs: 24, sm: 24, lg: 24, xl: 24 },
|
||||
labelCol:
|
||||
fixedSetting && fixedSetting.labelCol
|
||||
? fixedSetting.labelCol
|
||||
: { xs: 24, sm: 24, lg: 24, xl: 24 },
|
||||
wrapperCol:
|
||||
fixedSetting && fixedSetting.wrapperCol
|
||||
? fixedSetting.wrapperCol
|
||||
: { xs: 24, sm: 24, lg: 24, xl: 24 }
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 默认1列
|
||||
return {
|
||||
cols: { xs: 24, sm: 24, lg: 24, xl: 24 },
|
||||
labelCol: { xs: 4, sm: 4, lg: 4, xl: 4 },
|
||||
wrapperCol: { xs: 20, sm: 20, lg: 20, xl: 20 },
|
||||
fixed: {
|
||||
cols: { xs: 24, sm: 24, lg: 24, xl: 24 },
|
||||
labelCol: { xs: 4, sm: 4, lg: 4, xl: 4 },
|
||||
wrapperCol: { xs: 20, sm: 20, lg: 20, xl: 20 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 控制弹窗modal的宽高
|
||||
* @param widthRatio 弹窗modal宽度占屏幕比例
|
||||
* @param heightRatio 弹窗modal高度占屏幕比例
|
||||
* @param cutHeight 弹窗modal的body的高度比整个弹窗modal少的高度
|
||||
* @param bodyOverflowY 弹窗modal的body的overflow-y属性
|
||||
*/
|
||||
const modalWidthAndHeight = function (
|
||||
widthRatio = 0.7,
|
||||
heightRatio = 0.7,
|
||||
cutHeight = 40,
|
||||
bodyOverflowY = 'auto',
|
||||
backgroundColor = '#fff'
|
||||
) {
|
||||
const modalStyleWidth = document.documentElement.clientWidth * widthRatio + 'px'
|
||||
// let modalStyleHeight = document.documentElement.clientHeight * heightRatio + 'px';
|
||||
const bodyStyleWidth = document.documentElement.clientWidth * widthRatio + 'px'
|
||||
const bodyStyleHeight = document.documentElement.clientHeight * heightRatio - cutHeight + 'px'
|
||||
return {
|
||||
modalStyle: {
|
||||
// 弹窗宽高控制
|
||||
width: modalStyleWidth,
|
||||
height: 'auto'
|
||||
},
|
||||
bodyStyle: {
|
||||
// 弹窗body宽高控制
|
||||
width: bodyStyleWidth,
|
||||
height: bodyStyleHeight,
|
||||
overflowY: bodyOverflowY,
|
||||
backgroundColor
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 根据布局列数控制弹窗modal的宽高
|
||||
* (单列: 580*420 适用于1~6项内容时、
|
||||
* 两列:960*500 适用于6~12项内容时、
|
||||
* 三列:1280*600) 适用于12项以上
|
||||
* @param layout 列数
|
||||
* @param cutHeight 弹窗modal的body的高度比整个弹窗modal少的高度
|
||||
* @param bodyOverflowY 弹窗modal的body的overflow-y属性
|
||||
*/
|
||||
const modalWidthAndHeightBylayout = function (
|
||||
layout = 1,
|
||||
cutHeight = 40,
|
||||
bodyOverflowY = 'auto',
|
||||
backgroundColor = '#fff'
|
||||
) {
|
||||
let modalStyleWidth = null
|
||||
// let modalStyleHeight = document.documentElement.clientHeight * heightRatio + 'px';
|
||||
let bodyStyleWidth = null
|
||||
let bodyStyleHeight = null
|
||||
let bodyStylePadding = null
|
||||
if (layout === 1) {
|
||||
modalStyleWidth = 580 + 'px'
|
||||
bodyStyleWidth = 580 + 'px'
|
||||
bodyStyleHeight = 420 - cutHeight + 'px'
|
||||
bodyStylePadding = '20px 50px'
|
||||
} else if (layout === 2) {
|
||||
modalStyleWidth = 960 + 'px'
|
||||
bodyStyleWidth = 960 + 'px'
|
||||
bodyStyleHeight = 500 - cutHeight + 'px'
|
||||
bodyStylePadding = '20px'
|
||||
} else if (layout === 3) {
|
||||
modalStyleWidth = 1280 + 'px'
|
||||
bodyStyleWidth = 1280 + 'px'
|
||||
bodyStyleHeight = 600 - cutHeight + 'px'
|
||||
bodyStylePadding = '20px 40px'
|
||||
}
|
||||
return {
|
||||
modalStyle: {
|
||||
// 弹窗宽高控制
|
||||
width: modalStyleWidth,
|
||||
height: 'auto'
|
||||
},
|
||||
bodyStyle: {
|
||||
// 弹窗body宽高控制
|
||||
width: bodyStyleWidth,
|
||||
height: bodyStyleHeight,
|
||||
padding: bodyStylePadding,
|
||||
overflowY: bodyOverflowY,
|
||||
backgroundColor
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 获取内容高度: 传入元素的父元素高度 - 父元素除去内容之外的元素的高度
|
||||
* @param wrapId 元素的id
|
||||
* @param cutHeight 内容与父元素相差的高度,一般包括:父元素padding,按钮高度及margin,及其他
|
||||
*/
|
||||
const getContentHeight = function (params) {
|
||||
// 默认值auto
|
||||
let contentHeight = 'auto'
|
||||
if (params) {
|
||||
// 获取元素父元素
|
||||
const el = document.querySelector('#' + params.wrapId)
|
||||
if (el) {
|
||||
// 获取父元素高度
|
||||
const parentHeight = el.parentNode.offsetHeight
|
||||
// 传入的元素高度设为父元素高度
|
||||
// el.style.height = parentHeight + 'px'; 为加resize改变大小,注释掉这句.
|
||||
// 内容高度为 父元素高度 减去 父元素除去内容之外的元素的高度
|
||||
if (params.cutHeight) {
|
||||
contentHeight = parentHeight - params.cutHeight + 'px'
|
||||
} else {
|
||||
contentHeight = parentHeight + 'px'
|
||||
}
|
||||
}
|
||||
}
|
||||
return contentHeight
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验不通过,滚动到校验不通过元素位置,提示用户
|
||||
*/
|
||||
const getFirstCheckErrorElement = function (err) {
|
||||
for (const key in err) {
|
||||
// return document.querySelector("div[for='" + key + "']") || document.querySelector("div[for='" + key + "Alias']") || document.querySelector("div[for='" + key + "Name']");
|
||||
return document.querySelector('#' + key)
|
||||
}
|
||||
}
|
||||
const appointModalWidthAndHeight = function (
|
||||
height,
|
||||
width,
|
||||
cutHeight,
|
||||
bodyOverflowY = 'auto',
|
||||
backgroundColor = '#fff'
|
||||
) {
|
||||
let modalStyleWidth
|
||||
let bodyStyleWidth
|
||||
let bodyStyleHeight
|
||||
if (width === '100%' && height === '100%') {
|
||||
// 全屏模式
|
||||
modalStyleWidth = document.documentElement.clientWidth + 'px'
|
||||
bodyStyleWidth = document.documentElement.clientWidth + 'px'
|
||||
bodyStyleHeight = document.documentElement.clientHeight - cutHeight + 'px'
|
||||
} else {
|
||||
// 指定宽高
|
||||
modalStyleWidth = width + 'px'
|
||||
bodyStyleWidth = width + 'px'
|
||||
bodyStyleHeight = height - cutHeight + 'px'
|
||||
}
|
||||
return {
|
||||
modalStyle: {
|
||||
// 弹窗宽高控制
|
||||
width: modalStyleWidth,
|
||||
height: 'auto'
|
||||
},
|
||||
bodyStyle: {
|
||||
// 弹窗body宽高控制
|
||||
width: bodyStyleWidth,
|
||||
height: bodyStyleHeight,
|
||||
overflowY: bodyOverflowY,
|
||||
backgroundColor
|
||||
}
|
||||
}
|
||||
}
|
||||
export {
|
||||
formColLayout,
|
||||
flowformColLayout,
|
||||
modalWidthAndHeight,
|
||||
modalWidthAndHeightBylayout,
|
||||
getContentHeight,
|
||||
getFirstCheckErrorElement,
|
||||
appointModalWidthAndHeight
|
||||
}
|
||||
136
hotgo-web/src/utils/request.js
Normal file
136
hotgo-web/src/utils/request.js
Normal file
@@ -0,0 +1,136 @@
|
||||
import axios from 'axios'
|
||||
import store from '@/store'
|
||||
import storage from 'store'
|
||||
import notification from 'ant-design-vue/es/notification'
|
||||
import { VueAxios } from './axios'
|
||||
import { ACCESS_TOKEN } from '@/store/mutation-types'
|
||||
import errorCode from '@/utils/errorCode'
|
||||
|
||||
// 创建 axios 实例
|
||||
const request = axios.create({
|
||||
// API 请求的默认前缀
|
||||
baseURL: process.env.VUE_APP_BASE_API,
|
||||
// baseURL: 'https://aidex.setworld.net',
|
||||
timeout: 20000 // 请求超时时间
|
||||
})
|
||||
|
||||
// 异常拦截处理器
|
||||
const errorHandler = (error) => {
|
||||
console.log('err' + error)
|
||||
let { message } = error
|
||||
if (message === 'Network Error') {
|
||||
message = '后端接口连接异常'
|
||||
} else if (message.includes('timeout')) {
|
||||
message = '系统接口请求超时'
|
||||
} else if (message.includes('Request failed with status code')) {
|
||||
message = '系统接口' + message.substr(message.length - 3) + '异常'
|
||||
}
|
||||
notification.error({
|
||||
message: message,
|
||||
duration: 5
|
||||
})
|
||||
// return Promise.reject(error) //注释该行,否则接口请求失败会一直请求刷新错误数据,这里保证请求一次
|
||||
}
|
||||
|
||||
// request interceptor
|
||||
request.interceptors.request.use(config => {
|
||||
const token = storage.get(ACCESS_TOKEN)
|
||||
// 如果 token 存在
|
||||
// 让每个请求携带自定义 token 请根据实际情况自行修改
|
||||
if (token) {
|
||||
config.headers['Authorization'] = 'Bearer ' + token // 让每个请求携带自定义token 请根据实际情况自行修改
|
||||
// config.headers['accessAccess-Token'] = token
|
||||
}
|
||||
// get请求映射params参数
|
||||
if (config.method === 'get' && config.params) {
|
||||
let url = config.url + '?'
|
||||
for (const propName of Object.keys(config.params)) {
|
||||
const value = config.params[propName]
|
||||
var part = encodeURIComponent(propName) + '='
|
||||
// 修改漏洞
|
||||
if (value != null && typeof (value) !== 'undefined') {
|
||||
if (typeof value === 'object') {
|
||||
for (const key of Object.keys(value)) {
|
||||
const params = propName + '[' + key + ']'
|
||||
var subPart = encodeURIComponent(params) + '='
|
||||
url += subPart + encodeURIComponent(value[key]) + '&'
|
||||
}
|
||||
} else {
|
||||
url += part + encodeURIComponent(value) + '&'
|
||||
}
|
||||
}
|
||||
}
|
||||
url = url.slice(0, -1)
|
||||
config.params = {}
|
||||
config.url = url
|
||||
}
|
||||
return config
|
||||
}, errorHandler)
|
||||
|
||||
// response interceptor
|
||||
request.interceptors.response.use((res) => {
|
||||
// 请求rul
|
||||
const requestUrl = res.config.url
|
||||
// 未设置状态码则默认成功状态
|
||||
const code = res.data.code || 0
|
||||
// 获取错误信息
|
||||
const msg = errorCode[code] || res.data.message || errorCode['default']
|
||||
|
||||
if (code === 401) {
|
||||
notification.open({
|
||||
key: 'loginExpireTip',
|
||||
message: '系统提示',
|
||||
description: '登录状态已过期,请重新登录',
|
||||
btn: h => {
|
||||
return h(
|
||||
'a-button',
|
||||
{
|
||||
props: {
|
||||
type: 'primary',
|
||||
size: 'small'
|
||||
},
|
||||
on: {
|
||||
click: () => {
|
||||
store.dispatch('Logout').then(() => {
|
||||
location.href = '/index'
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
'确认'
|
||||
)
|
||||
},
|
||||
duration: 0,
|
||||
onClose: close
|
||||
})
|
||||
} else if (code === 500) {
|
||||
if (requestUrl !== '/login') {
|
||||
notification.error({
|
||||
message: msg,
|
||||
description: msg
|
||||
})
|
||||
}
|
||||
} else if (code !== 0) {
|
||||
notification.error({
|
||||
message: msg,
|
||||
duration: 5
|
||||
})
|
||||
} else {
|
||||
return res.data.data
|
||||
}
|
||||
return Promise.reject(msg)
|
||||
}, errorHandler)
|
||||
|
||||
const installer = {
|
||||
vm: {},
|
||||
install(Vue) {
|
||||
Vue.use(VueAxios, request)
|
||||
}
|
||||
}
|
||||
|
||||
export default request
|
||||
|
||||
export {
|
||||
installer as VueAxios,
|
||||
request as axios
|
||||
}
|
||||
9
hotgo-web/src/utils/requireIcons.js
Normal file
9
hotgo-web/src/utils/requireIcons.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const req = require.context('../assets/icons', false, /\.svg$/)
|
||||
const requireAll = requireContext => requireContext.keys()
|
||||
const re = /\.\/(.*)\.svg/
|
||||
|
||||
const icons = requireAll(req).map(i => {
|
||||
return i.match(re)[1]
|
||||
})
|
||||
|
||||
export default icons
|
||||
30
hotgo-web/src/utils/routeConvert.js
Normal file
30
hotgo-web/src/utils/routeConvert.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import cloneDeep from 'lodash.clonedeep'
|
||||
|
||||
export function convertRoutes (nodes) {
|
||||
if (!nodes) return null
|
||||
|
||||
nodes = cloneDeep(nodes)
|
||||
|
||||
let queue = Array.isArray(nodes) ? nodes.concat() : [nodes]
|
||||
|
||||
while (queue.length) {
|
||||
const levelSize = queue.length
|
||||
|
||||
for (let i = 0; i < levelSize; i++) {
|
||||
const node = queue.shift()
|
||||
|
||||
if (!node.children || !node.children.length) continue
|
||||
|
||||
node.children.forEach(child => {
|
||||
// 转化相对路径
|
||||
if (child.path[0] !== '/' && !child.path.startsWith('http')) {
|
||||
child.path = node.path.replace(/(\w*)[/]*$/, `$1/${child.path}`)
|
||||
}
|
||||
})
|
||||
|
||||
queue = queue.concat(node.children)
|
||||
}
|
||||
}
|
||||
|
||||
return nodes
|
||||
}
|
||||
5
hotgo-web/src/utils/screenLog.js
Normal file
5
hotgo-web/src/utils/screenLog.js
Normal file
@@ -0,0 +1,5 @@
|
||||
/* eslint-disable */
|
||||
export const printANSI = () => {
|
||||
// console.clear()
|
||||
// 这里可以配置首次加载输出到控制台的brand
|
||||
}
|
||||
128
hotgo-web/src/utils/util.js
Normal file
128
hotgo-web/src/utils/util.js
Normal file
@@ -0,0 +1,128 @@
|
||||
export function timeFix () {
|
||||
const time = new Date()
|
||||
const hour = time.getHours()
|
||||
return hour < 9 ? '早上好' : hour <= 11 ? '上午好' : hour <= 13 ? '中午好' : hour < 20 ? '下午好' : '晚上好'
|
||||
}
|
||||
|
||||
export function welcome () {
|
||||
const arr = ['休息一会儿吧', '准备吃什么呢?', '要不要打一把 DOTA', '我猜你可能累了']
|
||||
const index = Math.floor(Math.random() * arr.length)
|
||||
return arr[index]
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发 window.resize
|
||||
*/
|
||||
export function triggerWindowResizeEvent () {
|
||||
const event = document.createEvent('HTMLEvents')
|
||||
event.initEvent('resize', true, true)
|
||||
event.eventType = 'message'
|
||||
window.dispatchEvent(event)
|
||||
}
|
||||
|
||||
export function handleScrollHeader (callback) {
|
||||
let timer = 0
|
||||
|
||||
let beforeScrollTop = window.pageYOffset
|
||||
callback = callback || function () {}
|
||||
window.addEventListener(
|
||||
'scroll',
|
||||
event => {
|
||||
clearTimeout(timer)
|
||||
timer = setTimeout(() => {
|
||||
let direction = 'up'
|
||||
const afterScrollTop = window.pageYOffset
|
||||
const delta = afterScrollTop - beforeScrollTop
|
||||
if (delta === 0) {
|
||||
return false
|
||||
}
|
||||
direction = delta > 0 ? 'down' : 'up'
|
||||
callback(direction)
|
||||
beforeScrollTop = afterScrollTop
|
||||
}, 50)
|
||||
},
|
||||
false
|
||||
)
|
||||
}
|
||||
|
||||
export function isIE () {
|
||||
const bw = window.navigator.userAgent
|
||||
const compare = (s) => bw.indexOf(s) >= 0
|
||||
const ie11 = (() => 'ActiveXObject' in window)()
|
||||
return compare('MSIE') || ie11
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove loading animate
|
||||
* @param id parent element id or class
|
||||
* @param timeout
|
||||
*/
|
||||
export function removeLoadingAnimate (id = '', timeout = 1500) {
|
||||
if (id === '') {
|
||||
return
|
||||
}
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(document.getElementById(id))
|
||||
}, timeout)
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机生成数字
|
||||
* @param min 最小值
|
||||
* @param max 最大值
|
||||
* @return int 生成后的数字
|
||||
*/
|
||||
export function randomNumber (min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1) + min)
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机生成字符串
|
||||
* @param length 字符串的长度
|
||||
* @param chats 可选字符串区间(只会生成传入的字符串中的字符)
|
||||
* @return string 生成的字符串
|
||||
*/
|
||||
export function randomString (length, chats) {
|
||||
if (!length) length = 1
|
||||
if (!chats) chats = '0123456789qwertyuioplkjhgfdsazxcvbnm'
|
||||
let str = ''
|
||||
for (let i = 0; i < length; i++) {
|
||||
const num = randomNumber(0, chats.length - 1)
|
||||
str += chats[num]
|
||||
}
|
||||
return str
|
||||
}
|
||||
|
||||
/**
|
||||
* 随机生成uuid
|
||||
* @return string 生成的uuid
|
||||
*/
|
||||
export function randomUUID () {
|
||||
const chats = '0123456789abcdef'
|
||||
return randomString(32, chats)
|
||||
}
|
||||
/**
|
||||
* json对象单层,转换url参数
|
||||
* @param {*} paramObj
|
||||
*/
|
||||
export function formateObjToParamStr (paramObj) {
|
||||
const sdata = []
|
||||
for (const attr in paramObj) {
|
||||
sdata.push(`${attr} = ${filter(paramObj[attr])}`)
|
||||
}
|
||||
return sdata.join('&')
|
||||
}
|
||||
// 过滤特殊符号
|
||||
function filter (str) {
|
||||
// 特殊字符转义
|
||||
str += '' // 隐式转换
|
||||
str = str.replace(/%/g, '%25')
|
||||
str = str.replace(/\+/g, '%2B')
|
||||
str = str.replace(/ /g, '%20')
|
||||
str = str.replace(/\//g, '%2F')
|
||||
str = str.replace(/\?/g, '%3F')
|
||||
str = str.replace(/&/g, '%26')
|
||||
str = str.replace(/=/g, '%3D')
|
||||
str = str.replace(/#/g, '%23')
|
||||
return str
|
||||
}
|
||||
50
hotgo-web/src/utils/utils.less
Normal file
50
hotgo-web/src/utils/utils.less
Normal file
@@ -0,0 +1,50 @@
|
||||
.textOverflow() {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.textOverflowMulti(@line: 3, @bg: #fff) {
|
||||
position: relative;
|
||||
max-height: @line * 1.5em;
|
||||
margin-right: -1em;
|
||||
padding-right: 1em;
|
||||
overflow: hidden;
|
||||
line-height: 1.5em;
|
||||
text-align: justify;
|
||||
&::before {
|
||||
position: absolute;
|
||||
right: 14px;
|
||||
bottom: 0;
|
||||
padding: 0 1px;
|
||||
background: @bg;
|
||||
content: '...';
|
||||
}
|
||||
&::after {
|
||||
position: absolute;
|
||||
right: 14px;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
margin-top: 0.2em;
|
||||
background: white;
|
||||
content: '';
|
||||
}
|
||||
}
|
||||
|
||||
// mixins for clearfix
|
||||
// ------------------------
|
||||
.clearfix() {
|
||||
zoom: 1;
|
||||
&::before,
|
||||
&::after {
|
||||
display: table;
|
||||
content: ' ';
|
||||
}
|
||||
&::after {
|
||||
clear: both;
|
||||
height: 0;
|
||||
font-size: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
83
hotgo-web/src/utils/validate.js
Normal file
83
hotgo-web/src/utils/validate.js
Normal file
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* @param {string} path
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function isExternal (path) {
|
||||
return /^(https?:|mailto:|tel:)/.test(path)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function validUsername (str) {
|
||||
const validMap = ['admin', 'editor']
|
||||
return validMap.indexOf(str.trim()) >= 0
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} url
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function validURL (url) {
|
||||
const reg = /^([hH][tT]{2}[pP]:\/\/|[hH][tT]{2}[pP][sS]:\/\/)(([A-Za-z0-9-~]+)\.)+([A-Za-z0-9-~/])+$/
|
||||
return reg.test(url)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function validLowerCase (str) {
|
||||
const reg = /^[a-z]+$/
|
||||
return reg.test(str)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function validUpperCase (str) {
|
||||
const reg = /^[A-Z]+$/
|
||||
return reg.test(str)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function validAlphabets (str) {
|
||||
const reg = /^[A-Za-z]+$/
|
||||
return reg.test(str)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} email
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function validEmail (email) {
|
||||
const reg = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
||||
return reg.test(email)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function isString (str) {
|
||||
if (typeof str === 'string' || str instanceof String) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Array} arg
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function isArray (arg) {
|
||||
if (typeof Array.isArray === 'undefined') {
|
||||
return Object.prototype.toString.call(arg) === '[object Array]'
|
||||
}
|
||||
return Array.isArray(arg)
|
||||
}
|
||||
42
hotgo-web/src/utils/zipdownload.js
Normal file
42
hotgo-web/src/utils/zipdownload.js
Normal file
@@ -0,0 +1,42 @@
|
||||
import axios from 'axios'
|
||||
import storage from 'store'
|
||||
import { ACCESS_TOKEN } from '@/store/mutation-types'
|
||||
|
||||
const mimeMap = {
|
||||
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
zip: 'application/zip'
|
||||
}
|
||||
|
||||
const baseUrl = process.env.VUE_APP_BASE_API
|
||||
export function downLoadZip (str, filename) {
|
||||
var url = baseUrl + str
|
||||
axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
responseType: 'blob',
|
||||
headers: { 'Authorization': 'Bearer ' + storage.get(ACCESS_TOKEN) }
|
||||
}).then(res => {
|
||||
resolveBlob(res, mimeMap.zip)
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 解析blob响应内容并下载
|
||||
* @param {*} res blob响应内容
|
||||
* @param {String} mimeType MIME类型
|
||||
*/
|
||||
export function resolveBlob (res, mimeType) {
|
||||
const aLink = document.createElement('a')
|
||||
var blob = new Blob([res.data], { type: mimeType })
|
||||
// //从response的headers中获取filename, 后端response.setHeader("Content-disposition", "attachment; filename=xxxx.docx") 设置的文件名;
|
||||
var patt = new RegExp('filename=([^;]+\\.[^\\.;]+);*')
|
||||
var contentDisposition = decodeURI(res.headers['content-disposition'])
|
||||
var result = patt.exec(contentDisposition)
|
||||
console.log(result)
|
||||
var fileName = result[1]
|
||||
fileName = fileName.replace(/"/g, '')
|
||||
aLink.href = URL.createObjectURL(blob)
|
||||
aLink.setAttribute('download', fileName) // 设置下载文件名称
|
||||
document.body.appendChild(aLink)
|
||||
aLink.click()
|
||||
document.body.removeChild(aLink)
|
||||
}
|
||||
Reference in New Issue
Block a user