Commit 4f5055dd by liuchenxi

update: init repo

parents
> 1%
last 2 versions
[*.{js,jsx,ts,tsx,vue}]
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true
!/src
/src/images
/dist/
/*.js
This diff is collapsed. Click to expand it.
.DS_Store
node_modules
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
package-lock.json
yarn.lock
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
{
"printWidth": 400,
"tabWidth": 2,
"useTabs": false,
"singleQuote": true,
"semi": true,
"trailingComma": "none",
"bracketSpacing": true,
"jsxBracketSameLine": true,
"proseWrap": "preserve"
}
module.exports = {
presets: [
'@vue/app'
],
plugins: [
"@babel/plugin-proposal-optional-chaining"
]
}
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'scope-empty': [0],
'scope-case': [0],
'subject-full-stop': [0, 'never'],
'subject-case': [0, 'never'],
'type-enum': [ // commit type 类型
2,
'always',
[
'add', // 新功能
'feat', // 新功能
'fix', // 修改问题
'update', // 更新
'style', // 样式
'test', // 测试
'docs', // 文档
'refactor', // 重构
'chore' // 依赖包/辅助工具的变动
]
]
}
};
{
"name": "message-operation",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"dev": "vue-cli-service serve",
"start": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@babel/plugin-proposal-optional-chaining": "^7.11.0",
"axios": "^0.19.2",
"vue-clipboard2": "^0.1.1",
"core-js": "^2.6.5",
"element-ui": "^2.13.0",
"js-cookie": "^2.2.0",
"vue": "^2.6.11",
"vue-router": "^3.1.5"
},
"devDependencies": {
"@commitlint/cli": "^11.0.0",
"@commitlint/config-conventional": "^11.0.0",
"@vue/cli-plugin-babel": "^3.8.0",
"@vue/cli-plugin-eslint": "^3.8.0",
"@vue/cli-service": "^3.8.0",
"@vue/eslint-config-standard": "^4.0.0",
"babel-eslint": "^10.0.1",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"husky": "^4.3.0",
"less": "^3.9.0",
"less-loader": "^5.0.0",
"lint-staged": "^8.1.5",
"node-sass": "^4.9.0",
"qs": "^6.7.0",
"sass-loader": "^7.1.0",
"stylus": "^0.54.5",
"stylus-loader": "^3.0.2",
"vue-template-compiler": "^2.6.10"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged",
"commit-msg": "commitlint -e $HUSKY_GIT_PARAMS"
}
},
"lint-staged": {
"*.{js,vue}": [
"vue-cli-service lint",
"git add"
]
}
}
module.exports = {
plugins: {
autoprefixer: {}
}
}
<!DOCTYPE html>
<html lang="cn">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon2.ico">
<link rel="stylesheet" type="text/css" href="//web-1251519181.file.myqcloud.com/custom-element/custom-element.1.0.68.css" />
<title>实施运维</title>
</head>
<body class="damolish">
<noscript>
<strong>We're sorry but damolish doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<script src="//web-1251519181.file.myqcloud.com/lib-4.0/vue/2.6.10/vue.min.js"></script>
<script src="//web-1251519181.file.myqcloud.com/components/input.2.0.14.js"></script>
<script src="//web-1251519181.file.myqcloud.com/components/transfer.1.0.15.js"></script>
<script src="//web-1251519181.file.myqcloud.com/components/steps.1.0.8.js"></script>
<script src="//web-1251519181.file.myqcloud.com/components/step.1.0.5.js"></script>
<script src="//web-1251519181.file.myqcloud.com/components/user-info.1.0.3.js"></script>
<!-- <script src="//web-1251519181.file.myqcloud.com/components/layout.1.1.32.js"></script> -->
<!-- <script src="//web-1251519181.file.myqcloud.com/components/store-select.1.1.10.js"></script> -->
<!-- <script src="//web-1251519181.file.myqcloud.com/components/goods-rights-selector.1.0.6.js"></script> -->
</body>
</html>
<template>
<div id="app" class="dm-reset">
<router-view/>
</div>
</template>
<script>
export default {
name: 'App',
mounted() {
window.addEventListener('offline', _ => {
this.$message.error('网络连接中断');
});
}
};
</script>
<style lang="scss">
.el-pagination {
text-align: right;
}
</style>
import { request } from '@/utils/request.js';
export default function getFetch(api, baseUrl) {
api = api || {};
let keys = Object.keys(api);
keys.forEach(key => {
let opt = api[key];
if (typeof opt === 'string') opt = { url: opt };
opt.url = `${baseUrl}${opt.url}`;
api[key] = params => request(opt, params);
});
return api;
}
import getFetch from './getFetch.js';
let api1 = {
/** 登录信息 */
getUserInfo: 'gic-authcenter/loginuser',
/** 列表 */
getList: {
url: '/goods-async-schedulers/config/list',
method: 'get'
},
/** 下拉服务器ip列表 */
serverList: {
url: '/goods-async-schedulers/config/server-list',
method: 'get'
},
/** 开启同步 */
uploadSync: {
url: '/goods-async-schedulers/config/update-sync',
method: 'post'
},
getDetail: {
url: '/goods-async-schedulers/config/detail',
method: 'post'
},
update: {
url: '/goods-async-schedulers/config/update',
method: 'post'
},
create: {
url: '/goods-async-schedulers/config/create',
method: 'post'
},
importGoodsIndex: '/goods-async-schedulers/config/import-goods-index',
refreshGoodsIndex: '/goods-async-schedulers/config/refresh-goods-index',
refreshProductIndex: '/goods-async-schedulers/config/refresh-product-index', // 索引重建并写入数据
productIndexMapping: '/goods-async-schedulers/config/product-index-mapping',
goodsIndexMapping: '/goods-async-schedulers/config/goods-index-mapping'
};
// api = getFetch(api, '/gic-erp-manage');
api1 = getFetch(api1, '');
export default { ...api1 };
<template>
<div class="aside-menu">
<ul class="aside-menu__wrapper">
<template v-for="item in tabData">
<li
v-if="item.isShow == 1"
:class="['tab-left-list-cell p-l-14', {'active-tab': item.uri === activeTab}]"
:key="item.id"
@click="selectTab(item)">
<!-- <i class="my-icon" :class="['iconfont', item.icon, !!item.onlyIconActive ? 'iconActive' : '']"></i> -->
{{ item.menuName }}
<i v-if="item.nodeChildren && item.nodeChildren.length" :class="[item.collapsFlag ? 'el-icon-arrow-up' : 'el-icon-arrow-down']"></i>
</li>
<el-collapse-transition :key="`${item.id}-sub`">
<div v-show="item.collapsFlag">
<ul class="child-tab-left-list">
<template v-for="childitem in item.nodeChildren">
<li
v-if="childitem.isShow == 1"
:class="['tab-left-list-cell p-l-40', {'active-tab': childitem.uri == activeTab}]"
:key="childitem.id"
@click="selectTab(childitem)">
{{ childitem.menuName }}
<i v-if="childitem.nodeChildren && childitem.nodeChildren.length" :class="[childitem.collapsFlag ? 'el-icon-arrow-up' : 'el-icon-arrow-down']"></i>
</li>
<ul class="third-tab-left-list" :key="`${childitem.id}-sub`" v-show="childitem.collapsFlag">
<template v-for="thirditem in childitem.nodeChildren">
<li
v-if="thirditem.isShow == 1"
:class="['tab-left-list-cell p-l-60', {'active-tab': thirditem.uri === activeTab }]"
:key="thirditem.id"
@click="selectTab(thirditem)">
{{ thirditem.menuName }}
</li>
</template>
</ul>
</template>
</ul>
</div>
</el-collapse-transition>
</template>
</ul>
</div>
</template>
<script>
export default {
name: 'AsideMenu',
props: {
menu: Array
},
data() {
return {
activeTab: '',
tabData: []
};
},
methods: {
selectTab(item) {
console.log(item);
if (this.activeTab === item.uri) return;
if (Array.isArray(item.nodeChildren) && item.nodeChildren.length > 0) {
return item.collapsFlag = !item.collapsFlag;
} else {
this.$router.push({ path: item.uri });
this.tabData.forEach(ele => {
if (ele.id != item.id && (!ele.nodeChildren || !ele.nodeChildren.length)) {
ele.collapsFlag = false;
} else if (ele.nodeChildren && ele.nodeChildren.length) {
let i = 0;
ele.nodeChildren.forEach(element => {
if (element.id == item.id) i++;
});
i <= 0 && (ele.collapsFlag = false);
}
});
}
},
},
watch: {
'$route.path': {
immediate: true,
handler(path) {
this.activeTab = path;
}
},
menu: {
immediate: true,
handler(menu) {
let menuTree = menu.filter(item => item.code === 'goods_operation')[0] || {};
console.log(menu, menuTree);
this.tabData = (menuTree.nodeChildren || []).map(item => {
this.$set(item, 'collapsFlag', false);
if (item.uri === this.activeTab) {
this.$set(item, 'collapsFlag', true);
} else if (item.nodeChildren && item.nodeChildren.length) {
item.nodeChildren.forEach(element => {
if (element.uri === this.activeTab) this.$set(item, 'collapsFlag', true);
});
}
return item;
});
console.log(this.tabData);
}
}
}
};
</script>
<style lang="scss" scoped>
.aside-menu {
position: fixed;
top: 20px;
bottom: 20px;
// left: 20px;
// z-index: 2;
padding-top: 64px;
width: 200px;
overflow: hidden;
// height: 100%;
.aside-menu__wrapper {
width: 100%;
background-color: #fff;
overflow-y: auto;
box-shadow: 3px 0 4px 0 rgba(214, 224, 240, 0.3);
position: absolute;
top: 64px;
bottom: 0;
padding: 0 0 20px 0;
}
.tab-left-list-cell {
position: relative;
margin-top: 15px;
height: 30px;
font-size: 14px;
color: #303133;
text-align: left;
line-height: 30px;
white-space: nowrap;
overflow: hidden;
cursor: pointer;
.iconActive {
color: #2f54ed;
}
&:hover {
color: #606266;
background: rgba(24, 144, 255, 0.06);
i {
color: #2f54ed;
}
}
&.active-tab {
color: #606266;
background: rgba(24, 144, 255, 0.06);
&::before {
content: ' ';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 2px;
background: #2f54ed;
z-index: 1;
}
i {
color: #2f54ed;
}
}
.my-icon {
font-size: 17px;
color: #000;
padding-right: 8px;
width: 25px;
display: inline-block;
box-sizing: border-box;
}
}
.child-tab-left-list {
-webkit-transition: all 0.5s ease-in-out;
-o-transition: all 0.5s ease-in-out;
-moz-transition: all 0.5s ease-in-out;
transition: all 0.5s ease-in-out;
li {
position: relative;
text-align: left;
height: 30px;
line-height: 30px;
white-space: nowrap;
overflow: hidden;
cursor: pointer;
&:hover {
background: rgba(24, 144, 255, 0.06);
i {
color: #2f54ed;
}
}
&.active-tab {
background: rgba(24, 144, 255, 0.06);
&::before {
content: ' ';
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 2px;
background: #2f54ed;
z-index: 1;
}
i {
color: #2f54ed;
}
}
}
}
}
.p-l-14 {
padding-left: 14px;
}
.p-l-40 {
padding-left: 40px;
}
.p-l-60 {
padding-left: 60px;
}
</style>
<template>
<div id="breadcrumb">
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item v-for="item in navData" :key="item" :to="item.path ? { path: item.path } : null">{{ item.name }}</el-breadcrumb-item>
</el-breadcrumb>
<slot name="button"></slot>
</div>
</template>
<script>
export default {
props: {
navData: {
type: Array,
default() {
return [
{ name: '首页', path: '/' }
];
}
}
},
data() {
return {
};
}
};
</script>
<style lang="scss" scoped>
@import '@/styles/colors.scss';
#breadcrumb {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 20px solid $gray-background;
padding: 10px 20px;
}
</style>
\ No newline at end of file
<template>
<router-view/>
</template>
<script>
export default {
name: 'ModuleView'
};
</script>
<template>
<el-tabs :value="value" @tab-click="linkTo">
<el-tab-pane v-for="i in data" :key="i.name" :label="i.label" :name="i.name"></el-tab-pane>
</el-tabs>
</template>
<script>
export default {
name: 'PageTabs',
props: {
value: [ String, Number ], // name
data: Array, // [{ name: '', label: '', path: '' }]
},
methods: {
linkTo(ref) {
let { name } = ref || {};
let { path } = this.data.find(el => el.name == name) || {};
path && this.$router.push({ path });
},
},
};
</script>
<style>
</style>
<template>
<div class="header">
<a :href="index" class="logo">
<img src="../images/logo.png" alt="" />
<span>短信管理</span>
</a>
<yw-user-info :user-data="userInfo"></yw-user-info>
</div>
</template>
<script>
import { origin } from '@/config';
import fetch from '@/api/operation.js';
const { getUserInfo } = fetch;
export default {
name: 'YwHeader',
data() {
return {
userInfo: {
realName: '',
sex: '',
employeeNumber: '',
userMobile: '',
position: '',
},
showUserInfo: false,
index: origin + '/operation-platform/#/index'
};
},
mounted() {
this.getUserInfo();
},
methods: {
// 获取用户信息
getUserInfo() {
getUserInfo().then(res => {
let result = res?.result || {};
this.userInfo = Object.assign({}, this.userInfo, result);
this.$emit('updateAsideMenu', result?.menuTree || []);
this.$emit('set-global-data', { key: 'userInfo', data: result });
});
},
}
};
</script>
<style lang="less" scoped>
.header {
position: fixed;
top: 0;
right: 0;
left: 0;
// z-index: 20;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 45px;
width: 100%;
min-width: 1400px;
height: 64px;
background: #fff;
box-shadow: 0px 3px 4px 0px rgba(214, 224, 240, 0.3);
.logo {
display: flex;
align-items: center;
cursor: pointer;
img {
margin-right: 10px;
width: 30px;
height: 30px;
}
span {
padding-top: 2px;
font-size: 16px;
color: #303133;
}
}
}
</style>
function getOrigin() {
let origin = window.location.origin;
if (origin.indexOf('localhost') >= 0 || origin.indexOf('172.16') >= 0) {
origin = 'https://www.gicdev.com';
}
return origin;
}
export const origin = getOrigin();
// 请求成功的code
export const succCode = '0';
// 未登录、登录超时code
export const notAuthCode = '4002';
// 后端请求拦截的标识,用于区分是ajax请求还是页面跳转
export const isRequest = { isControl: true };
\ No newline at end of file
const formatMoney = (v, len, split) => {
if (!v) return '0.00';
split = split || ',', len = Math.abs((+len) % 20 || 2);
v = parseFloat((v + '').replace(/[^\d\.-]/g, '')).toFixed(len) + '';
return v.replace(/\d+/, function(v) {
let lit = v.length % 3 == 0;
let index = lit ? v.length - 3 : -1;
return v.split('').reverse().join('').replace(/\d{3}/g, function(k, l) {
return k + ((l == index && lit) ? '' : split);
}).split('').reverse().join('');
});
};
const formatDate = (val, format) => {
if (!val) return '--';
val = new Date(val);
let y = val.getFullYear();
let m = (val.getMonth() + 1).toString().padStart(2, '0');
let d = val.getDate().toString().padStart(2, '0');
let h = val.getHours().toString().padStart(2, '0');
let mm = val.getMinutes().toString().padStart(2, '0');
let s = val.getSeconds().toString().padStart(2, '0');
if (format == 'ymd') {
return y + '-' + m + '-' + d;
} else if (format == 'hms') {
return h + ':' + mm + ':' + s;
}
return `${y}-${m}-${d} ${h}:${mm}:${s}`;
};
// 时间戳转换成年月日
const getTime = (time) => {
if (!isNaN(time)) time = Number(time);
let now = new Date(time);
let year = now.getFullYear();
let month = now.getMonth() + 1;
month = month >= 10 ? month : '0' + month; // 判断小于10月份的情况
let date = now.getDate();
date = date >= 10 ? date : '0' + date; // 判断小于10日的情况
return year + '-' + month + '-' + date;
};
// 时间戳转换成时分秒
const getSeconds = (time) => {
if (!isNaN(time)) time = Number(time);
let now = new Date(time);
let hour = now.getHours();
hour = hour >= 10 ? hour : '0' + hour; // 判断小于10的时的情况
let minute = now.getMinutes();
minute = minute >= 10 ? minute : '0' + minute; // 判断小于10的分的情况
let second = now.getSeconds();
second = second >= 10 ? second : '0' + second; // 判断小于10的秒的情况
return hour + ':' + minute + ':' + second;
};
// 时间戳转换成时分
const getSeconds2 = (time) => {
if (!isNaN(time)) time = Number(time);
let now = new Date(time);
let hour = now.getHours();
hour = hour >= 10 ? hour : '0' + hour; // 判断小于10的时的情况
let minute = now.getMinutes();
minute = minute >= 10 ? minute : '0' + minute; // 判断小于10的分的情况
return hour + ':' + minute;
};
// 时间戳转换成年月日时分秒
const formatDate2 = (time) => {
if (!isNaN(time)) time = Number(time);
let now = new Date(time);
let year = now.getFullYear();
let month = now.getMonth() + 1;
month = month >= 10 ? month : '0' + month; // 判断小于10月份的情况
let date = now.getDate();
date = date >= 10 ? date : '0' + date; // 判断小于10日的情况
let hour = now.getHours();
hour = hour >= 10 ? hour : '0' + hour; // 判断小于10的时的情况
let minute = now.getMinutes();
minute = minute >= 10 ? minute : '0' + minute; // 判断小于10的分的情况
let second = now.getSeconds();
second = second >= 10 ? second : '0' + second; // 判断小于10的秒的情况
return year + '-' + month + '-' + date + ' ' + hour + ':' + minute + ':' + second;
};
export default {
formatMoney,
formatDate,
getTime,
getSeconds,
getSeconds2,
formatDate2
};
/* Logo 字体 */
@font-face {
font-family: "iconfont logo";
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
}
.logo {
font-family: "iconfont logo";
font-size: 160px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* tabs */
.nav-tabs {
position: relative;
}
.nav-tabs .nav-more {
position: absolute;
right: 0;
bottom: 0;
height: 42px;
line-height: 42px;
color: #666;
}
#tabs {
border-bottom: 1px solid #eee;
}
#tabs li {
cursor: pointer;
width: 100px;
height: 40px;
line-height: 40px;
text-align: center;
font-size: 16px;
border-bottom: 2px solid transparent;
position: relative;
z-index: 1;
margin-bottom: -1px;
color: #666;
}
#tabs .active {
border-bottom-color: #f00;
color: #222;
}
.tab-container .content {
display: none;
}
/* 页面布局 */
.main {
padding: 30px 100px;
width: 960px;
margin: 0 auto;
}
.main .logo {
color: #333;
text-align: left;
margin-bottom: 30px;
line-height: 1;
height: 110px;
margin-top: -50px;
overflow: hidden;
*zoom: 1;
}
.main .logo a {
font-size: 160px;
color: #333;
}
.helps {
margin-top: 40px;
}
.helps pre {
padding: 20px;
margin: 10px 0;
border: solid 1px #e7e1cd;
background-color: #fffdef;
overflow: auto;
}
.icon_lists {
width: 100% !important;
overflow: hidden;
*zoom: 1;
}
.icon_lists li {
width: 100px;
margin-bottom: 10px;
margin-right: 20px;
text-align: center;
list-style: none !important;
cursor: default;
}
.icon_lists li .code-name {
line-height: 1.2;
}
.icon_lists .icon {
display: block;
height: 100px;
line-height: 100px;
font-size: 42px;
margin: 10px auto;
color: #333;
-webkit-transition: font-size 0.25s linear, width 0.25s linear;
-moz-transition: font-size 0.25s linear, width 0.25s linear;
transition: font-size 0.25s linear, width 0.25s linear;
}
.icon_lists .icon:hover {
font-size: 100px;
}
.icon_lists .svg-icon {
/* 通过设置 font-size 来改变图标大小 */
width: 1em;
/* 图标和文字相邻时,垂直对齐 */
vertical-align: -0.15em;
/* 通过设置 color 来改变 SVG 的颜色/fill */
fill: currentColor;
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
normalize.css 中也包含这行 */
overflow: hidden;
}
.icon_lists li .name,
.icon_lists li .code-name {
color: #666;
}
/* markdown 样式 */
.markdown {
color: #666;
font-size: 14px;
line-height: 1.8;
}
.highlight {
line-height: 1.5;
}
.markdown img {
vertical-align: middle;
max-width: 100%;
}
.markdown h1 {
color: #404040;
font-weight: 500;
line-height: 40px;
margin-bottom: 24px;
}
.markdown h2,
.markdown h3,
.markdown h4,
.markdown h5,
.markdown h6 {
color: #404040;
margin: 1.6em 0 0.6em 0;
font-weight: 500;
clear: both;
}
.markdown h1 {
font-size: 28px;
}
.markdown h2 {
font-size: 22px;
}
.markdown h3 {
font-size: 16px;
}
.markdown h4 {
font-size: 14px;
}
.markdown h5 {
font-size: 12px;
}
.markdown h6 {
font-size: 12px;
}
.markdown hr {
height: 1px;
border: 0;
background: #e9e9e9;
margin: 16px 0;
clear: both;
}
.markdown p {
margin: 1em 0;
}
.markdown>p,
.markdown>blockquote,
.markdown>.highlight,
.markdown>ol,
.markdown>ul {
width: 80%;
}
.markdown ul>li {
list-style: circle;
}
.markdown>ul li,
.markdown blockquote ul>li {
margin-left: 20px;
padding-left: 4px;
}
.markdown>ul li p,
.markdown>ol li p {
margin: 0.6em 0;
}
.markdown ol>li {
list-style: decimal;
}
.markdown>ol li,
.markdown blockquote ol>li {
margin-left: 20px;
padding-left: 4px;
}
.markdown code {
margin: 0 3px;
padding: 0 5px;
background: #eee;
border-radius: 3px;
}
.markdown strong,
.markdown b {
font-weight: 600;
}
.markdown>table {
border-collapse: collapse;
border-spacing: 0px;
empty-cells: show;
border: 1px solid #e9e9e9;
width: 95%;
margin-bottom: 24px;
}
.markdown>table th {
white-space: nowrap;
color: #333;
font-weight: 600;
}
.markdown>table th,
.markdown>table td {
border: 1px solid #e9e9e9;
padding: 8px 16px;
text-align: left;
}
.markdown>table th {
background: #F7F7F7;
}
.markdown blockquote {
font-size: 90%;
color: #999;
border-left: 4px solid #e9e9e9;
padding-left: 0.8em;
margin: 1em 0;
}
.markdown blockquote p {
margin: 0;
}
.markdown .anchor {
opacity: 0;
transition: opacity 0.3s ease;
margin-left: 8px;
}
.markdown .waiting {
color: #ccc;
}
.markdown h1:hover .anchor,
.markdown h2:hover .anchor,
.markdown h3:hover .anchor,
.markdown h4:hover .anchor,
.markdown h5:hover .anchor,
.markdown h6:hover .anchor {
opacity: 1;
display: inline-block;
}
.markdown>br,
.markdown>p>br {
clear: both;
}
.hljs {
display: block;
background: white;
padding: 0.5em;
color: #333333;
overflow-x: auto;
}
.hljs-comment,
.hljs-meta {
color: #969896;
}
.hljs-string,
.hljs-variable,
.hljs-template-variable,
.hljs-strong,
.hljs-emphasis,
.hljs-quote {
color: #df5000;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-type {
color: #a71d5d;
}
.hljs-literal,
.hljs-symbol,
.hljs-bullet,
.hljs-attribute {
color: #0086b3;
}
.hljs-section,
.hljs-name {
color: #63a35c;
}
.hljs-tag {
color: #333333;
}
.hljs-title,
.hljs-attr,
.hljs-selector-id,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #795da3;
}
.hljs-addition {
color: #55a532;
background-color: #eaffea;
}
.hljs-deletion {
color: #bd2c00;
background-color: #ffecec;
}
.hljs-link {
text-decoration: underline;
}
/* 代码高亮 */
/* PrismJS 1.15.0
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection,
pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection,
code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection,
pre[class*="language-"] ::selection,
code[class*="language-"]::selection,
code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre)>code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre)>code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #9a6e3a;
background: hsla(0, 0%, 100%, .5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function,
.token.class-name {
color: #DD4A68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
<template>
<div class="layout">
<yw-header @updateAsideMenu="updateAsideMenu" @set-global-data="setGlobalData"></yw-header>
<div class="bottomBox">
<aside-menu :menu="menu"></aside-menu>
<main class="main">
<div class="breadcrumb" v-show="breadcrumbList.length">
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item v-for="item in breadcrumbList" :key="item" :to="item.path ? { path: item.path } : null">{{ item.name }}</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="content" :class="{ noBread: !breadcrumbList.length }">
<router-view class="routerCon" @getBread="getBread" />
</div>
</main>
</div>
</div>
</template>
<script>
import ywHeader from '@/components/yw-header.vue';
import asideMenu from '@/components/aside-menu.vue';
export default {
name: 'Layout',
components: {
ywHeader,
asideMenu,
},
provide() {
return {
globalData: this.globalData,
};
},
data() {
return {
menu: [],
breadcrumbList: [],
globalData: {},
};
},
methods: {
updateAsideMenu(menu) {
this.menu = menu || [];
},
getBread(val) {
this.breadcrumbList = val || [];
},
setGlobalData(data) {
this.$set(this.globalData, data.key, data.data);
},
}
};
</script>
<style lang="scss" scoped>
.layout {
min-width: 1400px;
height: 100vh;
}
.bottomBox {
padding: 20px;
height: 100%;
}
.main {
position: relative;
top: 64px;
left: 210px;
right: 0;
bottom: 0;
z-index: 1;
width: calc(100% - 210px);
height: calc(100% - 64px);
}
.breadcrumb {
display: flex;
align-items: center;
padding-left: 20px;
height: 50px;
background-color: #fff;
box-shadow: 0px 3px 4px 0px rgba(214, 224, 240, 0.3);
border-bottom: 1px solid #E6E7EB;
}
.content {
height: calc(100% - 50px);
// overflow-y: auto;
.routerCon {
min-height: 100%;
background-color: #fff;
margin: 0 0 20px 0;
}
}
.noBread {
height: 100%;
}
</style>
import '@/styles/reset.less';
import '@/styles/component.less';
// import './images/font-icon/iconfont.css';
// import './images/font-icon/iconfont.js';
import axios from 'axios';
import Vue from 'vue';
import App from './App.vue';
import router from './router';
import { isRequest } from '@/config';
import filters from '@/filters';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
// 请求头这种添加请求标识
Vue.use(ElementUI);
// 复制粘贴
import VueClipboard from 'vue-clipboard2';
Vue.use(VueClipboard);
axios.defaults.headers.common = Object.assign(axios.defaults.headers.common, isRequest);
axios.defaults.withCredentials = true;
Vue.config.productionTip = false;
Vue.prototype.axios = axios;
// 开启vue devtools.....
/* eslint-disable-next-line */
Vue.config.devtools = process.env.NODE_ENV !== 'production';
// 全局引入filter
Object.keys(filters).forEach(item => Vue.filter(item, filters[item]));
new Vue({
router,
render: h => h(App)
}).$mount('#app');
// eslint-disable-next-line
module.exports = (parantfile, file) => {
return () => import('@/views/' + parantfile + '/' + file + '.vue');
};
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
import { routes } from './routes.js';
// import Layout from '@/layout/layout';
export const staticRoutes = [
{
path: '*',
component: () => import('@/views/404.vue')
}
];
export const asyncRoutes = [
...routes
];
const router = new VueRouter({
// mode: 'history',
// base: '/gic-operation/',
routes: [ ...staticRoutes, ...asyncRoutes ]
});
export default router;
import Layout from '@/layout/layout.vue';
import _import from './import';
export const routes = [
{
path: '/',
name: '短信管理',
redirect: '/messageTemplate',
component: Layout,
children: [
{
path: '/messageTemplate',
name: '短信模板管理',
component: _import('message', 'index')
},
{
path: '/messagePass',
name: '短信通道管理',
},
]
}
];
// selected background color
@blue-selected: #f0f5ff;
// hover
@blue-hover: #597ef7;
// click
@blue-click: #1d39c4;
// normal、link、brand color
@blue: #2f54ed;
// success
@green-success: #52c41a;
// warning
@yellow-warning: #faad14;
// success
@red-error: #f5222d;
// 标题文字
@gray01: #303133;
// 常规信息、按钮文字
@gray02: #606266;
// 内容文字、说明文字
@gray03: #909399;
// 输入框说明文字
@gray-placeholder: #c0c4cc;
// 线框、输入框、下拉框的边框颜色
@gray-border: #c4c6cf;
// tab选项卡、表格单元格底部分割线
@gray-tab: #dcdfe6;
// 表头背景色
@gray-thead: #ebecf0;
// 分割线的颜色
@gray-separator: #e4e7ed;
// 背景底色
@gray-background: #f0f2f5;
// 输入框禁止输入的颜色
@gray-disable: #f5f7fa;
.damolish {
.el-table .cell,
.el-table th div,
.el-table--border td:first-child .cell,
.el-table--border th:first-child .cell {
padding-left: 10px;
}
}
.right_content {
padding: 10px;
}
.mr10 {
margin-right: 10px;
}
.ml10 {
margin-left: 10px;
}
.mt10 {
margin-top: 10px;
}
.mb10 {
margin-bottom: 10px;
}
\ No newline at end of file
/**
* Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/)
* http://cssreset.com
*/
@import "./colors.less";
html,
body,
div,
span,
applet,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video,
input {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font-weight: normal;
vertical-align: baseline;
box-sizing: border-box;
}
/* HTML5 display-role reset for older browsers */
article,
aside,
details,
figcaption,
figure,
footer,
header,
menu,
nav,
section {
display: block;
}
body {
line-height: 1;
}
blockquote,
q {
quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
/* custom */
a {
color: inherit;
text-decoration: none;
-webkit-backface-visibility: hidden;
}
li {
list-style: none;
}
input::-webkit-input-placeholder{
color: @gray-placeholder;
}
input:-ms-input-placeholder{
color: @gray-placeholder;
}
input::-moz-placeholder{
color: @gray-placeholder;
}
::-webkit-scrollbar {
width: 5px;
height: 5px;
-webkit-border-radius: 6px;
border-radius: 6px;
}
::-webkit-scrollbar-track {
-webkit-border-radius: 6px;
border-radius: 6px;
}
::-webkit-scrollbar-track-piece {
/*background-color: rgba(0, 0, 0, 0.2);
-webkit-border-radius: 6px;*/
}
::-webkit-scrollbar-thumb {
-webkit-border-radius: 6px;
border-radius: 6px;
background-color: rgba(0, 0, 0, 0.1)
}
@-moz-document url-prefix(http: //),url-prefix(https://) {
/* 滚动条颜色 */
scrollbar {
-moz-appearance: none !important;
width: 5px;
height: 5px;
-webkit-border-radius: 6px;
border-radius: 6px;
}
/* 滚动条按钮颜色 */
thumb, scrollbarbutton {
-moz-appearance: none !important;
}
/* 鼠标悬停时按钮颜色 */
thumb:hover, scrollbarbutton:hover {
-moz-appearance: none !important;
}
/* 隐藏上下箭头 */
scrollbarbutton {
display: none !important;
}
/* 纵向滚动条宽度 */
scrollbar[orient="vertical"] {
/*min-width: 15px !important;*/
}
}
scrollbar {
/* clear useragent default style*/
-moz-appearance: none !important;
}
/* buttons at two ends */
scrollbarbutton {
-moz-appearance: none !important;
}
/* the sliding part*/
thumb {
-moz-appearance: none !important;
}
scrollcorner {
-moz-appearance: none !important;
resize: both;
}
/* vertical or horizontal */
scrollbar[orient="vertical"] {
color: silver;
}
-moz-scrollbar-track {
width: 5px;
border: none;
background: #ff0000;
}
-moz-scrollbar-face {
width: 5px;
border: none;
background: #ff0000;
}
-moz-scrollbar-arrow {
width: 5px;
border: none;
background: #ff0000;
}
-moz-scrollbar {
-moz-scrollbar-width: 15px;
-moz-scrollbar-border: 1px solid black;
-moz-scrollbar-background-color: white;
-moz-scrollbar-track-background-color: silver;
-moz-scrollbar-arrow-background-color: silver;
-moz-scrollbar-arrow-color: blue;
}
/*::-webkit-scrollbar-button {
color: #c8cbd3;
}*/
html, body {
width: 100%;
height: 100%;
background-color: @gray-background;
font-size: 14px;
font-family: "Helvetica Neue", "Helvetica", "PingFang SC", "Hiragino Sans GB","Microsoft YaHei", "微软雅黑", Arial, sans-serif;
}
body {
-webkit-text-size-adjust: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
input:focus {
box-shadow: none;
outline: none;
}
.el-breadcrumb__inner a:hover,
.el-breadcrumb__inner.is-link:hover{
color: #2f54ed !important;
}
.damolish .el-step__head.is-finish{
color: #2f54ed;
border-color: #2f54ed;
}
.damolish .el-step__title.is-finish{
color: #2f54ed;
}
.damolish .el-step__description.is-finish{
color: #2f54ed;
}
\ No newline at end of file
const TokenKey = 'Admin-Token';
export function getToken() {
return localStorage.getItem(TokenKey);
}
export function setToken(token) {
return localStorage.setItem(TokenKey, token);
}
export function removeToken() {
return localStorage.removeItem(TokenKey);
}
import Vue from 'vue';
import Clipboard from 'clipboard';
function clipboardSuccess() {
Vue.prototype.$message({
message: 'Copy successfully',
type: 'success',
duration: 1500
});
}
function clipboardError() {
Vue.prototype.$message({
message: 'Copy failed',
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);
}
import axios from 'axios';
import qs from 'qs';
import { Message } from 'element-ui';
import { origin } from '@/config/index.js';
axios.defaults.baseURL = origin;
const request = (opt, params) => {
params = Object.assign({}, params);
opt = Object.assign({}, opt);
let requestConfig = {
// 请求路径
url: '',
params: '',
data: '',
// 请求type
method: 'get',
// request body 是否使用 formData格式
useFormData: false,
// response 是否使用 code === '0000' 验证
useIntercept: true,
// 设置headers
headers: {}
};
requestConfig = Object.assign(requestConfig, opt);
if (requestConfig.useFormData) params = qs.stringify(params);
switch (requestConfig.method.toLowerCase()) {
case 'get':
requestConfig.params = params;
break;
case 'post':
requestConfig.data = qs.stringify(params);
break;
default:
requestConfig.data = params;
break;
}
return new Promise((resolve, reject) => {
axios(requestConfig).then(res => {
let resp = res.data;
if (resp.errorCode != 0) {
Message({
message: resp.message || '未知错误',
type: 'warning'
});
return reject(resp);
}
resolve(resp);
}).catch(error => {
let response = error.response || {};
let data = response.data || {};
Message({
message: data.message || '网络连接异常',
type: 'warning'
});
reject(error);
});
});
};
export { axios, request };
<template>
<div class="not-found">您访问的页面被外星人带走啦...</div>
</template>
<script>
export default {
name: '404'
};
</script>
<style lang="scss" scoped>
.not-found {
display: flex;
justify-content: center;
align-items: center;
padding-bottom: 10vh;
width: 100vw;
height: 100vh;
background-color: #eee;
}
</style>
<template>
<div class="container right_content">
<div class="search">
<el-input v-model="searchText" prefix-icon="el-icon-search" placeholder="请输入品牌名称/公司名称" style="width: 234px" />
<el-select v-model="mode" placeholder="选择发送模式" class="ml10">
<el-option v-for="(item, index) in passList" :key="index" :value="item.value">{{ item.label }}</el-option>
</el-select>
</div>
<el-table :data="tableData.data" element-loading-text="拼命加载中">
<el-table-column v-for="(v, i) in tableData.tableHeader" :key="i" :prop="v.prop" :min-width="v.minWidth" :label="v.label" :formatter="v.formatter" :fixed="v.fixed" show-overflow-tooltip>
<template slot-scope="scope">
<span v-if="v.formatter" v-html="v.formatter(scope.row)"></span>
<span v-else>{{ scope.row[v.prop] || '--' }}</span>
</template>
</el-table-column>
<el-table-column label="操作">
<template slot-scope="{ row }">
<el-button type="text" @click="toDetail(row)">详情</el-button>
</template>
</el-table-column>
</el-table>
<dm-pagination background class="dm-pagination" @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="tableData.currentPage" :page-sizes="tableData.pageSizeList" :page-size="tableData.pageSize" layout="total, sizes, prev, pager, next" :total="tableData.total" hide-on-single-page />
</div>
</template>
<script>
export default {
data() {
return {
passList: [
{
label: '多通道',
value: 1
},
{
label: '腾讯云',
value: 2
},
{
label: '大汉三通',
value: 3
}
],
search: {
searchText: '',
mode: 0
},
tableData: {
data: [],
currentPage: 1,
pageSizeList: [ 20, 40, 60, 80 ],
pageSize: 20,
tableHeader: [],
total: 0
}
};
},
created() {
this.getTableHeader();
},
methods: {
// table methods
getTableHeader() {
this.tableData.tableHeader = [
{ label: '手机号', prop: 'phoneNumber' },
{ label: '黑名单原因', prop: 'reason' },
{ label: '操作人', prop: 'creatorName' }
];
},
async getTableData() {
// const { currentPage, pageSize } = this.tableData;
// const { phone, time } = this.search;
// const para = {
// currentPage,
// pageSize,
// phoneNumber: phone,
// startTime: new Date(time[0]).getTime() || '',
// endTime: new Date(time[1]).getTime() || ''
// };
// const result = await getBlackList(para);
// this.tableData.data = result.result.result || [];
// this.tableData.total = result.result.totalCount || 0;
},
handleSizeChange(val) {
this.tableData.pageSize = val;
this.tableData.currentPage = 1;
this.getTableData();
},
handleCurrentChange(val) {
this.tableData.currentPage = val;
this.getTableData();
},
toDetail(row) {
console.log(row);
}
}
};
</script>
<style scoped lang="scss"></style>
<template>
<div class="no-access">
<p>Sorry,您无该页面的访问权限,请联系超级管理员!</p>
</div>
</template>
<script>
export default {
name: 'NoAccess'
};
</script>
<style lang="scss" scoped>
.no-access {
display: flex;
justify-content: center;
align-items: center;
padding-bottom: 10vh;
width: 100vw;
height: 100vh;
font-size: 16px;
background-color: #eee;
}
</style>
const path = require("path");
module.exports = {
productionSourceMap: process.env.NODE_ENV !== 'production',
publicPath: process.env.NODE_ENV === 'production' ? '/goods-operation' : '/',
devServer: {
overlay: {
warnings: true,
errors: true
},
},
configureWebpack: config => {
config.externals = {
vue: 'Vue',
// 'vue-router': 'VueRouter',
// vuex: 'Vuex',
// axios: 'axios',
// 'element-ui': 'ELEMENT',
// BMap: 'BMap'
};
if (process.env.NODE_ENV === 'production') {
config.optimization.minimizer[0].options.terserOptions.compress.warnings = false;
config.optimization.minimizer[0].options.terserOptions.compress.drop_console = true;
config.optimization.minimizer[0].options.terserOptions.compress.drop_debugger = true;
config.optimization.minimizer[0].options.terserOptions.compress.pure_funcs = [
'console.log'
];
}
}
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment