clay : init()

This commit is contained in:
clay 2023-04-28 22:41:10 +08:00
parent 85d80ae56d
commit f386570d06
29 changed files with 14766 additions and 1 deletions

41
.drone.yml Normal file
View File

@ -0,0 +1,41 @@
kind: pipeline
type: docker
name: train_front
steps:
- name: build-vue
image: node:14.20
volumes:
- name: cache
path: /drone/src/node_modules
- name: build
path: /app/build
commands:
- npm -v
- mkdir -p ./node_modules
- export NODE_MODULES_PATH=`pwd`/node_modules
- set NODE_OPTIONS=--openssl-legacy-provider
- npm install --registry=https://registry.npm.taobao.org
- npm run build:prod
- rm -rf /app/build/$DRONE_COMMIT_BRANCH/dist
- cp -r dist /app/build/$DRONE_COMMIT_BRANCH/dist
- chmod 777 /app/build/$DRONE_COMMIT_BRANCH/dist
when:
branch:
- dev
- pro
volumes:
- name: build
host:
path: /www/wwwroot/bwc/bwc_web
- name: cache
host:
path: /home/cache
trigger:
branch:
- pro
- dev
event:
- push

22
.editorconfig Normal file
View File

@ -0,0 +1,22 @@
# 告诉EditorConfig插件这是根文件不用继续往上查找
root = true
# 匹配全部文件
[*]
# 设置字符集
charset = utf-8
# 缩进风格可选space、tab
indent_style = space
# 缩进的空格数
indent_size = 2
# 结尾换行符可选lf、cr、crlf
end_of_line = lf
# 在文件结尾插入新行
insert_final_newline = true
# 删除一行中的前后空格
trim_trailing_whitespace = true
# 匹配md结尾的文件
[*.md]
insert_final_newline = false
trim_trailing_whitespace = false

12
.env.development Normal file
View File

@ -0,0 +1,12 @@
# 开发环境配置
ENV = 'development'
# EBTS/开发环境
#VUE_APP_BASE_API = '/dev-api'
#VUE_APP_BASE_API = 'http://localhost:8085/dev-api'
#VUE_APP_BASE_API = '/dev-api'
SITE_TYPE = 'NEd5n92EMIpyyBslaNqsRgE'
VUE_APP_BASE_API = 'https://sist.swjtu.edu.cn/dev-api'
# 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true

6
.env.production Normal file
View File

@ -0,0 +1,6 @@
# 生产环境配置
ENV = 'production'
# EBTS/生产环境
#VUE_APP_BASE_API = '/prod-api'
VUE_APP_BASE_API = '/dev-api'

7
.env.staging Normal file
View File

@ -0,0 +1,7 @@
NODE_ENV = staging
# 测试环境配置
ENV = 'staging'
# EBTS/测试环境
VUE_APP_BASE_API = 'http://192.168.190.67/dev-api'

10
.eslintignore Normal file
View File

@ -0,0 +1,10 @@
# 忽略build目录下类型为js的文件的语法检查
build/*.js
# 忽略src/assets目录下文件的语法检查
src/assets
# 忽略public目录下文件的语法检查
public
# 忽略当前目录下为js的文件的语法检查
*.js
# 忽略当前目录下为vue的文件的语法检查
*.vue

199
.eslintrc.js Normal file
View File

@ -0,0 +1,199 @@
// ESlint 检查配置
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint',
sourceType: 'module'
},
env: {
browser: true,
node: true,
es6: true,
},
extends: ['plugin:vue/recommended', 'eslint:recommended'],
// add your custom rules here
//it is base on https://github.com/vuejs/eslint-config-vue
rules: {
"vue/max-attributes-per-line": [2, {
"singleline": 10,
"multiline": {
"max": 1,
"allowFirstLine": false
}
}],
"vue/singleline-html-element-content-newline": "off",
"vue/multiline-html-element-content-newline":"off",
"vue/name-property-casing": ["error", "PascalCase"],
"vue/no-v-html": "off",
'accessor-pairs': 2,
'arrow-spacing': [2, {
'before': true,
'after': true
}],
'block-spacing': [2, 'always'],
'brace-style': [2, '1tbs', {
'allowSingleLine': true
}],
'camelcase': [0, {
'properties': 'always'
}],
'comma-dangle': [2, 'never'],
'comma-spacing': [2, {
'before': false,
'after': true
}],
'comma-style': [2, 'last'],
'constructor-super': 2,
'curly': [2, 'multi-line'],
'dot-location': [2, 'property'],
'eol-last': 2,
'eqeqeq': ["error", "always", {"null": "ignore"}],
'generator-star-spacing': [2, {
'before': true,
'after': true
}],
'handle-callback-err': [2, '^(err|error)$'],
'indent': [2, 2, {
'SwitchCase': 1
}],
'jsx-quotes': [2, 'prefer-single'],
'key-spacing': [2, {
'beforeColon': false,
'afterColon': true
}],
'keyword-spacing': [2, {
'before': true,
'after': true
}],
'new-cap': [2, {
'newIsCap': true,
'capIsNew': false
}],
'new-parens': 2,
'no-array-constructor': 2,
'no-caller': 2,
'no-console': 'off',
'no-class-assign': 2,
'no-cond-assign': 2,
'no-const-assign': 2,
'no-control-regex': 0,
'no-delete-var': 2,
'no-dupe-args': 2,
'no-dupe-class-members': 2,
'no-dupe-keys': 2,
'no-duplicate-case': 2,
'no-empty-character-class': 2,
'no-empty-pattern': 2,
'no-eval': 2,
'no-ex-assign': 2,
'no-extend-native': 2,
'no-extra-bind': 2,
'no-extra-boolean-cast': 2,
'no-extra-parens': [2, 'functions'],
'no-fallthrough': 2,
'no-floating-decimal': 2,
'no-func-assign': 2,
'no-implied-eval': 2,
'no-inner-declarations': [2, 'functions'],
'no-invalid-regexp': 2,
'no-irregular-whitespace': 2,
'no-iterator': 2,
'no-label-var': 2,
'no-labels': [2, {
'allowLoop': false,
'allowSwitch': false
}],
'no-lone-blocks': 2,
'no-mixed-spaces-and-tabs': 2,
'no-multi-spaces': 2,
'no-multi-str': 2,
'no-multiple-empty-lines': [2, {
'max': 1
}],
'no-native-reassign': 2,
'no-negated-in-lhs': 2,
'no-new-object': 2,
'no-new-require': 2,
'no-new-symbol': 2,
'no-new-wrappers': 2,
'no-obj-calls': 2,
'no-octal': 2,
'no-octal-escape': 2,
'no-path-concat': 2,
'no-proto': 2,
'no-redeclare': 2,
'no-regex-spaces': 2,
'no-return-assign': [2, 'except-parens'],
'no-self-assign': 2,
'no-self-compare': 2,
'no-sequences': 2,
'no-shadow-restricted-names': 2,
'no-spaced-func': 2,
'no-sparse-arrays': 2,
'no-this-before-super': 2,
'no-throw-literal': 2,
'no-trailing-spaces': 2,
'no-undef': 2,
'no-undef-init': 2,
'no-unexpected-multiline': 2,
'no-unmodified-loop-condition': 2,
'no-unneeded-ternary': [2, {
'defaultAssignment': false
}],
'no-unreachable': 2,
'no-unsafe-finally': 2,
'no-unused-vars': [2, {
'vars': 'all',
'args': 'none'
}],
'no-useless-call': 2,
'no-useless-computed-key': 2,
'no-useless-constructor': 2,
'no-useless-escape': 0,
'no-whitespace-before-property': 2,
'no-with': 2,
'one-var': [2, {
'initialized': 'never'
}],
'operator-linebreak': [2, 'after', {
'overrides': {
'?': 'before',
':': 'before'
}
}],
'padded-blocks': [2, 'never'],
'quotes': [2, 'single', {
'avoidEscape': true,
'allowTemplateLiterals': true
}],
'semi': [2, 'never'],
'semi-spacing': [2, {
'before': false,
'after': true
}],
'space-before-blocks': [2, 'always'],
'space-before-function-paren': [2, 'never'],
'space-in-parens': [2, 'never'],
'space-infix-ops': 2,
'space-unary-ops': [2, {
'words': true,
'nonwords': false
}],
'spaced-comment': [2, 'always', {
'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
}],
'template-curly-spacing': [2, 'never'],
'use-isnan': 2,
'valid-typeof': 2,
'wrap-iife': [2, 'any'],
'yield-star-spacing': [2, 'both'],
'yoda': [2, 'never'],
'prefer-const': 2,
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
'object-curly-spacing': [2, 'always', {
objectsInObjects: false
}],
'array-bracket-spacing': [2, 'never']
}
}

23
.gitignore vendored Normal file
View File

@ -0,0 +1,23 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@ -1,2 +1,45 @@
# ceramic
# bwc_web
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Lints and fixes files
```
npm run lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
### 建议不要直接使用 cnpm 安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题
```
npm install --registry=https://registry.npm.taobao.org
```
### 启动服务
```
npm run dev
```

5
babel.config.js Normal file
View File

@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

35
build/index.js Normal file
View File

@ -0,0 +1,35 @@
const { run } = require('runjs')
const chalk = require('chalk')
const config = require('../vue.config.js')
const rawArgv = process.argv.slice(2)
const args = rawArgv.join(' ')
if (process.env.npm_config_preview || rawArgv.includes('--preview')) {
const report = rawArgv.includes('--report')
run(`vue-cli-service build ${args}`)
const port = 9526
const publicPath = config.publicPath
var connect = require('connect')
var serveStatic = require('serve-static')
const app = connect()
app.use(
publicPath,
serveStatic('./dist', {
index: ['index.html', '/']
})
)
app.listen(port, function () {
console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`))
if (report) {
console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`))
}
})
} else {
run(`vue-cli-service build ${args}`)
}

13327
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

59
package.json Normal file
View File

@ -0,0 +1,59 @@
{
"name": "bwc_web",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "vue-cli-service serve",
"build:prod": "vue-cli-service build",
"build:stage": "vue-cli-service build --mode staging",
"preview": "node build/index.js --preview",
"lint": "eslint --ext .js,.vue src",
"test:unit": "jest --clearCache && vue-cli-service test:unit",
"test:ci": "npm run lint && npm run test:unit",
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
"new": "plop"
},
"dependencies": {
"core-js": "^3.6.5",
"element-ui": "^2.15.6",
"less-loader": "^5.0.0",
"script-ext-html-webpack-plugin": "^2.1.5",
"vue": "^2.6.11",
"vue-i18n": "^8.26.7",
"vue-router": "^3.2.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-router": "^4.5.15",
"@vue/cli-service": "~4.5.0",
"axios": "^0.24.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"html-webpack-plugin": "^5.5.0",
"node-sass": "^4.14.1",
"sass-loader": "8.0.2",
"vue-template-compiler": "^2.6.11",
"vuex": "^3.6.2"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

38
public/index.html Normal file
View File

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html lang="">
<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 %>favicon.ico">
<title>西南交通大学 保卫处</title>
<script>
fnResize();
window.onresize = function() {
fnResize();
}
function fnResize() {
let deviceWidth = document.documentElement.clientWidth || window.innerWidth;
// let deviceWidth = document.documentElement.clientHeight || window.innerHeight;
if (deviceWidth >= 750) {
deviceWidth = 750;
}
if (deviceWidth <= 320) {
deviceWidth = 320;
}
document.documentElement.style.fontSize = (deviceWidth / 75) + 'px';
// document.documentElement.style.width = (deviceWidth / 75) + 'px';
// document.documentElement.style.height = (deviceWidth / 75) + 'px';
}
</script>
</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>
<!-- built files will be auto injected -->
</body>
</html>

21
src/App.vue Normal file
View File

@ -0,0 +1,21 @@
<template>
<div id="app">
<div>
你好,前端
</div>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
}
},
created() {
},
}
</script>
<style>
</style>

93
src/api/index.js Normal file
View File

@ -0,0 +1,93 @@
/**
* @author: Clay
* @date: 2022/1/14 13:26
* @descriptionindex
* @email: clay@hchyun.com
*/
import request from '@/utils/request'
// 获取统计数据
export function getConfig(configKey) {
return request({
url: '/web/config/'+configKey,
method: 'get',
})
}
// 获取所有导航
export function getNavigation(data) {
return request({
url: '/web/getnavall',
method: 'post',
data:data
})
}
// 获取节点信息(通用接口)
export function getNode(data) {
return request({
url: '/web/node',
method: 'post',
data:data
})
}
export function getNodeNav(data) {
return request({
url: '/web/nodeNav',
method: 'post',
data:data
})
}
// 获取文章列表
export function getArticleList(data) {
return request({
url: '/web/articlelist',
method: 'post',
data:data
})
}
// 获取面包屑
export function crumbs(id) {
return request({
url: '/web/crumbs',
method: 'post',
data:{
id:id
}
})
}
// 获取banner图
export function banner(type) {
return request({
url: '/web/banner',
method: 'post',
data:{
type:type
}
})
}
// 获取文章详情
export function article(id) {
return request({
url: '/web/article',
method: 'post',
data:{
id:id
}
})
}
// 获取文章详情
export function info(id) {
return request({
url: '/web/info',
method: 'post',
data:{
id:id
}
})
}

