This commit is contained in:
jiangrui 2021-04-30 09:59:43 +08:00
commit 801cb4b618
30 changed files with 2348 additions and 271 deletions

View File

@ -4,3 +4,4 @@ ENV = 'development'
# base api
#VUE_APP_BASE_API = '/dev-api'
VUE_APP_BASE_API = 'http://app.rt.xianci.info/'
#VUE_APP_BASE_API = 'http://api.rt.myntv.cn/'

1
.gitignore vendored
View File

@ -2,6 +2,7 @@
node_modules/
convenience-prod/
dist/
convenience-prod/
npm-debug.log*
yarn-debug.log*
yarn-error.log*

View File

@ -37,6 +37,7 @@
"tui-editor": "1.3.3",
"vue": "2.6.10",
"vue-count-to": "1.0.13",
"vue-cropper": "^0.5.3",
"vue-router": "3.0.2",
"vue-splitpane": "1.0.4",
"vuedraggable": "2.20.0",

View File

@ -12,6 +12,11 @@
<!--这里加载的语言文件会覆盖你在配置项目里添加的语言类型,比如你在配置项目里配置的是英文,这里加载的中文,那最后就是中文-->
<script type="text/javascript" charset="utf-8" src="<%= BASE_URL %>ueditor/lang/zh-cn/zh-cn.js"></script>
<title><%= webpackConfig.name %></title>
<script type="text/javascript" charset="utf-8" src="<%= BASE_URL %>ueditor/ueditor.config.js"></script>
<script type="text/javascript" charset="utf-8" src="<%= BASE_URL %>ueditor/ueditor.all.js"> </script>
<!--建议手动加在语言避免在ie下有时因为加载语言失败导致编辑器加载失败-->
<!--这里加载的语言文件会覆盖你在配置项目里添加的语言类型,比如你在配置项目里配置的是英文,这里加载的中文,那最后就是中文-->
<script type="text/javascript" charset="utf-8" src="<%= BASE_URL %>ueditor/lang/zh-cn/zh-cn.js"></script>
</head>
<body>
<div id="app"></div>

View File

