Merge pull request 'v1.2' (#4) from develop into master

master
p5rn97v8z 4 months ago
commit 3b135f6d74

@ -1,39 +1,30 @@
# house
一、系统介绍
本项目前后端分离
#### 介绍
{**以下是 Gitee 平台说明,您可以替换此简介**
Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN。专为开发者提供稳定、高效、安全的云端软件开发协作平台
无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
本系统分为管理员、房主、普通用户三种种角色
#### 软件架构
软件架构说明
用户角色包含以下功能:
登录、注册、房屋管理、房屋资讯、个人中心、密码修改
我的预约看房管理、我的租赁订单管理、我的房租缴纳管理、我的房屋退租管理、我的报修管理
房主角色包含以下功能:
#### 安装教程
登录、注册、房屋租赁管理、租赁订单管理、个人中心、密码修改、房屋缴租管理、房屋退租管理、报修信息管理
管理员角色包含以下功能:
1. xxxx
2. xxxx
3. xxxx
登录、用户管理、房主管理、房源分类管理、房屋租赁管理、预约看房管理、租赁订单管理、房屋缴租管理、房屋退租管理、报修信息管理
房屋资讯管理、个人中心、密码修改、轮播图管理
二、所用技术
后端技术栈:
#### 使用说明
springboot
mybatis-plus
MySQL 的
前端技术栈:
1. xxxx
2. xxxx
3. xxxx
vue 系列
元素 UI
三、环境介绍
基础环境 IDEA/eclipse JDK 1.8 Mysql5.7及以上Node.js14Maven3.6
#### 参与贡献
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/)
所有项目以及源代码本人均调试运行无问题 可支持远程调试运行

@ -0,0 +1,40 @@
<template>
<!-- App 根容器 -->
<div id="app" class="">
<!-- 路由视图出口所有页面内容将在此处动态渲染 -->
<router-view></router-view>
</div>
</template>
<script>
// App
export default {
// "app"
name: "app",
};
</script>
<style lang="scss">
/* 全局样式重置 */
* {
padding: 0;
margin: 0;
}
/* 设置 html 和 body 占满整个窗口 */
html, body {
width: 100%;
height: 100%;
}
/* 让 #app 容器也占满整个浏览器窗口 */
#app {
height: 100%;
}
/* 再次设置 body 的内外边距(防止某些浏览器默认样式影响) */
body {
padding: 0;
margin: 0;
}
</style>

@ -0,0 +1,9 @@
/* 改变主题色变量 */
$--color-primary: #00c292 !default;
$--color-success: #67c23a !default;
$--color-warning: #e6a23c !default;
$--color-danger: #f56c6c !default;
$--color-info: #909399 !default;
/* 改变 icon 字体路径变量,必需 */
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "~element-ui/packages/theme-chalk/src/index";

@ -0,0 +1,47 @@
.form-content {
background: #ffffff;
padding: 10px 10px 0 10px;
}
.table-content {
background: #ffffff;
padding: 0 10px;
}
.pagination-content {
margin-top: 10px;
padding-bottom: 10px;
text-align: right;
}
.detail-form-content{
background: #ffffff;
padding: 10px;
.el-input{
min-width: 200px;
max-width: 600px;
}
}
.bg {
position: absolute;
top: 0;
left: 0;
height: 100%;
}
.login-form {
position: absolute;
top: 0;
right: 0;
width: 350px;
height: 100%;
background: #ffffff;
padding: 0 60px;
font-size: 18px;
font-weight: bold;
}
.h1 {
margin-top: 80px;
font-size: 20px;
font-weight: bold;
}
.btn-login {
margin-top: 50px;
width: 100%;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

@ -0,0 +1,44 @@
<template>
<!-- 定义一个 SVG 图标组件 -->
<svg :class="svgClass" aria-hidden="true" v-on="$listeners"> <!-- -->
<use :xlink:href="iconName" /> <!-- 使用指定的图标符号 -->
</svg>
</template>
<script>
export default {
name: 'SvgIcon', // SvgIcon
props: { //
iconClass: { //
type: String, //
required: true //
},
className: { //
type: String, //
default: '' //
}
},
computed: { //
iconName() { // xlink:href
return `#icon-${this.iconClass}` // #icon-className
},
svgClass() { // SVG
if (this.className) { //
return 'svg-icon ' + this.className // svg-icon
} else { //
return 'svg-icon' // svg-icon
}
}
}
}
</script>
<style scoped>
.svg-icon {
width: 1em; /* 设置宽度为 1em */
height: 1em; /* 设置高度为 1em */
vertical-align: -0.15em; /* 设置垂直对齐方式 */
fill: currentColor; /* 设置填充颜色为当前文字颜色 */
overflow: hidden; /* 隐藏溢出内容 */
}
</style>

@ -0,0 +1,119 @@
<template>
<!-- 面包屑导航组件 -->
<el-breadcrumb class="app-breadcrumb" separator="(●'◡'●)" style="height:50px;backgroundColor:rgba(79, 73, 73, 1);borderRadius:0px;padding:0px 20px 0px 20px;boxShadow:;borderWidth:2px;borderStyle:;borderColor:rgba(193, 180, 180, 0.5);">
<!-- 动画过渡效果的面包屑项容器 -->
<transition-group name="breadcrumb" class="box" :style="1==1?'justifyContent:flex-start;':1==2?'justifyContent:center;':'justifyContent:flex-end;'">
<!-- 遍历生成面包屑项 -->
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
<!-- 如果是最后一项或设置了 noRedirect则显示为不可点击文本 -->
<span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.name }}</span>
<!-- 否则显示为可点击链接 -->
<a v-else @click.prevent="handleLink(item)">{{ item.name }}</a>
</el-breadcrumb-item>
</transition-group>
</el-breadcrumb>
</template>
<script>
import pathToRegexp from 'path-to-regexp' //
import { generateTitle } from '@/utils/i18n' //
export default {
data() {
return {
levelList: null //
}
},
watch: {
//
$route() {
this.getBreadcrumb()
}
},
created() {
this.getBreadcrumb() //
this.breadcrumbStyleChange() //
},
methods: {
generateTitle, //
getBreadcrumb() {
// meta.title
let route = this.$route //
let matched = route.matched.filter(item => item.meta) // meta
const first = matched[0] //
matched = [{ path: '/index' }].concat(matched) //
this.levelList = matched.filter(item => item.meta) //
},
isDashboard(route) {
const name = route && route.name //
if (!name) {
return false // false
}
return name.trim().toLocaleLowerCase() === 'Index'.toLocaleLowerCase() //
},
pathCompile(path) {
// ( GitHub #561)
const { params } = this.$route //
var toPath = pathToRegexp.compile(path) //
return toPath(params) //
},
handleLink(item) {
const { redirect, path } = item //
if (redirect) {
this.$router.push(redirect) //
return
}
this.$router.push(path) //
},
breadcrumbStyleChange(val) {
this.$nextTick(() => { // DOM
//
document.querySelectorAll('.app-breadcrumb .el-breadcrumb__separator').forEach(el => {
el.innerText = "(●'◡'●)" //
el.style.color = "rgba(235, 90, 170, 1)" //
})
//
document.querySelectorAll('.app-breadcrumb .el-breadcrumb__inner a').forEach(el => {
el.style.color = "rgba(196, 212, 244, 1)"
})
//
document.querySelectorAll('.app-breadcrumb .el-breadcrumb__inner .no-redirect').forEach(el => {
el.style.color = "rgba(244, 149, 32, 1)"
})
let str = "vertical" //
if ("vertical" === str) {
let headHeight = "60px" //
headHeight = parseInt(headHeight) + 10 + 'px' //
document.querySelectorAll('.app-breadcrumb').forEach(el => {
el.style.marginTop = headHeight //
})
}
})
}
}
}
</script>
<style lang="scss" scoped>
.app-breadcrumb {
display: block; //
font-size: 14px; //
line-height: 50px; //
.box {
display: flex; // 使
width: 100%; //
height: 100%; //
justify-content: flex-start; //
align-items: center; //
}
.no-redirect {
color: #97a8be; //
cursor: text; //
}
}
</style>

@ -0,0 +1,87 @@
<template>
<!-- 面包屑导航组件使用斜杠作为分隔符 -->
<el-breadcrumb class="app-breadcrumb" separator="/">
<!-- 动态过渡效果的面包屑项容器 -->
<transition-group name="breadcrumb">
<!-- 遍历生成面包屑项 -->
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
<!-- 如果是最后一项或设置了 noRedirect则显示纯文本 -->
<span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.name }}</span>
<!-- 否则显示可点击链接 -->
<a v-else @click.prevent="handleLink(item)">{{ item.name }}</a>
</el-breadcrumb-item>
</transition-group>
</el-breadcrumb>
</template>
<script>
import pathToRegexp from 'path-to-regexp' //
import { generateTitle } from '@/utils/i18n' //
export default {
data() {
return {
levelList: null //
}
},
watch: {
//
$route() {
this.getBreadcrumb()
}
},
created() {
this.getBreadcrumb() //
},
methods: {
generateTitle, //
getBreadcrumb() {
// meta.title
// 便
console.log(this.$route)
let matched = this.$route.matched.filter(item => item.meta) // meta
const first = matched[0] //
matched = [{ path: '/index' }].concat(matched) //
this.levelList = matched.filter(item => item.meta) // meta
},
//
isDashboard(route) {
const name = route && route.name //
if (!name) {
return false // false
}
return name.trim().toLocaleLowerCase() === 'Index'.toLocaleLowerCase() // "Index"
},
//
pathCompile(path) {
//
const { params } = this.$route //
var toPath = pathToRegexp.compile(path) // 使 path-to-regexp
return toPath(params) //
},
//
handleLink(item) {
const { redirect, path } = item //
if (redirect) {
this.$router.push(redirect) //
return
}
this.$router.push(path) //
}
}
}
</script>
<style lang="scss" scoped>
.app-breadcrumb.el-breadcrumb {
display: inline-block; /* 设置为行内块级元素 */
font-size: 14px; /* 设置字体大小 */
line-height: 50px; /* 设置行高 */
margin-left: 8px; /* 设置左侧外边距 */
.no-redirect {
color: #97a8be; /* 设置不可跳转文字颜色 */
cursor: text; /* 设置鼠标样式为文本 */
}
}
</style>

@ -0,0 +1,239 @@
<template>
<div>
<!-- 图片上传组件辅助 -->
<el-upload
class="avatar-uploader" <!-- 定义上传组件的样式类 -->
:action="getActionUrl" <!-- 指定图片上传的目标地址 -->
name="file" <!-- 上传文件的字段名 -->
:headers="header" <!-- 设置上传请求头 -->
:show-file-list="false" <!-- 不显示上传文件列表 -->
:on-success="uploadSuccess" <!-- 上传成功时的回调函数 -->
:on-error="uploadError" <!-- 上传失败时的回调函数 -->
:before-upload="beforeUpload" <!-- 上传前的钩子函数 -->
></el-upload>
<!-- 富文本编辑器组件 -->
<quill-editor
class="editor" <!-- 定义富文本编辑器的样式类 -->
v-model="value" <!-- 双向绑定编辑器内容 -->
ref="myQuillEditor" <!-- 定义引用名称 -->
:options="editorOption" <!-- 配置编辑器选项 -->
@blur="onEditorBlur($event)" <!-- 失去焦点事件 -->
@focus="onEditorFocus($event)" <!-- 获得焦点事件 -->
@change="onEditorChange($event)" <!-- 内容改变事件 -->
></quill-editor>
</div>
</template>
<script>
//
const toolbarOptions = [
["bold", "italic", "underline", "strike"], // 线线
["blockquote", "code-block"], //
[{ header: 1 }, { header: 2 }], //
[{ list: "ordered" }, { list: "bullet" }], //
[{ script: "sub" }, { script: "super" }], //
[{ indent: "-1" }, { indent: "+1" }], //
// [{'direction': 'rtl'}], //
[{ size: ["small", false, "large", "huge"] }], //
[{ header: [1, 2, 3, 4, 5, 6, false] }], //
[{ color: [] }, { background: [] }], //
[{ font: [] }], //
[{ align: [] }], //
["clean"], //
["link", "image", "video"] //
];
import { quillEditor } from "vue-quill-editor"; // Quill
import "quill/dist/quill.core.css"; // Quill
import "quill/dist/quill.snow.css"; // Snow
import "quill/dist/quill.bubble.css"; // Bubble
export default {
props: {
/* 编辑器的内容 */
value: {
type: String //
},
action: {
type: String //
},
/* 图片大小限制 */
maxSize: {
type: Number, //
default: 4000 // 4000 KB
}
},
components: {
quillEditor // Quill
},
data() {
return {
content: this.value, //
quillUpdateImg: false, //
editorOption: {
placeholder: "", //
theme: "snow", // 使 Snow
modules: {
toolbar: {
container: toolbarOptions, // 使
// container: "#toolbar",
handlers: {
image: function(value) {
if (value) {
// input
document.querySelector(".avatar-uploader input").click();
} else {
this.quill.format("image", false); //
}
}
// link: function(value) {
// if (value) {
// var href = prompt('url');
// this.quill.format("link", href);
// } else {
// this.quill.format("link", false);
// }
// },
}
}
}
},
// serverUrl: `${base.url}sys/storage/uploadSwiper?token=${storage.get('token')}`, //
header: {
// token: sessionStorage.token
'Token': this.$storage.get("Token") // Token
} //
};
},
computed: {
//
getActionUrl: function() {
// return this.$base.url + this.action + "?token=" + this.$storage.get("token");
return `/${this.$base.name}/` + this.action; //
}
},
methods: {
onEditorBlur() {
//
},
onEditorFocus() {
//
},
onEditorChange() {
console.log(this.value); //
//
this.$emit("input", this.value);
},
//
beforeUpload() {
//
this.quillUpdateImg = true;
},
uploadSuccess(res, file) {
// res
//
let quill = this.$refs.myQuillEditor.quill;
//
if (res.code === 0) {
//
let length = quill.getSelection().index;
// res.url
quill.insertEmbed(length, "image", this.$base.url+ "upload/" +res.file);
//
quill.setSelection(length + 1);
} else {
this.$message.error("图片插入失败"); //
}
//
this.quillUpdateImg = false;
},
//
uploadError() {
//
this.quillUpdateImg = false;
this.$message.error("图片插入失败"); //
}
}
};
</script>
<style>
.editor {
line-height: normal !important; /* 设置行高为正常值 */
height: 400px; /* 设置编辑器高度 */
}
.ql-snow .ql-tooltip[data-mode="link"]::before {
content: "请输入链接地址:"; /* 自定义链接输入提示文字 */
}
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
border-right: 0px; /* 去掉右侧边框 */
content: "保存"; /* 自定义保存按钮文字 */
padding-right: 0px; /* 去掉右侧内边距 */
}
.ql-snow .ql-tooltip[data-mode="video"]::before {
content: "请输入视频地址:"; /* 自定义视频输入提示文字 */
}
.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
content: "14px"; /* 默认字体大小 */
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
content: "10px"; /* 小号字体大小 */
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
content: "18px"; /* 大号字体大小 */
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
content: "32px"; /* 超大号字体大小 */
}
.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
content: "文本"; /* 默认文本样式 */
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
content: "标题1"; /* 一级标题 */
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
content: "标题2"; /* 二级标题 */
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
content: "标题3"; /* 三级标题 */
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
content: "标题4"; /* 四级标题 */
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
content: "标题5"; /* 五级标题 */
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
content: "标题6"; /* 六级标题 */
}
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
content: "标准字体"; /* 默认字体 */
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
content: "衬线字体"; /* 衬线字体 */
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
content: "等宽字体"; /* 等宽字体 */
}
</style>

@ -0,0 +1,139 @@
<template>
<div>
<!-- 上传文件组件 -->
<el-upload
ref="upload" <!-- 定义上传组件的引用名称 -->
:action="getActionUrl" <!-- 指定文件上传的目标地址 -->
list-type="picture-card" <!-- 设置为图片卡片样式 -->
:multiple="multiple" <!-- 是否支持多文件上传 -->
:limit="limit" <!-- 限制上传文件的数量 -->
:headers="myHeaders" <!-- 设置上传请求头 -->
:file-list="fileList" <!-- 绑定文件列表 -->
:on-exceed="handleExceed" <!-- 超出文件数量限制时的回调函数 -->
:on-preview="handleUploadPreview" <!-- 点击文件列表时的预览回调 -->
:on-remove="handleRemove" <!-- 文件移除时的回调函数 -->
:on-success="handleUploadSuccess" <!-- 文件上传成功时的回调函数 -->
:on-error="handleUploadErr" <!-- 文件上传失败时的回调函数 -->
:before-upload="handleBeforeUpload" <!-- 文件上传前的钩子函数 -->
>
<i class="el-icon-plus"></i> <!-- 显示上传按钮图标 -->
<div slot="tip" class="el-upload__tip" style="color:#838fa1;">{{tip}}</div> <!-- 提示文字 -->
</el-upload>
<!-- 查看大图的对话框 -->
<el-dialog :visible.sync="dialogVisible" size="tiny" append-to-body>
<img width="100%" :src="dialogImageUrl" alt> <!-- 显示大图 -->
</el-dialog>
</div>
</template>
<script>
import storage from "@/utils/storage"; //
import base from "@/utils/base"; //
export default {
data() {
return {
//
dialogVisible: false,
//
dialogImageUrl: "",
//
fileList: [],
fileUrlList: [], // URL
myHeaders:{} //
};
},
props: ["tip", "action", "limit", "multiple", "fileUrls"], //
mounted() {
this.init(); //
this.myHeaders= {
'Token':storage.get("Token") // Token
}
},
watch: {
fileUrls: function(val, oldVal) {
// fileUrls
this.init();
}
},
computed: {
//
getActionUrl: function() {
// return base.url + this.action + "?token=" + storage.get("token");
return `/${this.$base.name}/` + this.action; //
}
},
methods: {
//
init() {
// fileUrls
if (this.fileUrls) {
this.fileUrlList = this.fileUrls.split(","); //
let fileArray = [];
this.fileUrlList.forEach(function(item, index) {
var url = item; // URL
var name = index; // 使
var file = {
name: name,
url: url
};
fileArray.push(file); //
});
this.setFileList(fileArray); //
}
},
handleBeforeUpload(file) {
//
},
//
handleUploadSuccess(res, file, fileList) {
if (res && res.code === 0) {
// URL
fileList[fileList.length - 1]["url"] =
this.$base.url + "upload/" + file.response.file;
this.setFileList(fileList); //
this.$emit("change", this.fileUrlList.join(",")); // change
} else {
this.$message.error(res.msg); //
}
},
//
handleUploadErr(err, file, fileList) {
this.$message.error("文件上传失败"); //
},
//
handleRemove(file, fileList) {
this.setFileList(fileList); //
this.$emit("change", this.fileUrlList.join(",")); // change
},
//
handleUploadPreview(file) {
this.dialogImageUrl = file.url; // URL
this.dialogVisible = true; //
},
//
handleExceed(files, fileList) {
this.$message.warning(`最多上传${this.limit}张图片`); //
},
// fileList
setFileList(fileList) {
var fileArray = []; //
var fileUrlArray = []; // URL
// token
var token = storage.get("token");
fileList.forEach(function(item, index) {
var url = item.url.split("?")[0]; // URL
var name = item.name; //
var file = {
name: name,
url: url + "?token=" + token // token
};
fileArray.push(file); //
fileUrlArray.push(url); // URL
});
this.fileList = fileArray; //
this.fileUrlList = fileUrlArray; // URL
}
}
};
</script>
<style lang="scss" scoped>
</style>

@ -0,0 +1,60 @@
<template>
<el-card class="box-card"> <!-- 定义卡片组件的样式类 -->
<div slot="header" class="header"> <!-- 卡片头部内容 -->
<span>{{title}}</span> <!-- 显示标题内容 -->
<span>
<el-tag size="small" :type="titleTag">{{titleUnit}}</el-tag> <!-- -->
</span>
</div>
<div class="content"> <!-- 卡片主体内容 -->
{{content}}&nbsp;&nbsp; <!-- 显示主要内容 -->
<span class="unit">{{contentUnit}}</span> <!-- 显示内容单位 -->
</div>
<div class="bottom"> <!-- 卡片底部内容 -->
<span>{{bottomTitle}}</span> <!-- 显示底部标题 -->
<span>
{{bottomContent}} <!-- 显示底部内容 -->
<i :class="bottomIcon"></i> <!-- 显示底部图标 -->
</span>
</div>
</el-card>
</template>
<script>
export default {
props: [
"title", //
"titleTag", //
"titleUnit", //
"content", //
"contentUnit", //
"bottomTitle", //
"bottomContent", //
"bottomIcon" //
]
};
</script>
<style lang="scss" scoped>
.box-card {
margin-right: 10px; /* 设置卡片右侧外边距 */
.header {
display: flex; /* 使用弹性布局 */
justify-content: space-between; /* 子元素两端对齐 */
align-items: center; /* 子元素垂直居中对齐 */
}
.content {
font-size: 30px; /* 设置字体大小 */
font-weight: bold; /* 设置字体加粗 */
color: #666; /* 设置字体颜色 */
text-align: center; /* 文本居中对齐 */
.unit {
font-size: 16px; /* 设置单位字体大小 */
}
}
.bottom {
display: flex; /* 使用弹性布局 */
justify-content: space-between; /* 子元素两端对齐 */
align-items: center; /* 子元素垂直居中对齐 */
margin-top: 10px; /* 设置顶部外边距 */
}
}
</style>

@ -0,0 +1,126 @@
<template>
<div id="home-chart" style="width:100%;height:400px;"></div> <!-- 定义图表容器设置宽高 -->
</template>
<script>
export default {
mounted() {
this.homeChart(); //
},
methods: {
homeChart() {
// domecharts
var myChart = this.$echarts.init(document.getElementById("home-chart")); // DOM ECharts
//
var option = {
tooltip: {
trigger: "axis" //
},
legend: {
data: ["访问量", "用户量", "收入"] //
},
grid: {
left: "3%", //
right: "4%", //
bottom: "3%", //
containLabel: true //
},
xAxis: {
type: "category", // x
boundaryGap: false, //
data: [
"1月",
"2月",
"3月",
"4月",
"5月",
"6月",
"7月",
"8月",
"9月",
"10月",
"11月",
"12月"
] // x
},
yAxis: {
type: "value" // y
},
series: [
{
name: "访问量", //
type: "line", // 线
stack: "总量", //
data: [
120,
132,
101,
134,
90,
230,
210,
120,
132,
101,
134,
90,
230
] // 访
},
{
name: "用户量", //
type: "line", // 线
stack: "总量", //
data: [
220,
182,
191,
234,
290,
330,
310,
182,
191,
234,
290,
330,
310
] //
},
{
name: "收入", //
type: "line", // 线
stack: "总量", //
data: [
150,
232,
201,
154,
190,
330,
410,
232,
201,
154,
190,
330,
410
] //
}
]
};
// 使
myChart.setOption(option); //
//
window.onresize = function() {
myChart.resize(); //
};
}
}
};
</script>
<style lang="scss" scoped>
#home-chart {
background: #ffffff; /* 设置背景颜色为白色 */
padding: 20px 0; /* 设置上下内边距为 20px */
}
</style>

@ -0,0 +1,101 @@
<template>
<div class="home-comment"> <!-- 定义用户留言组件的根容器 -->
<div class="title">用户留言</div> <!-- 显示标题用户留言 -->
<div class="comment-list"> <!-- 定义留言列表容器 -->
<div v-for="(item,index) in list" v-bind:key="index" class="comment-item"> <!-- -->
<div class="user-content"> <!-- 用户信息容器 -->
<el-image
class="avator" <!-- 用户头像 -->
:src="item.avator" <!-- 绑定头像图片地址 -->
></el-image>
<span class="user">{{item.name}}</span> <!-- 显示用户名 -->
</div>
<div class="comment">{{item.content}}</div> <!-- 显示留言内容 -->
<div class="create-time">{{item.createTime}}</div> <!-- 显示留言时间 -->
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
list: [ //
{
name: "MaskLin", //
avator:
"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg", //
content:
"你以为只要长得漂亮就有男生喜欢?你以为只要有了钱漂亮妹子就自己贴上来了?你以为学霸就能找到好工作?我告诉你吧,这些都是真的!", //
createTime: "5月02日 00:00" //
},
{
name: "MaskLin", //
avator:
"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg", //
content: "作者太帅了", //
createTime: "5月04日 00:00" //
},
{
name: "MaskLin", //
avator:
"https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg", //
content: "作者太帅了", //
createTime: "5月04日 00:00" //
},
{
name: "MaskLin", //
avator: "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg", //
content: "作者太帅了", //
createTime: "5月04日 00:00" //
}
]
};
}
};
</script>
<style lang="scss" scoped>
.home-comment {
background: #ffffff; /* 设置背景颜色为白色 */
.title {
font-size: 18px; /* 设置标题字体大小 */
color: #666; /* 设置标题字体颜色 */
font-weight: bold; /* 设置标题字体加粗 */
padding: 10px; /* 设置内边距 */
border-bottom: 1px solid #eeeeee; /* 设置底部边框 */
}
.comment-list {
padding: 10px; /* 设置内边距 */
.comment-item {
padding: 10px; /* 设置内边距 */
border-bottom: 1px solid #eeeeee; /* 设置底部边框 */
.user-content {
display: flex; /* 使用弹性布局 */
align-items: center; /* 子元素垂直居中对齐 */
.user {
font-size: 18px; /* 设置用户名字体大小 */
color: #666; /* 设置用户名字体颜色 */
font-weight: bold; /* 设置用户名字体加粗 */
line-height: 50px; /* 设置行高 */
margin-left: 10px; /* 设置左侧外边距 */
}
.avator {
width: 50px; /* 设置头像宽度 */
height: 50px; /* 设置头像高度 */
border-radius: 50%; /* 设置头像为圆形 */
}
}
.comment {
margin-top: 10px; /* 设置顶部外边距 */
font-size: 14px; /* 设置留言内容字体大小 */
color: #888888; /* 设置留言内容字体颜色 */
}
.create-time {
margin-top: 15px; /* 设置顶部外边距 */
font-size: 14px; /* 设置留言时间字体大小 */
color: #888888; /* 设置留言时间字体颜色 */
}
}
}
}
</style>

@ -0,0 +1,55 @@
<template>
<div class="home-progress"> <!-- 定义组件的根容器 -->
<div class="title">月访问量</div> <!-- 显示标题月访问量 -->
<div class="tip">同上期增长</div> <!-- 显示提示信息同上期增长 -->
<el-progress <!-- 使 Element UI -->
class="progress" <!-- 设置进度条的样式类 -->
:text-inside="true" <!-- 将文字显示在进度条内部 -->
:stroke-width="24" <!-- 设置进度条的宽度 -->
:percentage="20" <!-- 设置进度百分比为 20% -->
status="success" <!-- 设置进度条状态为成功绿色 -->
></el-progress>
<div class="title">月用户量</div> <!-- 显示标题月用户量 -->
<div class="tip">同上期增长</div> <!-- 显示提示信息同上期增长 -->
<el-progress <!-- 使 Element UI -->
class="progress" <!-- 设置进度条的样式类 -->
:text-inside="true" <!-- 将文字显示在进度条内部 -->
:stroke-width="24" <!-- 设置进度条的宽度 -->
:percentage="50" <!-- 设置进度百分比为 50% -->
status="success" <!-- 设置进度条状态为成功绿色 -->
></el-progress>
<div class="title">月收入</div> <!-- 显示标题月收入 -->
<div class="tip">同上期减少</div> <!-- 显示提示信息同上期减少 -->
<el-progress <!-- 使 Element UI -->
class="progress" <!-- 设置进度条的样式类 -->
:text-inside="true" <!-- 将文字显示在进度条内部 -->
:stroke-width="24" <!-- 设置进度条的宽度 -->
:percentage="28" <!-- 设置进度百分比为 28% -->
status="exception" <!-- 设置进度条状态为异常红色 -->
></el-progress>
</div>
</template>
<script>
export default {}; // Vue
</script>
<style lang="scss">
.home-progress {
background: #ffffff; /* 设置背景颜色为白色 */
height: 400px; /* 设置组件高度 */
padding: 20px; /* 设置内边距 */
.title {
color: #666666; /* 设置标题文字颜色 */
font-weight: bold; /* 设置字体加粗 */
font-size: 20px; /* 设置字体大小 */
margin-top: 10px; /* 设置顶部外边距 */
}
.tip {
color: #888888; /* 设置提示文字颜色 */
font-size: 16px; /* 设置字体大小 */
margin-top: 10px; /* 设置顶部外边距 */
}
.progress {
margin-top: 10px; /* 设置进度条顶部外边距 */
}
}
</style>

@ -0,0 +1,60 @@
<template>
<!-- 左侧导航栏组件 -->
<el-aside class="index-aside" width="200px"> <!-- 定义左侧导航栏宽度为200px -->
<div class="index-aside-inner"> <!-- 内部容器 -->
<el-menu default-active="1"> <!-- 定义菜单默认激活项为第1项 -->
<el-menu-item @click="menuHandler('/')" index="1"> <!-- 菜单项点击跳转到首页 -->
<!-- <i class="el-icon-s-home"></i> --> <!-- 注释掉的图标 -->
首页 <!-- 显示首页文字 -->
</el-menu-item>
<!-- 动态生成子菜单 -->
<sub-menu
v-for="menu in menuList" <!-- 遍历菜单列表 -->
:key="menu.menuId" <!-- 设置唯一标识符 -->
:menu="menu" <!-- 传递当前菜单数据 -->
:dynamicMenuRoutes="dynamicMenuRoutes" <!-- 传递动态路由数据 -->
></sub-menu>
</el-menu>
</div>
</el-aside>
</template>
<script>
import SubMenu from "@/components/index/IndexAsideSub"; //
export default {
data() {
return {
menuList: [], //
dynamicMenuRoutes: [] //
};
},
components: {
SubMenu //
},
mounted() {
//
this.menuList = JSON.parse(sessionStorage.getItem("menuList") || "[]"); //
this.dynamicMenuRoutes = JSON.parse( //
sessionStorage.getItem("dynamicMenuRoutes") || "[]"
);
},
methods: {
menuHandler(path) { //
this.$router.push({ path: path }); //
}
}
};
</script>
<style lang="scss" scoped>
.index-aside {
margin-top: 80px; /* 设置顶部外边距 */
overflow: hidden; /* 隐藏溢出内容 */
.index-aside-inner {
width: 217px; /* 设置内部容器宽度 */
height: 100%; /* 设置高度为100% */
overflow-y: scroll; /* 纵向滚动条 */
}
}
</style>

@ -0,0 +1,247 @@
<template>
<!-- 左侧导航栏组件 -->
<el-aside class="index-aside" height="100vh" width="210px"> <!-- 定义左侧导航栏宽度和高度 -->
<div class="index-aside-inner menulist" style="height:100%"> <!-- 内部容器设置高度为100% -->
<div v-for="item in menuList" :key="item.roleName" v-if="role==item.roleName" class="menulist-item" style="height:100%;broder:0;background-color:#988181"> <!-- -->
<div class="menulistImg" style="backgroundColor:#ff0000;padding:25px 0" v-if="false && menulistStyle == 'vertical'"> <!-- -->
<el-image v-if="'http://codegen.caihongy.cn/20201021/cc7d45d9c8164b58b18351764eba9be1.jpg'" src="http://codegen.caihongy.cn/20201021/cc7d45d9c8164b58b18351764eba9be1.jpg" fit="cover" /> <!-- 显示图片 -->
</div>
<el-menu mode="vertical" :unique-opened="true" class="el-menu-demo" style="height:100%;" background-color="#988181" text-color="#111010" active-text-color="#99EFED" default-active="0"> <!-- 垂直菜单设置背景色文字颜色等 -->
<el-menu-item index="0" :style="menulistBorderBottom" @click="menuHandler('')"><i v-if="true" class="el-icon-s-home" />首页</el-menu-item> <!-- -->
<el-submenu :index="1+''" :style="menulistBorderBottom"> <!-- 子菜单个人中心 -->
<template slot="title">
<i v-if="true" class="el-icon-user-solid" /> <!-- 图标 -->
<span>个人中心</span> <!-- 菜单标题 -->
</template>
<el-menu-item :index="1-1" @click="menuHandler('updatePassword')"></el-menu-item> <!-- 修改密码子菜单 -->
<el-menu-item :index="1-2" @click="menuHandler('center')"></el-menu-item> <!-- 个人信息子菜单 -->
</el-submenu>
<el-submenu :style="menulistBorderBottom" v-for=" (menu,index) in item.backMenu" :key="menu.menu" :index="index+2+''"> <!-- -->
<template slot="title">
<i v-if="true" :class="icons[index]" /> <!-- 图标 -->
<span>{{ menu.menu }}</span> <!-- 菜单标题 -->
</template>
<el-menu-item v-for=" (child,sort) in menu.child" :key="sort" :index="(index+2)+'-'+sort" @click="menuHandler(child.tableName)">{{ child.menu }}</el-menu-item> <!-- 动态生成的子菜单项 -->
</el-submenu>
</el-menu>
</div>
</div>
</el-aside>
</template>
<script>
import menu from '@/utils/menu' //
export default {
data() {
return {
menuList: [], //
dynamicMenuRoutes: [], //
role: '', //
icons: [ //
'el-icon-s-cooperation',
'el-icon-s-order',
'el-icon-s-platform',
'el-icon-s-fold',
'el-icon-s-unfold',
'el-icon-s-operation',
'el-icon-s-promotion',
'el-icon-s-release',
'el-icon-s-ticket',
'el-icon-s-management',
'el-icon-s-open',
'el-icon-s-shop',
'el-icon-s-marketing',
'el-icon-s-flag',
'el-icon-s-comment',
'el-icon-s-finance',
'el-icon-s-claim',
'el-icon-s-custom',
'el-icon-s-opportunity',
'el-icon-s-data',
'el-icon-s-check',
'el-icon-s-grid',
'el-icon-menu',
'el-icon-chat-dot-square',
'el-icon-message',
'el-icon-postcard',
'el-icon-position',
'el-icon-microphone',
'el-icon-close-notification',
'el-icon-bangzhu',
'el-icon-time',
'el-icon-odometer',
'el-icon-crop',
'el-icon-aim',
'el-icon-switch-button',
'el-icon-full-screen',
'el-icon-copy-document',
'el-icon-mic',
'el-icon-stopwatch',
],
menulistStyle: 'vertical', //
menulistBorderBottom: {}, //
}
},
mounted() {
const menus = menu.list() //
this.menuList = menus //
this.role = this.$storage.get('role') //
},
created() {
setTimeout(() => {
this.menulistStyleChange() //
}, 10)
this.icons.sort(() => { //
return (0.5 - Math.random())
})
this.lineBorder() //
},
methods: {
lineBorder() {
let style = 'vertical' //
let w = '1px' //
let s = 'solid' //
let c = '#ccc' //
if(style == 'vertical') { //
this.menulistBorderBottom = { //
borderBottomWidth: w,
borderBottomStyle: s,
borderBottomColor: c
}
} else { //
this.menulistBorderBottom = { //
borderRightWidth: w,
borderRightStyle: s,
borderRightColor: c
}
}
},
menuHandler(name) { //
let router = this.$router //
name = '/' + name //
router.push(name) //
},
//
setMenulistHoverColor() {
let that = this
this.$nextTick(() => {
document.querySelectorAll('.menulist .el-menu-item').forEach(el => { //
el.addEventListener("mouseenter", e => { //
e.stopPropagation()
el.style.backgroundColor = "rgba(238, 221, 129, 1)" //
})
el.addEventListener("mouseleave", e => { //
e.stopPropagation()
el.style.backgroundColor = "#988181" //
})
el.addEventListener("focus", e => { //
e.stopPropagation()
el.style.backgroundColor = "rgba(238, 221, 129, 1)" //
})
})
document.querySelectorAll('.menulist .el-submenu__title').forEach(el => { //
el.addEventListener("mouseenter", e => { //
e.stopPropagation()
el.style.backgroundColor = "rgba(238, 221, 129, 1)" //
})
el.addEventListener("mouseleave", e => { //
e.stopPropagation()
el.style.backgroundColor = "#988181" //
})
})
})
},
//
setMenulistIconColor() {
this.$nextTick(() => {
document.querySelectorAll('.menulist .el-submenu__title .el-submenu__icon-arrow').forEach(el => {
el.style.color = "rgba(153, 153, 153, 1)" //
})
})
},
//
menulistStyleChange() {
this.setMenulistIconColor() //
this.setMenulistHoverColor() //
this.setMenulistStyleHeightChange() //
let str = "vertical" //
if ("horizontal" === str) { //
this.$nextTick(() => {
document.querySelectorAll('.el-container .el-container').forEach(el => { //
el.style.display = "block"
el.style.paddingTop = "60px" //
})
document.querySelectorAll('.el-aside').forEach(el => { //
el.style.width = "100%"
el.style.height = "62px"
el.style.paddingTop = '0'
})
document.querySelectorAll('.index-aside .index-aside-inner').forEach(el => { //
el.style.paddingTop = '0'
})
})
}
if ("vertical" === str) { //
this.$nextTick(() => {
document.querySelectorAll('.index-aside .index-aside-inner').forEach(el => { //
el.style.paddingTop = "60px"
})
})
}
},
//
setMenulistStyleHeightChange() {
this.$nextTick(() => {
document.querySelectorAll('.menulist-item>.el-menu--horizontal>.el-menu-item').forEach(el => {
el.style.height = "62px" //
el.style.lineHeight = "62px" //
})
document.querySelectorAll('.menulist-item>.el-menu--horizontal>.el-submenu>.el-submenu__title').forEach(el => {
el.style.height = "62px" //
el.style.lineHeight = "62px" //
})
})
},
}
}
</script>
<style lang="scss" scoped>
.index-aside {
position: relative; //
overflow: hidden; //
.menulistImg {
padding: 24px 0; //
box-sizing: border-box; // 使
.el-image {
margin: 0 auto; //
width: 100px; //
height: 100px; //
border-radius: 100%; //
display: block; //
}
}
.index-aside-inner {
height: 100%; // 100%
margin-right: -17px; //
margin-bottom: -17px; //
overflow: scroll; //
overflow-x: hidden !important; //
padding-top: 60px; //
box-sizing: border-box; // 使
&:focus {
outline: none; //
}
.el-menu {
border: 0; //
}
}
}
</style>