16
src/i18n/i18n.js Normal file
View File

@ -0,0 +1,16 @@
//i18n.js
import Vue from 'vue'
import locale from 'element-ui/lib/locale'
import VueI18n from 'vue-i18n'
import messages from './langs'
Vue.use(VueI18n)
const i18n = new VueI18n({
locale: localStorage.lang || 'cn',
messages
})
locale.i18n((key, value) => i18n.t(key, value)) //重点为了实现element插件的多语言切换
export default i18n

55
src/i18n/langs/cn.js Normal file
View File

@ -0,0 +1,55 @@
//cn.js
import zhLocale from 'element-ui/lib/locale/lang/zh-CN'
//{{ $t('message.news_ceter') }}
const cn = {
message: {
'student': '学生',
'staff': '教职工',
'alumni': '校友',
'examine': '考生',
'services_portal': '服务门户',
'switch': 'English',
'home': '学院首页',
'news_ceter': '新闻中心',
'more': '更多',
'research': '科学研究',
'academic': '学术交流',
'party': '党群工作',
'party_education': '党史教育',
'teaching_work': '教学工作',
'data_information': '数据中的信息',
'notice': '通知公告',
'scientific': '科学研究',
'undergraduate_education': '本科教育',
'postgraduate_education': '研究生教育',
'employees': '职工人数',
'number_students': '在校学生人数',
'graduate_tutor': '研究生导师',
'research_team': '科研团队',
'high_level_talents': '省部级以上高层次人才',
'major_projects': '国家级重大重点项目',
'contact_us': '联系我们',
'person': '人',
'pics': '个',
'adress': '犀浦校区地址:中国四川省成都市郫都区犀安路 999 号西南交通大学信息科学与技术学院',
'code': '邮政编码:611756',
'tel': '电话:+86 28 66366709(行政)',
'copyright': '版权所有◎2015西南交通大学信息科学与技术学院. All rights reserved.意见反馈',
'chinese_site': '西南交通大学(中文)',
'english_site': '西南交通大学(ENGLISH)',
'affairs_office': '西南交通大学国际合作与交流处',
'scholarship': '国家留学基金管理委员会',
'foreign': '中华人民共和国外交部',
'education': '中华人民共和国教育部门户网站',
'ieee': '电气和电子工程师协会(IEEE)',
'search': '搜索',
'placeholder': '请输入内容',
},
...zhLocale
}
export default cn

53
src/i18n/langs/en.js Normal file
View File

@ -0,0 +1,53 @@
//en.js
import enLocale from 'element-ui/lib/locale/lang/en'
const en = {
message: {
'student': 'Student',
'staff': 'Staff',
'alumni': 'Alumni',
'examine': 'Examine',
'services_portal': 'Services Portal',
'switch': '简体中文',
'home': 'Home',
'news_ceter': 'News Center',
'more': 'More',
'research': 'Research',
'academic': 'Academic',
'party': 'Party',
'party_education': 'Party Education',
'teaching_work': 'Teaching work',
'data_information': 'DATA INFORMATION',
'notice': 'Notice',
'scientific': 'Scientific',
'undergraduate_education': 'Undergraduate education',
'postgraduate_education': 'Postgraduate education',
'employees': 'Faculty Members',
'number_students': 'Internal Students',
'graduate_tutor': 'Tutors',
'research_team': 'Scientific Research Team',
'high_level_talents': 'Outstanding Talents',
'major_projects': 'Major projects',
'contact_us': '',
'person': '',
'pics': '',
'adress': '',
'code': '',
'tel': '',
'copyright': 'Copyright © 2014 School of Information Science and Technology, SWJTU. All rights reserved. Feedback',
'chinese_site': 'Southwest Jiaotong University(中文)',
'english_site': 'Southwest Jiaotong University(ENGLISH)',
'affairs_office': 'SWJTU International Affairs Office',
'scholarship': 'China Scholarship Counsil',
'foreign': 'Ministry of Foreign Affairs',
'education': 'Ministry of Education',
'ieee': 'IEEE',
'search': 'search',
'placeholder': 'please input',
},
}
export default en

