增加web代码
parent
45e62a67f3
commit
8925945571
|
@ -19,7 +19,7 @@ zap:
|
||||||
# redis configuration
|
# redis configuration
|
||||||
redis:
|
redis:
|
||||||
db: 0
|
db: 0
|
||||||
addr: '127.0.0.1:6379'
|
addr: '10.25.16.212:6379'
|
||||||
password: ''
|
password: ''
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
log/2021-11-17.log
|
log/2021-11-18.log
|
|
@ -1,43 +0,0 @@
|
||||||
[goweb-demo]2021/11/10 - 10:56:35.664 [34minfo[0m /Users/zero/work/mygithub/goweb-gin-demo/initialize/router.go:49 router register success
|
|
||||||
[goweb-demo]2021/11/10 - 10:56:35.667 [34minfo[0m /Users/zero/work/mygithub/goweb-gin-demo/core/server.go:31 server run success on {"address": ":8888"}
|
|
||||||
[goweb-demo]2021/11/10 - 11:00:35.952 [31merror[0m /Users/zero/work/mygithub/goweb-gin-demo/core/server.go:38 accept tcp [::]:8888: use of closed network connection
|
|
||||||
[goweb-demo]2021/11/10 - 11:00:55.329 [34minfo[0m /Users/zero/work/mygithub/goweb-gin-demo/initialize/router.go:49 router register success
|
|
||||||
[goweb-demo]2021/11/10 - 11:00:55.330 [34minfo[0m /Users/zero/work/mygithub/goweb-gin-demo/core/server.go:31 server run success on {"address": ":8888"}
|
|
||||||
[goweb-demo]2021/11/10 - 11:03:58.651 [34minfo[0m /Users/zero/work/mygithub/goweb-gin-demo/initialize/router.go:49 router register success
|
|
||||||
[goweb-demo]2021/11/10 - 11:03:58.653 [34minfo[0m /Users/zero/work/mygithub/goweb-gin-demo/core/server.go:31 server run success on {"address": ":8888"}
|
|
||||||
[goweb-demo]2021/11/10 - 11:07:46.066 [34minfo[0m /Users/zero/work/mygithub/goweb-gin-demo/initialize/router.go:49 router register success
|
|
||||||
goweb-gin-demo/initialize.Routers
|
|
||||||
/Users/zero/work/mygithub/goweb-gin-demo/initialize/router.go:49
|
|
||||||
goweb-gin-demo/core.RunServer
|
|
||||||
/Users/zero/work/mygithub/goweb-gin-demo/core/server.go:22
|
|
||||||
main.main
|
|
||||||
/Users/zero/work/mygithub/goweb-gin-demo/main.go:15
|
|
||||||
runtime.main
|
|
||||||
/Users/zero/go/sdk/go1.16.9/src/runtime/proc.go:225
|
|
||||||
[goweb-demo]2021/11/10 - 11:07:46.070 [34minfo[0m /Users/zero/work/mygithub/goweb-gin-demo/core/server.go:31 server run success on {"address": ":8888"}
|
|
||||||
goweb-gin-demo/core.RunServer
|
|
||||||
/Users/zero/work/mygithub/goweb-gin-demo/core/server.go:31
|
|
||||||
main.main
|
|
||||||
/Users/zero/work/mygithub/goweb-gin-demo/main.go:15
|
|
||||||
runtime.main
|
|
||||||
/Users/zero/go/sdk/go1.16.9/src/runtime/proc.go:225
|
|
||||||
[goweb-demo]2021/11/10 - 16:57:19.765 [34minfo[0m /Users/zero/work/mygithub/run_goweb-gin-demo/initialize/router.go:49 router register success
|
|
||||||
[goweb-demo]2021/11/10 - 16:57:19.767 [34minfo[0m /Users/zero/work/mygithub/run_goweb-gin-demo/core/server.go:31 server run success on {"address": ":8888"}
|
|
||||||
[goweb-demo]2021/11/10 - 17:26:39.999 [34minfo[0m /Users/zero/work/mygithub/run_goweb-gin-demo/initialize/router.go:49 router register success
|
|
||||||
[goweb-demo]2021/11/10 - 17:26:40.001 [34minfo[0m /Users/zero/work/mygithub/run_goweb-gin-demo/core/server.go:31 server run success on {"address": ":8888"}
|
|
||||||
[goweb-demo]2021/11/10 - 17:27:01.783 [31merror[0m /Users/zero/work/mygithub/run_goweb-gin-demo/api/wt/wt_reports.go:112 获取失败! {"err": "Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '[ 1, 2, 5, 1 ] LIMIT ? OFFSET ?' at line 1; Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '[ 1, 2, 5, 1 ] LIMIT ? OFFSET ?' at line 1"}
|
|
||||||
[goweb-demo]2021/11/10 - 17:29:35.409 [31merror[0m /Users/zero/work/mygithub/run_goweb-gin-demo/core/server.go:38 accept tcp [::]:8888: use of closed network connection
|
|
||||||
[goweb-demo]2021/11/10 - 17:29:47.850 [34minfo[0m /Users/zero/work/mygithub/run_goweb-gin-demo/initialize/router.go:49 router register success
|
|
||||||
[goweb-demo]2021/11/10 - 17:29:47.852 [34minfo[0m /Users/zero/work/mygithub/run_goweb-gin-demo/core/server.go:31 server run success on {"address": ":8888"}
|
|
||||||
[goweb-demo]2021/11/10 - 17:33:16.947 [31merror[0m /Users/zero/work/mygithub/run_goweb-gin-demo/core/server.go:38 accept tcp [::]:8888: use of closed network connection
|
|
||||||
[goweb-demo]2021/11/10 - 17:33:28.565 [34minfo[0m /Users/zero/work/mygithub/run_goweb-gin-demo/initialize/router.go:49 router register success
|
|
||||||
[goweb-demo]2021/11/10 - 17:33:28.566 [34minfo[0m /Users/zero/work/mygithub/run_goweb-gin-demo/core/server.go:31 server run success on {"address": ":8888"}
|
|
||||||
[goweb-demo]2021/11/10 - 18:07:58.172 [34minfo[0m /Users/zero/work/mygithub/run_goweb-gin-demo/initialize/router.go:49 router register success
|
|
||||||
[goweb-demo]2021/11/10 - 18:07:58.174 [34minfo[0m /Users/zero/work/mygithub/run_goweb-gin-demo/core/server.go:31 server run success on {"address": ":8888"}
|
|
||||||
[goweb-demo]2021/11/10 - 18:08:45.860 [34minfo[0m /Users/zero/work/mygithub/run_goweb-gin-demo/initialize/router.go:49 router register success
|
|
||||||
[goweb-demo]2021/11/10 - 18:08:45.861 [34minfo[0m /Users/zero/work/mygithub/run_goweb-gin-demo/core/server.go:31 server run success on {"address": ":8888"}
|
|
||||||
[goweb-demo]2021/11/10 - 18:45:34.852 [34minfo[0m /Users/zero/work/mygithub/run_goweb-gin-demo/initialize/router.go:49 router register success
|
|
||||||
[goweb-demo]2021/11/10 - 18:45:34.853 [34minfo[0m /Users/zero/work/mygithub/run_goweb-gin-demo/core/server.go:31 server run success on {"address": ":8888"}
|
|
||||||
[goweb-demo]2021/11/10 - 18:47:31.305 [31merror[0m /Users/zero/work/mygithub/run_goweb-gin-demo/core/server.go:38 accept tcp [::]:8888: use of closed network connection
|
|
||||||
[goweb-demo]2021/11/10 - 18:47:42.710 [34minfo[0m /Users/zero/work/mygithub/run_goweb-gin-demo/initialize/router.go:49 router register success
|
|
||||||
[goweb-demo]2021/11/10 - 18:47:42.711 [34minfo[0m /Users/zero/work/mygithub/run_goweb-gin-demo/core/server.go:31 server run success on {"address": ":8889"}
|
|
|
@ -16,3 +16,11 @@
|
||||||
[goweb-demo]2021/11/17 - 19:32:08.254 [31merror[0m /Users/zero/work/mygithub/goweb-gin-demo/server/api/wt/wt_comments.go:111 获取失败! {"err": "Error 1054: Unknown column 'wt_comments.nick_name' in 'field list'"}
|
[goweb-demo]2021/11/17 - 19:32:08.254 [31merror[0m /Users/zero/work/mygithub/goweb-gin-demo/server/api/wt/wt_comments.go:111 获取失败! {"err": "Error 1054: Unknown column 'wt_comments.nick_name' in 'field list'"}
|
||||||
[goweb-demo]2021/11/17 - 19:34:29.681 [34minfo[0m /Users/zero/work/mygithub/goweb-gin-demo/server/initialize/router.go:49 router register success
|
[goweb-demo]2021/11/17 - 19:34:29.681 [34minfo[0m /Users/zero/work/mygithub/goweb-gin-demo/server/initialize/router.go:49 router register success
|
||||||
[goweb-demo]2021/11/17 - 19:34:29.682 [34minfo[0m /Users/zero/work/mygithub/goweb-gin-demo/server/core/server.go:31 server run success on {"address": ":8981"}
|
[goweb-demo]2021/11/17 - 19:34:29.682 [34minfo[0m /Users/zero/work/mygithub/goweb-gin-demo/server/core/server.go:31 server run success on {"address": ":8981"}
|
||||||
|
[goweb-demo]2021/11/17 - 21:24:08.831 [34minfo[0m /Users/zero/work/mygithub/goweb-gin-demo/server/initialize/router.go:49 router register success
|
||||||
|
[goweb-demo]2021/11/17 - 21:24:08.832 [34minfo[0m /Users/zero/work/mygithub/goweb-gin-demo/server/core/server.go:31 server run success on {"address": ":8981"}
|
||||||
|
[goweb-demo]2021/11/17 - 13:25:22.345 [34minfo[0m /usr/local/weekly_report/initialize/router.go:49 router register success
|
||||||
|
[goweb-demo]2021/11/17 - 13:25:22.362 [34minfo[0m /usr/local/weekly_report/core/server.go:31 server run success on {"address": ":8981"}
|
||||||
|
[goweb-demo]2021/11/17 - 21:26:18.705 [31merror[0m /Users/zero/work/mygithub/goweb-gin-demo/server/core/server.go:38 accept tcp [::]:8981: use of closed network connection
|
||||||
|
[goweb-demo]2021/11/17 - 21:26:27.431 [34minfo[0m /Users/zero/work/mygithub/goweb-gin-demo/server/initialize/router.go:49 router register success
|
||||||
|
[goweb-demo]2021/11/17 - 21:26:27.434 [34minfo[0m /Users/zero/work/mygithub/goweb-gin-demo/server/core/server.go:31 server run success on {"address": ":8981"}
|
||||||
|
[goweb-demo]2021/11/17 - 21:26:59.880 [31merror[0m /Users/zero/work/mygithub/goweb-gin-demo/server/core/server.go:38 accept tcp [::]:8981: use of closed network connection
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
# weekly
|
||||||
|
|
||||||
|
## 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/).
|
|
@ -0,0 +1,5 @@
|
||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
'@vue/cli-plugin-babel/preset'
|
||||||
|
]
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,57 @@
|
||||||
|
{
|
||||||
|
"name": "weekly",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"serve": "vue-cli-service serve",
|
||||||
|
"build": "vue-cli-service dist",
|
||||||
|
"lint": "vue-cli-service lint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ant-design-vue": "^1.7.8",
|
||||||
|
"axios": "^0.21.4",
|
||||||
|
"core-js": "^3.6.5",
|
||||||
|
"js-base64": "^3.7.2",
|
||||||
|
"less": "^2.7.3",
|
||||||
|
"mavon-editor": "^2.9.1",
|
||||||
|
"qs": "^6.10.1",
|
||||||
|
"quill": "^1.3.7",
|
||||||
|
"vue": "^2.6.11",
|
||||||
|
"vue-froala-wysiwyg": "^4.0.6",
|
||||||
|
"vue-quill-editor": "^3.0.6",
|
||||||
|
"vue-router": "^3.5.3",
|
||||||
|
"vuex-persistedstate": "^4.1.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vue/cli-plugin-babel": "~4.5.0",
|
||||||
|
"@vue/cli-plugin-eslint": "~4.5.0",
|
||||||
|
"@vue/cli-service": "~4.5.0",
|
||||||
|
"babel-eslint": "^10.1.0",
|
||||||
|
"crypto-js": "^4.1.1",
|
||||||
|
"eslint": "^6.7.2",
|
||||||
|
"eslint-plugin-vue": "^6.2.2",
|
||||||
|
"less-loader": "^4.1.0",
|
||||||
|
"lodash.pick": "^4.4.0",
|
||||||
|
"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"
|
||||||
|
]
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 797 B |
|
@ -0,0 +1,17 @@
|
||||||
|
<!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><%= 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>
|
||||||
|
<!-- built files will be auto injected -->
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,44 @@
|
||||||
|
<template>
|
||||||
|
<a-config-provider :locale="zh_CN">
|
||||||
|
<div id="app">
|
||||||
|
<router-view></router-view>
|
||||||
|
</div>
|
||||||
|
</a-config-provider>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import zh_CN from 'ant-design-vue/lib/locale-provider/zh_CN'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'App',
|
||||||
|
data() {
|
||||||
|
return{
|
||||||
|
zh_CN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
#app {
|
||||||
|
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
main {
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
overflow-x: hidden;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
main > div {
|
||||||
|
width: calc(100vw - 310px);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
|
@ -0,0 +1,145 @@
|
||||||
|
<template>
|
||||||
|
<div class="login_div">
|
||||||
|
<div class="login_content">
|
||||||
|
<div class="login_title">周报系统</div>
|
||||||
|
<a-form :form="form" :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }" @submit="handleSubmit">
|
||||||
|
<a-form-item class="login_explain">
|
||||||
|
<a-input v-decorator="['username', { rules: [{ required: true, message: '用户名不能为空!' }] },]"
|
||||||
|
placeholder="请输入用户名" class="input_login" autocomplete="off">
|
||||||
|
<a-icon slot="prefix" type="user" class="icon_color" />
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item class="login_explain">
|
||||||
|
<a-input v-decorator="[ 'password', { rules: [{ required: true, message: '密码不能为空!' }] }, ]"
|
||||||
|
type="password"
|
||||||
|
placeholder="请输入密码" class="input_login">
|
||||||
|
<a-icon slot="prefix" type="lock" class="icon_color" />
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item class="login_explain captcha">
|
||||||
|
<a-input v-decorator="[ 'captcha', { rules: [{ required: true, message: '验证码不能为空!' }] }, ]"
|
||||||
|
@keyup.enter="handleSubmit"
|
||||||
|
placeholder="请输入验证码" style="width: 220px; margin-left: 30px" autocomplete="off">
|
||||||
|
</a-input>
|
||||||
|
<img :src="captcha" class="captcha_img" title="点击刷新" @click="getCaptcha" alt="">
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item>
|
||||||
|
<a-button type="primary" class="login_button" @click="handleSubmit">
|
||||||
|
登录
|
||||||
|
</a-button>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import api from '../../utils/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "LoginComponent",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
formLayout: 'horizontal',
|
||||||
|
captcha: '',
|
||||||
|
captchaId: '',
|
||||||
|
form: this.$form.createForm(this, { name: 'login' }),
|
||||||
|
message: '',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// 获取验证码
|
||||||
|
this.getCaptcha();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getCaptcha() {
|
||||||
|
this.$axios.post(api.GET_CAPTCHA.url).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.captcha = res.data.data.picPath;
|
||||||
|
this.captchaId = res.data.data.captchaId;
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleSubmit(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.form.validateFields((err, values) => {
|
||||||
|
const loginData = {};
|
||||||
|
// loginData.username = this.cryptos.encrypto(values.username);
|
||||||
|
// loginData.password = this.cryptos.encrypto(values.password);
|
||||||
|
loginData.username = values.username;
|
||||||
|
loginData.password = values.password;
|
||||||
|
loginData.captchaId = this.captchaId;
|
||||||
|
loginData.captcha = values.captcha;
|
||||||
|
if (!err) {
|
||||||
|
this.$axios.defaults.withCredentials = true;
|
||||||
|
this.$axios.post(api.LOGIN.url, loginData).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
// 存登录返回的session
|
||||||
|
sessionStorage.setItem('login', res.data.data.token);
|
||||||
|
sessionStorage.setItem('userId', res.data.data.user.ID);
|
||||||
|
sessionStorage.setItem('userName', res.data.data.user.userName);
|
||||||
|
sessionStorage.setItem('nickName', res.data.data.user.nickName);
|
||||||
|
this.$router.push('/');
|
||||||
|
} else {
|
||||||
|
this.getCaptcha();
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.login_div {
|
||||||
|
background-color: #6495ED;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
.login_content {
|
||||||
|
width: 386px;
|
||||||
|
margin-left: calc(50% - 193px);
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: rgba(255, 255, 255, 0.4);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.login_title {
|
||||||
|
font-size: 35px;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
.login_button {
|
||||||
|
margin-left: 160px;
|
||||||
|
}
|
||||||
|
.login_explain > div > div > .ant-form-explain {
|
||||||
|
text-align: left;
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
|
.captcha > div > div > .ant-form-item-children {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.icon_color {
|
||||||
|
color: rgba(0,0,0,.25);
|
||||||
|
}
|
||||||
|
.captcha_img {
|
||||||
|
height: 32px;
|
||||||
|
margin-left: 30px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.input_login {
|
||||||
|
width: 320px;
|
||||||
|
margin-left: 30px
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,499 @@
|
||||||
|
<template>
|
||||||
|
<div :class="mainDiv">
|
||||||
|
<div>
|
||||||
|
<a-button type="primary" style="float: right" @click="tripTo()"> 返回 </a-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="header_write">{{infoData.header}}</div>
|
||||||
|
<!-- 模板内容-->
|
||||||
|
<div v-for="(item, index) in infoData.contents" :key="index">
|
||||||
|
<div class="title_weekly">{{item.title}}:</div>
|
||||||
|
<quill-editor
|
||||||
|
:id="index"
|
||||||
|
style="margin-top: 20px"
|
||||||
|
v-model="item.content"
|
||||||
|
:ref="index"
|
||||||
|
@blur="onEditorBlur($event, index)" @focus="onEditorFocus($event, index)"
|
||||||
|
@change="onEditorChange($event)">
|
||||||
|
</quill-editor>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="title_weekly">图片上传</div>
|
||||||
|
<div>
|
||||||
|
<div class="clearfix">
|
||||||
|
<a-upload
|
||||||
|
action="/week/fileUploadAndDownload/upload"
|
||||||
|
list-type="picture-card"
|
||||||
|
:file-list="fileList"
|
||||||
|
@preview="handlePreview"
|
||||||
|
@change="handleChange"
|
||||||
|
:showUploadList="showUploadList"
|
||||||
|
accept=".png,.jpeg,.jpg"
|
||||||
|
:headers="{ 'x-token': xToken, 'x-user-id': xUserId}"
|
||||||
|
:remove="removeFile"
|
||||||
|
>
|
||||||
|
<div v-if="canEdit">
|
||||||
|
<a-icon type="plus" />
|
||||||
|
<div class="ant-upload-text">
|
||||||
|
Upload
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-upload>
|
||||||
|
<a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
|
||||||
|
<img alt="example" style="width: 100%" :src="previewImage" />
|
||||||
|
</a-modal>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="title_weekly">文件上传</div>
|
||||||
|
<div>
|
||||||
|
<div class="clearfix">
|
||||||
|
<a-upload
|
||||||
|
action="/week/fileUploadAndDownload/upload"
|
||||||
|
:file-list="fileList2"
|
||||||
|
@change="handleChange2"
|
||||||
|
:showUploadList="showUploadList"
|
||||||
|
:headers="{ 'x-token': xToken, 'x-user-id': xUserId}"
|
||||||
|
:remove="removeFile"
|
||||||
|
>
|
||||||
|
<div v-if="canEdit">
|
||||||
|
<a-button> <a-icon type="upload" /> Upload </a-button>
|
||||||
|
</div>
|
||||||
|
</a-upload>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="title_weekly" style="margin: 20px 0 0 0"><span style="color: red">*</span>发送给</div>
|
||||||
|
<a-select
|
||||||
|
mode="multiple"
|
||||||
|
style="width: 100%"
|
||||||
|
placeholder="请选择人员"
|
||||||
|
@change="userChange"
|
||||||
|
v-model="sends"
|
||||||
|
:disabled="!canEdit"
|
||||||
|
:class="sendToClass"
|
||||||
|
>
|
||||||
|
<a-select-option v-for="li in userList" :key="li.ID">
|
||||||
|
{{li.nickName}}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
<span style="color: red" v-if="sendToClass === 'cannotSubmit'">请选择人员</span>
|
||||||
|
|
||||||
|
<div style="text-align: center" v-if="canEdit">
|
||||||
|
<a-button type="primary" class="commit_button" @click="editReports"> 提交周报 </a-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="title_comments">评论</div>
|
||||||
|
<div v-for="(li, index) in commentsList">
|
||||||
|
<hr v-if="index !== 0"/>
|
||||||
|
|
||||||
|
<div class="title_weekly" style="font-size: 16px;">{{li.nickName}}:</div>
|
||||||
|
<div> {{li.comment}}</div>
|
||||||
|
<div style="width: 100%; text-align: right">{{li.CreatedAt}}</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a-textarea placeholder="请输入评论" v-model="comment" :rows="4" />
|
||||||
|
<div style="width: 100%; text-align: center">
|
||||||
|
<a-button type="primary" style="margin-top: 20px;" @click="addComment"> 提交评论 </a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import api from '../../utils/api'
|
||||||
|
import { quillEditor } from "vue-quill-editor";
|
||||||
|
import 'quill/dist/quill.core.css';
|
||||||
|
import 'quill/dist/quill.snow.css';
|
||||||
|
import 'quill/dist/quill.bubble.css';
|
||||||
|
|
||||||
|
function getBase64(file) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
reader.onload = () => resolve(reader.result);
|
||||||
|
reader.onerror = error => reject(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
export default {
|
||||||
|
name: "InfoComponent",
|
||||||
|
components: {quillEditor},
|
||||||
|
created() {
|
||||||
|
this.infoId = JSON.parse(this.$route.query.data);
|
||||||
|
// 根据id查询周报
|
||||||
|
this.findData();
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
mainDiv: 'top0',
|
||||||
|
infoId: '',
|
||||||
|
infoData: {},
|
||||||
|
canEdit: false,
|
||||||
|
showUploadList: {},
|
||||||
|
|
||||||
|
// 图片上传
|
||||||
|
fileList: [],
|
||||||
|
previewVisible: false,
|
||||||
|
previewImage: '',
|
||||||
|
xToken: sessionStorage.getItem('login'),
|
||||||
|
xUserId: sessionStorage.getItem('userId'),
|
||||||
|
pictures: [],
|
||||||
|
// 文件上传
|
||||||
|
fileList2: [],
|
||||||
|
// 周报模板
|
||||||
|
template: {},
|
||||||
|
// 人员列表
|
||||||
|
userList: [],
|
||||||
|
sends: [],
|
||||||
|
attachments: [],
|
||||||
|
// 发送到(选中人员列表)
|
||||||
|
sendTo: [],
|
||||||
|
sendToClass: 'canSubmit',
|
||||||
|
// 周报
|
||||||
|
commentsList: [],
|
||||||
|
comment: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
tripTo() {
|
||||||
|
this.$router.push('viewWeeklyReport');
|
||||||
|
},
|
||||||
|
findData() {
|
||||||
|
this.$axios.get(api.FIND_REPORT_BY_ID.url + `?id=${this.infoId}`).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.infoData = res.data.data.rewtReports;
|
||||||
|
|
||||||
|
if (this.infoData.userId === Number(sessionStorage.getItem('userId'))) {
|
||||||
|
this.canEdit = true;
|
||||||
|
} else {
|
||||||
|
this.showUploadList = {showRemoveIcon: false};
|
||||||
|
setTimeout(() => {
|
||||||
|
for (const li of document.getElementsByClassName('ql-toolbar')) {
|
||||||
|
li.style.display = 'none';
|
||||||
|
}
|
||||||
|
}, 80);
|
||||||
|
this.mainDiv = 'top1';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取周报评论
|
||||||
|
this.findComments(this.infoData.ID);
|
||||||
|
|
||||||
|
this.findUserList().then(() => {
|
||||||
|
this.setData();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
setData() {
|
||||||
|
// 查询模板
|
||||||
|
this.template = this.infoData.contents;
|
||||||
|
const pic = [];
|
||||||
|
for (let index = 0; index < this.infoData.pictures.length; index++) {
|
||||||
|
const temp = {};
|
||||||
|
temp.uid = index;
|
||||||
|
temp.name = this.infoData.pictures[index].name;
|
||||||
|
temp.key = this.infoData.pictures[index].key;
|
||||||
|
temp.url = this.BASEURL + api.DOWNLOAD_FILE.url + '?fileName=' + this.infoData.pictures[index].key;
|
||||||
|
temp.status = 'done';
|
||||||
|
pic.push(temp);
|
||||||
|
}
|
||||||
|
this.fileList = pic;
|
||||||
|
|
||||||
|
const files = [];
|
||||||
|
for (let index = 0; index < this.infoData.attachments.length; index++) {
|
||||||
|
const temp = {};
|
||||||
|
temp.uid = index;
|
||||||
|
temp.name = this.infoData.attachments[index].name;
|
||||||
|
temp.key = this.infoData.attachments[index].key;
|
||||||
|
temp.url = this.BASEURL + api.DOWNLOAD_FILE.url + '?fileName=' + this.infoData.attachments[index].key;
|
||||||
|
temp.status = 'done';
|
||||||
|
files.push(temp);
|
||||||
|
}
|
||||||
|
this.fileList2 = files;
|
||||||
|
|
||||||
|
const user = [];
|
||||||
|
for (const li of this.infoData.sendTo) {
|
||||||
|
let flag = false;
|
||||||
|
for (const tr of this.userList) {
|
||||||
|
if (tr.ID === li.id) {
|
||||||
|
flag = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!flag) {
|
||||||
|
const da = {};
|
||||||
|
da.ID = li.id;
|
||||||
|
da.userName = li.name;
|
||||||
|
this.userList.push(da);
|
||||||
|
}
|
||||||
|
user.push(li.id);
|
||||||
|
}
|
||||||
|
this.sends = user;
|
||||||
|
this.sendTo = this.infoData.sendTo;
|
||||||
|
},
|
||||||
|
// 图片上传
|
||||||
|
handleCancel() {
|
||||||
|
this.previewVisible = false;
|
||||||
|
},
|
||||||
|
async handlePreview(file) {
|
||||||
|
if (!file.url && !file.preview) {
|
||||||
|
file.preview = await getBase64(file.originFileObj);
|
||||||
|
}
|
||||||
|
this.previewImage = file.url || file.preview;
|
||||||
|
this.previewVisible = true;
|
||||||
|
},
|
||||||
|
handleChange({ fileList }) {
|
||||||
|
this.fileList = fileList;
|
||||||
|
},
|
||||||
|
// 文件上传
|
||||||
|
handleChange2({ fileList }) {
|
||||||
|
this.fileList2 = fileList;
|
||||||
|
},
|
||||||
|
// 删除文件
|
||||||
|
removeFile(file) {
|
||||||
|
if (this.canEdit) {
|
||||||
|
const params = {};
|
||||||
|
if (file.response) {
|
||||||
|
params.key = file.response.data.file.key;
|
||||||
|
} else {
|
||||||
|
params.key = file.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
const files = [];
|
||||||
|
for (const li of this.fileList) {
|
||||||
|
if (li.response) {
|
||||||
|
if (li.response.data.file.key !== params.key) {
|
||||||
|
files.push(li);
|
||||||
|
}
|
||||||
|
} else if (li.key !== params.key) {
|
||||||
|
files.push(li);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.fileList = files;
|
||||||
|
|
||||||
|
const files2 = [];
|
||||||
|
for (const li of this.fileList2) {
|
||||||
|
if (li.response) {
|
||||||
|
if (li.response.data.file.key !== params.key) {
|
||||||
|
files2.push(li);
|
||||||
|
}
|
||||||
|
} else if (li.key !== params.key) {
|
||||||
|
files2.push(li);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.fileList2 = files2;
|
||||||
|
|
||||||
|
this.$axios.post(api.DELETE_FILE.url, params).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message.success(res.data.msg);
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 失去焦点事件
|
||||||
|
onEditorBlur(event, id){
|
||||||
|
document.getElementById(id).children[0].style.zIndex = '1';
|
||||||
|
|
||||||
|
},
|
||||||
|
// 获得焦点事件
|
||||||
|
onEditorFocus(event, id){
|
||||||
|
if (!this.canEdit) {
|
||||||
|
event.enable(false);
|
||||||
|
} else {
|
||||||
|
event.enable(true);
|
||||||
|
}
|
||||||
|
document.getElementById(id).children[0].style.zIndex = '2';
|
||||||
|
},
|
||||||
|
// 内容改变事件
|
||||||
|
onEditorChange(){
|
||||||
|
// console.log(this.template.contents);
|
||||||
|
},
|
||||||
|
// 查询人员列表
|
||||||
|
async findUserList() {
|
||||||
|
const params = {};
|
||||||
|
params.page = 1;
|
||||||
|
params.pageSize = 99999;
|
||||||
|
this.$axios.post(api.GET_USER_LIST.url, params).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.userList = res.data.data.list;
|
||||||
|
return Promise.resolve(this.userList);
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
userChange(select) {
|
||||||
|
const temp = [];
|
||||||
|
if (select.length > 0) {
|
||||||
|
this.userList.forEach(li => {
|
||||||
|
for (const id of select) {
|
||||||
|
if (li.ID === id) {
|
||||||
|
const data = {};
|
||||||
|
data.id = id;
|
||||||
|
data.name = li.userName;
|
||||||
|
temp.push(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.sendTo = temp;
|
||||||
|
if (this.sendTo.length > 0) {
|
||||||
|
this.sendToClass = 'canSubmit';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
editReports() {
|
||||||
|
const pic = [];
|
||||||
|
if (this.fileList.length > 0) {
|
||||||
|
this.fileList.forEach(li => {
|
||||||
|
const da = {};
|
||||||
|
if (li.response) {
|
||||||
|
da.key = li.response.data.file.key;
|
||||||
|
da.name = li.response.data.file.name;
|
||||||
|
} else {
|
||||||
|
da.key = li.key;
|
||||||
|
da.name = li.name;
|
||||||
|
}
|
||||||
|
pic.push(da);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.pictures = pic;
|
||||||
|
|
||||||
|
const atta = [];
|
||||||
|
if (this.fileList2.length > 0) {
|
||||||
|
this.fileList2.forEach(li => {
|
||||||
|
const da = {};
|
||||||
|
if (li.response) {
|
||||||
|
da.key = li.response.data.file.key;
|
||||||
|
da.name = li.response.data.file.name;
|
||||||
|
} else {
|
||||||
|
da.key = li.key;
|
||||||
|
da.name = li.name;
|
||||||
|
}
|
||||||
|
atta.push(da);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.attachments = atta;
|
||||||
|
|
||||||
|
if (this.sendTo.length === 0) {
|
||||||
|
this.sendToClass = 'cannotSubmit';
|
||||||
|
} else {
|
||||||
|
const params = {};
|
||||||
|
params.id = this.infoData.ID;
|
||||||
|
params.userId = sessionStorage.getItem('userId');
|
||||||
|
params.userName = sessionStorage.getItem('userName');
|
||||||
|
params.sendTo = this.sendTo;
|
||||||
|
params.pictures = this.pictures;
|
||||||
|
params.attachments = this.attachments;
|
||||||
|
params.header = this.infoData.header;
|
||||||
|
params.contents = this.infoData.contents;
|
||||||
|
this.$axios.put(api.EDIT_REPORT.url, params).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message.success(res.data.msg);
|
||||||
|
this.fileList = [];
|
||||||
|
this.previewVisible = false;
|
||||||
|
this.previewImage = '';
|
||||||
|
this.pictures = [];
|
||||||
|
this.fileList2 = [];
|
||||||
|
this.template = {};
|
||||||
|
this.userList = [];
|
||||||
|
this.attachments = [];
|
||||||
|
this.sendTo = [];
|
||||||
|
this.findData();
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取周报评论
|
||||||
|
findComments(reportId) {
|
||||||
|
this.$axios.get(api.FIND_COMMENT_LIST.url + `?reportId=${reportId}&page=1&pageSise=99999`).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.commentsList = res.data.data.list;
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
addComment() {
|
||||||
|
const params = {};
|
||||||
|
params.reportId = this.infoData.ID;
|
||||||
|
params.userName = sessionStorage.getItem('userName');
|
||||||
|
|
||||||
|
params.comment = this.comment;
|
||||||
|
this.$axios.post(api.ADD_COMMENT.url, params).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message.success(res.data.msg);
|
||||||
|
this.findComments(this.infoData.ID);
|
||||||
|
this.comment = '';
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
editor() {
|
||||||
|
return this.$refs.myQuillEditor.quill;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style xml:lang="less">
|
||||||
|
.ql-toolbar {
|
||||||
|
position: fixed;
|
||||||
|
top: 104px;
|
||||||
|
background-color: white;
|
||||||
|
width: calc(100% - 270px);
|
||||||
|
left: 260px;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 1px 2px 1px 1px rgba(144,144,144,0.1);
|
||||||
|
}
|
||||||
|
.quill-editor {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
.ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-options {
|
||||||
|
z-index: 3;
|
||||||
|
top: 33px;
|
||||||
|
}
|
||||||
|
.ql-snow .ql-tooltip {
|
||||||
|
left: 0!important;
|
||||||
|
}
|
||||||
|
.header_write {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.readOnly {
|
||||||
|
-webkit-user-modify: read-only;
|
||||||
|
}
|
||||||
|
.canSubmit > div {
|
||||||
|
border-color: #d9d9d9;
|
||||||
|
}
|
||||||
|
.cannotSubmit > div {
|
||||||
|
border-color: red;
|
||||||
|
}
|
||||||
|
.top0 {
|
||||||
|
margin: 50px 0;
|
||||||
|
}
|
||||||
|
.top1 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.title_weekly {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.commit_button {
|
||||||
|
width: 400px;
|
||||||
|
margin-top: 20px
|
||||||
|
}
|
||||||
|
.title_comments {
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 20px 0;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,207 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<span>人员</span>
|
||||||
|
<a-select
|
||||||
|
class="select_div"
|
||||||
|
placeholder="请选择人员"
|
||||||
|
v-model="selectedUserId"
|
||||||
|
:allowClear="true"
|
||||||
|
:showSearch="true"
|
||||||
|
>
|
||||||
|
<a-select-option v-for="li in userList" :key="li.ID">
|
||||||
|
{{li.nickName}}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
|
||||||
|
<span class="span_title">起止时间</span>
|
||||||
|
<a-range-picker show-time style="margin-left: 10px" v-model="rangeTime">
|
||||||
|
<template slot="renderExtraFooter">
|
||||||
|
extra footer
|
||||||
|
</template>
|
||||||
|
</a-range-picker>
|
||||||
|
|
||||||
|
<span class="span_title">周报内容</span>
|
||||||
|
<a-input v-model="content" placeholder="请输入周报内容" class="content_input"></a-input>
|
||||||
|
|
||||||
|
<a-button type="primary" @click="findDataList" class="span_title">
|
||||||
|
查询
|
||||||
|
</a-button>
|
||||||
|
|
||||||
|
<div style="margin-top: 10px">
|
||||||
|
<a-table :columns="columns" :data-source="tableList" rowKey="ID" :pagination="pagination" @change="findDataList">
|
||||||
|
<span slot="action" slot-scope="text, li">
|
||||||
|
<a @click="openInfo(li)">详情</a>
|
||||||
|
</span>
|
||||||
|
<span slot="contents" slot-scope="text" class="ecllipsis" :title="toContent(text)">
|
||||||
|
{{toContent(text)}}
|
||||||
|
</span>
|
||||||
|
</a-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import api from '../../utils/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "MainComponent",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
userList: [],
|
||||||
|
selectedUserId: '',
|
||||||
|
rangeTime: [],
|
||||||
|
content: '',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: '姓名',
|
||||||
|
dataIndex: 'nickName',
|
||||||
|
key: 'nickName'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '内容',
|
||||||
|
dataIndex: 'contents',
|
||||||
|
key: 'contents',
|
||||||
|
scopedSlots: { customRender: 'contents' },
|
||||||
|
width: '500px',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '评论数',
|
||||||
|
dataIndex: 'commentCount',
|
||||||
|
key: 'commentCount'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '时间',
|
||||||
|
dataIndex: 'CreatedAt',
|
||||||
|
key: 'CreatedAt'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
key: 'action',
|
||||||
|
scopedSlots: { customRender: 'action' },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
tableList: [],
|
||||||
|
pagination: {
|
||||||
|
total: 0,
|
||||||
|
defaultCurrent: 1,
|
||||||
|
defaultPageSize: 10,
|
||||||
|
showSizeChanger: true,
|
||||||
|
pageSizeOptions: ['10', '20', '50', '100'],
|
||||||
|
onShowSizeChange: (current, pageSize) => {
|
||||||
|
this.pagination.defaultCurrent = current;
|
||||||
|
this.pagination.defaultPageSize = pageSize;
|
||||||
|
},
|
||||||
|
onChange: (current, pageSize) => {
|
||||||
|
this.pagination.defaultCurrent = current;
|
||||||
|
this.pagination.defaultPageSize = pageSize;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.findUserList();
|
||||||
|
this.findDataList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 查询人员列表
|
||||||
|
findUserList() {
|
||||||
|
const params = {};
|
||||||
|
params.page = 1;
|
||||||
|
params.pageSize = 9999;
|
||||||
|
|
||||||
|
this.$axios.post(api.GET_USER_LIST.url, params).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.userList = res.data.data.list;
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 分页查询周报列表
|
||||||
|
findDataList() {
|
||||||
|
let startTime = '';
|
||||||
|
let endTime = '';
|
||||||
|
if (this.rangeTime.length !== 0) {
|
||||||
|
startTime = this.toDate(this.rangeTime[0]._d);
|
||||||
|
endTime = this.toDate(this.rangeTime[1]._d);
|
||||||
|
}
|
||||||
|
this.$axios.get(api.FIND_REPORT_LIST.url + `?page=${this.pagination.defaultCurrent}&pageSize=${this.pagination.defaultPageSize}&content=${this.content}&currUserId=${sessionStorage.getItem('userId')}&userId=${this.selectedUserId}&startTime=${startTime}&endTime=${endTime}`).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.tableList = res.data.data.list;
|
||||||
|
this.pagination.total = res.data.data.total;
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
this.pagination.total = 0;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
openInfo(data) {
|
||||||
|
this.$router.push({
|
||||||
|
path:'/editWeeklyReport',
|
||||||
|
query:{data: JSON.stringify(data.ID)}
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
// 日期转化
|
||||||
|
toDate (date) {
|
||||||
|
const y = date.getFullYear();
|
||||||
|
let m = date.getMonth() + 1;
|
||||||
|
m = m < 10 ? ('0' + m) : m;
|
||||||
|
let d = date.getDate();
|
||||||
|
d = d < 10 ? ('0' + d) : d;
|
||||||
|
const h = date.getHours();
|
||||||
|
let minute = date.getMinutes();
|
||||||
|
minute = minute < 10 ? ('0' + minute) : minute;
|
||||||
|
return y + '-' + m + '-' + d+' '+h+':'+minute;
|
||||||
|
},
|
||||||
|
// 截取中文
|
||||||
|
toContent(data) {
|
||||||
|
let str = '';
|
||||||
|
data.forEach(li => {
|
||||||
|
str += li.title + this.toChinese(li.content) + ';';
|
||||||
|
});
|
||||||
|
return str;
|
||||||
|
},
|
||||||
|
toChinese(strValue) {
|
||||||
|
if (strValue !== null && strValue !== '') {
|
||||||
|
const reg = /[\u4e00-\u9fa5]/g;
|
||||||
|
let content = '';
|
||||||
|
try {
|
||||||
|
if (strValue.match(reg) !== null) {
|
||||||
|
content = strValue.match(reg).join('');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style xml:lang="less">
|
||||||
|
.ecllipsis {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
display: inline-block;
|
||||||
|
width: 500px;
|
||||||
|
}
|
||||||
|
.select_div {
|
||||||
|
width: 200px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
.span_title {
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
.content_input {
|
||||||
|
width: 200px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,226 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="static_ana">数据统计</div>
|
||||||
|
<div class="title_ana">周报</div>
|
||||||
|
<div class="content_ana">
|
||||||
|
<div class="left_ana">
|
||||||
|
<div>{{infoData.commitCount}}</div>
|
||||||
|
<a-popover placement="topLeft">
|
||||||
|
<template slot="content">
|
||||||
|
{{commitPeoples}}
|
||||||
|
</template>
|
||||||
|
<span>已提交</span>
|
||||||
|
</a-popover>
|
||||||
|
</div>
|
||||||
|
<div class="right_ana">
|
||||||
|
<div>{{infoData.uncommitCount}}</div>
|
||||||
|
<a-popover placement="topLeft">
|
||||||
|
<template slot="content">
|
||||||
|
{{uncommitPeoples}}
|
||||||
|
</template>
|
||||||
|
<span>未提交</span>
|
||||||
|
</a-popover>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="export_ana">导出功能</div>
|
||||||
|
<div class="content_ana">
|
||||||
|
<div class="left_ana">
|
||||||
|
<span class="title_ana">人员</span>
|
||||||
|
<a-select
|
||||||
|
mode="multiple"
|
||||||
|
style="width: 400px; margin-left: 20px"
|
||||||
|
placeholder="请选择人员"
|
||||||
|
@change="userChange"
|
||||||
|
v-model="sends"
|
||||||
|
>
|
||||||
|
<a-select-option v-for="li in userList" :key="li.ID">
|
||||||
|
{{li.userName}}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</div>
|
||||||
|
<div class="right_ana">
|
||||||
|
<span class="time_ana">起止时间</span>
|
||||||
|
<a-range-picker @change="timeOnChange" />
|
||||||
|
|
||||||
|
<a-button type="primary" @click="exportFile" style="margin-left: 20px"> 导出 </a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import api from '../../utils/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "StatisticalExport",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
infoData: {},
|
||||||
|
uncommitPeoples: '',
|
||||||
|
commitPeoples: '',
|
||||||
|
// 人员列表
|
||||||
|
userList: [],
|
||||||
|
sends: [],
|
||||||
|
reporters: [],
|
||||||
|
startTime: '',
|
||||||
|
endTime: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.findResult();
|
||||||
|
this.findUserList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
findResult() {
|
||||||
|
this.$axios.get(api.FIND_RESULT.url + `?userId=${sessionStorage.getItem('userId')}`).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.infoData = res.data.data.rewtOutput;
|
||||||
|
let un = '';
|
||||||
|
if (res.data.data.rewtOutput.uncommitPeoples) {
|
||||||
|
res.data.data.rewtOutput.uncommitPeoples.forEach(da => {
|
||||||
|
un += da.name + ',';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.uncommitPeoples = un.substring(0, un.length - 1);
|
||||||
|
|
||||||
|
let is = '';
|
||||||
|
if (res.data.data.rewtOutput.commitPeoples) {
|
||||||
|
res.data.data.rewtOutput.commitPeoples.forEach(da => {
|
||||||
|
is += da.name + ',';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.commitPeoples = is.substring(0, un.length - 1);
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
findUserList() {
|
||||||
|
const params = {};
|
||||||
|
params.page = 1;
|
||||||
|
params.pageSize = 99999;
|
||||||
|
this.$axios.post(api.GET_USER_LIST.url, params).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
let data = [];
|
||||||
|
const li = {};
|
||||||
|
li.ID = 0;
|
||||||
|
li.userName = '全部';
|
||||||
|
data.push(li);
|
||||||
|
data = data.concat(res.data.data.list);
|
||||||
|
this.userList = data;
|
||||||
|
|
||||||
|
const all = [];
|
||||||
|
res.data.data.list.forEach(li => {
|
||||||
|
all.push(li.ID);
|
||||||
|
});
|
||||||
|
this.allId = all;
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
userChange(select) {
|
||||||
|
let flag = false;
|
||||||
|
select.forEach(id => {
|
||||||
|
if (id === 0) {
|
||||||
|
flag = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const temp = [];
|
||||||
|
if (flag) {
|
||||||
|
this.sends = this.allId;
|
||||||
|
this.userList.forEach(li => {
|
||||||
|
if (li.ID !== 0) {
|
||||||
|
const data = {};
|
||||||
|
data.id = li.ID;
|
||||||
|
data.name = li.userName;
|
||||||
|
temp.push(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (select.length > 0) {
|
||||||
|
this.userList.forEach(li => {
|
||||||
|
select.forEach(id => {
|
||||||
|
if (li.ID === id) {
|
||||||
|
const data = {};
|
||||||
|
data.id = id;
|
||||||
|
data.name = li.userName;
|
||||||
|
temp.push(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.reporters = temp;
|
||||||
|
},
|
||||||
|
timeOnChange(date, dateString) {
|
||||||
|
this.startTime = dateString[0];
|
||||||
|
this.endTime = dateString[1];
|
||||||
|
},
|
||||||
|
exportFile() {
|
||||||
|
const name = this.startTime + '-' + this.endTime + '周报汇总.xlsx';
|
||||||
|
this.$axios({
|
||||||
|
url: api.EXPORT_FILE.url + `?userIds=${this.sends}&startTime=${this.startTime}&endTime=${this.endTime}`,
|
||||||
|
method: 'get',
|
||||||
|
responseType: 'blob'
|
||||||
|
}).then((res) => {
|
||||||
|
let blob = new Blob([res.data]);
|
||||||
|
let url = URL.createObjectURL(blob);
|
||||||
|
this.toFile(url, name)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
toFile(downUrl, fileName) {
|
||||||
|
const aLinkUrl = document.createElement('a');
|
||||||
|
aLinkUrl.href = downUrl;
|
||||||
|
aLinkUrl.download = fileName;
|
||||||
|
const clickAlink = (obj) => {
|
||||||
|
const ev = document.createEvent('MouseEvents');
|
||||||
|
ev.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
|
||||||
|
obj.dispatchEvent(ev)
|
||||||
|
};
|
||||||
|
clickAlink(aLinkUrl)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style xml:lang="less">
|
||||||
|
.static_ana {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.title_ana {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
.content_ana {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.left_ana {
|
||||||
|
width: 50%;
|
||||||
|
text-align: right;
|
||||||
|
padding-right: 50px;
|
||||||
|
border-right: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
.right_ana {
|
||||||
|
width: 50%;
|
||||||
|
padding-left: 50px;
|
||||||
|
}
|
||||||
|
.export_ana {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
.time_ana {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 20px 20px 20px 0;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,169 @@
|
||||||
|
<template>
|
||||||
|
<div class="content_div">
|
||||||
|
<div>
|
||||||
|
<span class="title_tem">模板标题</span>
|
||||||
|
<a-input v-model="data.header" placeholder="请输入模板标题" class="modal_title"></a-input>
|
||||||
|
|
||||||
|
<span class="create_people">创建人</span>
|
||||||
|
<span v-if="isCreate">{{userName}}</span>
|
||||||
|
<span v-else>{{data.userName}}</span>
|
||||||
|
|
||||||
|
<a-button type="primary" style="float: right" @click="saveData"> <a-icon type="save" /> 保存 </a-button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div v-if="!isCreate">
|
||||||
|
<div v-for="(li, index) in data.contents" :key="index">
|
||||||
|
<div class="content1">
|
||||||
|
<div class="content2">
|
||||||
|
<a-input v-model="li.title" placeholder="请输入字段标题" class="input_temp"></a-input>
|
||||||
|
<a-icon type="delete" style="cursor: pointer" @click="deleteContent(index)"/>
|
||||||
|
</div>
|
||||||
|
<div class="content_tem">
|
||||||
|
<span>
|
||||||
|
待填写者输入
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<div v-for="(li, index) in addContents" :key="index">
|
||||||
|
<div class="content1">
|
||||||
|
<div class="content2">
|
||||||
|
<a-input v-model="li.title" placeholder="请输入字段标题" class="input_temp"></a-input>
|
||||||
|
<a-icon type="delete" style="cursor: pointer" @click="deleteContent(index)"/>
|
||||||
|
</div>
|
||||||
|
<div class="content_tem">
|
||||||
|
<span>
|
||||||
|
待填写者输入
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a-button type="primary" class="add_button_tem" @click="addContent"> <a-icon type="plus" /> </a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import api from '../../utils/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "TemplateEditing",
|
||||||
|
created() {
|
||||||
|
this.findData();
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
data: {},
|
||||||
|
// 创建还是编辑
|
||||||
|
isCreate: true,
|
||||||
|
userName: '',
|
||||||
|
addContents: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
findData() {
|
||||||
|
this.$axios.get(api.GET_TEMPLATE_LIST.url).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
if (res.data.data.total > 0) {
|
||||||
|
this.isCreate = false;
|
||||||
|
this.data = res.data.data.list[0];
|
||||||
|
} else {
|
||||||
|
this.isCreate = true;
|
||||||
|
this.data.userName = sessionStorage.getItem('userName');
|
||||||
|
this.userName = sessionStorage.getItem('userName');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
addContent() {
|
||||||
|
const li = {};
|
||||||
|
li.title = '';
|
||||||
|
li.content = '';
|
||||||
|
if (this.data.contents) {
|
||||||
|
this.data.contents.push(li);
|
||||||
|
this.addContents.push(li);
|
||||||
|
} else {
|
||||||
|
const con = [];
|
||||||
|
con.push(li);
|
||||||
|
this.data.contents = con;
|
||||||
|
this.addContents.push(li);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deleteContent(index) {
|
||||||
|
this.data.contents.splice(index, 1);
|
||||||
|
},
|
||||||
|
saveData() {
|
||||||
|
if (this.isCreate) {
|
||||||
|
// 创建接口
|
||||||
|
this.$axios.post(api.ADD_TEMPLATE.url, this.data).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message.success(res.data.msg);
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 编辑接口
|
||||||
|
this.$axios.put(api.EDIT_TEMPLATE.url, this.data).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message.success(res.data.msg);
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style xml:lang="less">
|
||||||
|
.content_div {
|
||||||
|
height: 100%;
|
||||||
|
padding: 0 200px;
|
||||||
|
}
|
||||||
|
.content1 {
|
||||||
|
margin-top: 20px;
|
||||||
|
box-shadow: 0 2px 12px 0 #ccc;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
.content2 {
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
.input_temp {
|
||||||
|
width: calc(100% - 50px);
|
||||||
|
border: none;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.input_temp:focus {
|
||||||
|
border: none!important;
|
||||||
|
box-shadow: none!important;
|
||||||
|
}
|
||||||
|
.title_tem {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.modal_title {
|
||||||
|
width: 350px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
.create_people {
|
||||||
|
margin-left: 100px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.content_tem {
|
||||||
|
margin: 10px 0 0 10px;
|
||||||
|
}
|
||||||
|
.add_button_tem {
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,335 @@
|
||||||
|
<template>
|
||||||
|
<div class="content_wri">
|
||||||
|
<div class="header_write">{{template.header}}</div>
|
||||||
|
<!-- 模板内容-->
|
||||||
|
<div v-for="(item, index) in template.contents" :key="index">
|
||||||
|
<div class="title_weight">{{item.title}}:</div>
|
||||||
|
<quill-editor
|
||||||
|
:id="index"
|
||||||
|
style="margin-top: 20px"
|
||||||
|
v-model="item.content"
|
||||||
|
:ref="index"
|
||||||
|
@blur="onEditorBlur($event, index)" @focus="onEditorFocus($event, index)">
|
||||||
|
</quill-editor>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="title_weight">图片上传</div>
|
||||||
|
<div>
|
||||||
|
<div class="clearfix">
|
||||||
|
<a-upload
|
||||||
|
action="/week/fileUploadAndDownload/upload"
|
||||||
|
list-type="picture-card"
|
||||||
|
:file-list="fileList"
|
||||||
|
@preview="handlePreview"
|
||||||
|
@change="handleChange"
|
||||||
|
accept=".png,.jpeg,.jpg"
|
||||||
|
:headers="{ 'x-token': xToken, 'x-user-id': xUserId}"
|
||||||
|
:remove="removeFile"
|
||||||
|
>
|
||||||
|
<div v-if="fileList.length < 8">
|
||||||
|
<a-icon type="plus" />
|
||||||
|
<div class="ant-upload-text">
|
||||||
|
Upload
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-upload>
|
||||||
|
<a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
|
||||||
|
<img alt="example" style="width: 100%" :src="previewImage" />
|
||||||
|
</a-modal>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="title_weight">文件上传</div>
|
||||||
|
<div>
|
||||||
|
<div class="clearfix">
|
||||||
|
<a-upload
|
||||||
|
action="/week/fileUploadAndDownload/upload"
|
||||||
|
:file-list="fileList2"
|
||||||
|
@change="handleChange2"
|
||||||
|
:headers="{ 'x-token': xToken, 'x-user-id': xUserId}"
|
||||||
|
:remove="removeFile"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<a-button> <a-icon type="upload" /> Upload </a-button>
|
||||||
|
</div>
|
||||||
|
</a-upload>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div style="font-weight: 600; margin: 20px 0 0 0"><span style="color: red">*</span>发送给</div>
|
||||||
|
<a-select
|
||||||
|
mode="multiple"
|
||||||
|
style="width: 100%"
|
||||||
|
placeholder="请选择人员"
|
||||||
|
@change="userChange"
|
||||||
|
v-model="sends"
|
||||||
|
:class="sendToClass"
|
||||||
|
>
|
||||||
|
<a-select-option v-for="li in userList" :key="li.ID">
|
||||||
|
{{li.nickName}}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
<span style="color: red" v-if="sendToClass === 'cannotSubmit'">请选择人员</span>
|
||||||
|
|
||||||
|
<div style="text-align: center">
|
||||||
|
<a-button type="primary" class="commit_button" @click="addReports"> 提交 </a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import api from '../../utils/api'
|
||||||
|
import { quillEditor } from "vue-quill-editor";
|
||||||
|
import 'quill/dist/quill.core.css';
|
||||||
|
import 'quill/dist/quill.snow.css';
|
||||||
|
import 'quill/dist/quill.bubble.css';
|
||||||
|
|
||||||
|
function getBase64(file) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.readAsDataURL(file);
|
||||||
|
reader.onload = () => resolve(reader.result);
|
||||||
|
reader.onerror = error => reject(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
export default {
|
||||||
|
name: "WriteWeeklyReport",
|
||||||
|
components: {quillEditor},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 图片上传
|
||||||
|
fileList: [],
|
||||||
|
previewVisible: false,
|
||||||
|
previewImage: '',
|
||||||
|
xToken: sessionStorage.getItem('login'),
|
||||||
|
xUserId: sessionStorage.getItem('userId'),
|
||||||
|
pictures: [],
|
||||||
|
// 文件上传
|
||||||
|
fileList2: [],
|
||||||
|
// 周报模板
|
||||||
|
template: {},
|
||||||
|
// 人员列表
|
||||||
|
userList: [],
|
||||||
|
sends: [],
|
||||||
|
attachments: [],
|
||||||
|
sendToClass: 'canSubmit',
|
||||||
|
// 发送到(选中人员列表)
|
||||||
|
sendTo: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// 查询模板
|
||||||
|
this.findTempl();
|
||||||
|
// 查询人员列表
|
||||||
|
this.findUserList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 图片上传
|
||||||
|
handleCancel() {
|
||||||
|
this.previewVisible = false;
|
||||||
|
},
|
||||||
|
async handlePreview(file) {
|
||||||
|
if (!file.url && !file.preview) {
|
||||||
|
file.preview = await getBase64(file.originFileObj);
|
||||||
|
}
|
||||||
|
this.previewImage = file.url || file.preview;
|
||||||
|
this.previewVisible = true;
|
||||||
|
},
|
||||||
|
handleChange({ fileList }) {
|
||||||
|
this.fileList = fileList;
|
||||||
|
},
|
||||||
|
// 文件上传
|
||||||
|
handleChange2({ fileList }) {
|
||||||
|
this.fileList2 = fileList;
|
||||||
|
},
|
||||||
|
// 删除文件
|
||||||
|
removeFile(file) {
|
||||||
|
const params = {};
|
||||||
|
params.key = file.response.data.file.key;
|
||||||
|
|
||||||
|
const files = [];
|
||||||
|
this.fileList.forEach(li => {
|
||||||
|
if (li.response.data.file.key !== params.key) {
|
||||||
|
files.push(li);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.fileList = files;
|
||||||
|
|
||||||
|
const files2 = [];
|
||||||
|
this.fileList2.forEach(li => {
|
||||||
|
if (li.response.data.file.key !== params.key) {
|
||||||
|
files2.push(li);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.fileList2 = files2;
|
||||||
|
|
||||||
|
this.$axios.post(api.DELETE_FILE.url, params).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message.success(res.data.msg);
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 查询模板
|
||||||
|
findTempl() {
|
||||||
|
this.$axios.get(api.GET_TEMPLATE_LIST.url).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
if (res.data.data.total > 0) {
|
||||||
|
this.template = res.data.data.list[0];
|
||||||
|
} else {
|
||||||
|
this.$message.error('请先创建周报模板');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 失去焦点事件
|
||||||
|
onEditorBlur(event, id){
|
||||||
|
document.getElementById(id).children[0].style.zIndex = '1';
|
||||||
|
|
||||||
|
},
|
||||||
|
// 获得焦点事件
|
||||||
|
onEditorFocus(event, id){
|
||||||
|
document.getElementById(id).children[0].style.zIndex = '2';
|
||||||
|
},
|
||||||
|
// 查询人员列表
|
||||||
|
findUserList() {
|
||||||
|
const params = {};
|
||||||
|
params.page = 1;
|
||||||
|
params.pageSize = 99999;
|
||||||
|
this.$axios.post(api.GET_USER_LIST.url, params).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.userList = res.data.data.list;
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
userChange(select) {
|
||||||
|
const temp = [];
|
||||||
|
if (select.length > 0) {
|
||||||
|
this.userList.forEach(li => {
|
||||||
|
select.forEach(id => {
|
||||||
|
if (li.ID === id) {
|
||||||
|
const data = {};
|
||||||
|
data.id = id;
|
||||||
|
data.name = li.userName;
|
||||||
|
temp.push(data);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.sendTo = temp;
|
||||||
|
if (this.sendTo.length > 0) {
|
||||||
|
this.sendToClass = 'canSubmit';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addReports() {
|
||||||
|
const pic = [];
|
||||||
|
if (this.fileList.length > 0) {
|
||||||
|
this.fileList.forEach(li => {
|
||||||
|
const da = {};
|
||||||
|
da.key = li.response.data.file.key;
|
||||||
|
da.name = li.response.data.file.name;
|
||||||
|
pic.push(da);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.pictures = pic;
|
||||||
|
|
||||||
|
const atta = [];
|
||||||
|
if (this.fileList2.length > 0) {
|
||||||
|
this.fileList2.forEach(li => {
|
||||||
|
const da = {};
|
||||||
|
da.key = li.response.data.file.key;
|
||||||
|
da.name = li.response.data.file.name;
|
||||||
|
atta.push(da);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.attachments = atta;
|
||||||
|
|
||||||
|
if (this.sendTo.length === 0) {
|
||||||
|
this.sendToClass = 'cannotSubmit';
|
||||||
|
} else {
|
||||||
|
const params = {};
|
||||||
|
params.userId = Number(sessionStorage.getItem('userId'));
|
||||||
|
params.userName = sessionStorage.getItem('userName');
|
||||||
|
params.sendTo = this.sendTo;
|
||||||
|
params.pictures = this.pictures;
|
||||||
|
params.attachments = this.attachments;
|
||||||
|
params.header = this.template.header;
|
||||||
|
params.contents = this.template.contents;
|
||||||
|
this.$axios.post(api.ADD_REPORT.url, params).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message.success(res.data.msg);
|
||||||
|
this.findTempl();
|
||||||
|
this.findTempl();
|
||||||
|
this.fileList = [];
|
||||||
|
this.previewVisible = false;
|
||||||
|
this.previewImage = '';
|
||||||
|
this.pictures = [];
|
||||||
|
this.fileList2 = [];
|
||||||
|
this.template = {};
|
||||||
|
this.userList = [];
|
||||||
|
this.attachments = [];
|
||||||
|
this.sendTo = [];
|
||||||
|
this.sends = [];
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
editor() {
|
||||||
|
return this.$refs.myQuillEditor.quill;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style xml:lang="less">
|
||||||
|
.ql-toolbar {
|
||||||
|
position: fixed;
|
||||||
|
top: 104px;
|
||||||
|
background-color: white;
|
||||||
|
width: calc(100% - 270px);
|
||||||
|
left: 260px;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 1px 2px 1px 1px rgba(144,144,144,0.1);
|
||||||
|
}
|
||||||
|
.quill-editor {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
.ql-toolbar.ql-snow .ql-picker.ql-expanded .ql-picker-options {
|
||||||
|
z-index: 3;
|
||||||
|
top: 33px;
|
||||||
|
}
|
||||||
|
.ql-snow .ql-tooltip {
|
||||||
|
left: 0!important;
|
||||||
|
}
|
||||||
|
.header_write {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.canSubmit > div {
|
||||||
|
border-color: #d9d9d9;
|
||||||
|
}
|
||||||
|
.cannotSubmit > div {
|
||||||
|
border-color: red;
|
||||||
|
}
|
||||||
|
.content_wri {
|
||||||
|
margin: 50px 0;
|
||||||
|
}
|
||||||
|
.title_weight {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.commit_button {
|
||||||
|
width: 400px;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,328 @@
|
||||||
|
<template>
|
||||||
|
<a-layout class="content">
|
||||||
|
<a-layout-header class="header">
|
||||||
|
<div>
|
||||||
|
<div class="title_nav">
|
||||||
|
周报系统
|
||||||
|
</div>
|
||||||
|
<div @click="toggleCollapsed" class="control_button">
|
||||||
|
<a-icon :type="collapsed ? 'menu-unfold' : 'menu-fold'" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tip_div">
|
||||||
|
欢迎您:
|
||||||
|
<span class="tip_div_nickName">{{nickName}}</span>|
|
||||||
|
<span @click="logout" class="logout_span">注销</span>
|
||||||
|
</div>
|
||||||
|
</a-layout-header>
|
||||||
|
<a-layout>
|
||||||
|
<div class="left_div_nav">
|
||||||
|
<div :class="left_div">
|
||||||
|
<a-menu
|
||||||
|
class="menu_nav"
|
||||||
|
mode="inline"
|
||||||
|
theme="dark"
|
||||||
|
:inline-collapsed="collapsed"
|
||||||
|
style="text-align: left"
|
||||||
|
@click="menuClick"
|
||||||
|
:defaultSelectedKeys="defaultSelectedKeys"
|
||||||
|
:defaultOpenKeys="[1,6]"
|
||||||
|
>
|
||||||
|
<template v-for="item in menuList">
|
||||||
|
<a-menu-item v-if="!item.children" :key="item.ID" :title="item.name">
|
||||||
|
<a-icon type="pie-chart" />
|
||||||
|
<span>{{ item.name }}</span>
|
||||||
|
</a-menu-item>
|
||||||
|
<sub-menu v-else :key="item.ID" :menu-info="item" />
|
||||||
|
</template>
|
||||||
|
</a-menu>
|
||||||
|
</div>
|
||||||
|
<div :class="right_div" class="right_div_nav">
|
||||||
|
<div class="current_div">
|
||||||
|
<span class="current_span">当前位置:</span>
|
||||||
|
<span>{{location}}</span>
|
||||||
|
</div>
|
||||||
|
<a-layout class="layout_nav">
|
||||||
|
<a-layout-content
|
||||||
|
:style="{ background: '#fff', padding: '20px', margin: 0, minHeight: '280px' }"
|
||||||
|
>
|
||||||
|
<router-view></router-view>
|
||||||
|
</a-layout-content>
|
||||||
|
</a-layout>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-layout>
|
||||||
|
</a-layout>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { Menu } from 'ant-design-vue';
|
||||||
|
import api from '../../utils/api';
|
||||||
|
|
||||||
|
const SubMenu = {
|
||||||
|
template: `
|
||||||
|
<a-sub-menu :key="menuInfo.ID" v-bind="$props" v-on="$listeners">
|
||||||
|
<span slot="title" :title="menuInfo.name">
|
||||||
|
<a-icon :type="menuInfo.icon" /><span>{{ menuInfo.name }}</span>
|
||||||
|
</span>
|
||||||
|
<template v-for="item in menuInfo.children">
|
||||||
|
<a-menu-item v-if="!item.children" :key="item.ID" :title="item.name">
|
||||||
|
<a-icon :type="item.icon" />
|
||||||
|
<span>{{ item.name }}</span>
|
||||||
|
</a-menu-item>
|
||||||
|
<sub-menu v-else :key="item.ID" :menu-info="item" />
|
||||||
|
</template>
|
||||||
|
</a-sub-menu>
|
||||||
|
`,
|
||||||
|
name: 'SubMenu',
|
||||||
|
// must add isSubMenu: true
|
||||||
|
isSubMenu: true,
|
||||||
|
props: {
|
||||||
|
...Menu.SubMenu.props,
|
||||||
|
// Cannot overlap with properties within Menu.SubMenu.props
|
||||||
|
menuInfo: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
'sub-menu': SubMenu,
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// 监听vuex
|
||||||
|
'$store.state.pageRouterData.location' (newval) {
|
||||||
|
this.location = newval;
|
||||||
|
},
|
||||||
|
'$store.state.pageRouterData.defaultSelectedKeys' (newval) {
|
||||||
|
this.defaultSelectedKeys = newval;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name: "Navigation",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
collapsed: false,
|
||||||
|
left_div: 'left_div_open',
|
||||||
|
right_div: 'right_div_open',
|
||||||
|
location: this.$store.state.pageRouterData.location,
|
||||||
|
defaultSelectedKeys: this.$store.state.pageRouterData.defaultSelectedKeys,
|
||||||
|
menuList: [],
|
||||||
|
// 当前登录用户
|
||||||
|
nickName: sessionStorage.getItem('nickName'),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
setTimeout(this.findMenuList(), 1000);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 路由跳转
|
||||||
|
trip(name, path) {
|
||||||
|
this.location = name;
|
||||||
|
this.$router.push(path);
|
||||||
|
},
|
||||||
|
toggleCollapsed() {
|
||||||
|
this.collapsed = !this.collapsed;
|
||||||
|
if (this.left_div === 'left_div_open') {
|
||||||
|
this.left_div = 'left_div_close';
|
||||||
|
this.right_div = 'right_div_close';
|
||||||
|
|
||||||
|
if (document.getElementsByClassName('ql-toolbar').length > 0) {
|
||||||
|
document.getElementsByClassName('ql-toolbar').forEach(li => {
|
||||||
|
li.style.left = '90px';
|
||||||
|
li.style.width = 'calc(100% - 100px)';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else{
|
||||||
|
this.left_div = 'left_div_open';
|
||||||
|
this.right_div = 'right_div_open';
|
||||||
|
document.getElementsByClassName('ql-toolbar').forEach(li => {
|
||||||
|
li.style.left = '260px';
|
||||||
|
li.style.width = 'calc(100% - 270px)';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
findMenuList() {
|
||||||
|
this.$axios.defaults.headers.common['x-token'] = sessionStorage.getItem('login');
|
||||||
|
this.$axios.defaults.headers.common['x-user-id'] = sessionStorage.getItem('userId');
|
||||||
|
this.$axios.post(api.GET_MENU.url).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.menuList = res.data.data.menus;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
logout() {
|
||||||
|
sessionStorage.clear();
|
||||||
|
this.$store.commit('pageRouterData/setLocation', '查看周报');
|
||||||
|
this.$store.commit('pageRouterData/setDefaultSelectedKeys', [2]);
|
||||||
|
this.$router.push('/login');
|
||||||
|
},
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
menuClick({ item, key }) {
|
||||||
|
this.getCheckedNodes(this.menuList, key);
|
||||||
|
const keyArray = [key];
|
||||||
|
this.$store.commit('pageRouterData/setDefaultSelectedKeys', keyArray);
|
||||||
|
},
|
||||||
|
getCheckedNodes(data, value) {
|
||||||
|
data.forEach(item => {
|
||||||
|
if (item.ID === value) {
|
||||||
|
this.$store.commit('pageRouterData/setLocation', item.name);
|
||||||
|
this.trip(item.name, item.path);
|
||||||
|
} else {
|
||||||
|
if (item.children && item.children.length > 0) {
|
||||||
|
this.getCheckedNodes(item.children, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.content {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
section {
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: rgba(255, 255, 255, 0.4);
|
||||||
|
}
|
||||||
|
.left_div_open {
|
||||||
|
width: 250px;
|
||||||
|
background-color: rgb(0, 21, 41);
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.left_div_close {
|
||||||
|
width: 80px;
|
||||||
|
background-color: rgb(0, 21, 41);
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
.right_div_open {
|
||||||
|
width: calc(100% - 250px)
|
||||||
|
}
|
||||||
|
.right_div_close {
|
||||||
|
width: calc(100% - 80px)
|
||||||
|
}
|
||||||
|
.title_nav {
|
||||||
|
color: white;
|
||||||
|
font-size: 25px;
|
||||||
|
font-weight: 600;
|
||||||
|
text-align: left;
|
||||||
|
margin-left: -25px;
|
||||||
|
width: 225px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.control_button {
|
||||||
|
float: left;
|
||||||
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style xml:lang="less">
|
||||||
|
.ant-layout-header {
|
||||||
|
height: 64px;
|
||||||
|
padding: 0 50px;
|
||||||
|
line-height: 64px;
|
||||||
|
background: #0a42ab!important;
|
||||||
|
}
|
||||||
|
.__tabs {
|
||||||
|
display: -webkit-box;
|
||||||
|
margin-top: -1px;
|
||||||
|
width: 100%;
|
||||||
|
overflow-x: hidden;
|
||||||
|
}
|
||||||
|
.__tab-item {
|
||||||
|
white-space: nowrap;
|
||||||
|
padding: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
border: 1px solid #cccccc4d;
|
||||||
|
border-left: none;
|
||||||
|
border-bottom: 0;
|
||||||
|
line-height: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1),
|
||||||
|
padding 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.el-icon-close {
|
||||||
|
width: 12px;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
.__is-active {
|
||||||
|
border-bottom: 2px solid #409eff;
|
||||||
|
color: #409eff;
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
}
|
||||||
|
.__is-active .el-icon-close {
|
||||||
|
width: 12px;
|
||||||
|
margin-right: 0;
|
||||||
|
margin-left: 2px;
|
||||||
|
}
|
||||||
|
.__contextmenu {
|
||||||
|
margin: 0;
|
||||||
|
border: 1px solid #e4e7ed;
|
||||||
|
background: #fff;
|
||||||
|
z-index: 3000;
|
||||||
|
position: absolute;
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 5px 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #333;
|
||||||
|
box-shadow: 1px 1px 3px 0 rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
.__contextmenu li {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.__contextmenu li :hover {
|
||||||
|
background: #f2f2f2;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.__contextmenu li button {
|
||||||
|
color: #2c3e50;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.ant-menu-item {
|
||||||
|
margin: 0!important;
|
||||||
|
}
|
||||||
|
.tip_div {
|
||||||
|
float: right;
|
||||||
|
color: white;
|
||||||
|
width: 180px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.tip_div_nickName {
|
||||||
|
margin-right: 10px
|
||||||
|
}
|
||||||
|
.logout_span {
|
||||||
|
margin-left: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.left_div_nav {
|
||||||
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.right_div_nav {
|
||||||
|
background-color: rgba(231, 234, 237, 0.3);
|
||||||
|
}
|
||||||
|
.current_div {
|
||||||
|
background-color: white;
|
||||||
|
height: 30px;
|
||||||
|
text-align: left;
|
||||||
|
line-height: 30px;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.current_span {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 14px;
|
||||||
|
padding-left: 10px;
|
||||||
|
}
|
||||||
|
.layout_nav {
|
||||||
|
margin: 10px;
|
||||||
|
height: calc(100% - 50px);
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,283 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="rule_div">设定规则</div>
|
||||||
|
<div>
|
||||||
|
<span>需要提交人</span>
|
||||||
|
<a-select
|
||||||
|
mode="multiple"
|
||||||
|
class="select_sta"
|
||||||
|
placeholder="请选择人员"
|
||||||
|
@change="userChange"
|
||||||
|
v-model="sends"
|
||||||
|
>
|
||||||
|
<a-select-option v-for="li in userList" :key="li.ID">
|
||||||
|
{{li.nickName}}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="main_sta_div">
|
||||||
|
<span class="time_sta_span">起止时间</span>
|
||||||
|
<a-select v-model="startWeek" class="select_sta_time">
|
||||||
|
<a-select-option :value="1">
|
||||||
|
周一
|
||||||
|
</a-select-option>
|
||||||
|
<a-select-option :value="2">
|
||||||
|
周二
|
||||||
|
</a-select-option>
|
||||||
|
<a-select-option :value="3">
|
||||||
|
周三
|
||||||
|
</a-select-option>
|
||||||
|
<a-select-option :value="4">
|
||||||
|
周四
|
||||||
|
</a-select-option>
|
||||||
|
<a-select-option :value="5">
|
||||||
|
周五
|
||||||
|
</a-select-option>
|
||||||
|
<a-select-option :value="6">
|
||||||
|
周六
|
||||||
|
</a-select-option>
|
||||||
|
<a-select-option :value="7">
|
||||||
|
周日
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
|
||||||
|
<a-select v-model="startHour" class="select_str">
|
||||||
|
<a-select-option :key="0">
|
||||||
|
0:00
|
||||||
|
</a-select-option>
|
||||||
|
<a-select-option v-for="li in 23" :key="li">
|
||||||
|
{{li}}:00
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
|
||||||
|
<span style="margin-left: 20px">~</span>
|
||||||
|
|
||||||
|
<a-select v-model="endWeek" class="select_str">
|
||||||
|
<a-select-option :value="1">
|
||||||
|
周一
|
||||||
|
</a-select-option>
|
||||||
|
<a-select-option :value="2">
|
||||||
|
周二
|
||||||
|
</a-select-option>
|
||||||
|
<a-select-option :value="3">
|
||||||
|
周三
|
||||||
|
</a-select-option>
|
||||||
|
<a-select-option :value="4">
|
||||||
|
周四
|
||||||
|
</a-select-option>
|
||||||
|
<a-select-option :value="5">
|
||||||
|
周五
|
||||||
|
</a-select-option>
|
||||||
|
<a-select-option :value="6">
|
||||||
|
周六
|
||||||
|
</a-select-option>
|
||||||
|
<a-select-option :value="7">
|
||||||
|
周日
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
|
||||||
|
<a-select v-model="endHour" style="width: 80px; margin-left: 10px">
|
||||||
|
<a-select-option :key="0">
|
||||||
|
0:00
|
||||||
|
</a-select-option>
|
||||||
|
<a-select-option v-for="li in 23" :key="li">
|
||||||
|
{{li}}:00
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
|
||||||
|
<a-button type="primary" @click="submitData" style="margin-left: 20px"> 提交 </a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import api from '../../utils/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "StatisticalRules",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isCreate: true,
|
||||||
|
// 人员列表
|
||||||
|
userList: [],
|
||||||
|
sends: [],
|
||||||
|
reporters: [],
|
||||||
|
// 全选id
|
||||||
|
allId: [],
|
||||||
|
startWeek: '',
|
||||||
|
startHour: '',
|
||||||
|
endWeek: '',
|
||||||
|
endHour: '',
|
||||||
|
editId: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.findDataList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
findDataList() {
|
||||||
|
const params = {};
|
||||||
|
params.page = 1;
|
||||||
|
params.pageSize = 99999;
|
||||||
|
this.$axios.post(api.GET_USER_LIST.url, params).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
let data = [];
|
||||||
|
const li = {};
|
||||||
|
li.ID = 0;
|
||||||
|
li.userName = '全部';
|
||||||
|
data.push(li);
|
||||||
|
data = data.concat(res.data.data.list);
|
||||||
|
this.userList = data;
|
||||||
|
|
||||||
|
const all = [];
|
||||||
|
res.data.data.list.forEach(li => {
|
||||||
|
all.push(li.ID);
|
||||||
|
});
|
||||||
|
this.allId = all;
|
||||||
|
|
||||||
|
this.$axios.get(api.FIND_RULE_LIST.url + `?page=1&pageSize=1&userId=${sessionStorage.getItem('userId')}`).then(resp => {
|
||||||
|
if (resp.data.code === 0) {
|
||||||
|
if (resp.data.data.list) {
|
||||||
|
this.isCreate = false;
|
||||||
|
this.editId = resp.data.data.list[0].ID;
|
||||||
|
this.startWeek = resp.data.data.list[0].startWeek;
|
||||||
|
this.startHour = resp.data.data.list[0].startHour;
|
||||||
|
this.endWeek = resp.data.data.list[0].endWeek;
|
||||||
|
this.endHour = resp.data.data.list[0].endHour;
|
||||||
|
|
||||||
|
const user = [];
|
||||||
|
const temp = [];
|
||||||
|
|
||||||
|
for (const li of resp.data.data.list[0].reporters) {
|
||||||
|
let flag = false;
|
||||||
|
for (const tr of this.userList) {
|
||||||
|
if (tr.ID === li.id) {
|
||||||
|
flag = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!flag) {
|
||||||
|
const da = {};
|
||||||
|
da.ID = li.id;
|
||||||
|
da.userName = li.name;
|
||||||
|
this.userList.push(da);
|
||||||
|
}
|
||||||
|
user.push(li.id);
|
||||||
|
|
||||||
|
const data = {};
|
||||||
|
data.id = li.id;
|
||||||
|
data.name = li.name;
|
||||||
|
temp.push(data);
|
||||||
|
}
|
||||||
|
this.sends = user;
|
||||||
|
this.reporters = temp;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$message.error(resp.data.msg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
userChange(select) {
|
||||||
|
let flag = false;
|
||||||
|
select.forEach(li => {
|
||||||
|
if (li === 0) {
|
||||||
|
flag = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const temp = [];
|
||||||
|
if (flag) {
|
||||||
|
this.sends = this.allId;
|
||||||
|
this.userList.forEach(li => {
|
||||||
|
if (li.ID !== 0) {
|
||||||
|
const data = {};
|
||||||
|
data.id = li.ID;
|
||||||
|
data.name = li.userName;
|
||||||
|
temp.push(data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
if (select.length > 0) {
|
||||||
|
this.userList.forEach(li => {
|
||||||
|
select.forEach(id => {
|
||||||
|
if (li.ID === id) {
|
||||||
|
const data = {};
|
||||||
|
data.id = id;
|
||||||
|
data.name = li.userName;
|
||||||
|
temp.push(data);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.reporters = temp;
|
||||||
|
},
|
||||||
|
submitData() {
|
||||||
|
if (this.isCreate) {
|
||||||
|
// 新增
|
||||||
|
const params = {};
|
||||||
|
params.userId = Number(sessionStorage.getItem('userId'));
|
||||||
|
params.startWeek = this.startWeek;
|
||||||
|
params.startHour = this.startHour;
|
||||||
|
params.endWeek = this.endWeek;
|
||||||
|
params.endHour = this.endHour;
|
||||||
|
params.reporters = this.reporters;
|
||||||
|
this.$axios.post(api.ADD_RULE.url, params).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message.success(res.data.msg);
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 编辑
|
||||||
|
const params = {};
|
||||||
|
params.ID = this.editId;
|
||||||
|
params.userId = Number(sessionStorage.getItem('userId'));
|
||||||
|
params.startWeek = this.startWeek;
|
||||||
|
params.startHour = this.startHour;
|
||||||
|
params.endWeek = this.endWeek;
|
||||||
|
params.endHour = this.endHour;
|
||||||
|
params.reporters = this.reporters;
|
||||||
|
this.$axios.put(api.UPDATE_RULE.url, params).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message.success(res.data.msg);
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style xml:lang="less">
|
||||||
|
.rule_div {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.select_sta {
|
||||||
|
width: 500px;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
.main_sta_div {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
.time_sta_span {
|
||||||
|
margin-left: 14px;
|
||||||
|
}
|
||||||
|
.select_sta_time {
|
||||||
|
width: 80px;
|
||||||
|
margin-left: 20px;
|
||||||
|
}
|
||||||
|
.select_str {
|
||||||
|
width: 80px;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,286 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div style="height: 50px">
|
||||||
|
<a-button type="primary" @click="openAdd" style="float: right">
|
||||||
|
<a-icon type="plus" />
|
||||||
|
新增
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<a-table :columns="columns" :data-source="tableList" rowKey="ID" :pagination="pagination" @change="findUserList">
|
||||||
|
<template slot="authorityId" slot-scope="text, li">
|
||||||
|
<span v-for="al in authorityList" :key="al.ID">
|
||||||
|
<span v-if="al.authorityId === li.authorityId">{{al.authorityName}}</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<span slot="action" slot-scope="text, li">
|
||||||
|
<a @click="openEdit(li)">编辑</a>
|
||||||
|
<a-divider type="vertical" />
|
||||||
|
<a @click="openDelete(li)">删除</a>
|
||||||
|
</span>
|
||||||
|
</a-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a-modal v-model="addVisible" title="新增用户" @ok="submitAdd">
|
||||||
|
<a-form :form="addForm" :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }">
|
||||||
|
<a-form-item label="用户名">
|
||||||
|
<a-input v-decorator="[ 'username', { rules: [{ required: true, message: '用户名不能为空!' }] }, ]"
|
||||||
|
type="text"
|
||||||
|
placeholder="请输入用户名" class="input_width_use">
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="昵称">
|
||||||
|
<a-input v-decorator="[ 'nickname', { rules: [{ required: true, message: '昵称不能为空!' }] }, ]"
|
||||||
|
type="text"
|
||||||
|
placeholder="请输入昵称" class="input_width_use">
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="密码">
|
||||||
|
<a-input v-decorator="[ 'password', { rules: [{ required: true, message: '密码不能为空!' }] }, ]"
|
||||||
|
type="password"
|
||||||
|
placeholder="请输入密码" class="input_width_use">
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="角色">
|
||||||
|
<a-select style="width: 320px"
|
||||||
|
placeholder="请输入角色"
|
||||||
|
v-decorator="[ 'authorityId', { rules: [{ required: true, message: '角色不能为空!' }] }, ]"
|
||||||
|
@change="addAuthorityChange">
|
||||||
|
<a-select-option v-for="li in authorityList" :key="li.authorityId">
|
||||||
|
{{ li.authorityName }}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
|
||||||
|
<a-modal v-model="editVisible" title="编辑用户" @ok="submitEdit">
|
||||||
|
<a-form :form="editForm" :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }">
|
||||||
|
<a-input v-decorator="['ID']"
|
||||||
|
type="text" class="input_width_use" style="display: none">
|
||||||
|
</a-input>
|
||||||
|
<a-form-item label="用户名">
|
||||||
|
<a-input v-decorator="[ 'username', { rules: [{ required: true, message: '用户名不能为空!' }] }, ]"
|
||||||
|
type="text"
|
||||||
|
:disabled="true"
|
||||||
|
placeholder="请输入用户名" class="input_width_use">
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="昵称">
|
||||||
|
<a-input v-decorator="[ 'nickname', { rules: [{ required: true, message: '昵称不能为空!' }] }, ]"
|
||||||
|
type="text"
|
||||||
|
placeholder="请输入昵称" class="input_width_use">
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="密码">
|
||||||
|
<a-input v-decorator="[ 'password', { rules: [{ required: true, message: '密码不能为空!' }] }, ]"
|
||||||
|
type="password"
|
||||||
|
placeholder="请输入密码" class="input_width_use">
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="角色">
|
||||||
|
<a-select style="width: 320px"
|
||||||
|
placeholder="请输入角色"
|
||||||
|
v-decorator="[ 'authorityId', { rules: [{ required: true, message: '角色不能为空!' }] }, ]"
|
||||||
|
@change="editAuthorityChange">
|
||||||
|
<a-select-option v-for="li in authorityList" :key="li.authorityId">
|
||||||
|
{{ li.authorityName }}
|
||||||
|
</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import api from '../../utils/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "UserManagement",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
title: '用户名',
|
||||||
|
dataIndex: 'userName',
|
||||||
|
key: 'userName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '昵称',
|
||||||
|
dataIndex: 'nickName',
|
||||||
|
key: 'nickName',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '角色',
|
||||||
|
dataIndex: 'authorityId',
|
||||||
|
key: 'authorityId',
|
||||||
|
scopedSlots: { customRender: 'authorityId' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '操作',
|
||||||
|
key: 'action',
|
||||||
|
scopedSlots: { customRender: 'action' },
|
||||||
|
},
|
||||||
|
],
|
||||||
|
authorityList: [],
|
||||||
|
tableList: [],
|
||||||
|
pagination: {
|
||||||
|
total: 0,
|
||||||
|
defaultCurrent: 1,
|
||||||
|
defaultPageSize: 10,
|
||||||
|
showSizeChanger: true,
|
||||||
|
pageSizeOptions: ['10', '20', '50', '100'],
|
||||||
|
onShowSizeChange: (current, pageSize) => {
|
||||||
|
this.pagination.defaultCurrent = current;
|
||||||
|
this.pagination.defaultPageSize = pageSize;
|
||||||
|
},
|
||||||
|
onChange: (current, pageSize) => {
|
||||||
|
this.pagination.defaultCurrent = current;
|
||||||
|
this.pagination.defaultPageSize = pageSize;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
page: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
addVisible: false,
|
||||||
|
addForm: this.$form.createForm(this, { name: 'addUser' }),
|
||||||
|
addAuthorityIds: [],
|
||||||
|
|
||||||
|
editVisible: false,
|
||||||
|
editData: '',
|
||||||
|
editForm: this.$form.createForm(this, { name: 'editUser' }),
|
||||||
|
editAuthorityIds: [],
|
||||||
|
|
||||||
|
oldPassword: '',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.findUserList();
|
||||||
|
this.findAuthorityList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
findUserList() {
|
||||||
|
const params = {};
|
||||||
|
params.page = this.pagination.defaultCurrent;
|
||||||
|
params.pageSize = this.pagination.defaultPageSize;
|
||||||
|
this.$axios.post(api.GET_USER_LIST.url, params).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.tableList = res.data.data.list;
|
||||||
|
this.pagination.total = res.data.data.total;
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
this.pagination.total = 0;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 获取角色列表
|
||||||
|
findAuthorityList() {
|
||||||
|
const params = {};
|
||||||
|
params.page = 1;
|
||||||
|
params.pageSize = 9999;
|
||||||
|
this.$axios.post(api.GET_AUTHORITY_LIST.url, params).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.authorityList = res.data.data.list;
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 新增用户
|
||||||
|
openAdd() {
|
||||||
|
this.addForm.resetFields();
|
||||||
|
this.addVisible = true;
|
||||||
|
},
|
||||||
|
addAuthorityChange(value) {
|
||||||
|
this.addAuthorityIds = [value];
|
||||||
|
},
|
||||||
|
submitAdd(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.addForm.validateFields((err, values) => {
|
||||||
|
values.authorityIds = this.addAuthorityIds;
|
||||||
|
if (!err) {
|
||||||
|
this.$axios.post(api.ADD_USER.url, values).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message.success('新增成功!');
|
||||||
|
this.addForm.resetFields();
|
||||||
|
this.addVisible = false;
|
||||||
|
this.findUserList();
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 编辑用户
|
||||||
|
openEdit(data) {
|
||||||
|
this.editForm.resetFields();
|
||||||
|
this.editVisible = true;
|
||||||
|
this.editData = data;
|
||||||
|
|
||||||
|
this.oldPassword = data.password;
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.editForm.setFieldsValue({
|
||||||
|
ID: data.ID,
|
||||||
|
username: data.userName,
|
||||||
|
nickname: data.nickName,
|
||||||
|
password: data.password,
|
||||||
|
authorityId: data.authorityId
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.editAuthorityIds = [data.authorityId];
|
||||||
|
},
|
||||||
|
editAuthorityChange(value) {
|
||||||
|
this.editAuthorityIds = [value];
|
||||||
|
},
|
||||||
|
submitEdit(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
this.editForm.validateFields((err, values) => {
|
||||||
|
values.ID = this.editData.ID;
|
||||||
|
values.authorityIds = this.editAuthorityIds;
|
||||||
|
|
||||||
|
if (this.oldPassword === values.password) {
|
||||||
|
values.password = null;
|
||||||
|
}
|
||||||
|
if (!err) {
|
||||||
|
this.$axios.put(api.EDIT_USER.url, values).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message.success('编辑成功!');
|
||||||
|
this.editForm.resetFields();
|
||||||
|
this.editVisible = false;
|
||||||
|
this.findUserList();
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 删除用户
|
||||||
|
openDelete(data) {
|
||||||
|
this.$confirm({
|
||||||
|
title: '提示信息:',
|
||||||
|
content: '确定删除数据?',
|
||||||
|
onOk: () => this.submitDelete(data)
|
||||||
|
});
|
||||||
|
},
|
||||||
|
submitDelete(data) {
|
||||||
|
this.$axios.delete(api.DELETE_USER.url, {data: {ID: data.ID}}).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.$message.success('删除成功!');
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
this.findUserList();
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style xml:lang="less">
|
||||||
|
.input_width_use {
|
||||||
|
width: 320px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,96 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<a-form :form="form" class="edit_password">
|
||||||
|
<a-form-item label="当前密码">
|
||||||
|
<a-input v-decorator="['oldPassword',{rules: [{required: true,message: '请输入当前密码',}],},]"
|
||||||
|
type="password"
|
||||||
|
required="true"
|
||||||
|
placeholder="请输入当前密码" class="input_width_pass">
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="新密码">
|
||||||
|
<a-input v-decorator="['password1',{rules: [{required: true,message: '请输入密码',},{validator: validateToNextPassword}]}]"
|
||||||
|
type="password"
|
||||||
|
placeholder="请输入新密码" class="input_width_pass">
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="确认密码">
|
||||||
|
<a-input v-decorator="['password2',{rules: [{required: true,message: '请输入密码',},{validator: compareToFirstPassword}]}]"
|
||||||
|
type="password"
|
||||||
|
placeholder="请输入新密码" class="input_width_pass">
|
||||||
|
</a-input>
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item label="">
|
||||||
|
<a-button type="primary" @click="submitPassword" style="margin-left: 210px">
|
||||||
|
确定
|
||||||
|
</a-button>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import api from '../../utils/api'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "UserPassword",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 编辑
|
||||||
|
editVisible: false,
|
||||||
|
form: this.$form.createForm(this, { name: 'editPassword' }),
|
||||||
|
confirmDirty: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
compareToFirstPassword(rule, value, callback) {
|
||||||
|
const form = this.form;
|
||||||
|
if (value && value !== form.getFieldValue('password1')) {
|
||||||
|
callback('两次密码不一致');
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
validateToNextPassword(rule, value, callback) {
|
||||||
|
const form = this.form;
|
||||||
|
if (value && this.confirmDirty) {
|
||||||
|
form.validateFields(['password2'], { force: true });
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
},
|
||||||
|
// 修改账户密码提交事件
|
||||||
|
submitPassword(e) {
|
||||||
|
// 阻止与事件关联的默认动作
|
||||||
|
e.preventDefault();
|
||||||
|
this.form.validateFields((err, values) => {
|
||||||
|
const loginData = {};
|
||||||
|
loginData.username = sessionStorage.getItem('userName');
|
||||||
|
loginData.password = values.oldPassword;
|
||||||
|
loginData.newPassword = values.password1;
|
||||||
|
if (!err) {
|
||||||
|
this.$axios.post(api.CHANGE_PASSWORD.url, loginData).then(res => {
|
||||||
|
if (res.data.code === 0) {
|
||||||
|
this.form.resetFields();
|
||||||
|
this.$message.success(res.data.msg);
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.data.msg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style xml:lang="less">
|
||||||
|
.edit_password > .ant-form-item {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.edit_password > .ant-form-item > .ant-form-item-label {
|
||||||
|
width: 100px;
|
||||||
|
}
|
||||||
|
.input_width_pass {
|
||||||
|
width: 320px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,55 @@
|
||||||
|
import Vue from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
import axios from 'axios'
|
||||||
|
import Antd from 'ant-design-vue'
|
||||||
|
// 原ant-design css
|
||||||
|
import 'ant-design-vue/dist/antd.css'
|
||||||
|
// 自定义全局主题样式
|
||||||
|
import './theam/ant-design-vue.js'
|
||||||
|
import cryptos from './utils/crypto'
|
||||||
|
import global_variable from "./utils/global_variable";
|
||||||
|
// 路由
|
||||||
|
import router from './router'
|
||||||
|
// vuex
|
||||||
|
import store from './store/index.js'
|
||||||
|
import Vuex from 'vuex'
|
||||||
|
|
||||||
|
Vue.config.productionTip = false;
|
||||||
|
|
||||||
|
const instance = axios.create({
|
||||||
|
baseURL: '/week'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 配置过滤response
|
||||||
|
instance.interceptors.response.use((response) => {
|
||||||
|
if (response) {
|
||||||
|
if (response.data.code === 'FALSE') {
|
||||||
|
return 'FALSE';
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
}, error => {
|
||||||
|
return Promise.reject(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 跨域请求时是否需要使用凭证
|
||||||
|
instance.defaults.withCredentials = true;
|
||||||
|
|
||||||
|
instance.defaults.headers.post['Content-Type'] = 'application/json';
|
||||||
|
instance.defaults.headers.get['Content-Type'] = 'application/json';
|
||||||
|
|
||||||
|
// 配置请求头
|
||||||
|
instance.defaults.headers.common['x-token'] = sessionStorage.getItem('login');
|
||||||
|
instance.defaults.headers.common['x-user-id'] = sessionStorage.getItem('userId');
|
||||||
|
|
||||||
|
Vue.prototype.$axios = instance;
|
||||||
|
Vue.use(Antd);
|
||||||
|
Vue.prototype.cryptos = cryptos;
|
||||||
|
Vue.prototype.BASEURL = global_variable.baseURL;
|
||||||
|
Vue.use(Vuex);
|
||||||
|
|
||||||
|
new Vue({
|
||||||
|
router,
|
||||||
|
store,
|
||||||
|
render: h => h(App),
|
||||||
|
}).$mount('#app');
|
|
@ -0,0 +1,105 @@
|
||||||
|
import Vue from 'vue'
|
||||||
|
import Router from 'vue-router'
|
||||||
|
|
||||||
|
Vue.use(Router);
|
||||||
|
|
||||||
|
const router = new Router(
|
||||||
|
{
|
||||||
|
mode: 'history',
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
redirect: '/mainComponent',
|
||||||
|
meta: { title: '第一个展示的页面' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/main',
|
||||||
|
component: () => import('../components/navigation/Navigation.vue'),
|
||||||
|
meta: { title: '侧边栏仪表板' },
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '/mainComponent',
|
||||||
|
component: () => import('../components/main/MainComponent.vue'),
|
||||||
|
meta: { title: '主页面' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/viewWeeklyReport',
|
||||||
|
component: () => import('../components/main/MainComponent.vue'),
|
||||||
|
meta: { title: '查看周报' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/writeWeeklyReport',
|
||||||
|
component: () => import('../components/main/WriteWeeklyReport.vue'),
|
||||||
|
meta: { title: '写周报' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/editWeeklyReport',
|
||||||
|
component: () => import('../components/main/InfoComponent.vue'),
|
||||||
|
meta: { title: '编辑周报' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/statisticalExport',
|
||||||
|
component: () => import('../components/main/StatisticalExport.vue'),
|
||||||
|
meta: { title: '统计导出' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/templateEditing',
|
||||||
|
component: () => import('../components/main/TemplateEditing.vue'),
|
||||||
|
meta: { title: '模板编辑' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/userPassword',
|
||||||
|
component: () => import('../components/setUp/UserPassword.vue'),
|
||||||
|
meta: { title: '用户密码' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/statisticalRules',
|
||||||
|
component: () => import('../components/setUp/StatisticalRules.vue'),
|
||||||
|
meta: { title: '统计规则' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/userManagement',
|
||||||
|
component: () => import('../components/setUp/UserManagement.vue'),
|
||||||
|
meta: { title: '用户管理' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/test',
|
||||||
|
component: () => import('../components/test/TestComponent.vue'),
|
||||||
|
meta: { title: '测试页面' }
|
||||||
|
},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/login',
|
||||||
|
component: () => import('../components/login/LoginComponent.vue'),
|
||||||
|
meta: { title: '登录页' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '*',
|
||||||
|
redirect: '/404'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
// 获取session中存储的用户登录数据
|
||||||
|
let isLogin = sessionStorage.getItem('login');
|
||||||
|
if (isLogin) {
|
||||||
|
next();
|
||||||
|
} else {
|
||||||
|
if (to.path === '/login') {
|
||||||
|
next();
|
||||||
|
} else {
|
||||||
|
next('/login');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 解决重复路由报红问题
|
||||||
|
const originalPush = Router.prototype.push;
|
||||||
|
Router.prototype.push = function push (location) {
|
||||||
|
return originalPush.call(this, location).catch(err => err)
|
||||||
|
};
|
||||||
|
|
||||||
|
export default router
|
|
@ -0,0 +1,18 @@
|
||||||
|
import Vue from 'vue'
|
||||||
|
import Vuex from 'vuex'
|
||||||
|
import pageRouterData from './modules/pageRouterData'
|
||||||
|
import createPersistedState from 'vuex-persistedstate'
|
||||||
|
|
||||||
|
Vue.use(Vuex);
|
||||||
|
|
||||||
|
export default new Vuex.Store({
|
||||||
|
modules: {
|
||||||
|
pageRouterData,
|
||||||
|
},
|
||||||
|
state: {},
|
||||||
|
mutations: {},
|
||||||
|
// vuex持久化插件
|
||||||
|
plugins: [createPersistedState(
|
||||||
|
{storage: window.sessionStorage}
|
||||||
|
)]
|
||||||
|
})
|
|
@ -0,0 +1,17 @@
|
||||||
|
export default({
|
||||||
|
namespaced: true,
|
||||||
|
state: {
|
||||||
|
location: '',
|
||||||
|
defaultSelectedKeys: [2],
|
||||||
|
},
|
||||||
|
getters: {},
|
||||||
|
mutations: {
|
||||||
|
setLocation (state, data) {
|
||||||
|
state.location = data;
|
||||||
|
},
|
||||||
|
setDefaultSelectedKeys (state, data) {
|
||||||
|
state.defaultSelectedKeys = data;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {}
|
||||||
|
})
|
|
@ -0,0 +1,4 @@
|
||||||
|
import Vue from 'vue'
|
||||||
|
import Antd from 'ant-design-vue'
|
||||||
|
import './antd-variables.less'
|
||||||
|
Vue.use(Antd);
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
Write your variables here. All available variables can be
|
||||||
|
found in https://github.com/vueComponent/ant-design-vue/blob/master/components/style/themes/default.less.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@import '~ant-design-vue/dist/antd.less';
|
||||||
|
|
||||||
|
// Here are the variables to cover, such as:
|
||||||
|
@primary-color: #6495ED;
|
||||||
|
|
||||||
|
.ant-table table {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.ant-table-body > table > thead > tr > th {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 8px !important;
|
||||||
|
height: 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-thumb {
|
||||||
|
border-radius: 5px !important;
|
||||||
|
-webkit-box-shadow: inset 0 0 5px rgba(121, 185, 255, 0.4) !important;
|
||||||
|
background: rgba(121, 185, 255, 0.4) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar-track {
|
||||||
|
-webkit-box-shadow: inset 0 0 5px #F0F0F0 !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
background: #F0F0F0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-input[disabled] {
|
||||||
|
color: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-select-disabled {
|
||||||
|
color: rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ant-tree li .ant-tree-node-content-wrapper.ant-tree-node-selected {
|
||||||
|
background-color: rgba(121, 185, 255, 0.4) !important;
|
||||||
|
}
|
|
@ -0,0 +1,134 @@
|
||||||
|
const GET_CAPTCHA = {
|
||||||
|
url: '/base/captcha',
|
||||||
|
deacriptions: '获取验证码'
|
||||||
|
};
|
||||||
|
const LOGIN = {
|
||||||
|
url: '/base/login',
|
||||||
|
deacriptions: '登录'
|
||||||
|
};
|
||||||
|
const GET_MENU = {
|
||||||
|
url: '/menu/getMenu',
|
||||||
|
deacriptions: '获取动态路由'
|
||||||
|
};
|
||||||
|
const CHANGE_PASSWORD = {
|
||||||
|
url: '/user/changePassword',
|
||||||
|
deacriptions: '重置密码'
|
||||||
|
};
|
||||||
|
const GET_USER_LIST = {
|
||||||
|
url: '/user/getUserList',
|
||||||
|
deacriptions: '分页获取用户列表'
|
||||||
|
};
|
||||||
|
const GET_AUTHORITY_LIST = {
|
||||||
|
url: '/authority/getAuthorityList',
|
||||||
|
deacriptions: '获取角色列表'
|
||||||
|
};
|
||||||
|
const DELETE_USER = {
|
||||||
|
url: '/user/deleteUser',
|
||||||
|
deacriptions: '删除用户'
|
||||||
|
};
|
||||||
|
const ADD_USER = {
|
||||||
|
url: '/user/register',
|
||||||
|
deacriptions: '新增用户'
|
||||||
|
};
|
||||||
|
const EDIT_USER = {
|
||||||
|
url: '/user/setUserInfo',
|
||||||
|
deacriptions: '编辑用户'
|
||||||
|
};
|
||||||
|
const UPLOAD_FILE = {
|
||||||
|
url: '/fileUploadAndDownload/upload',
|
||||||
|
deacriptions: '文件上传'
|
||||||
|
};
|
||||||
|
const DELETE_FILE = {
|
||||||
|
url: '/fileUploadAndDownload/deleteFile',
|
||||||
|
deacriptions: '文件删除'
|
||||||
|
};
|
||||||
|
const DOWNLOAD_FILE = {
|
||||||
|
url: '/fileUploadAndDownload/download',
|
||||||
|
deacriptions: '文件下载'
|
||||||
|
};
|
||||||
|
const GET_TEMPLATE_LIST = {
|
||||||
|
url: '/wtTemplates/getWtTemplateList',
|
||||||
|
deacriptions: '获取模板'
|
||||||
|
};
|
||||||
|
const ADD_TEMPLATE = {
|
||||||
|
url: '/wtTemplates/createWtTemplate',
|
||||||
|
deacriptions: '新建模板'
|
||||||
|
};
|
||||||
|
const EDIT_TEMPLATE = {
|
||||||
|
url: '/wtTemplates/updateWtTemplate',
|
||||||
|
deacriptions: '编辑模板'
|
||||||
|
};
|
||||||
|
const ADD_REPORT = {
|
||||||
|
url: '/wtReports/createWtReports',
|
||||||
|
deacriptions: '创建周报'
|
||||||
|
};
|
||||||
|
const FIND_REPORT_LIST = {
|
||||||
|
url: '/wtReports/getWtReportsList',
|
||||||
|
deacriptions: '分页查询周报'
|
||||||
|
};
|
||||||
|
const EDIT_REPORT = {
|
||||||
|
url: '/wtReports/updateWtReports',
|
||||||
|
deacriptions: '更新周报'
|
||||||
|
};
|
||||||
|
const FIND_REPORT_BY_ID = {
|
||||||
|
url: '/wtReports/findWtReports',
|
||||||
|
deacriptions: '根据id查询周报'
|
||||||
|
};
|
||||||
|
const FIND_COMMENT_LIST = {
|
||||||
|
url: '/wtComment/getWtCommentList',
|
||||||
|
deacriptions: '获取周报评论'
|
||||||
|
};
|
||||||
|
const ADD_COMMENT = {
|
||||||
|
url: '/wtComment/createWtComment',
|
||||||
|
deacriptions: '创建周报评论'
|
||||||
|
};
|
||||||
|
const ADD_RULE = {
|
||||||
|
url: '/wtRule/createWtRule',
|
||||||
|
deacriptions: '创建规则'
|
||||||
|
};
|
||||||
|
const UPDATE_RULE = {
|
||||||
|
url: '/wtRule/updateWtRule',
|
||||||
|
deacriptions: '编辑规则'
|
||||||
|
};
|
||||||
|
const FIND_RULE_LIST = {
|
||||||
|
url: '/wtRule/getWtRuleList',
|
||||||
|
deacriptions: ' 查询规则'
|
||||||
|
};
|
||||||
|
const FIND_RESULT = {
|
||||||
|
url: '/wtOutput/GetStatResult',
|
||||||
|
deacriptions: ' 查询统计结果'
|
||||||
|
};
|
||||||
|
const EXPORT_FILE = {
|
||||||
|
url: '/wtOutput/ExportReportToExcel',
|
||||||
|
deacriptions: ' 导出报表'
|
||||||
|
};
|
||||||
|
|
||||||
|
//一定要注册才可以使用
|
||||||
|
export default {
|
||||||
|
GET_CAPTCHA: GET_CAPTCHA,
|
||||||
|
LOGIN: LOGIN,
|
||||||
|
GET_MENU: GET_MENU,
|
||||||
|
CHANGE_PASSWORD: CHANGE_PASSWORD,
|
||||||
|
GET_USER_LIST: GET_USER_LIST,
|
||||||
|
GET_AUTHORITY_LIST: GET_AUTHORITY_LIST,
|
||||||
|
DELETE_USER: DELETE_USER,
|
||||||
|
ADD_USER: ADD_USER,
|
||||||
|
EDIT_USER: EDIT_USER,
|
||||||
|
UPLOAD_FILE: UPLOAD_FILE,
|
||||||
|
DELETE_FILE: DELETE_FILE,
|
||||||
|
DOWNLOAD_FILE: DOWNLOAD_FILE,
|
||||||
|
GET_TEMPLATE_LIST: GET_TEMPLATE_LIST,
|
||||||
|
ADD_TEMPLATE: ADD_TEMPLATE,
|
||||||
|
EDIT_TEMPLATE: EDIT_TEMPLATE,
|
||||||
|
ADD_REPORT: ADD_REPORT,
|
||||||
|
FIND_REPORT_LIST: FIND_REPORT_LIST,
|
||||||
|
EDIT_REPORT: EDIT_REPORT,
|
||||||
|
FIND_REPORT_BY_ID: FIND_REPORT_BY_ID,
|
||||||
|
FIND_COMMENT_LIST: FIND_COMMENT_LIST,
|
||||||
|
ADD_COMMENT: ADD_COMMENT,
|
||||||
|
ADD_RULE: ADD_RULE,
|
||||||
|
UPDATE_RULE: UPDATE_RULE,
|
||||||
|
FIND_RULE_LIST: FIND_RULE_LIST,
|
||||||
|
FIND_RESULT: FIND_RESULT,
|
||||||
|
EXPORT_FILE: EXPORT_FILE,
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
import Crypto from 'crypto-js'
|
||||||
|
// 加密
|
||||||
|
export default {
|
||||||
|
// 设置key和偏移量
|
||||||
|
key: Crypto.enc.Latin1.parse('key'),
|
||||||
|
iv: Crypto.enc.Latin1.parse('iv'),
|
||||||
|
|
||||||
|
// 加密
|
||||||
|
encrypto (password) {
|
||||||
|
const res = Crypto.AES.encrypt(password, this.key, {
|
||||||
|
iv: this.iv,
|
||||||
|
mode: Crypto.mode.CBC,
|
||||||
|
padding: Crypto.pad.ZeroPadding
|
||||||
|
}).toString();
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 解密
|
||||||
|
decrypto (password) {
|
||||||
|
const res = Crypto.AES.decrypt(password, this.key, {
|
||||||
|
iv: this.iv,
|
||||||
|
mode: Crypto.mode.CBC,
|
||||||
|
padding: Crypto.pad.Pkcs7
|
||||||
|
})
|
||||||
|
return Crypto.enc.Utf8.stringify(res)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
// 配置全局变量
|
||||||
|
const baseURL = 'http://10.25.16.212:8980/week/';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
baseURL,
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
module.exports = {
|
||||||
|
outputDir: 'dist', //build输出目录
|
||||||
|
assetsDir: 'assets', //静态资源目录(js, css, img)
|
||||||
|
lintOnSave: false, //是否开启eslint
|
||||||
|
devServer: {
|
||||||
|
// host: "10.25.16.212",
|
||||||
|
host: "10.25.17.18",
|
||||||
|
port: '8080',
|
||||||
|
https: false,
|
||||||
|
hotOnly: false,
|
||||||
|
proxy: {
|
||||||
|
'/week': {
|
||||||
|
target: 'http://10.25.16.212:8981/',
|
||||||
|
ws: true,
|
||||||
|
changeOrigin: true,
|
||||||
|
pathRewrite: {
|
||||||
|
'^/week': ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
runtimeCompiler: true,
|
||||||
|
};
|
||||||
|
|
Loading…
Reference in New Issue