@ -0,0 +1,76 @@
<template>
<!-- 左侧导航栏组件 -->
<el-aside class="index-aside" width="200px"> <!-- 定义左侧导航栏宽度为200px -->
<div class="index-aside-inner"> <!-- 内部容器 -->
<div v-for="item in menuList" v-bind:key="item.roleName"> <!-- -->
<el-menu
background-color="#263238" <!-- 设置背景颜色 -->
text-color="#fff" <!-- 设置文字颜色 -->
active-text-color="#ffd04b" <!-- 设置激活项的文字颜色 -->
default-active="0" <!-- 默认激活项索引 -->
v-if="role==item.roleName" <!-- 根据角色名称判断是否显示 -->
>
<el-menu-item @click="menuHandler('home')" index="0">首页</el-menu-item> <!-- -->
<el-submenu :index="1+''"> <!-- 子菜单个人中心 -->
<template slot="title">
<span>个人中心</span> <!-- 菜单标题 -->
</template>
<el-menu-item
@click="menuHandler('updatePassword')" <!-- 点击事件处理函数 -->
:index="1-1" <!-- 设置菜单项索引 -->
>修改密码</el-menu-item> <!-- -->
<el-menu-item
@click="menuHandler('center')" <!-- 点击事件处理函数 -->
:index="1-2" <!-- 设置菜单项索引 -->
>个人信息</el-menu-item> <!-- -->
</el-submenu>
<el-submenu
v-for=" (menu,index) in item.backMenu" <!-- 遍历后端菜单 -->
v-bind:key="menu.menu" <!-- 设置唯一标识符 -->
:index="index+2+''" <!-- 设置菜单项索引 -->
>
<template slot="title">
<span>{{menu.menu}}</span> <!-- 动态显示菜单标题 -->
</template>
<el-menu-item
v-for=" (child,sort) in menu.child" <!-- 遍历子菜单 -->
v-bind:key="sort" <!-- 设置唯一标识符 -->
@click="menuHandler(child.tableName)" <!-- 点击事件处理函数 -->
:index="(index+2)+'-'+sort" <!-- 设置菜单项索引 -->
>{{child.menu}}</el-menu-item> <!-- -->
</el-submenu>
</el-menu>
</div>
</div>
</el-aside>
</template>
<script>
import menu from "@/utils/menu"; //
export default {
data() {
return {
menuList: [], //
dynamicMenuRoutes: [], //
role: "" //
};
},
mounted() {
let menus = menu.list(); //
this.menuList = menus; //
this.role = this.$storage.get("role"); //
console.log(this.menuList); //
console.log(this.role); //
},
methods: {
menuHandler(name) { //
this.$router.push({ name: name }); //
}
}
};
</script>
<style lang="scss" scoped>
/* 样式部分暂无内容 */
</style>

@ -0,0 +1,56 @@
<template>
<!-- 如果菜单有子菜单且数量大于等于1则显示为子菜单 -->
<el-submenu v-if="menu.list && menu.list.length >= 1" :index="menu.menuId + ''">
<!-- 子菜单标题 -->
<template slot="title">
<span>{{ menu.name }}</span> <!-- 显示菜单名称 -->
</template>
<!-- 递归渲染子菜单 -->
<sub-menu
v-for="item in menu.list" <!-- 遍历子菜单列表 -->
:key="item.menuId" <!-- 设置唯一标识符 -->
:menu="item" <!-- 传递当前子菜单数据 -->
:dynamicMenuRoutes="dynamicMenuRoutes" <!-- 传递动态路由数据 -->
></sub-menu>
</el-submenu>
<!-- 如果没有子菜单则显示为普通菜单项 -->
<el-menu-item v-else :index="menu.menuId + ''" @click="gotoRouteHandle(menu)">
<span>{{ menu.name }}</span> <!-- 显示菜单名称 -->
</el-menu-item>
</template>
<script>
import SubMenu from "./IndexAsideSub"; //
export default {
name: "sub-menu", //
props: {
menu: { //
type: Object, //
required: true //
},
dynamicMenuRoutes: { //
type: Array, //
required: true //
}
},
components: {
SubMenu //
},
methods: {
//
gotoRouteHandle(menu) {
var route = this.dynamicMenuRoutes.filter( // menuId
item => item.meta.menuId === menu.menuId
);
if (route.length >= 1) { //
if (route[0].component != null) { //
this.$router.replace({ name: route[0].name }); //
} else { //
this.$router.push({ name: "404" }); // 404
}
}
}
}
};
</script>

@ -0,0 +1,171 @@
<template>
<!-- 顶部导航栏组件 -->
<!-- <el-header> //
<el-menu background-color="#00c292" text-color="#FFFFFF" active-text-color="#FFFFFF" mode="horizontal">
<div class="fl title">{{this.$project.projectName}}</div> //
<div class="fr logout" style="display:flex;">
<el-menu-item index="3">
<div>{{this.$storage.get('role')}} {{this.$storage.get('adminName')}}</div> //
</el-menu-item>
<el-menu-item @click="onLogout" index="2">
<div>退出登录</div> // 退
</el-menu-item>
</div>
</el-menu>
</el-header> -->
<!-- 自定义顶部导航栏 -->
<div class="navbar" :style="{backgroundColor:heads.headBgColor,height:heads.headHeight,boxShadow:heads.headBoxShadow,lineHeight:heads.headHeight}">
<!-- 左侧标题菜单 -->
<div class="title-menu" :style="{justifyContent:heads.headTitleStyle=='1'?'flex-start':'center'}">
<!-- 如果启用了头部图片则显示图片 -->
<el-image v-if="heads.headTitleImg" class="title-img" :style="{width:heads.headTitleImgWidth,height:heads.headTitleImgHeight,boxShadow:heads.headTitleImgBoxShadow,borderRadius:heads.headTitleImgBorderRadius}" :src="heads.headTitleImgUrl" fit="cover"></el-image>
<!-- 显示项目名称 -->
<div class="title-name" :style="{color:heads.headFontColor,fontSize:heads.headFontSize}">{{this.$project.projectName}}</div>
</div>
<!-- 右侧菜单 -->
<div class="right-menu">
<!-- 用户信息 -->
<div class="user-info" :style="{color:heads.headUserInfoFontColor,fontSize:heads.headUserInfoFontSize}">{{this.$storage.get('role')}} {{this.$storage.get('adminName')}}</div>
<!-- 退出到前台按钮 -->
<div class="logout" :style="{color:heads.headLogoutFontColor,fontSize:heads.headLogoutFontSize}" @click="onIndexTap">退</div>
<!-- 退出登录按钮 -->
<div class="logout" :style="{color:heads.headLogoutFontColor,fontSize:heads.headLogoutFontSize}" @click="onLogout">退</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
dialogVisible: false, //
ruleForm: {}, //
user: {}, //
heads: { //
"headLogoutFontHoverColor": "rgba(41, 42, 42, 1)", // 退
"headFontSize": "20px", //
"headUserInfoFontColor": "rgba(238, 221, 129, 1)", //
"headBoxShadow": "0 1px 6px #444", //
"headTitleImgHeight": "44px", //
"headLogoutFontHoverBgColor": "rgba(247, 142, 142, 1)", // 退
"headFontColor": "rgba(153, 239, 237, 1)", //
"headTitleImg": false, //
"headHeight": "60px", //
"headTitleImgBorderRadius": "22px", //
"headTitleImgUrl": "http://codegen.caihongy.cn/20201021/cc7d45d9c8164b58b18351764eba9be1.jpg", //
"headBgColor": "#4F4949", //
"headTitleImgBoxShadow": "0 1px 6px #444", //
"headLogoutFontColor": "rgba(153, 239, 237, 1)", // 退
"headUserInfoFontSize": "16px", //
"headTitleImgWidth": "44px", //
"headTitleStyle": "2", // 12
"headLogoutFontSize": "16px" // 退
}
};
},
created() {
this.setHeaderStyle(); //
},
mounted() {
let sessionTable = this.$storage.get("sessionTable"); //
this.$http({
url: sessionTable + '/session', //
method: "get"
}).then(({ data }) => {
if (data && data.code === 0) { //
this.user = data.data; //
} else {
let message = this.$message;
message.error(data.msg); //
}
});
},
methods: {
onLogout() {
let storage = this.$storage;
let router = this.$router;
storage.remove("Token"); // Token
router.replace({ name: "login" }); //
},
onIndexTap() {
window.location.href = `${this.$base.indexUrl}`; //
},
setHeaderStyle() {
this.$nextTick(() => { // DOM
document.querySelectorAll('.navbar .right-menu .logout').forEach(el => { // 退
el.addEventListener("mouseenter", e => { //
e.stopPropagation();
el.style.backgroundColor = this.heads.headLogoutFontHoverBgColor; //
el.style.color = this.heads.headLogoutFontHoverColor; //
});
el.addEventListener("mouseleave", e => { //
e.stopPropagation();
el.style.backgroundColor = "transparent"; //
el.style.color = this.heads.headLogoutFontColor; //
});
});
});
}
}
};
</script>
<style lang="scss" scoped>
.navbar {
height: 60px; //
line-height: 60px; //
width: 100%; //
padding: 0 34px; //
box-sizing: border-box; // 使
background-color: #ff00ff; //
position: relative; //
z-index: 111; //
.right-menu {
position: absolute; //
right: 34px; //
top: 0; //
height: 100%; //
display: flex; // 使
justify-content: flex-end; //
align-items: center; //
z-index: 111; //
.user-info {
font-size: 16px; //
color: red; //
padding: 0 12px; //
}
.logout {
font-size: 16px; //
color: red; //
padding: 0 12px; //
cursor: pointer; //
}
}
.title-menu {
display: flex; // 使
justify-content: flex-start; //
align-items: center; //
width: 100%; //
height: 100%; //
.title-img {
width: 44px; //
height: 44px; //
border-radius: 22px; //
box-shadow: 0 1px 6px #444; //
margin-right: 16px; //
}
.title-name {
font-size: 24px; //
color: #fff; //
font-weight: 700; //
}
}
}
</style>

@ -0,0 +1,99 @@
<template>
<!-- 顶部导航栏 -->
<el-header>
<!-- 水平导航菜单 -->
<el-menu
background-color="#00c292" <!-- 设置背景颜色为绿色 -->
text-color="#FFFFFF" <!-- 设置文字颜色为白色 -->
active-text-color="#FFFFFF" <!-- 设置激活项的文字颜色为白色 -->
mode="horizontal" <!-- 设置菜单模式为水平 -->
>
<!-- 左侧项目名称 -->
<div class="fl title">{{this.$project.projectName}}</div> <!-- 显示项目名称 -->
<!-- 右侧退出登录区域 -->
<div class="fr logout" style="display:flex;">
<!-- 用户信息显示 -->
<el-menu-item index="3">
<div>{{this.$storage.get('role')}} {{this.$storage.get('adminName')}}</div> <!-- 显示用户角色和用户名 -->
</el-menu-item>
<!-- 退出登录按钮 -->
<el-menu-item @click="onLogout" index="2">
<div>退出登录</div> <!-- 点击时触发退出登录方法 -->
</el-menu-item>
</div>
</el-menu>
</el-header>
</template>
<script>
export default {
data() {
return {
dialogVisible: false, //
ruleForm: {}, //
user: {} //
};
},
mounted() {
//
this.$http({
url: `${this.$storage.get("sessionTable")}/session`, // URL
method: "get" // 使GET
}).then(({ data }) => {
if (data && data.code === 0) { //
this.user = data.data; // user
} else {
this.$message.error(data.msg); //
}
});
},
methods: {
onLogout() {
// 退
this.$storage.remove("Token"); // Token
this.$router.replace({ name: "login" }); //
}
}
};
</script>
<style lang="scss" scoped>
/* 样式部分 */
.el-header .fr {
float: right; /* 设置右浮动 */
}
.el-header .fl {
float: left; /* 设置左浮动 */
}
.el-header {
width: 100%; /* 宽度占满父容器 */
color: #333; /* 文字颜色 */
text-align: center; /* 文本居中对齐 */
line-height: 60px; /* 行高 */
padding: 0; /* 去掉内边距 */
z-index: 99; /* 设置层级 */
}
.logo {
width: 60px; /* 设置宽度 */
height: 60px; /* 设置高度 */
margin-left: 70px; /* 左侧外边距 */
}
.avator {
width: 40px; /* 设置宽度 */
height: 40px; /* 设置高度 */
background: #ffffff; /* 背景颜色为白色 */
border-radius: 50%; /* 圆角设置为圆形 */
}
.title {
color: #ffffff; /* 文字颜色为白色 */
font-size: 20px; /* 字体大小 */
font-weight: bold; /* 字体加粗 */
margin-left: 20px; /* 左侧外边距 */
}
</style>

@ -0,0 +1,132 @@
<template>
<!-- 主内容区域 -->
<el-main>
<!-- 面包屑导航组件动态绑定标题 -->
<bread-crumbs :title="title" class="bread-crumbs"></bread-crumbs>
<!-- 路由视图用于显示当前路由对应的组件 -->
<router-view class="router-view"></router-view>
</el-main>
</template>
<script>
import menu from "@/utils/menu"; //
export default {
data() {
return {
menuList: [], //
role: "", //
currentIndex: -2, //
itemMenu: [], //
title: '' //
};
},
mounted() {
let menus = menu.list(); //
this.menuList = menus; //
this.role = this.$storage.get("role"); //
},
methods: {
//
menuHandler(menu) {
this.$router.push({ name: menu.tableName }); //
this.title = menu.menu; //
},
//
titleChange(index, menus) {
this.currentIndex = index; //
this.itemMenu = menus; //
console.log(menus); //
},
//
homeChange(index) {
this.itemMenu = []; //
this.title = ""; //
this.currentIndex = index; //
this.$router.push({ name: 'home' }); //
},
//
centerChange(index) {
this.itemMenu = [ //
{
"buttons": ["新增", "查看", "修改", "删除"], //
"menu": "修改密码", //
"tableName": "updatePassword" //
},
{
"buttons": ["新增", "查看", "修改", "删除"], //
"menu": "个人信息", //
"tableName": "center" //
}
];
this.title = ""; //
this.currentIndex = index; //
this.$router.push({ name: 'home' }); //
}
}
};
</script>
<style lang="scss" scoped>
/* 样式部分 */
a {
text-decoration: none; /* 去掉链接下划线 */
color: #555; /* 设置链接文字颜色 */
}
a:hover {
background: #00c292; /* 鼠标悬停时的背景颜色 */
}
.nav-list {
width: 100%; /* 宽度占满父容器 */
margin: 0 auto; /* 居中对齐 */
text-align: left; /* 文本左对齐 */
margin-top: 20px; /* 设置顶部外边距 */
.nav-title {
display: inline-block; /* 设置为行内块元素 */
font-size: 15px; /* 设置字体大小 */
color: #333; /* 设置文字颜色 */
padding: 15px 25px; /* 设置内边距 */
border: none; /* 去掉边框 */
}
.nav-title.active {
color: #555; /* 设置激活状态的文字颜色 */
cursor: default; /* 设置鼠标样式为默认 */
background-color: #fff; /* 设置激活状态的背景颜色 */
}
}
.nav-item {
margin-top: 20px; /* 设置顶部外边距 */
background: #FFFFFF; /* 设置背景颜色 */
padding: 15px 0; /* 设置上下内边距 */
.menu {
padding: 15px 25px; /* 设置内边距 */
}
}
.el-main {
background-color: #F6F8FA; /* 设置主内容区域的背景颜色 */
padding: 0 24px; /* 设置左右内边距 */
// padding-top: 60px; /* */
}
.router-view {
padding: 10px; /* 设置内边距 */
margin-top: 10px; /* 设置顶部外边距 */
background: #FFFFFF; /* 设置背景颜色 */
box-sizing: border-box; /* 使用标准盒模型 */
}
.bread-crumbs {
width: 100%; /* 宽度占满父容器 */
// border-bottom: 1px solid #e9eef3; /* */
// border-top: 1px solid #e9eef3; /* */
margin-top: 10px; /* 设置顶部外边距 */
box-sizing: border-box; /* 使用标准盒模型 */
}
</style>

@ -0,0 +1,131 @@
// 引入 Vue 核心库
import Vue from 'vue'
// 引入根组件 App.vue
import App from '@/App.vue'
// 引入 Element UI 组件库(完整引入)
import ElementUI from 'element-ui'
// 引入 Element UI 的自定义样式文件SCSS
import '@/assets/css/element-variables.scss'
// 引入项目自定义全局样式文件
import '@/assets/css/style.scss'
// 引入路由配置模块(静态路由)
import router from '@/router/router-static.js'
// 引入面包屑导航组件,并注册为全局组件
import BreadCrumbs from '@/components/common/BreadCrumbs'
// 引入 ECharts 图表库
import echarts from 'echarts'
// 引入 ECharts 主题macarons
import 'echarts/theme/macarons.js'
// 引入封装的 HTTP 请求工具
import http from '@/utils/http.js'
// 引入基础配置文件(如 base URL
import base from '@/utils/base'
// 引入权限验证工具函数 isAuth
import { isAuth } from '@/utils/utils'
// 引入本地存储封装工具storage
import storage from "@/utils/storage"
// 引入通用文件上传组件
import FileUpload from "@/components/common/FileUpload"
// 引入富文本编辑器组件
import Editor from "@/components/common/Editor"
// 引入 API 接口统一管理模块
import api from '@/utils/api'
// 引入数据校验工具类
import * as validate from '@/utils/validate.js'
// 引入高德地图插件支持
import VueAMap from 'vue-amap'
// 引入图标资源
import '@/icons'
// 引入 Excel 导出组件
import JsonExcel from 'vue-json-excel'
// 引入打印功能库
import printJS from 'print-js'
// 引入 MD5 加密库
import md5 from 'js-md5'
// 使用高德地图插件
Vue.use(VueAMap)
// 初始化高德地图 API 加载器,配置 key 和所需插件
VueAMap.initAMapApiLoader({
key: 'ca04cee7ac952691aa67a131e6f0cee0',
plugin: [
'AMap.Autocomplete', 'AMap.PlaceSearch', 'AMap.Scale', 'AMap.OverView',
'AMap.ToolBar', 'AMap.MapType', 'AMap.PolyEditor', 'AMap.CircleEditor', 'AMap.Geocoder'
],
v: '1.4.4' // 高德 SDK 版本号
})
// 将 validate 工具挂载到 Vue 原型链上,方便全局调用
Vue.prototype.$validate = validate
// 将 http 挂载到 Vue 原型链上,用于全局发起请求
Vue.prototype.$http = http
// 将 echarts 挂载到 Vue 原型链上,用于全局使用图表
Vue.prototype.$echarts = echarts
// 获取基础配置对象并挂载到原型链
Vue.prototype.$base = base.get()
// 获取项目名称并挂载到原型链
Vue.prototype.$project = base.getProjectName()
// 将本地存储工具挂载到原型链
Vue.prototype.$storage = storage
// 将 API 接口模块挂载到原型链
Vue.prototype.$api = api
// 将权限判断方法挂载到原型链
Vue.prototype.isAuth = isAuth
// 使用 Element UI 插件,设置默认尺寸和 z-index
Vue.use(ElementUI, { size: 'medium', zIndex: 3000 })
// 关闭 Vue 启动时的生产提示
Vue.config.productionTip = false
// 注册全局组件:面包屑导航
Vue.component('bread-crumbs', BreadCrumbs)
// 注册全局组件:文件上传组件
Vue.component('file-upload', FileUpload)
// 注册全局组件:富文本编辑器
Vue.component('editor', Editor)
// 注册 Excel 导出组件
Vue.component('downloadExcel', JsonExcel)
// 将 MD5 方法挂载到 Vue 原型链上,用于加密处理
Vue.prototype.$md5 = md5
// 创建 Vue 实例,启动应用
new Vue({
// 渲染根组件 App
render: h => h(App),
// 使用路由配置
router
}).$mount('#app')

@ -0,0 +1,356 @@
<template>
<!-- 主容器块用于样式隔离与布局 -->
<div class="addEdit-block">
<!-- 表单组件绑定ruleForm数据模型使用ref方便在JS中引用 -->
<el-form
class="detail-form-content"
ref="ruleForm" <!-- 表单引用 -->
:model="ruleForm" <!-- 数据模型 -->
:rules="rules" <!-- 校验规则 -->
label-width="80px" <!-- 标签宽度 -->
:style="{backgroundColor:addEditForm.addEditBoxColor}" <!-- 动态背景色 -->
>
<!-- 布局行用于排列表单项 -->
<el-row>
<!-- 左半列跨度12占50% -->
<el-col :span="12">
<!-- 非查看模式时显示可编辑名称输入框 -->
<el-form-item class="input" v-if="type!='info'" label="名称" prop="name">
<!-- 输入框双向绑定ruleForm.name -->
<el-input v-model="ruleForm.name"
placeholder="名称" clearable :readonly="ro.name"></el-input> <!-- -->
</el-form-item>
<!-- 查看模式下显示只读名称输入框 -->
<div v-else>
<el-form-item class="input" label="名称" prop="name">
<!-- 强制只读状态 -->
<el-input v-model="ruleForm.name"
placeholder="名称" readonly></el-input> <!-- -->
</el-form-item>
</div>
</el-col>
<!-- 全宽列跨度24占100% -->
<el-col :span="24">
<!-- 非查看模式且value未锁定时显示上传组件 -->
<el-form-item class="upload" v-if="type!='info' && !ro.value" label="值" prop="value">
<!-- 文件上传组件 -->
<file-upload
tip="点击上传值" <!-- 提示文字 -->
action="file/upload" <!-- 上传接口地址 -->
:limit="3" <!-- 最多上传3个文件 -->
:multiple="true" <!-- 支持多选 -->
:fileUrls="ruleForm.value?ruleForm.value:''" <!-- 初始文件路径 -->
@change="valueUploadChange" <!-- 上传完成后的回调 -->
></file-upload>
</el-form-item>
<!-- 查看模式下展示图片预览 -->
<div v-else>
<el-form-item v-if="ruleForm.value" label="值" prop="value">
<!-- 循环展示多个图片 -->
<img style="margin-right:20px;" v-bind:key="index" v-for="(item,index) in ruleForm.value.split(',')" :src="item" width="100" height="100"> <!-- -->
</el-form-item>
</div>
</el-col>
</el-row>
<!-- 提交/取消按钮组 -->
<el-form-item class="btn">
<!-- 非查看模式显示提交按钮 -->
<el-button v-if="type!='info'" type="primary" class="btn-success" @click="onSubmit"></el-button> <!-- 提交操作 -->
<!-- 非查看模式显示取消按钮 -->
<el-button v-if="type!='info'" class="btn-close" @click="back()"></el-button> <!-- 取消操作 -->
<!-- 查看模式显示返回按钮 -->
<el-button v-if="type=='info'" class="btn-close" @click="back()"></el-button> <!-- 返回操作 -->
</el-form-item>
</el-form>
</div>
</template>
<script>
//
import { isNumber,isIntNumer,isEmail,isPhone, isMobile,isURL,checkIdCard } from "@/utils/validate";
export default {
data() {
let self = this;
//
var validateIdCard = (rule, value, callback) => {
if(!value){ //
callback(); //
} else if (!checkIdCard(value)) { //
callback(new Error("请输入正确的身份证号码")); //
} else {
callback(); //
}
};
// URL
var validateUrl = (rule, value, callback) => {
if(!value){ //
callback(); //
} else if (!isURL(value)) { // URL
callback(new Error("请输入正确的URL地址")); //
} else {
callback(); //
}
};
//
var validateMobile = (rule, value, callback) => {
if(!value){ //
callback(); //
} else if (!isMobile(value)) { //
callback(new Error("请输入正确的手机号码")); //
} else {
callback(); //
}
};
//
var validatePhone = (rule, value, callback) => {
if(!value){ //
callback(); //
} else if (!isPhone(value)) { //
callback(new Error("请输入正确的电话号码")); //
} else {
callback(); //
}
};
//
var validateEmail = (rule, value, callback) => {
if(!value){ //
callback(); //
} else if (!isEmail(value)) { //
callback(new Error("请输入正确的邮箱地址")); //
} else {
callback(); //
}
};
//
var validateNumber = (rule, value, callback) => {
if(!value){ //
callback(); //
} else if (!isNumber(value)) { //
callback(new Error("请输入数字")); //
} else {
callback(); //
}
};
//
var validateIntNumber = (rule, value, callback) => {
if(!value){ //
callback(); //
} else if (!isIntNumer(value)) { //
callback(new Error("请输入整数")); //
} else {
callback(); //
}
};
return {
//
addEditForm: {"btnSaveFontColor":"#fff", ...}, //
id: '', // ID
type: '', // add/edit/view
ro:{ //
name : false, //
value : false, //
},
ruleForm: { //
name: '', //
value: '', //
},
rules: { //
name: [
{ required: true, message: '名称不能为空', trigger: 'blur' }, //
],
value: [] //
}
};
},
props: ["parent"], //
computed: {}, //
created() { //
this.addEditStyleChange(); //
this.addEditUploadStyleChange(); //
},
methods: {
//
download(file){
window.open(`${file}`) //
},
// idtype
init(id,type) {
if (id) {
this.id = id; // ID
this.type = type; //
}
//
if(this.type == 'info' || this.type == 'else'){
this.info(id); //
} else if (this.type == 'cross') { //
var obj = this.$storage.getObj('crossObj'); //
for (var o in obj){
if(o == 'name'){ //
this.ruleForm.name = obj[o];
this.ro.name = true;
continue;
}
if(o == 'value'){ //
this.ruleForm.value = obj[o];
this.ro.value = true;
continue;
}
}
}
},
// ID
info(id) {
this.$http({ // HTTP
url: `config/info/${id}`, // URL
method: "get" //
}).then(({ data }) => { //
if (data && data.code === 0) {
this.ruleForm = data.data; //
} else {
this.$message.error(data.msg); //
}
});
},
//
onSubmit() {
this.$refs["ruleForm"].validate(valid => { //
if (valid) {
this.$http({ //
url: `config/${!this.ruleForm.id ? "save" : "update"}`, // URL
method: "post", //
data: this.ruleForm //
}).then(({ data }) => {
if (data && data.code === 0) { //
this.$message({
message: "操作成功",
type: "success",
duration: 1500,
onClose: () => {
this.parent.showFlag = true;
this.parent.addOrUpdateFlag = false;
this.parent.configCrossAddOrUpdateFlag = false;
this.parent.search(); //
this.parent.contentStyleChange();
}
});
} else {
this.$message.error(data.msg); //
}
});
}
});
},
// UUID
getUUID () {
return new Date().getTime(); // UUID
},
//
back() {
//
this.parent.showFlag = true;
this.parent.addOrUpdateFlag = false;
this.parent.configCrossAddOrUpdateFlag = false;
this.parent.contentStyleChange();
},
//
valueUploadChange(fileUrls) {
this.ruleForm.value = fileUrls; //
this.addEditUploadStyleChange() //
},
//
addEditStyleChange() {
this.$nextTick(() => {
// input
document.querySelectorAll('.addEdit-block .input .el-input__inner').forEach(el => {
el.style.height = this.addEditForm.inputHeight
el.style.color = this.addEditForm.inputFontColor
el.style.fontSize = this.addEditForm.inputFontSize
el.style.borderWidth = this.addEditForm.inputBorderWidth
el.style.borderStyle = this.addEditForm.inputBorderStyle
el.style.borderColor = this.addEditForm.inputBorderColor
el.style.borderRadius = this.addEditForm.inputBorderRadius
el.style.backgroundColor = this.addEditForm.inputBgColor
})
// label
document.querySelectorAll('.addEdit-block .input .el-form-item__label').forEach(el => {
el.style.lineHeight = this.addEditForm.inputHeight
el.style.color = this.addEditForm.inputLableColor
el.style.fontSize = this.addEditForm.inputLableFontSize
})
// select/date/upload/textarea...
})
},
//
addEditUploadStyleChange() {
this.$nextTick(() => {
document.querySelectorAll('.addEdit-block .upload .el-upload-list--picture-card .el-upload-list__item').forEach(el => {
el.style.width = this.addEditForm.uploadHeight
el.style.height = this.addEditForm.uploadHeight
el.style.borderWidth = this.addEditForm.uploadBorderWidth
el.style.borderStyle = this.addEditForm.uploadBorderStyle
el.style.borderColor = this.addEditForm.uploadBorderColor
el.style.borderRadius = this.addEditForm.uploadBorderRadius
el.style.backgroundColor = this.addEditForm.uploadBgColor
})
})
},
}
};
</script>
<style lang="scss">
.editor{
height: 500px; //
& /deep/ .ql-container {
height: 310px; // Quill
}
}
.amap-wrapper {
width: 100%; //
height: 500px; //
}
.search-box {
position: absolute; //
}
.addEdit-block {
margin: -10px; //
}
.detail-form-content {
padding: 12px; //
}
.btn .el-button {
padding: 0; // 0
}
</style>

