Commit f8c5cee9 by 林家欣

feat: 新增基础前端框架待完善

parent 7e84acb1
> 1%
last 2 versions
VUE_APP_CURRENTMODE = "development"
VUE_APP_HOST_URL = "https://icommunity.thed3chain.com:5443"
VUE_APP_LOG = true
\ No newline at end of file
VUE_APP_CURRENTMODE = "production"
VUE_APP_HOST_URL = "http://192.168.0.47:8090"
VUE_APP_LOG = false
\ No newline at end of file
VUE_APP_CURRENTMODE = "test"
VUE_APP_HOST_URL = "http://192.168.0.32:8070"
VUE_APP_LOG = true
\ No newline at end of file
module.exports = {
root: true,
env: {
node: true
},
'extends': [
'plugin:vue/essential',
'eslint:recommended'
],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
},
parserOptions: {
parser: 'babel-eslint'
}
}
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
/nbproject/private/
\ No newline at end of file
# GS1官网
#### Description
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
# GS1官网 # HashFlowWeb
#### 介绍 江北新区社会治理
{**以下是 Gitee 平台说明,您可以替换此简介**
Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台
无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
#### 软件架构
软件架构说明
#### 安装教程
1. xxxx
2. xxxx
3. xxxx
#### 使用说明
1. xxxx
2. xxxx
3. xxxx
#### 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
#### 特技
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
module.exports = {
"presets": [
"@vue/app"
],
"plugins": [
[
"component",
{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}
]
]
}
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "front",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"dev": "vue-cli-service serve --mode development",
"test": "vue-cli-service serve --mode test",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@popperjs/core": "^2.10.1",
"@tweenjs/tween.js": "^18.5.0",
"bootstrap": "^5.1.0",
"clear": "^0.1.0",
"core-js": "^2.6.11",
"echarts": "^4.7.0",
"element-ui": "^2.13.0",
"jquery": "^3.6.0",
"js-cookie": "^2.2.1",
"js-sha256": "^0.9.0",
"nprogress": "^0.2.0",
"popper.js": "^1.16.1",
"qrcodejs2": "0.0.2",
"v-clipboard": "^2.2.2",
"vue": "^2.6.11",
"vue-router": "^3.1.6",
"vuex": "^3.1.3",
"wangeditor": "^3.1.1",
"xss": "^1.0.6"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.12.1",
"@vue/cli-plugin-eslint": "^3.12.1",
"@vue/cli-service": "^3.12.1",
"axios": "^0.18.0",
"babel-eslint": "^10.0.1",
"babel-plugin-component": "^1.1.1",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"node-sass": "^4.13.0",
"sass-loader": "^7.1.0",
"vue-cli-plugin-axios": "0.0.4",
"vue-cli-plugin-element": "^1.0.1",
"vue-template-compiler": "^2.6.11"
}
}
module.exports = {
plugins: {
autoprefixer: {}
}
}
afb2cf3429c17103c02dbe83d01f558c
\ No newline at end of file
86993f45cfc57b70fbcbc25e7b54a4c6
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="referrer" content="never">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<!-- <link rel="shortcut icon" href="/favicon.ico"/> -->
<title>链通万家</title>
</head>
<body>
<noscript>
<strong>We're sorry but front 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>
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*/
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
line-height: 1.4;
margin: 1rem;
}
table {
border-collapse: collapse;
}
table th,
table td {
border: 1px solid #ccc;
padding: 0.4rem;
}
figure {
display: table;
margin: 1rem auto;
}
figure figcaption {
color: #999;
display: block;
margin-top: 0.25rem;
text-align: center;
}
hr {
border-color: #ccc;
border-style: solid;
border-width: 1px 0 0 0;
}
code {
background-color: #e8e8e8;
border-radius: 3px;
padding: 0.1rem 0.2rem;
}
.mce-content-body:not([dir=rtl]) blockquote {
border-left: 2px solid #ccc;
margin-left: 1.5rem;
padding-left: 1rem;
}
.mce-content-body[dir=rtl] blockquote {
border-right: 2px solid #ccc;
margin-right: 1.5rem;
padding-right: 1rem;
}
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*/
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif;line-height:1.4;margin:1rem}table{border-collapse:collapse}table td,table th{border:1px solid #ccc;padding:.4rem}figure{display:table;margin:1rem auto}figure figcaption{color:#999;display:block;margin-top:.25rem;text-align:center}hr{border-color:#ccc;border-style:solid;border-width:1px 0 0 0}code{background-color:#e8e8e8;border-radius:3px;padding:.1rem .2rem}.mce-content-body:not([dir=rtl]) blockquote{border-left:2px solid #ccc;margin-left:1.5rem;padding-left:1rem}.mce-content-body[dir=rtl] blockquote{border-right:2px solid #ccc;margin-right:1.5rem;padding-right:1rem}
/*# sourceMappingURL=content.min.css.map */
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*/
.tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection {
/* Note: this file is used inside the content, so isn't part of theming */
background-color: green;
display: inline-block;
opacity: 0.5;
position: absolute;
}
body {
-webkit-text-size-adjust: none;
}
body img {
/* this is related to the content margin */
max-width: 96vw;
}
body table img {
max-width: 95%;
}
body {
font-family: sans-serif;
}
table {
border-collapse: collapse;
}
/**
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
* Licensed under the LGPL or a commercial license.
* For LGPL see License.txt in the project root for license information.
* For commercial licenses see https://www.tiny.cloud/
*/
.tinymce-mobile-unfocused-selections .tinymce-mobile-unfocused-selection{background-color:green;display:inline-block;opacity:.5;position:absolute}body{-webkit-text-size-adjust:none}body img{max-width:96vw}body table img{max-width:95%}body{font-family:sans-serif}table{border-collapse:collapse}
/*# sourceMappingURL=content.mobile.min.css.map */
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
</script>
<style>
</style>
// 查询表单
.content-query{
.el-form{
@include el-form
.el-row{
.el-col{
.el-form-item{
width:100%;
.el-form-item__content{
width:calc(100% - 150px)
}
}
}
}
}
}
.content-list{
.el-form{
@include el-form
}
}
.content-msg{
padding:20px 20px;
background:$bg-color;
border-radius: 14px;
}
.editor-preview-context {
height: 500px;
// margin: 20px auto;
border:1px solid #ccc;
padding: 10px;
overflow: auto;
/* table 样式 */
table {
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
}
table td,
table th {
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
padding: 3px 5px;
}
table th {
border-bottom: 2px solid #ccc;
text-align: center;
}
/* blockquote 样式 */
blockquote {
display: block;
border-left: 8px solid #d0e5f2;
padding: 5px 10px;
margin: 10px 0;
line-height: 1.4;
font-size: 100%;
background-color: #f1f1f1;
}
/* code 样式 */
code {
display: inline-block;
*display: inline;
*zoom: 1;
background-color: #f1f1f1;
border-radius: 3px;
padding: 3px 5px;
margin: 0 3px;
}
pre code {
display: block;
}
/* ul ol 样式 */
ul, ol {
margin: 10px 0 10px 20px;
}
}
//查询
.el-button.query{
width:85px;
height: $input-height;
padding:0;
line-height: $input-height;
border-color: transparent;
border-radius: 5px;
background:#ffb73f;
color:#fff;
font-size: 15px;
font-weight: 400;
&:hover,
&:focus{
background:#e59f29;
}
&.is-disabled {
opacity: 0.5;
}
}
// 取消
.el-button.cancel{
padding:10px 18px;
border-radius: 5px;
border:1px solid #cbcbcb;
background:#ffffff;
color:#6b6a6a;
font-size: 14px;
&:hover,
&:focus{
background:#fff1d9;
}
&.is-disabled {
opacity: 0.5;
}
}
//提交
.el-button.submit,
// 确认
.el-button.confirm{
padding:10px 18px;
border-radius: 5px;
border-color: transparent;
background:#ffb73f;
color:#fff;
font-size: 14px;
&:hover,
&:focus{
background:#e59f29;
}
&.is-disabled {
opacity: 0.5;
}
}
// 上传按钮
.el-button.upload{
padding:10px 8px;
border:none;
color:$system-color1;
&:hover,
&:focus{
background:transparent
}
}
// 分页
.el-pagination.is-background{
margin-top:20px;
text-align: center;
.el-pager li:not(.disabled).active{
background: #FFB73F;
}
.el-pager li {
border-radius: 5px;
}
.btn-prev,.btn-next{
border-radius: 5px;
}
.el-input__inner{
border-radius: 5px!important;
&:hover,&:focus {
border-color: #FFB73F !important;
}
}
.el-input__inner.is-focus {
border-color: #FFB73F !important;
}
}
.el-select-dropdown.el-popper {
.el-scrollbar {
li.el-select-dropdown__item.selected {
color: #FFB73F !important;
}
}
}
// 表格
.content-list{
.el-table{
@include el-table
}
}
//表单
.content-form{
.el-form{
.el-row{
.el-col{
.el-form-item{
width: 100%;
.el-form-item__content{
width: 100%;
p{
color:#acacac;
text-align: center;
}
}
}
}
}
.el-form-item{
width: calc(50% - 20px);
.el-form-item__content{
width: calc(100% - 200px);
}
&.label-title{
.el-form-item__label{
font-size:16px;
font-weight: 600;
color:#323232;
}
}
&.label-caption{
.el-form-item__label{
font-weight: 600;
color:#b94339;
}
}
}
.el-form-item.full-item{
width: calc(100% - 40px);
}
@include el-form
&.form-center{
.el-form-item{
margin:0 auto 22px auto;
}
}
}
}
// 弹窗
.el-dialog{
width: 600px;
.el-dialog__header{
.el-dialog__title{
color:#555;
}
}
.el-dialog__body{
padding:10px 20px;
}
.el-form{
@include el-form
}
}
.content-tab{
.el-tabs{
.el-tabs__active-bar{
background-color:$system-color5;
}
.el-tabs__item{
color:#969696;
&.is-active{
color:$system-color5
}
}
}
}
.el-dropdown-menu{
.el-dropdown-menu__item{
color:$system-color5;
a{
color:$system-color5
}
}
}
//主体样式
.common-content{
background: $bg-color;
border-radius: $fs2;
padding:0 20px;
padding-bottom:30px;
.common-title{
text-align: center;
font-size: 20px;
font-weight: 600;
padding: 30px 0 35px 0;
}
.common-text{
img{
width:100%;
}
}
.common-serach{
padding: 0 !important;
.el-form{
.el-form-item{
margin-right:0;
}
.el-form-item__label{
// vertical-align:-52%;
&::before{
content:'*';
font-size:20px;
color: $side-menu-active-color;
vertical-align: -16%;
padding-right:4px;
}
}
.el-col-2{
text-align: center;
margin-top: 8px;
}
.editor{
margin-top:25px !important;
width: 100%;
.el-form-item__content{
width:100%;
}
}
}
}
.common-table /deep/{
.el-table{
margin-top:35px;
thead{
color: #414141;
}
tr th{
background-color: #f4f4f4;
&>.cell{
font-weight: 500;
padding-left: 10px;
padding-right: 10px;
vertical-align: middle;
font-size: $fs2;
text-align: center;
}
}
tr td{
color: #7B7F83;
font-size:11px;
text-align: center;
}
tbody{
tr{
border: 1px solid #000 !important;
}
}
}
}
.common-info{
p{
text-indent: 2em;
color: $button-color;
font-size:$fs2;
}
}
.common-opinion{
border-top: 1px solid #d4d4d4;
padding-top: 20px;
margin-top: 40px;
.cate {
height: 26px;
display: flex;
align-items: center;
font-size: 15px;
margin-bottom: 10px;
.cate-ico::after {
content: "";
width: 4px;
height: 16px;
background: #ffb73f;
display: block;
}
.cate-name {
line-height: 26px;
margin-left: 10px;
color: #414141;
span {
color: #969696;
margin-left: 10px;
}
}
}
.el-textarea {
.el-textarea__inner {
resize: none;
}
}
}
.button-Group {
margin-top:25px;
display: flex;
justify-content: center;
}
.headimg{
width: 52px;
}
}
.list_dialog{
.el-dialog{
.el-dialog__body{
.el-radio{
display: block;
margin: 15px 0;
.el-radio__input.is-checked{
.el-radio__inner{
border-color: #ffb73f;
background: #ffb73f;
}
}
.el-radio__input.is-checked+.el-radio__label{
color: #ffb73f;
}
}
}
}
}
\ No newline at end of file
@font-face {font-family: "element-icons";
src: url('//at.alicdn.com/t/font_1484447_u8ceexxyv8c.eot?t=1576754312625'); /* IE9 */
src: url('//at.alicdn.com/t/font_1484447_u8ceexxyv8c.eot?t=1576754312625#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,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') format('woff2'),
url('//at.alicdn.com/t/font_1484447_u8ceexxyv8c.woff?t=1576754312625') format('woff'),
url('//at.alicdn.com/t/font_1484447_u8ceexxyv8c.ttf?t=1576754312625') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('//at.alicdn.com/t/font_1484447_u8ceexxyv8c.svg?t=1576754312625#element-icons') format('svg'); /* iOS 4.1- */
}
.element-icons {
font-family: "element-icons" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.el-icon-jinqian:before {
content: "\f018";
}
.el-icon-bianji:before {
content: "\f014";
}
.el-icon-pdf:before {
content: "\e629";
}
.el-icon-jijinguanlirendengji:before {
content: "\f013";
}
.el-icon-shangchuan:before {
content: "\f012";
}
.el-icon-xinjianjijin:before {
content: "\f011";
}
.el-icon-yinrutouziren:before {
content: "\f008";
}
.el-icon-xinjianxiangmu:before {
content: "\f007";
}
.el-icon-jijinguanli:before {
content: "\f006";
}
.el-icon-zichanliuxiang:before {
content: "\f005";
}
.el-icon-touziguanli:before {
content: "\f004";
}
.el-icon-kehuguanli:before {
content: "\f003";
}
.el-icon-muziguanli:before {
content: "\f002";
}
.el-icon-gongzuotai:before {
content: "\f001";
}
.el-icon-yonghu:before {
content: "\f016";
}
.el-icon-mima:before {
content: "\f017";
}
.el-icon-daibanshixiang:before {
content: "\f019";
}
.el-icon-zhuye:before {
content: "\f020";
}
.el-icon-tuichu:before {
content: "\f021";
}
.el-icon-xinzeng:before {
content: "\f022";
}
.el-icon-pdf1:before {
content: "\f023";
}
.el-icon-doc:before {
content: "\f024";
}
.el-icon-xsl:before {
content: "\f025";
}
.el-icon-wenjianjia:before {
content: "\f026";
}
.el-icon-png:before {
content: "\f027";
}
.el-icon-uploadFile:before {
content: "\e603";
}
// 表单
@mixin el-form {
.el-form-item__label{
line-height: $input-height;
color:#807f80;
font-size: 12px;
}
.el-form-item__content{
line-height: $input-height;
.el-input{
.el-input__inner{
color: #807f80;
// font-size: 12px;
height: $input-height;
line-height: $input-height;
border-color:$input-border;
background:$input-background;
border-radius:5px;
vertical-align: top;
// &:focus,&:active {
// border-color: #ffb73f;
// }
}
.el-input__icon{
line-height: $input-height
}
&.is-disabled{
.el-input__inner,
.el-input-group__append{
border-color:#E4E7ED;
background:#F5F7FA;
color: #C0C4CC;
cursor: not-allowed;
}
}
}
.el-select{
width:100%;
}
.el-autocomplete{
width: 100%;
}
.el-date-editor{
width:100%;
// background:$input-background;
&.el-input__inner{
height: $input-height;
line-height: $input-height;
.el-range__icon,
.el-range-separator,
.el-range__close-icon{
line-height: 24px;
}
}
.el-range-input{
// background:$input-background;
}
}
.el-radio-group,.el-radio{
.el-radio__input{
&.is-checked + .el-radio__label{
color:$system-color1;
}
&.is-checked{
.el-radio__inner{
border:$system-color1;
background:$system-color1;
}
}
}
}
.el-checkbox-group,.el-tree,.el-checkbox{
.el-checkbox__input{
.el-checkbox__inner{
width: 18px;
height: 18px;
&::after{
left:6px;
top:3px;
}
}
&.is-focus{
.el-checkbox__inner{
border-color:$system-color1
}
}
.el-checkbox__inner{
&:hover{
border-color:$system-color1;
}
}
&.is-checked,
&.is-indeterminate{
.el-checkbox__inner{
background-color:$system-color1;
border-color:$system-color1;
}
}
&.is-checked + .el-checkbox__label{
color:$system-color1;
}
.el-checkbox{
width: 50%;
float:left;
}
.el-checkbox + .el-checkbox{
margin-left:0
}
}
}
.el-switch{
&.is-checked{
.el-switch__core{
// border-color:$btn-success;
// background-color:$btn-success
}
}
}
.el-textarea{
.el-textarea__inner{
height: 80px;
overflow: auto;
// background:$input-background;
}
}
.el-tree{
background:transparent;
.el-tree-node{
margin:10px 0;
}
.el-tree-node__content:hover,
.el-tree-node:focus>.el-tree-node__content{
background:transparent;
}
.el-tree-node__children{
.el-tree-node{
display: inline-block;
float:left;
}
}
}
}
}
// 表格
@mixin el-table{
font-size:$fs1;
th{
text-align: center;
color:$table-th-color;
font-size:$table-th-size;
font-weight: $table-th-weight;
&.gutter{
display: table-cell !important;
}
}
tbody{
tr.el-table__row{
td {
background-color: rgba(239,239,247,0.6);//$content-bg-color;
color:$table-td-color;
font-size:$table-td-size;
font-weight: $table-td-weight;
text-align:center;
}
&:hover {
background-color: $content-bg-color;
}
&.el-table__row--striped {
td{
background-color:$bg-color;
}
}
&.el-table__row--striped:hover {
background-color:$bg-color;
}
}
}
.cell{
>span,>a{
// padding:0 5px;
margin:0 5px;
cursor: pointer;
}
span{
&.edit{
color:$span-edit;
}
&.delete{
color:$span-delete;
}
&.reset{
color:$span-reset;
}
&.details{
color:$span-details;
}
&.click{
color:$span-details;
}
&.disabled{
color: $span-details;
}
&.actived{
color: $span-details;
}
&.row-index{
// color: $table-th-color;
// font-weight: $table-th-weight;
// font-size: $table-th-size;
}
&.row-router{
color: $span-edit;
font-size: $table-th-size;
}
&.row-role{
color: #4EA7A6;
}
}
>i{
color:#dde2e6;
}
>a{
color:#4f66cb
}
>p{
width: 58px;
height: 68px;
margin:0 auto;
display: flex;
justify-content: center;
align-items: center;
background-color: #ececec;
img{
width: 52px;
height: 62px;
}
}
.el-select{
.el-input__suffix{
.el-input__icon{
line-height: $input-height;
}
}
}
.el-input__inner{
height: $input-height;
}
}
}
\ No newline at end of file
@charset "utf-8";
/* CSS Document */
html,body,ul,li,ol,dl,dd,dt,p,h1,h2,h3,h4,h5,h6,form,img {
margin: 0;
padding: 0;
}
body{
font-size: 12px;
font-family: PingFangSC-Regular, sans-serif;
}
h1,h2,h3,h4,h5,h6{
font-weight: normal;
}
a{
text-decoration: none;
}
ul,ol {
list-style: none
}
input {
border: none;
padding-top: 0;
padding-bottom: 0;
}
input::-moz-focus-inner {
border: 0;
padding: 0
}
select,input {
vertical-align: middle
}
select,input,textarea {
margin: 0
}
input[type="text"],input[type="password"],textarea {
outline-style: none;
-webkit-appearance: none
}
button{
cursor: pointer;
border: none;
outline: none;
}
textarea {
resize: none
}
table {
border-collapse: collapse
}
em ,i{
font-style: normal;
}
a,button,input{
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
outline: none;
}
a,input[type='button'],input[type='submit']{
cursor:pointer;
}
::-webkit-scrollbar-track-piece {
background: #fff1d9;
border-radius: 2px;
}
::-webkit-scrollbar {
width: 4px;
height: 4px;
}
::-webkit-scrollbar-thumb {
min-height: 30px;
background: #ffb73f;
border-radius: 2px;
}
::-webkit-scrollbar-thumb:hover {
background-color: #e59f29;
}
select {
appearance:none;
-moz-appearance:none;
-webkit-appearance:none;
}
select::-ms-expand { display: none; }
textarea{
overflow: hidden;
}
// 背景颜色
$bg-color:#fff;
$side-bg-color: #FEFEFE;
$side-menu-active-color: #ffb73f;
$content-bg-color: #eeebf0;
// 系统颜色
$system-color1:#d75449;
$system-color2:#848688;
$system-color3:#fff;
$system-color4:#555;
$system-color5:#323232;
// 字体大小
$fs0:10px;
$fs1:12px;
$fs2:14px;
$fs3:16px;
$fs4:18px;
// 按钮样式
$input-height:35px;
$input-border:#cbcbcb;
$input-background:#fefefe;
$button-color:#323232;
// 表单样式
$table-th-color: #353434;
$table-th-size:13px;
$table-th-weight:bold;
$table-td-color:#6B6A6A;
$table-td-size:11px;
$table-td-weight:400;
$span-edit:#4EA7A6;
$span-delete:#4EA7A6;
$span-reset:#4EA7A6;
$span-details:#4EA7A6;
$span-click:#4EA7A6;
$span-disabled:#4EA7A6;
$span-actived:#4EA7A6;
.el-container.layout{
min-height: 100vh;
}
.el-container.is-vertical{
height: 100vh;
overflow: hidden;
}
.el-header{
$header-height: 65px;
padding: 0px;
header {
height: $header-height;
padding: 0 25px;
.header-user {
height: $header-height;
float:left;
display: -webkit-flex;
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
img {
width: 40px;
height: 40px;
border-radius: 50%;
vertical-align: middle;
}
div {
margin-left: 8px;
p {
padding: 3px 0;
font-size: 10px;
&.user-name {
color: #7A7878;
}
&.user-role {
font-size: 14px;
color: #353434;
}
}
}
}
.header-logout {
float:right;
height: $header-height;
line-height: $header-height;
span {
padding: 15px 5px;
height: 30px;
line-height: 30px;
cursor: pointer;
img {
display: inline-block;
width: 12px;
height: 12px;
vertical-align: middle;
}
p {
margin-left: 4px;
display: inline-block;
font-size: 10px;
color: #7A7878;
}
}
}
}
}
.el-aside{
height: 100vh;
overflow: visible;
background: $side-bg-color;
.el-menu{
border-right: none;
background: $side-bg-color;
.menu-logo {
height: 88px;
background: $side-menu-active-color;
box-shadow:0px 5px 5px 0px #260D0408;
border-radius:0 0 30px 30px;
display: flex;
justify-content: center;
align-items: center;
span {
font-size: 16px;
color: #8A4E22;
font-weight: bold;
img {
width: 30px;
height: 25px;
margin-right: 5px;
}
}
}
.menu-title {
margin-top: 25px;
margin-bottom: 10px;
padding-left: 28px;
font-size: 12px;
color:#B7B6B6;
}
.el-menu-item {
height: 50px;
line-height: 50px;
color: #6B6A6A;
background: transparent;
font-size: 16px;
i {
color: $side-bg-color;
font-size: 25px;
position: absolute;
top: 15px;
right: 15px;
}
&:hover,
&:focus,
&.is-active {
color: $side-bg-color;
background: $side-menu-active-color;
}
&.is-active {
border-radius: 0px 25px 25px 0px;
box-shadow: 0px 5px 5px 0px #0D0D0408;
margin-right: -8px;
i {
right: 23px;
}
}
}
}
}
.el-main{
background: $content-bg-color;
padding: 18px 25px 22px 25px;
.main-content{
.content-query{
padding: 0 20px;
background:$bg-color;
border-radius: 14px;
h2{
height: 30px;
line-height: 30px;
font-size: 13px;
color: #5B5A5A;
}
.query-handle{
text-align: right;
}
.el-form {
.el-form-item {
margin-top: 8px;
margin-bottom: 8px;
}
}
}
.content-item{
margin-bottom: 10px;
padding:10px 0;
background:$bg-color;
border-radius: 14px;
.el-tag{
margin:0 5px;
padding:0 5px;
cursor: pointer;
}
}
.content-list{
border-radius: 14px;
margin-top:10px;
padding:10px 0 15px 0;
background:$bg-color;
.list-button{
text-align: right;
margin-bottom:20px;
a{
font-size:14px;
color:$system-color1;
cursor: pointer;
i{
&:before{
margin-right: 5px;
}
}
}
i{
margin:0 5px;
font-size:14px;
color:$system-color1;
cursor: pointer;
&:before{
margin-right: 5px;
}
}
}
}
.content-apply.content-table{
background-color: #fff;
padding:20px 60px;
margin-top:0;
.el-table {
th{
background-color: #f4f4f4;
font-weight: bold;
}
tbody{
tr.el-table__row{
td {
background-color: #fff;//$content-bg-color;
color:#7b7f83;
}
&:hover {
background-color: #fff;
}
&.el-table__row--striped {
td{
background-color:#fff;
}
}
&.el-table__row--striped:hover {
background-color:#fff;
}
}
}
}
}
}
}
\ No newline at end of file
@import "./_reset.scss";
@import "./_style.scss";
@import "./_icon.scss";
@import "./_mixin.scss";
@import "./_base.scss";
\ No newline at end of file
import axios from "axios"
import {
MessageBox
} from "element-ui"
// import NProgress from 'nprogress'
import Qs from "qs"
import {
cleanObject,
REQUEST_HEADER_TOKEN,
ResponseCode,
handleResponseSuccess,
handleResponseError,
checkResponseCodeTokenError,
checkResponseCodeAuthUnPermitted
} from "./parameter"
import {
removeToken,
getToken
} from "@/utils/cookie.js"
const baseUrl = process.env.BASE_URL + "api"
function fetch(options) {
return new Promise((resolve, reject) => {
const instance = axios.create({
baseURL: baseUrl, //根地址
timeout: (30 * 1000), //请求时间
url: options.url, //请求地址
method: options.method, //请求方式
data: options.data, //传递数据,
transformRequest: [(data, headers) => {
headers["Content-Type"] = "application/json"
if (options.headers) {
Object.assign(headers, options.headers)
}
headers[REQUEST_HEADER_TOKEN] = window.vm.$store.state.user.token
return data
}], //请求前的数据处理
transformResponse: [(data /*, headers*/) => {
return data
}], //响应时的数据处理
responseType: options.resoponseType || "json", //响应数据类型
headers: options.headers || {
"X-Requested-With": "XMLHttpRequest"
}, //请求头部
})
// axios拦截器
instance.interceptors.request.use(config => {
return config
}, err => {
return Promise.reject(err)
}) //发送请求前的拦截
instance.interceptors.response.use(response => {
return response
}, err => {
if (err) {
return Promise.reject(err)
}
}) //响应数据的拦截
instance().then(res => {
const resData = res.data || {}
const code = String(resData.returnCode)
if (code === ResponseCode.success) {
resolve(resData)
} else if (checkResponseCodeTokenError(code)) {
if (getToken()) {
window.localStorage.clear()
removeToken()
MessageBox.alert("登录已失效或账号在其他地方登录,请重新登录", "提示", {
type: "warning",
center: true,
confirmButtonClass: "confirm",
callback: () => {
window.location.href = "/login"
setTimeout(() => {
window.location.reload()
}, 500)
}
})
}
} else if (checkResponseCodeAuthUnPermitted(code)) {
// if (window.location.pathname !== "/404") {
// window.location.href = "/404"
// reject(resData)
// }
reject(resData)
} else {
reject(resData)
}
}).catch((err) => {
reject(err)
})
// 数据处理
})
}
const sendRequst = async function(options) {
// NProgress.start()
let res = null
try {
const response = await fetch(options)
res = handleResponseSuccess(response)
} catch (err) {
res = handleResponseError(err)
}
// NProgress.done()
return Promise.resolve(res)
}
export const GET = async function (url, query) {
const queryString = Qs.stringify(cleanObject(query))
if (queryString) {
url += "?" + queryString
}
return await sendRequst({
url: url,
method: "get",
})
}
export const POST = async function (url, data) {
return await sendRequst({
url: url,
method: "post",
data: JSON.stringify(data),
headers: {
"Content-Type": "application/json"
}
})
}
export const POSTFORM = async (url, data) => {
return await sendRequst({
url: url,
method: "post",
data: Qs.stringify(data),
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
})
}
export const UPLOAD = async (url, formData) => {
return await sendRequst({
url: url,
method: "post",
data: formData,
headers: {
"Content-Type": "multipart/form-data"
}
})
}
export const DOWNLOAD = async function (url, query) {
const queryString = Qs.stringify(cleanObject(query))
if (queryString) {
url = baseUrl + url + "?" + queryString
}
window.location.href = url
}
export default fetch
import api from "./api.js"
const install = function(Vue){
if(install.installed){
return install.installed = true
}
Object.defineProperties(Vue.prototype,{
$api:{
get(){
return api
}
}
})
}
export default {install}
\ No newline at end of file
import {
GET, POSTFORM, POST, UPLOAD, DOWNLOAD
} from "../fetch.js"
// 根据业主id查询报名表
const QueryApplicationFormFindByUser = async (params) => {
return await GET("/cmt/committee/cmt/p5/apply/findByUser",params)
}
// 审核报名表
const AuditApplicationForm = async (params) => {
return await POST("/cmt/console/cmt/p5/apply/audit",params)
}
// 确认总报名记录审核结果
const VerifyApplyResult = async (stageId) => {
return await POST("/cmt/console/cmt/p5/apply/auditByStage",stageId)
}
// 根据id查询报名表
const QueryApplicationFormFindId = async (applyId) => {
return await GET("/cmt/console/cmt/p5/apply/findById",applyId)
}
// 查询审核通过的候选人清单
const QueryCandidateList = async (stageId) => {
return await GET("/cmt/console/cmt/p5/apply/findSelected",stageId)
}
// 审核联名报名记录
const AuditJointlyApply = async (params) => {
return await GET("/cmt/console/cmt/p5/apply/jointly/audit",params)
}
// 确认联名审核
const VerifyJointlyApply = async (stageId) => {
return await POST("/cmt/console/cmt/p5/apply/jointly/auditByStage",stageId)
}
// 查询指定人被联名清单
const QueryJointlyListFindSelected = async (params) => {
return await GET("/cmt/console/cmt/p5/apply/jointly/findBySelected",params)
}
// 查询报名列表
const QueryApplyList = async (params) => {
return await GET("/cmt/console/cmt/p5/apply/listByStage",params)
}
// 提交报名通知审核
const AuditApplyNotification = async(params) => {
return await POST("/cmt/console/cmt/p5/notification/audit",params)
}
// id查询报名通知
const QueryApplyNotificationById = async (id) => {
return await GET("/cmt/console/cmt/p5/notification/findById",id)
}
// 阶段查询报名通知
const QueryApplyNotificationFindByStage = async (stageId) => {
return await GET("/cmt/console/cmt/p5/notification/findByStage",stageId)
}
// 提交报名通知
const SubmitApplyNotification = async (params) => {
return await POST("/cmt/console/cmt/p5/notification/submit",params)
}
// 审批报名公示
const AuditApplyPublicity = async (params) => {
return await POST("/cmt/console/cmt/p5/publicity/audit",params)
}
//查询公示通知
const QueryPublicityFindByStage = async (stageId) => {
return await GET("/cmt/console/cmt/p5/publicity/findByStage",stageId)
}
// 提交公示通知
const SubmitPublicity = async (params) => {
return await POST("/cmt/console/cmt/p5/publicity/submit")
}
// 驳回业主报名事项
const RejectApply = async (params) => {
return await POST("/cmt/console/cmt/p5/reject",params)
}
export default {
QueryApplicationFormFindByUser,
AuditApplicationForm,
VerifyApplyResult,
QueryApplicationFormFindId,
QueryCandidateList,
AuditJointlyApply,
VerifyJointlyApply,
QueryJointlyListFindSelected,
QueryApplyList,
AuditApplyNotification,
QueryApplyNotificationById,
QueryApplyNotificationFindByStage,
SubmitApplyNotification,
AuditApplyPublicity,
QueryPublicityFindByStage,
SubmitPublicity,
RejectApply
}
// 参数格式化处理
// 删除空值参数
export function cleanObject(obj){
if(!obj){
return
}
let retObj = {...obj}
Object.keys(obj).forEach((key) => {
const val = obj[key]
if (val === null || val === undefined || (typeof val === 'string' && !val)){
delete retObj[key]
}
})
return retObj
}
export function getQueryStr(obj) {
if (!obj) return ""
return cleanArray(Object.keys(obj).map(key => {
if (obj[key] === undefined) {
return ""
}
return key + "=" + obj[key]
})).join("&")
}
export function cleanArray(actual) {
const newArray = []
for (let i = 0; i < actual.length; i++) {
if (actual[i]) {
newArray.push(actual[i])
}
}
return newArray
}
export const REQUEST_HEADER_TOKEN = "token"
export const ResponseCode = {
success: "0000",
tokenError: "0202",
tokenEmpty: "0203",
tokenInvalid: "0205",
authUnPermitted: "0201",
authFailed: "0206",
failed: "-100"
}
export function checkResponseCodeTokenError(resCode) {
const code = String(resCode)
return code === ResponseCode.tokenError
|| code === ResponseCode.tokenEmpty
|| code === ResponseCode.tokenInvalid
}
export function checkResponseCodeAuthUnPermitted(resCode) {
const code = String(resCode)
return code === ResponseCode.authUnPermitted
|| code === ResponseCode.authFailed
}
export function handleResponseSuccess(res = {}) {
return {
success: true,
returnCode: res.returnCode || ResponseCode.success,
returnMsg: res.returnMsg,
data: res.data || null
}
}
export function handleResponseError(res = {}) {
return {
success: false,
returnCode: res.returnCode || ResponseCode.failed,
returnMsg: res.returnMsg || "",
data: res.data || null
}
}
\ No newline at end of file
<template>
<div>
<!--
给editor加key是因为给tinymce keep-alive以后组件切换时tinymce编辑器会显示异常,
在activated钩子里改变key的值可以让编辑器重新创建
-->
<editor :id="tinymceFlag" :key="tinymceFlag" :init="tinymceInit" v-model="content"></editor>
</div>
</template>
<script>
import { uuid } from '@/utils/utils.js';
import "tinymce/tinymce";
import Editor from "@tinymce/tinymce-vue";
import "tinymce/themes/silver";
import "tinymce/plugins/preview";
import "tinymce/plugins/fullscreen";
export default {
name: "TinymcePreview",
components: {
editor: Editor
},
props: {
context: {
type: String,
default: ''
}
},
watch: {
context(newVal) {
this.content = newVal
}
},
data() {
return {
publicPath: process.env.BASE_URL,
tinymceFlag: uuid('tinymce-preview'),
tinymceInit: {},
content: "",
};
},
methods: {
},
created() {
this.tinymceInit = {
skin_url: `/tinymce/skins/ui/oxide`,
theme: "silver",
// content_css: `/tinymce/skins/content/default`,
language_url: `/tinymce/langs/zh_CN.js`,
language: "zh_CN",
height: 300,
browser_spellcheck: true, // 拼写检查
branding: false, // 去水印
statusbar: false, // 隐藏编辑器底部的状态栏
menubar: false, // 隐藏最上方menu
plugins: [
"fullscreen",
"preview"
],
toolbar: `preview fullscreen`,
content_style: `
* { padding:0; margin:0; }
html, body { height:100%; }
img { max-width:100%; display:block;height:auto; }
a { text-decoration: none; }
iframe { width: 100%; }
p { line-height:1.6; margin: 0px; }
table { word-wrap:break-word; word-break:break-all; max-width:100%; border:none; border-color:#999; }
.mce-object-iframe { width:100%; box-sizing:border-box; margin:0; padding:0; }
ul,ol { list-style-position:inside; }
`,
setup: function(editor) {
editor.on(
'init',
() => {
const body = editor.getBody();
if (body) {
body.setAttribute('contenteditable', false);
}
}
)
// editor.setMode('readonly')
}
};
},
mounted() {
}
};
</script>
<style lang="scss">
.tox-tinymce-aux {
z-index: 20000 !important;
}
</style>
\ No newline at end of file
<template>
<div>
<div id="editor"></div>
<!-- <el-button @click="setData">设置内容</el-button>
<el-button @click="getData">获取内容</el-button> -->
</div>
</template>
<script>
import WangEditor from 'wangeditor'
const xss = require('xss');
export default {
name: "WangEditor",
props: {
hiddenMenus: {
type: Boolean,
default: false
},
},
data() {
return {
editor: null,
}
},
mounted() {
this.initWangEditor()
},
beforeDestroy() {
this.editor = null
},
methods: {
initWangEditor() {
// https://github.com/wangfupeng1988/wangEditor/blob/master/src/js/config.js
const config = {
menus: [
'head', // 标题
'bold', // 粗体
'fontSize', // 字号
'fontName', // 字体
'italic', // 斜体
'underline', // 下划线
'foreColor', // 文字颜色
'backColor', // 背景颜色
'justify', // 对齐
'image', // 插入图片
'table', // 表格
'undo', // 撤销
'redo' // 重复
],
fontNames: [
'宋体',
'微软雅黑',
'Arial',
'Tahoma',
'Verdana'
],
colors: [
'#000000',
'#eeece0',
'#1c487f',
'#4d80bf',
'#c24f4a',
'#8baa4a',
'#7b5ba1',
'#46acc8',
'#f9963b',
'#ffffff'
],
lang: {
// '设置标题': 'title',
// '正文': 'p',
// '链接文字': 'link text',
// '链接': 'link',
// '插入': 'insert',
// '创建': 'init'
},
// pasteFilterStyle: true,
// pasteIgnoreImg: true,
debug: false,
zIndex: 100,
showLinkImg: false,
uploadImgMaxSize: 5 * 1024 * 1024,
uploadImgMaxLength: 1,
uploadImgShowBase64: false,
customUploadImg: this.customUploadImg,
}
this.editor = new WangEditor("#editor")
if (this.hiddenMenus) {
config.menus = []
}
this.editor.customConfig = config
this.editor.create()
},
async customUploadImg(files, insert) {
const file = files[0]
const response = await this.$api.UploadImage(file)
if (response.success && response.data) {
insert(response.data)
} else {
this.$message.error("上传图片失败,请稍后重试")
}
},
setEnabled(enabled) {
this.$nextTick(() => {
this.editor && this.editor.$textElem.attr('contenteditable', enabled)
})
},
setHtml(html) {
this.$nextTick(() => {
this.editor && this.editor.txt.html(html)
})
},
getHtml() {
const html = this.editor ? xss.filterXSS(this.editor.txt.html()) : ''
return html
},
clear() {
this.editor && this.editor.txt.clear()
},
getData() {
// console.log(this.getHtml())
},
setData() {
const html = `
<p>输入内容...</p>
<h2>dadadadadada</h2>
<p>adadadad&nbsp;</p>
<table border="0" width="100%" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<th>hello&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</th>
<th>&nbsp;dada</th>
</tr>
<tr>
<td>&nbsp;adad</td>
<td>&nbsp;ad</td>
</tr>
</tbody>
</table>
<p><br></p>
<p>a<img src="http://192.168.0.47:8090/file/download?fileId=a32a4ac9-4207-4b2a-9874-7519d78ab8d4.png" style="max-width: 100%;"><span
style="font-weight: bold;">dfadf</span><span style="font-weight: bold;"></span></p>
<p><span style="font-weight: bold; font-size: xx-large; font-family: Tahoma; font-style: italic;">ddddddddd</span></p>
<p><span style="text-decoration-line: underline;"><span
style="font-weight: bold; font-size: xx-large; font-family: Tahoma; font-style: italic;">dddd</span></span>
</p>
<p><span style="font-family: 宋体; font-size: x-small; color: rgb(139, 170, 74);">ddddafafdadfa</span></p>
<p><span style="font-family: 宋体; font-size: x-small; color: rgb(139, 170, 74);">dddafadfadfadf</span></p>
`
this.setHtml(html)
},
}
}
</script>
<style>
</style>
<template>
<footer>
<div style="color:yellow;">©Copyright 2020 江北新区</div>
</footer>
</template>
<script>
export default {
data() {
return {
}
},
computed:{
},
methods: {
},
mounted() {
},
created(){
}
}
</script>
<style lang="scss">
</style>
<template>
<header>
<div class="header-user">
<img src="../../assets/image/login-bg.jpg" alt=""/>
<div>
<p class="user-name">{{userNameInfoStr}}</p>
<p class="user-role">{{userRoleInfoStr}}</p>
</div>
</div>
<div class="header-logout">
<span @click="handleLogout">
<img src="../../assets/image/icon-logout.png" alt="">
<p>退出</p>
</span>
</div>
</header>
</template>
<script>
import {
mapActions,
mapGetters
} from "vuex"
export default {
data() {
return {
menu:[]
}
},
computed:{
...mapGetters("user", [
"userName",
"userBlockName",
"userRoleName"
]),
userNameInfoStr() {
return `你好,${this.userName} !`
},
userRoleInfoStr() {
let str = ""
if (this.userBlockName) {
str += `${this.userBlockName} `
}
if (this.userRoleName) {
str += `${this.userRoleName} `
}
return str
}
},
methods: {
...mapActions("user", [
"LogoutActionAction"
]),
handleLogout(){
this.$confirm("是否退出登录", "提示", {
type: "warning",
closeOnClickModal: false,
cancelButtonClass: "cancel",
confirmButtonClass: "confirm",
}).then(() => {
// 清除登录信息
this.LogoutActionAction()
}).catch(() => {})
},
},
mounted() {
},
created(){
}
}
</script>
<style lang="scss">
</style>
<template>
<el-menu router :default-active="$route.path">
<template>
<div class="menu-logo">
<!-- <router-link :to="{name:'home'}" class="span"> -->
<span><img src="../../assets/image/icon-menu-logo.png" alt="">链通万家</span>
<!-- </router-link> -->
</div>
<div class="menu-title">常用菜单</div>
<el-menu-item v-for="item in menu" :key="item.meta.name" :index="item.path">
<span>{{item.meta.name}}</span>
<i :class="item.meta.icon"></i>
</el-menu-item>
</template>
</el-menu>
</template>
<script>
import router from "@/router/index.js"
import {
mapState
} from "vuex"
export default {
data() {
return {
collapse: false,
menu: [],
roleId:[],
}
},
computed: {
...mapState({
userMenus: state => state.user.userMenus
})
},
methods: {
routerList(data){
const menuRoutes = data.filter(item => { return item.meta && item.meta.icon })
return menuRoutes.filter(item => {
const isInMenu = this.userMenus.some(auth => { return auth.path === item.path })
return isInMenu
})
}
},
mounted() {
this.menu = this.routerList(router.options.routes)
},
created() {
},
}
</script>
<style>
</style>
<template>
<el-container class="layout">
<el-aside width="180px">
<Sidebar></Sidebar>
</el-aside>
<el-container>
<el-header height="65px">
<Header></Header>
</el-header>
<el-main>
<router-view></router-view>
</el-main>
<!-- <el-footer>
<Footer></Footer>
</el-footer> -->
</el-container>
</el-container>
</template>
<script>
import Header from "./layout/header.vue"
// import Footer from "./layout/footer.vue"
import Sidebar from "./layout/sidebar.vue"
export default {
components: {
Header,
Sidebar
},
data() {
return {
userName: "",
sidebarNav: [],
}
},
computed: {
},
methods: {
},
created() {
},
mounted() {
}
}
</script>
<style lang="scss">
</style>
<template>
<el-dialog
custom-class="custom-dialog"
:width="width"
:title="title"
:visible.sync="isVisible"
:close-on-click-modal="false"
@open="handleOpen()"
@close="handleClose()"
:before-close="handleCancel">
<slot name="content"></slot>
<template slot="footer"><slot name="footer"></slot></template>
</el-dialog>
</template>
<script>
export default{
props:{
width: {
type: String,
default: '50%'
},
title: {
type: String,
default: ''
},
isVisible: {
type: Boolean,
default: false,
},
callOpen: {
type: Function
},
callClose: {
type: Function
},
callCancel: {
type: Function
}
},
data() {
return {
}
},
computed: {
},
methods:{
handleOpen() {
this.callOpen && this.callOpen()
},
handleClose() {
this.callClose && this.callClose()
},
handleCancel() {
this.callCancel && this.callCancel()
}
},
mounted(){}
}
</script>
<style lang="scss">
$dialog-border-radius: 20px;
.el-dialog.custom-dialog {
background: #fff;
box-shadow:0px 6px 36px 0px rgba(13,4,8,0.43);
border-radius: $dialog-border-radius;
.el-dialog__header {
display: flex;
flex-flow: row nowrap;
justify-content: center;
align-items: center;
padding: 0 60px;
height: 60px;
background: #ffb73f;
text-align: center;
border-radius: $dialog-border-radius $dialog-border-radius 0 0;
.el-dialog__title {
flex: 1;
font-size: 21px;
font-weight: bold;
color:#8A4E22;
line-height: 60px;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.el-dialog__headerbtn {
font-size: 50px;
top: 0;
right: 10px;
.el-dialog__close {
color: #EFEFF7;
}
}
}
.el-dialog__footer {
padding: 0;
border-radius: 0 0 $dialog-border-radius $dialog-border-radius;
}
}
</style>
<template>
<el-pagination
background
layout="total, prev, pager, next,sizes"
:current-page="queryInfo.pageIndex"
:page-size="queryInfo.pageSize"
:total="total"
:page-sizes="[10, 20, 50,100]"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"/>
</template>
<script>
export default{
props:{
total:{
type:Number,
default:0
},
queryInfo:{
type:Object,
default:() => {
return{}
}
},
inquireList:{
type:Function
}
},
methods:{
handleSizeChange(value){
this.queryInfo.pageSize = value
this.queryInfo.pageIndex = 1
this.inquireList && this.inquireList(this.queryInfo)
},
handleCurrentChange(value){
this.queryInfo.pageIndex = value
this.inquireList && this.inquireList(this.queryInfo)
}
},
}
</script>
<style>
</style>
This source diff could not be displayed because it is too large. You can view the blob instead.
import Vue from "vue"
import { BlockRoleType } from "@/config/constant"
import store from "@/vuex/store";
Vue.directive("preventReClick",{
inserted(el,binding){
el.addEventListener("click",() => {
el.disabled = true
setTimeout(() => {
el.disabled = false
}, binding.value || 1500)
})
}
})
Vue.directive("permission", {
bind(el, { value }) {
let isHas = false
const roleId = store.getters["user/userRole"];
// 设置业委会委员、会计、物业 需要管理员权限
if (value === 'block_set_comMember'
|| value === 'block_set_accountant'
|| value === 'block_set_servant') {
isHas = roleId === BlockRoleType.admin
}
// 会计有添加账号权限
if (value === 'account_add_balance') {
isHas = roleId === BlockRoleType.accountant
}
// 事项
if (value === 'matter_create_rectification' || value === 'matter_create_letter') {
isHas = roleId === BlockRoleType.comMember
}
if (value === 'matter_create'
|| value === 'matter_create_vote'
|| value === 'matter_create_vote-result'
|| value === 'matter_create_announce') {
isHas = roleId === BlockRoleType.comMember || roleId === BlockRoleType.temporal
}
setTimeout(() => {
if (!isHas) {
try {
el.parentNode.removeChild(el)
} catch (err) {
// console.log(err)
}
}
}, 200)
}
})
import Vue from 'vue'
import App from './App.vue'
import router from './router/index'
import store from './vuex/store'
import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/dist/js/bootstrap.min'
import './plugins/element.js'
import './plugins/qrcode.js'
import "./assets/css/main.scss"
import "./assets/css/layout.scss"
// 公共样式、布局样式
// 主题色调修改在assets/_style.scss 修改里面的变量即可
// 页面内容区布局分为2大块
// .content-query 为条件查询区域
// .content-list 为列表展示区域
// 不属于这两块内容的另起类名
// 封装axios
import api from "./axios/index"
Vue.use(api)
// 过滤器封装
import filters from "./filters/index"
Object.keys(filters).forEach(key => {
Vue.filter(key,filters[key])
})
// 全局注册 二次封装loading等待框、以及确认框函数
import ElPack from "./utils/interaction.js"
Vue.prototype.$ElPack = ElPack
// 自定义指令
import "./directives"
// Clipboard
import Clipboard from "v-clipboard"
Vue.use(Clipboard)
// Vuex
import storage from "./utils/storage.js"
Vue.prototype.$storage = storage
// ngprogress
import NProgress from "nprogress";
import 'nprogress/nprogress.css'
NProgress.inc(0.3);
NProgress.configure({ easing: "ease", speed: 500, showSpinner: false });
Vue.config.productionTip = false
router.beforeEach((to,from,next) => {
NProgress.start()
const whiteList = ["/404"]
if (whiteList.some(path => { return path === to.path })) {
next()
} else {
const {user} = store.state
// 检测是否已登录
if (user.token) {
const authList = user.userMenus
const redirectPathList = ["/login"]
const shouldRedirectToDefault = redirectPathList.some(path => { return path === to.path })
if (!to.path || shouldRedirectToDefault) {
const defaultAuth = authList[0]
// 加载第一个菜单栏项
if (defaultAuth && defaultAuth.path) {
next({ path: defaultAuth.path, replace: true })
} else {
next({ path: "/404", replace: true })
}
} else {
const isAuthed = authList.some(authItem => {
const result = to.path === authItem.path
|| to.path.startsWith(authItem.path)
return result
})
isAuthed ? next() : next({ path: "/404", replace: true })
}
} else {
// 进入登录页面
if (to.path === "/login") {
next()
} else {
next({ path: "/login", replace: true })
}
}
}
})
router.afterEach(() => {
NProgress.done()
})
window.vm = new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
import Vue from 'vue'
import {
Link,
Avatar,
Pagination,
Dialog,
Autocomplete,
Dropdown,
DropdownMenu,
DropdownItem,
Menu,
Submenu,
MenuItem,
MenuItemGroup,
Input,
InputNumber,
Radio,
RadioGroup,
RadioButton,
Checkbox,
CheckboxButton,
CheckboxGroup,
Switch,
Select,
Option,
OptionGroup,
Button,
ButtonGroup,
Table,
TableColumn,
DatePicker,
TimeSelect,
TimePicker,
Popover,
Tooltip,
Breadcrumb,
BreadcrumbItem,
Form,
FormItem,
Tabs,
TabPane,
Tag,
Tree,
Alert,
Slider,
Icon,
Row,
Col,
Upload,
Progress,
Badge,
Card,
Rate,
Steps,
Step,
Carousel,
CarouselItem,
Collapse,
CollapseItem,
Cascader,
ColorPicker,
Transfer,
Container,
Header,
Aside,
Main,
Footer,
Loading,
MessageBox,
Message,
Notification,
Divider,
Calendar
} from 'element-ui';
Vue.use(Link)
Vue.use(Avatar)
Vue.use(Pagination);
Vue.use(Dialog);
Vue.use(Autocomplete);
Vue.use(Dropdown);
Vue.use(DropdownMenu);
Vue.use(DropdownItem);
Vue.use(Menu);
Vue.use(Submenu);
Vue.use(MenuItem);
Vue.use(MenuItemGroup);
Vue.use(Input);
Vue.use(InputNumber);
Vue.use(Radio);
Vue.use(RadioGroup);
Vue.use(RadioButton);
Vue.use(Checkbox);
Vue.use(CheckboxButton);
Vue.use(CheckboxGroup);
Vue.use(Switch);
Vue.use(Select);
Vue.use(Option);
Vue.use(OptionGroup);
Vue.use(Button);
Vue.use(ButtonGroup);
Vue.use(Table);
Vue.use(TableColumn);
Vue.use(DatePicker);
Vue.use(TimeSelect);
Vue.use(TimePicker);
Vue.use(Popover);
Vue.use(Tooltip);
Vue.use(Breadcrumb);
Vue.use(BreadcrumbItem);
Vue.use(Form);
Vue.use(FormItem);
Vue.use(Tabs);
Vue.use(TabPane);
Vue.use(Tag);
Vue.use(Tree);
Vue.use(Alert);
Vue.use(Slider);
Vue.use(Icon);
Vue.use(Row);
Vue.use(Col);
Vue.use(Upload);
Vue.use(Progress);
Vue.use(Badge);
Vue.use(Card);
Vue.use(Rate);
Vue.use(Steps);
Vue.use(Step);
Vue.use(Carousel);
Vue.use(CarouselItem);
Vue.use(Collapse);
Vue.use(CollapseItem);
Vue.use(Cascader);
Vue.use(ColorPicker);
Vue.use(Transfer);
Vue.use(Container);
Vue.use(Header);
Vue.use(Aside);
Vue.use(Main);
Vue.use(Footer);
Vue.use(Divider);
Vue.use(Loading.directive);
Vue.use(Calendar)
Vue.prototype.$loading = Loading.service;
Vue.prototype.$msgbox = MessageBox;
Vue.prototype.$alert = MessageBox.alert;
Vue.prototype.$confirm = MessageBox.confirm;
Vue.prototype.$prompt = MessageBox.prompt;
Vue.prototype.$notify = Notification;
Vue.prototype.$message = Message;
import Vue from 'vue'
import QRCode from 'qrcodejs2'
Vue.prototype.$qrCode = QRCode;
import Vue from "vue"
import VueRouter from "vue-router"
import main from "@/components/main.vue"
Vue.use(VueRouter)
// 解决首页路由跳转的时候同一个路由多次添加,未跳转完成就重复跳转
const routerPush = VueRouter.prototype.push
VueRouter.prototype.push = function push (to) {
return routerPush.call(this, to).catch(err => err)
}
const routes = [
{
path: "/user",
name: "user",
component: main,
redirect: "/user",
meta: {
icon: "el-icon-arrow-right",
name: "用户管理"
},
children: [
{
path: "/",
name: "user_index",
meta: {
name: "用户管理",
type: "sidebar"
},
component: () => import("@/views/user/index")
}
]
},
{
path:"/404",
name:"404",
component:() => import("@/views/user/404")
},
{
path: "*",
redirect: "/404"
},
{
path: "/",
redirect: "/login"
},
{
path: "/login",
name: "login",
component: () => import("@/views/user/login"),
},
]
const router = new VueRouter({
mode: "history",
base: process.env.BASE_URL,
routes
})
export default router
import Cookies from 'js-cookie'
const AUTH_TOKEN = "token"
export function getToken() {
return Cookies.get(AUTH_TOKEN) || ""
}
export function setToken(token) {
return Cookies.set(AUTH_TOKEN, token)
}
export function removeToken() {
return Cookies.remove(AUTH_TOKEN)
}
/**
* Creates a function like `round`.
*
* @private
* @param {string} methodName The name of the `Math` method to use when rounding.
* @returns {Function} Returns the new round function.
*/
function createRound(methodName) {
const func = Math[methodName]
return (number, precision) => {
precision = precision == null ? 0 : (precision >= 0 ? Math.min(precision, 292) : Math.max(precision, -292))
if (precision) {
// Shift with exponential notation to avoid floating-point issues.
// See [MDN](https://mdn.io/round#Examples) for more details.
let pair = `${number}e`.split('e')
const value = func(`${pair[0]}e${+pair[1] + precision}`)
pair = `${value}e`.split('e')
return +`${pair[0]}e${+pair[1] - precision}`
}
return func(number)
}
}
export const floor = createRound('floor')
export const round = createRound('round')
export const ceil = createRound('ceil')
// https://github.com/lodash/lodash/blob/377e2d87c88893a8a1e4e3cd04da5a8893ea7a7b/.internal/createRound.js
\ No newline at end of file
Date.prototype.Format = function (fmt) {
var o = {
//月份
"M+": this.getMonth() + 1,
//日
"d+": this.getDate(),
//小时
"H+": this.getHours(),
"h+": this.getHours(),
//分
"m+": this.getMinutes(),
//秒
"s+": this.getSeconds(),
//季度
"q+": Math.floor((this.getMonth() + 3) / 3),
//毫秒
"S": this.getMilliseconds()
};
if (/(y+)/.test(fmt))
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt))
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
}
import {
Loading,
MessageBox
} from "element-ui"
class ElPack {
constructor(text, type, loading) {
this.text = text
this.type = type
this.loading = loading
}
open(text) {
this.loading = Loading.service({
lock: true, //全屏锁定的标识符
text: text, //文字提示
spinner: 'el-icon-loading', //图片
background: 'rgba(0, 0, 0, 0.7)' //背景颜色
})
}
close() {
this.loading.close()
}
confirm(text, type) {
return MessageBox.confirm(text, "提示", {
cancelButtonClass: 'cancel',
confirmButtonClass: 'confirm',
type: type,
})
}
}
export default new ElPack
const storage = {
set(name,value){
if(!value){
localStorage.removeItem(name)
return
}
const expire = new Date().getTime()
localStorage[name] = JSON.stringify({
value,
time:expire + 7 * 24 * 60 * 60 * 1000
})
},
get(name){
const data = localStorage[name]
if(data !== undefined){
let cacheData = JSON.parse(data)
if(!cacheData || cacheData.time < new Date()){
localStorage.removeItem(name)
return null
}
return cacheData.value
}
},
remove(name){
return localStorage.removeItem(name)
}
}
export default storage
\ No newline at end of file
// 节流
export function throttle(fn, interval) {
let delay = interval || 1500
let previous = 0
return function() {
let now = Date.now()
let that = this
let args = arguments
if (now - previous > delay) {
fn.apply(that, args)
previous = now
}
}
}
// 防抖
export function debounce(fn, interval) {
let delay = interval || 1500
let timer = null
return function() {
let that = this
let args = arguments
timer && clearTimeout(timer)
timer = setTimeout(function() {
fn.apply(that, args)
}, delay)
}
}
var unique = 0;
export function uuid(prefix) {
const time = Date.now();
const random = Math.floor(Math.random() * 1000000000);
unique++;
return prefix + '_' + random + unique + String(time);
}
export function getDocumentTitle(content) {
return "链通万家 | " + content
}
import * as RegExp from "./regexp"
const validate = {
account:(rule,value,callback) => {
if(!value){
return callback(new Error("请输入用户名"))
}
const reg = RegExp.REG_Account
if(!reg.test(value)){
return callback(new Error("用户名即为用户登录账号,英文+数字组成,限30字符"))
}
return callback()
},
realName:(rule,value,callback) => {
const reg = RegExp.REG_RealName
if (value) {
if (!reg.test(value)) {
return callback(new Error("真实姓名为中文,且为2~10个字符"))
}
}
return callback()
},
phone:(rule,value,callback) => {
const reg = RegExp.REG_PhoneNumber
if(value){
if(!reg.test(value)){
return callback(new Error("请输入11位手机号码"))
}
}
return callback()
},
identityCard:(rule,value,callback) => {
const reg = RegExp.IDENTITY_CARD
if(value){
if(!reg.test(value)){
return callback(new Error("请输入18位身份证号码"))
}
}
return callback()
},
password:(rule, value, callback) => {
if (!value) {
return callback(new Error("请输入您的原始密码"));
}
if (value.length < 6 || value.length > 16) {
return callback(new Error("密码长度请输入6-16位"));
}
return callback();
},
fundAmount: (rule, value, callback) => {
if (value) {
if (!RegExp.REG_AMOUNT.test(value)) {
return callback(new Error("输入不合法,最多保留2位小数"))
}
}
return callback()
},
amountVerify:(rule,value,callback) => {
if(value){
const reg = RegExp.REG_AMOUNT
if(reg.test(value)){
return callback()
}
return callback(new Error("金额最多保留2位小数"))
}
return callback("请输入金额")
},
percentVerify: (rule, value, callback) => {
if (value) {
const reg = RegExp.REG_Percent
if (!reg.test(value)) {
return callback(new Error("请输入正确的百分比,最多保留2位小数"))
}
if (value > 100) {
return callback(new Error("请输入正确的百分比,最多保留2位小数"))
}
}
return callback()
},
integer:(rule,value,callback) => {
if(value){
const reg = RegExp.REG_INTEGER
if(!reg.test(value)){
return callback(new Error("请输入正整数"))
}
}
return callback()
},
multiNumber:(rule,value,callback) => {
if(!value){
return callback(new Error("请填写解限售数量"))
}
const reg = RegExp.MULTI_NUMBER
if(!reg.test(value)){
return callback(new Error("数字之间请用逗号隔开区分"))
}
return callback()
},
dateVerify:(rule,value,callback) => {
if(!value){
return callback(new Error("请填写解限售时间"))
}
const reg = RegExp.REG_DATE
if(!reg.test(value)){
return callback(new Error("正确格式为YYYY-MM-DD,用逗号隔开区分"))
}
return callback()
}
}
export default validate
// 保留2位小数的金额正则
export const REG_AMOUNT = new RegExp("^\\d{1,15}(\\.\\d{0,2})?$")
// 登录账号,由英文+数字组成,长度为30个字符
export const REG_Account = new RegExp("^[a-zA-Z0-9_-]{1,30}$")
// 真实姓名为中文,且为2~10个字符
export const REG_RealName = new RegExp("^[\u4E00-\u9FA5]{2,10}$")
// 手机号码
export const REG_PhoneNumber = new RegExp("^1[3456789]\\d{9}$")
// 百分比
export const REG_Percent = new RegExp("^(\\d|[1-9]\\d|100)(\\.\\d{0,2})?$")
// 非负正数(0或者正整数)
export const REG_INTEGER = new RegExp("^(0|[1-9][0-9]*)$")
export const MULTI_NUMBER = new RegExp("^\\d+(,\\d+)*,?$")
export const REG_DATE = new RegExp("^\\d{4}\\-\\d{2}\\-\\d{2}(,\\d{4}\\-\\d{2}\\-\\d{2})*$")
// 身份证号码验证
export const IDENTITY_CARD = new RegExp("/(^\\d{15}$)|(^\\d{18}$)|(^\\d{17}(\\d|X|x)$)/")
<template>
<div class="main-error">
<div class="content-error">
<div class="error-code">4<span>0</span>4</div>
<div class="error-desc">{{tips}}</div>
<div class="error-desc_sub">{{subTips}}</div>
<div class="error-handle">
<!-- <router-link to="/">
<el-button type="primary" v-preventReClick @click="backHome">返回首页</el-button>
</router-link> -->
<el-button class="error-btn" v-preventReClick @click="backLast">返回</el-button>
</div>
</div>
</div>
</template>
<script>
export default{
data(){
return{
tips:"您要找的页面不存在",
subTips:"可能是因为您的链接地址有误、或者您没有权限访问该页面。"
}
},
methods:{
backHome(){
this.$router.push("/")
},
backLast(){
// console.log(window.history, window.history.state, this.$router.history)
if (window.history.length <= 1) {
this.backHome()
return false
}
this.backHome() // FIXME: 没有权限的path -> 404,点击后会自动重定向到404
// this.$router.history.go(-1)
}
},
mounted(){
},
created() {
document.title = "404 Not Found"
},
}
</script>
<style lang="scss" scoped>
.main-error {
width: 100%;
height: 100vh;
display: flex;
justify-content: center;
align-content: center;
.content-error{
display: flex;
justify-content: center;
align-items: center;
align-content: center;
flex-direction: column;
box-sizing: border-box;
.error-code{
align-self: center;
line-height: 1;
font-size: 250px;
font-weight: bolder;
color: #f02d2d;
span{
color:#00a854
}
}
.error-desc{
margin-top: 15px;
font-size: 30px;
color: #777;
}
.error-desc_sub{
margin-top: 20px;
font-size: 16px;
color: #777;
}
.error-handle{
margin-top: 30px;
padding-bottom: 200px;
.error-btn{
// margin-left: 100px;
}
}
}
}
</style>
<template>
<div class="main-content">
<div class="content-query">
<el-form inline>
<el-form-item label="用户名称">
<el-input clearable v-model.trim="queryInfo.name" placeholder="请输入用户名称"></el-input>
</el-form-item>
<el-form-item label="联系电话">
<el-input clearable v-model.trim="queryInfo.mobile" placeholder="请输入联系电话"></el-input>
</el-form-item>
<el-form-item label="身份证号">
<el-input clearable v-model.trim="queryInfo.idCard" placeholder="请输入身份证号"></el-input>
</el-form-item>
<el-form-item>
<el-button class="query" v-preventReClick @click="handleSearch">查询</el-button>
</el-form-item>
</el-form>
</div>
<div class="content-list">
<el-table
:data="dataList"
stripe
v-loading="loading"
element-loading-text="数据加载中..."
element-loading-spinner="el-icon-loading"
element-loading-background="rgba(255, 255, 255, 1)">
<el-table-column width="100px" label="用户编号">
<template slot-scope="scope">
<span class="row-index">{{scope.$index+1}}</span>
</template>
</el-table-column>
<el-table-column label="用户名称" prop="realName">
<template slot-scope="scope">
<span v-clipboard="scope.row.realName" v-clipboard:success="clipboardSuccess">{{scope.row.realName}}</span>
</template>
</el-table-column>
<el-table-column label="身份证号" prop="idCard">
<template slot-scope="scope">
<span v-clipboard="scope.row.idCard" v-clipboard:success="clipboardSuccess">{{scope.row.idCard}}</span>
</template>
</el-table-column>
<el-table-column label="联系电话" prop="mobile">
<template slot-scope="scope">
<span v-clipboard="scope.row.mobile" v-clipboard:success="clipboardSuccess">{{scope.row.mobile}}</span>
</template>
</el-table-column>
<el-table-column label="用户角色">
<template slot-scope="scope">
<span class="row-role" v-preventReClick @click="handleCheck(scope.row)">
{{scope.row.roleEdits|roleFilter}}
</span>
</template>
</el-table-column>
</el-table>
<Pagination :total="total" :queryInfo="queryInfo" :inquireList="queryList"></Pagination>
</div>
<Dialog title="角色详情" :data="dialog.data" :isVisible="dialog.isShow" :callCancel="handleDialogCancel">
</Dialog>
</div>
</template>
<script>
import Pagination from "@/components/tool/pagination.vue"
import Dialog from "./userDetailDialog.vue"
import {
QUERY_PAGE_SIZE_20,
BlockRoleType,
BlockRoleSortIndex,
BlockRoleNameFromType
} from "@/config/constant.js"
export default {
components: {
Pagination,
Dialog
},
data() {
return {
loading: false,
queryInfo: {
pageIndex: 1,
pageSize: QUERY_PAGE_SIZE_20,
name: "",
mobile: "",
idCard: ""
},
total: 0,
dataList: [],
dialog: {
isShow: false,
data: {}
},
}
},
computed: {
},
methods: {
// 获取数据函数
async queryList() {
this.loading = true
const response = await this.$api.QueryUserListAsync(this.queryInfo)
this.loading = false
if (response.success) {
const { count = 0, data = [] } = response.data || {}
this.total = count
this.dataList = Object.freeze(data)
} else {
this.$message.error(response.returnMsg || "数据加载失败")
}
},
// 条件查询
handleSearch() {
this.queryInfo.pageIndex = 1
this.queryList()
},
handleCheck(row) {
this.dialog.data = row
this.dialog.isShow = true
},
handleDialogCancel() {
this.dialog.isShow = false
},
clipboardSuccess({ value }) {
if (!value) {
return
}
this.$notify({
title: '',
message: '拷贝成功',
type: 'success',
duration: 1500
})
}
},
filters: {
roleFilter: (roles) => {
if (roles && Array.isArray(roles) && roles.length > 0) {
return [...roles].sort((i1, i2) => {
if (BlockRoleSortIndex(i1.roleId) > BlockRoleSortIndex(i2.roleId)) return 1
else if (BlockRoleSortIndex(i1.roleId) === BlockRoleSortIndex(i2.roleId)) return 0
else return -1
}).map(item => {
return BlockRoleNameFromType(Number(item.roleId))
}).filter((item, index, arr) => {
return !!item && arr.indexOf(item, 0) === index
}).join('、')
}
return BlockRoleNameFromType(BlockRoleType.simple)
}
},
mounted() {
},
created() {
document.title = "链通万家 | 用户管理"
this.queryList()
}
}
</script>
<style lang="scss">
</style>
<template>
<div class="main-login">
<div class="login-content">
<h2><img src="../../assets/image/icon-login-logo.png" alt="">链通万家</h2>
<div class="qrcode-main">
<div class="qrcode-img" ref="qrcodeImg"></div>
<div :class="['qrcode-help', {'scanned': scanned}]">
<p class="error-cont center">二维码已扫描</p>
</div>
<div :class="['qrcode-help', {'agreed': agreed}]">
<p class="error-cont center">登录中...</p>
</div>
<div :class="['qrcode-help', {'cancelled': cancelled}]"
v-preventReClick
@click="resetQRCode">
<img src="../../assets/image/icon-qrcode-refresh.png" alt="">
<p class="error-cont">登录已取消</p>
</div>
<div :class="['qrcode-help', {'invalid': invalid}]"
v-preventReClick
@click="resetQRCode">
<img src="../../assets/image/icon-qrcode-refresh.png" alt="">
<p class="error-cont">二维码已失效</p>
</div>
<div :class="['qrcode-help', {'req_failed': requestFailed}]"
v-preventReClick
@click="resetQRCode">
<img src="../../assets/image/icon-qrcode-refresh.png" alt="">
<p class="error-cont">获取二维码失败</p>
</div>
</div>
<div class="tip-message">请使用微信小程序扫码登录</div>
</div>
</div>
</template>
<script>
import {
mapState,
mapActions
} from "vuex"
import QRCode from "qrcodejs2"
import { QrCodeStatus } from "@/config/constant"
export default {
data() {
return {
qrcodeInfo: {
qrcode: '',
token: '',
status: QrCodeStatus.ready
},
requestQRCodeFlag: true,
qrcode: null,
timer: null,
loopTime: 2000 // 2s
}
},
computed: {
...mapState({
token: state => state.user.token,
userMenus: state => state.user.userMenus
}),
invalid() {
return this.qrcodeInfo.status === QrCodeStatus.outdated
},
scanned() {
return this.qrcodeInfo.status === QrCodeStatus.scanned
},
cancelled() {
return this.qrcodeInfo.status === QrCodeStatus.cancelled
},
agreed() {
return this.qrcodeInfo.status === QrCodeStatus.agreed
},
requestFailed() {
return !this.requestQRCodeFlag && !this.qrcodeInfo.qrcode
}
},
methods: {
...mapActions("user", [
"SetUserTokenAction",
"SetUserInfoAction",
"SetUserMenusAction",
"CleanLoggedDataAction"
]),
...mapActions("industry", [
"SetIndustryBlockId"
]),
startLoop() {
this.stopLoop()
this.timer = setInterval(this.fetchQRCodeStatus, this.loopTime);
},
stopLoop() {
if (this.timer) {
clearInterval(this.timer)
this.timer = null
}
},
createQRCode() {
this.qrcode = new QRCode(this.$refs.qrcodeImg, {
width: 160,
height: 160,
colorDark: "#333333",
colorLight: "#ffffff",
correctLevel: QRCode.CorrectLevel.L
})
},
async fetchQRCodeStatus() {
const response = await this.$api.GetQRCodeStatusAsync(this.qrcodeInfo.qrcode)
const resData = response.data || {}
const status = Number(resData.code)
this.qrcodeInfo.status = status
if (status === QrCodeStatus.cancelled || status === QrCodeStatus.outdated) {
this.stopLoop()
} else if (status === QrCodeStatus.agreed && resData.token) {
this.stopLoop()
this.handleLogin(resData)
}
},
async getQRCode() {
const response = await this.$api.GetQRCodeAsync()
this.requestQRCodeFlag = response.success && response.data
if (this.requestQRCodeFlag) {
this.qrcodeInfo = {
qrcode: response.data,
status: QrCodeStatus.ready
}
this.qrcode.makeCode(this.qrcodeInfo.qrcode)
this.$refs.qrcodeImg.title = ""
this.startLoop()
}
},
resetQRCode() {
this.qrcode.clear()
this.requestQRCodeFlag = true
this.qrcodeInfo.qrcode = ''
this.qrcodeInfo.status = QrCodeStatus.ready
this.getQRCode()
},
async handleLogin(data) {
const { token, userInfo, consoleMenus } = data || {}
console.log(token, userInfo, consoleMenus)
// 设置token
this.SetUserTokenAction(token)
// 设置用户信息
this.SetUserInfoAction(userInfo)
// 设置业委会成立小区ID
this.SetIndustryBlockId(userInfo.blockId)
// 设置菜单栏
this.SetUserMenusAction(consoleMenus.map(({name, url}) => {return { name, path: url }}))
// 进入主页
this.redirectHomePage()
},
redirectHomePage() {
const homeMenu = this.userMenus[0]
if (homeMenu && homeMenu.path) {
// 根据当前权限跳转到菜单栏第一个页面
this.$router.push({ path: homeMenu.path })
} else {
this.$router.push({ path: "/404" })
}
}
},
beforeDestroy() {
this.stopLoop()
},
created() {
document.title = "链通万家 | 登录"
},
mounted() {
const homeMenu = this.userMenus[0]
if (this.token && homeMenu && homeMenu.path) {
this.redirectHomePage()
} else {
this.CleanLoggedDataAction()
this.$nextTick(() => {
this.createQRCode()
this.getQRCode()
})
}
}
}
</script>
<style lang="scss" scoped>
$content-width: 320px;
$content-height: 350px;
$qrcode-width:160px;
$qrcode-height:160px;
.main-login {
width: 100%;
height: 100vh;
background: #DCDCDC;
background-image: url(../../assets/image/login-bg.jpg);
background-size: 100% 100%;
position: relative;
.login-content {
width: $content-width;
height: $content-height;
position: absolute;
right: 80px;
top: 130px;
padding: 0;
background: rgba(255,255,255,1.0);
opacity: 0.9;
border-radius: 30px;
box-shadow:0px 5px 16px 0px rgba(13,4,8,0.33);
text-align: center;
h2 {
margin: 30px auto;
font-size: 24px;
text-align: center;
color: #ffb73f;
font-weight:bold;
img {
width: 35px;
height: 35px;
margin-right: 8px;
}
}
.qrcode-main {
margin: 0 auto 30px;
width: $qrcode-width;
height: $qrcode-height;
.qrcode-img {
position: absolute;
display: inline-block;
background: rgba(250,250,250,0.9);
left: ceil(($content-width - $qrcode-width) / 2);
img {
width: $qrcode-width;
height: $qrcode-height;
background-color: lightgray;
}
}
.qrcode-help {
position: absolute;
width: $qrcode-width;
height: $qrcode-height;
background: rgba(250,250,250,0.9);
z-index: 9;
text-align: center;
display: none;
&.scanned,&.cancelled,&.invalid,&.agreed,&.req_failed {
display: block;
}
.error-cont {
color: #4C91B0;
font-size: 20px;
font-weight: 500;
margin-top: 5px;
&.center {
margin-top: 70px;
}
}
img {
margin: 20px auto 0px;
width: 80px;
height: 80px;
}
}
}
.tip-message{
color: #585858;
font-size:18px;
font-weight:bold;
}
}
}
</style>
<template>
<Dialog
width="650px"
:title="title"
:isVisible="isVisible"
:callOpen="handleOpen"
:callClose="handleClose"
:callCancel="callCancel">
<div class="user-detail-dialog__content" slot="content">
<div class="row-detail__item">
<span class="row-detail__item_title">用户名称:</span>
<span class="row-detail__item_text">{{userInfo.realName}}</span>
</div>
<div class="row-detail__item">
<span class="row-detail__item_title">联系电话:</span>
<span class="row-detail__item_text">{{userInfo.mobile}}</span>
</div>
<div class="row-detail__item">
<span class="row-detail__item_title">身份证号:</span>
<span class="row-detail__item_text">{{userInfo.idCard}}</span>
</div>
<div class="row-detail__item bottom">
<span class="row-detail__item_title roles">角色对应小区:</span>
<el-table max-height="250" class="row-detail__item_roles" :data="rolesData" border stripe>
<el-table-column label="角色名称">
<template slot-scope="scope">
{{scope.row.roleId | roleFormat}}
</template>
</el-table-column>
<el-table-column label="所属小区">
<template slot-scope="scope">
{{scope.row.blockName || '/'}}
</template>
</el-table-column>
<el-table-column label="楼栋">
<template slot-scope="scope">
{{scope.row.building}}
</template>
</el-table-column>
<el-table-column label="单元">
<template slot-scope="scope">
{{scope.row.unit}}
</template>
</el-table-column>
<el-table-column label="房号">
<template slot-scope="scope">
{{scope.row.room}}
</template>
</el-table-column>
</el-table>
</div>
</div>
</Dialog>
</template>
<script>
import Dialog from "@/components/tool/dialog.vue"
import {
BlockRoleSortIndex,
BlockRoleNameFromType
} from "@/config/constant.js"
export default{
components: {
Dialog
},
props:{
title: {
type: String,
default: ''
},
data: {
type: Object,
default: null
},
isVisible: {
type: Boolean,
default: false,
},
callCancel: {
type: Function
}
},
data() {
return {
userInfo: {
realName: '',
mobile: '',
idCard: ''
},
rolesData: null
}
},
filters: {
roleFormat: (roleId) => {
return BlockRoleNameFromType(Number(roleId))
}
},
methods:{
handleOpen() {
this.$nextTick(function() {
const data = this.data || {}
this.userInfo.realName = data.realName || ''
this.userInfo.mobile = data.mobile || ''
this.userInfo.idCard = data.idCard || ''
if (data.roleEdits && Array.isArray(data.roleEdits) && data.roleEdits.length > 0) {
this.rolesData = [...data.roleEdits].sort((i1, i2) => {
if (BlockRoleSortIndex(i1.roleId) > BlockRoleSortIndex(i2.roleId)) return 1
else if (BlockRoleSortIndex(i1.roleId) === BlockRoleSortIndex(i2.roleId)) return 0
else return -1
})
}
})
},
handleClose() {
this.$nextTick(function() {
this.userInfo.realName = ''
this.userInfo.mobile = ''
this.userInfo.idCard = ''
this.rolesData = null
})
},
},
mounted(){}
}
</script>
<style lang="scss">
.user-detail-dialog__content {
$item_height: 35px;
.row-detail__item {
&.bottom {
margin-bottom: 25px;
}
.row-detail__item_title {
margin-left: 100px;
color: #5C5C5C;
font-size: 14px;
font-weight: bold;
line-height: $item_height;
&.roles {
color: #868686;
font-size: 10px;
}
}
.row-detail__item_text {
margin-left: 20px;
color: #8A4E22;
font-size: 14px;
font-weight: 400;
line-height: $item_height;
}
.row-detail__item_roles {
width: 550px;
margin: 0 auto;
th {
background-color: #FFB73F;
padding: 1px 0;
text-align: center;
.cell {
font-size: 13px;
color: #8A4E22;
line-height: 35px;
}
}
td {
background-color: #fff;
padding: 1px 0;
text-align: center;
.cell {
font-size: 12px;
color: #5BACAB;
line-height: 30px;
}
}
}
}
}
</style>
import Vue from 'vue'
import Vuex from 'vuex'
import user from "./user/index.js"
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
user: user,
}
})
import * as TYPES from './types';
import api from "@/axios/api"
const actions = {
SetUserInfoAction({ commit }, userInfo) {
commit(TYPES.SET_USER_INFO, userInfo)
},
SetUserTokenAction({ commit }, token) {
commit(TYPES.SET_AUTH_TOKEN, token)
},
SetUserMenusAction({ commit }, menus) {
commit(TYPES.SAVE_USER_MENUS, menus)
},
CleanLoggedDataAction({ dispatch, commit }) {
dispatch("SetUserTokenAction", null)
dispatch("SetUserInfoAction", null)
dispatch("SetUserMenusAction", null)
commit(TYPES.SET_FINANCE_TYPES, null)
commit(TYPES.SET_ALL_BLOCK_LIST, null)
},
LogoutActionAction({ dispatch }) {
dispatch('CleanLoggedDataAction')
window.localStorage.clear()
window.location.reload()
},
async GetFinanceTypeListAction({ commit, state }) {
const { financeTypeList } = state
if (financeTypeList && Array.isArray(financeTypeList) && financeTypeList.length > 0) {
return financeTypeList
}
const { success, data } = await api.GetFinanceTypeListAsync()
if (success && data && Array.isArray(data) && data.length > 0) {
commit(TYPES.SET_FINANCE_TYPES, data)
return data
}
return []
},
async GetAllBlockListAction({ commit, state }) {
const { allBlockList } = state
if (allBlockList && Array.isArray(allBlockList) && allBlockList.length > 0) {
return allBlockList
}
const { success, data } = await api.GetAllBlockListAsync()
if (success && data && Array.isArray(data) && data.length > 0) {
commit(TYPES.SET_ALL_BLOCK_LIST, data)
return data
}
return []
}
}
export default actions
import {
BlockRoleType,
BlockRoleNameFromType,
MatterType,
MatterStatusOwnerCode
} from "@/config/constant.js"
const getters = {
// 用户id
userId: state => {
const { userInfo } = state
return userInfo.id || ''
},
// 用户姓名
userName: state => {
const { userInfo } = state
return userInfo.realName || ''
},
// 用户身份证
userIdCard: state => {
const { userInfo } = state
return userInfo.idNumber || ''
},
// 用户手机号码
userMobile: state => {
const { userInfo } = state
return userInfo.phone || ''
},
userBlockName: state => {
const { userInfo } = state
return userInfo.blockName || ''
},
userRole: state => {
const { userInfo } = state
return Number(userInfo.roleId)
},
userRoleName: state => {
const { userInfo } = state
return BlockRoleNameFromType(Number(userInfo.roleId))
},
isLoggedAdmin: state => {
const { userInfo } = state
return Number(userInfo.roleId) === BlockRoleType.admin
},
isCurrentBlockOnlyTemporal: state => {
const { userInfo } = state
return userInfo.blockName === '旭日爱上城6区'
},
isElementPermission: state => (value, data = null) => {
const { userInfo } = state
const roleId = Number(userInfo.roleId)
// const roleId = BlockRoleType.comMember
// 设置网格管理员
if (value === 'block_set_grid_manager') {
return roleId === BlockRoleType.admin
}
// 设置业委会委员、临管人员、会计、物业 需要管理员权限
if (value === 'block_set_comMember'
|| value === 'block_set_community'
|| value === 'block_set_management'
|| value === 'block_set_temporal'
|| value === 'block_set_accountant'
|| value === 'block_set_servant') {
if (roleId !== BlockRoleType.admin) {
return false
}
// 仅旭日爱上城6区需要设置临管人员
const { name } = data || {}
const block_xrasc6 = '旭日爱上城6区'
if (value === 'block_set_temporal') {
return name === block_xrasc6
}
if (value === 'block_set_comMember') {
return name !== block_xrasc6
}
return true
}
// 会计有添加账号权限
if (value === 'account_add_balance') {
return roleId === BlockRoleType.accountant
}
// 事项
if (value === 'matter_create') {
return (
roleId === BlockRoleType.comMember ||
roleId === BlockRoleType.temporal
)
}
if (value === 'matter_create_rectification' || value === 'matter_create_letter') {
return (
roleId === BlockRoleType.comMember ||
roleId === BlockRoleType.temporal
)
}
if (value === 'matter_create_vote'
|| value === 'matter_create_vote-result'
|| value === 'matter_create_announce') {
return (
roleId === BlockRoleType.comMember ||
roleId === BlockRoleType.temporal
)
}
if (value === 'matter_action_audit_approve' || value === 'matter_action_audit_reject') {
// 审核仅社区和物管办
const { status } = data || {}
const myStatus = Number(status)
return (roleId === BlockRoleType.community && myStatus === MatterStatusOwnerCode.communityInProgress) ||
(roleId === BlockRoleType.management && myStatus === MatterStatusOwnerCode.managementInProgress)
}
if (value === 'matter_action_reply_letter') {
// 已发布的公函,业委会需要进行回函
const { matterType, status, isLetters } = data || {}
const myMatterType = String(matterType)
const myStatus = Number(status)
return (
myMatterType === MatterType.letter &&
myStatus === MatterStatusOwnerCode.end &&
!isLetters &&
(roleId === BlockRoleType.comMember || roleId === BlockRoleType.temporal)
)
}
if (value === 'matter_action_accept_rectification') {
// 已发布的整改单,物业需要进行接收整改
const { matterType, status, isAccept } = data || {}
const myMatterType = String(matterType)
const myStatus = Number(status)
return (
myMatterType === MatterType.rectification &&
myStatus === MatterStatusOwnerCode.end &&
!isAccept &&
roleId === BlockRoleType.servant
)
}
if (value === 'matter_action_edit_tags') {
return false
}
return false
}
}
export default getters
\ No newline at end of file
import state from "./state.js"
import actions from "./actions.js"
import mutations from "./mutations.js"
import getters from "./getters.js"
export default {
namespaced: true,
state,
mutations,
actions,
getters
}
\ No newline at end of file
This diff is collapsed. Click to expand it.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment