初始项目

This commit is contained in:
liupopo
2023-02-11 12:55:02 +08:00
parent 1748bda84a
commit 0b89e36064
3363 changed files with 506201 additions and 1 deletions

View File

@@ -0,0 +1,27 @@
import Cookies from 'js-cookie'
const TokenKey = 'loginToken'
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token) {
return Cookies.set(TokenKey, token)
}
export function removeToken() {
return Cookies.remove(TokenKey)
}
export function get(key) {
return Cookies.get(key)
}
export function set(key,value) {
return Cookies.set(key, value)
}
export function remove(key) {
return Cookies.remove(key)
}

View File

@@ -0,0 +1,63 @@
import axios from 'axios'
import { Message, MessageBox } from 'element-ui'
import store from '../store'
import { getToken } from '@/utils/auth'
// 创建axios实例
let service = axios.create({
baseURL: process.env.BASE_API, // api的base_url
timeout: 5000 // 请求超时时间
})
// request拦截器
service.interceptors.request.use(config => {
if (store.getters.token) {
config.headers = {
'Authorization' : "Token " + getToken('Token'), //携带权限参数
};
}
return config
}, error => {
Promise.reject(error)
})
// respone拦截器
service.interceptors.response.use(
response => {
/**
* code:200,接口正常返回;
*/
const res = response.data
if (res.code !== 200) {
Message({
message: res.message,
type: 'error',
duration: 5 * 1000
})
// 根据服务端约定的状态码5001:非法的token; 5002:其他客户端登录了; 5004:Token 过期了;
if (res.code === 5001 || res.code === 5002 || res.code === 5004) {
MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
store.dispatch('LogOut').then(() => {
location.reload()// 为了重新实例化vue-router对象 避免bug
})
})
}
return Promise.reject('error')
} else { // res.code === 200,正常返回数据
return response.data
}
},
error => {
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
return Promise.reject(error)
}
)
export default service

View File

@@ -0,0 +1,36 @@
import Vue from 'vue'
import Clipboard from 'clipboard'
function clipboardSuccess() {
Vue.prototype.$message({
message: '复制成功',
type: 'success',
duration: 1500
})
}
function clipboardError() {
Vue.prototype.$message({
message: '复制失败',
type: 'error'
})
}
export default function handleClipboard(text, event) {
const clipboard = new Clipboard(event.target, {
text: () => text
})
clipboard.on('success', () => {
clipboardSuccess()
clipboard.off('error')
clipboard.off('success')
clipboard.destroy()
})
clipboard.on('error', () => {
clipboardError()
clipboard.off('error')
clipboard.off('success')
clipboard.destroy()
})
clipboard.onClick(event)
}

View File

@@ -0,0 +1,43 @@
// date.js
export function formatDate(date, fmt) {
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
}
let o = {
'M+': date.getMonth() + 1,
'd+': date.getDate(),
'h+': date.getHours(),
'm+': date.getMinutes(),
's+': date.getSeconds()
};
for (let k in o) {
if (new RegExp(`(${k})`).test(fmt)) {
let str = o[k] + '';
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? str : padLeftZero(str));
}
}
return fmt;
}
function padLeftZero(str) {
return ('00' + str).substr(str.length);
}
export function str2Date(dateStr, separator) {
if (!separator) {
separator = "-";
}
let dateArr = dateStr.split(separator);
let year = parseInt(dateArr[0]);
let month;
//处理月份为04这样的情况
if (dateArr[1].indexOf("0") == 0) {
month = parseInt(dateArr[1].substring(1));
} else {
month = parseInt(dateArr[1]);
}
let day = parseInt(dateArr[2]);
let date = new Date(year, month - 1, day);
return date;
}

View File