@ -0,0 +1,519 @@
<template>
<!-- 主容器块 -->
<div class="main-content">
<!-- 列表页显示条件 -->
<div v-if="showFlag">
<!-- 表单组件用于搜索 -->
<el-form :inline="true" :model="searchForm" class="form-content">
<!-- 搜索框布局 -->
<el-row :gutter="20" class="slt" :style="{justifyContent:contents.searchBoxPosition=='1'?'flex-start':contents.searchBoxPosition=='2'?'center':'flex-end'}">
<!-- 名称输入框 -->
<el-form-item :label="contents.inputTitle == 1 ? '名称' : ''">
<!-- 带前置图标的输入框 -->
<el-input v-if="contents.inputIcon == 1 && contents.inputIconPosition == 1" prefix-icon="el-icon-search" v-model="searchForm.name" placeholder="名称" clearable></el-input>
<!-- 带后置图标的输入框 -->
<el-input v-if="contents.inputIcon == 1 && contents.inputIconPosition == 2" suffix-icon="el-icon-search" v-model="searchForm.name" placeholder="名称" clearable></el-input>
<!-- 无图标输入框 -->
<el-input v-if="contents.inputIcon == 0" v-model="searchForm.name" placeholder="名称" clearable></el-input>
</el-form-item>
<!-- 查询按钮 -->
<el-form-item>
<!-- 带前置图标的查询按钮 -->
<el-button v-if="contents.searchBtnIcon == 1 && contents.searchBtnIconPosition == 1" icon="el-icon-search" type="success" @click="search()">{{ contents.searchBtnFont == 1?'':'' }}</el-button>
<!-- 带后置图标的查询按钮 -->
<el-button v-if="contents.searchBtnIcon == 1 && contents.searchBtnIconPosition == 2" type="success" @click="search()">{{ contents.searchBtnFont == 1?'':'' }}<i class="el-icon-search el-icon--right"/></el-button>
<!-- 无图标查询按钮 -->
<el-button v-if="contents.searchBtnIcon == 0" type="success" @click="search()">{{ contents.searchBtnFont == 1?'':'' }}</el-button>
</el-form-item>
</el-row>
<!-- 按钮组布局 -->
<el-row class="ad" :style="{justifyContent:contents.btnAdAllBoxPosition=='1'?'flex-start':contents.btnAdAllBoxPosition=='2'?'center':'flex-end'}">
<el-form-item>
<!-- 新增按钮带前置图标 -->
<el-button
v-if="isAuth('config','新增') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 1"
type="success"
icon="el-icon-plus"
@click="addOrUpdateHandler()"
>{{ contents.btnAdAllFont == 1?'新增':'' }}</el-button>
<!-- 新增按钮带后置图标 -->
<el-button
v-if="isAuth('config','新增') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 2"
type="success"
@click="addOrUpdateHandler()"
>{{ contents.btnAdAllFont == 1?'新增':'' }}<i class="el-icon-plus el-icon--right" /></el-button>
<!-- 新增按钮无图标 -->
<el-button
v-if="isAuth('config','新增') && contents.btnAdAllIcon == 0"
type="success"
@click="addOrUpdateHandler()"
>{{ contents.btnAdAllFont == 1?'新增':'' }}</el-button>
<!-- 删除按钮带前置图标 -->
<el-button
v-if="isAuth('config','删除') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 1 && contents.tableSelection"
:disabled="dataListSelections.length <= 0"
type="danger"
icon="el-icon-delete"
@click="deleteHandler()"
>{{ contents.btnAdAllFont == 1?'删除':'' }}</el-button>
<!-- 删除按钮带后置图标 -->
<el-button
v-if="isAuth('config','删除') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 2 && contents.tableSelection"
:disabled="dataListSelections.length <= 0"
type="danger"
@click="deleteHandler()"
>{{ contents.btnAdAllFont == 1?'删除':'' }}<i class="el-icon-delete el-icon--right" /></el-button>
<!-- 删除按钮无图标 -->
<el-button
v-if="isAuth('config','删除') && contents.btnAdAllIcon == 0 && contents.tableSelection"
:disabled="dataListSelections.length <= 0"
type="danger"
@click="deleteHandler()"
>{{ contents.btnAdAllFont == 1?'删除':'' }}</el-button>
</el-form-item>
</el-row>
</el-form>
<!-- 数据表格 -->
<div class="table-content">
<el-table class="tables" :size="contents.tableSize" :show-header="contents.tableShowHeader"
:header-row-style="headerRowStyle" :header-cell-style="headerCellStyle"
:border="contents.tableBorder"
:fit="contents.tableFit"
:stripe="contents.tableStripe"
:row-style="rowStyle"
:cell-style="cellStyle"
:style="{width: '100%',fontSize:contents.tableContentFontSize,color:contents.tableContentFontColor}"
v-if="isAuth('config','查看')"
:data="dataList"
v-loading="dataListLoading"
@selection-change="selectionChangeHandler">
<!-- 多选列 -->
<el-table-column v-if="contents.tableSelection"
type="selection"
header-align="center"
align="center"
width="50">
</el-table-column>
<!-- 索引列 -->
<el-table-column label="索引" v-if="contents.tableIndex" type="index" width="50" />
<!-- 名称列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="name"
header-align="center"
label="名称">
<template slot-scope="scope">
{{scope.row.name}} <!-- 显示名称字段 -->
</template>
</el-table-column>
<!-- 值列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign" prop="value"
header-align="center"
width="200"
label="值">
<template slot-scope="scope">
<div v-if="scope.row.value"> <!-- -->
<img :src="scope.row.value.split(',')[0]" width="100" height="100">
</div>
<div v-else></div> <!-- -->
</template>
</el-table-column>
<!-- 操作列 -->
<el-table-column width="300" :align="contents.tableAlign"
header-align="center"
label="操作">
<template slot-scope="scope">
<!-- 查看详情按钮带前置图标 -->
<el-button v-if="isAuth('config','查看') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 1" type="success" icon="el-icon-tickets" size="mini" @click="addOrUpdateHandler(scope.row.id,'info')">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<!-- 查看详情按钮带后置图标 -->
<el-button v-if="isAuth('config','查看') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 2" type="success" size="mini" @click="addOrUpdateHandler(scope.row.id,'info')">{{ contents.tableBtnFont == 1?'':'' }}<i class="el-icon-tickets el-icon--right" /></el-button>
<!-- 查看详情按钮无图标 -->
<el-button v-if="isAuth('config','查看') && contents.tableBtnIcon == 0" type="success" size="mini" @click="addOrUpdateHandler(scope.row.id,'info')">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<!-- 修改按钮带前置图标 -->
<el-button v-if="isAuth('config','修改') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 1" type="primary" icon="el-icon-edit" size="mini" @click="addOrUpdateHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<!-- 修改按钮带后置图标 -->
<el-button v-if="isAuth('config','修改') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 2" type="primary" size="mini" @click="addOrUpdateHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}<i class="el-icon-edit el-icon--right" /></el-button>
<!-- 修改按钮无图标 -->
<el-button v-if="isAuth('config','修改') && contents.tableBtnIcon == 0" type="primary" size="mini" @click="addOrUpdateHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<!-- 删除按钮带前置图标 -->
<el-button v-if="isAuth('config','删除') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 1" type="danger" icon="el-icon-delete" size="mini" @click="deleteHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<!-- 删除按钮带后置图标 -->
<el-button v-if="isAuth('config','删除') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 2" type="danger" size="mini" @click="deleteHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}<i class="el-icon-delete el-icon--right" /></el-button>
<!-- 删除按钮无图标 -->
<el-button v-if="isAuth('config','删除') && contents.tableBtnIcon == 0" type="danger" size="mini" @click="deleteHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<el-pagination
clsss="pages"
:layout="layouts"
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
:current-page="pageIndex"
:page-sizes="[10, 20, 50, 100]"
:page-size="Number(contents.pageEachNum)"
:total="totalPage"
:small="contents.pageStyle"
class="pagination-content"
:background="contents.pageBtnBG"
:style="{textAlign:contents.pagePosition==1?'left':contents.pagePosition==2?'center':'right'}"
></el-pagination>
</div>
</div>
<!-- 添加/修改页面 -->
<add-or-update v-if="addOrUpdateFlag" :parent="this" ref="addOrUpdate"></add-or-update>
</div>
</template>
<script>
// /
import AddOrUpdate from "./add-or-update";
export default {
data() {
return {
//
searchForm: {
key: ""
},
dataList: [], //
pageIndex: 1, //
pageSize: 10, //
totalPage: 0, //
dataListLoading: false, //
dataListSelections: [], //
showFlag: true, //
sfshVisiable: false, //
shForm: {}, //
chartVisiable: false, //
addOrUpdateFlag: false, // /
contents: { /* 样式配置对象 */ }, //
layouts: '', //
};
},
created() {
this.init(); //
this.getDataList(); //
this.contentStyleChange(); //
},
mounted() {
//
},
filters: {
htmlfilter: function (val) {
return val.replace(/<[^>]*>/g).replace(/undefined/g,''); // HTMLundefined
}
},
components: {
AddOrUpdate, //
},
methods: {
contentStyleChange() {
this.contentSearchStyleChange(); //
this.contentBtnAdAllStyleChange(); //
this.contentSearchBtnStyleChange(); //
this.contentTableBtnStyleChange(); //
this.contentPageStyleChange(); //
},
contentSearchStyleChange() {
this.$nextTick(() => {
//
document.querySelectorAll('.form-content .slt .el-input__inner').forEach(el => {
let textAlign = 'left';
if (this.contents.inputFontPosition == 2) textAlign = 'center';
if (this.contents.inputFontPosition == 3) textAlign = 'right';
el.style.textAlign = textAlign;
el.style.height = this.contents.inputHeight;
el.style.lineHeight = this.contents.inputHeight;
el.style.color = this.contents.inputFontColor;
el.style.fontSize = this.contents.inputFontSize;
el.style.borderWidth = this.contents.inputBorderWidth;
el.style.borderStyle = this.contents.inputBorderStyle;
el.style.borderColor = this.contents.inputBorderColor;
el.style.borderRadius = this.contents.inputBorderRadius;
el.style.backgroundColor = this.contents.inputBgColor;
});
if (this.contents.inputTitle) {
//
document.querySelectorAll('.form-content .slt .el-form-item__label').forEach(el => {
el.style.color = this.contents.inputTitleColor;
el.style.fontSize = this.contents.inputTitleSize;
el.style.lineHeight = this.contents.inputHeight;
});
}
setTimeout(() => {
//
document.querySelectorAll('.form-content .slt .el-input__prefix').forEach(el => {
el.style.color = this.contents.inputIconColor;
el.style.lineHeight = this.contents.inputHeight;
});
document.querySelectorAll('.form-content .slt .el-input__suffix').forEach(el => {
el.style.color = this.contents.inputIconColor;
el.style.lineHeight = this.contents.inputHeight;
});
document.querySelectorAll('.form-content .slt .el-input__icon').forEach(el => {
el.style.lineHeight = this.contents.inputHeight;
});
}, 10);
});
},
//
contentSearchBtnStyleChange() {
this.$nextTick(() => {
document.querySelectorAll('.form-content .slt .el-button--success').forEach(el => {
el.style.height = this.contents.searchBtnHeight;
el.style.color = this.contents.searchBtnFontColor;
el.style.fontSize = this.contents.searchBtnFontSize;
el.style.borderWidth = this.contents.searchBtnBorderWidth;
el.style.borderStyle = this.contents.searchBtnBorderStyle;
el.style.borderColor = this.contents.searchBtnBorderColor;
el.style.borderRadius = this.contents.searchBtnBorderRadius;
el.style.backgroundColor = this.contents.searchBtnBgColor;
});
});
},
//
contentBtnAdAllStyleChange() {
this.$nextTick(() => {
//
document.querySelectorAll('.form-content .ad .el-button--success').forEach(el => {
el.style.height = this.contents.btnAdAllHeight;
el.style.color = this.contents.btnAdAllAddFontColor;
el.style.fontSize = this.contents.btnAdAllFontSize;
el.style.borderWidth = this.contents.btnAdAllBorderWidth;
el.style.borderStyle = this.contents.btnAdAllBorderStyle;
el.style.borderColor = this.contents.btnAdAllBorderColor;
el.style.borderRadius = this.contents.btnAdAllBorderRadius;
el.style.backgroundColor = this.contents.btnAdAllAddBgColor;
});
//
document.querySelectorAll('.form-content .ad .el-button--danger').forEach(el => {
el.style.height = this.contents.btnAdAllHeight;
el.style.color = this.contents.btnAdAllDelFontColor;
el.style.fontSize = this.contents.btnAdAllFontSize;
el.style.borderWidth = this.contents.btnAdAllBorderWidth;
el.style.borderStyle = this.contents.btnAdAllBorderStyle;
el.style.borderColor = this.contents.btnAdAllBorderColor;
el.style.borderRadius = this.contents.btnAdAllBorderRadius;
el.style.backgroundColor = this.contents.btnAdAllDelBgColor;
});
//
document.querySelectorAll('.form-content .ad .el-button--warning').forEach(el => {
el.style.height = this.contents.btnAdAllHeight;
el.style.color = this.contents.btnAdAllWarnFontColor;
el.style.fontSize = this.contents.btnAdAllFontSize;
el.style.borderWidth = this.contents.btnAdAllBorderWidth;
el.style.borderStyle = this.contents.btnAdAllBorderStyle;
el.style.borderColor = this.contents.btnAdAllBorderColor;
el.style.borderRadius = this.contents.btnAdAllBorderRadius;
el.style.backgroundColor = this.contents.btnAdAllWarnBgColor;
});
});
},
//
rowStyle({ row, rowIndex }) {
if (rowIndex % 2 == 1) {
if (this.contents.tableStripe) {
return { color: this.contents.tableStripeFontColor }; //
}
} else {
return '';
}
},
//
cellStyle({ row, rowIndex }) {
if (rowIndex % 2 == 1) {
if (this.contents.tableStripe) {
return { backgroundColor: this.contents.tableStripeBgColor }; //
}
} else {
return '';
}
},
//
headerRowStyle({ row, rowIndex }) {
return { color: this.contents.tableHeaderFontColor }; //
},
//
headerCellStyle({ row, rowIndex }) {
return { backgroundColor: this.contents.tableHeaderBgColor }; //
},
//
contentTableBtnStyleChange() {
//
},
//
contentPageStyleChange() {
let arr = [];
if (this.contents.pageTotal) arr.push('total'); //
if (this.contents.pageSizes) arr.push('sizes'); //
if (this.contents.pagePrevNext) {
arr.push('prev'); //
if (this.contents.pagePager) arr.push('pager'); //
arr.push('next'); //
}
if (this.contents.pageJumper) arr.push('jumper'); //
this.layouts = arr.join(); //
this.contents.pageEachNum = 10; //
},
init() {
//
},
search() {
this.pageIndex = 1; //
this.getDataList(); //
},
//
getDataList() {
this.dataListLoading = true; //
let params = {
page: this.pageIndex,
limit: this.pageSize,
sort: 'id',
};
if (this.searchForm.name != '' && this.searchForm.name != undefined) {
params['name'] = '%' + this.searchForm.name + '%'; //
}
this.$http({
url: "config/page",
method: "get",
params: params
}).then(({ data }) => {
if (data && data.code === 0) {
this.dataList = data.data.list; //
this.totalPage = data.data.total; //
} else {
this.dataList = [];
this.totalPage = 0;
}
this.dataListLoading = false; //
});
},
//
sizeChangeHandle(val) {
this.pageSize = val; //
this.pageIndex = 1; //
this.getDataList(); //
},
//
currentChangeHandle(val) {
this.pageIndex = val; //
this.getDataList(); //
},
//
selectionChangeHandler(val) {
this.dataListSelections = val; //
},
// /
addOrUpdateHandler(id, type) {
this.showFlag = false; //
this.addOrUpdateFlag = true; // /
this.crossAddOrUpdateFlag = false; // /
if (type != 'info') {
type = 'else'; //
}
this.$nextTick(() => {
this.$refs.addOrUpdate.init(id, type); //
});
},
//
download(file) {
window.open(`${file}`); //
},
//
deleteHandler(id) {
var ids = id
? [Number(id)] //
: this.dataListSelections.map(item => {
return Number(item.id); //
});
this.$confirm(`确定进行[${id ? "删除" : "批量删除"}]操作?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$http({
url: "config/delete",
method: "post",
data: ids
}).then(({ data }) => {
if (data && data.code === 0) {
this.$message({
message: "操作成功",
type: "success",
duration: 1500,
onClose: () => {
this.search(); //
}
});
} else {
this.$message.error(data.msg); //
}
});
});
},
}
};
</script>
<style lang="scss" scoped>
.slt {
margin: 0 !important; /* 移除外边距 */
display: flex; /* 弹性布局 */
}
.ad {
margin: 0 !important; /* 移除外边距 */
display: flex; /* 弹性布局 */
}
.pages {
& /deep/ el-pagination__sizes {
& /deep/ el-input__inner {
height: 22px; /* 高度 */
line-height: 22px; /* 行高 */
}
}
}
.el-button+.el-button {
margin: 0; /* 移除按钮间距 */
}
.tables {
& /deep/ .el-button--success {
height: 40px; /* 高度 */
color: #333; /* 字体颜色 */
font-size: 14px; /* 字体大小 */
border-width: 1px; /* 边框宽度 */
border-style: solid; /* 边框样式 */
border-color: rgba(196, 210, 244, 1); /* 边框颜色 */
border-radius: 22px; /* 圆角 */
background-color: rgba(171, 239, 239, 1); /* 背景颜色 */
}
& /deep/ .el-button--primary {
height: 40px; /* 高度 */
color: #333; /* 字体颜色 */
font-size: 14px; /* 字体大小 */
border-width: 1px; /* 边框宽度 */
border-style: solid; /* 边框样式 */
border-color: rgba(196, 210, 244, 1); /* 边框颜色 */
border-radius: 22px; /* 圆角 */
background-color: rgba(240, 242, 124, 1); /* 背景颜色 */
}
& /deep/ .el-button--danger {
height: 40px; /* 高度 */
color: #333; /* 字体颜色 */
font-size: 14px; /* 字体大小 */
border-width: 1px; /* 边框宽度 */
border-style: solid; /* 边框样式 */
border-color: rgba(196, 210, 244, 1); /* 边框颜色 */
border-radius: 22px; /* 圆角 */
background-color: rgba(244, 150, 150, 1); /* 背景颜色 */
}
& /deep/ .el-button {
margin: 4px; /* 按钮间距 */
}
}
</style>

@ -0,0 +1,445 @@
<template>
<!-- 主容器块 -->
<div class="addEdit-block">
<!-- 表单组件用于添加或修改 -->
<el-form
class="detail-form-content"
ref="ruleForm"
:model="ruleForm" <!-- 绑定表单数据模型 -->
:rules="rules" <!-- 表单验证规则 -->
label-width="80px" <!-- 标签宽度 -->
:style="{backgroundColor:addEditForm.addEditBoxColor}" <!-- 动态背景颜色 -->
>
<el-row>
<!-- 空行占位 -->
</el-row>
<!-- 评论内容区域 -->
<el-row>
<el-col :span="24">
<!-- 评论内容输入框编辑模式 -->
<el-form-item class="textarea" v-if="type!='info'" label="评论内容" prop="content">
<el-input
style="min-width: 200px; max-width: 600px;" <!-- 输入框宽度限制 -->
type="textarea" <!-- 文本域类型 -->
:rows="8" <!-- 行数 -->
placeholder="评论内容" <!-- 占位符 -->
v-model="ruleForm.content" readonly> <!-- 只读绑定 -->
</el-input>
</el-form-item>
<!-- 评论内容显示查看模式 -->
<div v-else>
<el-form-item v-if="ruleForm.content" label="评论内容" prop="content">
<span>{{ruleForm.content}}</span> <!-- 显示评论内容 -->
</el-form-item>
</div>
</el-col>
</el-row>
<!-- 回复内容区域 -->
<el-row>
<el-col :span="24">
<!-- 回复内容输入框编辑模式 -->
<el-form-item class="textarea" v-if="type!='info'" label="回复内容" prop="reply">
<el-input
style="min-width: 200px; max-width: 600px;" <!-- 输入框宽度限制 -->
type="textarea" <!-- 文本域类型 -->
:rows="8" <!-- 行数 -->
placeholder="回复内容" <!-- 占位符 -->
v-model="ruleForm.reply"> <!-- 绑定回复内容 -->
</el-input>
</el-form-item>
<!-- 回复内容显示查看模式 -->
<div v-else>
<el-form-item v-if="ruleForm.reply" label="回复内容" prop="reply">
<span>{{ruleForm.reply}}</span> <!-- 显示回复内容 -->
</el-form-item>
</div>
</el-col>
</el-row>
<!-- 操作按钮区域 -->
<el-form-item class="btn">
<!-- 提交按钮编辑模式 -->
<el-button v-if="type!='info'" type="primary" class="btn-success" @click="onSubmit"></el-button>
<!-- 取消按钮编辑模式 -->
<el-button v-if="type!='info'" class="btn-close" @click="back()"></el-button>
<!-- 返回按钮查看模式 -->
<el-button v-if="type=='info'" class="btn-close" @click="back()"></el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
//
import { isNumber,isIntNumer,isEmail,isPhone, isMobile,isURL,checkIdCard } from "@/utils/validate";
export default {
data() {
let self = this;
//
var validateIdCard = (rule, value, callback) => {
if(!value){
callback();
} else if (!checkIdCard(value)) {
callback(new Error("请输入正确的身份证号码"));
} else {
callback();
}
};
// URL
var validateUrl = (rule, value, callback) => {
if(!value){
callback();
} else if (!isURL(value)) {
callback(new Error("请输入正确的URL地址"));
} else {
callback();
}
};
//
var validateMobile = (rule, value, callback) => {
if(!value){
callback();
} else if (!isMobile(value)) {
callback(new Error("请输入正确的手机号码"));
} else {
callback();
}
};
//
var validatePhone = (rule, value, callback) => {
if(!value){
callback();
} else if (!isPhone(value)) {
callback(new Error("请输入正确的电话号码"));
} else {
callback();
}
};
//
var validateEmail = (rule, value, callback) => {
if(!value){
callback();
} else if (!isEmail(value)) {
callback(new Error("请输入正确的邮箱地址"));
} else {
callback();
}
};
//
var validateNumber = (rule, value, callback) => {
if(!value){
callback();
} else if (!isNumber(value)) {
callback(new Error("请输入数字"));
} else {
callback();
}
};
//
var validateIntNumber = (rule, value, callback) => {
if(!value){
callback();
} else if (!isIntNumer(value)) {
callback(new Error("请输入整数"));
} else {
callback();
}
};
return {
addEditForm: {"btnSaveFontColor":"#fff","selectFontSize":"14px","btnCancelBorderColor":"rgba(152, 129, 129, 1)","inputBorderRadius":"22px","inputFontSize":"14px","textareaBgColor":"#fff","btnSaveFontSize":"14px","textareaBorderRadius":"22px","uploadBgColor":"#fff","textareaBorderStyle":"solid","btnCancelWidth":"88px","textareaHeight":"120px","dateBgColor":"#fff","btnSaveBorderRadius":"22px","uploadLableFontSize":"14px","textareaBorderWidth":"1px","inputLableColor":"#606266","addEditBoxColor":"rgba(210, 194, 194, 0.29)","dateIconFontSize":"14px","btnSaveBgColor":"#409EFF","uploadIconFontColor":"#8c939d","textareaBorderColor":"rgba(152, 129, 129, 1)","btnCancelBgColor":"rgba(143, 222, 143, 1)","selectLableColor":"#606266","btnSaveBorderStyle":"solid","dateBorderWidth":"1px","dateLableFontSize":"14px","dateBorderRadius":"22px","btnCancelBorderStyle":"solid","selectLableFontSize":"14px","selectBorderStyle":"solid","selectIconFontColor":"#C0C4CC","btnCancelHeight":"44px","inputHeight":"40px","btnCancelFontColor":"#606266","dateBorderColor":"rgba(152, 129, 129, 1)","dateIconFontColor":"#C0C4CC","uploadBorderStyle":"solid","dateBorderStyle":"solid","dateLableColor":"#606266","dateFontSize":"14px","inputBorderWidth":"1px","uploadIconFontSize":"28px","selectHeight":"40px","inputFontColor":"#606266","uploadHeight":"148px","textareaLableColor":"#606266","textareaLableFontSize":"14px","btnCancelFontSize":"14px","inputBorderStyle":"solid","btnCancelBorderRadius":"22px","inputBgColor":"rgba(252, 250, 250, 1)","inputLableFontSize":"14px","uploadLableColor":"#606266","uploadBorderRadius":"22px","btnSaveHeight":"44px","selectBgColor":"#fff","btnSaveWidth":"88px","selectIconFontSize":"14px","dateHeight":"40px","selectBorderColor":"rgba(152, 129, 129, 1)","inputBorderColor":"rgba(152, 129, 129, 1)","uploadBorderColor":"rgba(152, 129, 129, 1)","textareaFontColor":"#606266","selectBorderWidth":"1px","dateFontColor":"#606266","btnCancelBorderWidth":"1px","uploadBorderWidth":"1px","textareaFontSize":"14px","selectBorderRadius":"22px","selectFontColor":"#606266","btnSaveBorderColor":"#409EFF","btnSaveBorderWidth":"1px"}, //
id: '', // ID
type: '', //
ro:{
refid : false, // ID
userid : false, // ID
content : false, //
reply : false, //
},
ruleForm: {
refid: '', // ID
userid: '', // ID
content: '', //
reply: '', //
},
rules: {
refid: [
{ required: true, message: '关联表id不能为空', trigger: 'blur' }, // ID
],
userid: [
{ required: true, message: '用户id不能为空', trigger: 'blur' }, // ID
],
content: [
{ required: true, message: '评论内容不能为空', trigger: 'blur' }, //
],
reply: [
], //
}
};
},
props: ["parent"], //
computed: {}, //
created() {
this.addEditStyleChange(); //
this.addEditUploadStyleChange(); //
},
methods: {
//
download(file){
window.open(`${file}`); //
},
//
init(id,type) {
if (id) {
this.id = id; // ID
this.type = type; //
}
if(this.type=='info'||this.type=='else'){
this.info(id); //
}else if(this.type=='cross'){
var obj = this.$storage.getObj('crossObj'); //
for (var o in obj){
if(o=='refid'){
this.ruleForm.refid = obj[o]; // ID
this.ro.refid = true; //
continue;
}
if(o=='userid'){
this.ruleForm.userid = obj[o]; // ID
this.ro.userid = true; //
continue;
}
if(o=='content'){
this.ruleForm.content = obj[o]; //
this.ro.content = true; //
continue;
}
if(o=='reply'){
this.ruleForm.reply = obj[o]; //
this.ro.reply = true; //
continue;
}
}
}
},
//
info(id) {
this.$http({
url: `discussfangwuxinxi/info/${id}`, //
method: "get"
}).then(({ data }) => {
if (data && data.code === 0) {
this.ruleForm = data.data; //
} else {
this.$message.error(data.msg); //
}
});
},
//
onSubmit() {
// ${column.compare}
// ${column.compare}
// ${column.compare}
// ${column.compare}
this.$refs["ruleForm"].validate(valid => { //
if (valid) {
this.$http({
url: `discussfangwuxinxi/${!this.ruleForm.id ? "save" : "update"}`, //
method: "post",
data: this.ruleForm //
}).then(({ data }) => {
if (data && data.code === 0) {
this.$message({
message: "操作成功", //
type: "success",
duration: 1500,
onClose: () => {
this.parent.showFlag = true; //
this.parent.addOrUpdateFlag = false; //
this.parent.discussfangwuxinxiCrossAddOrUpdateFlag = false; //
this.parent.search(); //
this.parent.contentStyleChange(); //
}
});
} else {
this.$message.error(data.msg); //
}
});
}
});
},
// UUID
getUUID () {
return new Date().getTime(); //
},
//
back() {
this.parent.showFlag = true; //
this.parent.addOrUpdateFlag = false; //
this.parent.discussfangwuxinxiCrossAddOrUpdateFlag = false; //
this.parent.contentStyleChange(); //
},
//
addEditStyleChange() {
this.$nextTick(()=>{
// input
document.querySelectorAll('.addEdit-block .input .el-input__inner').forEach(el=>{
el.style.height = this.addEditForm.inputHeight; //
el.style.color = this.addEditForm.inputFontColor; //
el.style.fontSize = this.addEditForm.inputFontSize; //
el.style.borderWidth = this.addEditForm.inputBorderWidth; //
el.style.borderStyle = this.addEditForm.inputBorderStyle; //
el.style.borderColor = this.addEditForm.inputBorderColor; //
el.style.borderRadius = this.addEditForm.inputBorderRadius; //
el.style.backgroundColor = this.addEditForm.inputBgColor; //
});
document.querySelectorAll('.addEdit-block .input .el-form-item__label').forEach(el=>{
el.style.lineHeight = this.addEditForm.inputHeight; //
el.style.color = this.addEditForm.inputLableColor; //
el.style.fontSize = this.addEditForm.inputLableFontSize; //
});
// select
document.querySelectorAll('.addEdit-block .select .el-input__inner').forEach(el=>{
el.style.height = this.addEditForm.selectHeight; //
el.style.color = this.addEditForm.selectFontColor; //
el.style.fontSize = this.addEditForm.selectFontSize; //
el.style.borderWidth = this.addEditForm.selectBorderWidth; //
el.style.borderStyle = this.addEditForm.selectBorderStyle; //
el.style.borderColor = this.addEditForm.selectBorderColor; //
el.style.borderRadius = this.addEditForm.selectBorderRadius; //
el.style.backgroundColor = this.addEditForm.selectBgColor; //
});
document.querySelectorAll('.addEdit-block .select .el-form-item__label').forEach(el=>{
el.style.lineHeight = this.addEditForm.selectHeight; //
el.style.color = this.addEditForm.selectLableColor; //
el.style.fontSize = this.addEditForm.selectLableFontSize; //
});
document.querySelectorAll('.addEdit-block .select .el-select__caret').forEach(el=>{
el.style.color = this.addEditForm.selectIconFontColor; //
el.style.fontSize = this.addEditForm.selectIconFontSize; //
});
// date
document.querySelectorAll('.addEdit-block .date .el-input__inner').forEach(el=>{
el.style.height = this.addEditForm.dateHeight; //
el.style.color = this.addEditForm.dateFontColor; //
el.style.fontSize = this.addEditForm.dateFontSize; //
el.style.borderWidth = this.addEditForm.dateBorderWidth; //
el.style.borderStyle = this.addEditForm.dateBorderStyle; //
el.style.borderColor = this.addEditForm.dateBorderColor; //
el.style.borderRadius = this.addEditForm.dateBorderRadius; //
el.style.backgroundColor = this.addEditForm.dateBgColor; //
});
document.querySelectorAll('.addEdit-block .date .el-form-item__label').forEach(el=>{
el.style.lineHeight = this.addEditForm.dateHeight; //
el.style.color = this.addEditForm.dateLableColor; //
el.style.fontSize = this.addEditForm.dateLableFontSize; //
});
document.querySelectorAll('.addEdit-block .date .el-input__icon').forEach(el=>{
el.style.color = this.addEditForm.dateIconFontColor; //
el.style.fontSize = this.addEditForm.dateIconFontSize; //
el.style.lineHeight = this.addEditForm.dateHeight; //
});
// upload
let iconLineHeight = parseInt(this.addEditForm.uploadHeight) - parseInt(this.addEditForm.uploadBorderWidth) * 2 + 'px'; //
document.querySelectorAll('.addEdit-block .upload .el-upload--picture-card').forEach(el=>{
el.style.width = this.addEditForm.uploadHeight; //
el.style.height = this.addEditForm.uploadHeight; //
el.style.borderWidth = this.addEditForm.uploadBorderWidth; //
el.style.borderStyle = this.addEditForm.uploadBorderStyle; //
el.style.borderColor = this.addEditForm.uploadBorderColor; //
el.style.borderRadius = this.addEditForm.uploadBorderRadius; //
el.style.backgroundColor = this.addEditForm.uploadBgColor; //
});
document.querySelectorAll('.addEdit-block .upload .el-form-item__label').forEach(el=>{
el.style.lineHeight = this.addEditForm.uploadHeight; //
el.style.color = this.addEditForm.uploadLableColor; //
el.style.fontSize = this.addEditForm.uploadLableFontSize; //
});
document.querySelectorAll('.addEdit-block .upload .el-icon-plus').forEach(el=>{
el.style.color = this.addEditForm.uploadIconFontColor; //
el.style.fontSize = this.addEditForm.uploadIconFontSize; //
el.style.lineHeight = iconLineHeight; //
el.style.display = 'block'; //
});
//
document.querySelectorAll('.addEdit-block .textarea .el-textarea__inner').forEach(el=>{
el.style.height = this.addEditForm.textareaHeight; //
el.style.color = this.addEditForm.textareaFontColor; //
el.style.fontSize = this.addEditForm.textareaFontSize; //
el.style.borderWidth = this.addEditForm.textareaBorderWidth; //
el.style.borderStyle = this.addEditForm.textareaBorderStyle; //
el.style.borderColor = this.addEditForm.textareaBorderColor; //
el.style.borderRadius = this.addEditForm.textareaBorderRadius; //
el.style.backgroundColor = this.addEditForm.textareaBgColor; //
});
document.querySelectorAll('.addEdit-block .textarea .el-form-item__label').forEach(el=>{
// el.style.lineHeight = this.addEditForm.textareaHeight; //
el.style.color = this.addEditForm.textareaLableColor; //
el.style.fontSize = this.addEditForm.textareaLableFontSize; //
});
//
document.querySelectorAll('.addEdit-block .btn .btn-success').forEach(el=>{
el.style.width = this.addEditForm.btnSaveWidth; //
el.style.height = this.addEditForm.btnSaveHeight; //
el.style.color = this.addEditForm.btnSaveFontColor; //
el.style.fontSize = this.addEditForm.btnSaveFontSize; //
el.style.borderWidth = this.addEditForm.btnSaveBorderWidth; //
el.style.borderStyle = this.addEditForm.btnSaveBorderStyle; //
el.style.borderColor = this.addEditForm.btnSaveBorderColor; //
el.style.borderRadius = this.addEditForm.btnSaveBorderRadius; //
el.style.backgroundColor = this.addEditForm.btnSaveBgColor; //
});
//
document.querySelectorAll('.addEdit-block .btn .btn-close').forEach(el=>{
el.style.width = this.addEditForm.btnCancelWidth; //
el.style.height = this.addEditForm.btnCancelHeight; //
el.style.color = this.addEditForm.btnCancelFontColor; //
el.style.fontSize = this.addEditForm.btnCancelFontSize; //
el.style.borderWidth = this.addEditForm.btnCancelBorderWidth; //
el.style.borderStyle = this.addEditForm.btnCancelBorderStyle; //
el.style.borderColor = this.addEditForm.btnCancelBorderColor; //
el.style.borderRadius = this.addEditForm.btnCancelBorderRadius; //
el.style.backgroundColor = this.addEditForm.btnCancelBgColor; //
});
});
},
//
addEditUploadStyleChange() {
this.$nextTick(()=>{
document.querySelectorAll('.addEdit-block .upload .el-upload-list--picture-card .el-upload-list__item').forEach(el=>{
el.style.width = this.addEditForm.uploadHeight; //
el.style.height = this.addEditForm.uploadHeight; //
el.style.borderWidth = this.addEditForm.uploadBorderWidth; //
el.style.borderStyle = this.addEditForm.uploadBorderStyle; //
el.style.borderColor = this.addEditForm.uploadBorderColor; //
el.style.borderRadius = this.addEditForm.uploadBorderRadius; //
el.style.backgroundColor = this.addEditForm.uploadBgColor; //
});
});
},
}
};
</script>
<style lang="scss">
.editor{
height: 500px; //
& /deep/ .ql-container {
height: 310px; //
}
}
.amap-wrapper {
width: 100%; //
height: 500px; //
}
.search-box {
position: absolute; //
}
.addEdit-block {
margin: -10px; //
}
.detail-form-content {
padding: 12px; //
}
.btn .el-button {
padding: 0; //
}
</style>

@ -0,0 +1,525 @@
<template>
<!-- 主容器 -->
<div class="main-content">
<!-- 列表页显示区域 -->
<div v-if="showFlag">
<!-- 表单组件用于搜索 -->
<el-form :inline="true" :model="searchForm" class="form-content">
<!-- 搜索框布局 -->
<el-row :gutter="20" class="slt" :style="{justifyContent:contents.searchBoxPosition=='1'?'flex-start':contents.searchBoxPosition=='2'?'center':'flex-end'}">
<!-- 搜索输入框 -->
<el-form-item :label="contents.inputTitle == 1 ? '评论内容' : ''">
<!-- 带前缀图标的输入框 -->
<el-input v-if="contents.inputIcon == 1 && contents.inputIconPosition == 1" prefix-icon="el-icon-search" v-model="searchForm.content" placeholder="评论内容" clearable></el-input>
<!-- 带后缀图标的输入框 -->
<el-input v-if="contents.inputIcon == 1 && contents.inputIconPosition == 2" suffix-icon="el-icon-search" v-model="searchForm.content" placeholder="评论内容" clearable></el-input>
<!-- 不带图标的输入框 -->
<el-input v-if="contents.inputIcon == 0" v-model="searchForm.content" placeholder="评论内容" clearable></el-input>
</el-form-item>
<!-- 搜索按钮 -->
<el-form-item>
<!-- 带前缀图标的查询按钮 -->
<el-button v-if="contents.searchBtnIcon == 1 && contents.searchBtnIconPosition == 1" icon="el-icon-search" type="success" @click="search()">{{ contents.searchBtnFont == 1?'':'' }}</el-button>
<!-- 带后缀图标的查询按钮 -->
<el-button v-if="contents.searchBtnIcon == 1 && contents.searchBtnIconPosition == 2" type="success" @click="search()">{{ contents.searchBtnFont == 1?'':'' }}<i class="el-icon-search el-icon--right"/></el-button>
<!-- 不带图标的查询按钮 -->
<el-button v-if="contents.searchBtnIcon == 0" type="success" @click="search()">{{ contents.searchBtnFont == 1?'':'' }}</el-button>
</el-form-item>
</el-row>
<!-- 新增删除按钮布局 -->
<el-row class="ad" :style="{justifyContent:contents.btnAdAllBoxPosition=='1'?'flex-start':contents.btnAdAllBoxPosition=='2'?'center':'flex-end'}">
<el-form-item>
<!-- 新增按钮带前缀图标 -->
<el-button
v-if="isAuth('discussfangwuxinxi','新增') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 1"
type="success"
icon="el-icon-plus"
@click="addOrUpdateHandler()"
>{{ contents.btnAdAllFont == 1?'新增':'' }}</el-button>
<!-- 新增按钮带后缀图标 -->
<el-button
v-if="isAuth('discussfangwuxinxi','新增') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 2"
type="success"
@click="addOrUpdateHandler()"
>{{ contents.btnAdAllFont == 1?'新增':'' }}<i class="el-icon-plus el-icon--right" /></el-button>
<!-- 新增按钮不带图标 -->
<el-button
v-if="isAuth('discussfangwuxinxi','新增') && contents.btnAdAllIcon == 0"
type="success"
@click="addOrUpdateHandler()"
>{{ contents.btnAdAllFont == 1?'新增':'' }}</el-button>
<!-- 删除按钮带前缀图标 -->
<el-button
v-if="isAuth('discussfangwuxinxi','删除') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 1 && contents.tableSelection"
:disabled="dataListSelections.length <= 0"
type="danger"
icon="el-icon-delete"
@click="deleteHandler()"
>{{ contents.btnAdAllFont == 1?'删除':'' }}</el-button>
<!-- 删除按钮带后缀图标 -->
<el-button
v-if="isAuth('discussfangwuxinxi','删除') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 2 && contents.tableSelection"
:disabled="dataListSelections.length <= 0"
type="danger"
@click="deleteHandler()"
>{{ contents.btnAdAllFont == 1?'删除':'' }}<i class="el-icon-delete el-icon--right" /></el-button>
<!-- 删除按钮不带图标 -->
<el-button
v-if="isAuth('discussfangwuxinxi','删除') && contents.btnAdAllIcon == 0 && contents.tableSelection"
:disabled="dataListSelections.length <= 0"
type="danger"
@click="deleteHandler()"
>{{ contents.btnAdAllFont == 1?'删除':'' }}</el-button>
</el-form-item>
</el-row>
</el-form>
<!-- 表格内容 -->
<div class="table-content">
<!-- 表格组件 -->
<el-table class="tables" :size="contents.tableSize" :show-header="contents.tableShowHeader"
:header-row-style="headerRowStyle" :header-cell-style="headerCellStyle"
:border="contents.tableBorder"
:fit="contents.tableFit"
:stripe="contents.tableStripe"
:row-style="rowStyle"
:cell-style="cellStyle"
:style="{width: '100%',fontSize:contents.tableContentFontSize,color:contents.tableContentFontColor}"
:data="dataList"
v-loading="dataListLoading"
@selection-change="selectionChangeHandler">
<!-- 多选列 -->
<el-table-column v-if="contents.tableSelection"
type="selection"
header-align="center"
align="center"
width="50">
</el-table-column>
<!-- 索引列 -->
<el-table-column label="索引" v-if="contents.tableIndex" type="index" width="50" />
<!-- 评论内容列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="content"
header-align="center"
label="评论内容">
<template slot-scope="scope">
{{scope.row.content}} <!-- 显示评论内容 -->
</template>
</el-table-column>
<!-- 回复内容列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="reply"
header-align="center"
label="回复内容">
<template slot-scope="scope">
{{scope.row.reply}} <!-- 显示回复内容 -->
</template>
</el-table-column>
<!-- 操作列 -->
<el-table-column width="300" :align="contents.tableAlign"
header-align="center"
label="操作">
<template slot-scope="scope">
<!-- 详情按钮带前缀图标 -->
<el-button v-if=" contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 1" type="success" icon="el-icon-tickets" size="mini" @click="addOrUpdateHandler(scope.row.id,'info')">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<!-- 详情按钮带后缀图标 -->
<el-button v-if=" contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 2" type="success" size="mini" @click="addOrUpdateHandler(scope.row.id,'info')">{{ contents.tableBtnFont == 1?'':'' }}<i class="el-icon-tickets el-icon--right" /></el-button>
<!-- 详情按钮不带图标 -->
<el-button v-if=" contents.tableBtnIcon == 0" type="success" size="mini" @click="addOrUpdateHandler(scope.row.id,'info')">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<!-- 修改按钮带前缀图标 -->
<el-button v-if="isAuth('discussfangwuxinxi','修改') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 1" type="primary" icon="el-icon-edit" size="mini" @click="addOrUpdateHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<!-- 修改按钮带后缀图标 -->
<el-button v-if="isAuth('discussfangwuxinxi','修改') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 2" type="primary" size="mini" @click="addOrUpdateHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}<i class="el-icon-edit el-icon--right" /></el-button>
<!-- 修改按钮不带图标 -->
<el-button v-if="isAuth('discussfangwuxinxi','修改') && contents.tableBtnIcon == 0" type="primary" size="mini" @click="addOrUpdateHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<!-- 查看评论按钮带前缀图标 -->
<el-button v-if="isAuth('discussfangwuxinxi','查看评论') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 1" type="primary" icon="el-icon-edit" size="mini" @click="disscussListHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<!-- 查看评论按钮带后缀图标 -->
<el-button v-if="isAuth('discussfangwuxinxi','查看评论') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 2" type="primary" size="mini" @click="disscussListHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}<i class="el-icon-edit el-icon--right" /></el-button>
<!-- 查看评论按钮不带图标 -->
<el-button v-if="isAuth('discussfangwuxinxi','查看评论') && contents.tableBtnIcon == 0" type="primary" size="mini" @click="disscussListHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<!-- 回复按钮带前缀图标 -->
<el-button v-if="contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 1" type="primary" icon="el-icon-edit" size="mini" @click="addOrUpdateHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<!-- 回复按钮带后缀图标 -->
<el-button v-if="contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 2" type="primary" size="mini" @click="addOrUpdateHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}<i class="el-icon-edit el-icon--right" /></el-button>
<!-- 回复按钮不带图标 -->
<el-button v-if="contents.tableBtnIcon == 0" type="primary" size="mini" @click="addOrUpdateHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<!-- 删除按钮带前缀图标 -->
<el-button v-if=" contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 1" type="danger" icon="el-icon-delete" size="mini" @click="deleteHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<!-- 删除按钮带后缀图标 -->
<el-button v-if=" contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 2" type="danger" size="mini" @click="deleteHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}<i class="el-icon-delete el-icon--right" /></el-button>
<!-- 删除按钮不带图标 -->
<el-button v-if=" contents.tableBtnIcon == 0" type="danger" size="mini" @click="deleteHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<el-pagination
clsss="pages"
:layout="layouts"
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
:current-page="pageIndex"
:page-sizes="[10, 20, 50, 100]"
:page-size="Number(contents.pageEachNum)"
:total="totalPage"
:small="contents.pageStyle"
class="pagination-content"
:background="contents.pageBtnBG"
:style="{textAlign:contents.pagePosition==1?'left':contents.pagePosition==2?'center':'right'}"
></el-pagination>
</div>
</div>
<!-- 添加/修改页面组件 -->
<add-or-update v-if="addOrUpdateFlag" :parent="this" ref="addOrUpdate"></add-or-update>
</div>
</template>
<script>
// /
import AddOrUpdate from "./add-or-update";
export default {
data() {
return {
searchForm: { //
key: ""
},
dataList: [], //
pageIndex: 1, //
pageSize: 10, //
totalPage: 0, //
dataListLoading: false, //
dataListSelections: [], //
showFlag: true, //
sfshVisiable: false, //
shForm: {}, //
chartVisiable: false, //
addOrUpdateFlag:false, // /
contents:{"searchBtnFontColor":"#333","pagePosition":"1","inputFontSize":"14px","inputBorderRadius":"22px","tableBtnDelFontColor":"#333","tableBtnIconPosition":"1","searchBtnHeight":"40px","inputIconColor":"rgba(66, 130, 129, 1)","searchBtnBorderRadius":"22px","tableStripe":false,"btnAdAllWarnFontColor":"#333","tableBtnDelBgColor":"rgba(244, 150, 150, 1)","searchBtnIcon":"1","tableSize":"medium","searchBtnBorderStyle":"solid","tableSelection":true,"searchBtnBorderWidth":"1px","tableContentFontSize":"14px","searchBtnBgColor":"rgba(153, 239, 237, 1)","inputTitleSize":"14px","btnAdAllBorderColor":"#DCDFE6","pageJumper":true,"btnAdAllIconPosition":"1","searchBoxPosition":"1","tableBtnDetailFontColor":"#333","tableBtnHeight":"40px","pagePager":true,"searchBtnBorderColor":"#DCDFE6","tableHeaderFontColor":"rgba(33, 34, 35, 1)","inputTitle":"1","tableBtnBorderRadius":"22px","btnAdAllFont":"1","btnAdAllDelFontColor":"rgba(21, 20, 20, 1)","tableBtnIcon":"1","btnAdAllHeight":"40px","btnAdAllWarnBgColor":"rgba(238, 236, 126, 1)","btnAdAllBorderWidth":"1px","tableStripeFontColor":"#606266","tableBtnBorderStyle":"solid","inputHeight":"40px","btnAdAllBorderRadius":"22px","btnAdAllDelBgColor":"rgba(234, 93, 93, 0.69)","pagePrevNext":true,"btnAdAllAddBgColor":"rgba(153, 239, 237, 1)","searchBtnFont":"1","tableIndex":true,"btnAdAllIcon":"1","tableSortable":true,"pageSizes":true,"tableFit":true,"pageBtnBG":true,"searchBtnFontSize":"14px","tableBtnEditBgColor":"rgba(240, 242, 124, 1)","inputBorderWidth":"1px","inputFontPosition":"1","inputFontColor":"#333","pageEachNum":10,"tableHeaderBgColor":"rgba(152, 129, 129, 1)","inputTitleColor":"#333","btnAdAllBoxPosition":"1","tableBtnDetailBgColor":"rgba(171, 239, 239, 1)","inputIcon":"0","searchBtnIconPosition":"1","btnAdAllFontSize":"14px","inputBorderStyle":"solid","inputBgColor":"rgba(197, 174, 174, 0.32)","pageStyle":false,"pageTotal":true,"btnAdAllAddFontColor":"#333","tableBtnFont":"1","tableContentFontColor":"rgba(22, 22, 23, 1)","inputBorderColor":"rgba(152, 129, 129, 1)","tableShowHeader":true,"tableBtnFontSize":"14px","tableBtnBorderColor":"rgba(196, 210, 244, 1)","inputIconPosition":"1","tableBorder":true,"btnAdAllBorderStyle":"solid","tableBtnBorderWidth":"1px","tableStripeBgColor":"rgba(213, 197, 197, 1)","tableBtnEditFontColor":"#333","tableAlign":"center"}, //
layouts: '', //
};
},
created() {
this.init(); //
this.getDataList(); //
this.contentStyleChange(); //
},
mounted() {
//
},
filters: {
htmlfilter: function (val) {
return val.replace(/<[^>]*>/g).replace(/undefined/g,''); // HTMLundefined
}
},
components: {
AddOrUpdate, //
},
methods: {
contentStyleChange() {
this.contentSearchStyleChange(); //
this.contentBtnAdAllStyleChange(); // /
this.contentSearchBtnStyleChange(); //
this.contentTableBtnStyleChange(); //
this.contentPageStyleChange(); //
},
contentSearchStyleChange() {
this.$nextTick(()=>{
document.querySelectorAll('.form-content .slt .el-input__inner').forEach(el=>{
let textAlign = 'left'; //
if(this.contents.inputFontPosition == 2) textAlign = 'center'; //
if(this.contents.inputFontPosition == 3) textAlign = 'right'; //
el.style.textAlign = textAlign; //
el.style.height = this.contents.inputHeight; //
el.style.lineHeight = this.contents.inputHeight; //
el.style.color = this.contents.inputFontColor; //
el.style.fontSize = this.contents.inputFontSize; //
el.style.borderWidth = this.contents.inputBorderWidth; //
el.style.borderStyle = this.contents.inputBorderStyle; //
el.style.borderColor = this.contents.inputBorderColor; //
el.style.borderRadius = this.contents.inputBorderRadius; //
el.style.backgroundColor = this.contents.inputBgColor; //
});
if(this.contents.inputTitle) {
document.querySelectorAll('.form-content .slt .el-form-item__label').forEach(el=>{
el.style.color = this.contents.inputTitleColor; //
el.style.fontSize = this.contents.inputTitleSize; //
el.style.lineHeight = this.contents.inputHeight; //
});
}
setTimeout(()=>{
document.querySelectorAll('.form-content .slt .el-input__prefix').forEach(el=>{
el.style.color = this.contents.inputIconColor; //
el.style.lineHeight = this.contents.inputHeight; //
});
document.querySelectorAll('.form-content .slt .el-input__suffix').forEach(el=>{
el.style.color = this.contents.inputIconColor; //
el.style.lineHeight = this.contents.inputHeight; //
});
document.querySelectorAll('.form-content .slt .el-input__icon').forEach(el=>{
el.style.lineHeight = this.contents.inputHeight; //
});
},10);
});
},
//
contentSearchBtnStyleChange() {
this.$nextTick(()=>{
document.querySelectorAll('.form-content .slt .el-button--success').forEach(el=>{
el.style.height = this.contents.searchBtnHeight; //
el.style.color = this.contents.searchBtnFontColor; //
el.style.fontSize = this.contents.searchBtnFontSize; //
el.style.borderWidth = this.contents.searchBtnBorderWidth; //
el.style.borderStyle = this.contents.searchBtnBorderStyle; //
el.style.borderColor = this.contents.searchBtnBorderColor; //
el.style.borderRadius = this.contents.searchBtnBorderRadius; //
el.style.backgroundColor = this.contents.searchBtnBgColor; //
});
});
},
//
contentBtnAdAllStyleChange() {
this.$nextTick(()=>{
document.querySelectorAll('.form-content .ad .el-button--success').forEach(el=>{
el.style.height = this.contents.btnAdAllHeight; //
el.style.color = this.contents.btnAdAllAddFontColor; //
el.style.fontSize = this.contents.btnAdAllFontSize; //
el.style.borderWidth = this.contents.btnAdAllBorderWidth; //
el.style.borderStyle = this.contents.btnAdAllBorderStyle; //
el.style.borderColor = this.contents.btnAdAllBorderColor; //
el.style.borderRadius = this.contents.btnAdAllBorderRadius; //
el.style.backgroundColor = this.contents.btnAdAllAddBgColor; //
});
document.querySelectorAll('.form-content .ad .el-button--danger').forEach(el=>{
el.style.height = this.contents.btnAdAllHeight; //
el.style.color = this.contents.btnAdAllDelFontColor; //
el.style.fontSize = this.contents.btnAdAllFontSize; //
el.style.borderWidth = this.contents.btnAdAllBorderWidth; //
el.style.borderStyle = this.contents.btnAdAllBorderStyle; //
el.style.borderColor = this.contents.btnAdAllBorderColor; //
el.style.borderRadius = this.contents.btnAdAllBorderRadius; //
el.style.backgroundColor = this.contents.btnAdAllDelBgColor; //
});
document.querySelectorAll('.form-content .ad .el-button--warning').forEach(el=>{
el.style.height = this.contents.btnAdAllHeight; //
el.style.color = this.contents.btnAdAllWarnFontColor; //
el.style.fontSize = this.contents.btnAdAllFontSize; //
el.style.borderWidth = this.contents.btnAdAllBorderWidth; //
el.style.borderStyle = this.contents.btnAdAllBorderStyle; //
el.style.borderColor = this.contents.btnAdAllBorderColor; //
el.style.borderRadius = this.contents.btnAdAllBorderRadius; //
el.style.backgroundColor = this.contents.btnAdAllWarnBgColor; //
});
});
},
//
rowStyle({ row, rowIndex}) {
if (rowIndex % 2 == 1) { //
if(this.contents.tableStripe) {
return {color:this.contents.tableStripeFontColor}; //
}
} else {
return ''; //
}
},
//
cellStyle({ row, rowIndex}){
if (rowIndex % 2 == 1) { //
if(this.contents.tableStripe) {
return {backgroundColor:this.contents.tableStripeBgColor}; //
}
} else {
return ''; //
}
},
//
headerRowStyle({ row, rowIndex}){
return {color: this.contents.tableHeaderFontColor}; //
},
//
headerCellStyle({ row, rowIndex}){
return {backgroundColor: this.contents.tableHeaderBgColor}; //
},
//
contentTableBtnStyleChange(){
//
},
//
contentPageStyleChange(){
let arr = []; //
if(this.contents.pageTotal) arr.push('total'); //
if(this.contents.pageSizes) arr.push('sizes'); //
if(this.contents.pagePrevNext){
arr.push('prev'); //
if(this.contents.pagePager) arr.push('pager'); //
arr.push('next'); //
}
if(this.contents.pageJumper) arr.push('jumper'); //
this.layouts = arr.join(); //
this.contents.pageEachNum = 10; //
},
init () {
//
},
search() {
this.pageIndex = 1; //
this.getDataList(); //
},
//
getDataList() {
this.dataListLoading = true; //
let params = {
page: this.pageIndex, //
limit: this.pageSize, //
sort: 'id', //
refid : this.$route.query.refid, // ID
}
if(this.searchForm.content!='' && this.searchForm.content!=undefined){
params['content'] = '%' + this.searchForm.content + '%'; //
}
this.$http({
url: "discussfangwuxinxi/page", //
method: "get",
params: params
}).then(({ data }) => {
if (data && data.code === 0) {
this.dataList = data.data.list; //
this.totalPage = data.data.total; //
} else {
this.dataList = []; //
this.totalPage = 0; //
}
this.dataListLoading = false; //
});
},
//
sizeChangeHandle(val) {
this.pageSize = val; //
this.pageIndex = 1; //
this.getDataList(); //
},
//
currentChangeHandle(val) {
this.pageIndex = val; //
this.getDataList(); //
},
//
selectionChangeHandler(val) {
this.dataListSelections = val; //
},
// /
addOrUpdateHandler(id,type) {
this.showFlag = false; //
this.addOrUpdateFlag = true; // /
this.crossAddOrUpdateFlag = false; //
if(type!='info'){
type = 'else'; //
}
this.$nextTick(() => {
this.$refs.addOrUpdate.init(id,type); //
});
},
//
disscussListHandler(id,type) {
this.$router.push({path:'/discussdiscussfangwuxinxi',query:{refid:id}}); //
},
//
download(file){
window.open(`${file}`); //
},
//
deleteHandler(id) {
var ids = id
? [Number(id)] //
: this.dataListSelections.map(item => {
return Number(item.id); //
});
this.$confirm(`确定进行[${id ? "删除" : "批量删除"}]操作?`, "提示", {
confirmButtonText: "确定", //
cancelButtonText: "取消", //
type: "warning" //
}).then(() => {
this.$http({
url: "discussfangwuxinxi/delete", //
method: "post",
data: ids
}).then(({ data }) => {
if (data && data.code === 0) {
this.$message({
message: "操作成功", //
type: "success",
duration: 1500,
onClose: () => {
this.search(); //
}
});
} else {
this.$message.error(data.msg); //
}
});
});
},
}
};
</script>
<style lang="scss" scoped>
.slt {
margin: 0 !important; //
display: flex; // 使
}
.ad {
margin: 0 !important; //
display: flex; // 使
}
.pages {
& /deep/ el-pagination__sizes{ //
& /deep/ el-input__inner {
height: 22px; //
line-height: 22px; //
}
}
}
.el-button+.el-button {
margin:0; //
}
.tables {
& /deep/ .el-button--success { //
height: 40px;
color: #333;
font-size: 14px;
border-width: 1px;
border-style: solid;
border-color: rgba(196, 210, 244, 1);
border-radius: 22px;
background-color: rgba(171, 239, 239, 1);
}
& /deep/ .el-button--primary { //
height: 40px;
color: #333;
font-size: 14px;
border-width: 1px;
border-style: solid;
border-color: rgba(196, 210, 244, 1);
border-radius: 22px;
background-color: rgba(240, 242, 124, 1);
}
& /deep/ .el-button--danger { //
height: 40px;
color: #333;
font-size: 14px;
border-width: 1px;
border-style: solid;
border-color: rgba(196, 210, 244, 1);
border-radius: 22px;
background-color: rgba(244, 150, 150, 1);
}
& /deep/ .el-button {
margin: 4px; //
}
}
</style>

@ -0,0 +1,332 @@
<template>
<!-- 主容器 -->
<div class="addEdit-block">
<!-- 表单组件 -->
<el-form
class="detail-form-content"
ref="ruleForm" <!-- 表单引用 -->
:model="ruleForm" <!-- 绑定表单数据模型 -->
:rules="rules" <!-- 绑定验证规则 -->
label-width="80px" <!-- 标签宽度 -->
:style="{backgroundColor:addEditForm.addEditBoxColor}" <!-- 动态背景色 -->
>
<!-- 空行 -->
<el-row></el-row>
<!-- 评论内容区域 -->
<el-row>
<el-col :span="24"> <!-- 占满整列 -->
<!-- 编辑模式下的评论内容输入框 -->
<el-form-item class="textarea" v-if="type!='info'" label="评论内容" prop="content">
<el-input
style="min-width: 200px; max-width: 600px;" <!-- 输入框宽度限制 -->
type="textarea" <!-- 文本域类型 -->
:rows="8" <!-- 显示行数 -->
placeholder="评论内容" <!-- 占位符 -->
v-model="ruleForm.content" readonly> <!-- 双向绑定并只读 -->
</el-input>
</el-form-item>
<!-- 查看模式下的评论内容显示 -->
<div v-else>
<el-form-item v-if="ruleForm.content" label="评论内容" prop="content">
<span>{{ruleForm.content}}</span> <!-- 显示评论内容 -->
</el-form-item>
</div>
</el-col>
</el-row>
<!-- 回复内容区域 -->
<el-row>
<el-col :span="24"> <!-- 占满整列 -->
<!-- 编辑模式下的回复内容输入框 -->
<el-form-item class="textarea" v-if="type!='info'" label="回复内容" prop="reply">
<el-input
style="min-width: 200px; max-width: 600px;" <!-- 输入框宽度限制 -->
type="textarea" <!-- 文本域类型 -->
:rows="8" <!-- 显示行数 -->
placeholder="回复内容" <!-- 占位符 -->
v-model="ruleForm.reply"> <!-- 双向绑定回复内容 -->
</el-input>
</el-form-item>
<!-- 查看模式下的回复内容显示 -->
<div v-else>
<el-form-item v-if="ruleForm.reply" label="回复内容" prop="reply">
<span>{{ruleForm.reply}}</span> <!-- 显示回复内容 -->
</el-form-item>
</div>
</el-col>
</el-row>
<!-- 操作按钮 -->
<el-form-item class="btn">
<!-- 提交按钮非查看模式 -->
<el-button v-if="type!='info'" type="primary" class="btn-success" @click="onSubmit"></el-button>
<!-- 取消按钮非查看模式 -->
<el-button v-if="type!='info'" class="btn-close" @click="back()"></el-button>
<!-- 返回按钮查看模式 -->
<el-button v-if="type=='info'" class="btn-close" @click="back()"></el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
//
import { isNumber,isIntNumer,isEmail,isPhone, isMobile,isURL,checkIdCard } from "@/utils/validate";
export default {
data() {
let self = this;
//
var validateIdCard = (rule, value, callback) => {
if(!value){
callback(); //
} else if (!checkIdCard(value)) {
callback(new Error("请输入正确的身份证号码")); //
} else {
callback(); //
}
};
// URL
var validateUrl = (rule, value, callback) => {
if(!value){
callback(); //
} else if (!isURL(value)) {
callback(new Error("请输入正确的URL地址")); //
} else {
callback(); //
}
};
//
var validateMobile = (rule, value, callback) => {
if(!value){
callback(); //
} else if (!isMobile(value)) {
callback(new Error("请输入正确的手机号码")); //
} else {
callback(); //
}
};
//
var validatePhone = (rule, value, callback) => {
if(!value){
callback(); //
} else if (!isPhone(value)) {
callback(new Error("请输入正确的电话号码")); //
} else {
callback(); //
}
};
//
var validateEmail = (rule, value, callback) => {
if(!value){
callback(); //
} else if (!isEmail(value)) {
callback(new Error("请输入正确的邮箱地址")); //
} else {
callback(); //
}
};
//
var validateNumber = (rule, value, callback) => {
if(!value){
callback(); //
} else if (!isNumber(value)) {
callback(new Error("请输入数字")); //
} else {
callback(); //
}
};
//
var validateIntNumber = (rule, value, callback) => {
if(!value){
callback(); //
} else if (!isIntNumer(value)) {
callback(new Error("请输入整数")); //
} else {
callback(); //
}
};
return {
//
addEditForm: {"btnSaveFontColor":"#fff","selectFontSize":"14px",...}, //
id: '', // ID
type: '', // //
ro:{ //
refid : false,
userid : false,
content : false,
reply : false,
},
ruleForm: { //
refid: '',
userid: '',
content: '',
reply: '',
},
rules: { //
refid: [
{ required: true, message: '关联表id不能为空', trigger: 'blur' }, //
],
userid: [
{ required: true, message: '用户id不能为空', trigger: 'blur' }, //
],
content: [
{ required: true, message: '评论内容不能为空', trigger: 'blur' }, //
],
reply: [] //
}
};
},
props: ["parent"], //
computed: {}, //
created() { //
this.addEditStyleChange(); //
this.addEditUploadStyleChange(); //
},
methods: {
//
download(file){
window.open(`${file}`); //
},
//
init(id,type) {
if (id) {
this.id = id; // ID
this.type = type; //
}
if(this.type=='info'||this.type=='else'){
this.info(id); //
}else if(this.type=='cross'){
var obj = this.$storage.getObj('crossObj'); //
for (var o in obj){
if(o=='refid'){ // refid
this.ruleForm.refid = obj[o];
this.ro.refid = true; //
continue;
}
if(o=='userid'){ // userid
this.ruleForm.userid = obj[o];
this.ro.userid = true; //
continue;
}
if(o=='content'){ // content
this.ruleForm.content = obj[o];
this.ro.content = true; //
continue;
}
if(o=='reply'){ // reply
this.ruleForm.reply = obj[o];
this.ro.reply = true; //
continue;
}
}
}
},
//
info(id) {
this.$http({
url: `discusswoyaodangfangzhu/info/${id}`, //
method: "get" // GET
}).then(({ data }) => {
if (data && data.code === 0) {
this.ruleForm = data.data; //
} else {
this.$message.error(data.msg); //
}
});
},
//
onSubmit() {
this.$refs["ruleForm"].validate(valid => { //
if (valid) { //
this.$http({
url: `discusswoyaodangfangzhu/${!this.ruleForm.id ? "save" : "update"}`, //
method: "post", // POST
data: this.ruleForm //
}).then(({ data }) => {
if (data && data.code === 0) { //
this.$message({ //
message: "操作成功",
type: "success",
duration: 1500,
onClose: () => { //
this.parent.showFlag = true; //
this.parent.addOrUpdateFlag = false; //
this.parent.discusswoyaodangfangzhuCrossAddOrUpdateFlag = false;
this.parent.search(); //
this.parent.contentStyleChange(); //
}
});
} else {
this.$message.error(data.msg); //
}
});
}
});
},
// UUID
getUUID () {
return new Date().getTime(); //
},
//
back() {
this.parent.showFlag = true; //
this.parent.addOrUpdateFlag = false; //
this.parent.discusswoyaodangfangzhuCrossAddOrUpdateFlag = false;
this.parent.contentStyleChange(); //
},
//
addEditStyleChange() {
this.$nextTick(()=>{ // DOM
// input
document.querySelectorAll('.addEdit-block .input .el-input__inner').forEach(el=>{
el.style.height = this.addEditForm.inputHeight; //
el.style.color = this.addEditForm.inputFontColor; //
// ...
});
// textarea
document.querySelectorAll('.addEdit-block .textarea .el-textarea__inner').forEach(el=>{
el.style.height = this.addEditForm.textareaHeight; //
// ...
});
//
document.querySelectorAll('.addEdit-block .btn .btn-success').forEach(el=>{
el.style.width = this.addEditForm.btnSaveWidth; //
// ...
});
})
},
//
addEditUploadStyleChange() {
this.$nextTick(()=>{
document.querySelectorAll('.addEdit-block .upload .el-upload-list--picture-card .el-upload-list__item').forEach(el=>{
el.style.width = this.addEditForm.uploadHeight; //
el.style.height = this.addEditForm.uploadHeight; //
// ...
})
})
},
}
};
</script>
<style lang="scss">
.editor{
height: 500px; /* 编辑器高度 */
& /deep/ .ql-container { /* 深度选择器覆盖子组件样式 */
height: 310px; /* 内容区高度 */
}
}
.amap-wrapper { /* 地图容器 */
width: 100%; /* 全宽 */
height: 500px; /* 固定高度 */
}
.search-box { /* 搜索框定位 */
position: absolute; /* 绝对定位 */
}
.addEdit-block { /* 主容器 */
margin: -10px; /* 负边距抵消布局间隙 */
}
.detail-form-content { /* 表单内容 */
padding: 12px; /* 内边距 */
}
.btn .el-button { /* 按钮样式 */
padding: 0; /* 移除默认padding */
}
</style>

@ -0,0 +1,737 @@
<template>
<!-- 主容器 -->
<div class="main-content">
<!-- 列表页主体 -->
<div v-if="showFlag">
<!-- 搜索表单 -->
<el-form :inline="true" :model="searchForm" class="form-content">
<!-- 搜索区域布局 -->
<el-row
:gutter="20"
class="slt"
:style="{
justifyContent:
contents.searchBoxPosition == '1' ? 'flex-start' :
contents.searchBoxPosition == '2' ? 'center' : 'flex-end'
}"
>
<!-- 评论内容搜索框 -->
<el-form-item :label="contents.inputTitle == 1 ? '评论内容' : ''">
<!-- 带前缀图标的输入框 -->
<el-input
v-if="contents.inputIcon == 1 && contents.inputIconPosition == 1"
prefix-icon="el-icon-search"
v-model="searchForm.content"
placeholder="评论内容"
clearable
></el-input>
<!-- 带后缀图标的输入框 -->
<el-input
v-if="contents.inputIcon == 1 && contents.inputIconPosition == 2"
suffix-icon="el-icon-search"
v-model="searchForm.content"
placeholder="评论内容"
clearable
></el-input>
<!-- 无图标的输入框 -->
<el-input
v-if="contents.inputIcon == 0"
v-model="searchForm.content"
placeholder="评论内容"
clearable
></el-input>
</el-form-item>
<!-- 查询按钮 -->
<el-form-item>
<!-- 前置图标的查询按钮 -->
<el-button
v-if="contents.searchBtnIcon == 1 && contents.searchBtnIconPosition == 1"
icon="el-icon-search"
type="success"
@click="search()"
>{{ contents.searchBtnFont == 1?'查询':'' }}</el-button>
<!-- 后置图标的查询按钮 -->
<el-button
v-if="contents.searchBtnIcon == 1 && contents.searchBtnIconPosition == 2"
type="success"
@click="search()"
>{{ contents.searchBtnFont == 1?'查询':'' }}<i class="el-icon-search el-icon--right"/></el-button>
<!-- 无图标的查询按钮 -->
<el-button
v-if="contents.searchBtnIcon == 0"
type="success"
@click="search()"
>{{ contents.searchBtnFont == 1?'查询':'' }}</el-button>
</el-form-item>
</el-row>
<!-- 操作按钮区域 -->
<el-row
class="ad"
:style="{
justifyContent:
contents.btnAdAllBoxPosition == '1' ? 'flex-start' :
contents.btnAdAllBoxPosition == '2' ? 'center' : 'flex-end'
}"
>
<el-form-item>
<!-- 新增按钮前置图标 -->
<el-button
v-if="isAuth('discusswoyaodangfangzhu','新增') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 1"
type="success"
icon="el-icon-plus"
@click="addOrUpdateHandler()"
>{{ contents.btnAdAllFont == 1?'新增':'' }}</el-button>
<!-- 新增按钮后置图标 -->
<el-button
v-if="isAuth('discusswoyaodangfangzhu','新增') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 2"
type="success"
@click="addOrUpdateHandler()"
>{{ contents.btnAdAllFont == 1?'新增':'' }}<i class="el-icon-plus el-icon--right" /></el-button>
<!-- 新增按钮无图标 -->
<el-button
v-if="isAuth('discusswoyaodangfangzhu','新增') && contents.btnAdAllIcon == 0"
type="success"
@click="addOrUpdateHandler()"
>{{ contents.btnAdAllFont == 1?'新增':'' }}</el-button>
<!-- 删除按钮前置图标 -->
<el-button
v-if="isAuth('discusswoyaodangfangzhu','删除') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 1 && contents.tableSelection"
:disabled="dataListSelections.length <= 0"
type="danger"
icon="el-icon-delete"
@click="deleteHandler()"
>{{ contents.btnAdAllFont == 1?'删除':'' }}</el-button>
<!-- 删除按钮后置图标 -->
<el-button
v-if="isAuth('discusswoyaodangfangzhu','删除') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 2 && contents.tableSelection"
:disabled="dataListSelections.length <= 0"
type="danger"
@click="deleteHandler()"
>{{ contents.btnAdAllFont == 1?'删除':'' }}<i class="el-icon-delete el-icon--right" /></el-button>
<!-- 删除按钮无图标 -->
<el-button
v-if="isAuth('discusswoyaodangfangzhu','删除') && contents.btnAdAllIcon == 0 && contents.tableSelection"
:disabled="dataListSelections.length <= 0"
type="danger"
@click="deleteHandler()"
>{{ contents.btnAdAllFont == 1?'删除':'' }}</el-button>
</el-form-item>
</el-row>
</el-form>
<!-- 表格区域 -->
<div class="table-content">
<!-- 数据表格 -->
<el-table
class="tables"
:size="contents.tableSize"
:show-header="contents.tableShowHeader"
:header-row-style="headerRowStyle"
:header-cell-style="headerCellStyle"
:border="contents.tableBorder"
:fit="contents.tableFit"
:stripe="contents.tableStripe"
:row-style="rowStyle"
:cell-style="cellStyle"
:style="{
width: '100%',
fontSize: contents.tableContentFontSize,
color: contents.tableContentFontColor
}"
:data="dataList"
v-loading="dataListLoading"
@selection-change="selectionChangeHandler"
>
<!-- 多选列 -->
<el-table-column
v-if="contents.tableSelection"
type="selection"
header-align="center"
align="center"
width="50"
></el-table-column>
<!-- 索引列 -->
<el-table-column
label="索引"
v-if="contents.tableIndex"
type="index"
width="50"
/>
<!-- 评论内容列 -->
<el-table-column
:sortable="contents.tableSortable"
:align="contents.tableAlign"
prop="content"
header-align="center"
label="评论内容"
>
<template slot-scope="scope">
{{ scope.row.content }}
</template>
</el-table-column>
<!-- 回复内容列 -->
<el-table-column
:sortable="contents.tableSortable"
:align="contents.tableAlign"
prop="reply"
header-align="center"
label="回复内容"
>
<template slot-scope="scope">
{{ scope.row.reply }}
</template>
</el-table-column>
<!-- 操作列 -->
<el-table-column
width="300"
:align="contents.tableAlign"
header-align="center"
label="操作"
>
<template slot-scope="scope">
<!-- 查看详情按钮 -->
<el-button
v-if="contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 1"
type="success"
icon="el-icon-tickets"
size="mini"
@click="addOrUpdateHandler(scope.row.id,'info')"
>{{ contents.tableBtnFont == 1?'详情':'' }}</el-button>
<el-button
v-if="contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 2"
type="success"
size="mini"
@click="addOrUpdateHandler(scope.row.id,'info')"
>{{ contents.tableBtnFont == 1?'详情':'' }}<i class="el-icon-tickets el-icon--right" /></el-button>
<el-button
v-if="contents.tableBtnIcon == 0"
type="success"
size="mini"
@click="addOrUpdateHandler(scope.row.id,'info')"
>{{ contents.tableBtnFont == 1?'详情':'' }}</el-button>
<!-- 修改按钮 -->
<el-button
v-if="isAuth('discusswoyaodangfangzhu','修改') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 1"
type="primary"
icon="el-icon-edit"
size="mini"
@click="addOrUpdateHandler(scope.row.id)"
>{{ contents.tableBtnFont == 1?'修改':'' }}</el-button>
<el-button
v-if="isAuth('discusswoyaodangfangzhu','修改') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 2"
type="primary"
size="mini"
@click="addOrUpdateHandler(scope.row.id)"
>{{ contents.tableBtnFont == 1?'修改':'' }}<i class="el-icon-edit el-icon--right" /></el-button>
<el-button
v-if="isAuth('discusswoyaodangfangzhu','修改') && contents.tableBtnIcon == 0"
type="primary"
size="mini"
@click="addOrUpdateHandler(scope.row.id)"
>{{ contents.tableBtnFont == 1?'修改':'' }}</el-button>
<!-- 查看评论按钮 -->
<el-button
v-if="isAuth('discusswoyaodangfangzhu','查看评论') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 1"
type="primary"
icon="el-icon-edit"
size="mini"
@click="disscussListHandler(scope.row.id)"
>{{ contents.tableBtnFont == 1?'查看评论':'' }}</el-button>
<el-button
v-if="isAuth('discusswoyaodangfangzhu','查看评论') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 2"
type="primary"
size="mini"
@click="disscussListHandler(scope.row.id)"
>{{ contents.tableBtnFont == 1?'查看评论':'' }}<i class="el-icon-edit el-icon--right" /></el-button>
<el-button
v-if="isAuth('discusswoyaodangfangzhu','查看评论') && contents.tableBtnIcon == 0"
type="primary"
size="mini"
@click="disscussListHandler(scope.row.id)"
>{{ contents.tableBtnFont == 1?'查看评论':'' }}</el-button>
<!-- 回复按钮 -->
<el-button
v-if="contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 1"
type="primary"
icon="el-icon-edit"
size="mini"
@click="addOrUpdateHandler(scope.row.id)"
>{{ contents.tableBtnFont == 1?'回复':'' }}</el-button>
<el-button
v-if="contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 2"
type="primary"
size="mini"
@click="addOrUpdateHandler(scope.row.id)"
>{{ contents.tableBtnFont == 1?'回复':'' }}<i class="el-icon-edit el-icon--right" /></el-button>
<el-button
v-if="contents.tableBtnIcon == 0"
type="primary"
size="mini"
@click="addOrUpdateHandler(scope.row.id)"
>{{ contents.tableBtnFont == 1?'回复':'' }}</el-button>
<!-- 删除按钮 -->
<el-button
v-if="contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 1"
type="danger"
icon="el-icon-delete"
size="mini"
@click="deleteHandler(scope.row.id)"
>{{ contents.tableBtnFont == 1?'删除':'' }}</el-button>
<el-button
v-if="contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 2"
type="danger"
size="mini"
@click="deleteHandler(scope.row.id)"
>{{ contents.tableBtnFont == 1?'删除':'' }}<i class="el-icon-delete el-icon--right" /></el-button>
<el-button
v-if="contents.tableBtnIcon == 0"
type="danger"
size="mini"
@click="deleteHandler(scope.row.id)"
>{{ contents.tableBtnFont == 1?'删除':'' }}</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<el-pagination
clsss="pages"
:layout="layouts"
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
:current-page="pageIndex"
:page-sizes="[10, 20, 50, 100]"
:page-size="Number(contents.pageEachNum)"
:total="totalPage"
:small="contents.pageStyle"
class="pagination-content"
:background="contents.pageBtnBG"
:style="{
textAlign:
contents.pagePosition == 1 ? 'left' :
contents.pagePosition == 2 ? 'center' : 'right'
}"
></el-pagination>
</div>
</div>
<!-- 添加/修改页面 -->
<add-or-update v-if="addOrUpdateFlag" :parent="this" ref="addOrUpdate"></add-or-update>
</div>
</template>
<script>
//
import AddOrUpdate from "./add-or-update";
export default {
data() {
return {
//
searchForm: { key: "" },
//
dataList: [],
//
pageIndex: 1,
//
pageSize: 10,
//
totalPage: 0,
//
dataListLoading: false,
//
dataListSelections: [],
//
showFlag: true,
//
sfshVisiable: false,
//
shForm: {},
//
chartVisiable: false,
//
addOrUpdateFlag: false,
//
contents: {
"searchBtnFontColor": "#333",
"pagePosition": "1",
"inputFontSize": "14px",
// ...
},
//
layouts: '',
};
},
created() {
//
this.init();
//
this.getDataList();
//
this.contentStyleChange()
},
mounted() {
//
},
filters: {
// HTML
htmlfilter: function (val) {
return val.replace(/<[^>]*>/g).replace(/undefined/g,'');
}
},
components: {
//
AddOrUpdate,
},
methods: {
//
contentStyleChange() {
this.contentSearchStyleChange()
this.contentBtnAdAllStyleChange()
this.contentSearchBtnStyleChange()
this.contentTableBtnStyleChange()
this.contentPageStyleChange()
},
//
contentSearchStyleChange() {
this.$nextTick(()=>{
document.querySelectorAll('.form-content .slt .el-input__inner').forEach(el=>{
let textAlign = 'left'
if(this.contents.inputFontPosition == 2) textAlign = 'center'
if(this.contents.inputFontPosition == 3) textAlign = 'right'
el.style.textAlign = textAlign
el.style.height = this.contents.inputHeight
el.style.lineHeight = this.contents.inputHeight
el.style.color = this.contents.inputFontColor
el.style.fontSize = this.contents.inputFontSize
el.style.borderWidth = this.contents.inputBorderWidth
el.style.borderStyle = this.contents.inputBorderStyle
el.style.borderColor = this.contents.inputBorderColor
el.style.borderRadius = this.contents.inputBorderRadius
el.style.backgroundColor = this.contents.inputBgColor
})
if(this.contents.inputTitle) {
document.querySelectorAll('.form-content .slt .el-form-item__label').forEach(el=>{
el.style.color = this.contents.inputTitleColor
el.style.fontSize = this.contents.inputTitleSize
el.style.lineHeight = this.contents.inputHeight
})
}
setTimeout(()=>{
document.querySelectorAll('.form-content .slt .el-input__prefix').forEach(el=>{
el.style.color = this.contents.inputIconColor
el.style.lineHeight = this.contents.inputHeight
})
document.querySelectorAll('.form-content .slt .el-input__suffix').forEach(el=>{
el.style.color = this.contents.inputIconColor
el.style.lineHeight = this.contents.inputHeight
})
document.querySelectorAll('.form-content .slt .el-input__icon').forEach(el=>{
el.style.lineHeight = this.contents.inputHeight
})
},10)
})
},
//
contentSearchBtnStyleChange() {
this.$nextTick(()=>{
document.querySelectorAll('.form-content .slt .el-button--success').forEach(el=>{
el.style.height = this.contents.searchBtnHeight
el.style.color = this.contents.searchBtnFontColor
el.style.fontSize = this.contents.searchBtnFontSize
el.style.borderWidth = this.contents.searchBtnBorderWidth
el.style.borderStyle = this.contents.searchBtnBorderStyle
el.style.borderColor = this.contents.searchBtnBorderColor
el.style.borderRadius = this.contents.searchBtnBorderRadius
el.style.backgroundColor = this.contents.searchBtnBgColor
})
})
},
// /
contentBtnAdAllStyleChange() {
this.$nextTick(()=>{
document.querySelectorAll('.form-content .ad .el-button--success').forEach(el=>{
el.style.height = this.contents.btnAdAllHeight
el.style.color = this.contents.btnAdAllAddFontColor
el.style.fontSize = this.contents.btnAdAllFontSize
el.style.borderWidth = this.contents.btnAdAllBorderWidth
el.style.borderStyle = this.contents.btnAdAllBorderStyle
el.style.borderColor = this.contents.btnAdAllBorderColor
el.style.borderRadius = this.contents.btnAdAllBorderRadius
el.style.backgroundColor = this.contents.btnAdAllAddBgColor
})
document.querySelectorAll('.form-content .ad .el-button--danger').forEach(el=>{
el.style.height = this.contents.btnAdAllHeight
el.style.color = this.contents.btnAdAllDelFontColor
el.style.fontSize = this.contents.btnAdAllFontSize
el.style.borderWidth = this.contents.btnAdAllBorderWidth
el.style.borderStyle = this.contents.btnAdAllBorderStyle
el.style.borderColor = this.contents.btnAdAllBorderColor
el.style.borderRadius = this.contents.btnAdAllBorderRadius
el.style.backgroundColor = this.contents.btnAdAllDelBgColor
})
document.querySelectorAll('.form-content .ad .el-button--warning').forEach(el=>{
el.style.height = this.contents.btnAdAllHeight
el.style.color = this.contents.btnAdAllWarnFontColor
el.style.fontSize = this.contents.btnAdAllFontSize
el.style.borderWidth = this.contents.btnAdAllBorderWidth
el.style.borderStyle = this.contents.btnAdAllBorderStyle
el.style.borderColor = this.contents.btnAdAllBorderColor
el.style.borderRadius = this.contents.btnAdAllBorderRadius
el.style.backgroundColor = this.contents.btnAdAllWarnBgColor
})
})
},
//
rowStyle({ row, rowIndex}) {
if (rowIndex % 2 == 1) {
if(this.contents.tableStripe) {
return {color:this.contents.tableStripeFontColor}
}
} else {
return ''
}
},
//
cellStyle({ row, rowIndex}){
if (rowIndex % 2 == 1) {
if(this.contents.tableStripe) {
return {backgroundColor:this.contents.tableStripeBgColor}
}
} else {
return ''
}
},
//
headerRowStyle({ row, rowIndex}){
return {color: this.contents.tableHeaderFontColor}
},
//
headerCellStyle({ row, rowIndex}){
return {backgroundColor: this.contents.tableHeaderBgColor}
},
//
contentTableBtnStyleChange(){
// ...
},
//
contentPageStyleChange(){
let arr = []
if(this.contents.pageTotal) arr.push('total')
if(this.contents.pageSizes) arr.push('sizes')
if(this.contents.pagePrevNext){
arr.push('prev')
if(this.contents.pagePager) arr.push('pager')
arr.push('next')
}
if(this.contents.pageJumper) arr.push('jumper')
this.layouts = arr.join()
this.contents.pageEachNum = 10
},
//
init () {
// ...
},
//
search() {
this.pageIndex = 1;
this.getDataList();
},
//
getDataList() {
this.dataListLoading = true;
let params = {
page: this.pageIndex,
limit: this.pageSize,
sort: 'id',
refid : this.$route.query.refid,
}
if(this.searchForm.content!='' && this.searchForm.content!=undefined){
params['content'] = '%' + this.searchForm.content + '%'
}
this.$http({
url: "discusswoyaodangfangzhu/page",
method: "get",
params: params
}).then(({ data }) => {
if (data && data.code === 0) {
this.dataList = data.data.list;
this.totalPage = data.data.total;
} else {
this.dataList = [];
this.totalPage = 0;
}
this.dataListLoading = false;
});
},
//
sizeChangeHandle(val) {
this.pageSize = val;
this.pageIndex = 1;
this.getDataList();
},
//
currentChangeHandle(val) {
this.pageIndex = val;
this.getDataList();
},
//
selectionChangeHandler(val) {
this.dataListSelections = val;
},
// /
addOrUpdateHandler(id,type) {
this.showFlag = false;
this.addOrUpdateFlag = true;
this.crossAddOrUpdateFlag = false;
if(type!='info'){
type = 'else';
}
this.$nextTick(() => {
this.$refs.addOrUpdate.init(id,type);
});
},
//
disscussListHandler(id,type) {
this.$router.push({path:'/discussdiscusswoyaodangfangzhu',query:{refid:id}});
},
//
download(file){
window.open(`${file}`)
},
//
deleteHandler(id) {
var ids = id
? [Number(id)]
: this.dataListSelections.map(item => {
return Number(item.id);
});
this.$confirm(`确定进行[${id ? "删除" : "批量删除"}]操作?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$http({
url: "discusswoyaodangfangzhu/delete",
method: "post",
data: ids
}).then(({ data }) => {
if (data && data.code === 0) {
this.$message({
message: "操作成功",
type: "success",
duration: 1500,
onClose: () => {
this.search();
}
});
} else {
this.$message.error(data.msg);
}
});
});
},
}
};
</script>
<style lang="scss" scoped>
/* 搜索区域布局 */
.slt {
margin: 0 !important;
display: flex;
}
/* 操作区域布局 */
.ad {
margin: 0 !important;
display: flex;
}
/* 分页样式 */
.pages {
& /deep/ el-pagination__sizes{
& /deep/ el-input__inner {
height: 22px;
line-height: 22px;
}
}
}
/* 按钮间距 */
.el-button+.el-button {
margin:0;
}
/* 表格按钮样式 */
.tables {
& /deep/ .el-button--success {
height: 40px;
color: #333;
font-size: 14px;
border-width: 1px;
border-style: solid;
border-color: rgba(196, 210, 244, 1);
border-radius: 22px;
background-color: rgba(171, 239, 239, 1);
}
& /deep/ .el-button--primary {
height: 40px;
color: #333;
font-size: 14px;
border-width: 1px;
border-style: solid;
border-color: rgba(196, 210, 244, 1);
border-radius: 22px;
background-color: rgba(240, 242, 124, 1);
}
& /deep/ .el-button--danger {
height: 40px;
color: #333;
font-size: 14px;
border-width: 1px;
border-style: solid;
border-color: rgba(196, 210, 244, 1);
border-radius: 22px;
background-color: rgba(244, 150, 150, 1);
}
& /deep/ .el-button {
margin: 4px;
}
}
</style>

