Commit 6f677b4c authored by lvweichao's avatar lvweichao

feat: project init

parents
.DS_Store
node_modules
*.lock
package-lock.json
*.log
dist
./package.json
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
\ No newline at end of file
商户系统
\ No newline at end of file
module.exports = {
root: true,
env: {
node: true,
},
extends: ['plugin:vue/vue3-essential', 'eslint:recommended', '@vue/prettier'],
parserOptions: {
parser: 'babel-eslint',
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
},
overrides: [
{
files: [
'**/__tests__/*.{j,t}s?(x)',
'**/tests/unit/**/*.spec.{j,t}s?(x)',
],
env: {
jest: true,
},
},
],
};
module.exports = {
presets: ['@vue/cli-plugin-babel/preset'],
};
{
"name": "op-management",
"version": "0.1.0",
"private": true,
"scripts": {
"start": "vue-cli-service serve",
"build": "vue-cli-service build",
"test:unit": "vue-cli-service test:unit",
"lint": "vue-cli-service lint"
},
"dependencies": {
"axios": "^0.21.1",
"core-js": "^3.6.5",
"element-plus": "^1.0.2-beta.44",
"vue": "^3.0.0",
"vue-router": "^4.0.0-beta.12",
"vuex": "^4.0.0-beta.4"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^4.5.6",
"@vue/cli-plugin-eslint": "^4.5.6",
"@vue/cli-plugin-unit-jest": "^4.5.6",
"@vue/cli-service": "^4.5.6",
"@vue/compiler-sfc": "^3.0.0-beta.1",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/test-utils": "^2.0.0-alpha.1",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-vue": "^7.0.0-alpha.0",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"prettier": "^1.19.1"
},
"browserslist": [
"> 1%",
"last 10 versions",
"not ie <= 8",
"iOS >= 8",
"Android >= 4.1"
],
"license": "YIDIAN"
}
<!DOCTYPE html>
<html lang="en">
<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="https://static.yidianzixun.com/img/faviconred.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled.
Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
</body>
</html>
<template>
<div id="app">
<layout>
<router-view />
</layout>
</div>
</template>
<script>
// Layout 为布局组件,控制页面基础布局,通过 slot 实现
import Layout from '@/layouts';
export default {
components: {
Layout,
},
};
</script>
<style lang="less" src="./global.less"></style>
<template>
<div class="page-footer"></div>
</template>
<script>
export default {};
</script>
<style></style>
const headerConfig = {
appName: 'OP运营管理后台',
logo: 'http://si1.go2yd.com/get-image/0ZAJxXeZ6iu',
menuItems: [
{
path: '/home',
name: '首页',
},
{
path: '/about',
name: '关于'
}
],
// miscellaneous: {
// // 配置当用户头像不存在时使用的fallback头像图URL
// defaultAvatar: '//s.go2yd.com/a/thead_meiguoduizhang.png',
// },
};
export default headerConfig;
\ No newline at end of file
<template>
<div>
<div class="line"></div>
<el-menu
class="el-menu-demo"
mode="horizontal"
router=true
@select="handleSelect"
background-color="#545c64"
text-color="#fff"
:default-active="activeMenu"
active-text-color="#ffd04b"
>
<el-menu-item
v-for="item in menuItems"
:index="item.path"
:key="item.path"
@select="() => handleSelect(item.path)"
>
{{ item.name }}
<!-- <router-link :to="item.path" class="menu-router">{{ item.name }}</router-link> -->
</el-menu-item>
</el-menu>
</div>
</template>
<script>
import headerConfig from "./config";
const { menuItems } = headerConfig;
export default {
name: "PageHeader",
data() {
return {
menuItems,
activeMenu: "",
basicPath: "/app/op-management",
};
},
methods: {
handleSelect(path) {
this.activeMenu = path;
},
},
};
</script>
<style lang="less">
.menu-router {
display: inline-block;
line-height: 60px;
width: 100%;
}
</style>
const currEnv = "prod"
const API_URI = {
'dev': "XXX",
'test': "XXX",
'prod': "XXX"
}
export default {
API_URI: API_URI[currEnv]
}
\ No newline at end of file
@import './styles/reset.less';
@import './styles/loading.less';
html,
body,
#root,
#app {
height: 100%;
}
body {
margin: 0;
}
.layout {
display: flex;
flex-direction: column;
height: 100%;
}
.main {
flex: 1;
}
<template>
<div class="layout">
<!-- 页面公共 header -->
<page-header class="page-header"></page-header>
<!-- 页面主体部分 -->
<div class="main">
<slot></slot>
</div>
<!-- 页面公共 footer -->
<page-footer class="page-footer"></page-footer>
</div>
</template>
<script>
import PageHeader from '@/components/PageHeader';
import PageFooter from '@/components/PageFooter';
export default {
components: {
PageHeader,
PageFooter,
},
};
</script>
<style lang="less" src="./index.less"></style>
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import ElementPlus from 'element-plus';
// import './assets/styles/index.scss';
import 'element-plus/lib/theme-chalk/index.css';
import 'dayjs/locale/zh-cn';
import locale from 'element-plus/lib/locale/lang/zh-cn';
createApp(App)
.use(router)
.use(store)
.use(ElementPlus, { locale })
.mount('#app');
<template>
<div class="page-about">
<ul class="doc-list">
<li>
<a href="https://v3.vuejs.org/guide/introduction.html" target="_blank"
>Vue3 使用指南</a
>
</li>
<li>
<a
href="https://next.router.vuejs.org/guide/migration/#new-features"
target="_blank"
>Vue Router for Vue3</a
>
</li>
<li>
<a
href="https://github.com/vuejs/vuex/tree/4.0#breaking-changes"
target="_blank"
>
Vuex for Vue3</a
>
</li>
</ul>
<h3><router-link to="/">返回首页</router-link></h3>
</div>
</template>
<style lang="less">
.page-about {
padding-top: 100px;
text-align: center;
h1,
h2,
h3 {
margin-bottom: 20px;
color: #333;
font-size: 20px;
}
a {
color: #42b983;
font-size: 20px;
text-decoration: underline;
&:hover {
opacity: 0.8;
}
}
.doc-list {
margin: 30px 0;
}
}
</style>
// 示例样式
.page-home {
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-size: cover;
color: #fff;
.logo {
width: 60px;
height: 60px;
}
.title {
margin-top: 10px;
font-size: 22px;
}
.desp {
margin: 10px 5% 0;
}
a {
color: #fff;
text-decoration: underline;
}
}
<template>
<div class="page-home">
home
</div>
</template>
<script>
export default {};
</script>
<style lang="less" src="./index.less">
// 样式可以内联,也可以通过 src 引入
</style>
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../pages/Home';
const routes = [
{
path: '/',
name: 'Home',
component: Home,
},
{
path: '/about',
name: 'About',
component: () => import(/* webpackChunkName: "about" */ '../pages/About'),
},
];
const router = createRouter({
history: createWebHistory('/app/op-management'),
routes,
});
export default router;
import Vuex from 'vuex';
export default Vuex.createStore({
state: {},
mutations: {},
actions: {},
modules: {},
});
#loading {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
background-color: #fff;
z-index: 1000;
}
#loading,
#loading:after {
background-position: 50%;
background-repeat: no-repeat;
}
#loading:after {
content: '';
display: block;
background-image: url(//si1.go2yd.com/get-image/0fOxKQtpE80);
position: fixed;
background-repeat: no-repeat;
z-index: 1001;
left: 50%;
top: 50%;
height: 28px;
width: 140px;
margin-left: -70px;
margin-top: -25px;
background-size: 100% 100%;
}
.yidian-night #loading {
background-color: #333;
}
.yidian-night #loading:after {
background-image: url(//si1.go2yd.com/get-image/0fOxY9asGmm);
}
body,
div,
span,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
a,
code,
em,
img,
q,
small,
strong,
dd,
dl,
dt,
li,
ol,
ul,
fieldset,
form,
label,
table,
tbody,
tr,
th,
td,
input {
margin: 0;
padding: 0;
border: 0;
}
* {
box-sizing: border-box;
}
html,
body {
-webkit-font-smoothing: antialiased;
}
html {
font-size: 100%;
}
body {
font-size: 100%;
line-height: 1.5;
margin: 0 auto;
font-family: 'Helvetica Neue', Helvetica, 'PingFang SC', 'Hiragino Sans GB',
'Microsoft YaHei', '微软雅黑', Arial, sans-serif;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
a,
a:active,
a:hover,
a:focus,
a:visited {
text-decoration: none;
}
a,
img {
-webkit-touch-callout: none;
}
img {
border: 0;
}
ol,
ul,
li {
list-style: none;
}
input:focus,
textarea:focus,
button {
outline: none;
}
input,
textarea {
-webkit-appearance: none;
}
/**
* axios封装
*/
import axios from 'axios';
import { ElMessage } from 'element-plus';
import { setToken, formatDate } from '/@/libs/utils';
import { APP_URI } from '../config/app.config';
import config from '/@/config';
import router from '/@/router';
import md5 from 'js-md5';
/**
* show error tip
* @param mgs
*/
const showErrorMessage = (mgs) => {
ElMessage({
message: mgs,
type: 'error',
showClose: true
});
};
/**
* default axios config
*/
export const defaultConfig = {
baseURL: APP_URI,
timeout: 10000
// baseURL: '/',
};
/**
* default params
* @returns {}
*/
const getDefaultParams = () => {};
const getDefaultHeaders = () => {};
/**
* axios instance
* @type {AxiosInstance}
*/
const instance = axios.create(defaultConfig);
/**
* axios instance interceptors
*/
instance.interceptors.request.use(
function (config) {
// network error
if (navigator.onLine !== undefined && navigator.onLine === false) {
return Promise.reject({ message: '网络未链接', code: -1 });
}
/**
* merge headers
*/
config.headers = {...getDefaultHeaders(), ...config.headers}
/**
* merge params
*/
config.params = { ...getDefaultParams(), ...config.params }
return config;
},
function (error) {
// handle error
return Promise.reject(error);
}
);
/**
* axios response instance
*/
instance.interceptors.response.use(
function (response) {
const { data = {} } = response;
const code = data.code ?? -1;
if (code !== 0) {
const msg = data.reason || '未定义错误';
showErrorMessage(data.reason);
return Promise.reject({ code, msg });
}
if (data.message) {
Message({
message: data.reason,
type: 'info',
showClose: true
});
}
return data;
},
function (error) {
if (!(error.code && error.code === -1)) error.message = '接口请求错误';
showErrorMessage(error.message);
return Promise.reject(error);
}
);
/**
* Get
* @param {*} url
* @param {*} params
*/
export const get = (url, params) => {
return instance.request({
url,
method: 'get',
params
});
};
/**
* Post
* @param {*} url
* @param {*} params
*/
export const post = (url, data) => {
return instance.request({
url,
method: 'post',
data
});
};
export default instance;
import { shallowMount } from '@vue/test-utils';
import HelloWorld from '@/components/HelloWorld.vue';
describe('HelloWorld.vue', () => {
it('renders props.msg when passed', () => {
const msg = 'new message';
const wrapper = shallowMount(HelloWorld, {
propsData: { msg },
});
expect(wrapper.text()).toMatch(msg);
});
});
{
"vue": true,
"name": "app-template-h5-vue3"
}
const path = require('path');
const isDev = process.env.NODE_ENV === 'development';
module.exports = {
outputDir: isDev
? './dist'
: path.resolve('../../../www/dist/app/op-management'),
publicPath: isDev ? '/app/op-management' : '/dist/app/op-management',
configureWebpack: {
devServer: {
proxy: {
'/api': {
target: 'http://dev.yidian-inc.com:4000',
changeOrigin: true,
},
},
},
},
chainWebpack: config => {
// 默认不开启 prefetch
config.plugins.delete('prefetch');
// 默认不开启 preload
config.plugins.delete('preload');
// 修改页面 title
config.plugin('html').tap(args => {
args[0].title = '运营管理系统';
return args;
});
},
};
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