@@ -0,0 +1,37 @@
const github = 'https://github.com/shenzhuan/zscat-me';
const appUrl = process.env.VUE_APP_URL // development和production环境是不同的
const shareUrl = 'https://juejin.im/post/5d0b4d28f265da1baf7cf293'
const shareTitle = '用Vue-cli3+element+mockjs 实现后台管理权限系统及顶栏三级菜单显示';
const weibo = {
'weiboUrl': 'http://service.weibo.com/share/share.php',
'weiboAppkey' : '2003962826',
'pic':'https://user-gold-cdn.xitu.io/2019/6/20/16b7425dfa01dbf3?imageView2/1/w/1304/h/734/q/85/format/webp/interlace/1'
}
const qq = {
'baseUrl':'http://connect.qq.com/widget/shareqq/index.html',
'pic':'https://user-gold-cdn.xitu.io/2019/6/20/16b7425dfa01dbf3?imageView2/1/w/1304/h/734/q/85/format/webp/interlace/1',
'desc':'最近完成了我的后台管理系统权限功能的实现,同时觉得后台系统所有的菜单都左置,会限制菜单的扩展,因此我改进了三级菜单的显示。',
'summary':'文章梗概',
'source':'qzone'
}
const qqZone = {
'baseUrl':'https://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey',
'pic':'https://user-gold-cdn.xitu.io/2019/6/20/16b7425dfa01dbf3?imageView2/1/w/1304/h/734/q/85/format/webp/interlace/1',
'desc':'最近完成了我的后台管理系统权限功能的实现,同时觉得后台系统所有的菜单都左置,会限制菜单的扩展,因此我改进了三级菜单的显示。',
'summary':'文章梗概',
'site':'qzone'
}
const douban = {
'baseUrl':'https://www.douban.com/share/service',
'pic':'https://user-gold-cdn.xitu.io/2019/6/20/16b7425dfa01dbf3?imageView2/1/w/1304/h/734/q/85/format/webp/interlace/1',
}
export {
appUrl,
shareUrl,
shareTitle,
weibo,
qq,
qqZone,
douban,
github
}

View File