@ -0,0 +1,309 @@
<template>
<!-- 主容器div -->
<div class="addEdit-block">
<!-- ElementUI表单组件 -->
<el-form
<!-- 表单类名 -->
class="detail-form-content"
<!-- 表单引用标识 -->
ref="ruleForm"
<!-- 数据模型绑定 -->
:model="ruleForm"
<!-- 验证规则 -->
:rules="rules"
<!-- 标签宽度 -->
label-width="80px"
<!-- 动态背景色 -->
:style="{backgroundColor:addEditForm.addEditBoxColor}"
>
<!-- ElementUI布局行 -->
<el-row>
<!-- 布局列(合同编号) -->
<el-col :span="12">
<!-- 编辑模式输入项 -->
<el-form-item class="input" v-if="type!='info'" label="合同编号" prop="hetongbianhao">
<!-- 可编辑输入框 -->
<el-input v-model="ruleForm.hetongbianhao"
placeholder="合同编号" clearable :readonly="ro.hetongbianhao"></el-input>
</el-form-item>
<!-- 查看模式展示 -->
<div v-else>
<el-form-item class="input" label="合同编号" prop="hetongbianhao">
<!-- 只读展示 -->
<el-input v-model="ruleForm.hetongbianhao"
placeholder="合同编号" readonly></el-input>
</el-form-item>
</div>
</el-col>
<!-- 房屋名称字段(结构同上) -->
<el-col :span="12">
<el-form-item class="input" v-if="type!='info'" label="房屋名称" prop="fangwumingcheng">
<el-input v-model="ruleForm.fangwumingcheng"
placeholder="房屋名称" clearable :readonly="ro.fangwumingcheng"></el-input>
</el-form-item>
<div v-else>
<el-form-item class="input" label="房屋名称" prop="fangwumingcheng">
<el-input v-model="ruleForm.fangwumingcheng"
placeholder="房屋名称" readonly></el-input>
</el-form-item>
</div>
</el-col>
<!-- 其他字段按相同结构省略... -->
<!-- 图片上传区域 -->
<el-col :span="24">
<!-- 上传控件 -->
<el-form-item class="upload" v-if="type!='info' && !ro.tupian" label="图片" prop="tupian">
<!-- 自定义上传组件 -->
<file-upload
tip="点击上传图片"
action="file/upload"
:limit="3"
:multiple="true"
:fileUrls="ruleForm.tupian?ruleForm.tupian:''"
@change="tupianUploadChange"
></file-upload>
</el-form-item>
<!-- 图片预览 -->
<div v-else>
<el-form-item v-if="ruleForm.tupian" label="图片" prop="tupian">
<!-- 循环显示图片 -->
<img style="margin-right:20px;" v-bind:key="index" v-for="(item,index) in ruleForm.tupian.split(',')"
:src="item" width="100" height="100">
</el-form-item>
</div>
</el-col>
<!-- 报修日期字段 -->
<el-col :span="12">
<el-form-item class="date" v-if="type!='info'" label="报修日期" prop="baoxiuriqi">
<!-- 日期选择器 -->
<el-date-picker
format="yyyy 年 MM 月 dd 日"
value-format="yyyy-MM-dd"
v-model="ruleForm.baoxiuriqi"
type="date"
placeholder="报修日期">
</el-date-picker>
</el-form-item>
<!-- 只读展示 -->
<div v-else>
<el-form-item class="input" v-if="ruleForm.baoxiuriqi" label="报修日期" prop="baoxiuriqi">
<el-input v-model="ruleForm.baoxiuriqi"
placeholder="报修日期" readonly></el-input>
</el-form-item>
</div>
</el-col>
<!-- 其他字段按相同结构省略... -->
</el-row>
<!-- 操作按钮组 -->
<el-form-item class="btn">
<!-- 提交按钮 -->
<el-button v-if="type!='info'" type="primary" class="btn-success" @click="onSubmit"></el-button>
<!-- 取消按钮 -->
<el-button v-if="type!='info'" class="btn-close" @click="back()"></el-button>
<!-- 返回按钮 -->
<el-button v-if="type=='info'" class="btn-close" @click="back()"></el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
//
import { isNumber,isIntNumer,isEmail,isPhone, isMobile,isURL,checkIdCard } from "@/utils/validate";
export default {
data() {
let self = this;
//
var validateIdCard = (rule, value, callback) => {
if(!value){
callback();
} else if (!checkIdCard(value)) {
callback(new Error("请输入正确的身份证号码"));
} else {
callback();
}
};
// URL
var validateUrl = (rule, value, callback) => {
if(!value){
callback();
} else if (!isURL(value)) {
callback(new Error("请输入正确的URL地址"));
} else {
callback();
}
};
//
var validateMobile = (rule, value, callback) => {
if(!value){
callback();
} else if (!isMobile(value)) {
callback(new Error("请输入正确的手机号码"));
} else {
callback();
}
};
// ...
return {
//
addEditForm: {"btnSaveFontColor":"#fff",...}, //
id: '', // ID
type: '', //
ro:{ //
hetongbianhao : false,
// ...
},
ruleForm: { //
hetongbianhao: '',
// ...
},
leixingOptions: [], //
rules: { //
hetongbianhao: [],
// ...
}
};
},
props: ["parent"], //
computed: {}, //
created() { //
this.addEditStyleChange()
this.addEditUploadStyleChange()
},
methods: {
//
download(file){
window.open(`${file}`)
},
//
init(id,type) {
if (id) {
this.id = id;
this.type = type;
}
//
if(this.type=='info'||this.type=='else'){
this.info(id);
}else if(this.type=='cross'){
//
}
//
this.$http({
url: `${this.$storage.get('sessionTable')}/session`,
method: "get"
}).then(({ data }) => {
if (data && data.code === 0) {
var json = data.data;
} else {
this.$message.error(data.msg);
}
});
//
this.leixingOptions = "水工,电工,木工".split(',')
},
//
info(id) {
this.$http({
url: `fangwubaoxiu/info/${id}`,
method: "get"
}).then(({ data }) => {
if (data && data.code === 0) {
this.ruleForm = data.data;
} else {
this.$message.error(data.msg);
}
});
},
//
onSubmit() {
this.$refs["ruleForm"].validate(valid => {
if (valid) {
this.$http({
url: `fangwubaoxiu/${!this.ruleForm.id ? "save" : "update"}`,
method: "post",
data: this.ruleForm
}).then(({ data }) => {
if (data && data.code === 0) {
this.$message({
message: "操作成功",
type: "success",
duration: 1500,
onClose: () => {
this.parent.showFlag = true;
this.parent.addOrUpdateFlag = false;
this.parent.fangwubaoxiuCrossAddOrUpdateFlag = false;
this.parent.search();
this.parent.contentStyleChange();
}
});
} else {
this.$message.error(data.msg);
}
});
}
});
},
// UUID
getUUID () {
return new Date().getTime();
},
//
back() {
this.parent.showFlag = true;
this.parent.addOrUpdateFlag = false;
this.parent.fangwubaoxiuCrossAddOrUpdateFlag = false;
this.parent.contentStyleChange();
},
//
tupianUploadChange(fileUrls) {
this.ruleForm.tupian = fileUrls;
this.addEditUploadStyleChange()
},
//
addEditStyleChange() {
this.$nextTick(() => {
// DOM
})
},
//
addEditUploadStyleChange() {
this.$nextTick(() => {
//
})
},
}
};
</script>
<style lang="scss">
.editor{
height: 500px; //
& /deep/ .ql-container {
height: 310px; //
}
}
.amap-wrapper {
width: 100%; //
height: 500px;
}
.search-box {
position: absolute; //
}
.addEdit-block {
margin: -10px; //
}
.detail-form-content {
padding: 12px; //
}
.btn .el-button {
padding: 0; //
}
</style>

@ -0,0 +1,769 @@
<template>
<div class="main-content">
<!-- 列表页 -->
<div v-if="showFlag">
<!-- 搜索框表单 -->
<el-form :inline="true" :model="searchForm" class="form-content">
<!-- 搜索框行根据配置动态调整对齐方式 -->
<el-row :gutter="20" class="slt" :style="{justifyContent:contents.searchBoxPosition=='1'?'flex-start':contents.searchBoxPosition=='2'?'center':'flex-end'}">
<!-- 房屋名称搜索框 -->
<el-form-item :label="contents.inputTitle == 1 ? '房屋名称' : ''">
<!-- 前置图标搜索框 -->
<el-input v-if="contents.inputIcon == 1 && contents.inputIconPosition == 1" prefix-icon="el-icon-search" v-model="searchForm.fangwumingcheng" placeholder="房屋名称" clearable></el-input>
<!-- 后置图标搜索框 -->
<el-input v-if="contents.inputIcon == 1 && contents.inputIconPosition == 2" suffix-icon="el-icon-search" v-model="searchForm.fangwumingcheng" placeholder="房屋名称" clearable></el-input>
<!-- 无图标搜索框 -->
<el-input v-if="contents.inputIcon == 0" v-model="searchForm.fangwumingcheng" placeholder="房屋名称" clearable></el-input>
</el-form-item>
<!-- 类型搜索框 -->
<el-form-item :label="contents.inputTitle == 1 ? '类型' : ''">
<el-input v-if="contents.inputIcon == 1 && contents.inputIconPosition == 1" prefix-icon="el-icon-search" v-model="searchForm.leixing" placeholder="类型" clearable></el-input>
<el-input v-if="contents.inputIcon == 1 && contents.inputIconPosition == 2" suffix-icon="el-icon-search" v-model="searchForm.leixing" placeholder="类型" clearable></el-input>
<el-input v-if="contents.inputIcon == 0" v-model="searchForm.leixing" placeholder="类型" clearable></el-input>
</el-form-item>
<!-- 房主姓名搜索框 -->
<el-form-item :label="contents.inputTitle == 1 ? '房主姓名' : ''">
<el-input v-if="contents.inputIcon == 1 && contents.inputIconPosition == 1" prefix-icon="el-icon-search" v-model="searchForm.fangzhuxingming" placeholder="房主姓名" clearable></el-input>
<el-input v-if="contents.inputIcon == 1 && contents.inputIconPosition == 2" suffix-icon="el-icon-search" v-model="searchForm.fangzhuxingming" placeholder="房主姓名" clearable></el-input>
<el-input v-if="contents.inputIcon == 0" v-model="searchForm.fangzhuxingming" placeholder="房主姓名" clearable></el-input>
</el-form-item>
<!-- 用户名搜索框 -->
<el-form-item :label="contents.inputTitle == 1 ? '用户名' : ''">
<el-input v-if="contents.inputIcon == 1 && contents.inputIconPosition == 1" prefix-icon="el-icon-search" v-model="searchForm.yonghuming" placeholder="用户名" clearable></el-input>
<el-input v-if="contents.inputIcon == 1 && contents.inputIconPosition == 2" suffix-icon="el-icon-search" v-model="searchForm.yonghuming" placeholder="用户名" clearable></el-input>
<el-input v-if="contents.inputIcon == 0" v-model="searchForm.yonghuming" placeholder="用户名" clearable></el-input>
</el-form-item>
<!-- 查询按钮 -->
<el-form-item>
<el-button v-if="contents.searchBtnIcon == 1 && contents.searchBtnIconPosition == 1" icon="el-icon-search" type="success" @click="search()">{{ contents.searchBtnFont == 1?'':'' }}</el-button>
<el-button v-if="contents.searchBtnIcon == 1 && contents.searchBtnIconPosition == 2" type="success" @click="search()">{{ contents.searchBtnFont == 1?'':'' }}<i class="el-icon-search el-icon--right"/></el-button>
<el-button v-if="contents.searchBtnIcon == 0" type="success" @click="search()">{{ contents.searchBtnFont == 1?'':'' }}</el-button>
</el-form-item>
</el-row>
<!-- 操作按钮行 -->
<el-row class="ad" :style="{justifyContent:contents.btnAdAllBoxPosition=='1'?'flex-start':contents.btnAdAllBoxPosition=='2'?'center':'flex-end'}">
<el-form-item>
<!-- 新增按钮 -->
<el-button
v-if="isAuth('fangwubaoxiu','新增') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 1"
type="success"
icon="el-icon-plus"
@click="addOrUpdateHandler()"
>{{ contents.btnAdAllFont == 1?'新增':'' }}</el-button>
<el-button
v-if="isAuth('fangwubaoxiu','新增') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 2"
type="success"
@click="addOrUpdateHandler()"
>{{ contents.btnAdAllFont == 1?'新增':'' }}<i class="el-icon-plus el-icon--right" /></el-button>
<el-button
v-if="isAuth('fangwubaoxiu','新增') && contents.btnAdAllIcon == 0"
type="success"
@click="addOrUpdateHandler()"
>{{ contents.btnAdAllFont == 1?'新增':'' }}</el-button>
<!-- 删除按钮 -->
<el-button
v-if="isAuth('fangwubaoxiu','删除') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 1 && contents.tableSelection"
:disabled="dataListSelections.length <= 0"
type="danger"
icon="el-icon-delete"
@click="deleteHandler()"
>{{ contents.btnAdAllFont == 1?'删除':'' }}</el-button>
<el-button
v-if="isAuth('fangwubaoxiu','删除') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 2 && contents.tableSelection"
:disabled="dataListSelections.length <= 0"
type="danger"
@click="deleteHandler()"
>{{ contents.btnAdAllFont == 1?'删除':'' }}<i class="el-icon-delete el-icon--right" /></el-button>
<el-button
v-if="isAuth('fangwubaoxiu','删除') && contents.btnAdAllIcon == 0 && contents.tableSelection"
:disabled="dataListSelections.length <= 0"
type="danger"
@click="deleteHandler()"
>{{ contents.btnAdAllFont == 1?'删除':'' }}</el-button>
</el-form-item>
</el-row>
</el-form>
<!-- 表格内容 -->
<div class="table-content">
<el-table class="tables" :size="contents.tableSize" :show-header="contents.tableShowHeader"
:header-row-style="headerRowStyle" :header-cell-style="headerCellStyle"
:border="contents.tableBorder"
:fit="contents.tableFit"
:stripe="contents.tableStripe"
:row-style="rowStyle"
:cell-style="cellStyle"
:style="{width: '100%',fontSize:contents.tableContentFontSize,color:contents.tableContentFontColor}"
v-if="isAuth('fangwubaoxiu','查看')"
:data="dataList"
v-loading="dataListLoading"
@selection-change="selectionChangeHandler">
<!-- 多选列 -->
<el-table-column v-if="contents.tableSelection"
type="selection"
header-align="center"
align="center"
width="50">
</el-table-column>
<!-- 索引列 -->
<el-table-column label="索引" v-if="contents.tableIndex" type="index" width="50" />
<!-- 合同编号列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="hetongbianhao"
header-align="center"
label="合同编号">
<template slot-scope="scope">
{{scope.row.hetongbianhao}}
</template>
</el-table-column>
<!-- 房屋名称列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="fangwumingcheng"
header-align="center"
label="房屋名称">
<template slot-scope="scope">
{{scope.row.fangwumingcheng}}
</template>
</el-table-column>
<!-- 房屋类型列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="fangwuleixing"
header-align="center"
label="房屋类型">
<template slot-scope="scope">
{{scope.row.fangwuleixing}}
</template>
</el-table-column>
<!-- 小区列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="xiaoqu"
header-align="center"
label="小区">
<template slot-scope="scope">
{{scope.row.xiaoqu}}
</template>
</el-table-column>
<!-- 报修名称列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="baoxiumingcheng"
header-align="center"
label="报修名称">
<template slot-scope="scope">
{{scope.row.baoxiumingcheng}}
</template>
</el-table-column>
<!-- 类型列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="leixing"
header-align="center"
label="类型">
<template slot-scope="scope">
{{scope.row.leixing}}
</template>
</el-table-column>
<!-- 报修内容列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="baoxiuneirong"
header-align="center"
label="报修内容">
<template slot-scope="scope">
{{scope.row.baoxiuneirong}}
</template>
</el-table-column>
<!-- 图片列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign" prop="tupian"
header-align="center"
width="200"
label="图片">
<template slot-scope="scope">
<div v-if="scope.row.tupian">
<img :src="scope.row.tupian.split(',')[0]" width="100" height="100">
</div>
<div v-else></div>
</template>
</el-table-column>
<!-- 报修日期列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="baoxiuriqi"
header-align="center"
label="报修日期">
<template slot-scope="scope">
{{scope.row.baoxiuriqi}}
</template>
</el-table-column>
<!-- 房主账号列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="fangzhuzhanghao"
header-align="center"
label="房主账号">
<template slot-scope="scope">
{{scope.row.fangzhuzhanghao}}
</template>
</el-table-column>
<!-- 房主姓名列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="fangzhuxingming"
header-align="center"
label="房主姓名">
<template slot-scope="scope">
{{scope.row.fangzhuxingming}}
</template>
</el-table-column>
<!-- 用户名列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="yonghuming"
header-align="center"
label="用户名">
<template slot-scope="scope">
{{scope.row.yonghuming}}
</template>
</el-table-column>
<!-- 联系电话列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="lianxidianhua"
header-align="center"
label="联系电话">
<template slot-scope="scope">
{{scope.row.lianxidianhua}}
</template>
</el-table-column>
<!-- 审核回复列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="shhf"
header-align="center"
label="审核回复">
</el-table-column>
<!-- 审核状态列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="sfsh"
header-align="center"
label="审核状态">
<template slot-scope="scope">
<span style="margin-right:10px">{{scope.row.sfsh=='是'?'通过':'未通过'}}</span>
</template>
</el-table-column>
<!-- 审核操作列 -->
<el-table-column v-if="isAuth('fangwubaoxiu','')"
prop="sfsh"
header-align="center"
label="审核">
<template slot-scope="scope">
<el-button type="text" icon="el-icon-edit" size="small" @click="shDialog(scope.row)"></el-button>
</template>
</el-table-column>
<!-- 操作列 -->
<el-table-column width="300" :align="contents.tableAlign"
header-align="center"
label="操作">
<template slot-scope="scope">
<!-- 详情按钮 -->
<el-button v-if="isAuth('fangwubaoxiu','查看') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 1" type="success" icon="el-icon-tickets" size="mini" @click="addOrUpdateHandler(scope.row.id,'info')">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<el-button v-if="isAuth('fangwubaoxiu','查看') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 2" type="success" size="mini" @click="addOrUpdateHandler(scope.row.id,'info')">{{ contents.tableBtnFont == 1?'':'' }}<i class="el-icon-tickets el-icon--right" /></el-button>
<el-button v-if="isAuth('fangwubaoxiu','查看') && contents.tableBtnIcon == 0" type="success" size="mini" @click="addOrUpdateHandler(scope.row.id,'info')">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<!-- 处理按钮 -->
<el-button v-if="isAuth('fangwubaoxiu','处理') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 1" type="success" icon="el-icon-tickets" size="mini" @click="weixiuchuliCrossAddOrUpdateHandler(scope.row,'cross')">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<el-button v-if="isAuth('fangwubaoxiu','处理') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 2" type="success" size="mini" @click="weixiuchuliCrossAddOrUpdateHandler(scope.row,'cross')">{{ contents.tableBtnFont == 1?'':'' }}<i class="el-icon-tickets el-icon--right" /></el-button>
<el-button v-if="isAuth('fangwubaoxiu','处理') && contents.tableBtnIcon == 0" type="success" size="mini" @click="weixiuchuliCrossAddOrUpdateHandler(scope.row,'cross')">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<!-- 修改按钮 -->
<el-button v-if="isAuth('fangwubaoxiu','修改') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 1" type="primary" icon="el-icon-edit" size="mini" @click="addOrUpdateHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<el-button v-if="isAuth('fangwubaoxiu','修改') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 2" type="primary" size="mini" @click="addOrUpdateHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}<i class="el-icon-edit el-icon--right" /></el-button>
<el-button v-if="isAuth('fangwubaoxiu','修改') && contents.tableBtnIcon == 0" type="primary" size="mini" @click="addOrUpdateHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<!-- 删除按钮 -->
<el-button v-if="isAuth('fangwubaoxiu','删除') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 1" type="danger" icon="el-icon-delete" size="mini" @click="deleteHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<el-button v-if="isAuth('fangwubaoxiu','删除') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 2" type="danger" size="mini" @click="deleteHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}<i class="el-icon-delete el-icon--right" /></el-button>
<el-button v-if="isAuth('fangwubaoxiu','删除') && contents.tableBtnIcon == 0" type="danger" size="mini" @click="deleteHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页控件 -->
<el-pagination
clsss="pages"
:layout="layouts"
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
:current-page="pageIndex"
:page-sizes="[10, 20, 50, 100]"
:page-size="Number(contents.pageEachNum)"
:total="totalPage"
:small="contents.pageStyle"
class="pagination-content"
:background="contents.pageBtnBG"
:style="{textAlign:contents.pagePosition==1?'left':contents.pagePosition==2?'center':'right'}"
></el-pagination>
</div>
</div>
<!-- 添加/修改页面 -->
<add-or-update v-if="addOrUpdateFlag" :parent="this" ref="addOrUpdate"></add-or-update>
<!-- 处理页面 -->
<weixiuchuli-cross-add-or-update v-if="weixiuchuliCrossAddOrUpdateFlag" :parent="this" ref="weixiuchuliCrossaddOrUpdate"></weixiuchuli-cross-add-or-update>
<!-- 审核对话框 -->
<el-dialog
title="审核"
:visible.sync="sfshVisiable"
width="50%">
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="审核状态">
<el-select v-model="shForm.sfsh" placeholder="审核状态">
<el-option label="通过" value="是"></el-option>
<el-option label="不通过" value="否"></el-option>
</el-select>
</el-form-item>
<el-form-item label="内容">
<el-input type="textarea" :rows="8" v-model="shForm.shhf"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="shDialog"> </el-button>
<el-button type="primary" @click="shHandler"> </el-button>
</span>
</el-dialog>
</div>
</template>
<script>
// /
import AddOrUpdate from "./add-or-update";
//
import weixiuchuliCrossAddOrUpdate from "../weixiuchuli/add-or-update";
export default {
data() {
return {
//
searchForm: {
key: ""
},
//
dataList: [],
//
pageIndex: 1,
//
pageSize: 10,
//
totalPage: 0,
//
dataListLoading: false,
//
dataListSelections: [],
//
showFlag: true,
//
sfshVisiable: false,
//
shForm: {},
//
chartVisiable: false,
// /
addOrUpdateFlag:false,
//
weixiuchuliCrossAddOrUpdateFlag: false,
//
contents:{"searchBtnFontColor":"#333","pagePosition":"1","inputFontSize":"14px","inputBorderRadius":"22px","tableBtnDelFontColor":"#333","tableBtnIconPosition":"1","searchBtnHeight":"40px","inputIconColor":"rgba(66, 130, 129, 1)","searchBtnBorderRadius":"22px","tableStripe":false,"btnAdAllWarnFontColor":"#333","tableBtnDelBgColor":"rgba(244, 150, 150, 1)","searchBtnIcon":"1","tableSize":"medium","searchBtnBorderStyle":"solid","tableSelection":true,"searchBtnBorderWidth":"1px","tableContentFontSize":"14px","searchBtnBgColor":"rgba(153, 239, 237, 1)","inputTitleSize":"14px","btnAdAllBorderColor":"#DCDFE6","pageJumper":true,"btnAdAllIconPosition":"1","searchBoxPosition":"1","tableBtnDetailFontColor":"#333","tableBtnHeight":"40px","pagePager":true,"searchBtnBorderColor":"#DCDFE6","tableHeaderFontColor":"rgba(33, 34, 35, 1)","inputTitle":"1","tableBtnBorderRadius":"22px","btnAdAllFont":"1","btnAdAllDelFontColor":"rgba(21, 20, 20, 1)","tableBtnIcon":"1","btnAdAllHeight":"40px","btnAdAllWarnBgColor":"rgba(238, 236, 126, 1)","btnAdAllBorderWidth":"1px","tableStripeFontColor":"#606266","tableBtnBorderStyle":"solid","inputHeight":"40px","btnAdAllBorderRadius":"22px","btnAdAllDelBgColor":"rgba(234, 93, 93, 0.69)","pagePrevNext":true,"btnAdAllAddBgColor":"rgba(153, 239, 237, 1)","searchBtnFont":"1","tableIndex":true,"btnAdAllIcon":"1","tableSortable":true,"pageSizes":true,"tableFit":true,"pageBtnBG":true,"searchBtnFontSize":"14px","tableBtnEditBgColor":"rgba(240, 242, 124, 1)","inputBorderWidth":"1px","inputFontPosition":"1","inputFontColor":"#333","pageEachNum":10,"tableHeaderBgColor":"rgba(152, 129, 129, 1)","inputTitleColor":"#333","btnAdAllBoxPosition":"1","tableBtnDetailBgColor":"rgba(171, 239, 239, 1)","inputIcon":"0","searchBtnIconPosition":"1","btnAdAllFontSize":"14px","inputBorderStyle":"solid","inputBgColor":"rgba(197, 174, 174, 0.32)","pageStyle":false,"pageTotal":true,"btnAdAllAddFontColor":"#333","tableBtnFont":"1","tableContentFontColor":"rgba(22, 22, 23, 1)","inputBorderColor":"rgba(152, 129, 129, 1)","tableShowHeader":true,"tableBtnFontSize":"14px","tableBtnBorderColor":"rgba(196, 210, 244, 1)","inputIconPosition":"1","tableBorder":true,"btnAdAllBorderStyle":"solid","tableBtnBorderWidth":"1px","tableStripeBgColor":"rgba(213, 197, 197, 1)","tableBtnEditFontColor":"#333","tableAlign":"center"},
//
layouts: '',
};
},
//
created() {
this.init();
this.getDataList();
this.contentStyleChange()
},
//
mounted() {
},
//
filters: {
// HTML
htmlfilter: function (val) {
return val.replace(/<[^>]*>/g).replace(/undefined/g,'');
}
},
//
components: {
AddOrUpdate,
weixiuchuliCrossAddOrUpdate,
},
//
methods: {
//
contentStyleChange() {
this.contentSearchStyleChange()
this.contentBtnAdAllStyleChange()
this.contentSearchBtnStyleChange()
this.contentTableBtnStyleChange()
this.contentPageStyleChange()
},
//
contentSearchStyleChange() {
this.$nextTick(()=> {
document.querySelectorAll('.form-content .slt .el-input__inner').forEach(el => {
let textAlign = 'left'
if(this.contents.inputFontPosition == 2) textAlign = 'center'
if(this.contents.inputFontPosition == 3) textAlign = 'right'
el.style.textAlign = textAlign
el.style.height = this.contents.inputHeight
el.style.lineHeight = this.contents.inputHeight
el.style.color = this.contents.inputFontColor
el.style.fontSize = this.contents.inputFontSize
el.style.borderWidth = this.contents.inputBorderWidth
el.style.borderStyle = this.contents.inputBorderStyle
el.style.borderColor = this.contents.inputBorderColor
el.style.borderRadius = this.contents.inputBorderRadius
el.style.backgroundColor = this.contents.inputBgColor
})
if(this.contents.inputTitle) {
document.querySelectorAll('.form-content .slt .el-form-item__label').forEach(el => {
el.style.color = this.contents.inputTitleColor
el.style.fontSize = this.contents.inputTitleSize
el.style.lineHeight = this.contents.inputHeight
})
}
setTimeout(() => {
document.querySelectorAll('.form-content .slt .el-input__prefix').forEach(el => {
el.style.color = this.contents.inputIconColor
el.style.lineHeight = this.contents.inputHeight
})
document.querySelectorAll('.form-content .slt .el-input__suffix').forEach(el => {
el.style.color = this.contents.inputIconColor
el.style.lineHeight = this.contents.inputHeight
})
document.querySelectorAll('.form-content .slt .el-input__icon').forEach(el => {
el.style.lineHeight = this.contents.inputHeight
})
},10)
})
},
//
contentSearchBtnStyleChange() {
this.$nextTick(() => {
document.querySelectorAll('.form-content .slt .el-button--success').forEach(el => {
el.style.height = this.contents.searchBtnHeight
el.style.color = this.contents.searchBtnFontColor
el.style.fontSize = this.contents.searchBtnFontSize
el.style.borderWidth = this.contents.searchBtnBorderWidth
el.style.borderStyle = this.contents.searchBtnBorderStyle
el.style.borderColor = this.contents.searchBtnBorderColor
el.style.borderRadius = this.contents.searchBtnBorderRadius
el.style.backgroundColor = this.contents.searchBtnBgColor
})
})
},
//
contentBtnAdAllStyleChange() {
this.$nextTick(() => {
document.querySelectorAll('.form-content .ad .el-button--success').forEach(el => {
el.style.height = this.contents.btnAdAllHeight
el.style.color = this.contents.btnAdAllAddFontColor
el.style.fontSize = this.contents.btnAdAllFontSize
el.style.borderWidth = this.contents.btnAdAllBorderWidth
el.style.borderStyle = this.contents.btnAdAllBorderStyle
el.style.borderColor = this.contents.btnAdAllBorderColor
el.style.borderRadius = this.contents.btnAdAllBorderRadius
el.style.backgroundColor = this.contents.btnAdAllAddBgColor
})
document.querySelectorAll('.form-content .ad .el-button--danger').forEach(el => {
el.style.height = this.contents.btnAdAllHeight
el.style.color = this.contents.btnAdAllDelFontColor
el.style.fontSize = this.contents.btnAdAllFontSize
el.style.borderWidth = this.contents.btnAdAllBorderWidth
el.style.borderStyle = this.contents.btnAdAllBorderStyle
el.style.borderColor = this.contents.btnAdAllBorderColor
el.style.borderRadius = this.contents.btnAdAllBorderRadius
el.style.backgroundColor = this.contents.btnAdAllDelBgColor
})
document.querySelectorAll('.form-content .ad .el-button--warning').forEach(el => {
el.style.height = this.contents.btnAdAllHeight
el.style.color = this.contents.btnAdAllWarnFontColor
el.style.fontSize = this.contents.btnAdAllFontSize
el.style.borderWidth = this.contents.btnAdAllBorderWidth
el.style.borderStyle = this.contents.btnAdAllBorderStyle
el.style.borderColor = this.contents.btnAdAllBorderColor
el.style.borderRadius = this.contents.btnAdAllBorderRadius
el.style.backgroundColor = this.contents.btnAdAllWarnBgColor
})
})
},
//
rowStyle({ row, rowIndex}) {
if (rowIndex % 2 == 1) {
if(this.contents.tableStripe) {
return {color:this.contents.tableStripeFontColor}
}
} else {
return ''
}
},
//
cellStyle({ row, rowIndex}) {
if (rowIndex % 2 == 1) {
if(this.contents.tableStripe) {
return {backgroundColor:this.contents.tableStripeBgColor}
}
} else {
return ''
}
},
//
headerRowStyle({ row, rowIndex}) {
return {color: this.contents.tableHeaderFontColor}
},
//
headerCellStyle({ row, rowIndex}) {
return {backgroundColor: this.contents.tableHeaderBgColor}
},
//
contentTableBtnStyleChange(){
//
},
//
contentPageStyleChange(){
let arr = []
if(this.contents.pageTotal) arr.push('total')
if(this.contents.pageSizes) arr.push('sizes')
if(this.contents.pagePrevNext){
arr.push('prev')
if(this.contents.pagePager) arr.push('pager')
arr.push('next')
}
if(this.contents.pageJumper) arr.push('jumper')
this.layouts = arr.join()
this.contents.pageEachNum = 10
},
//
weixiuchuliCrossAddOrUpdateHandler(row,type){
this.showFlag = false;
this.addOrUpdateFlag = false;
this.weixiuchuliCrossAddOrUpdateFlag = true;
this.$storage.set('crossObj',row);
this.$storage.set('crossTable','fangwubaoxiu');
this.$nextTick(() => {
this.$refs.weixiuchuliCrossaddOrUpdate.init(row.id,type);
});
},
//
init () {
//
this.leixingOptions = "水工,电工,木工".split(',')
},
//
search() {
this.pageIndex = 1;
this.getDataList();
},
//
getDataList() {
this.dataListLoading = true;
let params = {
page: this.pageIndex,
limit: this.pageSize,
sort: 'id',
}
//
if(this.searchForm.fangwumingcheng!='' && this.searchForm.fangwumingcheng!=undefined){
params['fangwumingcheng'] = '%' + this.searchForm.fangwumingcheng + '%'
}
if(this.searchForm.leixing!='' && this.searchForm.leixing!=undefined){
params['leixing'] = '%' + this.searchForm.leixing + '%'
}
if(this.searchForm.fangzhuxingming!='' && this.searchForm.fangzhuxingming!=undefined){
params['fangzhuxingming'] = '%' + this.searchForm.fangzhuxingming + '%'
}
if(this.searchForm.yonghuming!='' && this.searchForm.yonghuming!=undefined){
params['yonghuming'] = '%' + this.searchForm.yonghuming + '%'
}
//
this.$http({
url: "fangwubaoxiu/page",
method: "get",
params: params
}).then(({ data }) => {
if (data && data.code === 0) {
this.dataList = data.data.list;
this.totalPage = data.data.total;
} else {
this.dataList = [];
this.totalPage = 0;
}
this.dataListLoading = false;
});
},
//
sizeChangeHandle(val) {
this.pageSize = val;
this.pageIndex = 1;
this.getDataList();
},
//
currentChangeHandle(val) {
this.pageIndex = val;
this.getDataList();
},
//
selectionChangeHandler(val) {
this.dataListSelections = val;
},
// /
addOrUpdateHandler(id,type) {
this.showFlag = false;
this.addOrUpdateFlag = true;
this.crossAddOrUpdateFlag = false;
if(type!='info'){
type = 'else';
}
this.$nextTick(() => {
this.$refs.addOrUpdate.init(id,type);
});
},
// /
shDialog(row){
this.sfshVisiable = !this.sfshVisiable;
if(row){
this.shForm = {
hetongbianhao: row.hetongbianhao,
fangwumingcheng: row.fangwumingcheng,
fangwuleixing: row.fangwuleixing,
xiaoqu: row.xiaoqu,
baoxiumingcheng: row.baoxiumingcheng,
leixing: row.leixing,
baoxiuneirong: row.baoxiuneirong,
tupian: row.tupian,
baoxiuriqi: row.baoxiuriqi,
fangzhuzhanghao: row.fangzhuzhanghao,
fangzhuxingming: row.fangzhuxingming,
yonghuming: row.yonghuming,
lianxidianhua: row.lianxidianhua,
sfsh: row.sfsh,
shhf: row.shhf,
id: row.id
}
}
},
//
shHandler(){
this.$confirm(`确定操作?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$http({
url: "fangwubaoxiu/update",
method: "post",
data: this.shForm
}).then(({ data }) => {
if (data && data.code === 0) {
this.$message({
message: "操作成功",
type: "success",
duration: 1500,
onClose: () => {
this.getDataList();
this.shDialog()
}
});
} else {
this.$message.error(data.msg);
}
});
});
},
//
download(file){
window.open(`${file}`)
},
//
deleteHandler(id) {
var ids = id
? [Number(id)]
: this.dataListSelections.map(item => {
return Number(item.id);
});
this.$confirm(`确定进行[${id ? "删除" : "批量删除"}]操作?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$http({
url: "fangwubaoxiu/delete",
method: "post",
data: ids
}).then(({ data }) => {
if (data && data.code === 0) {
this.$message({
message: "操作成功",
type: "success",
duration: 1500,
onClose: () => {
this.search();
}
});
} else {
this.$message.error(data.msg);
}
});
});
}
}
};
</script>
<style lang="scss" scoped>
//
.slt {
margin: 0 !important;
display: flex;
}
//
.ad {
margin: 0 !important;
display: flex;
}
//
.pages {
& /deep/ .el-pagination__sizes{
& /deep/ .el-input__inner {
height: 22px;
line-height: 22px;
}
}
}
//
.el-button+.el-button {
margin:0;
}
//
.tables {
& /deep/ .el-button--success {
height: 40px;
color: #333;
font-size: 14px;
border-width: 1px;
border-style: solid;
border-color: rgba(196, 210, 244, 1);
border-radius: 22px;
background-color: rgba(171, 239, 239, 1);
}
& /deep/ .el-button--primary {
height: 40px;
color: #333;
font-size: 14px;
border-width: 1px;
border-style: solid;
border-color: rgba(196, 210, 244, 1);
border-radius: 22px;
background-color: rgba(240, 242, 124, 1);
}
& /deep/ .el-button--danger {
height: 40px;
color: #333;
font-size: 14px;
border-width: 1px;
border-style: solid;
border-color: rgba(196, 210, 244, 1);
border-radius: 22px;
background-color: rgba(244, 150, 150, 1);
}
& /deep/ .el-button {
margin: 4px;
}
}
</style>