6
src/i18n/langs/index.js Normal file
View File

@ -0,0 +1,6 @@
import en from './en'
import cn from './cn'
export default {
en,
cn
}

58
src/main.js Normal file
View File

@ -0,0 +1,58 @@
import Vue from 'vue'
import Vuex from 'vuex'
import App from './App.vue'
import router from './router'
import i18n from './i18n/i18n'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import 'element-ui/lib/theme-chalk/display.css';
import en from 'element-ui/lib/locale/lang/en'
import cn from 'element-ui/lib/locale/lang/zh-CN'
//要添加的代码
router.beforeEach((to, from, next) => {
// chrome
document.body.scrollTop = 0
// firefox
document.documentElement.scrollTop = 0
// safari
window.pageYOffset = 0
next()
})
i18n.mergeLocaleMessage('en', en)
i18n.mergeLocaleMessage('zh', cn)
Vue.config.productionTip = false
Vue.use(ElementUI)
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
isEnglish: false,
menuList :{},
},
mutations: {
increment (state) {
state.count++
}
},
computed:{
setEnglish(isEnglish){
this.store.isEnglish = isEnglish
},
},
getters:{
getEnglish(){
return this.store.isEnglish
}
}
})
new Vue({
i18n,
router,
store: store,
render: h => h(App)
}).$mount('#app')

19
src/router/index.js Normal file
View File

@ -0,0 +1,19 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
const routes = [
]
const router = new VueRouter({
mode: 'history',
routes
})
export default router

31
src/settings.js Normal file
View File

@ -0,0 +1,31 @@
module.exports = {
title: 'SIST',
/**
* 是否系统布局配置
*/
showSettings: false,
/**
* 是否显示 tagsView
*/
tagsView: true,
/**
* 是否固定头部
*/
fixedHeader: false,
/**
* 是否显示logo
*/
sidebarLogo: true,
/**
* @type {string | array} 'production' | ['production', 'development']
* @description Need show err logs component.
* The default is only used in the production env
* If you want to also use it in dev, you can pass ['production', 'development']
*/
errorLog: 'production'
}

190
src/utils/ebts.js Normal file
View File

@ -0,0 +1,190 @@
/**
* 通用js方法封装处理
* Copyright (c) 2021 ebts
*/
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 time_str = 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 time_str
}
// 表单重置
export function resetForm(refName) {
if (this.$refs[refName]) {
this.$refs[refName].resetFields();
}
}
// 添加日期范围
export function addDateRange(params, dateRange) {
var search = params;
search.beginTime = "";
search.endTime = "";
if (null != dateRange && '' != dateRange) {
search.beginTime = dateRange[0];
search.endTime = dateRange[1];
}
return search;
}
// 添加搜索创建时间日期范围
export function addCreateDateRange(params, dateRange) {
var search = params;
let data = {
beginCreateTime: "",
endCreateTime: "",
};
if (null != dateRange && '' != dateRange) {
data.beginCreateTime = dateRange[0];
data.endCreateTime = dateRange[1];
}
search.parameter = JSON.stringify(data)
return search;
}
// 回显数据字典
export function selectDictLabel(datas, value) {
try {
var actions = [];
Object.keys(datas).some((key) => {
if (datas[key].dictValue == ('' + value)) {
actions.push(datas[key].dictLabel);
return true;
}
})
return actions.join('');
}catch (e) {
console.log(e)
return null
}
}
// 回显数据字典
export function selectDictCode(datas, value) {
var actions = [];
Object.keys(datas).some((key) => {
if (datas[key].dictCode == ('' + value)) {
actions.push(datas[key].dictLabel);
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].dictValue == ('' + temp[val])) {
actions.push(datas[key].dictLabel + currentSeparator);
}
})
})
return actions.join('').substring(0, actions.join('').length - 1);
}
// 通用下载方法
export function download(fileName) {
window.location.href = baseURL + "/common/download?fileName=" + encodeURI(fileName) + "&delete=" + true;
}
// 字符串格式化(%s )
export function sprintf(str) {
var args = arguments, flag = true, 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) {
try {
id = id || 'id'
parentId = parentId || 'parentId'
children = children || 'children'
rootId = rootId || Math.min.apply(Math, data.map(item => {
return item[parentId]
})) || 0
//对源数据深度克隆
const cloneData = JSON.parse(JSON.stringify(data))
//循环所有项
const treeData = cloneData.filter(father => {
let branchArr = cloneData.filter(child => {
//返回每一项的子级数组
return father[id] === child[parentId]
});
branchArr.length > 0 ? father.children = branchArr : '';
//返回第一层
return father[parentId] === rootId;
});
return treeData != '' ? treeData : data;
} catch (e) {
console.log(e)
return null;
}
}

6
src/utils/errorCode.js Normal file
View File

@ -0,0 +1,6 @@
export default {
'401': '认证失败,无法访问系统资源',
'403': '当前操作没有权限',
'404': '访问资源不存在',
'default': '系统未知错误,请反馈给管理员'
}

76
src/utils/request.js Normal file
View File

@ -0,0 +1,76 @@
import axios from 'axios'
import {Notification, Message} from 'element-ui'
import errorCode from '@/utils/errorCode'
import {setAppLanguage} from "@/utils/sist";
//todo 显示消息处理
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项表示请求URL公共部分
baseURL: process.env.VUE_APP_BASE_API,
// 超时
timeout: 10000
})
解析
// request拦截器
service.interceptors.request.use(config => {
if (config.method == 'post') {
config.data['sitetype'] = 'NEd5n92EMIpyyBslaNqsRgE';
let lang = sessionStorage.getItem("lang");
config.data['lang'] = lang;
}
return config
}, error => {
console.log(error)
Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use(res => {
// 未设置状态码则默认成功状态
const code = res.data.code || 200;
// 获取错误信息
const msg = errorCode[code] || res.data.msg || errorCode['default']
if (code === 500) {
//Message({
// message: msg,
// type: 'error'
//})
return Promise.reject(new Error(msg))
} else if (code == 199) {
//Message({
// message: "查询结果为空!",
// type: 'info'
//})
return res.data
} else if (code !== 200) {
Notification.error({
title: msg
})
return Promise.reject('error')
} else {
return res.data
}
},
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) + "异常";
}
//Message({
// message: message,
// type: 'error',
// duration: 5 * 1000
//})
return Promise.reject(error)
}
)
export default service

190
src/utils/sist.js Normal file
View File