@@ -0,0 +1,250 @@
const goodsUtilsFun = {
// 格式化时间
timeFun(data) {
if(!isNaN(data)) {
var time = new Date(parseInt(data))
var y = time.getFullYear();
var m = time.getMonth()+1;
var d = time.getDate();
var h = time.getHours() < 10 ? '0'+time.getHours() : time.getHours();
var mm = time.getMinutes() < 10 ? '0'+time.getMinutes() : time.getMinutes();
var s = time.getSeconds() < 10 ? '0'+time.getSeconds() : time.getSeconds();
return y +'-'+m+'-'+d+' '+h+':'+mm+':'+s;
}
return ''
},
timeTwoFun(data) {
if(!isNaN(data)) {
var time = new Date(parseInt(data))
var y = time.getFullYear();
var m = time.getMonth()+1 < 10 ? `0${time.getMonth()+1}` : time.getMonth()+1;
var d = time.getDate() < 10 ? '0'+ time.getDate() : time.getDate();
var h = time.getHours() < 10 ? '0'+time.getHours() : time.getHours();
var mm = time.getMinutes() < 10 ? '0'+time.getMinutes() : time.getMinutes();
var s = time.getSeconds() < 10 ? '0'+time.getSeconds() : time.getSeconds();
return y +'-'+m+'-'+d+' '+h+':'+mm+':'+s;
}
return ''
},
timeDayFun(data) {
if(!isNaN(data)) {
var time = new Date(parseInt(data))
var y = time.getFullYear();
var m = time.getMonth()+1;
var d = time.getDate();
return y +'-'+m+'-'+d;
}
return ''
},
timeStamp(index) {
if (index != '') {
let time = new Date(index).getTime()
return time
}
return ''
},
// 到秒
timeStampFun() {
let time = Date.parse(new Date())
return time
},
callweekDay(data) {
let currentTime = this.timeStamp(data)
let mondayData = ''
let sundayData = ''
if (data) {
let timeNum = new Date(data).getDay()
console.log('我是周几',timeNum)
if (timeNum == 0) {
timeNum = 7
}
console.log('我是周几2',timeNum)
mondayData = this.timeDayFun(currentTime - 1000 * 60 * 60 * 24 * (timeNum - 1))
sundayData = this.timeDayFun(currentTime + 1000 * 60 * 60 * 24 * (7 - timeNum))
}
console.log('我是周几3',mondayData,sundayData)
return {
mondayData,
sundayData
}
},
// 选择日期的格式
selectData(data) {
let startTime = ''
let endTime = ''
endTime = this.timeDayFun(this.timeStampFun() - 1000 * 60 * 60 * 24 * 1)
if (data == 1) {
startTime = this.timeDayFun(this.timeStampFun() - 1000 * 60 * 60 * 24 * 1)
} else if (data == 7) {
startTime = this.timeDayFun(this.timeStampFun() - 1000 * 60 * 60 * 24 * 7)
} else if (data == 15) {
startTime = this.timeDayFun(this.timeStampFun() - 1000 * 60 * 60 * 24 * 15)
} else if (data == 30) {
startTime = this.timeDayFun(this.timeStampFun() - 1000 * 60 * 60 * 24 * 30)
}
return {
startTime,
endTime
}
},
// 分类数据组合
classFun(data,res) {
if (!res) {
let arr = []
data.forEach(element => {
if (element.id != '1') {
let objOne = {}
objOne.id = element.id
objOne.label = element.name
objOne.level = element.level
if(element.hasOwnProperty('listTwo')){
if (element.listTwo.length != 0) {
objOne.children = []
element.listTwo.forEach((elementTwo,i) =>{
let objTwo = {}
objTwo.id = elementTwo.id
objTwo.label = elementTwo.name
objTwo.level = elementTwo.level
objOne.children.push(objTwo)
if(elementTwo.hasOwnProperty('listThree')){
if (elementTwo.listThree.length != 0) {
objOne.children[i].children = []
elementTwo.listThree.forEach((elementThree,index) => {
let objThree = {}
objThree.id = elementThree.id
objThree.label = elementThree.name
objThree.level = elementThree.level
objOne.children[i].children.push(objThree)
})
}
}
})
}
}
arr.push(objOne)
}
});
return arr
} else {
let arr = []
arr.push({
id: '1',
label: '全部分类'
})
data.forEach(element => {
let objOne = {}
objOne.id = element.id
objOne.label = element.name
objOne.level = element.level
if(element.hasOwnProperty('listTwo')){
if (element.listTwo.length != 0) {
objOne.children = []
element.listTwo.forEach((elementTwo,i) =>{
let objTwo = {}
objTwo.id = elementTwo.id
objTwo.label = elementTwo.name
objTwo.level = elementTwo.level
objOne.children.push(objTwo)
if(elementTwo.hasOwnProperty('listThree')){
if (elementTwo.listThree.length != 0) {
objOne.children[i].children = []
elementTwo.listThree.forEach((elementThree,index) => {
let objThree = {}
objThree.id = elementThree.id
objThree.label = elementThree.name
objThree.level = elementThree.level
objOne.children[i].children.push(objThree)
})
}
}
})
}
}
arr.push(objOne)
});
return arr
}
},
classAllFun(data,res) {
if (!res) {
let arr = []
data.forEach(element => {
let objOne = {}
objOne.id = element.id
objOne.label = element.name
objOne.level = element.level
if(element.hasOwnProperty('listTwo')){
if (element.listTwo.length != 0) {
objOne.children = []
element.listTwo.forEach((elementTwo,i) =>{
let objTwo = {}
objTwo.id = elementTwo.id
objTwo.label = elementTwo.name
objTwo.level = elementTwo.level
objOne.children.push(objTwo)
if(elementTwo.hasOwnProperty('listThree')){
if (elementTwo.listThree.length != 0) {
objOne.children[i].children = []
elementTwo.listThree.forEach((elementThree,index) => {
let objThree = {}
objThree.id = elementThree.id
objThree.label = elementThree.name
objThree.level = elementThree.level
objOne.children[i].children.push(objThree)
})
}
}
})
}
}
arr.push(objOne)
});
return arr
}
},
// 检验字符长度
getByteLen(val) {
var len = 0;
var len2 = 0;
var len3 = 0;
for (var i = 0; i < val.length; i++) {
var patt = new RegExp(/[^\x00-\xff]/ig);
var a = val[i];
if (patt.test(a)) {
len += 2;
} else {
len2 += 1;
}
}
len3 = len + len2
return {
len,
len2,
len3
};
},
sumAdd(data) {
let num = 0
data.forEach(element => {
num += element * 1
});
console.log('最后的返回值',num.toFixed(2))
return num.toFixed(2)
},
threeNumReplice(data) {
let res = data + ''
if (res) {
var f = parseFloat(res); if (isNaN(f)) return false; var f = Math.round(res * 100) / 100; var s = f.toString(); var rs = s.indexOf('.'); if (rs < 0) { rs = s.length; s += '.'; } while (s.length < (rs + 1) + 2) { s += '0'; } //每三位用一个逗号隔开
var leftNum=s.split(".")[0]; var rightNum="."+s.split(".")[1]; var result; //定义数组记录截取后的价格
var resultArray=new Array(); if(leftNum.length>3){ var i=true; while (i){ resultArray.push(leftNum.slice(-3)); leftNum=leftNum.slice(0,leftNum.length-3); if(leftNum.length<4){ i=false; } } //由于从后向前截取,所以从最后一个开始遍历并存到一个新的数组,顺序调换
var sortArray=new Array(); for(var i=resultArray.length-1;i>=0;i--){ sortArray.push(resultArray[i]); } result=leftNum+","+sortArray.join(",")+rightNum; }else { result=s; } return result;
} else {
return res
}
}
}
export default goodsUtilsFun