@ -0,0 +1,585 @@
<template>
<!-- 添加/编辑表单容器 -->
<div class="addEdit-block">
<!-- 表单组件 -->
<el-form
class="detail-form-content"
ref="ruleForm"
:model="ruleForm"
:rules="rules"
label-width="80px"
:style="{backgroundColor:addEditForm.addEditBoxColor}" <!-- 设置表单背景颜色 -->
>
<el-row> <!-- 表单布局行 -->
<el-col :span="12"> <!-- 左侧列宽度为12 -->
<el-form-item class="input" v-if="type!='info'" label="合同编号" prop="hetongbianhao"> <!-- -->
<el-input v-model="ruleForm.hetongbianhao"
placeholder="合同编号" clearable :readonly="ro.hetongbianhao"></el-input>
</el-form-item>
<div v-else> <!-- -->
<el-form-item class="input" label="合同编号" prop="hetongbianhao">
<el-input v-model="ruleForm.hetongbianhao"
placeholder="合同编号" readonly></el-input>
</el-form-item>
</div>
</el-col>
<el-col :span="12"> <!-- 右侧列宽度为12 -->
<el-form-item class="input" v-if="type!='info'" label="房屋名称" prop="fangwumingcheng"> <!-- -->
<el-input v-model="ruleForm.fangwumingcheng"
placeholder="房屋名称" clearable :readonly="ro.fangwumingcheng"></el-input>
</el-form-item>
<div v-else> <!-- -->
<el-form-item class="input" label="房屋名称" prop="fangwumingcheng">
<el-input v-model="ruleForm.fangwumingcheng"
placeholder="房屋名称" readonly></el-input>
</el-form-item>
</div>
</el-col>
<el-col :span="12"> <!-- 左侧列宽度为12 -->
<el-form-item class="input" v-if="type!='info'" label="房屋类型" prop="fangwuleixing"> <!-- -->
<el-input v-model="ruleForm.fangwuleixing"
placeholder="房屋类型" clearable :readonly="ro.fangwuleixing"></el-input>
</el-form-item>
<div v-else> <!-- -->
<el-form-item class="input" label="房屋类型" prop="fangwuleixing">
<el-input v-model="ruleForm.fangwuleixing"
placeholder="房屋类型" readonly></el-input>
</el-form-item>
</div>
</el-col>
<el-col :span="12"> <!-- 右侧列宽度为12 -->
<el-form-item class="input" v-if="type!='info'" label="小区" prop="xiaoqu"> <!-- -->
<el-input v-model="ruleForm.xiaoqu"
placeholder="小区" clearable :readonly="ro.xiaoqu"></el-input>
</el-form-item>
<div v-else> <!-- -->
<el-form-item class="input" label="小区" prop="xiaoqu">
<el-input v-model="ruleForm.xiaoqu"
placeholder="小区" readonly></el-input>
</el-form-item>
</div>
</el-col>
<el-col :span="12"> <!-- 左侧列宽度为12 -->
<el-form-item class="select" v-if="type!='info'" label="评分" prop="pingfen"> <!-- -->
<el-select v-model="ruleForm.pingfen" placeholder="请选择评分">
<el-option
v-for="(item,index) in pingfenOptions"
v-bind:key="index"
:label="item"
:value="item">
</el-option>
</el-select>
</el-form-item>
<div v-else> <!-- -->
<el-form-item class="input" label="评分" prop="pingfen">
<el-input v-model="ruleForm.pingfen"
placeholder="评分" readonly></el-input>
</el-form-item>
</div>
</el-col>
<el-col :span="12"> <!-- 右侧列宽度为12 -->
<el-form-item class="date" v-if="type!='info'" label="评价日期" prop="pingjiariqi"> <!-- -->
<el-date-picker
format="yyyy 年 MM 月 dd 日"
value-format="yyyy-MM-dd"
v-model="ruleForm.pingjiariqi"
type="date"
placeholder="评价日期">
</el-date-picker>
</el-form-item>
<div v-else> <!-- -->
<el-form-item class="input" v-if="ruleForm.pingjiariqi" label="评价日期" prop="pingjiariqi">
<el-input v-model="ruleForm.pingjiariqi"
placeholder="评价日期" readonly></el-input>
</el-form-item>
</div>
</el-col>
<el-col :span="12"> <!-- 左侧列宽度为12 -->
<el-form-item class="input" v-if="type!='info'" label="房主账号" prop="fangzhuzhanghao"> <!-- -->
<el-input v-model="ruleForm.fangzhuzhanghao"
placeholder="房主账号" clearable :readonly="ro.fangzhuzhanghao"></el-input>
</el-form-item>
<div v-else> <!-- -->
<el-form-item class="input" label="房主账号" prop="fangzhuzhanghao">
<el-input v-model="ruleForm.fangzhuzhanghao"
placeholder="房主账号" readonly></el-input>
</el-form-item>
</div>
</el-col>
<el-col :span="12"> <!-- 右侧列宽度为12 -->
<el-form-item class="input" v-if="type!='info'" label="用户名" prop="yonghuming"> <!-- -->
<el-input v-model="ruleForm.yonghuming"
placeholder="用户名" clearable :readonly="ro.yonghuming"></el-input>
</el-form-item>
<div v-else> <!-- -->
<el-form-item class="input" label="用户名" prop="yonghuming">
<el-input v-model="ruleForm.yonghuming"
placeholder="用户名" readonly></el-input>
</el-form-item>
</div>
</el-col>
<el-col :span="12"> <!-- 左侧列宽度为12 -->
<el-form-item class="input" v-if="type!='info'" label="联系电话" prop="lianxidianhua"> <!-- -->
<el-input v-model="ruleForm.lianxidianhua"
placeholder="联系电话" clearable :readonly="ro.lianxidianhua"></el-input>
</el-form-item>
<div v-else> <!-- -->
<el-form-item class="input" label="联系电话" prop="lianxidianhua">
<el-input v-model="ruleForm.lianxidianhua"
placeholder="联系电话" readonly></el-input>
</el-form-item>
</div>
</el-col>
</el-row>
<el-row> <!-- 新的表单布局行 -->
<el-col :span="24"> <!-- 占满整行 -->
<el-form-item class="textarea" v-if="type!='info'" label="评价内容" prop="pingjianeirong"> <!-- -->
<el-input
style="min-width: 200px; max-width: 600px;" <!-- 设置文本框宽度范围 -->
type="textarea"
:rows="8" <!-- 设置文本框行数 -->
placeholder="评价内容"
v-model="ruleForm.pingjianeirong" >
</el-input>
</el-form-item>
<div v-else> <!-- -->
<el-form-item v-if="ruleForm.pingjianeirong" label="评价内容" prop="pingjianeirong">
<span>{{ruleForm.pingjianeirong}}</span>
</el-form-item>
</div>
</el-col>
</el-row>
<el-form-item class="btn"> <!-- 按钮容器 -->
<el-button v-if="type!='info'" type="primary" class="btn-success" @click="onSubmit"></el-button> <!-- 提交按钮 -->
<el-button v-if="type!='info'" class="btn-close" @click="back()"></el-button> <!-- 取消按钮 -->
<el-button v-if="type=='info'" class="btn-close" @click="back()"></el-button> <!-- 返回按钮 -->
</el-form-item>
</el-form>
</div>
</template>
<script>
//
import { isNumber,isIntNumer,isEmail,isPhone, isMobile,isURL,checkIdCard } from "@/utils/validate";
export default {
data() {
let self = this
//
var validateIdCard = (rule, value, callback) => {
if(!value){
callback();
} else if (!checkIdCard(value)) {
callback(new Error("请输入正确的身份证号码"));
} else {
callback();
}
};
// URL
var validateUrl = (rule, value, callback) => {
if(!value){
callback();
} else if (!isURL(value)) {
callback(new Error("请输入正确的URL地址"));
} else {
callback();
}
};
//
var validateMobile = (rule, value, callback) => {
if(!value){
callback();
} else if (!isMobile(value)) {
callback(new Error("请输入正确的手机号码"));
} else {
callback();
}
};
//
var validatePhone = (rule, value, callback) => {
if(!value){
callback();
} else if (!isPhone(value)) {
callback(new Error("请输入正确的电话号码"));
} else {
callback();
}
};
//
var validateEmail = (rule, value, callback) => {
if(!value){
callback();
} else if (!isEmail(value)) {
callback(new Error("请输入正确的邮箱地址"));
} else {
callback();
}
};
//
var validateNumber = (rule, value, callback) => {
if(!value){
callback();
} else if (!isNumber(value)) {
callback(new Error("请输入数字"));
} else {
callback();
}
};
//
var validateIntNumber = (rule, value, callback) => {
if(!value){
callback();
} else if (!isIntNumer(value)) {
callback(new Error("请输入整数"));
} else {
callback();
}
};
return {
//
addEditForm: { /* 样式配置参数 */ },
id: '',
type: '',
ro:{
//
hetongbianhao : false,
fangwumingcheng : false,
fangwuleixing : false,
xiaoqu : false,
pingfen : false,
pingjianeirong : false,
pingjiariqi : false,
fangzhuzhanghao : false,
yonghuming : false,
.lianxidianhua : false,
sfsh : false,
shhf : false,
},
//
ruleForm: {
hetongbianhao: '',
fangwumingcheng: '',
fangwuleixing: '',
xiaoqu: '',
pingfen: '',
pingjianeirong: '',
pingjiariqi: '',
fangzhuzhanghao: '',
yonghuming: '',
lianxidianhua: '',
shhf: '',
},
//
pingfenOptions: [],
//
rules: {
hetongbianhao: [
],
fangwumingcheng: [
],
fangwuleixing: [
],
xiaoqu: [
],
pingfen: [
],
pingjianeirong: [
],
pingjiariqi: [
],
fangzhuzhanghao: [
],
yonghuming: [
],
lianxidianhua: [
],
sfsh: [
],
shhf: [
],
}
};
},
props: ["parent"], //
computed: {
},
created() {
this.addEditStyleChange() //
this.addEditUploadStyleChange() //
},
methods: {
//
download(file){
window.open(`${file}`)
},
//
init(id,type) {
if (id) {
this.id = id; // ID
this.type = type; //
}
if(this.type=='info'||this.type=='else'){ //
this.info(id); //
}else if(this.type=='cross'){ //
var obj = this.$storage.getObj('crossObj'); //
for (var o in obj){ //
if(o=='hetongbianhao'){
this.ruleForm.hetongbianhao = obj[o]; //
this.ro.hetongbianhao = true; //
continue;
}
if(o=='fangwumingcheng'){
this.ruleForm.fangwumingcheng = obj[o]; //
this.ro.fangwumingcheng = true; //
continue;
}
if(o=='fangwuleixing'){
this.ruleForm.fangwuleixing = obj[o]; //
this.ro.fangwuleixing = true; //
continue;
}
if(o=='xiaoqu'){
this.ruleForm.xiaoqu = obj[o]; //
this.ro.xiaoqu = true; //
continue;
}
if(o=='pingfen'){
this.ruleForm.pingfen = obj[o]; //
this.ro.pingfen = true; //
continue;
}
if(o=='pingjianeirong'){
this.ruleForm.pingjianeirong = obj[o]; //
this.ro.pingjianeirong = true; //
continue;
}
if(o=='pingjiariqi'){
this.ruleForm.pingjiariqi = obj[o]; //
this.ro.pingjiariqi = true; //
continue;
}
if(o=='fangzhuzhanghao'){
this.ruleForm.fangzhuzhanghao = obj[o]; //
this.ro.fangzhuzhanghao = true; //
continue;
}
if(o=='yonghuming'){
this.ruleForm.yonghuming = obj[o]; //
this.ro.yonghuming = true; //
continue;
}
if(o=='lianxidianhua'){
this.ruleForm.lianxidianhua = obj[o]; //
this.ro.lianxidianhua = true; //
continue;
}
}
}
//
this.$http({
url: `${this.$storage.get('sessionTable')}/session`,
method: "get"
}).then(({ data }) => {
if (data && data.code === 0) {
var json = data.data;
} else {
this.$message.error(data.msg); //
}
});
this.pingfenOptions = "1,2,3,4,5".split(','); //
},
//
info(id) {
this.$http({
url: `fangwupingjia/info/${id}`, //
method: "get"
}).then(({ data }) => {
if (data && data.code === 0) {
this.ruleForm = data.data; //
} else {
this.$message.error(data.msg); //
}
});
},
//
onSubmit() {
//
this.$refs["ruleForm"].validate(valid => {
if (valid) {
this.$http({
url: `fangwupingjia/${!this.ruleForm.id ? "save" : "update"}`, //
method: "post",
data: this.ruleForm
}).then(({ data }) => {
if (data && data.code === 0) {
this.$message({
message: "操作成功", //
type: "success",
duration: 1500,
onClose: () => {
this.parent.showFlag = true; //
this.parent.addOrUpdateFlag = false; //
this.parent.fangwupingjiaCrossAddOrUpdateFlag = false; //
this.parent.search(); //
this.parent.contentStyleChange(); //
}
});
} else {
this.$message.error(data.msg); //
}
});
}
});
},
//
getUUID () {
return new Date().getTime();
},
//
back() {
this.parent.showFlag = true; //
this.parent.addOrUpdateFlag = false; //
this.parent.fangwupingjiaCrossAddOrUpdateFlag = false; //
this.parent.contentStyleChange(); //
},
addEditStyleChange() { //
this.$nextTick(()=>{ // DOM
// input
document.querySelectorAll('.addEdit-block .input .el-input__inner').forEach(el=>{
el.style.height = this.addEditForm.inputHeight;
el.style.color = this.addEditForm.inputFontColor;
el.style.fontSize = this.addEditForm.inputFontSize;
el.style.borderWidth = this.addEditForm.inputBorderWidth;
el.style.borderStyle = this.addEditForm.inputBorderStyle;
el.style.borderColor = this.addEditForm.inputBorderColor;
el.style.borderRadius = this.addEditForm.inputBorderRadius;
el.style.backgroundColor = this.addEditForm.inputBgColor;
});
document.querySelectorAll('.addEdit-block .input .el-form-item__label').forEach(el=>{
el.style.lineHeight = this.addEditForm.inputHeight;
el.style.color = this.addEditForm.inputLableColor;
el.style.fontSize = this.addEditForm.inputLableFontSize;
});
// select
document.querySelectorAll('.addEdit-block .select .el-input__inner').forEach(el=>{
el.style.height = this.addEditForm.selectHeight;
el.style.color = this.addEditForm.selectFontColor;
el.style.fontSize = this.addEditForm.selectFontSize;
el.style.borderWidth = this.addEditForm.selectBorderWidth;
el.style.borderStyle = this.addEditForm.selectBorderStyle;
el.style.borderColor = this.addEditForm.selectBorderColor;
el.style.borderRadius = this.addEditForm.selectBorderRadius;
el.style.backgroundColor = this.addEditForm.selectBgColor;
});
document.querySelectorAll('.addEdit-block .select .el-form-item__label').forEach(el=>{
el.style.lineHeight = this.addEditForm.selectHeight;
el.style.color = this.addEditForm.selectLableColor;
el.style.fontSize = this.addEditForm.selectLableFontSize;
});
document.querySelectorAll('.addEdit-block .select .el-select__caret').forEach(el=>{
el.style.color = this.addEditForm.selectIconFontColor;
el.style.fontSize = this.addEditForm.selectIconFontSize;
});
// date
document.querySelectorAll('.addEdit-block .date .el-input__inner').forEach(el=>{
el.style.height = this.addEditForm.dateHeight;
el.style.color = this.addEditForm.dateFontColor;
el.style.fontSize = this.addEditForm.dateFontSize;
el.style.borderWidth = this.addEditForm.dateBorderWidth;
el.style.borderStyle = this.addEditForm.dateBorderStyle;
el.style.borderColor = this.addEditForm.dateBorderColor;
el.style.borderRadius = this.addEditForm.dateBorderRadius;
el.style.backgroundColor = this.addEditForm.dateBgColor;
});
document.querySelectorAll('.addEdit-block .date .el-form-item__label').forEach(el=>{
el.style.lineHeight = this.addEditForm.dateHeight;
el.style.color = this.addEditForm.dateLableColor;
el.style.fontSize = this.addEditForm.dateLableFontSize;
});
document.querySelectorAll('.addEdit-block .date .el-input__icon').forEach(el=>{
el.style.color = this.addEditForm.dateIconFontColor;
el.style.fontSize = this.addEditForm.dateIconFontSize;
el.style.lineHeight = this.addEditForm.dateHeight;
});
// textarea
document.querySelectorAll('.addEdit-block .textarea .el-textarea__inner').forEach(el=>{
el.style.height = this.addEditForm.textareaHeight;
el.style.color = this.addEditForm.textareaFontColor;
el.style.fontSize = this.addEditForm.textareaFontSize;
el.style.borderWidth = this.addEditForm.textareaBorderWidth;
el.style.borderStyle = this.addEditForm.textareaBorderStyle;
el.style.borderColor = this.addEditForm.textareaBorderColor;
el.style.borderRadius = this.addEditForm.textareaBorderRadius;
el.style.backgroundColor = this.addEditForm.textareaBgColor;
});
document.querySelectorAll('.addEdit-block .textarea .el-form-item__label').forEach(el=>{
el.style.color = this.addEditForm.textareaLableColor;
el.style.fontSize = this.addEditForm.textareaLableFontSize;
});
//
document.querySelectorAll('.addEdit-block .btn .btn-success').forEach(el=>{
el.style.width = this.addEditForm.btnSaveWidth;
el.style.height = this.addEditForm.btnSaveHeight;
el.style.color = this.addEditForm.btnSaveFontColor;
el.style.fontSize = this.addEditForm.btnSaveFontSize;
el.style.borderWidth = this.addEditForm.btnSaveBorderWidth;
el.style.borderStyle = this.addEditForm.btnSaveBorderStyle;
el.style.borderColor = this.addEditForm.btnSaveBorderColor;
el.style.borderRadius = this.addEditForm.btnSaveBorderRadius;
el.style.backgroundColor = this.addEditForm.btnSaveBgColor;
});
document.querySelectorAll('.addEdit-block .btn .btn-close').forEach(el=>{
el.style.width = this.addEditForm.btnCancelWidth;
el.style.height = this.addEditForm.btnCancelHeight;
el.style.color = this.addEditForm.btnCancelFontColor;
el.style.fontSize = this.addEditForm.btnCancelFontSize;
el.style.borderWidth = this.addEditForm.btnCancelBorderWidth;
el.style.borderStyle = this.addEditForm.btnCancelBorderStyle;
el.style.borderColor = this.addEditForm.btnCancelBorderColor;
el.style.borderRadius = this.addEditForm.btnCancelBorderRadius;
el.style.backgroundColor = this.addEditForm.btnCancelBgColor;
});
});
},
addEditUploadStyleChange() { //
this.$nextTick(()=>{ // DOM
document.querySelectorAll('.addEdit-block .upload .el-upload-list--picture-card .el-upload-list__item').forEach(el=>{
el.style.width = this.addEditForm.uploadHeight;
el.style.height = this.addEditForm.uploadHeight;
el.style.borderWidth = this.addEditForm.uploadBorderWidth;
el.style.borderStyle = this.addEditForm.uploadBorderStyle;
el.style.borderColor = this.addEditForm.uploadBorderColor;
el.style.borderRadius = this.addEditForm.uploadBorderRadius;
el.style.backgroundColor = this.addEditForm.uploadBgColor;
});
});
},
}
};
</script>
<style lang="scss">
.editor{
height: 500px; <!-- 编辑器高度 -->
& /deep/ .ql-container { <!-- 编辑器内容区域 -->
height: 310px; <!-- 设置内容区域高度 -->
}
}
.amap-wrapper { <!-- 地图容器 -->
width: 100%; <!-- 宽度为100% -->
height: 500px; <!-- 高度为500px -->
}
.search-box { <!-- 搜索按钮容器 -->
position: absolute; <!-- 绝对定位 -->
}
.addEdit-block { <!-- 表单容器 -->
margin: -10px; <!-- 外边距 -->
}
.detail-form-content { <!-- 表单内容 -->
padding: 12px; <!-- 内边距 -->
}
.btn .el-button { <!-- 按钮样式 -->
padding: 0; <!-- 无内边距 -->
}
</style>