@ -0,0 +1,190 @@
/**
* @author: Clay
* @date: 2022/1/16 11:13
* @descriptionsist
* @email: clay@hchyun.com
*/
let vm = null
import {info} from "@/api";
export function setThis(that) {
vm = that
}
export function getParentNode(id) {
try {
let menuList = JSON.parse(sessionStorage.getItem("menu"));
for (let menu of menuList) {
for (let child of menu.children) {
if (id == child.encodeId) {
menu.children = []
child.children = []
return {
stair: menu, second: child,
}
}
for (let item of child.children) {
if (id == item.encodeId) {
menu.children = []
child.children = []
item.children = []
return {
stair: menu, second: child, three: item
}
}
}
}
}
return null
} catch (e) {
return null
}
}
export function getNodeMenu(id) {
try {
let menuList = JSON.parse(sessionStorage.getItem("menu"));
for (let menu of menuList) {
for (let child of menu.children) {
for (let item of child.children) {
if (id == item.encodeId) {
return item
}
}
}
}
return null
} catch (e) {
return null
}
}
export function setAppLanguage() {
let lang = sessionStorage.getItem("lang");
if (lang != null) {
vm.$i18n.locale = lang
return
}
var language = window.navigator.userLanguage || window.navigator.language;
if (language == 'zh-CN') {
lang = 'cn'
} else {
lang = 'en'
}
vm.$i18n.locale = lang
sessionStorage.setItem("lang", lang)
}
export function setLanguage() {
let lang = vm.$route.query && vm.$route.query.lang
if (lang != undefined) {
vm.$i18n.locale = lang
sessionStorage.setItem("lang", lang)
}
}
export function toArticle(news, width) {
console.log(width, "width")
info(news.id).then(res => {
let info = null
try {
info = getParentNode(res.data.encodeId)
console.log(info)
} catch (e) {
}
if (info == null) {
return
}
let routeData = null;
if (info.three == null) {
if (width) {
routeData = "/pc/" + info.second.encodeId + "?id=" + news.id + "&type=" + info.second.type + "&lang=" + sessionStorage.getItem("lang");
} else {
routeData = "/mobile/" + info.second.encodeId + "?id=" + news.id + "&type=" + info.second.type + "&lang=" + sessionStorage.getItem("lang");
}
} else {
console.log(info.three, "toArticle,info.three")
if (width) {
routeData = "/pc/" + info.second.encodeId + "/" + info.three.encodeId + "?id=" + news.id + "&lang=" + sessionStorage.getItem("lang");
} else {
routeData = "/mobile/" + info.second.encodeId + "/" + info.three.encodeId + "?id=" + news.id + "&lang=" + sessionStorage.getItem("lang");
}
}
linkTo(routeData)
})
}
function linkTo(routeData) {
let userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
if (userAgent.indexOf("Safari") > -1) {
window.location.href = window.location.origin + routeData
} else {
window.open(routeData.href, "_blank")
}
}
export function lookMoreComment(item, width) {
info(item.id).then(res => {
let info = null
try {
info = getParentNode(res.data.encodeId)
} catch (e) {
}
if (info == null) {
return
}
if (info.three == null) {
if (width) {
vm.$router.push("/pc/" + info.second.encodeId + "?type=" + info.second.type + "&lang=" + sessionStorage.getItem("lang"));
} else {
vm.$router.push("/mobile/" + info.second.encodeId + "?type=" + info.second.type + "&lang=" + sessionStorage.getItem("lang"));
}
} else {
if (width) {
vm.$router.push("/pc/" + info.second.encodeId + "/" + info.three.encodeId + "?type=" + info.second.type + "&lang=" + sessionStorage.getItem("lang"));
} else {
vm.$router.push("/mobile/" + info.second.encodeId + "/" + info.three.encodeId + "?type=" + info.second.type + "&lang=" + sessionStorage.getItem("lang"));
}
}
})
}
export function lookMoreFixedComment(id, width) {
let info = null
try {
info = getParentNode(id)
console.log(info)
} catch (e) {
}
if (info == null) {
return
let routeData = null;
if (info.three == null) {
if (width) {
routeData = "/pc/" + info.second.encodeId + "?type=" + info.second.type + "&lang=" + sessionStorage.getItem("lang");
} else {
routeData = "/mobile/" + info.second.encodeId + "?type=" + info.second.type + "&lang=" + sessionStorage.getItem("lang");
}
} else {
if (width) {
routeData = "/pc/" + info.second.encodeId + "/" + info.three.encodeId + "?type=" + info.second.type + "&lang=" + sessionStorage.getItem("lang");
} else {
routeData = "/mobile/" + info.second.encodeId + "/" + info.three.encodeId + "?type=" + info.second.type + "&lang=" + sessionStorage.getItem("lang");
}
}
linkTo(routeData)
// window.location.href = window.location.origin + routeData.href
// window.open(window.location.origin + routeData.href, "_blank")
}
}