View File

@@ -0,0 +1,84 @@
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 (('' + time).length === 10) time = parseInt(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(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key]
if (key === 'a') return ['一', '二', '三', '四', '五', '六', '日'][value - 1]
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
return time_str
}
/**
* 树形数据转换
* @param {*} data
* @param {*} id
* @param {*} pid
*/
export function treeDataTranslate (data, id = 'id', pid = 'parentId') {
var res = []
var temp = {}
for (var i = 0; i < data.length; i++) {
temp[data[i][id]] = data[i]
}
for (var k = 0; k < data.length; k++) {
if (temp[data[k][pid]] && data[k][id] !== data[k][pid]) {
if (!temp[data[k][pid]]['childrens']) {
temp[data[k][pid]]['childrens'] = []
}
if (!temp[data[k][pid]]['_level']) {
temp[data[k][pid]]['_level'] = 1
}
data[k]['_level'] = temp[data[k][pid]]._level + 1
temp[data[k][pid]]['childrens'].push(data[k])
} else {
res.push(data[k])
}
}
return res
}
export function formatTime(time, option) {
time = +time * 1000
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() + '分'
}
}

View File

@@ -0,0 +1,25 @@
import store from '@/store'
/**
* @param {Array} value
* @returns {Boolean}
* @example see @/views/permission/directive.vue
*/
export default function checkPermission(value) {
if (value && value instanceof Array && value.length > 0) {
const roles = store.getters && store.getters.roles
const permissionRoles = value
const hasPermission = roles.some(role => {
return permissionRoles.includes(role)
})
if (!hasPermission) {
return false
}
return true
} else {
console.error(`need roles! Like v-permission="['admin','editor']"`)
return false
}
}

View File

@@ -0,0 +1,79 @@
import axios from 'axios'
import { Message, MessageBox } from 'element-ui'
import store from '../store'
import { getToken,get } from '@/utils/auth'
// 创建axios实例
const service = axios.create({
baseURL: process.env.BASE_API, // api的base_url
timeout: 35000 // 请求超时时间
})
// request拦截器
service.interceptors.request.use(config => {
if (store.getters.token) {
let test = config.data;
if(test){
config.data['access_token']= getToken()
}
if (get('storeId') && 'undefined'!=get('storeId')){
config.headers['storeid'] = get('storeId')
}
config.headers['Authorization'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
}else{
config.headers['client_id'] = 'app';
config.headers['client_secret'] = 'app';
}
return config
}, error => {
// Do something with request error
console.log(error) // for debug
Promise.reject(error)
})
// respone拦截器
service.interceptors.response.use(
response => {
/**
* code为非200是抛错 可结合自己业务进行修改
*/
const res = response.data
if (res.code !== 200 && !res.access_token) {
console.log(res);
Message({
message: res.msg,
type: 'error',
duration: 3 * 1000
})
// 401:未登录;
if (res.code === 401||res.code === 403) {
MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', {
confirmButtonText: '重新登录',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
store.dispatch('FedLogOut').then(() => {
location.reload()// 为了重新实例化vue-router对象 避免bug
})
})
}
return Promise.reject('error')
} else {
return response.data
}
},
error => {
console.log(error);
Message({
message: error.message,
type: 'error',
duration: 3 * 1000
})
return Promise.reject(error)
}
)
export default service

View File

@@ -0,0 +1,38 @@
export function isvalidUsername(str) {
const valid_map = ['admin', 'test']
return true;
}
/* 合法uri*/
export function validateURL(textval) {
const urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
return urlregex.test(textval)
}
/* 小写字母*/
export function validateLowerCase(str) {
const reg = /^[a-z]+$/
return reg.test(str)
}
/* 大写字母*/
export function validateUpperCase(str) {
const reg = /^[A-Z]+$/
return reg.test(str)
}
/* 大小写字母*/
export function validatAlphabets(str) {
const reg = /^[A-Za-z]+$/
return reg.test(str)
}
/**
* 验证邮箱
* @param str
* @returns {boolean}
*/
export function validatEmail(str) {
const reg = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/
return reg.test(str)
}