@ -0,0 +1,813 @@
<template>
<!-- 主内容区域 -->
<div class="main-content">
<!-- 列表页显示区域 -->
<div v-if="showFlag">
<!-- 搜索框表单 -->
<el-form :inline="true" :model="searchForm" class="form-content">
<!-- 搜索框布局行 -->
<el-row :gutter="20" class="slt" :style="{justifyContent:contents.searchBoxPosition=='1'?'flex-start':contents.searchBoxPosition=='2'?'center':'flex-end'}">
<!-- 房屋名称搜索框 -->
<el-form-item :label="contents.inputTitle == 1 ? '房屋名称' : ''">
<!-- 前缀图标搜索框 -->
<el-input v-if="contents.inputIcon == 1 && contents.inputIconPosition == 1" prefix-icon="el-icon-search" v-model="searchForm.fangwumingcheng" placeholder="房屋名称" clearable></el-input>
<!-- 后缀图标搜索框 -->
<el-input v-if="contents.inputIcon == 1 && contents.inputIconPosition == 2" suffix-icon="el-icon-search" v-model="searchForm.fangwumingcheng" placeholder="房屋名称" clearable></el-input>
<!-- 无图标搜索框 -->
<el-input v-if="contents.inputIcon == 0" v-model="searchForm.fangwumingcheng" placeholder="房屋名称" clearable></el-input>
</el-form-item>
<!-- 评分搜索框 -->
<el-form-item :label="contents.inputTitle == 1 ? '评分' : ''">
<!-- 前缀图标搜索框 -->
<el-input v-if="contents.inputIcon == 1 && contents.inputIconPosition == 1" prefix-icon="el-icon-search" v-model="searchForm.pingfen" placeholder="评分" clearable></el-input>
<!-- 后缀图标搜索框 -->
<el-input v-if="contents.inputIcon == 1 && contents.inputIconPosition == 2" suffix-icon="el-icon-search" v-model="searchForm.pingfen" placeholder="评分" clearable></el-input>
<!-- 无图标搜索框 -->
<el-input v-if="contents.inputIcon == 0" v-model="searchForm.pingfen" placeholder="评分" clearable></el-input>
</el-form-item>
<!-- 房主账号搜索框 -->
<el-form-item :label="contents.inputTitle == 1 ? '房主账号' : ''">
<!-- 前缀图标搜索框 -->
<el-input v-if="contents.inputIcon == 1 && contents.inputIconPosition == 1" prefix-icon="el-icon-search" v-model="searchForm.fangzhuzhanghao" placeholder="房主账号" clearable></el-input>
<!-- 后缀图标搜索框 -->
<el-input v-if="contents.inputIcon == 1 && contents.inputIconPosition == 2" suffix-icon="el-icon-search" v-model="searchForm.fangzhuzhanghao" placeholder="房主账号" clearable></el-input>
<!-- 无图标搜索框 -->
<el-input v-if="contents.inputIcon == 0" v-model="searchForm.fangzhuzhanghao" placeholder="房主账号" clearable></el-input>
</el-form-item>
<!-- 用户名搜索框 -->
<el-form-item :label="contents.inputTitle == 1 ? '用户名' : ''">
<!-- 前缀图标搜索框 -->
<el-input v-if="contents.inputIcon == 1 && contents.inputIconPosition == 1" prefix-icon="el-icon-search" v-model="searchForm.yonghuming" placeholder="用户名" clearable></el-input>
<!-- 后缀图标搜索框 -->
<el-input v-if="contents.inputIcon == 1 && contents.inputIconPosition == 2" suffix-icon="el-icon-search" v-model="searchForm.yonghuming" placeholder="用户名" clearable></el-input>
<!-- 无图标搜索框 -->
<el-input v-if="contents.inputIcon == 0" v-model="searchForm.yonghuming" placeholder="用户名" clearable></el-input>
</el-form-item>
<!-- 查询按钮 -->
<el-form-item>
<!-- 前缀图标查询按钮 -->
<el-button v-if="contents.searchBtnIcon == 1 && contents.searchBtnIconPosition == 1" icon="el-icon-search" type="success" @click="search()">{{ contents.searchBtnFont == 1?'':'' }}</el-button>
<!-- 后缀图标查询按钮 -->
<el-button v-if="contents.searchBtnIcon == 1 && contents.searchBtnIconPosition == 2" type="success" @click="search()">{{ contents.searchBtnFont == 1?'':'' }}<i class="el-icon-search el-icon--right"/></el-button>
<!-- 无图标查询按钮 -->
<el-button v-if="contents.searchBtnIcon == 0" type="success" @click="search()">{{ contents.searchBtnFont == 1?'':'' }}</el-button>
</el-form-item>
</el-row>
<!-- 操作按钮区域 -->
<el-row class="ad" :style="{justifyContent:contents.btnAdAllBoxPosition=='1'?'flex-start':contents.btnAdAllBoxPosition=='2'?'center':'flex-end'}">
<el-form-item>
<!-- 新增按钮 -->
<el-button
v-if="isAuth('fangwupingjia','新增') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 1"
type="success"
icon="el-icon-plus"
@click="addOrUpdateHandler()"
>{{ contents.btnAdAllFont == 1?'新增':'' }}</el-button>
<!-- 不同图标位置的新增按钮 -->
<el-button
v-if="isAuth('fangwupingjia','新增') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 2"
type="success"
@click="addOrUpdateHandler()"
>{{ contents.btnAdAllFont == 1?'新增':'' }}<i class="el-icon-plus el-icon--right" /></el-button>
<!-- 无图标的新增按钮 -->
<el-button
v-if="isAuth('fangwupingjia','新增') && contents.btnAdAllIcon == 0"
type="success"
@click="addOrUpdateHandler()"
>{{ contents.btnAdAllFont == 1?'新增':'' }}</el-button>
<!-- 删除按钮 -->
<el-button
v-if="isAuth('fangwupingjia','删除') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 1 && contents.tableSelection"
:disabled="dataListSelections.length <= 0"
type="danger"
icon="el-icon-delete"
@click="deleteHandler()"
>{{ contents.btnAdAllFont == 1?'删除':'' }}</el-button>
<!-- 不同图标位置的删除按钮 -->
<el-button
v-if="isAuth('fangwupingjia','删除') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 2 && contents.tableSelection"
:disabled="dataListSelections.length <= 0"
type="danger"
@click="deleteHandler()"
>{{ contents.btnAdAllFont == 1?'删除':'' }}<i class="el-icon-delete el-icon--right" /></el-button>
<!-- 无图标的删除按钮 -->
<el-button
v-if="isAuth('fangwupingjia','删除') && contents.btnAdAllIcon == 0 && contents.tableSelection"
:disabled="dataListSelections.length <= 0"
type="danger"
@click="deleteHandler()"
>{{ contents.btnAdAllFont == 1?'删除':'' }}</el-button>
<!-- 统计报表按钮 -->
<el-button
v-if="isAuth('fangwupingjia','报表') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 1"
type="warning"
icon="el-icon-s-data"
@click="chartDialog()"
>{{ contents.btnAdAllFont == 1?'统计报表':'' }}</el-button>
<el-button
v-if="isAuth('fangwupingjia','报表') && contents.btnAdAllIcon == 1 && contents.btnAdAllIconPosition == 2"
type="warning"
@click="chartDialog()"
>{{ contents.btnAdAllFont == 1?'统计报表':'' }}<i class="el-icon-s-data el-icon--right" /></el-button>
<el-button
v-if="isAuth('fangwupingjia','报表') && contents.btnAdAllIcon == 0"
type="warning"
@click="chartDialog()"
>{{ contents.btnAdAllFont == 1?'统计报表':'' }}</el-button>
</el-form-item>
</el-row>
</el-form>
<!-- 数据表格内容区域 -->
<div class="table-content">
<!-- 数据表格 -->
<el-table class="tables" :size="contents.tableSize" :show-header="contents.tableShowHeader"
:header-row-style="headerRowStyle" :header-cell-style="headerCellStyle"
:border="contents.tableBorder"
:fit="contents.tableFit"
:stripe="contents.tableStripe"
:row-style="rowStyle"
:cell-style="cellStyle"
:style="{width: '100%',fontSize:contents.tableContentFontSize,color:contents.tableContentFontColor}"
v-if="isAuth('fangwupingjia','查看')"
:data="dataList"
v-loading="dataListLoading"
@selection-change="selectionChangeHandler">
<!-- 多选列 -->
<el-table-column v-if="contents.tableSelection"
type="selection"
header-align="center"
align="center"
width="50">
</el-table-column>
<!-- 索引列 -->
<el-table-column label="索引" v-if="contents.tableIndex" type="index" width="50" />
<!-- 合同编号列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="hetongbianhao"
header-align="center"
label="合同编号">
<template slot-scope="scope">
{{scope.row.hetongbianhao}}
</template>
</el-table-column>
<!-- 房屋名称列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="fangwumingcheng"
header-align="center"
label="房屋名称">
<template slot-scope="scope">
{{scope.row.fangwumingcheng}}
</template>
</el-table-column>
<!-- 房屋类型列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="fangwuleixing"
header-align="center"
label="房屋类型">
<template slot-scope="scope">
{{scope.row.fangwuleixing}}
</template>
</el-table-column>
<!-- 小区列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="xiaoqu"
header-align="center"
label="小区">
<template slot-scope="scope">
{{scope.row.xiaoqu}}
</template>
</el-table-column>
<!-- 评分列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="pingfen"
header-align="center"
label="评分">
<template slot-scope="scope">
{{scope.row.pingfen}}
</template>
</el-table-column>
<!-- 评价内容列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="pingjianeirong"
header-align="center"
label="评价内容">
<template slot-scope="scope">
{{scope.row.pingjianeirong}}
</template>
</el-table-column>
<!-- 评价日期列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="pingjiariqi"
header-align="center"
label="评价日期">
<template slot-scope="scope">
{{scope.row.pingjiariqi}}
</template>
</el-table-column>
<!-- 房主账号列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="fangzhuzhanghao"
header-align="center"
label="房主账号">
<template slot-scope="scope">
{{scope.row.fangzhuzhanghao}}
</template>
</el-table-column>
<!-- 用户名列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="yonghuming"
header-align="center"
label="用户名">
<template slot-scope="scope">
{{scope.row.yonghuming}}
</template>
</el-table-column>
<!-- 联系电话列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="lianxidianhua"
header-align="center"
label="联系电话">
<template slot-scope="scope">
{{scope.row.lianxidianhua}}
</template>
</el-table-column>
<!-- 审核回复列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="shhf"
header-align="center"
label="审核回复">
</el-table-column>
<!-- 审核状态列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
prop="sfsh"
header-align="center"
label="审核状态">
<template slot-scope="scope">
<span style="margin-right:10px">{{scope.row.sfsh=='是'?'通过':'未通过'}}</span>
</template>
</el-table-column>
<!-- 审核操作列 -->
<el-table-column :sortable="contents.tableSortable" :align="contents.tableAlign"
v-if="isAuth('fangwupingjia','审核')"
prop="sfsh"
header-align="center"
label="审核">
<template slot-scope="scope">
<el-button type="text" icon="el-icon-edit" size="small" @click="shDialog(scope.row)"></el-button>
</template>
</el-table-column>
<!-- 操作列 -->
<el-table-column width="300" :align="contents.tableAlign"
header-align="center"
label="操作">
<template slot-scope="scope">
<!-- 详情按钮 -->
<el-button v-if="isAuth('fangwupingjia','查看') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 1" type="success" icon="el-icon-tickets" size="mini" @click="addOrUpdateHandler(scope.row.id,'info')">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<el-button v-if="isAuth('fangwupingjia','查看') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 2" type="success" size="mini" @click="addOrUpdateHandler(scope.row.id,'info')">{{ contents.tableBtnFont == 1?'':'' }}<i class="el-icon-tickets el-icon--right" /></el-button>
<el-button v-if="isAuth('fangwupingjia','查看') && contents.tableBtnIcon == 0" type="success" size="mini" @click="addOrUpdateHandler(scope.row.id,'info')">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<!-- 修改按钮 -->
<el-button v-if="isAuth('fangwupingjia','修改') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 1" type="primary" icon="el-icon-edit" size="mini" @click="addOrUpdateHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<el-button v-if="isAuth('fangwupingjia','修改') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 2" type="primary" size="mini" @click="addOrUpdateHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}<i class="el-icon-edit el-icon--right" /></el-button>
<el-button v-if="isAuth('fangwupingjia','修改') && contents.tableBtnIcon == 0" type="primary" size="mini" @click="addOrUpdateHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<!-- 删除按钮 -->
<el-button v-if="isAuth('fangwupingjia','删除') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 1" type="danger" icon="el-icon-delete" size="mini" @click="deleteHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
<el-button v-if="isAuth('fangwupingjia','删除') && contents.tableBtnIcon == 1 && contents.tableBtnIconPosition == 2" type="danger" size="mini" @click="deleteHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}<i class="el-icon-delete el-icon--right" /></el-button>
<el-button v-if="isAuth('fangwupingjia','删除') && contents.tableBtnIcon == 0" type="danger" size="mini" @click="deleteHandler(scope.row.id)">{{ contents.tableBtnFont == 1?'':'' }}</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<el-pagination
clsss="pages"
:layout="layouts"
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
:current-page="pageIndex"
:page-sizes="[10, 20, 50, 100]"
:page-size="Number(contents.pageEachNum)"
:total="totalPage"
:small="contents.pageStyle"
class="pagination-content"
:background="contents.pageBtnBG"
:style="{textAlign:contents.pagePosition==1?'left':contents.pagePosition==2?'center':'right'}"
></el-pagination>
</div>
</div>
<!-- 添加/修改页面 -->
<add-or-update v-if="addOrUpdateFlag" :parent="this" ref="addOrUpdate"></add-or-update>
<!-- 审核对话框 -->
<el-dialog
title="审核"
:visible.sync="sfshVisiable"
width="50%">
<el-form ref="form" :model="form" label-width="80px">
<el-form-item label="审核状态">
<el-select v-model="shForm.sfsh" placeholder="审核状态">
<el-option label="通过" value="是"></el-option>
<el-option label="不通过" value="否"></el-option>
</el-select>
</el-form-item>
<el-form-item label="内容">
<el-input type="textarea" :rows="8" v-model="shForm.shhf"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="shDialog"> </el-button>
<el-button type="primary" @click="shHandler"> </el-button>
</span>
</el-dialog>
<!-- 统计报表对话框 -->
<el-dialog
title="统计报表"
:visible.sync="chartVisiable"
width="800">
<div id="pingfenChart" style="width:100%;height:600px;"></div>
<span slot="footer" class="dialog-footer">
<el-button @click="chartDialog"></el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import AddOrUpdate from "./add-or-update";
export default {
data() {
return {
//
searchForm: {
key: ""
},
//
dataList: [],
//
pageIndex: 1,
//
pageSize: 10,
//
totalPage: 0,
//
dataListLoading: false,
//
dataListSelections: [],
//
showFlag: true,
//
sfshVisiable: false,
//
shForm: {},
//
chartVisiable: false,
// /
addOrUpdateFlag: false,
//
contents: { /* 配置参数 */ },
//
layouts: '',
};
},
created() {
this.init();
this.getDataList();
this.contentStyleChange();
},
mounted() {
},
filters: {
// HTML
htmlfilter: function (val) {
return val.replace(/<[^>]*>/g).replace(/undefined/g,'');
}
},
components: {
AddOrUpdate,
},
methods: {
//
contentStyleChange() {
this.contentSearchStyleChange();
this.contentBtnAdAllStyleChange();
this.contentSearchBtnStyleChange();
this.contentTableBtnStyleChange();
this.contentPageStyleChange();
},
//
contentSearchStyleChange() {
this.$nextTick(()=>{
document.querySelectorAll('.form-content .slt .el-input__inner').forEach(el=>{
let textAlign = 'left';
if(this.contents.inputFontPosition == 2) textAlign = 'center';
if(this.contents.inputFontPosition == 3) textAlign = 'right';
el.style.textAlign = textAlign;
el.style.height = this.contents.inputHeight;
el.style.lineHeight = this.contents.inputHeight;
el.style.color = this.contents.inputFontColor;
el.style.fontSize = this.contents.inputFontSize;
el.style.borderWidth = this.contents.inputBorderWidth;
el.style.borderStyle = this.contents.inputBorderStyle;
el.style.borderColor = this.contents.inputBorderColor;
el.style.borderRadius = this.contents.inputBorderRadius;
el.style.backgroundColor = this.contents.inputBgColor;
});
if(this.contents.inputTitle) {
document.querySelectorAll('.form-content .slt .el-form-item__label').forEach(el=>{
el.style.color = this.contents.inputTitleColor;
el.style.fontSize = this.contents.inputTitleSize;
el.style.lineHeight = this.contents.inputHeight;
});
}
setTimeout(()=>{
document.querySelectorAll('.form-content .slt .el-input__prefix').forEach(el=>{
el.style.color = this.contents.inputIconColor;
el.style.lineHeight = this.contents.inputHeight;
});
document.querySelectorAll('.form-content .slt .el-input__suffix').forEach(el=>{
el.style.color = this.contents.inputIconColor;
el.style.lineHeight = this.contents.inputHeight;
});
document.querySelectorAll('.form-content .slt .el-input__icon').forEach(el=>{
el.style.lineHeight = this.contents.inputHeight;
});
},10);
});
},
//
contentSearchBtnStyleChange() {
this.$nextTick(()=>{
document.querySelectorAll('.form-content .slt .el-button--success').forEach(el=>{
el.style.height = this.contents.searchBtnHeight;
el.style.color = this.contents.searchBtnFontColor;
el.style.fontSize = this.contents.searchBtnFontSize;
el.style.borderWidth = this.contents.searchBtnBorderWidth;
el.style.borderStyle = this.contents.searchBtnBorderStyle;
el.style.borderColor = this.contents.searchBtnBorderColor;
el.style.borderRadius = this.contents.searchBtnBorderRadius;
el.style.backgroundColor = this.contents.searchBtnBgColor;
});
});
},
//
contentBtnAdAllStyleChange() {
this.$nextTick(()=>{
document.querySelectorAll('.form-content .ad .el-button--success').forEach(el=>{
el.style.height = this.contents.btnAdAllHeight;
el.style.color = this.contents.btnAdAllAddFontColor;
el.style.fontSize = this.contents.btnAdAllFontSize;
el.style.borderWidth = this.contents.btnAdAllBorderWidth;
el.style.borderStyle = this.contents.btnAdAllBorderStyle;
el.style.borderColor = this.contents.btnAdAllBorderColor;
el.style.borderRadius = this.contents.btnAdAllBorderRadius;
el.style.backgroundColor = this.contents.btnAdAllAddBgColor;
});
document.querySelectorAll('.form-content .ad .el-button--danger').forEach(el=>{
el.style.height = this.contents.btnAdAllHeight;
el.style.color = this.contents.btnAdAllDelFontColor;
el.style.fontSize = this.contents.btnAdAllFontSize;
el.style.borderWidth = this.contents.btnAdAllBorderWidth;
el.style.borderStyle = this.contents.btnAdAllBorderStyle;
el.style.borderColor = this.contents.btnAdAllBorderColor;
el.style.borderRadius = this.contents.btnAdAllBorderRadius;
el.style.backgroundColor = this.contents.btnAdAllDelBgColor;
});
document.querySelectorAll('.form-content .ad .el-button--warning').forEach(el=>{
el.style.height = this.contents.btnAdAllHeight;
el.style.color = this.contents.btnAdAllWarnFontColor;
el.style.fontSize = this.contents.btnAdAllFontSize;
el.style.borderWidth = this.contents.btnAdAllBorderWidth;
el.style.borderStyle = this.contents.btnAdAllBorderStyle;
el.style.borderColor = this.contents.btnAdAllBorderColor;
el.style.borderRadius = this.contents.btnAdAllBorderRadius;
el.style.backgroundColor = this.contents.btnAdAllWarnBgColor;
});
});
},
//
rowStyle({ row, rowIndex}) {
if (rowIndex % 2 == 1) {
if(this.contents.tableStripe) {
return {color:this.contents.tableStripeFontColor};
}
} else {
return '';
}
},
cellStyle({ row, rowIndex}) {
if (rowIndex % 2 == 1) {
if(this.contents.tableStripe) {
return {backgroundColor:this.contents.tableStripeBgColor};
}
} else {
return '';
}
},
headerRowStyle({ row, rowIndex}) {
return {color: this.contents.tableHeaderFontColor};
},
headerCellStyle({ row, rowIndex}) {
return {backgroundColor: this.contents.tableHeaderBgColor};
},
//
contentTableBtnStyleChange() {
//
},
//
contentPageStyleChange() {
let arr = [];
if(this.contents.pageTotal) arr.push('total');
if(this.contents.pageSizes) arr.push('sizes');
if(this.contents.pagePrevNext){
arr.push('prev');
if(this.contents.pagePager) arr.push('pager');
arr.push('next');
}
if(this.contents.pageJumper) arr.push('jumper');
this.layouts = arr.join();
this.contents.pageEachNum = 10;
},
//
chartDialog() {
this.chartVisiable = !this.chartVisiable;
this.$nextTick(()=>{
var pingfenChart = this.$echarts.init(document.getElementById("pingfenChart"),'macarons');
this.$http({
url: "group/fangwupingjia/pingfen",
method: "get",
}).then(({ data }) => {
if (data && data.code === 0) {
let res = data.data;
let xAxis = [];
let yAxis = [];
let pArray = [];
for(let i=0;i<res.length;i++){
xAxis.push(res[i].pingfen);
yAxis.push(res[i].total);
pArray.push({
value: res[i].total,
name: res[i].pingfen
});
var option = {};
option = {
title: {
text: '房屋评价',
left: 'center'
},
tooltip: {
trigger: 'item',
formatter: '{b} : {c} ({d}%)'
},
series: [
{
type: 'pie',
radius: '55%',
center: ['50%', '60%'],
data: pArray,
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
pingfenChart.setOption(option);
window.onresize = function() {
pingfenChart.resize();
};
}
}
});
});
},
//
init () {
this.pingfenOptions = "1,2,3,4,5".split(',');
},
//
search() {
this.pageIndex = 1;
this.getDataList();
},
//
getDataList() {
this.dataListLoading = true;
let params = {
page: this.pageIndex,
limit: this.pageSize,
sort: 'id',
};
if(this.searchForm.fangwumingcheng!='' && this.searchForm.fangwumingcheng!=undefined){
params['fangwumingcheng'] = '%' + this.searchForm.fangwumingcheng + '%';
}
if(this.searchForm.pingfen!='' && this.searchForm.pingfen!=undefined){
params['pingfen'] = '%' + this.searchForm.pingfen + '%';
}
if(this.searchForm.fangzhuzhanghao!='' && this.searchForm.fangzhuzhanghao!=undefined){
params['fangzhuzhanghao'] = '%' + this.searchForm.fangzhuzhanghao + '%';
}
if(this.searchForm.yonghuming!='' && this.searchForm.yonghuming!=undefined){
params['yonghuming'] = '%' + this.searchForm.yonghuming + '%';
}
this.$http({
url: "fangwupingjia/page",
method: "get",
params: params
}).then(({ data }) => {
if (data && data.code === 0) {
this.dataList = data.data.list;
this.totalPage = data.data.total;
} else {
this.dataList = [];
this.totalPage = 0;
}
this.dataListLoading = false;
});
},
//
sizeChangeHandle(val) {
this.pageSize = val;
this.pageIndex = 1;
this.getDataList();
},
//
currentChangeHandle(val) {
this.pageIndex = val;
this.getDataList();
},
//
selectionChangeHandler(val) {
this.dataListSelections = val;
},
// /
addOrUpdateHandler(id,type) {
this.showFlag = false;
this.addOrUpdateFlag = true;
this.crossAddOrUpdateFlag = false;
if(type!='info'){
type = 'else';
}
this.$nextTick(() => {
this.$refs.addOrUpdate.init(id,type);
});
},
//
shDialog(row){
this.sfshVisiable = !this.sfshVisiable;
if(row){
this.shForm = {
hetongbianhao: row.hetongbianhao,
fangwumingcheng: row.fangwumingcheng,
fangwuleixing: row.fangwuleixing,
xiaoqu: row.xiaoqu,
pingfen: row.pingfen,
pingjianeirong: row.pingjianeirong,
pingjiariqi: row.pingjiariqi,
fangzhuzhanghao: row.fangzhuzhanghao,
yonghuming: row.yonghuming,
lianxidianhua: row.lianxidianhua,
sfsh: row.sfsh,
shhf: row.shhf,
id: row.id
}
}
},
//
shHandler(){
this.$confirm(`确定操作?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$http({
url: "fangwupingjia/update",
method: "post",
data: this.shForm
}).then(({ data }) => {
if (data && data.code === 0) {
this.$message({
message: "操作成功",
type: "success",
duration: 1500,
onClose: () => {
this.getDataList();
this.shDialog();
}
});
} else {
this.$message.error(data.msg);
}
});
});
},
//
download(file){
window.open(`${file}`);
},
//
deleteHandler(id) {
var ids = id
? [Number(id)]
: this.dataListSelections.map(item => {
return Number(item.id);
});
this.$confirm(`确定进行[${id ? "删除" : "批量删除"}]操作?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
this.$http({
url: "fangwupingjia/delete",
method: "post",
data: ids
}).then(({ data }) => {
if (data && data.code === 0) {
this.$message({
message: "操作成功",
type: "success",
duration: 1500,
onClose: () => {
this.search();
}
});
} else {
this.$message.error(data.msg);
}
});
});
},
}
};
</script>
<style lang="scss" scoped>
/* 搜索按钮区域样式 */
.slt {
margin: 0 !important;
display: flex;
}
/* 操作按钮区域样式 */
.ad {
margin: 0 !important;
display: flex;
}
/* 分页组件样式 */
.pages {
& /deep/ .el-pagination__sizes {
& /deep/ .el-input__inner {
height: 22px;
line-height: 22px;
}
}
}
/* 按钮间距调整 */
.el-button+.el-button {
margin: 0;
}
/* 表格按钮样式 */
.tables {
& /deep/ .el-button--success {
height: 40px;
color: #333;
font-size: 14px;
border-width: 1px;
border-style: solid;
border-color: rgba(196, 210, 244, 1);
border-radius: 22px;
background-color: rgba(171, 239, 239, 1);
}
& /deep/ .el-button--primary {
height: 40px;
color: #333;
font-size: 14px;
border-width: 1px;
border-style: solid;
border-color: rgba(196, 210, 244, 1);
border-radius: 22px;
background-color: rgba(240, 242, 124, 1);
}
& /deep/ .el-button--danger {
height: 40px;
color: #333;
font-size: 14px;
border-width: 1px;
border-style: solid;
border-color: rgba(196, 210, 244, 1);
border-radius: 22px;
background-color: rgba(244, 150, 150, 1);
}
& /deep/ .el-button {
margin: 4px;
}
}
</style>

@ -0,0 +1,175 @@
import Vue from 'vue'; // 引入 Vue 核心库
// 配置路由
import VueRouter from 'vue-router'; // 引入 Vue Router 库
Vue.use(VueRouter); // 使用 Vue Router 插件
// 1. 创建组件
import Index from '@/views/index'; // 导入首页组件
import Home from '@/views/home'; // 导入主页组件
import Login from '@/views/login'; // 导入登录页组件
import NotFound from '@/views/404'; // 导入 404 页面组件
import UpdatePassword from '@/views/update-password'; // 导入修改密码页面组件
import pay from '@/views/pay'; // 导入支付页面组件
import register from '@/views/register'; // 导入注册页面组件
import center from '@/views/center'; // 导入个人信息页面组件
import fangwuleixing from '@/views/modules/fangwuleixing/list'; // 导入房屋类型列表页面组件
import discussfangwuxinxi from '@/views/modules/discussfangwuxinxi/list'; // 导入房屋信息评论列表页面组件
import news from '@/views/modules/news/list'; // 导入公告信息列表页面组件
import weixiuchuli from '@/views/modules/weixiuchuli/list'; // 导入维修处理列表页面组件
import storeup from '@/views/modules/storeup/list'; // 导入我的收藏管理列表页面组件
import fangwupingjia from '@/views/modules/fangwupingjia/list'; // 导入房屋评价列表页面组件
import fangwuxinxi from '@/views/modules/fangwuxinxi/list'; // 导入房屋信息列表页面组件
import yuyuekanfang from '@/views/modules/yuyuekanfang/list'; // 导入预约看房列表页面组件
import woyaodangfangzhu from '@/views/modules/woyaodangfangzhu/list'; // 导入我要当房主列表页面组件
import fangzhu from '@/views/modules/fangzhu/list'; // 导入房主列表页面组件
import yonghu from '@/views/modules/yonghu/list'; // 导入用户列表页面组件
import discusswoyaodangfangzhu from '@/views/modules/discusswoyaodangfangzhu/list'; // 导入我要当房主评论列表页面组件
import fangwubaoxiu from '@/views/modules/fangwubaoxiu/list'; // 导入房屋报修列表页面组件
import hetongxinxi from '@/views/modules/hetongxinxi/list'; // 导入合同信息列表页面组件
import messages from '@/views/modules/messages/list'; // 导入留言板管理列表页面组件
import config from '@/views/modules/config/list'; // 导入轮播图管理列表页面组件
// 2. 配置路由 注意:名字
const routes = [ // 定义路由规则数组
{
path: '/index', // 路由路径
name: '首页', // 路由名称
component: Index, // 对应的组件
children: [ // 子路由
{
path: '/', // 默认子路径
name: '首页', // 子路由名称
component: Home, // 对应的子组件
meta: { icon: '', title: 'center' } // 元信息,包含图标和标题
},
{
path: '/updatePassword', // 修改密码页面路径
name: '修改密码', // 路由名称
component: UpdatePassword, // 对应的组件
meta: { icon: '', title: 'updatePassword' } // 元信息
},
{
path: '/pay', // 支付页面路径
name: '支付', // 路由名称
component: pay, // 对应的组件
meta: { icon: '', title: 'pay' } // 元信息
},
{
path: '/center', // 个人信息页面路径
name: '个人信息', // 路由名称
component: center, // 对应的组件
meta: { icon: '', title: 'center' } // 元信息
},
{
path: '/fangwuleixing', // 房屋类型页面路径
name: '房屋类型', // 路由名称
component: fangwuleixing // 对应的组件
},
{
path: '/discussfangwuxinxi', // 房屋信息评论页面路径
name: '房屋信息评论', // 路由名称
component: discussfangwuxinxi // 对应的组件
},
{
path: '/news', // 公告信息页面路径
name: '公告信息', // 路由名称
component: news // 对应的组件
},
{
path: '/weixiuchuli', // 维修处理页面路径
name: '维修处理', // 路由名称
component: weixiuchuli // 对应的组件
},
{
path: '/storeup', // 我的收藏管理页面路径
name: '我的收藏管理', // 路由名称
component: storeup // 对应的组件
},
{
path: '/fangwupingjia', // 房屋评价页面路径
name: '房屋评价', // 路由名称
component: fangwupingjia // 对应的组件
},
{
path: '/fangwuxinxi', // 房屋信息页面路径
name: '房屋信息', // 路由名称
component: fangwuxinxi // 对应的组件
},
{
path: '/yuyuekanfang', // 预约看房页面路径
name: '预约看房', // 路由名称
component: yuyuekanfang // 对应的组件
},
{
path: '/woyaodangfangzhu', // 我要当房主页面路径
name: '我要当房主', // 路由名称
component: woyaodangfangzhu // 对应的组件
},
{
path: '/fangzhu', // 房主页面路径
name: '房主', // 路由名称
component: fangzhu // 对应的组件
},
{
path: '/yonghu', // 用户页面路径
name: '用户', // 路由名称
component: yonghu // 对应的组件
},
{
path: '/discusswoyaodangfangzhu', // 我要当房主评论页面路径
name: '我要当房主评论', // 路由名称
component: discusswoyaodangfangzhu // 对应的组件
},
{
path: '/fangwubaoxiu', // 房屋报修页面路径
name: '房屋报修', // 路由名称
component: fangwubaoxiu // 对应的组件
},
{
path: '/hetongxinxi', // 合同信息页面路径
name: '合同信息', // 路由名称
component: hetongxinxi // 对应的组件
},
{
path: '/messages', // 留言板管理页面路径
name: '留言板管理', // 路由名称
component: messages // 对应的组件
},
{
path: '/config', // 轮播图管理页面路径
name: '轮播图管理', // 路由名称
component: config // 对应的组件
}
]
},
{
path: '/login', // 登录页面路径
name: 'login', // 路由名称
component: Login, // 对应的组件
meta: { icon: '', title: 'login' } // 元信息
},
{
path: '/register', // 注册页面路径
name: 'register', // 路由名称
component: register, // 对应的组件
meta: { icon: '', title: 'register' } // 元信息
},
{
path: '/', // 默认跳转路径
name: '首页', // 路由名称
redirect: '/index' // 重定向到 /index
}, /* 默认跳转路由 */
{
path: '*', // 匹配所有未定义的路径
component: NotFound // 对应的组件为 404 页面
}
];
// 3. 实例化 VueRouter 注意:名字
const router = new VueRouter({ // 创建 VueRouter 实例
mode: 'hash', // 使用 hash 模式
/* hash模式改为history */
routes // 将路由规则传递给 VueRouter
});
export default router; // 导出路由实例

@ -0,0 +1,17 @@
const api = { // 定义 API 对象,存储后端接口地址
// 积分订单相关接口
orderpage: 'orders/page', // 获取积分订单分页数据
orderdelete: 'orders/delete', // 删除积分订单
orderinfo: 'orders/info/', // 获取积分订单详情(需拼接 ID
ordersave: 'orders/save', // 保存新的积分订单
orderupdate: 'orders/update', // 更新已有积分订单
// 配置相关接口
configpage: 'config/page', // 获取配置分页数据
configdelete: 'config/delete', // 删除配置项
configinfo: 'config/info/', // 获取配置项详情(需拼接 ID
configsave: 'config/save', // 保存新的配置项
configupdate: 'config/update' // 更新已有配置项
};
export default api; // 导出 API 对象,供其他模块使用

@ -0,0 +1,16 @@
const base = { // 定义一个名为 base 的对象,用于存储基础配置方法
get() { // 定义 get 方法,返回基础配置信息
return { // 返回一个包含基础配置的对象
url: "http://localhost:8080/springboot08hr3/", // 后端服务的基础 URL 地址
name: "springboot08hr3", // 项目的名称或标识符
// 退出到首页链接
indexUrl: 'http://localhost:8080/springboot08hr3/front/index.html' // 前端首页的 URL用于用户退出登录后跳转
};
},
getProjectName() { // 定义 getProjectName 方法,返回项目名称
return { // 返回一个包含项目名称的对象
projectName: "房屋租赁系统" // 项目的中文名称
};
}
};
export default base; // 导出 base 对象,供其他模块使用

@ -0,0 +1,38 @@
import axios from 'axios'; // 引入 axios 库,用于发送 HTTP 请求
import router from '@/router/router-static'; // 引入路由配置文件
import storage from '@/utils/storage'; // 引入存储工具,用于操作本地存储
const http = axios.create({ // 创建一个自定义的 axios 实例
timeout: 1000 * 86400, // 设置请求超时时间为 1 天(单位:毫秒)
withCredentials: true, // 跨域请求时是否携带凭证(如 Cookie
baseURL: '/springboot08hr3', // 设置请求的基础 URL
headers: { // 设置默认请求头
'Content-Type': 'application/json; charset=utf-8' // 指定内容类型为 JSON
}
});
// 请求拦截器:在请求发送前进行处理
http.interceptors.request.use(
config => {
config.headers['Token'] = storage.get('Token'); // 从存储中获取 Token 并添加到请求头中
return config; // 返回配置对象
},
error => {
return Promise.reject(error); // 如果发生错误,返回拒绝的 Promise
}
);
// 响应拦截器:在接收到响应数据后进行处理
http.interceptors.response.use(
response => {
if (response.data && response.data.code === 401) { // 如果响应数据存在且状态码为 401Token 失效)
router.push({ name: 'login' }); // 跳转到登录页面
}
return response; // 返回响应数据
},
error => {
return Promise.reject(error); // 如果发生错误,返回拒绝的 Promise
}
);
export default http; // 导出自定义的 axios 实例,供其他模块使用

@ -0,0 +1,12 @@
// translate router.meta.title, be used in breadcrumb sidebar tagsview // 用于翻译路由的 meta.title适用于面包屑、侧边栏和标签视图
export function generateTitle(title) { // 导出生成标题的函数,参数为标题名称
const hasKey = this.$te('route.' + title); // 检查是否存在对应的语言键值,$te 方法来自 vue-i18n
if (hasKey) { // 如果存在对应的键值
// $t :this method from vue-i18n, inject in @/lang/index.js // $t 方法来自 vue-i18n在 @/lang/index.js 中注入
const translatedTitle = this.$t('route.' + title); // 使用 $t 方法获取翻译后的标题
return translatedTitle; // 返回翻译后的标题
}
return title; // 如果没有找到对应的键值,返回原始标题
}

@ -0,0 +1,324 @@
const menu = { // 定义一个 menu 对象,用于存储菜单数据和方法
list() { // 定义 list 方法,返回菜单数据
return [ // 返回一个包含角色及其对应菜单的数组
{ // 第一个角色:管理员
backMenu: [ // 后台菜单列表
{ // 用户管理
child: [{ // 子菜单
buttons: ["新增", "查看", "修改", "删除"], // 按钮权限
menu: "用户", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "yonghu" // 数据表名
}],
menu: "用户管理" // 父菜单名称
},
{ // 房主管理
child: [{ // 子菜单
buttons: ["新增", "查看", "修改", "删除"], // 按钮权限
menu: "房主", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "fangzhu" // 数据表名
}],
menu: "房主管理" // 父菜单名称
},
{ // 房屋类型管理
child: [{ // 子菜单
buttons: ["新增", "查看", "修改", "删除"], // 按钮权限
menu: "房屋类型", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "fangwuleixing" // 数据表名
}],
menu: "房屋类型管理" // 父菜单名称
},
{ // 房屋信息管理
child: [{ // 子菜单
buttons: ["新增", "查看", "修改", "删除", "查看评论"], // 按钮权限
menu: "房屋信息", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "fangwuxinxi" // 数据表名
}],
menu: "房屋信息管理" // 父菜单名称
},
{ // 预约看房管理
child: [{ // 子菜单
buttons: ["查看", "修改", "删除", "审核", "合同"], // 按钮权限
menu: "预约看房", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "yuyuekanfang" // 数据表名
}],
menu: "预约看房管理" // 父菜单名称
},
{ // 合同信息管理
child: [{ // 子菜单
buttons: ["查看", "修改", "删除"], // 按钮权限
menu: "合同信息", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "hetongxinxi" // 数据表名
}],
menu: "合同信息管理" // 父菜单名称
},
{ // 房屋报修管理
child: [{ // 子菜单
buttons: ["查看", "修改", "删除", "审核", "处理"], // 按钮权限
menu: "房屋报修", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "fangwubaoxiu" // 数据表名
}],
menu: "房屋报修管理" // 父菜单名称
},
{ // 维修处理管理
child: [{ // 子菜单
buttons: ["查看", "修改", "删除"], // 按钮权限
menu: "维修处理", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "weixiuchuli" // 数据表名
}],
menu: "维修处理管理" // 父菜单名称
},
{ // 房屋评价管理
child: [{ // 子菜单
buttons: ["查看", "修改", "删除", "审核", "报表"], // 按钮权限
menu: "房屋评价", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "fangwupingjia" // 数据表名
}],
menu: "房屋评价管理" // 父菜单名称
},
{ // 我要当房主管理
child: [{ // 子菜单
buttons: ["查看", "审核", "删除", "修改"], // 按钮权限
menu: "我要当房主", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "woyaodangfangzhu" // 数据表名
}],
menu: "我要当房主管理" // 父菜单名称
},
{ // 留言板管理
child: [{ // 子菜单
buttons: ["查看", "修改", "回复", "删除"], // 按钮权限
menu: "留言板管理", // 菜单名称
tableName: "messages" // 数据表名
}],
menu: "留言板管理" // 父菜单名称
},
{ // 系统管理
child: [{ // 子菜单
buttons: ["新增", "查看", "修改", "删除"], // 按钮权限
menu: "公告信息", // 菜单名称
tableName: "news" // 数据表名
}, {
buttons: ["新增", "查看", "修改", "删除"], // 按钮权限
menu: "轮播图管理", // 菜单名称
tableName: "config" // 数据表名
}],
menu: "系统管理" // 父菜单名称
}
],
frontMenu: [ // 前台菜单列表
{ // 房屋信息模块
child: [{ // 子菜单
buttons: ["查看", "预约"], // 按钮权限
menu: "房屋信息列表", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "fangwuxinxi" // 数据表名
}],
menu: "房屋信息模块" // 父菜单名称
},
{ // 我要当房主模块
child: [{ // 子菜单
buttons: ["查看"], // 按钮权限
menu: "我要当房主列表", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "woyaodangfangzhu" // 数据表名
}],
menu: "我要当房主模块" // 父菜单名称
}
],
hasBackLogin: "是", // 是否有后台登录功能
hasBackRegister: "否", // 是否有后台注册功能
hasFrontLogin: "否", // 是否有前台登录功能
hasFrontRegister: "否", // 是否有前台注册功能
roleName: "管理员", // 角色名称
tableName: "users" // 数据表名
},
{ // 第二个角色:用户
backMenu: [ // 后台菜单列表
{ // 预约看房管理
child: [{ // 子菜单
buttons: ["查看", "修改", "删除"], // 按钮权限
menu: "预约看房", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "yuyuekanfang" // 数据表名
}],
menu: "预约看房管理" // 父菜单名称
},
{ // 合同信息管理
child: [{ // 子菜单
buttons: ["查看", "审核", "支付", "报修", "评价"], // 按钮权限
menu: "合同信息", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "hetongxinxi" // 数据表名
}],
menu: "合同信息管理" // 父菜单名称
},
{ // 房屋报修管理
child: [{ // 子菜单
buttons: ["查看", "修改", "删除", "审核", "处理"], // 按钮权限
menu: "房屋报修", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "fangwubaoxiu" // 数据表名
}],
menu: "房屋报修管理" // 父菜单名称
},
{ // 维修处理管理
child: [{ // 子菜单
buttons: ["查看"], // 按钮权限
menu: "维修处理", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "weixiuchuli" // 数据表名
}],
menu: "维修处理管理" // 父菜单名称
},
{ // 房屋评价管理
child: [{ // 子菜单
buttons: ["查看", "修改", "删除"], // 按钮权限
menu: "房屋评价", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "fangwupingjia" // 数据表名
}],
menu: "房屋评价管理" // 父菜单名称
},
{ // 我要当房主管理
child: [{ // 子菜单
buttons: ["新增", "查看", "修改", "删除", "审核", "查看评论"], // 按钮权限
menu: "我要当房主", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "woyaodangfangzhu" // 数据表名
}],
menu: "我要当房主管理" // 父菜单名称
},
{ // 我的收藏管理
child: [{ // 子菜单
buttons: ["查看", "删除"], // 按钮权限
menu: "我的收藏管理", // 菜单名称
tableName: "storeup" // 数据表名
}],
menu: "我的收藏管理" // 父菜单名称
}
],
frontMenu: [ // 前台菜单列表
{ // 房屋信息模块
child: [{ // 子菜单
buttons: ["查看", "预约"], // 按钮权限
menu: "房屋信息列表", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "fangwuxinxi" // 数据表名
}],
menu: "房屋信息模块" // 父菜单名称
},
{ // 我要当房主模块
child: [{ // 子菜单
buttons: ["查看"], // 按钮权限
menu: "我要当房主列表", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "woyaodangfangzhu" // 数据表名
}],
menu: "我要当房主模块" // 父菜单名称
}
],
hasBackLogin: "是", // 是否有后台登录功能
hasBackRegister: "否", // 是否有后台注册功能
hasFrontLogin: "是", // 是否有前台登录功能
hasFrontRegister: "是", // 是否有前台注册功能
roleName: "用户", // 角色名称
tableName: "yonghu" // 数据表名
},
{ // 第三个角色:房主
backMenu: [ // 后台菜单列表
{ // 房屋信息管理
child: [{ // 子菜单
buttons: ["查看"], // 按钮权限
menu: "房屋信息", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "fangwuxinxi" // 数据表名
}],
menu: "房屋信息管理" // 父菜单名称
},
{ // 预约看房管理
child: [{ // 子菜单
buttons: ["查看"], // 按钮权限
menu: "预约看房", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "yuyuekanfang" // 数据表名
}],
menu: "预约看房管理" // 父菜单名称
},
{ // 合同信息管理
child: [{ // 子菜单
buttons: ["查看"], // 按钮权限
menu: "合同信息", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "hetongxinxi" // 数据表名
}],
menu: "合同信息管理" // 父菜单名称
},
{ // 房屋报修管理
child: [{ // 子菜单
buttons: ["查看"], // 按钮权限
menu: "房屋报修", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "fangwubaoxiu" // 数据表名
}],
menu: "房屋报修管理" // 父菜单名称
},
{ // 维修处理管理
child: [{ // 子菜单
buttons: ["查看"], // 按钮权限
menu: "维修处理", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "weixiuchuli" // 数据表名
}],
menu: "维修处理管理" // 父菜单名称
},
{ // 房屋评价管理
child: [{ // 子菜单
buttons: ["查看"], // 按钮权限
menu: "房屋评价", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "fangwupingjia" // 数据表名
}],
menu: "房屋评价管理" // 父菜单名称
}
],
frontMenu: [ // 前台菜单列表
{ // 房屋信息模块
child: [{ // 子菜单
buttons: ["查看", "预约"], // 按钮权限
menu: "房屋信息列表", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "fangwuxinxi" // 数据表名
}],
menu: "房屋信息模块" // 父菜单名称
},
{ // 我要当房主模块
child: [{ // 子菜单
buttons: ["查看"], // 按钮权限
menu: "我要当房主列表", // 菜单名称
menuJump: "列表", // 跳转类型
tableName: "woyaodangfangzhu" // 数据表名
}],
menu: "我要当房主模块" // 父菜单名称
}
],
hasBackLogin: "是", // 是否有后台登录功能
hasBackRegister: "是", // 是否有后台注册功能
hasFrontLogin: "否", // 是否有前台登录功能
hasFrontRegister: "否", // 是否有前台注册功能
roleName: "房主", // 角色名称
tableName: "fangzhu" // 数据表名
}
];
}
};
export default menu; // 导出 menu 对象,供其他模块使用

@ -0,0 +1,16 @@
const storage = { // 定义一个名为 storage 的对象,用于操作浏览器的 localStorage
set(key, value) { // 定义 set 方法,用于存储键值对
localStorage.setItem(key, JSON.stringify(value)); // 将 value 转换为 JSON 字符串后存储到 localStorage 中
},
get(key) { // 定义 get 方法,用于获取指定 key 的值
return localStorage.getItem(key) ? localStorage.getItem(key).replace('"', '').replace('"', '') : ""; // 获取值并移除可能存在的引号,如果不存在则返回空字符串
},
getObj(key) { // 定义 getObj 方法,用于获取指定 key 的值并解析为对象
return localStorage.getItem(key) ? JSON.parse(localStorage.getItem(key)) : null; // 如果存在对应的值,则解析为 JSON 对象,否则返回 null
},
remove(key) { // 定义 remove 方法,用于删除指定 key 的值
localStorage.removeItem(key); // 从 localStorage 中移除指定的 key
}
};
export default storage; // 导出 storage 对象,供其他模块使用

@ -0,0 +1,39 @@
import storage from './storage'; // 导入 storage 工具模块,用于操作本地存储
import menu from './menu'; // 导入 menu 工具模块,用于获取菜单数据
/**
* 是否有权限
* @param {*} tableName 表名用于匹配菜单中的表名
* @param {*} key 权限按钮名称用于检查用户是否有该权限
*/
export function isAuth(tableName, key) { // 定义 isAuth 函数,用于检查用户是否有指定权限
let role = storage.get("role"); // 从本地存储中获取当前用户角色
if (!role) { // 如果未获取到角色
role = '管理员'; // 默认设置为“管理员”
}
let menus = menu.list(); // 获取菜单列表数据
for (let i = 0; i < menus.length; i++) { // 遍历菜单列表
if (menus[i].roleName == role) { // 如果当前菜单的角色与用户角色匹配
for (let j = 0; j < menus[i].backMenu.length; j++) { // 遍历后台菜单
for (let k = 0; k < menus[i].backMenu[j].child.length; k++) { // 遍历子菜单
if (tableName == menus[i].backMenu[j].child[k].tableName) { // 如果表名匹配
let buttons = menus[i].backMenu[j].child[k].buttons.join(','); // 将按钮权限数组转为逗号分隔的字符串
return buttons.indexOf(key) !== -1 || false; // 检查权限按钮是否存在于按钮权限字符串中,返回布尔值
}
}
}
}
}
// 注释掉的代码部分:另一种实现方式,逻辑类似
// for(let i=0;i<menus.length;i++){
// if(menus[i].roleName==role){
// for(let j=0;j<menus[i].backMenu.length;j++){
// if(menus[i].backMenu[j].tableName==tableName){
// let buttons = menus[i].backMenu[j].child[0].buttons.join(',');
// return buttons.indexOf(key) !== -1 || false
// }
// }
// }
// }
return false; // 如果未找到匹配的权限,返回 false
}

@ -0,0 +1,59 @@
/**
* 邮箱校验函数
* @param {*} s 输入的字符串
*/
export function isEmail (s) { // 定义邮箱校验函数
return /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((.[a-zA-Z0-9_-]{2,3}){1,2})$/.test(s); // 使用正则表达式校验邮箱格式
}
/**
* 手机号码校验函数
* @param {*} s 输入的字符串
*/
export function isMobile (s) { // 定义手机号码校验函数
return /^1[0-9]{10}$/.test(s); // 使用正则表达式校验手机号码格式以1开头的11位数字
}
/**
* 电话号码校验函数
* @param {*} s 输入的字符串
*/
export function isPhone (s) { // 定义电话号码校验函数
return /^([0-9]{3,4}-)?[0-9]{7,8}$/.test(s); // 使用正则表达式校验电话号码格式可带区号3-4位号码长度为7-8位
}
/**
* URL地址校验函数
* @param {*} s 输入的字符串
*/
export function isURL (s) { // 定义URL地址校验函数
return /^http[s]?:\/\/.*/.test(s); // 使用正则表达式校验URL格式支持http和https协议
}
/**
* 匹配数字可以是小数不可以是负数可以为空
* @param {*} s 输入的字符串
*/
export function isNumber(s){ // 定义数字校验函数
return /(^-?[+-]?([0-9]*\.?[0-9]+|[0-9]+\.?[0-9]*)([eE][+-]?[0-9]+)?$)|(^$)/.test(s); // 使用正则表达式校验数字格式,支持小数、科学计数法,允许为空
}
/**
* 匹配整数可以为空
* @param {*} s 输入的字符串
*/
export function isIntNumer(s){ // 定义整数校验函数
return /(^-?\d+$)|(^$)/.test(s); // 使用正则表达式校验整数格式,允许负数,允许为空
}
/**
* 身份证校验函数
*/
export function checkIdCard(idcard) { // 定义身份证校验函数
const regIdCard = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/; // 定义身份证号码的正则表达式支持15位、18位最后一位可以是数字或X/x
if (!regIdCard.test(idcard)) { // 如果身份证号码不符合正则表达式
return false; // 返回false表示校验失败
} else {
return true; // 返回true表示校验成功
}
}

@ -0,0 +1,359 @@
<template>
<!-- 页面根容器 -->
<div>
<!-- 表单组件 -->
<el-form
class="detail-form-content"
ref="ruleForm"
:model="ruleForm"
:rules="rules"
label-width="80px"
>
<!-- 遍历字段列表生成表单项 -->
#foreach($column in $columns)
<!-- 如果字段类型是“日”(日期) -->
#if($column.type == "日")
<el-form-item label="${column.comments}" prop="${column.columnName}">
<el-date-picker
format="yyyy 年 MM 月 dd 日"
value-format="yyyy-MM-dd HH:mm:ss"
v-model="ruleForm.${column.columnName}"
type="date"
placeholder="${column.comments}">
</el-date-picker>
</el-form-item>
<!-- 如果字段类型是“下”(下拉选择) -->
#elseif( $column.type == "下" )
<el-form-item label="${column.comments}" prop="${column.columnName}">
<el-select v-model="ruleForm.${column.columnName}" placeholder="请选择${column.comments}">
<el-option
v-for="(item,index) in ${column.columnName}Options"
v-bind:key="index"
:label="item"
:value="item">
</el-option>
</el-select>
</el-form-item>
<!-- 如果字段类型是“图”(图片上传) -->
#elseif($column.type=="图")
<el-form-item label="${column.comments}" prop="${column.columnName}">
<file-upload
tip="点击上传${column.comments}"
action="file/upload"
:limit="3"
:multiple="true"
:fileUrls="ruleForm.${column.columnName}?ruleForm.${column.columnName}:''"
@change="${column.columnName}UploadChange"
></file-upload>
</el-form-item>
<!-- 如果字段类型是“视”(视频或文件上传) -->
#elseif($column.type=="视")
<el-form-item label="${column.comments}" prop="${column.columnName}">
<file-upload
tip="点击上传${column.comments}"
action="file/upload"
:limit="1"
:multiple="true"
:fileUrls="ruleForm.${column.columnName}?ruleForm.${column.columnName}:''"
@change="${column.columnName}UploadChange"
></file-upload>
</el-form-item>
<!-- 如果字段类型是“多”(富文本编辑器) -->
#elseif($column.type=="多")
<!-- 如果字段名为 sfsh审核状态 -->
#elseif($column.columnName=="sfsh")
<!-- 如果字段为两步联动字段 -->
#elseif($column.towStep=="是")
<el-form-item label="${column.comments}" prop="${column.columnName}">
<el-select v-model="ruleForm.${column.columnName}" placeholder="请选择${column.comments}">
<el-option key="是" label="是" value="是"></el-option>
<el-option key="否" label="否" value="否"></el-option>
</el-select>
</el-form-item>
<!-- 如果字段为一级联动字段 -->
#elseif($column.type=="联" && $column.level==1)
<el-form-item label="${column.comments}" prop="${column.columnName}">
<el-select @change="oneChange" v-model="ruleForm.${column.columnName}" placeholder="请选择${column.comments}">
<el-option v-bind:key="index" v-for="(item,index) in oneOptions" :label="item" :value="item"></el-option>
</el-select>
</el-form-item>
<!-- 如果字段为二级联动字段 -->
#elseif($column.type=="联" && $column.level==2)
<el-form-item label="${column.comments}" prop="${column.columnName}">
<el-select @change="towChange" v-model="ruleForm.${column.columnName}" placeholder="请选择${column.comments}">
<el-option v-bind:key="index" v-for="(item,index) in towOptions" :label="item" :value="item"></el-option>
</el-select>
</el-form-item>
<!-- 如果字段为三级联动字段 -->
#elseif($column.type=="联" && $column.level==3)
<el-form-item label="${column.comments}" prop="${column.columnName}">
<el-select v-model="ruleForm.${column.columnName}" placeholder="请选择${column.comments}">
<el-option v-bind:key="index" v-for="(item,index) in threeOptions" :label="item" :value="item"></el-option>
</el-select>
</el-form-item>
<!-- 特殊处理:倒计时结束时间字段 -->
#elseif($column.columnName=='reversetime')
<el-form-item label="倒计结束" prop="reversetime">
<el-date-picker
format="yyyy 年 MM 月 dd 日"
value-format="yyyy-MM-dd HH:mm:ss"
v-model="ruleForm.reversetime"
type="date"
placeholder="倒计结束">
</el-date-picker>
</el-form-item>
<!-- 默认情况:普通输入框 -->
#else
<el-form-item label="${column.comments}" prop="${column.columnName}">
<el-input v-model="ruleForm.${column.columnName}"
placeholder="${column.comments}" clearable></el-input>
</el-form-item>
#end
#end
<!-- 富文本字段单独遍历处理 -->
#foreach($column in $columns)
#if($column.columnName != $pk.columnName)
#if($column.type=="多")
<el-form-item label="${column.comments}" prop="${column.columnName}">
<editor
v-model="ruleForm.${column.columnName}"
class="editor"
action="file/upload">
</editor>
</el-form-item>
#end
#end
#end
<!-- 提交与取消按钮 -->
<el-form-item>
<el-button type="primary" @click="onSubmit">提交</el-button>
<el-button @click="back()">取消</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
// 导入数字和整数验证函数
import { isNumber, isIntNumer } from "@/utils/validate";
export default {
data() {
// 数字格式校验函数
var validateNumber = (rule, value, callback) => {
if (!value) {
callback();
} else if (!isNumber(value)) {
callback(new Error("请输入数字"));
} else {
callback();
}
};
// 整数格式校验函数
var validateIntNumber = (rule, value, callback) => {
if (!value) {
callback();
} else if (!isIntNumer(value)) {
callback(new Error("请输入整数"));
} else {
callback();
}
};
return {
// 表单数据对象
ruleForm: {},
// 初始化下拉选项和联动数据结构
#foreach($column in $columns)
#if($column.type=="联" && $column.level==1)
oneOptions:[], // 一级联动选项
#elseif($column.type=="联" && $column.level==2)
towOptions:[], // 二级联动选项
#elseif($column.type=="联" && $column.level==3)
threeOptions:[], // 三级联动选项
#elseif( $column.type == "下" )
${column.columnName}Options: [], // 下拉选项数组
#end
#end
// 表单验证规则集合
rules: {
#foreach($column in $columns)
${column.columnName}: [
#if($column.isNullable == "否")
{ required: true, message: '${column.comments}不能为空', trigger: 'blur' },
#end
#if($column.formatValidation=="数")
{ validator: validateIntNumber, trigger: 'blur' },
#end
#if($column.formatValidation=="浮")
{ validator: validateNumber, trigger: 'blur' },
#end
],
#end
}
};
},
// 接收父组件传递的 props
props: ["parent"],
methods: {
// 初始化方法,根据 ID 获取详情信息
init(id) {
if (id) {
this.info(id);
}
// 如果不是默认用户表,则请求下拉或联动数据
#if($tableName!='defaultuser')
#foreach($column in $columns)
#if($column.type=="联" && $column.level==1)
#[[this.$http({]]#
url: `option/${tableName}/${column.columnName}?level=1`,
method: "get"
}).then(({ data }) => {
if (data && data.code === 0) {
this.oneOptions = data.data;
this.towOptions = [];
this.threeOptions = [];
} else {
#[[this.$message.error(data.msg);]]#
}
});
#elseif( $column.type == "下" )
#[[this.$http({]]#
url: `option/${column.refTable}/${column.refColumn}`,
method: "get"
}).then(({ data }) => {
if (data && data.code === 0) {
this. ${column.columnName}Options = data.data;
} else {
#[[this.$message.error(data.msg);]]#
}
});
#end
#end
#end
},
// 联动字段相关逻辑
#foreach($column in $columns)
#if($column.type=="联" && $column.level==1)
#set($oneColumn = $column.columnName)
#end
#if($column.type=="联" && $column.level==2)
#set($twoColumn = $column.columnName)
// 一级联动变化时触发
oneChange(){
#[[this.$http({]]#
url: `option/${tableName}/${column.columnName}?level=2&parent=` + this.ruleForm.${oneColumn},
method: "get"
}).then(({ data }) => {
if (data && data.code === 0) {
this.twoOptions = data.data;
this.threeOptions = [];
} else {
#[[this.$message.error(data.msg);]]#
}
});
},
#end
#if($column.type=="联" && $column.level==3)
// 二级联动变化时触发
twoChange(){
#[[this.$http({]]#
url: `option/${tableName}/${column.columnName}?level=3&parent=` + this.ruleForm.${twoColumn},
method: "get"
}).then(({ data }) => {
if (data && data.code === 0) {
this.twoOptions = data.data;
this.threeOptions = [];
} else {
#[[this.$message.error(data.msg);]]#
}
});
},
#end
#end
// 获取详情数据
info(id) {
#[[this.$http({]]#
url: `${tableName}/info/#[[${id}]]#`,
method: "get"
}).then(({ data }) => {
if (data && data.code === 0) {
this.ruleForm = data.data;
} else {
#[[this.$message.error(data.msg);]]#
}
});
},
// 表单提交方法
onSubmit() {
#[[this.$refs["ruleForm"].validate(valid => {]]#
if (valid) {
#[[this.$http({]]#
url: `${tableName}/#[[${!this.ruleForm.id]]# ? "save" : "update"}`,
method: "post",
data: this.ruleForm
}).then(({ data }) => {
if (data && data.code === 0) {
#[[this.$message({]]#
message: "操作成功",
type: "success",
duration: 1500,
onClose: () => {
this.parent.showFlag = false;
this.parent.search();
}
});
} else {
#[[this.$message.error(data.msg);]]#
}
});
}
});
},
// 返回上一页
back() {
this.parent.showFlag = false;
},
// 图片或视频上传回调
#foreach($column in $columns)
#if($column.type=="图" || $column.type=="视")
${column.columnName}UploadChange(fileUrls) {
this.ruleForm.${column.columnName} = fileUrls;
},
#end
#end
}
};
</script>
<style lang="scss" scoped>
.editor{
height: 500px; /* 设置富文本编辑器高度 */
}
</style>