124
vue.config.js Normal file
View File

@ -0,0 +1,124 @@
'use strict'
const path = require('path')
const defaultSettings = require('./src/settings.js')
function resolve(dir) {
return path.join(__dirname, dir)
}
const name = defaultSettings.title || 'SIST' // 标题
const port = process.env.port || process.env.npm_config_port || 80 // 端口
// vue.config.js 配置说明
//官方vue.config.js 参考文档 https://cli.vuejs.org/zh/config/#css-loaderoptions
// 这里只列一部分,具体配置参考文档
module.exports = {
// 部署生产环境和开发环境下的URL。
// 默认情况下Vue CLI 会假设你的应用是被部署在一个域名的根路径上
// 例如 https://www.hchyun.cn/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.hchyun.com/admin/,则设置 baseUrl 为 /admin/。
// publicPath: process.env.NODE_ENV === "production" ? "/" : "/",
publicPath: "/",
// 在npm run build 或 yarn build 时 生成文件的目录名称要和baseUrl的生产环境路径一致默认dist
outputDir: 'dist',
// 用于放置生成的静态资源 (js、css、img、fonts) 的;(项目打包之后,静态资源会放在这个文件夹下)
assetsDir: 'static',
// 是否开启eslint保存检测有效值ture | false | 'error'
lintOnSave: process.env.NODE_ENV === 'development',
// 如果你不需要生产环境的 source map可以将其设置为 false 以加速生产环境构建。
productionSourceMap: true,
// webpack-dev-server 相关配置
devServer: {
host: '0.0.0.0',
// port: port,
port: 8080,
open: true,
proxy: {
// detail: https://cli.vuejs.org/config/#devserver-proxy
[process.env.VUE_APP_BASE_API]: {
target: `https://sist.swjtu.edu.cn/`,
// target: `http://hchyunapi.tomey.live`,
changeOrigin: true,
pathRewrite: {
['^' + process.env.VUE_APP_BASE_API]: '/dev-api'
}
}
},
disableHostCheck: true
},
// 强制内联CSS
// 默认true: 使用CSS分离插件 ExtractTextPlugin采用独立样式文件载入不采用 <style> 方式内联至 html 文件中
css: { extract: false },
configureWebpack: {
name: name,
resolve: {
alias: {
'@': resolve('src')
}
}
},
chainWebpack(config) {
config.plugins.delete('preload') // TODO: need test
config.plugins.delete('prefetch') // TODO: need test
// set svg-sprite-loader
config.module
.rule('svg')
.exclude.add(resolve('src/assets/icons'))
.end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/assets/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
config
.when(process.env.NODE_ENV !== 'development',
config => {
config
.plugin('ScriptExtHtmlWebpackPlugin')
.after('html')
.use('script-ext-html-webpack-plugin', [{
// `runtime` must same as runtimeChunk name. default is `runtime`
inline: /runtime\..*\.js$/
}])
.end()
config
.optimization.splitChunks({
chunks: 'all',
cacheGroups: {
libs: {
name: 'chunk-libs',
test: /[\\/]node_modules[\\/]/,
priority: 10,
chunks: 'initial' // only package third parties that are initially dependent
},
elementUI: {
name: 'chunk-elementUI', // split elementUI into a single package
priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app
test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm
},
commons: {
name: 'chunk-commons',
test: resolve('src/components'), // can customize your rules
minChunks: 3, // minimum common number
priority: 5,
reuseExistingChunk: true
}
}
})
config.optimization.runtimeChunk('single'),
{
from: path.resolve(__dirname, './public/robots.txt'),//防爬虫文件
to:'./',//到根目录下
}
}
)
}
}