@ -2,7 +2,7 @@ import request from '@/utils/request'
/**
* 工单列表
* @param {YW_Content_Code,YW_Type_Code} data
* @param {Object}} data
* @returns
*/
export function list(data) {
@ -26,7 +26,7 @@ export function typeList() {
/**
* 发起办事
* @param {residentInformation,eventTypeId,sponsor,remark,Attachment} data
* @param {Object} data
* @returns
*/
export function add(data) {
@ -39,7 +39,7 @@ export function add(data) {
/**
* 工单详情
* @param {工单id} id
* @param {String} id
* @returns
*/
export function info(id) {
@ -52,7 +52,7 @@ export function info(id) {
/**
* 工单操作
* @param {id,version,type,ids,remark,attachmentList,approve,evaluation} data
* @param {Object} data
* @returns
*/
export function update(data) {
@ -65,7 +65,7 @@ export function update(data) {
/**
* 获取沟通人员列表
* @param {id} data
* @param {String} data
* @returns
*/
export function communicationList(data) {

14
src/api/region.js Normal file
View File

@ -0,0 +1,14 @@
import request from "@/utils/request";
/**
* 行政区域列表
* @param {*} data
* @returns
*/
export function getRegions() {
return request({
// /api/convenience/v2/region/list
url: "/api/convenience/v2/region/list",
method: "get"
});
}

View File

@ -0,0 +1,54 @@
import request from "@/utils/request";
/**
* 居民信息列表
* @param {*} data
* @returns
*/
export function getResidentInfoList(data) {
return request({
url: "/api/convenience/residentInformation/list",
method: "post",
data
});
}
/**
* 添加居民信息
* @param {*} data
* @returns
*/
export function addResidentInfoList(data) {
return request({
url: "/api/convenience/residentInformation/add",
method: "post",
data
});
}
/**
* 居民信息修改
* @param {*} data
* @returns
*/
export function updateResidentInfo(data) {
return request({
url: "/api/convenience/residentInformation",
method: "put",
data
});
}
/**
* 居民信息删除
* @param {*} id
* @returns
*/
export function deleteResident(id) {
return request({
url: "/api/convenience/residentInformation",
method: "delete",
params:id
});
}

View File

@ -1,13 +1,21 @@
import request from '@/utils/request'
import request from "@/utils/request";
/**
* 通讯录
* @returns
*/
export function staffList() {
// export function staffList() {
// return request({
// url: "/api/convenience/v2/staff/list",
// method: "post",
// data: { category: "CONVENIENCE" }
// });
// }
export function staffList(data) {
return request({
url: '/api/convenience/v2/staff/list',
method: 'post'
method: 'post',
data
})
}
@ -18,8 +26,8 @@ export function staffList() {
*/
export function info(data) {
return request({
url: '/api/convenience/v2/staff/info',
method: 'get',
url: "/api/convenience/v2/staff/info",
method: "get",
params: data
})
});
}

View File

@ -1,5 +1,10 @@
import request from '@/utils/request'
/**
* 工作手册列表
* @param {Object}} data
* @returns
*/
export function workBookList(data) {
return request({
url: '/api/convenience/workBook/list',
@ -7,3 +12,16 @@ export function workBookList(data) {
data
})
}
/**
* 工作手册详情
* @param {String} id
* @returns
*/
export function getWorkBookInfo(id) {
return request({
url: '/api/convenience/workBook/detail',
method: 'get',
params:id
})
}

View File

@ -0,0 +1,73 @@
<template>
<el-cascader
v-model="regionNames"
style="width:240px"
:options="regions"
:props="{ checkStrictly: true }"
placeholder="行政区域"
@change="emitSelectValue"
clearable
/>
</template>
<script>
import { getRegions } from "@/api/region";
export default {
data() {
return {
regionNames: [],
regions: []
};
},
// props:['organizationAttribution','permanentResidenceRegion','permanentResidenceTown'],
props: ["_regionNames"],
created() {
this.getList();
this.regionNames = this._regionNames;
console.log(233);
console.log(this.regionNames);
},
mounted(){
console.log(244);
},
methods: {
getList() {
getRegions().then(res => {
const tempData = res.d;
const countyArr = []; // ,1
tempData.map(county => {
const countyObj = {
value: county.root.name,
label: county.root.name,
disabled: true,
children: []
};
countyArr.push(countyObj);
county.node.map(town => {
const townObj = {
value: town.root.name,
label: town.root.name,
disabled: !town.root.check,
children: []
};
countyObj.children.push(townObj);
town.node.map(country => {
townObj.children.push({
value: country.root.name,
label: country.root.name,
disabled: !country.root.check,
});
});
});
});
this.regions = countyArr;
});
},
emitSelectValue(val) {
this.$emit("input", val);
}
}
};
</script>
<style></style>

View File

@ -0,0 +1,370 @@
<template>
<div>
<!-- 多图片上传 -->
<el-upload
v-if="multiple"
action="string"
list-type="picture-card"
:on-preview="handlePreview"
:auto-upload="false"
:on-remove="handleRemove"
:http-request="upload"
:on-change="consoleFL"
:file-list="uploadList"
>
<i class="el-icon-plus" />
</el-upload>
<!-- 单图片上传 -->
<el-upload
v-else
class="avatar-uploader"
action="'string'"
:auto-upload="false"
:show-file-list="false"
:on-change="handleCrop"
:http-request="upload"
>
<img
v-if="imageUrl"
ref="singleImg"
:src="imageUrl"
class="avatar"
:style="{ width: width + 'px', height: height + 'px' }"
@mouseenter="mouseEnter"
@mouseleave="mouseLeave"
/>
<i
v-else
class="el-icon-plus avatar-uploader-icon"
:style="{
width: width + 'px',
height: height + 'px',
'line-height': height + 'px',
'font-size': height / 6 + 'px'
}"
/>
<!-- 单图片上传状态显示 -->
<!-- <div v-if="imageUrl" class="reupload" ref="reupload" @click.stop="handlePreviewSingle" @mouseenter="mouseEnter" @mouseleave="mouseLeave" :style="{width:reuploadWidth+'px',height:reuploadWidth+'px','line-height':reuploadWidth+'px','font-size':reuploadWidth/5+'px'}">重新上传</div> -->
<div
v-if="imageUrl"
id="uploadIcon"
ref="reupload"
:style="{ width: '100%' }"
@mouseenter="mouseEnter"
@mouseleave="mouseLeave"
>
<i
class="el-icon-zoom-in"
:style="{
color: '#2E2E2E',
fontSize: '25px',
display: 'inline-block',
paddingRight: '15px'
}"
@click.stop="handlePreviewSingle"
/>
<!-- <i class="el-icon-upload" :style="{color:'#2E2E2E',fontSize:'25px',display:'inline-block'}" /> -->
<i
class="el-icon-delete"
:style="{
color: '#2E2E2E',
fontSize: '25px',
display: 'inline-block'
}"
@click.stop="handlePicRemove"
/>
</div>
<div
ref="uploading"
class="reupload"
:style="{
width: reuploadWidth + 'px',
height: reuploadWidth + 'px',
'line-height': reuploadWidth + 'px',
'font-size': reuploadWidth / 5 + 'px'
}"
>
上传中..
</div>
<div
ref="failUpload"
class="reupload"
:style="{
width: reuploadWidth + 'px',
height: reuploadWidth + 'px',
'line-height': reuploadWidth + 'px',
'font-size': reuploadWidth / 5 + 'px'
}"
>
上传失败
</div>
</el-upload>
<!-- 多图片预览弹窗 -->
<el-dialog :visible.sync="dialogVisible" append-to-body>
<img width="100%" :src="dialogImageUrl" alt="" />
</el-dialog>
<!-- 剪裁组件弹窗 -->
<el-dialog
:visible.sync="cropperModel"
:width="news ? '990px' : '800px'"
:before-close="beforeClose"
append-to-body
>
<Cropper
ref="vueCropper"
:img-file="file"
:fixed-number="fixedNumber"
:news="news"
@upload="upload"
/>
</el-dialog>
</div>
</template>
<script>
import Cropper from "@/components/uploader/cropper";
// import axios from 'axios'
import OSS from "@/utils/aliOSS";
import UUID from "uuidjs";
export default {
name: "Uploader",
components: {
Cropper
},
props: {
targetUrl: {
//
type: String,
default: "http://120.77.82.246:6789/api/postUpLoadFiles"
},
multiple: {
//
type: Boolean,
default: false
},
initUrl: {
//
default: ""
},
fixedNumber: {
//
default: function() {
return [3, 1];
}
},
news: {
type: Boolean,
default: false
},
width: {
//
type: Number,
default: 178
},
height: {
//
type: Number,
default: 178
}
},
data() {
return {
file: "", //
imageUrl: "", //
dialogImageUrl: "", //
uploadList: [], //
reupload: true, // ""
dialogVisible: false, //
cropperModel: false, //
reuploadWidth: this.height * 0.7 //
};
},
watch: {
initUrl: function(val) {
//
console.info("watch");
console.info(val);
if (val) {
if (typeof this.initUrl === "string") {
this.imageUrl = val;
} else {
this.uploadList = this.formatImgArr(val);
}
} else {
this.imageUrl = "";
this.uploadList = [];
}
}
},
updated() {
if (this.$refs.vueCropper) {
this.$refs.vueCropper.Update();
}
},
mounted() {
if (typeof this.initUrl === "string") {
this.imageUrl = this.initUrl;
} else {
this.uploadList = this.formatImgArr(this.initUrl);
}
},
methods: {
/** **************************** multiple多图情况 **************************************/
handlePreview(file) {
//
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
handleRemove(file, fileList) {
//
this.uploadList = fileList;
this.$emit("imgupload", this.formatImgArr(this.uploadList));
},
handlePicRemove(file) {
this.imageUrl = "";
this.$emit("imgupload", this.imageUrl);
},
consoleFL(file, fileList) {
//
this.cropperModel = true;
this.file = file;
this.uploadList = fileList;
},
/** **********************************************************************************/
/** **************************** single单图情况 **************************************/
handlePreviewSingle(file) {
//
// this.dialogImageUrl = this.file.url
this.dialogImageUrl = this.imageUrl;
this.dialogVisible = true;
},
mouseEnter() {
//
this.$refs.reupload.style.display = "block";
if (this.$refs.failUpload.style.display === "block") {
this.$refs.failUpload.style.display = "none";
}
this.$refs.singleImg.style.opacity = "0.6";
},
mouseLeave() {
//
this.$refs.reupload.style.display = "none";
this.$refs.singleImg.style.opacity = "1";
},
handleCrop(file, files) {
file.url = URL.createObjectURL(file.raw);
// console.log(file)
//
this.cropperModel = true;
this.file = file;
// this.imageUrl = file.url
},
/** **********************************************************************************/
upload(data) {
// upload
if (!this.multiple) {
//
this.$refs.uploading.style.display = "block";
}
// const formData = new FormData()
// formData.append('file', data, '123.png')
// axios.defaults.withCredentials = false
// axios.post(this.targetUrl, formData, { headers: { 'Content-Type': 'multipart/form-data' }}).then(res => {
const name = UUID.generate() + ".png";
OSS(data, name).then(res => {
if (!this.multiple) {
//
this.$refs.uploading.style.display = "none";
}
// console.log(res)
if (res.res.status === 200) {
//
const currentPic = res.url;
if (this.multiple) {
this.uploadList.pop();
this.uploadList.push({
url: currentPic,
uid: "111"
});
// console.log(this.formatImgArr(this.uploadList))
this.$emit("imgupload", this.formatImgArr(this.uploadList));
} else {
this.$emit("imgupload", currentPic);
}
} else {
this.$message({
type: "warning",
message: "上传失败!"
});
//
if (!this.multiple) {
this.$refs.failUpload.style.display = "block";
} else {
this.uploadList.pop();
}
}
});
this.cropperModel = false;
},
formatImgArr(arr) {
// console.log(arr);
if (arr) {
const result = arr.map((item, index) => {
if (typeof item === "string") {
return {
url: item,
uid: `index${index}`
};
} else {
return item.url;
}
});
return result;
}
},
beforeClose(done) {
this.uploadList.pop();
this.cropperModel = false;
}
}
};
</script>
<style>
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409eff;
}
.avatar-uploader-icon {
color: #8c939d;
text-align: center;
}
.avatar {
display: block;
}
.reupload {
border-radius: 50%;
position: absolute;
color: #fff;
background-color: #000000;
opacity: 0.6;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: none;
}
#uploadIcon {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: none;
}
</style>

View File

@ -0,0 +1,596 @@
<template>
<div>
<div v-if="news" class="font-box">
<span />
<span style="margin-right: 70px">热门预览</span>
<span style="margin-right: 6px">非热门预览</span>
</div>
<div class="cropper-content">
<!-- 剪裁框 -->
<div class="cropper">
<vueCropper
ref="cropper"
:img="option.img"
:output-size="option.size"
:output-type="option.outputType"
:info="true"
:full="option.full"
:can-move="option.canMove"
:can-move-box="option.canMoveBox"
:original="option.original"
:auto-crop="option.autoCrop"
:auto-crop-width="option.autoCropWidth"
:auto-crop-height="option.autoCropHeight"
:fixed-box="option.fixedBox"
:fixed="option.fixed"
:fixed-number="fixedNumber"
@realTime="realTime"
/>
</div>
<!-- 预览框 -->
<div class="show-preview" :style="{'width': '300px', 'height': '300px', 'overflow': 'hidden', 'margin': '0 25px', 'display':'flex', 'align-items' : 'center'}" @mousedown="previewContainerDown" @mousemove="previewContainerMove" @mouseup="previewContainerUp" @mouseleave="previewContainerLeave">
<div :style="previews.div" style="position: relative">
<div :ref="previewId" :style="previews.div" class="preview">
<img :src="previews.url" :style="previews.img">
<img v-if="water.url" :src="water.url" :style="water.img" class="water">
</div>
<div v-show="water.url" :style="previews.div" class="water-cropper">
<!-- @mousemove.self="cropMove" -->
<div class="crop-box" :style="water.img" @mousedown.self="cropDown">
<span class="crop-line line-w" />
<span class="crop-line line-a" />
<span class="crop-line line-s" />
<span class="crop-line line-d" />
<span class="crop-point point1" @mousedown.stop="pointDown($event, 'lt')" />
<span class="crop-point point2" @mousedown.stop="pointDown($event, 'rt')" />
<span class="crop-point point3" @mousedown.stop="pointDown($event, 'lb')" />
<span class="crop-point point4" @mousedown.stop="pointDown($event, 'rb')" />
</div>
</div>
</div>
</div>
<!-- 新闻预览框 -->
<div v-if="news" class="news-preview" :style="{'width': '200px', 'height': '300px', 'overflow': 'hidden', 'margin': '0', 'display':'flex', 'align-items' : 'center'}">
<!-- <div class="news-box"> -->
<div :ref="previewId" :style="previews.div" class="preview">
<img :src="previews.url" :style="previews.img" style="margin-left: -75px">
<img v-if="water.url" :src="water.url" :style="water.img" style="margin-left: -75px" class="water">
</div>
<!-- </div> -->
</div>
</div>
<div class="footer-btn">
<!-- 缩放旋转按钮 -->
<div class="scope-btn">
<el-button type="primary" icon="el-icon-zoom-in" @click="changeScale(1)" />
<el-button type="primary" icon="el-icon-zoom-out" @click="changeScale(-1)" />
<el-button type="primary" @click="rotateLeft">逆时针旋转</el-button>
<el-button type="primary" @click="rotateRight">顺时针旋转</el-button>
</div>
<!-- 确认上传按钮 -->
<div class="upload-btn">
<el-button type="primary" @click="uploadImg('blob')">上传</el-button>
<el-button type="primary" @click="selectWater">选择水印</el-button>
<el-button type="primary" @click="water.url = null">取消水印</el-button>
<!-- <input type="file" name="" id="" accept=""> -->
</div>
</div>
</div>
</template>
<script>
// import VueCropper from 'vue-cropper'
// import html2canvas from 'html2canvas'
// import { createElement } from 'dropzone'
export default {
props: ['imgFile', 'fixedNumber', 'news'],
data() {
name:'Cropper'
return {
previewId: 'waterProview' + Date.parse(new Date()),
previews: {}, //
option: {
img: '', // ()
size: 1, // (:1)
full: true, // true (:false)
outputType: 'png', // (:jpg)
canMove: true, // (:true)
original: false, // (:false)
canMoveBox: true, // (:true)
autoCrop: true, // (:false)
autoCropWidth: 400, // (:80%)
autoCropHeight: 400, // (:80%)
fixedBox: false, // (:false)
fixed: true, // (:true)
fixedNumber: [1.5, 1] // (:[1:1])
},
downImg: '#',
//
waterUrl: null,
water: {
url: null,
img: {
width: '100px',
height: '100px',
left: '0px',
top: '0px'
}
},
waterBox: {
left: 0,
top: 0,
width: 100,
height: 100,
scale: 1,
prop: 1
},
waterInfo: {
waterX: 0,
waterY: 0,
x: 0,
y: 0
},
waterMove: false,
pointInfo: {
pointX: 0,
pointY: 0,
x: 0,
y: 0,
width: 0,
height: 0
},
pointType: null,
pointIsMove: false,
successimg: null
}
},
watch: {
waterBox: {
handler(newValue, oldValue) {
// console.log(newValue)
this.water.img.left = newValue.left + 'px'
this.water.img.top = newValue.top + 'px'
this.water.img.width = newValue.width + 'px'
this.water.img.height = newValue.height + 'px'
},
deep: true
}
},
methods: {
changeScale(num) {
//
num = num || 1
this.$refs.cropper.changeScale(num)
},
rotateLeft() {
//
console.log(this.$refs.cropper)
this.$refs.cropper.rotateLeft()
},
rotateRight() {
//
console.log(this.$refs.cropper)
this.$refs.cropper.rotateRight()
},
Update() {
// this.file = this.imgFile
this.option.img = this.imgFile.url
},
realTime(data) {
//
this.previews = data
},
uploadImg(type) {
//
event.preventDefault()
const that = this
this.$refs.cropper.getCropData(async data => {
// that.$emit('upload', data)
let cropInfo, waterInfo
if (!this.water.url) {
if (type === 'blob') {
this.$refs.cropper.getCropBlob(data => {
that.$emit('upload', data)
})
} else {
this.$refs.cropper.getCropData(data => {
that.$emit('upload', data)
})
}
}
await (() => {
const cropImg = new Image()
cropImg.src = data
cropImg.onload = () => {
cropInfo = {
img: cropImg,
width: cropImg.width,
height: cropImg.height,
x: 0,
y: 0
}
const waterImg = new Image()
waterImg.crossOrigin = ''
waterImg.src = this.water.url
waterImg.onload = () => {
waterInfo = {
img: waterImg,
width: this.waterBox.width,
height: this.waterBox.height,
x: this.waterBox.left,
y: this.waterBox.top
}
// console.log(cropInfo)
// console.log(waterInfo)
const canvas = document.createElement('canvas')
canvas.width = cropInfo.width
canvas.height = cropInfo.height
const ctx = canvas.getContext('2d')
ctx.drawImage(cropInfo.img, cropInfo.x, cropInfo.y, cropInfo.width, cropInfo.height)
// console.log(this.previews.div)
const prop = cropInfo.width / parseFloat(this.previews.div.width)
ctx.drawImage(waterInfo.img, waterInfo.x * prop, waterInfo.y * prop, waterInfo.width * prop, waterInfo.height * prop)
// console.log(this.previews)
if (type === 'blob') {
canvas.toBlob((blob) => {
that.$emit('upload', blob)
})
} else {
that.$emit('upload', canvas.toDataURL('image/png'))
}
/*
// canvas
const canvas = document.createElement('canvas')
// DOM
const canvasDom = this.$refs[this.previewId]
//
const width = parseInt(window.getComputedStyle(canvasDom).width)
const height = parseInt(window.getComputedStyle(canvasDom).height)
// 2
canvas.width = width * 2
canvas.height = height * 2
canvas.style.width = width + 'px'
canvas.style.height = height + 'px'
const context = canvas.getContext('2d')
context.scale(2, 2)
const options = {
backgroundColor: null,
canvas: canvas,
useCORS: true
}
console.log(123)
html2canvas(canvasDom, options).then(canvas => {
// console.log(canvas.toDataURL('image/png'))
// that.successimg = canvas.toDataURL('image/png')
//
if (type === 'blob') {
console.log('blob')
canvas.toBlob((blob) => {
that.$emit('upload', blob)
})
} else {
that.$emit('upload', canvas.toDataURL('image/png'))
}
})
*/
}
}
})()
})
// return
//
// if (type === 'blob') {
// this.$refs.cropper.getCropBlob(data => {
// that.$emit('upload', data)
// })
// } else {
// this.$refs.cropper.getCropData(data => {
// that.$emit('upload', data)
// })
// }
},
//
selectWater() { //
const input = document.createElement('input')
input.type = 'file'
input.accept = 'image/*'
input.addEventListener('change', (e) => {
const file = e.path[0].files[0]
const imgURL = window.URL.createObjectURL(file)
const image = new Image()
image.src = imgURL
image.onload = () => {
this.water.url = imgURL
const { width, height } = image
const prop = width / height
this.waterBox.prop = prop
this.waterBox.height = 100
this.waterBox.width = 100 * prop
}
})
setTimeout(() => {
input.click()
}, 100)
},
previewContainerDown(e) {
},
previewContainerMove(e) {
if (this.waterMove) {
this.cropMove(e)
} else if (this.pointIsMove) {
this.pointMove(e)
}
},
previewContainerUp() {
this.waterMove = false
this.pointIsMove = false
},
previewContainerLeave() {
this.waterMove = false
this.pointIsMove = false
},
cropDown(e) {
const { clientX, clientY } = e
this.waterInfo.x = this.waterBox.left
this.waterInfo.y = this.waterBox.top
this.waterInfo.waterX = clientX
this.waterInfo.waterY = clientY
this.waterMove = true
},
cropMove(e) {
if (this.waterMove) {
const { clientX, clientY } = e
this.waterBox.left = (clientX - this.waterInfo.waterX) + this.waterInfo.x
this.waterBox.top = (clientY - this.waterInfo.waterY) + this.waterInfo.y
}
},
//
pointDown(e, type) {
const { clientX, clientY } = e
this.pointInfo.x = this.waterBox.left
this.pointInfo.y = this.waterBox.top
this.pointInfo.width = this.waterBox.width
this.pointInfo.height = this.waterBox.height
this.pointInfo.pointX = clientX
this.pointInfo.pointY = clientY
this.pointType = type
this.pointIsMove = true
},
pointMove(e) {
if (this.pointIsMove) {
const { clientX, clientY } = e
const left = (clientX - this.pointInfo.pointX) + this.pointInfo.x
const top = (clientY - this.pointInfo.pointY) + this.pointInfo.y
if (this.pointType === 'lt') {
this.waterBox.left = left
this.waterBox.top = top
const height = this.pointInfo.height - (clientY - this.pointInfo.pointY)
this.waterBox.height = height
this.waterBox.width = height * this.waterBox.prop
// this.waterBox.width = this.pointInfo.width - (clientX - this.pointInfo.pointX)
// this.waterBox.height = this.pointInfo.height - (clientY - this.pointInfo.pointY)
} else if (this.pointType === 'rt') {
this.waterBox.top = top
const height = this.pointInfo.height - (clientY - this.pointInfo.pointY)
this.waterBox.height = height
this.waterBox.width = height * this.waterBox.prop
// this.waterBox.width = this.pointInfo.width + (clientX - this.pointInfo.pointX)
// this.waterBox.height = this.pointInfo.height - (clientY - this.pointInfo.pointY)
} else if (this.pointType === 'lb') {
this.waterBox.left = left
const height = this.pointInfo.height + (clientY - this.pointInfo.pointY)
this.waterBox.height = height
this.waterBox.width = height * this.waterBox.prop
// this.waterBox.width = this.pointInfo.width - (clientX - this.pointInfo.pointX)
// this.waterBox.height = this.pointInfo.height + (clientY - this.pointInfo.pointY)
} else if (this.pointType === 'rb') {
const height = this.pointInfo.height + (clientY - this.pointInfo.pointY)
this.waterBox.height = height
this.waterBox.width = height * this.waterBox.prop
// this.waterBox.width = this.pointInfo.width + (clientX - this.pointInfo.pointX)
// this.waterBox.height = this.pointInfo.height + (clientY - this.pointInfo.pointY)
}
}
}
}
// components: { VueCropper }
}
</script>
<style>
.cropper-content {
display: flex;
display: -webkit-flex;
justify-content: flex-end;
-webkit-justify-content: flex-end;
}
.cropper-content .cropper {
width: 350px;
height: 300px;
}
.cropper-content .show-preview {
flex: 1;
-webkit-flex: 1;
display: flex;
display: -webkit-flex;
justify-content: center;
-webkit-justify-content: center;
overflow: hidden;
border: 1px solid #cccccc;
background: #cccccc;
margin-left: 40px;
}
.preview {
overflow: hidden;
border: 1px solid #cccccc;
background: #cccccc;
}
.footer-btn {
margin-top: 30px;
display: flex;
display: -webkit-flex;
justify-content: flex-end;
-webkit-justify-content: flex-end;
}
.footer-btn .scope-btn {
width: 380px;
display: flex;
display: -webkit-flex;
justify-content: space-between;
-webkit-justify-content: space-between;
}
.footer-btn .upload-btn {
flex: 1;
-webkit-flex: 1;
display: flex;
display: -webkit-flex;
justify-content: center;
-webkit-justify-content: center;
}
.footer-btn .btn {
outline: none;
display: inline-block;
line-height: 1;
white-space: nowrap;
cursor: pointer;
-webkit-appearance: none;
text-align: center;
-webkit-box-sizing: border-box;
box-sizing: border-box;
outline: 0;
margin: 0;
-webkit-transition: 0.1s;
transition: 0.1s;
font-weight: 500;
padding: 8px 15px;
font-size: 12px;
border-radius: 3px;
color: #fff;
background-color: #67c23a;
border-color: #67c23a;
}
/* 水印 */
.cropper-content .show-preview{
position: relative;
user-select: none;
}
.water-cropper{
position: absolute;
top: 0;
right: 0;
/* display: flex;
align-items: center; */
}
.water{
position: absolute;
top: 0;
right: 0;
}
.preview {
position: relative;
}
.crop-box{
/* position: relative; */
position: absolute;
width: 50px;
height: 50px;
cursor: move;
}
.crop-line, .crop-point{
background: #39f;
position: absolute;
user-select: none
}
.crop-line{
opacity: 0.5;
}
.line-w, .line-s{
height: 1px;
width: 100%;
}
.line-a, .line-d{
width: 1px;
height: 100%;
}
.line-w{
top: 0;
left: 0;
}
.line-s{
top: 100%;
left: 0;
}
.line-a{
top: 0;
left: 0;
}
.line-d{
top: 0;
left: 100%;
}
.crop-point{
width: 8px;
height: 8px;
opacity: 0.75;
background-color: #39f;
border-radius: 100%;
}
.water-cropper .point1{
top: -4px;
left: -4px;
cursor: nw-resize;
}
.water-cropper .point2{
top: -4px;
right: -4px;
cursor: ne-resize;
}
.water-cropper .point3{
left: -4px;
bottom: -4px;
cursor: sw-resize;
}
.water-cropper .point4{
right: -4px;
bottom: -4px;
cursor: se-resize;
}
/* #39f */
.news-preview{
border: 1px solid #cccccc;
background: #cccccc;
}
/* .show-preview.news{
display: flex;
align-items: center;
} */
/* .news .news-box{
overflow: hidden;
} */
.font-box{
display: flex;
justify-content: space-around;
padding-bottom: 10px;
}
</style>

View File

@ -1,24 +1,24 @@
<script>
export default {
name: 'MenuItem',
name: "MenuItem",
functional: true,
props: {
icon: {
type: String,
default: ''
default: ""
},
title: {
type: String,
default: ''
default: ""
}
},
render(h, context) {
const { icon, title } = context.props
const vnodes = []
const { icon, title } = context.props;
const vnodes = [];
if (icon) {
if (icon.includes('el-icon')) {
vnodes.push(<i class={[icon, 'sub-el-icon']} />)
if (icon.includes("el-icon")) {
vnodes.push(<i class={[icon, "sub-el-icon"]} />);
// icon_menu_statistical
} else {
vnodes.push(
@ -28,20 +28,18 @@ export default {
// >
// <svg-icon icon-class={icon} />
// </div>
<i
class={['icon_menu_' + icon, 'icon_menu']}
></i>
)
<i class={["icon_menu_" + icon, "icon_menu"]}></i>
);
// vnodes.push(<svg-icon icon-class={icon}/>)
}
}
if (title) {
vnodes.push(<span slot='title'>{title}</span>)
vnodes.push(<span slot="title">{title}</span>);
}
return vnodes
return vnodes;
}
}
};
</script>
<style scoped>
@ -58,11 +56,14 @@ export default {
.icon_menu_convenience {
background: url("./img/icon_convenience.png") no-repeat;
}
.icon_menu_workBook{
.icon_menu_workBook {
background: url("./img/icon_workBook.png") no-repeat;
}
.icon_menu_dxdb{
background: url('./img/icon_dxdb.png')no-repeat;
.icon_menu_dxdb {
background: url("./img/icon_dxdb.png") no-repeat;
}
.icon_menu_jmInfo {
background: url("./img/icon_jmInfo.png") no-repeat;
}
.sub-el-icon {
color: currentColor;

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -4,6 +4,7 @@ import Cookies from 'js-cookie'
import 'normalize.css/normalize.css' // a modern alternative to CSS resets
import Element from 'element-ui'
import './styles/element-variables.scss'
// import enLang from 'element-ui/lib/locale/lang/en'// 如果使用中文语言包请默认支持,无需额外引入,请删除该依赖
@ -14,10 +15,15 @@ import App from './App'
import store from './store'
import router from './router'
import VueCropper from 'vue-cropper'
Vue.use(VueCropper)
import './icons' // icon
import './permission' // permission control
import './utils/error-log' // error log
import has from './utils/permissionFilter.js'
import * as filters from './filters' // global filters
/**

View File

@ -91,8 +91,8 @@ export const constantRoutes = [
redirect: "/convenience/list",
meta: {
title: "工单管理",
icon: "convenience",
roles: ["admin", "editor"]
icon: "convenience"
// roles: ["admin", "editor"]
},
children: [
{
@ -141,9 +141,9 @@ export const constantRoutes = [
redirect: "/workBook/list",
meta: {
title: "工作手册管理",
icon: "list",
roles: ["admin", "editor"]
icon: "list"
},
hidden: true,
children: [
{
path: "list",
@ -155,6 +155,18 @@ export const constantRoutes = [
affix: true,
parentTitle: "工作手册管理"
}
},
{
path: "detail",
component: () => import("@/views/workBook/detail"),
name: "workBookDetail",
meta: {
title: "工作手册详情",
icon: "workBook",
affix: true,
parentTitle: "工作手册详情"
},
hidden: true
}
]
},
@ -270,6 +282,30 @@ export const constantRoutes = [
* the routes that need to be dynamically loaded based on user roles
*/
export const asyncRoutes = [
{
path: "/residentInformation",
component: Layout,
name: "ResidentInformation",
redirect: "/residentInformation/list",
meta: {
title: "居民信息管理",
icon: "jmInfo",
roles: ["SSS"]
},
children: [
{
path: "list",
component: () => import("@/views/residentInformation/list"),
name: "residentInformationList",
meta: {
title: "居民信息列表",
icon: "jmInfo",
affix: true,
parentTitle: "居民信息管理"
}
}
]
},
// {
// path: '/permission',
// component: Layout,

View File

@ -7,6 +7,7 @@ const getters = {
token: state => state.user.token,
avatar: state => state.user.avatar,
name: state => state.user.name,
regionIds: state=>state.user.regionIds,
introduction: state => state.user.introduction,
roles: state => state.user.roles,
permission_routes: state => state.permission.routes,

View File

@ -16,11 +16,11 @@ const mutations = {
if (state.sidebar.opened) {
Cookies.set('sidebarStatus', 1)
} else {
Cookies.set('sidebarStatus', 0)
Cookies.set('sidebarStatus', 1)
}
},
CLOSE_SIDEBAR: (state, withoutAnimation) => {
Cookies.set('sidebarStatus', 0)
Cookies.set('sidebarStatus', 1)
state.sidebar.opened = false
state.sidebar.withoutAnimation = withoutAnimation
},

View File

@ -50,7 +50,7 @@ const actions = {
generateRoutes({ commit }, roles) {
return new Promise(resolve => {
let accessedRoutes
if (roles.includes('admin')) {
if (roles.includes('RESIDENT_ADMIN')) {
accessedRoutes = asyncRoutes || []
} else {
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)

View File

@ -1,56 +1,57 @@
import { login, logout, getInfo } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
import router, { resetRouter } from '@/router'
import { login, logout, getInfo } from "@/api/user";
import { getToken, setToken, removeToken } from "@/utils/auth";
import router, { resetRouter } from "@/router";
const state = {
token: getToken(),
name: '',
avatar: '',
introduction: '',
roles: []
}
name: "",
avatar: "",
introduction: "",
roles: [],
regionIds: ""
};
const mutations = {
SET_TOKEN: (state, token) => {
state.token = token
state.token = token;
},
SET_INTRODUCTION: (state, introduction) => {
state.introduction = introduction
state.introduction = introduction;
},
SET_NAME: (state, name) => {
// console.log(name);
state.name = name
state.name = name;
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
state.avatar = avatar;
},
SET_ROLES: (state, roles) => {
// console.log(roles);
state.roles = roles
state.roles = roles;
},
SET_REGIONIDS: (state, regionIds) => {
state.regionIds = regionIds;
}
}
};
const actions = {
setToken({ commit }, token) {
commit('SET_TOKEN', token)
setToken(token)
// commit("SET_ROLES", ['admin']);
commit("SET_TOKEN", token);
setToken(token);
},
// user login
login({ commit }, userInfo) {
const { username, password } = userInfo
const { username, password } = userInfo;
return new Promise((resolve, reject) => {
login({ username: username.trim(), password: password })
.then(response => {
const { data } = response
commit('SET_TOKEN', data.token)
setToken(data.token)
resolve()
const { data } = response;
commit("SET_TOKEN", data.token);
setToken(data.token);
resolve();
})
.catch(error => {
reject(error)
})
})
reject(error);
});
});
},
// get user info
@ -58,16 +59,23 @@ const actions = {
return new Promise((resolve, reject) => {
getInfo({})
.then(res => {
commit('SET_ROLES', ['admin'])
sessionStorage.setItem('id', res.d.id)
commit('SET_NAME', res.d.name)
commit('SET_AVATAR', res.d.avatar)
resolve({ roles: ['admin'] })
// console.log();
let roles = res.d.isResidentsAdministrator || [];
roles.push("admin");
commit("SET_ROLES", roles);
// commit('SET_ROLES', ['admin'])
// console.log(['admin',...res.isResidentsAdministrator]);
sessionStorage.setItem("Permissions", JSON.stringify(roles));
sessionStorage.setItem("id", res.d.id);
commit("SET_NAME", res.d.name);
commit("SET_AVATAR", res.d.avatar);
commit("SET_REGIONIDS",res.d.regionIds)
resolve({ roles });
})
.catch(error => {
reject(error)
})
})
reject(error);
});
});
},
// user logout
@ -75,14 +83,14 @@ const actions = {
// return new Promise((resolve, reject) => {
// logout(state.token)
// .then(() => {
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
removeToken()
resetRouter()
commit("SET_TOKEN", "");
commit("SET_ROLES", []);
removeToken();
resetRouter();
// reset visited views and cached views
// to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2485
dispatch('tagsView/delAllViews', null, { root: true })
dispatch("tagsView/delAllViews", null, { root: true });
// resolve()
// })
@ -95,40 +103,40 @@ const actions = {
// remove token
resetToken({ commit }) {
return new Promise(resolve => {
commit('SET_TOKEN', '')
console.log('resetToken')
commit('SET_ROLES', [])
removeToken()
resolve()
})
commit("SET_TOKEN", "");
console.log("resetToken");
commit("SET_ROLES", []);
removeToken();
resolve();
});
},
// dynamically modify permissions
async changeRoles({ commit, dispatch }, role) {
const token = role + '-token'
const token = role + "-token";
commit('SET_TOKEN', token)
setToken(token)
commit("SET_TOKEN", token);
setToken(token);
const { roles } = await dispatch('getInfo')
const { roles } = await dispatch("getInfo");
resetRouter()
resetRouter();
// generate accessible routes map based on roles
const accessRoutes = await dispatch('permission/generateRoutes', roles, {
const accessRoutes = await dispatch("permission/generateRoutes", roles, {
root: true
})
});
// dynamically add accessible routes
router.addRoutes(accessRoutes)
router.addRoutes(accessRoutes);
// reset visited views and cached views
dispatch('tagsView/delAllViews', null, { root: true })
dispatch("tagsView/delAllViews", null, { root: true });
}
}
};
export default {
namespaced: true,
state,
mutations,
actions
}
};

View File

@ -0,0 +1,30 @@
import Vue from "vue";
/** 权限指令**/
const has = Vue.directive("has", {
// bind只调用一次指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
// inserted被绑定元素插入父节点时调用
// (仅保证父节点存在,但不一定已被插入文档中)。
// update所在组件的 VNode 更新时调用,但是可能发生在其子 VNode
// 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新。
inserted: function(el, binding, vnode) {
// 获取按钮权限
if (!Vue.prototype.$_has(binding.value)) {
console.log(el);
el.parentNode.removeChild(el);
}
}
});
// 权限检查方法
Vue.prototype.$_has = function(value) {
let isExist = false;
const btnPermissionsStr = sessionStorage.getItem("Permissions");
if (btnPermissionsStr === undefined || btnPermissionsStr === null) {
return false;
}
if (btnPermissionsStr.indexOf(value) > -1) {
isExist = true;
}
return isExist;
};
export { has };

View File

@ -63,7 +63,7 @@ service.interceptors.response.use(
}
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
if (res.c === 403003 || res.c === 9000) {
if (res.c === 403003 || res.c === 403001) {
// to re-login
MessageBox.confirm('请重新登录', '登出确认', {
confirmButtonText: '重新登录',

View File

@ -1,9 +1,6 @@
<template>
<div class="app-container">
<div class="filter-container">
<!-- abc -->
</div>
<!-- bbc -->
<div class="filter-container"></div>
<el-form
ref="convenienceForm"
style="width:680px"
@ -12,14 +9,14 @@
label-width="80px"
class="el-form"
>
<el-form-item label="受理人" prop="residentInformation">
<el-form-item label="申办人" prop="residentInformation">
<el-input
v-model="convenience.residentInformation"
placeholder="群众身份证号或者手机号"
placeholder="群众身份证号"
/>
</el-form-item>
<el-form-item label="办事项目">
<el-form-item label="办事项目" prop="eventTypeId">
<!-- <el-cascader
v-model="convenience.eventTypeId"
:options="typeOptions"
@ -40,7 +37,7 @@
</el-select>
</el-form-item>
<el-form-item label="文字说明">
<el-form-item label="文字说明" prop="remark">
<el-input
v-model="convenience.remark"
type="textarea"
@ -49,7 +46,7 @@
/>
</el-form-item>
<el-form-item label="附件">
<el-form-item label="附件" prop="attachment">
<AliOss v-model="convenience.attachment" multiple />
</el-form-item>
<el-form-item>
@ -72,7 +69,6 @@ export default {
var checkInfo = (rule, value, callback) => {
if (value === "") {
callback(new Error("受理人不能为空"));
// console.log('value==<>');
} else {
info({ param: this.convenience.residentInformation || undefined }).then(
res => {
@ -81,7 +77,6 @@ export default {
} else {
this.searchInput = res.d.id;
callback();
// this.convenience.residentInformation = res.d.id;
}
}
);
@ -93,11 +88,16 @@ export default {
eventTypeId: undefined,
remark: undefined,
sponsor: "STAFF",
attachment: undefined
attachment:undefined
},
typeOptions: [],
rules: {
residentInformation: [{ validator: checkInfo, trigger: "blur" }]
residentInformation: [{ validator: checkInfo, trigger: "blur" }],
eventTypeId: [
{ required: true, message: "办事项目不能为空", trigger: "change" }
]
// remark: [{ validator: checkRemark, trigger: "blur" }],
// attachment: [{ validator: checkAttachment, trigger: "change" }]
},
fileList: undefined,
searchInput: undefined
@ -109,32 +109,22 @@ export default {
methods: {
getTypeList() {
typeList().then(res => {
// this.typeOptions = [];
this.typeOptions = res.d
// res.d.map(i => {
// const children = [];
// i.eventTypesList.map(c => {
// const level2 = {
// label: c.eventName,
// value: c.id
// };
// children.push(level2);
// });
// const level1 = {
// label: i.eventName,
// children
// };
// this.typeOptions.push(level1);
// });
this.typeOptions = res.d;
});
},
handleAdd() {
this.$refs.convenienceForm.validate(valid => {
if (valid) {
this.convenience.residentInformation = this.searchInput;
add(this.convenience).then(res => {
if (!this.convenience.remark) {
if (!(this.convenience.attachment&&this.convenience.attachment.length > 0)) {
this.$notify.error("文字说明与附件必须含有一项");
return;
}
}
let payload = Object.assign({}, this.convenience);
payload.residentInformation = this.searchInput;
add(payload).then(res => {
if (res.c === 200) {
this.$notify.success("创建成功");
this.$router.push("/convenience/list");

View File

@ -50,7 +50,9 @@
type="text"
style="font-size:16px"
@click="cascader"
><i class="icon_edit"/>{{ isEventTypeChange ? "取消" : "编辑" }}</el-button
><i class="icon_edit" />{{
isEventTypeChange ? "取消" : "编辑"
}}</el-button
>
</div>
<div style="color:#787878;font-size:14px;">
@ -456,11 +458,34 @@
<h3>{{ item.content }}</h3>
<p v-if="item.type === 11">审批人{{ getNames(item.to) }}</p>
<p
v-for="(attachment, index) in item.attachmentList"
:key="index"
<p v-for="(file, index) in item.attachmentList" :key="index">
<i
v-if="convenience.residentInformation.id === item.from.id"
class="icon_fujian_self"
/><i v-else class="icon_fujian" />
<!-- file -->
<span
v-if="
isAssetTypeAnAudio(file.substr(file.lastIndexOf('.') + 1))
"
@click="handleSetAudio(file)"
>{{ file }}</span
>
<span
v-if="
isAssetTypeAnImage(file.substr(file.lastIndexOf('.') + 1))
"
@click="handleSetPreviewImg(file)"
>{{ file }}</span
>
<el-link v-else :href="file" :underline="false" target="_blank">
{{ file.substring(file.lastIndexOf("/") + 1) }}
</el-link>
<!-- <span
v-if="
isAssetTypeAnImage(
attachment.substr(attachment.lastIndexOf('.') + 1)
@ -473,19 +498,31 @@
v-if="convenience.residentInformation.id === item.from.id"
class="icon_fujian_self"
/><i v-else class="icon_fujian" />
{{
attachment.substring(attachment.lastIndexOf("/") + 1)
}}</span
{{ attachment.substring(attachment.lastIndexOf("/") + 1) }}
</span>
<span
v-else-if="
isAssetTypeAnAudio(
attachment.substr(attachment.lastIndexOf('.') + 1)
)
"
@click="handleSetAudio(attachment)"
>
</span>
<el-link
v-else
:href="attachment"
:underline="false"
target="_blank"
>
<i class="icon_fujian" />
<i
v-if="convenience.residentInformation.id === item.from.id"
class="icon_fujian_self"
/><i v-else class="icon_fujian" />
{{ attachment.substring(attachment.lastIndexOf("/") + 1) }}
</el-link>
</el-link> -->
</p>
<p v-if="item.type === 13 || item.type === 10">
审批结果{{ item.approve ? "通过" : "驳回" }}
@ -532,10 +569,31 @@
</div>
</div>
<el-dialog :visible.sync="dialogPreviewImg" width="500px">
<el-dialog
:visible.sync="dialogPreviewImg"
width="500px"
title="预览"
:destroy-on-clos="true"
>
<img width="100%" :src="dialogImageUrl" alt="" />
</el-dialog>
<el-dialog
:visible.sync="dialogAudio"
width="500px"
title="预览"
:destroy-on-clos="true"
@close="handleClose"
>
<video
id="myVideo"
:src="dialogAudioSrc"
controls
autoplay
width="100%"
/>
</el-dialog>
<el-dialog
class="dialog"
center
@ -613,9 +671,28 @@
>
<div class="preview-container">
<el-form ref="updateForm" style="width:100%" :rules="rules">
<el-form-item label="选择行政区域" v-if="updateType!==6">
<el-cascader
class="filter-item"
v-model="regionSearchVal"
style="width:100%"
:options="regions"
:show-all-levels="false"
@change="handleRegionChange"
placeholder="行政区域"
clearable
/>
</el-form-item>
<el-form-item
v-if="updateType === 8 || updateType === 11"
label="选择审批人"
>
<span
v-if="!staffOptions.length > 0"
style="font-size:12px;color:red"
>该行政区域下无工作人员</span
>
<el-select
v-model="spr"
@ -637,6 +714,11 @@
v-if="updateType === 8 || updateType === 14"
label="选择被转交人"
>
<span
v-if="!staffOptions.length > 0"
style="font-size:12px;color:red"
>该行政区域下无工作人员</span
>
<el-select v-model="bzjr" placeholder="请选择" style="width:100%">
<el-option
v-for="item in staffOptions"
@ -677,6 +759,12 @@
<span slot="footer" class="dialog-footer">
<el-button type="default" @click="applyDialog = false">取消</el-button>
<el-button type="primary" @click="apply">提交</el-button>
<!-- <el-button
type="primary"
:disabled="JSON.stringify(spr) === '[]'"
@click="apply"
>提交</el-button
> -->
</span>
</el-dialog>
@ -710,6 +798,8 @@ import {
import { parseTime } from "@/utils";
import { staffList } from "@/api/staff";
import AliOss from "@/components/AliOSS/index.vue";
import { getRegions } from "@/api/region";
import { mapGetters } from "vuex";
export default {
filters: {
@ -768,6 +858,9 @@ export default {
return statusMap[status];
}
},
computed: {
...mapGetters(["regionIds"])
},
components: {
AliOss
},
@ -827,13 +920,23 @@ export default {
},
dialogPreviewImg: false,
dialogImageUrl: undefined,
dialogAudio: false,
dialogAudioSrc: undefined,
dialogApprovalReminder: false,
dialogEventType: false,
typeOptions: [],
eventTypeId: undefined,
applyDetail: false,
isEventTypeChange: false,
cxPop: false
cxPop: false,
audioSources: ["http://storage.myntv.cn/files20210415_142012.m4a"],
regionSearchVal: [],
regions: [],
staffQuery: {
regionIds: "",
isAll: false,
category: "CONVENIENCE"
}
};
},
created() {
@ -841,6 +944,7 @@ export default {
this.getStaffList();
this.getCommunicationList();
this.getTypeList();
this.getRegionList();
},
methods: {
getInfo() {
@ -919,7 +1023,6 @@ export default {
// label: i.eventName,
// children
// };
// this.typeOptions.push(level1);
// });
});
@ -995,13 +1098,25 @@ export default {
});
},
getStaffList() {
staffList().then(res => {
let payload = Object.assign({}, this.staffQuery);
let arr = payload.regionIds.split(",");
arr.map((item, index) => {
if (item === "false") {
arr.splice(index, 1);
}
});
payload.regionIds = arr.join(",");
// console.log(payload);
staffList(payload).then(res => {
this.staffOptions = [];
// staffList().then(res => {
res.d.records.map(item => {
const obj = {
label: item.name,
value: item.id
};
this.staffOptions.push(obj);
console.log(this.staffOptions);
});
});
},
@ -1095,8 +1210,41 @@ export default {
// approve: undefined,
// evaluation: undefined
},
setDefaultRegionSelectVal() {
// console.log('swich');
const tempLen = this.regionIds.split(",").length;
this.regionSearchVal = [];
this.staffQuery.regionIds = this.regionIds
switch (tempLen) {
case 1:
console.log(1);
this.regionSearchVal.push(this.regionIds, false);
console.log(this.regionSearchVal);
break;
case 2:
console.log(2);
this.regionSearchVal.push(this.regionIds, false);
// console.log(this.regionSearchVal);
break;
case 3:
console.log(3);
this.regionSearchVal.push(this.regionIds);
break;
default:
this.regionSearchVal = [];
break;
}
this.getStaffList();
},
handleApprovalReminder() {
// this.regionSearchVal = [];
this.dialogApprovalReminder = true;
// console.log(this.regionIds);
this.setDefaultRegionSelectVal();
// this.dialogApprovalReminder = true;
},
handleConfirmApprovalReminder() {
this.dialogApprovalReminder = false;
@ -1154,11 +1302,12 @@ export default {
this.updateType = 14;
this.applyDialog = true;
}
this.setDefaultRegionSelectVal();
break;
case 16:
//
// this.applyDialog = true;
this.$notify.warning('功能尚未开发完成,敬请期待')
this.$notify.warning("功能尚未开发完成,敬请期待");
break;
default:
this.updateData();
@ -1213,6 +1362,9 @@ export default {
this.payload.ids.push(this.bzjr);
break;
}
// this.$refs.updateForm.validate(valid => {
// console.log(valid);
// });
update(this.payload).then(res => {
if (res.c === 200) {
this.$notify.success("操作成功");
@ -1255,6 +1407,18 @@ export default {
this.dialogImageUrl = imgurl;
this.dialogPreviewImg = true;
},
isAssetTypeAnAudio(ext) {
// console.log(e);
return ["m4a", "mp4", "mp3", "mov"].indexOf(ext.toLowerCase()) !== -1;
},
handleSetAudio(src) {
this.dialogAudio = true;
this.dialogAudioSrc = src;
},
handleClose() {
// console.log('close');
document.getElementById("myVideo").pause();
},
handleChangeEventType() {
this.dialogEventType = true;
},
@ -1274,12 +1438,62 @@ export default {
this.$nextTick(() => {
const tempRef = this.$refs.eventTypeRef;
console.log(tempRef);
if(tempRef)
tempRef.toggleMenu();
if (tempRef) tempRef.toggleMenu();
// tempRef.$el.style.display = "inline-block";
// this.$refs.eventTypeRef.focusFirstNode();
}, 100);
},
getRegionList() {
getRegions().then(res => {
const tempData = res.d;
const countyArr = []; // ,1
tempData.map(county => {
const countyObj = {
value: county.root.id,
label: county.root.name,
disabled: !county.root.check,
// children: [{value:true,label:''},{value:false,label:''}],
children: [
{
value: false,
label: county.root.name,
disabled: false
// children: []
}
]
};
countyArr.push(countyObj);
county.node.map(town => {
const townObj = {
value: town.root.id,
label: town.root.name,
disabled: !town.root.check,
// children: [{value:true,label:''},{value:false,label:''}],
children: [
{
value: false,
label: town.root.name,
disabled: false
// children: []
}
]
};
countyObj.children.push(townObj);
town.node.map(country => {
townObj.children.push({
value: country.root.id,
label: country.root.name,
disabled: !country.root.check
});
});
});
});
this.regions = countyArr;
});
},
handleRegionChange(val) {
this.staffQuery.regionIds = val.join(",");
this.getStaffList();
}
},
beforeRouteLeave(to, from, next) {
@ -1542,7 +1756,7 @@ h3 {
margin-right: 6px;
vertical-align: top;
}
.icon_edit{
.icon_edit {
background: url("./img/icon_edit.png") no-repeat;
width: 16px;
height: 16px;

View File

@ -31,7 +31,12 @@
</el-row> -->
<el-row :gutter="20">
<el-col :xs='24' :lg='24' :sm='24' style="color:#787878;margin-bottom:20px"><span>数据统计</span><span style="float:right">更新时间{{new Date() | parseTime}}</span></el-col>
<el-col :xs="24" :lg="24" :sm="24" style="color:#787878;margin-bottom:20px"
><span>数据统计</span
><span style="float:right"
>更新时间{{ new Date() | parseTime("{y}-{m}-{d} {h}:00:00") }}</span
></el-col
>
<el-col
v-for="(value, key, index) in statisticalData"
:key="index"
@ -42,7 +47,10 @@
<div class="countLayout">
<i :class="`countIcon icon_${index}`"></i>
<span v-if="key === 'all'" style="font-size:24px"
>累计服务量 <span style="color:#ff663d;font-size:49px;vertical-align: middle;">{{ value }}</span></span
>累计服务量 <span
style="color:#ff663d;font-size:49px;vertical-align: middle;"
>{{ value }}</span
></span
>
<div
v-else
@ -60,7 +68,7 @@
<script>
import CountTo from "vue-count-to";
import {parseTime} from '@/utils'
import { parseTime } from "@/utils";
import { statisticalData } from "@/api/statisticalData";
export default {
@ -85,38 +93,61 @@ export default {
// }
getStatisticalData() {
statisticalData(this.listQuery).then(res => {
this.statisticalData = res.d;
this.statisticalData = {
all: 318,
平均办结时间: 61722,
平均受理时间: 22349,
未受理量: 0,
未受理率: 0,
按时受理量: 318,
按时受理率: 1.0,
超时受理量: 0,
超时受理率: 0.0,
按时办结量: 307,
按时办结率: 1.0,
超时办结量: 0,
超时办结率: 0.0,
未办结量: 11,
未办结率: 0.0346,
非常满意量: 274,
非常满意率: 0.8925,
满意量: 33,
满意率: 0.1075,
不满意量: 0,
不满意率: 0.0
};
// this.statisticalData = res.d;
});
},
formatUnit(key, value) {
// console.log(key,value);
let str = '';
if (key.indexOf("率")!= -1) {
let str = "";
if (key.indexOf("率") != -1) {
str = `${(value * 100).toFixed(2)}%`;
} else if (key.indexOf("时间")!= -1) {
} else if (key.indexOf("时间") != -1) {
str = this.timeFormat(value);
} else {
str = value;
}
// console.log(str);
return str
return str;
},
timeFormat(timeStamp) {
const timeStr = `${
Math.floor(timeStamp / 3600) < 9
? '0' + Math.floor(timeStamp / 3600)
? "0" + Math.floor(timeStamp / 3600)
: Math.floor(timeStamp / 3600)
}:${
Math.floor(((timeStamp % 86400) % 3600) / 60) < 9
? '0' + Math.floor(((timeStamp % 86400) % 3600) / 60)
? "0" + Math.floor(((timeStamp % 86400) % 3600) / 60)
: Math.floor(((timeStamp % 86400) % 3600) / 60)
}:${
Math.floor(((timeStamp % 86400) % 3600) % 60) < 9
? '0' + Math.floor(((timeStamp % 86400) % 3600) % 60)
? "0" + Math.floor(((timeStamp % 86400) % 3600) % 60)
: Math.floor(((timeStamp % 86400) % 3600) % 60)
}`
return timeStr
},
}`;
return timeStr;
}
}
};
</script>

View File

@ -5,7 +5,13 @@
align-items: center;flex-direction: column;
justify-content: center;"
>
<div class="systemTitle"><i class="login_titleLine_left"/>壤塘家园定点服务系统 <i class="login_titleLine_left" style="transform: rotate(180deg);margin-left:29px"/></div>
<div class="systemTitle">
<i class="login_titleLine_left" />壤塘家园定点服务系统
<i
class="login_titleLine_left"
style="transform: rotate(180deg);margin-left:29px"
/>
</div>
<div
style="background: white;
width: 1053px;
@ -13,13 +19,12 @@
margin: 0 auto;"
>
<el-row>
<el-col
:span="12"
<el-col :span="12"
><img
src="./img/loginImg.png"
style="padding: 70px 0px 70px 72px;width:100%"
alt=""
></el-col>
/></el-col>
<el-col :span="12">
<el-form
@ -78,7 +83,8 @@
type="primary"
style="width:100%;margin-bottom:30px;border-radius:10px;height:54px"
@click.native.prevent="handleLogin"
>登录</el-button>
>登录</el-button
>
</el-form>
</el-col>
</el-row>
@ -87,12 +93,12 @@
</template>
<script>
import { validUsername } from '@/utils/validate'
import { getGuestToken, getSms } from '@/api/user'
import Axios from 'axios'
import { validUsername } from "@/utils/validate";
import { getGuestToken, getSms } from "@/api/user";
import Axios from "axios";
export default {
name: 'Login',
name: "Login",
// components: { SocialSign },
data() {
const validateUsername = (rule, value, callback) => {
@ -102,57 +108,59 @@ export default {
// callback()
// }
if (value.length < 4) {
callback(new Error('账号格式错误不能为空或小于11位'))
callback(new Error("账号格式错误不能为空或小于11位"));
} else {
callback()
}
callback();
}
};
const validateCaptcha = (rule, value, callback) => {
if (value.length < 6) {
callback(new Error('验证码格式错误不能为空或小于6位'))
callback(new Error("验证码格式错误不能为空或小于6位"));
} else {
callback()
}
callback();
}
};
return {
// loginForm: {
// username: 'admin',
// password: '111111'
// },
loginForm: {
username: '',
captcha: '',
appVersion: '1.0.0',
system: 'IOS',
// username: "", //18882564006
// captcha: "",
username: "18882564006", //18882564006
captcha: "111111",
appVersion: "1.0.0",
system: "IOS",
device: navigator.userAgent,
extra: ''
extra: ""
},
loginRules: {
username: [
{ required: true, trigger: 'blur', validator: validateUsername }
{ required: true, trigger: "blur", validator: validateUsername }
],
captcha: [
{ required: true, trigger: 'blur', validator: validateCaptcha }
{ required: true, trigger: "blur", validator: validateCaptcha }
]
},
passwordType: 'password',
passwordType: "password",
capsTooltip: false,
loading: false,
showDialog: false,
redirect: undefined,
otherQuery: {},
codeText: '获取验证码',
codeText: "获取验证码",
time: 60,
getCodeDisabled: false
}
};
},
watch: {
$route: {
handler: function(route) {
const query = route.query
const query = route.query;
if (query) {
this.redirect = query.redirect
this.otherQuery = this.getOtherQuery(query)
this.redirect = query.redirect;
this.otherQuery = this.getOtherQuery(query);
}
},
immediate: true
@ -160,30 +168,30 @@ export default {
},
created() {
// window.addEventListener('storage', this.afterQRScan)
const { appVersion, system, device, extra } = this.loginForm
const { appVersion, system, device, extra } = this.loginForm;
const payload = {
appVersion,
system,
device,
extra
}
};
Axios({
method: 'POST',
method: "POST",
url: `${process.env.VUE_APP_BASE_API}api/auth/guest`,
data: payload,
headers: {
Authorization: 'basic YW5kcm9pZC1jbGllbnQ6YW5kcm9pZC1zZWNyZXQtMjAyMA=='
Authorization: "basic YW5kcm9pZC1jbGllbnQ6YW5kcm9pZC1zZWNyZXQtMjAyMA=="
}
}).then(res => {
// console.log(res);
sessionStorage.setItem('token', res.data.d.access_token)
})
sessionStorage.setItem("token", res.data.d.access_token);
});
},
mounted() {
if (this.loginForm.username === '') {
this.$refs.username.focus()
} else if (this.loginForm.captcha === '') {
this.$refs.password.focus()
if (this.loginForm.username === "") {
this.$refs.username.focus();
} else if (this.loginForm.captcha === "") {
this.$refs.password.focus();
}
},
destroyed() {
@ -191,8 +199,8 @@ export default {
},
methods: {
checkCapslock(e) {
const { key } = e
this.capsTooltip = key && key.length === 1 && key >= 'A' && key <= 'Z'
const { key } = e;
this.capsTooltip = key && key.length === 1 && key >= "A" && key <= "Z";
},
// showPwd() {
// if (this.passwordType === 'password') {
@ -208,37 +216,37 @@ export default {
this.$refs.loginForm.validate(valid => {
if (valid) {
Axios({
method: 'POST',
method: "POST",
url: `${process.env.VUE_APP_BASE_API}api/auth/sms`,
data: this.loginForm,
headers: {
Authorization:
'basic YW5kcm9pZC1jbGllbnQ6YW5kcm9pZC1zZWNyZXQtMjAyMA=='
"basic YW5kcm9pZC1jbGllbnQ6YW5kcm9pZC1zZWNyZXQtMjAyMA=="
}
}).then(res => {
console.log(res)
console.log(res);
if (res.data.c === 200) {
this.$store.dispatch('user/setToken', res.data.d.access_token)
this.$store.dispatch("user/setToken", res.data.d.access_token);
this.$router.push({
path: this.redirect || '/',
path: this.redirect || "/",
query: this.otherQuery
})
});
this.$notify({
title: '成功',
message: '登录成功',
type: 'success',
title: "成功",
message: "登录成功",
type: "success",
duration: 2000
})
});
} else {
this.$notify.error(res.data.m)
this.$notify.error(res.data.m);
}
})
});
} else {
console.log('error submit!!')
console.log("error submit!!");
return false
return false;
}
})
});
// this.$refs.loginForm.validate(valid => {
// if (valid) {
// this.loading = true
@ -258,53 +266,53 @@ export default {
},
getOtherQuery(query) {
return Object.keys(query).reduce((acc, cur) => {
if (cur !== 'redirect') {
acc[cur] = query[cur]
if (cur !== "redirect") {
acc[cur] = query[cur];
}
return acc
}, {})
return acc;
}, {});
},
handleSms() {
this.getCodeDisabled = false
this.getCodeDisabled = false;
const payload = {
phone: this.loginForm.username,
category: 'SIGNIN'
}
category: "SIGNIN"
};
Axios({
method: 'GET',
method: "GET",
url: `${process.env.VUE_APP_BASE_API}api/common/sms/send`,
params: payload,
headers: {
Authorization: 'Bearer ' + sessionStorage.getItem('token')
Authorization: "Bearer " + sessionStorage.getItem("token")
}
}).then(res => {
if (res.data.c === 200) {
this.getCodeDisabled = true
this.timer()
this.getCodeDisabled = true;
this.timer();
this.$notify({
title: '成功',
message: '获取验证码成功',
type: 'success',
title: "成功",
message: "获取验证码成功",
type: "success",
duration: 2000
})
});
}
})
});
},
timer() {
this.codeText = `${this.time}s 后重新获取`
this.codeText = `${this.time}s 后重新获取`;
var interval = setInterval(() => {
this.time--
this.codeText = `${this.time}s 后重新获取`
this.time--;
this.codeText = `${this.time}s 后重新获取`;
if (this.time === 0) {
this.time = 60
this.codeText = '获取验证码'
this.getCodeDisabled = false
clearInterval(interval)
this.time = 60;
this.codeText = "获取验证码";
this.getCodeDisabled = false;
clearInterval(interval);
}
}, 1000)
}, 1000);
}
}
}
};
</script>
<style lang="scss">
@ -339,7 +347,7 @@ button:focus {
padding: 12px 5px 12px 15px;
color: $light_gray;
height: 47px;
caret-color: $cursor;
caret-color: #000;
&:-webkit-autofill {
box-shadow: 0 0 0px 1000px $bg inset !important;
@ -446,8 +454,8 @@ $light_gray: #1890ff;
padding: 10px;
cursor: pointer;
}
.login_titleLine_left{
background: url('./img/login_titleLine_left.png')no-repeat;
.login_titleLine_left {
background: url("./img/login_titleLine_left.png") no-repeat;
background-size: cover;
display: inline-block;
width: 315px;
@ -455,7 +463,7 @@ $light_gray: #1890ff;
margin-right: 29px;
vertical-align: middle;
}
.systemTitle{
.systemTitle {
font-size: 37px;
color: rgb(255, 255, 255);
margin-bottom: 63px;

View File

@ -0,0 +1,545 @@
<template>
<div class="app-container" style="padding-top:0">
<!-- <div>{{ list }}</div> -->
<div class="filter-container">
<!-- <el-button v-if="list" id="te" type="warning" v-has="'editor'">abc</el-button> -->
<el-input
v-model="listQuery.params.name"
style="width:200px;margin-right:10px"
class="filter-item"
placeholder="姓名"
clearable
/>
<!-- <el-input
v-model="listQuery.params.nameZ"
style="width:200px;margin-right:10px"
class="filter-item"
placeholder="姓名(藏语)"
clearable
/> -->
<el-input
v-model="listQuery.params.phone"
style="width:200px;margin-right:10px"
class="filter-item"
placeholder="手机号"
clearable
/>
<el-input
v-model="listQuery.params.idCard"
style="width:200px;margin-right:10px"
class="filter-item"
placeholder="身份证号"
clearable
/>
<!-- isConvenience -->
<!-- <RegionSelect v-model="regionSearchVal" class="filter-item" /> -->
<el-cascader
class="filter-item"
v-model="regionSearchVal"
style="width:240px"
:options="regions"
:props="{ checkStrictly: true }"
placeholder="行政区域"
clearable
/>
<!-- <span style="margin-left:10px;margin-right:10px;"
>是否是便民工作人员</span
> -->
<el-checkbox
v-model="isStaff"
@change="handleIsStaff"
style="margin-left:10px"
>是否是便民工作人员</el-checkbox
>
<!-- <el-switch
v-model="listQuery.params.isConvenience"
active-color="#13ce66"
inactive-color="#ff4949"
>
</el-switch> -->
<el-button type="primary" @click="handleSearch" style="margin-left:10px"
>搜索</el-button
>
</div>
<el-button
@click="handleAdd"
type="primary"
size="mini"
style="font-size:12px;padding:10px 20px;margin-bottom:20px"
>新增</el-button
>
<el-table :data="list" style="width: 100%" border v-loading="listLoading">
<el-table-column prop="name" label="姓名" width="100">
<template slot-scope="scope">
{{ scope.row.name }}
</template>
</el-table-column>
<el-table-column prop="nameZ" label="姓名(藏语)" width="180">
<template slot-scope="scope">
{{ scope.row.nameZ }}
</template>
</el-table-column>
<el-table-column prop="phone" label="手机号" width="120">
<template slot-scope="scope">
{{ scope.row.phone }}
</template>
</el-table-column>
<el-table-column prop="phone" label="身份证号" width="200">
<template slot-scope="scope">
{{ scope.row.idCard }}
</template>
</el-table-column>
<el-table-column prop="phone" label="是否是便民工作人员" width="150">
<template slot-scope="scope">
{{ scope.row.isConvenience ? "是" : "否" }}
</template>
</el-table-column>
<el-table-column prop="phone" label="所属行政区域">
<template slot-scope="scope">
{{
scope.row.permanentResidenceRegion +
(scope.row.permanentResidenceTown
? "-" + scope.row.permanentResidenceTown
: "") +
(scope.row.permanentResidenceTownShip
? "-" + scope.row.permanentResidenceTownShip
: "")
}}
</template>
</el-table-column>
<el-table-column label="操作" width="300px" fixed="right" align="center">
<template slot-scope="scope">
<el-button
@click="handleEdit(scope.row)"
type="primary"
size="mini"
style="font-size:12px;padding:10px 20px"
>修改</el-button
>
<el-button
@click="handleDelete(scope.row)"
type="danger"
size="mini"
style="font-size:12px;padding:10px 20px;border-radius:21px"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-if="total > 0"
:total="total"
:page.sync="listQuery.lastPageIndex"
:limit.sync="listQuery.size"
@pagination="getList"
/>
<el-dialog
:close-on-click-modal="false"
:title="textMap[dialogStatus]"
:visible.sync="dialogAddVisible"
:close-on-press-escape="false"
width="60%"
>
<el-form
:model="residentInfo"
ref="residentInfoForm"
label-width="155px"
class="el-form"
:rules="rules"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="头像">
<cut-upload
:fixed-number="[1, 1]"
:init-url="residentInfo.avatar"
@imgupload="UploadCbk"
/>
</el-form-item>
<el-form-item label="姓名" prop="name">
<el-input v-model="residentInfo.name" />
</el-form-item>
<el-form-item label="姓名(藏文)">
<el-input v-model="residentInfo.nameZ" />
</el-form-item>
<el-form-item label="性别">
<el-radio v-model="residentInfo.sex" :label="0"></el-radio>
<el-radio v-model="residentInfo.sex" :label="1"></el-radio>
<el-radio v-model="residentInfo.sex" :label="2">未知</el-radio>
</el-form-item>
<el-form-item label="手机号">
<el-input v-model="residentInfo.phone" />
</el-form-item>
<el-form-item label="身份证号" prop="idCard">
<el-input v-model="residentInfo.idCard" />
</el-form-item>
<el-form-item label="身份证地址">
<el-input v-model="residentInfo.idCardAddress" />
</el-form-item>
</el-col>
<el-col :span="12" style="padding-top:40px">
<el-form-item label="职务">
<el-input v-model="residentInfo.duty" />
</el-form-item>
<el-form-item label="职务(藏文)">
<el-input v-model="residentInfo.dutyZ" />
</el-form-item>
<el-form-item label="职责">
<el-input v-model="residentInfo.description" />
</el-form-item>
<el-form-item label="职责(藏文)">
<el-input v-model="residentInfo.descriptionZ" />
</el-form-item>
<el-form-item label="序号">
<el-input v-model="residentInfo.sort" />
</el-form-item>
<el-form-item label="行政区域" prop="regionIds">
<el-cascader
v-model="residentInfo.regionIds"
style="width:240px"
:options="regions"
:props="{ checkStrictly: true }"
placeholder="行政区域"
clearable
/>
</el-form-item>
<el-form-item label="是否是便民工作人员">
<el-switch v-model="residentInfo.isConvenience"></el-switch>
</el-form-item>
<el-form-item label="是否是便民领导">
<el-switch v-model="residentInfo.isConvenienceLeader"></el-switch>
</el-form-item>
<el-form-item label="授权权限" v-has="'RESIDENT_SET_ADMIN'">
<el-select
v-model="residentInfo.isResidentsAdministrator"
multiple
>
<el-option
label="设置权限"
value="RESIDENT_SET_ADMIN"
></el-option>
<el-option label="居民管理" value="RESIDENT_ADMIN"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<!-- <el-form-item label="是否是融媒体工作人员">
<el-switch v-model="residentInfo.isNews"></el-switch>
</el-form-item>
<el-form-item label="是否是融媒体领导">
<el-switch v-model="residentInfo.isNewsLeader"></el-switch>
</el-form-item> -->
</el-form>
<!-- logconven.ne -->
<span slot="footer" class="dialog-footer">
<el-button @click="dialogAddVisible = false"> </el-button>
<el-button
type="primary"
@click="dialogStatus === 'create' ? createData() : updateData()"
> </el-button
>
</span>
</el-dialog>
<el-dialog
title="提示"
:visible.sync="dialogDeleteConfirm"
width="30%"
center
>
<span>确定删除吗</span>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogDeleteConfirm = false"> </el-button>
<el-button type="primary" @click="deleteData"> </el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import {
getResidentInfoList,
addResidentInfoList,
updateResidentInfo,
deleteResident
} from "@/api/residentInformation";
import RegionSelect from "@/components/RegionSelect";
import { getRegions } from "@/api/region";
import Pagination from "@/components/Pagination";
import CutUpload from "@/components/cutUploadImage/index.vue";
export default {
components: { Pagination, CutUpload, RegionSelect },
data() {
return {
listLoading: false,
total: 0,
listQuery: {
lastPageIndex: 1,
size: 10,
params: {
name: "",
phone: "",
idCard: ""
}
},
dialogAddVisible: false,
textMap: {
update: "修改",
create: "创建"
},
dialogStatus: "",
list: [],
regions: [],
rules: {
name: [
{ required: true, message: "居民姓名不能为空", trigger: "blur" }
],
idCard: [
{ required: true, message: "居民身份证号不能为空", trigger: "blur" }
],
regionIds: [
{ required: true, message: "行政区域不能为空", trigger: "blur" }
]
},
residentInfo: {
avatar: ""
},
regionSearchVal: undefined,
dialogDeleteConfirm: false,
isStaff: false
};
},
created() {
this.getList();
this.getRegions();
},
methods: {
getList() {
this.listLoading = true;
getResidentInfoList(this.listQuery).then(res => {
this.list = res.d.list;
this.total = res.d.total;
this.listLoading = false;
});
},
getRegions() {
getRegions().then(res => {
const tempData = res.d;
const countyArr = []; // ,1
tempData.map(county => {
const countyObj = {
value: county.root.name,
label: county.root.name,
disabled: !county.root.check,
children: []
};
countyArr.push(countyObj);
county.node.map(town => {
const townObj = {
value: town.root.name,
label: town.root.name,
disabled: !town.root.check,
children: []
};
countyObj.children.push(townObj);
town.node.map(country => {
townObj.children.push({
value: country.root.name,
label: country.root.name,
disabled: !country.root.check
});
});
});
});
this.regions = countyArr;
});
},
handleSearch() {
this.listQuery.params.isConvenience = this.isStaff ? true : undefined;
if (this.regionSearchVal) {
switch (this.regionSearchVal.length) {
case 1:
this.listQuery.params.PermanentResidenceRegion = this.regionSearchVal[0];
this.listQuery.params.PermanentResidenceTown = undefined;
this.listQuery.params.PermanentResidenceTownShip = undefined;
break;
case 2:
this.listQuery.params.PermanentResidenceTown = this.regionSearchVal[1];
this.listQuery.params.PermanentResidenceRegion = undefined;
this.listQuery.params.PermanentResidenceTownShip = undefined;
break;
case 3:
this.listQuery.params.PermanentResidenceTownShip = this.regionSearchVal[2];
this.listQuery.params.PermanentResidenceRegion = undefined;
this.listQuery.params.PermanentResidenceTown = undefined;
break;
default:
this.listQuery.params.PermanentResidenceRegion = undefined;
this.listQuery.params.PermanentResidenceTown = undefined;
this.listQuery.params.PermanentResidenceTownShip = undefined;
break;
}
// this.listQuery.params.permanentResidenceRegion = this.regionSearchVal[0];
// this.listQuery.params.permanentResidenceTown = this.regionSearchVal[1];
// this.listQuery.params.permanentResidenceTownShip = this.regionSearchVal[2];
}
this.getList();
},
resetResidentInfo() {
this.residentInfo = {
id: undefined,
avatar: undefined,
name: undefined,
nameZ: undefined,
description: undefined,
descriptionZ: undefined,
duty: undefined,
dutyZ: undefined,
idCard: undefined,
idCardAddress: undefined,
isConvenience: false,
isConvenienceLeader: false,
isNews: false,
isNewsLeader: false,
isResidentsAdministrator: [],
phone: undefined,
sex: undefined,
regionIds: undefined,
sort: undefined
};
},
UploadCbk(data) {
this.residentInfo.avatar = data;
},
handleAdd() {
this.resetResidentInfo();
this.dialogStatus = "create";
this.$nextTick(() => {
this.dialogAddVisible = true;
});
},
formatSubmitParams() {
let regions = this.residentInfo.regionIds;
this.residentInfo.permanentResidenceRegion = regions[0];
this.residentInfo.permanentResidenceTown = regions[1];
this.residentInfo.permanentResidenceTownShip = regions[2];
},
createData() {
this.$refs.residentInfoForm.validate(valid => {
if (valid) {
this.formatSubmitParams();
let payload = [];
let info = Object.assign({}, this.residentInfo);
delete info.regionIds;
payload.push(info);
addResidentInfoList(payload).then(res => {
if (res.c === 200) {
this.$notify.success("创建成功");
this.dialogAddVisible = false;
this.getList();
}
});
}
});
},
updateData() {
this.$refs.residentInfoForm.validate(valid => {
if (valid) {
this.formatSubmitParams();
delete this.residentInfo.regionIds;
updateResidentInfo(this.residentInfo).then(res => {
// console.log(res);
if (res.c === 200) {
this.$notify.success("修改成功");
this.dialogAddVisible = false;
this.getList();
}
});
}
});
},
handleEdit(row) {
// this.$nextTick(() => {
this.residentInfo = Object.assign({}, row);
let arr = [];
if (this.residentInfo.permanentResidenceRegion) {
arr.push(this.residentInfo.permanentResidenceRegion);
}
if (this.residentInfo.permanentResidenceTown) {
arr.push(this.residentInfo.permanentResidenceTown);
}
if (this.residentInfo.permanentResidenceTownShip) {
arr.push(this.residentInfo.permanentResidenceTownShip);
}
this.residentInfo.regionIds = arr;
this.dialogStatus = "update";
this.dialogAddVisible = true;
// },100);
},
handleDelete(row) {
this.residentInfo = Object.assign({}, row);
this.dialogDeleteConfirm = true;
},
deleteData() {
deleteResident({ id: this.residentInfo.id }).then(res => {
// console.log(res);
if (res.c === 200) {
this.$notify.success("删除成功");
this.dialogDeleteConfirm = false;
this.getList();
}
});
},
handleIsStaff(val) {
// console.log(val);
if (val === false) {
// console.log('ab');
this.listQuery.params.isConvenience === undefined;
let temp = Object.assign({}, this.listQuery);
temp.params.isConvenience === undefined;
this.listQuery = temp;
// console.log(this.listQuery);
}
// if (!val) {
// this.listQuery.params.isConvenience === undefined;
// console.log(this.listQuery.params);
// }
}
}
};
</script>
<style></style>

View File

@ -0,0 +1,48 @@
<template>
<div class="app-container">
<el-form>
<el-form-item label="新闻标题:">
<span>{{ info.title }}</span>
</el-form-item>
<!-- <el-form-item label="新闻副标题:">
<span>{{info.title}}</span>
</el-form-item> -->
<el-form-item label="新闻简介:">
<span>{{ info.introduction }}</span>
</el-form-item>
<el-form-item label="发布时间:">
<span>{{ info.releaseTime | parseTime }}</span>
</el-form-item>
</el-form>
<Editor v-model="info.content" style="width: 100%" :disabled="true"/>
</div>
</template>
<script>
import Editor from "@/components/UEditor/index.vue";
import { getWorkBookInfo } from "@/api/workBook";
export default {
data() {
return {
id: this.$route.query.id,
info: {}
};
},
components: { Editor },
created() {
this.getInfo();
},
methods: {
getInfo() {
// console.log(this.id);
getWorkBookInfo({ id: this.id }).then(res => {
// console.log(res);
this.info = res.d;
});
}
}
};
</script>
<style></style>

View File

@ -1,16 +1,16 @@
<template>
<div class="app-container" style="padding-top:15px">
<!-- <div class="filter-container" /> -->
<div class="workBookLayout">
<div class="title">工作手册管理</div>
<div class="text-center" style="padding:10% 0">
<!-- <div class="workBookLayout"> -->
<!-- <div class="title">工作手册管理</div> -->
<!-- <div class="text-center" style="padding:10% 0">
<img class="img" src="./img/comingSoon.png" alt="">
<h2>业务正在努力开发中...</h2>
<div style="color:#787878">该功能即将上线请稍等</div>
</div>
</div>
</div> -->
<!-- </div> -->
<!-- <el-table
<el-table
v-loading="listLoading"
:data="list"
border
@ -30,11 +30,11 @@
</template>
</el-table-column>
<el-table-column label="新闻副标题" align="center">
<!-- <el-table-column label="新闻副标题" align="center">
<template slot-scope="scope">
<span>{{ scope.row.subtitle }}</span>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column label="新闻简介" align="center">
<template slot-scope="scope">
@ -42,24 +42,41 @@
</template>
</el-table-column>
<el-table-column label="新闻列表上的图片地址集合" align="center">
<!-- <el-table-column label="新闻列表上的图片地址集合" align="center">
<template slot-scope="scope">
<span>{{ scope.row.images }}</span>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column label="发布时间" align="center">
<template slot-scope="scope">
<span>{{ scope.row.releaseTime }}</span>
<span>{{ scope.row.releaseTime | parseTime}}</span>
</template>
</el-table-column>
</el-table> -->
<el-table-column label="操作" width="300px" fixed="right" align="center">
<template slot-scope="scope">
<el-button
@click="
$router.push({
path: '/workBook/detail',
query: { id: scope.row.id }
})
"
type="primary"
size="mini"
style="font-size:12px;padding:10px 20px"
>详情</el-button
>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import Pagination from '@/components/Pagination'
import { workBookList } from '@/api/workBook'
import Pagination from "@/components/Pagination";
import { workBookList } from "@/api/workBook";
export default {
components: { Pagination },
@ -73,20 +90,20 @@ export default {
size: 10,
keyword: undefined
}
}
};
},
created() {
this.getList()
this.getList();
},
methods: {
getList() {
workBookList(this.listQuery).then(res => {
// console.log(res)
this.list = res.d.records
})
this.list = res.d.records;
});
}
}
}
};
</script>
<style scoped>

View File

@ -25,7 +25,8 @@ module.exports = {
* Detail: https://cli.vuejs.org/config/#publicpath
*/
publicPath: '/',
outputDir: 'dist',
// outputDir: 'dist',
outputDir: process.env.NODE_ENV === 'development' ? 'convenience-dev' : 'convenience-prod',
assetsDir: 'static',
lintOnSave: process.env.NODE_ENV === 'development',
productionSourceMap: false,