@ -0,0 +1,11 @@
// 定义 base 对象,用于存储基础配置信息(如 API 地址、模块名称)
const base = {
// url当前模块的请求基础地址使用 schemaname 动态替换模块名
url : "http://localhost:8080/${schemaname}/",
// name当前模块的名称同样由 schemaname 变量动态填充
name: "${schemaname}"
}
// 导出 base 对象,供其他组件或模块引用
export default base

@ -0,0 +1,51 @@
// 引入 axios 库用于发起 HTTP 请求
import axios from 'axios'
// 引入静态路由模块,用于在请求失败或 token 失效时跳转到登录页
import router from '@/router/router-static'
// 引入本地存储工具模块,用于操作 Token 等信息
import storage from '@/utils/storage'
// 创建一个 axios 实例,配置基础参数
const http = axios.create({
timeout: 1000 * 86400, // 超时时间设置为一天(单位:毫秒)
withCredentials: true, // 允许携带 cookies
baseURL: '/${schemaname}', // 请求的基础路径,使用 schemaname 动态替换模块名
headers: { // 默认请求头
'Content-Type': 'application/json; charset=utf-8' // 指定内容类型为 JSON
}
})
// 请求拦截器:在每次请求发出前做一些处理
http.interceptors.request.use(config => {
// 在请求头中添加 Token 字段,从 storage 中获取当前用户的 Token
config.headers['Token'] = storage.get('Token') // 请求头带上token
// 返回修改后的请求配置对象
return config
}, error => {
// 请求错误时拦截并返回 Promise reject
return Promise.reject(error)
})
// 响应拦截器:在每次响应到达前做一些处理
http.interceptors.response.use(response => {
// 如果响应数据中有 code 且值为 401表示 Token 失效
if (response.data && response.data.code === 401) {
// 清除登录信息(该方法未启用,可根据需要实现)
// clearLoginInfo()
// 跳转到登录页面
router.push({ name: 'login' })
}
// 返回响应结果
return response
}, error => {
// 响应出错时拦截并返回 Promise reject
return Promise.reject(error)
})
// 导出自定义的 axios 实例,供其他组件或模块调用
export default http

@ -0,0 +1,398 @@
<template>
<div class="main-content">
<!-- 列表页 -->
<div v-if="!showFlag">
<!-- 查询表单 -->
<el-form :inline="true" :model="searchForm" class="form-content">
<!-- 遍历字段列表生成查询项 -->
#foreach($column in $columns)
#if($column.queryFlag == "是")
<el-form-item label="${column.comments}">
<!-- 如果字段类型为“日”(日期) -->
#if($column.type == "日")
<el-date-picker
v-model="searchForm.${column.columnName}"
type="date"
placeholder="${column.comments}">
</el-date-picker>
<!-- 如果字段类型为“下”(下拉选择) -->
#elseif( $column.type == "下" )
<el-select v-model="searchForm.${column.columnName}" placeholder="请选择${column.comments}">
<!-- 拆分自定义内容作为选项 -->
#set($array = ${column.customize.split(",")})
#foreach($item in $array)
<el-option
:key="${item}"
:label="${item}"
:value="${item}">
</el-option>
#end
</el-select>
<!-- 默认情况:普通输入框 -->
#else
<el-input v-model="searchForm.${column.columnName}"
placeholder="${column.comments}" clearable></el-input>
#end
</el-form-item>
#end
#end
<!-- 查询、新增、删除按钮组 -->
<el-form-item>
<el-button round @click="search()">查询</el-button>
<el-button
v-if="isAuth('${tableName}','新增')"
type="primary"
@click="addOrUpdateHandler()"
round
>新增</el-button>
<el-button
v-if="isAuth('${tableName}','删除')"
:disabled="dataListSelections.length <= 0"
type="danger"
@click="deleteHandler()"
round
>删除</el-button>
</el-form-item>
</el-form>
<!-- 表格区域 -->
<div class="table-content">
<!-- 数据表格 -->
<el-table
v-if="isAuth('${tableName}','查看')"
:data="dataList"
border
v-loading="dataListLoading"
@selection-change="selectionChangeHandler"
style="width: 100%;">
<!-- 多选列 -->
<el-table-column
type="selection"
header-align="center"
align="center"
width="50">
</el-table-column>
<!-- 遍历字段列表生成表格列 -->
#foreach($column in $columns)
<!-- 图片字段显示为图片 -->
#if($column.type=='图')
<el-table-column prop="${column.columnName}"
header-align="center"
align="center"
width="200"
label="${column.comments}">
<template slot-scope="scope">
<img :src="scope.row.${column.columnName}.split(',')[0]" min-width="100" height="100">
</template>
</el-table-column>
<!-- 视频字段显示为下载按钮 -->
#elseif($column.type=='视')
<el-table-column prop="${column.columnName}"
header-align="center"
align="center"
label="${column.comments}">
<template slot-scope="scope">
<el-button type="text" size="small" @click="download(scope.row.${column.columnName})">下载</el-button>
</template>
</el-table-column>
<!-- 富文本字段不显示在列表中 -->
#elseif($column.type=='多')
<!-- 排除特定字段 -->
#elseif($column.columnName=='clicktime')
#elseif($column.columnName=='reversetime')
#elseif($column.columnName=='clicknum')
<!-- 默认字段作为普通列展示 -->
#else
<el-table-column
prop="${column.columnName}"
header-align="center"
align="center"
sortable
width="200"
label="${column.comments}">
</el-table-column>
#end
#end
<!-- 审核状态列 -->
#if($sfsh=="是")
<el-table-column
prop="sfsh"
header-align="center"
align="center"
sortable
label="审核">
</el-table-column>
#end
<!-- 操作列 -->
<el-table-column
fixed="right"
header-align="center"
align="center"
width="150"
label="操作">
<template slot-scope="scope">
<!-- 审核按钮(仅当 sfsh 为“是”时显示) -->
#if($sfsh=="是")
<el-button type="text" icon="el-icon-edit" size="small" @click="shHandler(scope.row.id,scope.row.sfsh)">审核</el-button>
#end
<!-- 修改按钮 -->
<el-button v-if="isAuth('${tableName}','修改')" type="text" icon="el-icon-edit" size="small" @click="addOrUpdateHandler(scope.row.id)">修改</el-button>
<!-- 删除按钮 -->
<el-button v-if="isAuth('${tableName}','删除')" type="text" icon="el-icon-delete" size="small" @click="deleteHandler(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<el-pagination
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
:current-page="pageIndex"
:page-sizes="[10, 20, 50, 100]"
:page-size="pageSize"
:total="totalPage"
layout="total, sizes, prev, pager, next, jumper"
class="pagination-content"
></el-pagination>
</div>
</div>
<!-- 添加/修改页面 -->
<!-- 将父组件的 search 方法传递给子组件 -->
<add-or-update v-else :parent="this" ref="addOrUpdate"></add-or-update>
</div>
</template>
<script>
// 引入 AddOrUpdate 组件(用于新增或编辑数据)
import AddOrUpdate from "./add-or-update";
export default {
data() {
return {
// 查询表单数据对象
searchForm: {
key: ""
},
// 表格数据列表
dataList: [],
// 当前页码
pageIndex: 1,
// 每页条数
pageSize: 10,
// 总记录数
totalPage: 0,
// 加载状态
dataListLoading: false,
// 多选数据
dataListSelections: [],
// 是否显示添加/修改界面
showFlag: false
};
},
mounted() {
// 页面挂载后执行初始化和加载数据
this.init();
this.getDataList();
},
components: {
// 注册 AddOrUpdate 子组件
AddOrUpdate
},
methods: {
// 初始化方法,处理提醒逻辑
init () {
#foreach($column in $columns)
#if($column.remind=="数")
let url = 'remind/${tableName}/${column.columnName}/1?1=1';
#if($column.remindEnd)
url+=`&remindend=${column.remindEnd}`,
#end
#if($column.remindStart)
url+=`&remindstart=${column.remindStart}`,
#end
#[[this.$http({]]#
url: url,
method: "get",
}).then(({ data }) => {
if (data && data.code == 0 && data.count>0 ) {
#[[this.$alert(`有${data.count}条数据到达预警数量`)]]#
}
});
#elseif($column.remind=="日")
let url = 'remind/${tableName}/${column.columnName}/2?1=1';
#if($column.remindEnd)
url+=`&remindend=${column.remindEnd}`,
#end
#if($column.remindStart)
url+=`&remindstart=${column.remindStart}`,
#end
#[[this.$http({]]#
url: url,
method: "get",
}).then(({ data }) => {
if (data && data.code == 0 && data.count>0 ) {
#[[this.$alert(`有${data.count}条数据到期`)]]#
}
});
#end
#end
},
// 查询方法
search() {
this.pageIndex = 1;
this.getDataList();
},
// 获取数据列表
getDataList() {
this.dataListLoading = true;
#[[this.$http({]]#
url: "${tableName}/page",
method: "get",
params: {
page: this.pageIndex,
limit: this.pageSize,
sort: 'id',
#foreach($column in $columns)
#if($column.queryFlag == "是")
${column.columnName} : this.searchForm.${column.columnName},
#end
#end
}
}).then(({ data }) => {
if (data && data.code === 0) {
this.dataList = data.data.list;
this.totalPage = data.data.total;
} else {
this.dataList = [];
this.totalPage = 0;
}
this.dataListLoading = false;
});
},
// 每页条数变化时触发
sizeChangeHandle(val) {
this.pageSize = val;
this.pageIndex = 1;
this.getDataList();
},
// 当前页码变化时触发
currentChangeHandle(val) {
this.pageIndex = val;
this.getDataList();
},
// 多选变化时触发
selectionChangeHandler(val) {
this.dataListSelections = val;
},
// 打开新增/修改弹窗
addOrUpdateHandler(id) {
this.showFlag = true;
#[[this.$nextTick(() => {]]#
#[[this.$refs.addOrUpdate.init(id);]]#
});
},
// 审核操作
shHandler(id,sfsh){
if(sfsh=="是"){
sfsh = '否'
}else{
sfsh = '是'
}
#[[this.$confirm(`确定操作?`, "提示", {]]#
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
#[[this.$http({]]#
url: "sh/${tableName}",
method: "post",
data: {
id:id,
sfsh:sfsh
}
}).then(({ data }) => {
if (data && data.code === 0) {
#[[this.$message({]]#
message: "操作成功",
type: "success",
duration: 1500,
onClose: () => {
this.getDataList();
}
});
} else {
#[[this.$message.error(data.msg);]]#
}
});
});
},
// 下载文件方法
download(file){
window.open(`#[[${file}]]#`)
},
// 删除操作
deleteHandler(id) {
var ids = id
? [Number(id)]
: this.dataListSelections.map(item => {
return Number(item.id);
});
#[[this.$confirm(`确定进行[${id ? "删除" : "批量删除"}]操作?`, "提示", {]]#
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
#[[this.$http({]]#
url: "${tableName}/delete",
method: "post",
data: ids
}).then(({ data }) => {
if (data && data.code === 0) {
#[[this.$message({]]#
message: "操作成功",
type: "success",
duration: 1500,
onClose: () => {
this.search();
}
});
} else {
#[[this.$message.error(data.msg);]]#
}
});
});
}
}
};
</script>
<style lang="scss" scoped>
/* 当前样式为空,可根据需求添加自定义样式 */
</style>

@ -0,0 +1,109 @@
<template>
<!-- 页面根容器 -->
<div>
<!-- 登录背景图片 -->
<img class="bg" src="@/assets/img/bg.jpg">
<!-- 登录表单 -->
<el-form :model="rulesForm" :rules="rules" ref="rulesForm" class="login-form">
<!-- 登录标题 -->
<h1 class="h1">管理员登陆</h1>
<!-- 用户名输入项 -->
<el-form-item label="账号" prop="username">
<el-input type="text" v-model="rulesForm.username"></el-input>
</el-form-item>
<!-- 密码输入项 -->
<el-form-item label="密码" prop="password">
<el-input type="password" v-model="rulesForm.password"></el-input>
</el-form-item>
<!-- 角色选择项 -->
<el-form-item label="" prop="role">
<!-- 循环渲染角色选项 -->
<el-radio v-for="item in menus"
v-bind:key="item.roleName"
v-model="rulesForm.role"
:label="item.roleName">
{{item.roleName}}
</el-radio>
</el-form-item>
<!-- 登录按钮 -->
<el-button @click="login()" class="btn-login" type="primary">登陆</el-button>
</el-form>
</div>
</template>
<script>
// 引入菜单工具模块,用于获取角色列表
import menu from '@/utils/menu'
export default {
data() {
return {
// 表单数据对象
rulesForm: {
username: "", // 用户名
password: "", // 密码
role: "" // 角色
},
menus:[], // 菜单(角色)列表
tableName:"users", // 默认登录表名为 users
// 表单验证规则
rules: {
username: [{ required: true, message: "请输入账号", trigger: "blur" }],
password: [{ required: true, message: "请输入密码", trigger: "blur" }]
}
};
},
mounted(){
// 页面挂载后获取角色列表
let menus = menu.list();
this.menus = menus;
},
methods: {
// 登录方法
login() {
#[[this.$refs["rulesForm"].validate(valid => {]]#
// 根据选中的角色查找对应的数据库表名
let menus = this.menus;
for(let i=0;i<menus.length;i++){
if(menus[i].roleName==this.rulesForm.role){
this.tableName = menus[i].tableName
}
}
// 如果表单验证通过
if (valid) {
#[[this.$http({]]#
url: `#[[${this.tableName}]]#/login?username=#[[${this.rulesForm.username}&password=${this.rulesForm.password}]]#`,
method: "post"
}).then(({ data }) => {
if (data && data.code === 0) {
// 登录成功,保存 Token 和角色信息
#[[this.$storage.set("Token", data.token);]]#
#[[this.$storage.set("role", this.rulesForm.role);]]#
// 跳转到首页
#[[this.$router.replace({ path: "/index/" });]]#
} else {
// 登录失败提示错误信息
#[[this.$message.error(data.msg);]]#
}
});
}
});
}
}
};
</script>
<style lang="scss" scoped>
/* 当前样式为空,可在此添加自定义样式 */
</style>

@ -0,0 +1,11 @@
// 定义一个名为 menu 的对象,用于管理菜单数据
const menu = {
// list 方法用于返回菜单列表数据
list() {
// 返回 ${roleMenus},该变量由模板引擎动态替换为不同角色的菜单配置
return ${roleMenus}
}
}
// 导出 menu 对象,供其他模块引用
export default menu

@ -0,0 +1,54 @@
// 引入 Vue 核心库
import Vue from 'vue';
// 配置路由:引入 VueRouter 插件
import VueRouter from 'vue-router';
Vue.use(VueRouter); // 安装 VueRouter 插件
// 1. 创建组件:导入需要用到的页面组件
import Index from '@/views/index'; // 主页框架(包含头部、侧边栏等)
import Home from '@/views/home'; // 首页内容组件
import Login from '@/views/login'; // 登录页组件
import NotFound from '@/views/404'; // 404 页面组件
// 动态导入后台菜单相关的模块列表组件(使用 Velocity 模板循环生成)
#foreach($tableName in $backMenuTables)
import ${tableName} from '@/views/modules/${tableName}/list'
#end
// 2. 配置路由规则
const routes = [
{
path: '/index', name:'index', component: Index, children: [
// 默认子路由:访问 /index 自动跳转到首页
{
path: '/',
name: 'home',
component: Home
},
// 动态生成后台菜单对应的路由(每个表一个路由)
#foreach($tableName in $backMenuTables)
,{
path: '/${tableName}',
name: '${tableName}',
component: ${tableName}
}
#end
]
},
// 登录页路由
{ path: '/login', name:'login', component: Login },
// 默认跳转至首页
{ path: '/', redirect: '/index/' },
// 所有未匹配路径都跳转到 404 页面
{ path: '*', component: NotFound }
];
// 3. 实例化 VueRouter 路由对象
const router = new VueRouter({
mode: 'hash', /* 使用 hash 模式,也可改为 history 模式 */
routes /* 简写形式,相当于 routes: routes */
})
// 导出路由实例,供 main.js 使用
export default router;

@ -0,0 +1,65 @@
// 引入 path 模块,用于处理路径
const path = require('path')
// 定义 resolve 函数用于快速拼接路径__dirname 表示当前文件所在目录
function resolve(dir) {
return path.join(__dirname, dir)
}
// 定义 publicPath 函数,根据环境变量决定资源引用路径
function publicPath(){
if (process.env.NODE_ENV == 'production') {
// 生产环境使用相对路径 "././"
return "././";
} else {
// 开发环境使用绝对路径 "/"
return "/";
}
}
// vue.config.js 配置导出对象
module.exports = {
// 设置项目公共资源的基础路径,调用 publicPath() 动态判断
publicPath: publicPath(),
// 国际化配置:如果需要切换语言包,可以取消下面插件的注释,并调整路径
configureWebpack: {
// plugins: [
// new webpack.NormalModuleReplacementPlugin(
// /element-ui[\/\\]lib[\/\\]locale[\/\\]lang[\/\\]zh-CN/,
// 'element-ui/lib/locale/lang/en'
// )
// ]
// 配置 Webpack 的解析规则
resolve: {
alias: {
// 设置别名 '@' 指向 src 目录,方便导入模块
'@': resolve('src')
}
}
},
// 开发服务器配置(仅在开发环境生效)
devServer: {
host: "0.0.0.0", // 指定开发服务器监听的 host默认是 localhost
port: 8081, // 指定开发服务器运行端口为 8081
hot: true, // 启用热更新功能(修改代码后无需刷新页面)
https: false, // 是否启用 HTTPS 模式(默认不启用)
// 配置请求代理,解决跨域问题
proxy: {
// 所有以 '/${schemaname}' 开头的请求都会被代理到目标服务器
'/${schemaname}': {
target: 'http://localhost:8080/${schemaname}/', // 要代理的目标服务器地址
changeOrigin: true, // 允许改变请求头中的 origin 字段为目标地址
secure: false, // 不验证 SSL 证书(适用于自签名 SSL 证书)
// 请求路径重写:将路径中开头的 '/${schemaname}' 替换为空字符串
pathRewrite: {
'^/${schemaname}': ''
}
}
}
}
}
Loading…
Cancel
Save