村民圈
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
const install = function(Vue) {
|
const install = function(Vue) {
|
||||||
if (install.installed) return Promise.resolve();
|
if (install.installed) return Promise.resolve();
|
||||||
else {
|
else {
|
||||||
let contexts = require.context('../project/shandong/apps', true, /(\/.+)\/App[^\/]+\.vue$/);
|
let contexts = require.context('../packages', true, /(\/.+)\/App[^\/]+\.vue$/);
|
||||||
if (contexts) {
|
if (contexts) {
|
||||||
contexts.keys().map((e) => {
|
contexts.keys().map((e) => {
|
||||||
if (contexts(e).default) {
|
if (contexts(e).default) {
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
<template>
|
||||||
|
<div class="appDispatchManagement">
|
||||||
|
<keep-alive :include="['List']">
|
||||||
|
<component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component>
|
||||||
|
</keep-alive>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Detail from './components/Detail'
|
||||||
|
import Add from './components/Add'
|
||||||
|
import List from './components/List'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "AppDispatchManagement",
|
||||||
|
label: '公文流转',
|
||||||
|
|
||||||
|
components: {List, Detail, Add},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
permissions: Function
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
component: 'List',
|
||||||
|
params: {},
|
||||||
|
include: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created(){
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
onChange (data) {
|
||||||
|
if (data.type === 'detail') {
|
||||||
|
this.component = 'Detail'
|
||||||
|
this.params = data.params
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.type === 'add') {
|
||||||
|
console.log(123)
|
||||||
|
this.component = 'Add'
|
||||||
|
this.params = data.params
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.type === 'list') {
|
||||||
|
this.component = 'List'
|
||||||
|
this.params = data.params
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (data.isRefresh) {
|
||||||
|
this.$refs.component.getList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.appDispatchManagement{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
388
packages/shandong/AppDispatchManagement/components/Add.vue
Normal file
388
packages/shandong/AppDispatchManagement/components/Add.vue
Normal file
@@ -0,0 +1,388 @@
|
|||||||
|
<template>
|
||||||
|
<section class="managementDetail">
|
||||||
|
<ai-detail>
|
||||||
|
<template #title>
|
||||||
|
<ai-title title="公文登记" isShowBottomBorder isShowBack @onBackClick="cancel(true)"/>
|
||||||
|
</template>
|
||||||
|
<template #content>
|
||||||
|
<ai-card title="公文信息">
|
||||||
|
<template slot="content">
|
||||||
|
<div class="form_div mar-t16">
|
||||||
|
<el-form
|
||||||
|
ref="rules"
|
||||||
|
:model="form"
|
||||||
|
:rules="formRules"
|
||||||
|
size="small"
|
||||||
|
label-suffix=":"
|
||||||
|
label-width="100px"
|
||||||
|
>
|
||||||
|
<el-form-item label="公文名称" prop="documentName">
|
||||||
|
<el-input
|
||||||
|
v-model="form.documentName"
|
||||||
|
placeholder="请输入..."
|
||||||
|
maxlength="50"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<div class="above">
|
||||||
|
<div class="left">
|
||||||
|
<el-form-item label="公文编号" prop="documentCode">
|
||||||
|
<el-input
|
||||||
|
v-model="form.documentCode"
|
||||||
|
placeholder="请输入..."
|
||||||
|
maxlength="50"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<el-form-item label="公文类型" prop="documentType">
|
||||||
|
<el-select
|
||||||
|
v-model="form.documentType"
|
||||||
|
placeholder="请选择..."
|
||||||
|
clearable
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="(item, i) in dict.getDict('officialDocumentName')"
|
||||||
|
:key="i"
|
||||||
|
:label="item.dictName"
|
||||||
|
:value="item.dictValue"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="above">
|
||||||
|
<div class="left">
|
||||||
|
<el-form-item label="保密等级">
|
||||||
|
<el-select
|
||||||
|
v-model="form.confidentialityLevel"
|
||||||
|
placeholder="请选择..."
|
||||||
|
clearable
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="(item, i) in dict.getDict('officialDocumentConfidentialityLevel')"
|
||||||
|
:key="i"
|
||||||
|
:label="item.dictName"
|
||||||
|
:value="item.dictValue"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<el-form-item label="阅示类型" prop="readType">
|
||||||
|
<el-select @change="readTypeChange"
|
||||||
|
v-model="form.readType"
|
||||||
|
placeholder="请选择..."
|
||||||
|
clearable
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="(item, i) in dict.getDict('officialDocumentReadType')"
|
||||||
|
:key="i"
|
||||||
|
:label="item.dictName"
|
||||||
|
:value="item.dictValue"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="above">
|
||||||
|
<div class="left">
|
||||||
|
<el-form-item label="紧急程度">
|
||||||
|
<el-select
|
||||||
|
v-model="form.emergencyLevel"
|
||||||
|
placeholder="请选择..."
|
||||||
|
clearable
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="(item, i) in dict.getDict('officialDocumentEmergencyLevel')"
|
||||||
|
:key="i"
|
||||||
|
:label="item.dictName"
|
||||||
|
:value="item.dictValue"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="above">
|
||||||
|
<div class="left">
|
||||||
|
<el-form-item label="发文机关">
|
||||||
|
<el-input
|
||||||
|
v-model="form.issuingUnit"
|
||||||
|
placeholder="请输入..."
|
||||||
|
maxlength="50"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<el-form-item label="发文字号">
|
||||||
|
<el-input
|
||||||
|
v-model="form.issuingFont"
|
||||||
|
placeholder="请输入..."
|
||||||
|
maxlength="50"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="above">
|
||||||
|
<div class="left">
|
||||||
|
<el-form-item label="签发人">
|
||||||
|
<el-input
|
||||||
|
v-model="form.signer"
|
||||||
|
placeholder="请输入..."
|
||||||
|
maxlength="50"
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<el-input
|
||||||
|
v-model="form.remark"
|
||||||
|
type="textarea"
|
||||||
|
:rows="5"
|
||||||
|
maxlength="200"
|
||||||
|
show-word-limit
|
||||||
|
placeholder="请输入..."
|
||||||
|
></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="附件">
|
||||||
|
<div class="upload">
|
||||||
|
<ai-uploader :instance="instance" v-model="form.files" fileType="file" :limit="9" @change="onChange"></ai-uploader>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
<ai-card title="流转信息">
|
||||||
|
<template #content>
|
||||||
|
<span class="form-label">流转对象:</span>
|
||||||
|
<div class="user-content">
|
||||||
|
<ai-wechat-selecter slot="append" :instance="instance" v-model="form.flowUsers" isShowUser :isMultiple="isMultiple"></ai-wechat-selecter>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
</template>
|
||||||
|
<template #footer>
|
||||||
|
<el-button class="delete-btn footer-btn" @click="cancel(true)">取消</el-button>
|
||||||
|
<el-button class="footer-btn" type="primary" @click="save('rules', '1')">保存并流转</el-button>
|
||||||
|
<el-button class="footer-btn" @click="save('rules', '0')">保存</el-button>
|
||||||
|
</template>
|
||||||
|
</ai-detail>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "managementDetail",
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
permissions: Function,
|
||||||
|
params: Object
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
form: {
|
||||||
|
documentName: '',
|
||||||
|
documentCode: '',
|
||||||
|
documentType: '',
|
||||||
|
confidentialityLevel: '',
|
||||||
|
readType: '',
|
||||||
|
emergencyLevel: '',
|
||||||
|
issuingTime: '',
|
||||||
|
issuingUnit: '',
|
||||||
|
issuingFont: '',
|
||||||
|
signer: '',
|
||||||
|
overDescription: '',
|
||||||
|
overTime: '',
|
||||||
|
deliver: '',
|
||||||
|
remark: '',
|
||||||
|
files: [],
|
||||||
|
fileIds: [],
|
||||||
|
flowUsers: [],
|
||||||
|
},
|
||||||
|
isMultiple: true,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
formRules(){
|
||||||
|
return {
|
||||||
|
documentName: [{required: true, message: "请输入公文名称", trigger: 'change' }],
|
||||||
|
documentCode: [{required: true, message: "请输入公文编号", trigger: 'change' }],
|
||||||
|
documentType: [{required: true, message: "请选择公文类型", trigger: 'change' }],
|
||||||
|
readType: [{required: true, message: "请选择阅示类型", trigger: 'change' }],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
colConfigs(){
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
prop: 'meetingUserName',
|
||||||
|
align: 'center',
|
||||||
|
label: '姓名',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'meetingUserPhone',
|
||||||
|
align: 'center',
|
||||||
|
label: '手机号码',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'meetingUnitName',
|
||||||
|
align: 'center',
|
||||||
|
label: '所属部门',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
slot: 'joinStatus',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
slot: 'option',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.dict.load('issuingUnit','officialDocumentEmergencyLevel', 'officialDocumentReadType', 'officialDocumentConfidentialityLevel', 'officialDocumentName');
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if(this.params.id) {
|
||||||
|
this.getDetail()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onChange() {
|
||||||
|
|
||||||
|
},
|
||||||
|
readTypeChange() {
|
||||||
|
if(this.form.readType == 0) {
|
||||||
|
this.isMultiple = false
|
||||||
|
if(this.form.flowUsers.length > 1) {
|
||||||
|
this.form.flowUsers = []
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
this.isMultiple = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getDetail() {
|
||||||
|
this.instance.post(`/app/appofficialdocumentinfo/queryDetailById?id=${this.params.id}&flag=0`, null).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.form = {...res.data}
|
||||||
|
this.form.files = this.form.files || []
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
save(formName, status){
|
||||||
|
this.$refs[formName].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.submit(status)
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
submit(status) {
|
||||||
|
var flowUsers = []
|
||||||
|
this.form.flowUsers.map(item => {
|
||||||
|
var info = {
|
||||||
|
flowUserId: item.id,
|
||||||
|
flowUserName: item.name,
|
||||||
|
avatar: item.avatar
|
||||||
|
}
|
||||||
|
flowUsers.push(info)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.form.fileIds = []
|
||||||
|
if(this.form.files.length) {
|
||||||
|
this.form.files.map((item) => {
|
||||||
|
this.form.fileIds.push(item.id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.instance.post(`/app/appofficialdocumentinfo/addOrUpdate`, {
|
||||||
|
...this.form,
|
||||||
|
status: status,
|
||||||
|
flowUsers: flowUsers
|
||||||
|
}, null).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
if(this.params.id){
|
||||||
|
this.$message.success("编辑成功");
|
||||||
|
}else{
|
||||||
|
this.$message.success("提交成功");
|
||||||
|
}
|
||||||
|
this.cancel(true)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
cancel(isRefresh) {
|
||||||
|
this.$emit('change', {
|
||||||
|
type: 'list',
|
||||||
|
isRefresh: !!isRefresh
|
||||||
|
})
|
||||||
|
},
|
||||||
|
downFileAll () {
|
||||||
|
if (this.form.files.length > 0) {
|
||||||
|
this.instance.post('/app/appofficialdocumentinfo/downLoadAllFileForDetail', null, {
|
||||||
|
responseType: 'blob',
|
||||||
|
params: {
|
||||||
|
id: this.form.id
|
||||||
|
}
|
||||||
|
}).then((res) => {
|
||||||
|
const link = document.createElement('a')
|
||||||
|
let blob = new Blob([res], { type: 'application/vnd.ms-excel' })
|
||||||
|
link.style.display = 'none'
|
||||||
|
link.href = URL.createObjectURL(blob)
|
||||||
|
var num = ''
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
num += Math.ceil(Math.random() * 10)
|
||||||
|
}
|
||||||
|
link.setAttribute('download', '公文文件' + '.zip')
|
||||||
|
document.body.appendChild(link)
|
||||||
|
link.click()
|
||||||
|
document.body.removeChild(link)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.$message.error('暂无附件提供下载')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.managementDetail {
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
background: #f3f6f9;
|
||||||
|
.above{
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
.left{
|
||||||
|
width: 50%;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.right{
|
||||||
|
width: 50%;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.el-select{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.el-date-editor.el-input{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.iconEdit,.Edit{
|
||||||
|
color:#5088FF;
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
padding-left: 8px;
|
||||||
|
}
|
||||||
|
.form-label{
|
||||||
|
display: inline-block;
|
||||||
|
width: 100px;
|
||||||
|
color: #666;
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.user-content{
|
||||||
|
display: inline-block;
|
||||||
|
width: calc(100% - 100px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
563
packages/shandong/AppDispatchManagement/components/Detail.vue
Normal file
563
packages/shandong/AppDispatchManagement/components/Detail.vue
Normal file
@@ -0,0 +1,563 @@
|
|||||||
|
<template>
|
||||||
|
<section class="managementDetail">
|
||||||
|
<ai-detail>
|
||||||
|
<template #title>
|
||||||
|
<ai-title title="公文详情" isShowBottomBorder isShowBack @onBackClick="cancel(true)">
|
||||||
|
<template #rightBtn>
|
||||||
|
<ai-wechat-selecter :instance="instance" v-model="addUser" :isMultiple="form.readType == '0' ? false : true" @change="onChange" v-if="form.status === '0'">
|
||||||
|
<el-button
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
icon="iconfont iconMediaPlayer_Play">
|
||||||
|
开始流转
|
||||||
|
</el-button>
|
||||||
|
</ai-wechat-selecter>
|
||||||
|
<ai-wechat-selecter :instance="instance" v-model="addUser" :isMultiple="form.readType == '0' ? false : true" @change="onChange" v-if="form.status === '2' && form.readType == '0'">
|
||||||
|
<el-button
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
icon="iconfont iconResetting">
|
||||||
|
再次流转
|
||||||
|
</el-button>
|
||||||
|
</ai-wechat-selecter>
|
||||||
|
<el-button
|
||||||
|
@click="endCirculation"
|
||||||
|
v-if="form.status === '1'"
|
||||||
|
size="small"
|
||||||
|
icon="iconfont iconReject">
|
||||||
|
结束流转</el-button>
|
||||||
|
</template>
|
||||||
|
</ai-title>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
<template #content>
|
||||||
|
<ai-card :title="form.documentName">
|
||||||
|
<template slot="content">
|
||||||
|
<ai-wrapper class="mar-t16" label-width="80px" :columnsNumber="3">
|
||||||
|
<ai-info-item label="公文编号:"><span>{{form.documentCode || '-'}}</span></ai-info-item>
|
||||||
|
<ai-info-item label="公文类型:"><span>{{$dict.getLabel("officialDocumentName", form.documentType) || '-'}}</span></ai-info-item>
|
||||||
|
<ai-info-item label="保密等级:"><span>{{$dict.getLabel("officialDocumentConfidentialityLevel", form.confidentialityLevel) || '-'}}</span></ai-info-item>
|
||||||
|
</ai-wrapper>
|
||||||
|
<ai-wrapper label-width="80px" :columnsNumber="3">
|
||||||
|
<ai-info-item label="阅示类型:"><span>{{$dict.getLabel("officialDocumentReadType", form.readType) || '-'}}</span></ai-info-item>
|
||||||
|
<ai-info-item label="紧急程度:"><span>{{$dict.getLabel("officialDocumentEmergencyLevel", form.emergencyLevel) || '-'}}</span></ai-info-item>
|
||||||
|
<ai-info-item label="发文机关:"><span>{{dict.getLabel('issuingUnit',form.issuingUnit)|| '-'}}</span></ai-info-item>
|
||||||
|
</ai-wrapper>
|
||||||
|
<ai-wrapper label-width="80px" :columnsNumber="3">
|
||||||
|
<ai-info-item label="发文字号:"><span>{{form.issuingFont || '-'}}</span></ai-info-item>
|
||||||
|
<ai-info-item label="签发人:"><span>{{form.signer || '-'}}</span></ai-info-item>
|
||||||
|
<ai-info-item label="发文时间:"><span>{{form.createTime || '-'}}</span></ai-info-item>
|
||||||
|
</ai-wrapper>
|
||||||
|
<ai-wrapper label-width="80px" :columnsNumber="1">
|
||||||
|
<ai-info-item label="备注:"><span>{{form.remark || '-'}}</span></ai-info-item>
|
||||||
|
</ai-wrapper>
|
||||||
|
<ai-bar title="附件" >
|
||||||
|
<template slot="right" v-if="form.files && form.files.length">
|
||||||
|
<span class="Edit" @click="downFileAll"><i class="iconfont iconDownload"></i>下载全部</span>
|
||||||
|
</template>
|
||||||
|
</ai-bar>
|
||||||
|
<ai-file-list v-if="form.files && form.files.length"
|
||||||
|
:fileList="form.files"
|
||||||
|
:fileOps="{ name: 'name', size: 'fileSizeStr' }"
|
||||||
|
></ai-file-list>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
<ai-card title="流转信息">
|
||||||
|
<template #right>
|
||||||
|
<ai-wechat-selecter :instance="instance" v-model="addFlow" @change="addPeople" v-if="form.readType==0 && form.status !== '2'">
|
||||||
|
<el-button
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
icon="iconfont iconAdd">
|
||||||
|
指派人员
|
||||||
|
</el-button>
|
||||||
|
</ai-wechat-selecter>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #content>
|
||||||
|
<ai-wrapper
|
||||||
|
label-width="70px"
|
||||||
|
:columnsNumber="3">
|
||||||
|
<ai-info-item label="流转状态:"><span :class="'status-' + form.status">{{ dict.getLabel('documentStatus', form.status) }}</span></ai-info-item>
|
||||||
|
<ai-info-item label="当前流转对象:" label-width="98px" v-if="form.readType === '0'">{{ form.flowUserName || '-' }}</ai-info-item>
|
||||||
|
<ai-info-item></ai-info-item>
|
||||||
|
</ai-wrapper>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
<ai-card title="流转记录">
|
||||||
|
<template #right>
|
||||||
|
<ai-wechat-selecter :instance="instance" v-model="addFlow" @change="addFlowChange" v-if="form.readType === '1' && (form.status === '1' || form.status === '0') && $permissions('app_appofficialdocumentinfo_edit')">
|
||||||
|
<el-button
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
icon="iconfont iconAdd">
|
||||||
|
添加人员
|
||||||
|
</el-button>
|
||||||
|
</ai-wechat-selecter>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #content>
|
||||||
|
<div class="ai-steps" v-if="form.readType === '0'">
|
||||||
|
<div class="ai-steps__item" v-for="(item, index) in form.flowUsers" :key="index">
|
||||||
|
<div class="ai-steps__item--left">
|
||||||
|
<div class="ai-steps__item__avatar">
|
||||||
|
<img :src="item.avatar" v-if="item.avatar">
|
||||||
|
<h2 v-else>{{ formatName(item.flowUserName) }}</h2>
|
||||||
|
<i class="iconfont iconSteps_Finished"></i>
|
||||||
|
</div>
|
||||||
|
<div class="ai-steps__item--content">
|
||||||
|
<span>{{ dict.getLabel('documentFlowStatus', item.flowStatus) }}</span>
|
||||||
|
<h2>{{ item.flowUserName }}</h2>
|
||||||
|
<p v-if="item.description">{{ item.description }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ai-steps__item--right">{{ item.flowTime }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ai-table
|
||||||
|
class="table"
|
||||||
|
v-if="form.readType === '1'"
|
||||||
|
:tableData="tableData"
|
||||||
|
:col-configs="colConfigs"
|
||||||
|
:total="total"
|
||||||
|
:isShowPagination="false"
|
||||||
|
:current.sync="search.current"
|
||||||
|
:size.sync="search.size"
|
||||||
|
:border="true">
|
||||||
|
<el-table-column slot="options" label="操作" align="center" width="120px">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<span
|
||||||
|
v-if="$permissions('app_appofficialdocumentinfo_edit')"
|
||||||
|
class="iconfont iconDelete"
|
||||||
|
title="删除"
|
||||||
|
style="cursor: pointer;"
|
||||||
|
@click="remove(row.id)">
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</ai-table>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
</template>
|
||||||
|
</ai-detail>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "managementDetail",
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
permissions: Function,
|
||||||
|
params: Object
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
form: {
|
||||||
|
documentName: '',
|
||||||
|
documentCode: '',
|
||||||
|
documentType: '',
|
||||||
|
confidentialityLevel: '',
|
||||||
|
readType: '',
|
||||||
|
emergencyLevel: '',
|
||||||
|
issuingTime: '',
|
||||||
|
issuingUnit: '',
|
||||||
|
issuingFont: '',
|
||||||
|
signer: '',
|
||||||
|
overDescription: '',
|
||||||
|
overTime: '',
|
||||||
|
deliver: '',
|
||||||
|
remark: '',
|
||||||
|
files: [],
|
||||||
|
fileIds: [],
|
||||||
|
flowUsers: [],
|
||||||
|
},
|
||||||
|
isAdd: true,
|
||||||
|
isMultiple: true,
|
||||||
|
addUser: [],
|
||||||
|
addFlow: [],
|
||||||
|
tableData: [],
|
||||||
|
search: {
|
||||||
|
size: 10,
|
||||||
|
current: 1
|
||||||
|
},
|
||||||
|
total: 10,
|
||||||
|
colConfigs: [
|
||||||
|
{ prop: 'flowUserName', label: '姓名', align: 'center' },
|
||||||
|
{ prop: 'readTime', label: '时间', align: 'center' },
|
||||||
|
{
|
||||||
|
prop: 'readStatus',
|
||||||
|
label: '阅示情况',
|
||||||
|
align: 'center',
|
||||||
|
render: (h, params) => {
|
||||||
|
return h('span', {
|
||||||
|
style: {
|
||||||
|
color: params.row.readStatus === '0' ? '#FF8822' : '#2EA222'
|
||||||
|
}
|
||||||
|
}, this.$dict.getLabel('readingStatus', params.row.readStatus))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ slot: 'options', label: '操作', align: 'center' }
|
||||||
|
],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
formRules(){
|
||||||
|
return {
|
||||||
|
documentName: [{required: true, message: "请输入公文名称", trigger: 'change' }],
|
||||||
|
documentCode: [{required: true, message: "请输入公文编号", trigger: 'change' }],
|
||||||
|
documentType: [{required: true, message: "请选择公文类型", trigger: 'change' }],
|
||||||
|
readType: [{required: true, message: "请选择阅示类型", trigger: 'change' }],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.dict.load('issuingUnit','officialDocumentEmergencyLevel', 'officialDocumentReadType', 'officialDocumentConfidentialityLevel', 'officialDocumentName', 'documentFlowStatus', 'readingStatus');
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.form = this.params
|
||||||
|
this.showDetail = true
|
||||||
|
this.isAdd = false
|
||||||
|
this.getDetail()
|
||||||
|
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
remove (id) {
|
||||||
|
if(this.form.flowUsers.length<=1){
|
||||||
|
return this.$message.error("至少留一个流转对象!");
|
||||||
|
}
|
||||||
|
this.$confirm('确定删除该传阅人员吗?').then(() => {
|
||||||
|
this.instance.post(`/app/appofficialdocumentflow/delete?ids=${id}`).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message.success('删除成功!')
|
||||||
|
this.getDetail()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
formatName (name) {
|
||||||
|
if(name == undefined){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return name.substr(name.length - 2, name.length > 2 ? (name.length - 1) : name.length)
|
||||||
|
},
|
||||||
|
addPeople() { //指派人员
|
||||||
|
this.instance.post(`/app/appofficialdocumentinfo/flowById`,null,{
|
||||||
|
params:{
|
||||||
|
flowUserId:this.addFlow[0].id,
|
||||||
|
flowUserName:this.addFlow[0].name,
|
||||||
|
avatar:this.addFlow[0].avatar,
|
||||||
|
flag:0,
|
||||||
|
id:this.form.id,
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message({
|
||||||
|
message:"指派成功",
|
||||||
|
type:"success"
|
||||||
|
})
|
||||||
|
this.getDetail()
|
||||||
|
this.addFlow = []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
addFlowChange() { //添加传阅人员
|
||||||
|
let data = this.form
|
||||||
|
const fileIds = data.files.length ? data.files.map(item => item.id) : []
|
||||||
|
const flowUsers = [...this.addFlow].map(item => {
|
||||||
|
return {
|
||||||
|
flowUserId: item.id,
|
||||||
|
flowUserName: item.name,
|
||||||
|
avatar: item.avatar
|
||||||
|
}
|
||||||
|
})
|
||||||
|
delete data.files
|
||||||
|
this.instance.post(`/app/appofficialdocumentflow/add`, {
|
||||||
|
id: this.form.id,
|
||||||
|
...data,
|
||||||
|
status: '1',
|
||||||
|
flowUsers,
|
||||||
|
fileIds
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message.success('添加成功')
|
||||||
|
this.getDetail()
|
||||||
|
this.addFlow = []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onChange() {
|
||||||
|
if (!this.addUser.length) {
|
||||||
|
return this.$message.error('请选择流转人员')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.form.readType === '0' && this.form.status === '0') {
|
||||||
|
// 开始流转
|
||||||
|
let data = this.form
|
||||||
|
const flowUsers = [...this.addUser].map(item => {
|
||||||
|
return {
|
||||||
|
flowUserId: item.id,
|
||||||
|
flowUserName: item.name,
|
||||||
|
avatar: item.avatar
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const fileIds = data.files.length ? data.files.map(item => item.id) : []
|
||||||
|
delete data.files
|
||||||
|
this.instance.post(`/app/appofficialdocumentinfo/addOrUpdate`, {
|
||||||
|
id: this.form.id,
|
||||||
|
...data,
|
||||||
|
status: '1',
|
||||||
|
flowUsers: flowUsers,
|
||||||
|
fileIds
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message.success('流转成功')
|
||||||
|
this.getDetail()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 再次流转
|
||||||
|
this.instance.post(`/app/appofficialdocumentinfo/flowById`, null, {
|
||||||
|
params: {
|
||||||
|
flag: '1',
|
||||||
|
flowUserId: this.addUser[0].id,
|
||||||
|
flowUserName: this.addUser[0].name,
|
||||||
|
avatar: this.addUser[0].avatar,
|
||||||
|
id: this.form.id
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message.success('添加成功')
|
||||||
|
this.getDetail(this.id)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
readTypeChange() {
|
||||||
|
if(this.form.readType == 0) {
|
||||||
|
this.isMultiple = false
|
||||||
|
if(this.form.flowUsers.length > 1) {
|
||||||
|
this.form.flowUsers = []
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
this.isMultiple = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getDetail() {
|
||||||
|
this.instance.post(`/app/appofficialdocumentinfo/queryDetailById?id=${this.params.id}&flag=0`, null).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.form = {...res.data}
|
||||||
|
this.form.files = this.form.files || []
|
||||||
|
if (res.data.readType === '1') {
|
||||||
|
this.tableData = res.data.flowUsers
|
||||||
|
this.total = res.data.flowUsers.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
save(formName, status){
|
||||||
|
this.$refs[formName].validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.submit(status)
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
submit(status) {
|
||||||
|
this.form.flowUsers.map(item => {
|
||||||
|
item.flowUserId = item.id,
|
||||||
|
item.flowUserName = item.name
|
||||||
|
})
|
||||||
|
|
||||||
|
this.form.fileIds = []
|
||||||
|
if(this.form.files.length) {
|
||||||
|
this.form.files.map((item) => {
|
||||||
|
this.form.fileIds.push(item.id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.instance.post(`/app/appofficialdocumentinfo/addOrUpdate`, {
|
||||||
|
...this.form,
|
||||||
|
status: status
|
||||||
|
}, null).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
if(!this.isAdd){
|
||||||
|
this.$message.success("编辑成功");
|
||||||
|
}else{
|
||||||
|
this.$message.success("提交成功");
|
||||||
|
this.cancel(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
addCancel() {
|
||||||
|
if(this.params.id) { //新增
|
||||||
|
this.cancel(true)
|
||||||
|
}else {
|
||||||
|
this.showDetail = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
cancel(isRefresh) {
|
||||||
|
this.$emit('change', {
|
||||||
|
type: 'list',
|
||||||
|
isRefresh: !!isRefresh
|
||||||
|
})
|
||||||
|
},
|
||||||
|
downFileAll () {
|
||||||
|
if (this.form.files.length > 0) {
|
||||||
|
this.instance.post('/app/appofficialdocumentinfo/downLoadAllFileForDetail', null, {
|
||||||
|
responseType: 'blob',
|
||||||
|
params: {
|
||||||
|
id: this.form.id
|
||||||
|
}
|
||||||
|
}).then((res) => {
|
||||||
|
const link = document.createElement('a')
|
||||||
|
let blob = new Blob([res], { type: 'application/vnd.ms-excel' })
|
||||||
|
link.style.display = 'none'
|
||||||
|
link.href = URL.createObjectURL(blob)
|
||||||
|
var num = ''
|
||||||
|
for (let i = 0; i < 10; i++) {
|
||||||
|
num += Math.ceil(Math.random() * 10)
|
||||||
|
}
|
||||||
|
link.setAttribute('download', '公文文件' + '.zip')
|
||||||
|
document.body.appendChild(link)
|
||||||
|
link.click()
|
||||||
|
document.body.removeChild(link)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
this.$message.error('暂无附件提供下载')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
endCirculation () {
|
||||||
|
this.$confirm('确定结束流转?').then(() => {
|
||||||
|
this.instance.post(`/app/appofficialdocumentinfo/finishById?id=${this.form.id}`).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message.success('操作成功')
|
||||||
|
this.cancel(true)
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.managementDetail {
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
background: #f3f6f9;
|
||||||
|
.above{
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
.left{
|
||||||
|
width: 50%;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.right{
|
||||||
|
width: 50%;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.el-select{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.el-date-editor.el-input{
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.iconEdit,.Edit{
|
||||||
|
color:#5088FF;
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
padding-left: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.ai-steps {
|
||||||
|
padding-bottom: 40px;
|
||||||
|
.ai-steps__item {
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-bottom: 44px;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
position: absolute;
|
||||||
|
left: 20px;
|
||||||
|
top: 40px;
|
||||||
|
width: 1px;
|
||||||
|
height: 44px;
|
||||||
|
background: #DDDDDD;
|
||||||
|
content: ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
padding-bottom: 0;
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-steps__item--left {
|
||||||
|
display: flex;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.ai-steps__item--content {
|
||||||
|
span {
|
||||||
|
color: #333;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
margin-top: 4px;
|
||||||
|
color: #666666;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-top: 8px;
|
||||||
|
color: #666666;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-steps__item__avatar {
|
||||||
|
position: relative;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
margin-right: 16px;
|
||||||
|
|
||||||
|
i {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 4px;
|
||||||
|
right: 0;
|
||||||
|
color: #2ea222;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img, h2 {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 50%;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 14px;
|
||||||
|
background: #2266FF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-steps__item--right {
|
||||||
|
margin-left: 20px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
color: #999999;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
310
packages/shandong/AppDispatchManagement/components/List.vue
Normal file
310
packages/shandong/AppDispatchManagement/components/List.vue
Normal file
@@ -0,0 +1,310 @@
|
|||||||
|
<template>
|
||||||
|
<ai-list class="AppDispatchManagement">
|
||||||
|
<template slot="title">
|
||||||
|
<ai-title title="公文流转" isShowBottomBorder></ai-title>
|
||||||
|
</template>
|
||||||
|
<template slot="content">
|
||||||
|
<ai-search-bar>
|
||||||
|
<template slot="left">
|
||||||
|
<ai-select
|
||||||
|
v-model="searchObj.documentType"
|
||||||
|
placeholder="选择公文类型"
|
||||||
|
clearable
|
||||||
|
@change="(page.current = 1), getList()"
|
||||||
|
:selectList="dict.getDict('officialDocumentName')"
|
||||||
|
></ai-select>
|
||||||
|
<ai-select
|
||||||
|
v-model="searchObj.confidentialityLevel"
|
||||||
|
placeholder="选择保密等级"
|
||||||
|
clearable
|
||||||
|
@change="(page.current = 1), getList()"
|
||||||
|
:selectList="dict.getDict('officialDocumentConfidentialityLevel')"
|
||||||
|
></ai-select>
|
||||||
|
<ai-select
|
||||||
|
v-model="searchObj.status"
|
||||||
|
placeholder="选择流转状态"
|
||||||
|
clearable
|
||||||
|
@change="(page.current = 1), getList()"
|
||||||
|
:selectList="dict.getDict('documentStatus')"
|
||||||
|
></ai-select>
|
||||||
|
<ai-select
|
||||||
|
v-model="searchObj.readType"
|
||||||
|
placeholder="选择阅示类型"
|
||||||
|
clearable
|
||||||
|
@change="(page.current = 1), getList()"
|
||||||
|
:selectList="dict.getDict('officialDocumentReadType')"
|
||||||
|
></ai-select>
|
||||||
|
|
||||||
|
<!-- <el-row class="dateRange" type="flex" align="middle">
|
||||||
|
<span class="dateLabel">操作时间</span>
|
||||||
|
<el-date-picker
|
||||||
|
size="small"
|
||||||
|
v-model="searchObj.createTimeStart"
|
||||||
|
placeholder="开始日期"
|
||||||
|
@change="page.current = 1, getList()"
|
||||||
|
value-format="yyyy-MM-dd" />
|
||||||
|
<el-date-picker
|
||||||
|
size="small"
|
||||||
|
v-model="searchObj.createTimeEnd"
|
||||||
|
placeholder="结束日期"
|
||||||
|
@change="page.current = 1, getList()"
|
||||||
|
value-format="yyyy-MM-dd" />
|
||||||
|
</el-row> -->
|
||||||
|
</template>
|
||||||
|
<template slot="right">
|
||||||
|
<el-input placeholder="输入公文名称/编号"
|
||||||
|
v-model="searchObj.name"
|
||||||
|
size="small"
|
||||||
|
@change="(page.current = 1), getList()"
|
||||||
|
clearable
|
||||||
|
prefix-icon="iconfont iconSearch"/>
|
||||||
|
</template>
|
||||||
|
</ai-search-bar>
|
||||||
|
<ai-search-bar class="mt10">
|
||||||
|
<template slot="left">
|
||||||
|
<el-button type="primary" icon="iconfont iconAdd" @click="toAdd({})"
|
||||||
|
>添加
|
||||||
|
</el-button
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</ai-search-bar>
|
||||||
|
<ai-table
|
||||||
|
:tableData="tableData"
|
||||||
|
:col-configs="colConfigs"
|
||||||
|
:total="page.total"
|
||||||
|
ref="aitableex"
|
||||||
|
:current.sync="page.current"
|
||||||
|
row-key="id"
|
||||||
|
default-expand-all
|
||||||
|
:tree-props="{ children: 'merchandiseList' }"
|
||||||
|
:size.sync="page.size"
|
||||||
|
@getList="getList"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
>
|
||||||
|
<el-table-column slot="selection" type="selection" width="55"></el-table-column>
|
||||||
|
<el-table-column slot="options" label="操作" align="center" width="200">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<el-button v-if="row.status != 0" type="text" @click="goDetail(row)">详情</el-button>
|
||||||
|
<el-button v-if="row.status == 0" type="text" @click="toAdd(row)">编辑</el-button>
|
||||||
|
<el-button type="text" @click="del(row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</ai-table>
|
||||||
|
</template>
|
||||||
|
</ai-list>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "management",
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
permissions: Function,
|
||||||
|
areaId: String,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
searchObj: {
|
||||||
|
documentType: '',
|
||||||
|
confidentialityLevel: '',
|
||||||
|
readType: '',
|
||||||
|
createTimeStart: null,
|
||||||
|
createTimeEnd: null,
|
||||||
|
name: '',
|
||||||
|
},
|
||||||
|
page: {
|
||||||
|
size: 10,
|
||||||
|
current: 1,
|
||||||
|
total: 0,
|
||||||
|
},
|
||||||
|
tableData: [],
|
||||||
|
shopList: [],
|
||||||
|
ids: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
colConfigs() {
|
||||||
|
return [
|
||||||
|
{slot: "selection", label: "", align: "center"},
|
||||||
|
{
|
||||||
|
prop: "documentCode",
|
||||||
|
label: "公文编号",
|
||||||
|
width: 120,
|
||||||
|
align: "center",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "documentName",
|
||||||
|
label: "公文名称",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "documentType",
|
||||||
|
label: "公文类型",
|
||||||
|
width: 120,
|
||||||
|
align: "center",
|
||||||
|
formart: (documentType) =>
|
||||||
|
this.$dict.getLabel("officialDocumentName", documentType),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "readType",
|
||||||
|
label: "阅示类型",
|
||||||
|
width: 120,
|
||||||
|
align: "center",
|
||||||
|
formart: (readType) =>
|
||||||
|
this.$dict.getLabel("officialDocumentReadType", readType),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "confidentialityLevel",
|
||||||
|
label: "保密等级",
|
||||||
|
width: 120,
|
||||||
|
align: "center",
|
||||||
|
formart: (confidentialityLevel) =>
|
||||||
|
this.$dict.getLabel("officialDocumentConfidentialityLevel", confidentialityLevel),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "flowUserName",
|
||||||
|
label: "当前流转对象",
|
||||||
|
width: 180,
|
||||||
|
align: "center",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "status",
|
||||||
|
label: "流转状态",
|
||||||
|
width: 120,
|
||||||
|
align: "center",
|
||||||
|
render: (h, {row}) => {
|
||||||
|
return h('span', {style: {color: this.dict.getColor('documentStatus', row.status)}}, this.dict.getLabel('documentStatus', row.status))
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "createTime",
|
||||||
|
label: "操作时间",
|
||||||
|
width: 180,
|
||||||
|
align: "center",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: "createUserName",
|
||||||
|
label: "操作人",
|
||||||
|
width: 120,
|
||||||
|
align: "center",
|
||||||
|
},
|
||||||
|
{slot: "options", label: "操作"},
|
||||||
|
];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.dict.load('officialDocumentName', 'officialDocumentConfidentialityLevel', 'officialDocumentReadType', 'documentStatus').then(() => {
|
||||||
|
this.$nextTick(() => this.getList())
|
||||||
|
})
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
changeTime() {
|
||||||
|
this.page.current = 1
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
getList() {
|
||||||
|
this.instance.post(`/app/appofficialdocumentinfo/list`, null, {
|
||||||
|
params: {
|
||||||
|
...this.searchObj,
|
||||||
|
...this.page
|
||||||
|
},
|
||||||
|
}).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.tableData = res.data.records;
|
||||||
|
this.tableData.map((item) => {
|
||||||
|
if (item.createTime) {
|
||||||
|
item.createTime = item.createTime.substring(0, 10)
|
||||||
|
} else {
|
||||||
|
item.createTime = '-'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.page.total = res.data.total;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
reset() {
|
||||||
|
Object.keys(this.searchObj).forEach((e) => {
|
||||||
|
this.searchObj[e] = "";
|
||||||
|
});
|
||||||
|
this.searchObj.createTimeStart = null;
|
||||||
|
this.searchObj.createTimeEnd = null;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
toAdd(params) {
|
||||||
|
this.$emit('change', {
|
||||||
|
type: 'add',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
},
|
||||||
|
goDetail(row) {
|
||||||
|
this.$emit('change', {
|
||||||
|
type: 'detail',
|
||||||
|
params: {
|
||||||
|
...row
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
del(item) {
|
||||||
|
this.$confirm("删除后不可恢复,是否要删除该公文?", {
|
||||||
|
type: 'error'
|
||||||
|
}).then(() => {
|
||||||
|
this.instance
|
||||||
|
.post(`/app/appofficialdocumentinfo/delete?ids=${item.id}`)
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message.success("删除成功!");
|
||||||
|
this.getList();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handleSelectionChange(val) {
|
||||||
|
this.ids = [];
|
||||||
|
val.forEach(e => {
|
||||||
|
this.ids.push(e.id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.AppDispatchManagement {
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
background: #f3f6f9;
|
||||||
|
|
||||||
|
::v-deep .el-range-editor--small.el-input__inner {
|
||||||
|
width: 258px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .dateRange {
|
||||||
|
.dateLabel {
|
||||||
|
height: 32px;
|
||||||
|
border: 1px solid #D0D4DC;
|
||||||
|
line-height: 32px;
|
||||||
|
padding: 0 8px;
|
||||||
|
background: #F5F5F5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-input__inner {
|
||||||
|
border-radius: 0;
|
||||||
|
transform: translateX(-1px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
cursor: pointer;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconCorrect {
|
||||||
|
color: #53b43b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.iconReject {
|
||||||
|
color: #e75555;
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,766 @@
|
|||||||
|
<template>
|
||||||
|
<section class="statistics tabs-init el-tabs__content_f3f6f9">
|
||||||
|
<div style="margin-top: 16px;height: 270px;">
|
||||||
|
<div class="left">
|
||||||
|
<div class="item-left mar-b16">
|
||||||
|
<div class="item-left-title">公文总数</div>
|
||||||
|
<div class="item-left-num" style="color:#4B87FE;">{{totalOfficialDocumentStatistics}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-left">
|
||||||
|
<div class="item-left-title">本月新增</div>
|
||||||
|
<div class="item-left-num" style="color:#2EA222;">{{newMonthonStatistics}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<div class="chart-content" style="padding-right:0;">
|
||||||
|
<div class="chart-line">
|
||||||
|
<div class="chart-title">近12个月公文登记情况</div>
|
||||||
|
<div v-if="lineChartData.length"
|
||||||
|
class="chart-info"
|
||||||
|
style="
|
||||||
|
width: 100%;
|
||||||
|
height: 206px;
|
||||||
|
padding: 16px 16px 20px 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
"
|
||||||
|
id="chartLine"
|
||||||
|
></div>
|
||||||
|
<ai-empty v-else style="height: 148px;"></ai-empty>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="chart-content">
|
||||||
|
<div class="chart-line" style="margin-right: 16px;">
|
||||||
|
<div class="chart-title">阅示类型统计</div>
|
||||||
|
<div style="overflow:hidden;">
|
||||||
|
<div
|
||||||
|
class="chart-info"
|
||||||
|
style="
|
||||||
|
width: 288px;
|
||||||
|
height: 288px;
|
||||||
|
padding: 16px 0 0 16px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
float:left;
|
||||||
|
"
|
||||||
|
id="readType"
|
||||||
|
></div>
|
||||||
|
<div class="list-type mar-t102">
|
||||||
|
<div class="item" v-for="(item, index) in readTypeList" :key="index">
|
||||||
|
<div class="type-title">
|
||||||
|
<span class="item-color-bg" :style="{'backgroundColor': item.bgColor}"></span>{{item.title}}
|
||||||
|
</div>
|
||||||
|
<div class="num">{{item.num}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="chart-line">
|
||||||
|
<div class="chart-title">公文类型统计</div>
|
||||||
|
<div style="overflow:hidden;">
|
||||||
|
<div
|
||||||
|
class="chart-info"
|
||||||
|
style="
|
||||||
|
width: 288px;
|
||||||
|
height: 288px;
|
||||||
|
padding: 16px 0 0 16px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
float:left;
|
||||||
|
"
|
||||||
|
id="docType"
|
||||||
|
></div>
|
||||||
|
<div class="list-type mar-t60">
|
||||||
|
<div class="item" v-for="(item, index) in docTypeList" :key="index">
|
||||||
|
<div class="type-title">
|
||||||
|
<span class="item-color-bg" :style="{'backgroundColor': item.bgColor}"></span>{{item.title}}
|
||||||
|
</div>
|
||||||
|
<div class="num">{{item.num}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState } from "vuex";
|
||||||
|
import charts from "echarts";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "statistics",
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
permissions: Function,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
readTypeList: [
|
||||||
|
{
|
||||||
|
title: '传阅',
|
||||||
|
num: '0',
|
||||||
|
bgColor: '#4B87FE'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '批示',
|
||||||
|
num: '0',
|
||||||
|
bgColor: '#FFAA44'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
docTypeList: [
|
||||||
|
{
|
||||||
|
title: '决议',
|
||||||
|
num: '0',
|
||||||
|
bgColor: '#FF4466'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '决定',
|
||||||
|
num: '0',
|
||||||
|
bgColor: '#FFAA44'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '通知',
|
||||||
|
num: '0',
|
||||||
|
bgColor: '#4B87FE'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '通告',
|
||||||
|
num: '0',
|
||||||
|
bgColor: '#45A3FF'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '函',
|
||||||
|
num: '0',
|
||||||
|
bgColor: '#2EA222'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '其它',
|
||||||
|
num: '0',
|
||||||
|
bgColor: '#B244FF'
|
||||||
|
},
|
||||||
|
],
|
||||||
|
lineChartTitle: [],
|
||||||
|
lineChartData: [],
|
||||||
|
totalOfficialDocumentStatistics: 0,
|
||||||
|
newMonthonStatistics: 0,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(["user"]),
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getInfo()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getInfo() {
|
||||||
|
this.instance.post(`/app/appofficialsenddeliverinfo/getStatistics`).then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.newMonthonStatistics = res.data.newMonthonStatistics || 0
|
||||||
|
this.totalOfficialDocumentStatistics = res.data.totalOfficialSendStatistics || 0
|
||||||
|
if(res.data.officialRegistrationStatistics && res.data.officialRegistrationStatistics.length) {
|
||||||
|
res.data.officialRegistrationStatistics.map(item => {
|
||||||
|
this.lineChartTitle.push(item.name)
|
||||||
|
this.lineChartData.push(item.v1)
|
||||||
|
})
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.setLineChart()
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
if(res.data.readTheTypeStatistics && res.data.readTheTypeStatistics.length) {
|
||||||
|
res.data.readTheTypeStatistics.map(item => {
|
||||||
|
if(item.name == 0){
|
||||||
|
this.readTypeList[1].num = item.v1 || 0
|
||||||
|
}
|
||||||
|
if(item.name == 1){
|
||||||
|
this.readTypeList[0].num = item.v1 || 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.setReadChart()
|
||||||
|
}
|
||||||
|
if(res.data.officialSendTypeStatistics && res.data.officialSendTypeStatistics.length) {
|
||||||
|
res.data.officialSendTypeStatistics.map(item => {
|
||||||
|
if(item.name == 0){
|
||||||
|
this.docTypeList[0].num = item.v1
|
||||||
|
}
|
||||||
|
if(item.name == 1){
|
||||||
|
this.docTypeList[1].num = item.v1
|
||||||
|
}
|
||||||
|
if(item.name == 3){
|
||||||
|
this.docTypeList[2].num = item.v1
|
||||||
|
}
|
||||||
|
if(item.name == 2){
|
||||||
|
this.docTypeList[3].num = item.v1
|
||||||
|
}
|
||||||
|
if(item.name == 4){
|
||||||
|
this.docTypeList[4].num = item.v1
|
||||||
|
}
|
||||||
|
if(item.name == 5){
|
||||||
|
this.docTypeList[5].num = item.v1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.setDocChart()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
setLineChart() {
|
||||||
|
var chartLine = charts.init(document.getElementById("chartLine"));
|
||||||
|
var option = {
|
||||||
|
title: {
|
||||||
|
text: "",
|
||||||
|
},
|
||||||
|
tooltip: {
|
||||||
|
trigger: "axis",
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
top: "10%",
|
||||||
|
left: "2%",
|
||||||
|
right: "2%",
|
||||||
|
bottom: "2%",
|
||||||
|
containLabel: true,
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: "category",
|
||||||
|
boundaryGap: false,
|
||||||
|
data: this.lineChartTitle,
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: "value",
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: "",
|
||||||
|
type: "line",
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: "#26f",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data: this.lineChartData,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
chartLine.setOption(option);
|
||||||
|
},
|
||||||
|
setReadChart() {
|
||||||
|
var chart = charts.init(document.getElementById("readType"));
|
||||||
|
var option = {
|
||||||
|
tooltip: {
|
||||||
|
trigger: "item",
|
||||||
|
formatter: "{b}: {c} ({d}%)",
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: "",
|
||||||
|
type: "pie",
|
||||||
|
radius: ["50%", "80%"],
|
||||||
|
avoidLabelOverlap: false,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'inside',
|
||||||
|
formatter: '{d}%',
|
||||||
|
fontSize: '14',
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
fontSize: '14',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
value: this.readTypeList[0].num,
|
||||||
|
name: '传阅',
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: '#4B87FE'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: this.readTypeList[1].num,
|
||||||
|
name: '批示',
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: '#FFAA44'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
chart.setOption(option);
|
||||||
|
},
|
||||||
|
setDocChart() {
|
||||||
|
var chart = charts.init(document.getElementById("docType"));
|
||||||
|
var option = {
|
||||||
|
tooltip: {
|
||||||
|
trigger: "item",
|
||||||
|
formatter: "{b}: {c} ({d}%)",
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: "",
|
||||||
|
type: "pie",
|
||||||
|
radius: ["50%", "80%"],
|
||||||
|
avoidLabelOverlap: false,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'inside',
|
||||||
|
formatter: '{d}%',
|
||||||
|
fontSize: '14',
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
fontSize: '14',
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
value: this.docTypeList[0].num,
|
||||||
|
name: '决议',
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: '#FF4466'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: this.docTypeList[1].num,
|
||||||
|
name: '决定',
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: '#FFAA44'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: this.docTypeList[2].num,
|
||||||
|
name: '通知',
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: '#4B87FE'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: this.docTypeList[3].num,
|
||||||
|
name: '通告',
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: '#45A3FF'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: this.docTypeList[4].num,
|
||||||
|
name: '函',
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: '#2EA222'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: this.docTypeList[5].num,
|
||||||
|
name: '其它',
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: '#B244FF'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
chart.setOption(option);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.statistics {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: #f3f6f9;
|
||||||
|
// overflow: hidden;
|
||||||
|
.left{
|
||||||
|
width: 29%;
|
||||||
|
float: left;
|
||||||
|
margin-left: 16px;
|
||||||
|
.item-left{
|
||||||
|
padding: 0 20px;
|
||||||
|
width: 100%;
|
||||||
|
height: 120px;
|
||||||
|
background: #FFFFFF;
|
||||||
|
box-shadow: 0px 16px 32px 0px rgba(0, 0, 0, 0.02);
|
||||||
|
border-radius: 4px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
.item-left-title{
|
||||||
|
color: #333;
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 20px 0 16px 0;
|
||||||
|
}
|
||||||
|
.item-left-num{
|
||||||
|
font-size: 32px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.right{
|
||||||
|
width: calc(70% - 20px);
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.mar-t102{
|
||||||
|
margin-top: 102px;
|
||||||
|
}
|
||||||
|
.mar-t60{
|
||||||
|
margin-top: 60px;
|
||||||
|
}
|
||||||
|
.list-type{
|
||||||
|
width:calc(100% - 360px);
|
||||||
|
float:right;
|
||||||
|
margin-left: 20px;
|
||||||
|
font-size: 14px;
|
||||||
|
padding-right: 40px;
|
||||||
|
.item{
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
line-height: 20px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
.type-title{
|
||||||
|
color: #666;
|
||||||
|
.item-color-bg{
|
||||||
|
display: inline-block;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
background: #4B87FE;
|
||||||
|
border-radius: 1px;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.num{
|
||||||
|
color: #333;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.chart-content {
|
||||||
|
width: 100%;
|
||||||
|
// height: 336px;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 0 16px 16px 16px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
.chart-line {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0px 16px 32px 0px rgba(0, 0, 0, 0.02);
|
||||||
|
}
|
||||||
|
.chart-title {
|
||||||
|
line-height: 48px;
|
||||||
|
border-bottom: 1px solid #e6e8ee;
|
||||||
|
padding-left: 16px;
|
||||||
|
color: #333;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.tab-row {
|
||||||
|
padding: 16px 16px 16px 16px;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.tab-col {
|
||||||
|
height: 64px;
|
||||||
|
flex: 1;
|
||||||
|
background-color: #fff;
|
||||||
|
margin-right: 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid rgba(216, 224, 232, 1);
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.tab-title {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #333;
|
||||||
|
height: 14px;
|
||||||
|
line-height: 14px;
|
||||||
|
vertical-align: super;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-num {
|
||||||
|
height: 24px;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
line-height: 24px;
|
||||||
|
font-family: DINAlternate-Bold, serif;
|
||||||
|
float: right;
|
||||||
|
line-height: 64px;
|
||||||
|
padding-right: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-col:nth-last-child(1) {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
display: inline-block;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
padding: 20px 8px 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-panel {
|
||||||
|
flex: 1;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #d8e0e8;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 12px 16px 0 16px;
|
||||||
|
|
||||||
|
b {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: rgba(51, 51, 51, 1);
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ASBarChart {
|
||||||
|
height: 286px;
|
||||||
|
|
||||||
|
& + .no-data {
|
||||||
|
margin: 83px auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#PartyAgePieChart,
|
||||||
|
#PartyEduPieChart {
|
||||||
|
height: 264px;
|
||||||
|
|
||||||
|
& + .no-data {
|
||||||
|
margin: 72px auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.party_title {
|
||||||
|
height: 48px;
|
||||||
|
line-height: 48px;
|
||||||
|
background: #fff;
|
||||||
|
text-indent: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.party_content {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
padding: 16px;
|
||||||
|
|
||||||
|
.party_left {
|
||||||
|
width: 280px;
|
||||||
|
background: #eaedf1;
|
||||||
|
border: 1px solid #d8dce3;
|
||||||
|
position: relative;
|
||||||
|
border-radius: 4px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.p {
|
||||||
|
height: 28px;
|
||||||
|
line-height: 28px;
|
||||||
|
background: #d9e0e9;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #333;
|
||||||
|
text-indent: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left_tree {
|
||||||
|
padding: 8px;
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.left_cont {
|
||||||
|
width: 95%;
|
||||||
|
position: absolute;
|
||||||
|
top: 38px;
|
||||||
|
margin-top: 8px;
|
||||||
|
height: calc(100% - 80px);
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
.el-tree {
|
||||||
|
background: #eaedf1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right_btn {
|
||||||
|
width: 96px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 2px;
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 4px 0;
|
||||||
|
position: fixed;
|
||||||
|
z-index: 999;
|
||||||
|
|
||||||
|
li {
|
||||||
|
height: 28px;
|
||||||
|
line-height: 28px;
|
||||||
|
cursor: pointer;
|
||||||
|
text-indent: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
li:hover {
|
||||||
|
background-color: #eff6ff;
|
||||||
|
color: #5088ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn_img {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
background: #f5f6f7;
|
||||||
|
height: 32px;
|
||||||
|
line-height: 32px;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
text-align: center;
|
||||||
|
border-top: 1px solid #d8dce3;
|
||||||
|
border-radius: 0 0 4px 4px;
|
||||||
|
|
||||||
|
span {
|
||||||
|
flex: 1;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.party_right {
|
||||||
|
flex: 1;
|
||||||
|
overflow: auto;
|
||||||
|
margin-left: 11px;
|
||||||
|
|
||||||
|
.total-panel {
|
||||||
|
margin-bottom: 21px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
flex: 1;
|
||||||
|
margin-right: 32px;
|
||||||
|
display: flex;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #d8e0e8;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #333;
|
||||||
|
padding: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
height: 97px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 14px;
|
||||||
|
color: rgba(51, 51, 51, 1);
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
b {
|
||||||
|
font-size: 20px;
|
||||||
|
color: rgba(51, 51, 51, 1);
|
||||||
|
line-height: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.operation {
|
||||||
|
overflow: hidden;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 64px;
|
||||||
|
line-height: 64px;
|
||||||
|
display: flex;
|
||||||
|
z-index: 1000;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background-color: #f3f6f9;
|
||||||
|
box-shadow: inset 0px 1px 0px 0px #eeeeee;
|
||||||
|
|
||||||
|
button {
|
||||||
|
width: 92px;
|
||||||
|
height: 32px;
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-btn {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mask {
|
||||||
|
.content {
|
||||||
|
padding-bottom: 100px;
|
||||||
|
}
|
||||||
|
.el-table {
|
||||||
|
border: 1px solid #d8e0e8;
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
line-height: 28px;
|
||||||
|
text-align: right;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #5088ff;
|
||||||
|
width: 88px;
|
||||||
|
float: right;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.vc-input-120 {
|
||||||
|
width: 120px !important;
|
||||||
|
float: right;
|
||||||
|
padding-right: 16px;
|
||||||
|
|
||||||
|
.el-input__inner {
|
||||||
|
width: 120px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
66
packages/shandong/AppVillageCode/AppVillageCode.vue
Normal file
66
packages/shandong/AppVillageCode/AppVillageCode.vue
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<template>
|
||||||
|
<div class="doc-circulation ailist-wrapper">
|
||||||
|
<keep-alive :include="['List']">
|
||||||
|
<component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component>
|
||||||
|
</keep-alive>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import List from './components/List'
|
||||||
|
import Add from './components/Add'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'AppVillageCode',
|
||||||
|
label: '一村一码',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object
|
||||||
|
},
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
component: 'List',
|
||||||
|
params: {},
|
||||||
|
include: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
components: {
|
||||||
|
Add,
|
||||||
|
List
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted () {
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
onChange (data) {
|
||||||
|
if (data.type === 'Add') {
|
||||||
|
this.component = 'Add'
|
||||||
|
this.params = data.params
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.type === 'list') {
|
||||||
|
this.component = 'List'
|
||||||
|
this.params = data.params
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (data.isRefresh) {
|
||||||
|
this.$refs.component.getList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.doc-circulation {
|
||||||
|
height: 100%;
|
||||||
|
background: #F3F6F9;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
135
packages/shandong/AppVillageCode/components/Add.vue
Normal file
135
packages/shandong/AppVillageCode/components/Add.vue
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
<template>
|
||||||
|
<ai-detail>
|
||||||
|
<template slot="title">
|
||||||
|
<ai-title title="添加二维码" isShowBack isShowBottomBorder @onBackClick="cancel(false)">
|
||||||
|
</ai-title>
|
||||||
|
</template>
|
||||||
|
<template slot="content">
|
||||||
|
<ai-card title="基本信息">
|
||||||
|
<template #content>
|
||||||
|
<el-form class="ai-form" ref="form" :model="form" label-width="110px" label-position="right">
|
||||||
|
<el-form-item label="地区" style="width: 100%;" prop="codeName">
|
||||||
|
<span style="color: #666;">{{ form.areaName }}</span>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="二维码名称" prop="codeName" :rules="[{ required: true, message: '请输入二维码名称', trigger: 'blur' }]">
|
||||||
|
<el-input size="small" placeholder="请输入二维码名称" style="width: 328px;" v-model="form.codeName"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item style="width: 100%;" label="二维码类型" prop="type" :rules="[{ required: true, message: '请选择二维码类型', trigger: 'change' }]">
|
||||||
|
<el-radio-group v-model="form.type">
|
||||||
|
<el-radio label="0">群二维码</el-radio>
|
||||||
|
<el-radio label="1">个人二维码</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="上传二维码" prop="codeUrl" style="width: 100%;" :rules="[{ required: true, message: '请上传二维码', trigger: 'change' }]">
|
||||||
|
<ai-uploader :instance="instance" v-model="form.codeUrl" :limit="1"></ai-uploader>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
</template>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="cancel">取消</el-button>
|
||||||
|
<el-button type="primary" @click="confirm">提交</el-button>
|
||||||
|
</template>
|
||||||
|
</ai-detail>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'Add',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
params: Object
|
||||||
|
},
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
info: {},
|
||||||
|
form: {
|
||||||
|
areaId: '',
|
||||||
|
codeName: '',
|
||||||
|
areaName: '',
|
||||||
|
code: '',
|
||||||
|
codeUrl: [],
|
||||||
|
type: '',
|
||||||
|
},
|
||||||
|
id: '',
|
||||||
|
areaList: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created () {
|
||||||
|
this.getAreaList()
|
||||||
|
|
||||||
|
if (this.params && this.params.areaId && !this.params.id) {
|
||||||
|
this.form.areaId = this.params.areaId
|
||||||
|
this.form.areaName = this.params.areaName
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.params && this.params.id) {
|
||||||
|
this.id = this.params.id
|
||||||
|
this.getInfo(this.params.id)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
getInfo (id) {
|
||||||
|
this.instance.post(`/app/appeveryvillagecode/queryDetailById?id=${id}`).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.form = res.data
|
||||||
|
this.form.codeUrl = [{
|
||||||
|
url: res.data.codeUrl
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
getAreaList() {
|
||||||
|
this.instance.post(`/admin/area/queryAreaByParentId?id=341021104000`).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.areaList = res.data.map(item => {
|
||||||
|
item.dictName = item.name
|
||||||
|
item.dictValue = item.id
|
||||||
|
|
||||||
|
return item
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onClose () {
|
||||||
|
this.form.explain = ''
|
||||||
|
},
|
||||||
|
|
||||||
|
confirm () {
|
||||||
|
this.$refs.form.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.instance.post(`/app/appeveryvillagecode/addOrUpdate`, {
|
||||||
|
...this.form,
|
||||||
|
codeUrl: this.form.codeUrl[0].url
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message.success('提交成功')
|
||||||
|
setTimeout(() => {
|
||||||
|
this.cancel(true)
|
||||||
|
}, 600)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
cancel (isRefresh) {
|
||||||
|
this.$emit('change', {
|
||||||
|
type: 'list',
|
||||||
|
isRefresh: !!isRefresh
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
</style>
|
||||||
422
packages/shandong/AppVillageCode/components/List.vue
Normal file
422
packages/shandong/AppVillageCode/components/List.vue
Normal file
@@ -0,0 +1,422 @@
|
|||||||
|
<template>
|
||||||
|
<ai-list class="villagecode">
|
||||||
|
<template slot="title">
|
||||||
|
<ai-title title="一村一码" isShowBottomBorder></ai-title>
|
||||||
|
</template>
|
||||||
|
<template #left>
|
||||||
|
<div class="villagecode-left">
|
||||||
|
<div class="villagecode-left__title">
|
||||||
|
<h2>村列表</h2>
|
||||||
|
</div>
|
||||||
|
<div class="addressBook-left__list">
|
||||||
|
<div class="addressBook-left__list--title">
|
||||||
|
<el-input
|
||||||
|
class="addressBook-left__list--search"
|
||||||
|
size="mini"
|
||||||
|
placeholder="请输入地区名称"
|
||||||
|
v-model="unitName"
|
||||||
|
suffix-icon="iconfont iconSearch">
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
<el-tree
|
||||||
|
:filter-node-method="filterNode"
|
||||||
|
ref="tree"
|
||||||
|
:props="defaultProps"
|
||||||
|
node-key="id"
|
||||||
|
:data="areaTree"
|
||||||
|
highlight-current
|
||||||
|
:current-node-key="search.areaId"
|
||||||
|
:default-expanded-keys="defaultExpanded"
|
||||||
|
:default-checked-keys="defaultChecked"
|
||||||
|
@current-change="onTreeChange">
|
||||||
|
</el-tree>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template slot="content">
|
||||||
|
<ai-search-bar class="search-bar">
|
||||||
|
<template #left>
|
||||||
|
<el-button size="small" type="primary" :disabled="isShowAdd" icon="iconfont iconAdd" @click="toAdd('')">添加活码</el-button>
|
||||||
|
</template>
|
||||||
|
</ai-search-bar>
|
||||||
|
<ai-table
|
||||||
|
:tableData="tableData"
|
||||||
|
:col-configs="colConfigs"
|
||||||
|
:total="total"
|
||||||
|
style="margin-top: 6px;"
|
||||||
|
:current.sync="search.current"
|
||||||
|
:size.sync="search.size"
|
||||||
|
@getList="getList">
|
||||||
|
<el-table-column slot="tags" label="标签">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<div class="table-tags">
|
||||||
|
<el-tag type="info" v-for="(item, index) in row.tags" size="small" :key="index">{{ item }}</el-tag>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column slot="options" width="180px" fixed="right" label="操作" align="center">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<div class="table-options">
|
||||||
|
<el-popover
|
||||||
|
placement="bottom"
|
||||||
|
width="160"
|
||||||
|
:visible-arrow="false"
|
||||||
|
popper-class="wechat-message__container"
|
||||||
|
trigger="hover">
|
||||||
|
<el-button type="text" slot="reference">二维码</el-button>
|
||||||
|
<div style="font-size: 0;">
|
||||||
|
<img class="message-info__img" :src="row.codeUrl">
|
||||||
|
</div>
|
||||||
|
</el-popover>
|
||||||
|
<el-button type="text" @click="toAdd(row.id)">编辑</el-button>
|
||||||
|
<el-button type="text" @click="remove(row.id)">删除</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</ai-table>
|
||||||
|
</template>
|
||||||
|
</ai-list>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState } from 'vuex'
|
||||||
|
export default {
|
||||||
|
name: 'List',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
search: {
|
||||||
|
current: 1,
|
||||||
|
size: 10,
|
||||||
|
status: 0,
|
||||||
|
title: '',
|
||||||
|
areaId: ''
|
||||||
|
},
|
||||||
|
defaultExpanded: [],
|
||||||
|
defaultChecked: [],
|
||||||
|
areaTree: [],
|
||||||
|
defaultProps: {
|
||||||
|
children: 'children',
|
||||||
|
label: 'name'
|
||||||
|
},
|
||||||
|
currIndex: -1,
|
||||||
|
areaList: [],
|
||||||
|
total: 10,
|
||||||
|
colConfigs: [
|
||||||
|
{prop: 'codeName', label: '名称', align: 'left'},
|
||||||
|
{prop: 'type', label: '二维码类型', align: 'left', formart: v => v === '0' ? '群二维码' : '个人二维码'},
|
||||||
|
{prop: 'createUserName', label: '创建人'},
|
||||||
|
{prop: 'createTime', label: '创建时间'},
|
||||||
|
{slot: 'options', label: '操作'}
|
||||||
|
],
|
||||||
|
areaName: '',
|
||||||
|
unitName: '',
|
||||||
|
tableData: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
...mapState(['user']),
|
||||||
|
|
||||||
|
isShowAdd () {
|
||||||
|
const str = this.search.areaId.substr(this.search.areaId.length - 3)
|
||||||
|
|
||||||
|
return str === '000'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
unitName (val) {
|
||||||
|
this.$refs.tree.filter(val)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.search.areaId = this.user.info.areaId
|
||||||
|
this.areaName = this.user.info.areaName
|
||||||
|
this.getTree()
|
||||||
|
this.getAreaList()
|
||||||
|
this.getList()
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
getList() {
|
||||||
|
this.instance.post(`/app/appeveryvillagecode/list`, null, {
|
||||||
|
params: {
|
||||||
|
...this.search
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.tableData = res.data.records
|
||||||
|
this.total = res.data.total
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
filterNode(value, data) {
|
||||||
|
if (!value) return true
|
||||||
|
return data.name.indexOf(value) !== -1
|
||||||
|
},
|
||||||
|
|
||||||
|
onTreeChange (e) {
|
||||||
|
this.search.areaId = e.id
|
||||||
|
this.areaName = e.name
|
||||||
|
this.search.current = 1
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.getList()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
getTree () {
|
||||||
|
this.instance.post(`/admin/area/queryAllArea?id=${this.user.info.areaId}`).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
let parent = res.data.map(v => {
|
||||||
|
v.label = v.name
|
||||||
|
v.children = []
|
||||||
|
|
||||||
|
return v
|
||||||
|
}).filter(e => !e.parentid)[0]
|
||||||
|
this.defaultExpanded = [parent.id]
|
||||||
|
this.defaultChecked = [parent.id]
|
||||||
|
this.search.areaId = parent.id
|
||||||
|
this.addChild(parent, res.data)
|
||||||
|
this.areaTree = [parent]
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.tree.setCurrentKey(parent.id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
addChild (parent, list) {
|
||||||
|
for (let i = 0; i < list.length; i++) {
|
||||||
|
if (list[i].parentId === parent.id) {
|
||||||
|
parent.children.push(list[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (list.length > 0) {
|
||||||
|
parent['children'].map(v => this.addChild(v, list))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
getAreaList() {
|
||||||
|
this.instance.post(`/admin/area/queryAreaByParentId?id=341021104000`).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.areaList = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
remove(id) {
|
||||||
|
this.$confirm('确定删除该数据?').then(() => {
|
||||||
|
this.instance.post(`/app/appeveryvillagecode/delete?ids=${id}`).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message.success('删除成功!')
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
toAdd(id) {
|
||||||
|
this.$emit('change', {
|
||||||
|
type: 'Add',
|
||||||
|
params: {
|
||||||
|
areaName: this.areaName,
|
||||||
|
id: id || '',
|
||||||
|
areaId: this.search.areaId
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.villagecode {
|
||||||
|
.table-tags {
|
||||||
|
.el-tag {
|
||||||
|
margin-right: 8px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.addressBook-left__list {
|
||||||
|
height: calc(100% - 40px);
|
||||||
|
padding: 8px 8px;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
.addressBook-left__tags--item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: 40px;
|
||||||
|
padding: 0 8px 0 16px;
|
||||||
|
color: #222222;
|
||||||
|
|
||||||
|
&.addressBook-left__tags--item-active, &:hover {
|
||||||
|
background: #E8EFFF;
|
||||||
|
color: #2266FF;
|
||||||
|
|
||||||
|
i, span {
|
||||||
|
color: #2266FF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
cursor: pointer;
|
||||||
|
color: #8e9ebf;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.addressBook-left__list--title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
|
||||||
|
.addressBook-left__list--search {
|
||||||
|
flex: 1;
|
||||||
|
::v-deep input {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
width: 84px;
|
||||||
|
flex-shrink: 1;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #222222;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-tree {
|
||||||
|
background: transparent;
|
||||||
|
|
||||||
|
.el-tree-node__expand-icon.is-leaf {
|
||||||
|
color: transparent!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree-node__content > .el-tree-node__expand-icon {
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree-node__content {
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree__empty-text {
|
||||||
|
color: #222;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree-node__children .el-tree-node__content {
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-tree-node__content:hover {
|
||||||
|
background: #E8EFFF;
|
||||||
|
color: #222222;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-current > .el-tree-node__content {
|
||||||
|
&:hover {
|
||||||
|
background: #2266FF;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
background: #2266FF;
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.villagecode-left {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
background: #FAFAFB;
|
||||||
|
|
||||||
|
.villagecode-left__title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 40px;
|
||||||
|
padding: 0 16px;
|
||||||
|
background: #E5E5E5;
|
||||||
|
|
||||||
|
h2 {
|
||||||
|
color: #222;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.villagecode-left__list {
|
||||||
|
height: calc(100% - 40px);
|
||||||
|
padding: 8px 0;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
span {
|
||||||
|
display: block;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
padding: 0 24px;
|
||||||
|
color: #222222;
|
||||||
|
font-size: 14px;
|
||||||
|
cursor: pointer;
|
||||||
|
border-right: 2px solid transparent;
|
||||||
|
background: transparent;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #2266FF;
|
||||||
|
background: #E8EFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.left-active {
|
||||||
|
color: #2266FF;
|
||||||
|
border-color: #2266FF;
|
||||||
|
background: #E8EFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .ai-list__content--right {
|
||||||
|
|
||||||
|
.ai-list__content--right-wrapper {
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-info__img {
|
||||||
|
font-size: 0;
|
||||||
|
width: 144px;
|
||||||
|
height: 144px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
66
packages/shandong/AppVillagersCircle/AppVillagersCircle.vue
Normal file
66
packages/shandong/AppVillagersCircle/AppVillagersCircle.vue
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<template>
|
||||||
|
<div class="doc-circulation ailist-wrapper">
|
||||||
|
<keep-alive :include="['List']">
|
||||||
|
<component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component>
|
||||||
|
</keep-alive>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import List from './components/List'
|
||||||
|
import Detail from './components/Detail'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'AppVillagersCircle',
|
||||||
|
label: '村民圈',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object
|
||||||
|
},
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
component: 'List',
|
||||||
|
params: {},
|
||||||
|
include: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
components: {
|
||||||
|
List,
|
||||||
|
Detail
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted () {
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
onChange (data) {
|
||||||
|
if (data.type === 'Detail') {
|
||||||
|
this.component = 'Detail'
|
||||||
|
this.params = data.params
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.type === 'list') {
|
||||||
|
this.component = 'List'
|
||||||
|
this.params = data.params
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
if (data.isRefresh) {
|
||||||
|
this.$refs.component.getList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.doc-circulation {
|
||||||
|
height: 100%;
|
||||||
|
background: #F3F6F9;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
105
packages/shandong/AppVillagersCircle/components/Detail.vue
Normal file
105
packages/shandong/AppVillagersCircle/components/Detail.vue
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
<template>
|
||||||
|
<ai-detail>
|
||||||
|
<template slot="title">
|
||||||
|
<ai-title title="村民圈详情" isShowBack isShowBottomBorder @onBackClick="cancel(false)">
|
||||||
|
</ai-title>
|
||||||
|
</template>
|
||||||
|
<template slot="content">
|
||||||
|
<ai-card title="基础信息">
|
||||||
|
<ai-wrapper slot="content">
|
||||||
|
<ai-info-item label="主题" :value="info.content" isLine></ai-info-item>
|
||||||
|
<ai-info-item label="发布地区" :value="info.areaName" isLine></ai-info-item>
|
||||||
|
<ai-info-item label="议事截止时间" :value="info.discussDeadline"></ai-info-item>
|
||||||
|
<ai-info-item label="公示截止时间" :value="info.publicityDeadline"></ai-info-item>
|
||||||
|
<ai-info-item label="议事类型" :value="dict.getLabel('discussType', info.type)" isLine></ai-info-item>
|
||||||
|
<ai-info-item label="是否匿名投票" v-if="info.type === '1'" :value="info.anonymous === '1' ? '是' : '否'"></ai-info-item>
|
||||||
|
<ai-info-item label="投票方式" v-if="info.type === '1'" :value="info.voteType === '0' ? '单选' : '多选'"></ai-info-item>
|
||||||
|
<ai-info-item label="图片" isLine>
|
||||||
|
<ai-uploader
|
||||||
|
:instance="instance"
|
||||||
|
disabled
|
||||||
|
v-model="info.images"
|
||||||
|
:limit="9">
|
||||||
|
</ai-uploader>
|
||||||
|
</ai-info-item>
|
||||||
|
</ai-wrapper>
|
||||||
|
</ai-card>
|
||||||
|
<ai-dialog
|
||||||
|
:visible.sync="isShowAdd"
|
||||||
|
width="680px"
|
||||||
|
height="580px"
|
||||||
|
title="发表意见"
|
||||||
|
@close="onClose"
|
||||||
|
@onConfirm="onConfirm">
|
||||||
|
<el-form ref="form" class="ai-form" :model="form" label-width="110px" label-position="right">
|
||||||
|
<el-form-item label="发表意见" prop="content" style="width: 100%;" :rules="[{ required: true, message: '请发表你的观点和意见', trigger: 'blur' }]">
|
||||||
|
<el-input size="small" type="textarea" :rows="5" show-word-limit :maxlength="140" placeholder="请发表你的观点和意见" v-model="form.content"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ai-dialog>
|
||||||
|
</template>
|
||||||
|
</ai-detail>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState } from 'vuex'
|
||||||
|
export default {
|
||||||
|
name: 'Detail',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
params: Object
|
||||||
|
},
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
info: {},
|
||||||
|
id: '',
|
||||||
|
search: {
|
||||||
|
current: 1,
|
||||||
|
size: 10
|
||||||
|
},
|
||||||
|
isShowAdd: false,
|
||||||
|
form: {
|
||||||
|
content: ''
|
||||||
|
},
|
||||||
|
type: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
...mapState(['user'])
|
||||||
|
},
|
||||||
|
|
||||||
|
created () {
|
||||||
|
this.getInfo(this.params.id)
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
getInfo (id) {
|
||||||
|
this.instance.post(`/app/appvillagediscuss/queryDetailById?id=${id}`).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.info = res.data
|
||||||
|
this.info.images = res.data.images ? JSON.parse(res.data.images) : []
|
||||||
|
this.type = res.data.type
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onClose () {
|
||||||
|
this.form.content = ''
|
||||||
|
},
|
||||||
|
|
||||||
|
cancel (isRefresh) {
|
||||||
|
this.$emit('change', {
|
||||||
|
type: 'list',
|
||||||
|
isRefresh: !!isRefresh
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
</style>
|
||||||
173
packages/shandong/AppVillagersCircle/components/List.vue
Normal file
173
packages/shandong/AppVillagersCircle/components/List.vue
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
<template>
|
||||||
|
<ai-list class="notice">
|
||||||
|
<template slot="title">
|
||||||
|
<ai-title title="村民圈" isShowBottomBorder isShowArea v-model="search.areaId" :instance="instance" @change="search.current = 1, getList()"></ai-title>
|
||||||
|
</template>
|
||||||
|
<template slot="content">
|
||||||
|
<ai-search-bar class="search-bar">
|
||||||
|
<template #left>
|
||||||
|
<ai-select placeholder="请选择状态" v-model="search.type" clearable @change="search.current = 1, getList()" :selectList="dict.getDict('discussType')"></ai-select>
|
||||||
|
<ai-select placeholder="请选择话题" v-model="search.status" clearable @change="search.current = 1, getList()" :selectList="dict.getDict('discussStatus')"></ai-select>
|
||||||
|
</template>
|
||||||
|
<template #right>
|
||||||
|
<el-input
|
||||||
|
v-model="search.title"
|
||||||
|
class="search-input"
|
||||||
|
size="small"
|
||||||
|
@keyup.enter.native="search.current = 1, search.title, getList()"
|
||||||
|
placeholder="请输入发布人姓名"
|
||||||
|
clearable
|
||||||
|
@clear="search.current = 1, search.title = '', getList()"
|
||||||
|
suffix-icon="iconfont iconSearch">
|
||||||
|
</el-input>
|
||||||
|
</template>
|
||||||
|
</ai-search-bar>
|
||||||
|
<ai-table
|
||||||
|
:tableData="tableData"
|
||||||
|
:col-configs="colConfigs"
|
||||||
|
:total="total"
|
||||||
|
style="margin-top: 6px;"
|
||||||
|
:current.sync="search.current"
|
||||||
|
:size.sync="search.size"
|
||||||
|
@getList="getList">
|
||||||
|
<el-table-column slot="tags" label="标签">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<div class="table-tags">
|
||||||
|
<el-tag type="info" v-for="(item, index) in row.tags" size="small" :key="index">{{ item }}</el-tag>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column slot="options" width="160px" fixed="right" label="操作" align="center">
|
||||||
|
<template slot-scope="{ row }">
|
||||||
|
<div class="table-options">
|
||||||
|
<el-button type="text" title="详情" @click="toDetail(row.id)">详情</el-button>
|
||||||
|
<el-button type="text" title="取消公示" @click="changeStatus(row)" :disabled="row.status !== '1'">结束公示</el-button>
|
||||||
|
<el-button type="text" @click="remove(row.id)">删除</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</ai-table>
|
||||||
|
</template>
|
||||||
|
</ai-list>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState } from 'vuex'
|
||||||
|
export default {
|
||||||
|
name: 'List',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
search: {
|
||||||
|
current: 1,
|
||||||
|
size: 10,
|
||||||
|
status: '',
|
||||||
|
type: '',
|
||||||
|
title: '',
|
||||||
|
areaId: ''
|
||||||
|
},
|
||||||
|
currIndex: -1,
|
||||||
|
areaList: [],
|
||||||
|
total: 10,
|
||||||
|
colConfigs: [
|
||||||
|
{ prop: 'content', label: '议事主题', align: 'left', width: '200px' },
|
||||||
|
{ prop: 'type', label: '议事类型', align: 'center', formart: v => this.dict.getLabel('discussType', v) },
|
||||||
|
{ prop: 'createUserName', label: '话事人', align: 'center' },
|
||||||
|
{ prop: 'msgCountTotal', label: '观点数量', align: 'center', formart: v => v === 0 ? '-' : v },
|
||||||
|
{ prop: 'voteCount', label: '投票数量', align: 'center', formart: v => v === 0 ? '-' : v },
|
||||||
|
{ prop: 'status', label: '发布状态', align: 'center', formart: v => this.dict.getLabel('discussStatus', v) },
|
||||||
|
{ prop: 'createTime', label: '发布时间', align: 'center' },
|
||||||
|
{ slot: 'options', label: '操作', align: 'center' }
|
||||||
|
],
|
||||||
|
areaName: '',
|
||||||
|
unitName: '',
|
||||||
|
tableData: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
...mapState(['user'])
|
||||||
|
},
|
||||||
|
|
||||||
|
created () {
|
||||||
|
this.search.areaId = this.user.info.areaId
|
||||||
|
this.dict.load(['discussType', 'discussStatus']).then(() => {
|
||||||
|
this.getList()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
getList() {
|
||||||
|
this.instance.post(`/app/appvillagediscuss/listUp`, null, {
|
||||||
|
params: {
|
||||||
|
type: 0,
|
||||||
|
...this.search
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.tableData = res.data.records.map(v => {
|
||||||
|
return {
|
||||||
|
...v,
|
||||||
|
content: v.content || v.title
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.total = res.data.total
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
changeStatus (item) {
|
||||||
|
this.$confirm('是否要结束公示', {type: 'warning'}).then(() => {
|
||||||
|
this.instance.post('/app/appvillagediscuss/finishPublic', {
|
||||||
|
status: '2',
|
||||||
|
id: item.id
|
||||||
|
}).then(res => {
|
||||||
|
if (res && res.code == 0) {
|
||||||
|
this.$message.success('结束公示成功')
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
remove(id) {
|
||||||
|
this.$confirm('确定删除该数据?').then(() => {
|
||||||
|
this.instance.post(`/app/appvillagediscuss/delete?ids=${id}`).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message.success('删除成功!')
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
toDetail (id) {
|
||||||
|
this.$emit('change', {
|
||||||
|
type: 'Detail',
|
||||||
|
params: {
|
||||||
|
id: id || ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
toAdd(id) {
|
||||||
|
this.$emit('change', {
|
||||||
|
type: 'Add',
|
||||||
|
params: {
|
||||||
|
id: id || ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.notice {
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
registry=http://192.168.1.87:4873/
|
|
||||||
email=aixianling@sinoecare.com
|
|
||||||
always-auth=true
|
|
||||||
_auth="YWRtaW46YWRtaW4xMjM="
|
|
||||||
package-lock=false
|
|
||||||
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="AppGridBlock">
|
|
||||||
<keep-alive include="List">
|
|
||||||
<component
|
|
||||||
ref="component"
|
|
||||||
:is="component"
|
|
||||||
@change="onChange"
|
|
||||||
:params="params"
|
|
||||||
:instance="instance"
|
|
||||||
:dict="dict"
|
|
||||||
:isEdit="isEdit"
|
|
||||||
></component>
|
|
||||||
</keep-alive>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import List from "./components/list";
|
|
||||||
import Add from "./components/add";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "AppGridBlock",
|
|
||||||
label: "网格区块--山东",
|
|
||||||
|
|
||||||
props: {
|
|
||||||
instance: Function,
|
|
||||||
dict: Object,
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
component: "List",
|
|
||||||
params: {},
|
|
||||||
include: [],
|
|
||||||
isEdit: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
|
||||||
Add,
|
|
||||||
List,
|
|
||||||
},
|
|
||||||
|
|
||||||
mounted() {},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
onChange(data) {
|
|
||||||
if (data.type === "Add") {
|
|
||||||
this.component = "Add";
|
|
||||||
this.params = data.params;
|
|
||||||
this.isEdit = data.isEdit
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.type === "list") {
|
|
||||||
this.component = "List";
|
|
||||||
this.params = data.params;
|
|
||||||
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if (data.isRefresh) {
|
|
||||||
this.$refs.component.getList();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.AppGridBlock {
|
|
||||||
height: 100%;
|
|
||||||
background: #f3f6f9;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,580 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="add-block">
|
|
||||||
<ai-detail>
|
|
||||||
<template #title>
|
|
||||||
<ai-title
|
|
||||||
:title="title"
|
|
||||||
:isShowBack="true"
|
|
||||||
:isShowBottomBorder="true"
|
|
||||||
@onBackClick="cancel(false)"
|
|
||||||
></ai-title>
|
|
||||||
</template>
|
|
||||||
<template #content>
|
|
||||||
<ai-card title="层级信息">
|
|
||||||
<template slot="content">
|
|
||||||
<ai-wrapper label-width="120px" :columnsNumber="2" style="margin-top: 16px">
|
|
||||||
<ai-info-item label="上级层级单位:"><span>{{ forms.parentGirdName }}</span></ai-info-item>
|
|
||||||
</ai-wrapper>
|
|
||||||
</template>
|
|
||||||
</ai-card>
|
|
||||||
|
|
||||||
<el-form
|
|
||||||
ref="rules"
|
|
||||||
:model="forms"
|
|
||||||
:rules="formRules"
|
|
||||||
size="small"
|
|
||||||
label-suffix=":"
|
|
||||||
label-width="120px"
|
|
||||||
>
|
|
||||||
<ai-card title="基础信息">
|
|
||||||
<template slot="content">
|
|
||||||
<div class="above">
|
|
||||||
<div class="left">
|
|
||||||
<el-form-item label="网格名称" prop="girdName">
|
|
||||||
<el-input
|
|
||||||
v-model="forms.girdName"
|
|
||||||
placeholder="请输入…"
|
|
||||||
:maxlength="50"
|
|
||||||
show-word-limit
|
|
||||||
></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="网格类型" prop="girdType">
|
|
||||||
<el-select
|
|
||||||
v-model="forms.girdType"
|
|
||||||
placeholder="请选择"
|
|
||||||
clearable
|
|
||||||
style="width: 100%;"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(item, i) in dict.getDict('girdType')"
|
|
||||||
:key="i"
|
|
||||||
:label="item.dictName"
|
|
||||||
:value="item.dictValue"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="是否最后一级" prop="isLastLevel">
|
|
||||||
<el-select
|
|
||||||
v-model="forms.isLastLevel"
|
|
||||||
placeholder="请选择"
|
|
||||||
clearable
|
|
||||||
style="width: 100%;"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(item, i) in dict.getDict('isLastLevel')"
|
|
||||||
:key="i"
|
|
||||||
:label="item.dictName"
|
|
||||||
:value="item.dictValue"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
|
||||||
<div class="right">
|
|
||||||
<el-form-item label="网格编码" prop="girdCode">
|
|
||||||
<el-input
|
|
||||||
v-model="forms.girdCode"
|
|
||||||
placeholder="请输入…"
|
|
||||||
maxlength="30"
|
|
||||||
show-word-limit
|
|
||||||
></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="网格层级" prop="girdLevel">
|
|
||||||
<el-select
|
|
||||||
v-model="forms.girdLevel"
|
|
||||||
placeholder="请选择"
|
|
||||||
:disabled="isEdit"
|
|
||||||
clearable
|
|
||||||
style="width: 100%;"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(item, i) in dict.getDict('girdLevel')"
|
|
||||||
:key="i"
|
|
||||||
:label="item.dictName"
|
|
||||||
:value="item.dictValue"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</ai-card>
|
|
||||||
|
|
||||||
<ai-card title="其他信息">
|
|
||||||
<template slot="content">
|
|
||||||
<div class="above">
|
|
||||||
<div class="left">
|
|
||||||
<!-- <el-form-item label="事件上报主体" prop="eventReportUnitId">
|
|
||||||
<el-cascader
|
|
||||||
style="width: 100%"
|
|
||||||
:options="unitOps"
|
|
||||||
ref="cascader"
|
|
||||||
v-model="forms.eventReportUnitId"
|
|
||||||
:props="unitProps"
|
|
||||||
:show-all-levels="false"
|
|
||||||
/>
|
|
||||||
</el-form-item> -->
|
|
||||||
<el-form-item label="初始日期" prop="startDate">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="forms.startDate"
|
|
||||||
type="date"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
placeholder="选择日期"
|
|
||||||
style="width: 100%;"
|
|
||||||
>
|
|
||||||
</el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="终止日期" prop="endDate">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="forms.endDate"
|
|
||||||
type="date"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
placeholder="选择日期"
|
|
||||||
style="width: 100%;"
|
|
||||||
>
|
|
||||||
</el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
|
||||||
<div class="right">
|
|
||||||
<el-form-item label="面积" prop="area">
|
|
||||||
<el-input
|
|
||||||
v-model="forms.area"
|
|
||||||
placeholder="面积㎡"
|
|
||||||
></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<el-form-item label="网格地址" prop="address">
|
|
||||||
<el-input v-model="forms.address" placeholder="限200字" maxlength="200"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="网格范围" prop="enclosure" v-if="forms.girdLevel === '2' || isAddLastLevel">
|
|
||||||
<el-button size="small" @click="showMap = true">地图标绘</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</template>
|
|
||||||
</ai-card>
|
|
||||||
</el-form>
|
|
||||||
</template>
|
|
||||||
<template #footer>
|
|
||||||
<el-button @click="cancel(false)" class="delete-btn footer-btn">
|
|
||||||
取 消
|
|
||||||
</el-button>
|
|
||||||
<el-button type="primary" @click="save()" class="footer-btn">
|
|
||||||
提 交
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
</ai-detail>
|
|
||||||
<ai-dialog
|
|
||||||
title="网格范围"
|
|
||||||
:visible.sync="showMap"
|
|
||||||
:customFooter="true"
|
|
||||||
:destroyOnClose="true"
|
|
||||||
@opened="beforeSelectMap"
|
|
||||||
border
|
|
||||||
width="850px"
|
|
||||||
>
|
|
||||||
<div class="map">
|
|
||||||
<div class="tipinput">
|
|
||||||
<el-input
|
|
||||||
v-model="searchAddress"
|
|
||||||
@change="addressChange"
|
|
||||||
clearable
|
|
||||||
placeholder="请输入关键字"
|
|
||||||
id="tipinput"
|
|
||||||
size="medium"
|
|
||||||
style="width: 200px"
|
|
||||||
></el-input>
|
|
||||||
</div>
|
|
||||||
<div id="panel"></div>
|
|
||||||
<div class="container" id="container"></div>
|
|
||||||
<el-button-group
|
|
||||||
style="margin-top: 8px"
|
|
||||||
v-if="forms.plottingStatus == 1"
|
|
||||||
>
|
|
||||||
<el-button type="primary" size="mini" @click="polyEditor.open()"
|
|
||||||
>开始编辑
|
|
||||||
</el-button
|
|
||||||
>
|
|
||||||
<el-button size="mini" @click="polyEditor.close()"
|
|
||||||
>结束编辑
|
|
||||||
</el-button
|
|
||||||
>
|
|
||||||
</el-button-group>
|
|
||||||
<el-button-group
|
|
||||||
style="margin-top: 8px"
|
|
||||||
v-if="forms.plottingStatus == 0"
|
|
||||||
>
|
|
||||||
<el-button size="mini" @click="draw('polygon')"
|
|
||||||
>开始绘制多边形
|
|
||||||
</el-button
|
|
||||||
>
|
|
||||||
<!-- <el-button size="mini" @click="close()">关闭绘制</el-button> -->
|
|
||||||
<el-button size="mini" @click="clear()">清除绘制</el-button>
|
|
||||||
</el-button-group>
|
|
||||||
</div>
|
|
||||||
<div class="dialog-footer" slot="footer">
|
|
||||||
<el-button size="medium" @click="showMap = false">取消</el-button>
|
|
||||||
<el-button type="primary" size="medium" @click="surePotting()"
|
|
||||||
>确认
|
|
||||||
</el-button
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</ai-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import AMapLoader from "@amap/amap-jsapi-loader";
|
|
||||||
import {mapState} from "vuex";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "addBlock",
|
|
||||||
props: {
|
|
||||||
instance: Function,
|
|
||||||
dict: Object,
|
|
||||||
params: Object,
|
|
||||||
isEdit: Boolean
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
forms: {
|
|
||||||
address: "",
|
|
||||||
area: "",
|
|
||||||
points: [],
|
|
||||||
endDate: "",
|
|
||||||
eventReportUnit: "",
|
|
||||||
eventReportUnitId: "",
|
|
||||||
girdCode: "",
|
|
||||||
girdLevel: "",
|
|
||||||
girdList: [],
|
|
||||||
girdName: "",
|
|
||||||
girdType: "",
|
|
||||||
isLastLevel: "",
|
|
||||||
parentGirdId: "",
|
|
||||||
parentGirdName: "",
|
|
||||||
startDate: "",
|
|
||||||
plottingStatus: "0",
|
|
||||||
},
|
|
||||||
showMap: false,
|
|
||||||
map: "",
|
|
||||||
mouseTool: "",
|
|
||||||
searchAddress: "",
|
|
||||||
placeSearch: "",
|
|
||||||
overlays: [],
|
|
||||||
options: [],
|
|
||||||
path: [],
|
|
||||||
location: {},
|
|
||||||
polyEditor: "",
|
|
||||||
title: "添加网格区块",
|
|
||||||
parentGirdInfo: {},
|
|
||||||
isAddLastLevel: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapState(["user"]),
|
|
||||||
formRules() {
|
|
||||||
return {
|
|
||||||
girdName: [
|
|
||||||
{required: true, message: "请输入网格名称", trigger: "change"},
|
|
||||||
],
|
|
||||||
girdLevel: [
|
|
||||||
{required: true, message: "请选择网格层级", trigger: "change"},
|
|
||||||
],
|
|
||||||
girdCode: [
|
|
||||||
{required: true, message: "请输入网格编号"},
|
|
||||||
{pattern: /^\d+$/g, message: "请输入数字"},
|
|
||||||
]
|
|
||||||
};
|
|
||||||
},
|
|
||||||
unitProps() {
|
|
||||||
return {
|
|
||||||
value: "id",
|
|
||||||
checkStrictly: true,
|
|
||||||
emitPath: false,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
unitOps() {
|
|
||||||
let initData = JSON.parse(JSON.stringify(this.options)),
|
|
||||||
ops = initData.filter((e) => !e.parentId);
|
|
||||||
ops.map((e) => this.addChild(e, initData));
|
|
||||||
return ops;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getCorpLocation()
|
|
||||||
if (this.isEdit) {
|
|
||||||
this.title = "编辑网格区块";
|
|
||||||
this.searchDetail();
|
|
||||||
} else {
|
|
||||||
this.forms.parentGirdId = this.params.id;
|
|
||||||
this.forms.parentGirdName = this.params.girdName;
|
|
||||||
this.isAddLastLevel = this.params.girdLevel === '1'
|
|
||||||
// this.forms.girdLevel = Number(this.info.girdLevel) + 1 +'';
|
|
||||||
// this.forms.isLastLevel = ['0','1'].includes(this.forms.girdLevel)?'0':'1';
|
|
||||||
this.title = "添加网格区块";
|
|
||||||
}
|
|
||||||
// this.getAllUnit(this.user.info.areaId);
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
cancel(isRefresh) {
|
|
||||||
this.$emit('change', {
|
|
||||||
type: 'list',
|
|
||||||
isRefresh: !!isRefresh,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
// 获取所有单位
|
|
||||||
getAllUnit(data) {
|
|
||||||
this.options = [];
|
|
||||||
this.instance.post("/admin/sysunit/getAll", null, {
|
|
||||||
params: {areaId: data},
|
|
||||||
}).then((res) => {
|
|
||||||
if (res?.data) {
|
|
||||||
res.data = res.data.map((a) => {
|
|
||||||
return {...a, label: a.name}
|
|
||||||
});
|
|
||||||
this.options = res.data.filter((e) => !e.parentId);
|
|
||||||
this.options.map((t) => this.addChild(t, res.data));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
beforeSelectMap() {
|
|
||||||
AMapLoader.load({
|
|
||||||
key: "b553334ba34f7ac3cd09df9bc8b539dc", // 申请好的Web端开发者Key,首次调用 load 时必填
|
|
||||||
version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
|
|
||||||
plugins: ["AMap.MouseTool", "AMap.PlaceSearch", "AMap.PolygonEditor"], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
|
|
||||||
AMapUI: {
|
|
||||||
// 是否加载 AMapUI,缺省不加载
|
|
||||||
version: "1.1", // AMapUI 缺省 1.1
|
|
||||||
plugins: [], // 需要加载的 AMapUI ui插件
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((AMap) => {
|
|
||||||
this.map = new AMap.Map("container", {
|
|
||||||
resizeEnable: true,
|
|
||||||
});
|
|
||||||
if (this.forms.plottingStatus == 1) {
|
|
||||||
let path = [];
|
|
||||||
this.forms.points.map((e, index) => {
|
|
||||||
path[index] = [e.lng, e.lat];
|
|
||||||
});
|
|
||||||
let polygon = new AMap.Polygon({
|
|
||||||
path: path,
|
|
||||||
strokeColor: "#FF33FF",
|
|
||||||
strokeWeight: 6,
|
|
||||||
strokeOpacity: 0.2,
|
|
||||||
fillOpacity: 0.4,
|
|
||||||
fillColor: "#1791fc",
|
|
||||||
zIndex: 50,
|
|
||||||
bubble: true,
|
|
||||||
});
|
|
||||||
this.map.add([polygon]);
|
|
||||||
this.map.setFitView();
|
|
||||||
this.polyEditor = new AMap.PolygonEditor(this.map, polygon);
|
|
||||||
} else {
|
|
||||||
this.mouseTool = new AMap.MouseTool(this.map);
|
|
||||||
// this.map.add(new AMap.Marker({
|
|
||||||
// position:this.map.getCenter()
|
|
||||||
// }));
|
|
||||||
this.placeSearch = new AMap.PlaceSearch({
|
|
||||||
pageSize: 3, // 单页显示结果条数
|
|
||||||
pageIndex: 1, // 页码
|
|
||||||
city: "", // 兴趣点城市
|
|
||||||
citylimit: false, //是否强制限制在设置的城市内搜索
|
|
||||||
map: this.map, // 展现结果的地图实例
|
|
||||||
panel: "panel", // 结果列表将在此容器中进行展示。
|
|
||||||
autoFitView: true, // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
|
|
||||||
});
|
|
||||||
this.map.setZoomAndCenter(14, [this.location.lng, this.location.lat], false, 600);
|
|
||||||
this.eventOn();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getCorpLocation() {
|
|
||||||
this.instance.post("/app/appdvcpconfig/getCorpLocation").then(res => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.location = res.data
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
//地图事件绑定
|
|
||||||
eventOn() {
|
|
||||||
this.path = [];
|
|
||||||
this.overlays = [];
|
|
||||||
this.map.on("mousemove", null, this);
|
|
||||||
this.mouseTool.on("draw", ({obj}) => {
|
|
||||||
obj.getPath().map((e) => {
|
|
||||||
this.path.push({lat: e.getLat(), lng: e.getLng()});
|
|
||||||
});
|
|
||||||
this.overlays.push(obj);
|
|
||||||
})
|
|
||||||
},
|
|
||||||
//map搜索
|
|
||||||
addressChange(val) {
|
|
||||||
this.placeSearch.search(val);
|
|
||||||
},
|
|
||||||
close() {
|
|
||||||
this.mouseTool.close(true);
|
|
||||||
},
|
|
||||||
clear() {
|
|
||||||
this.map.remove(this.overlays);
|
|
||||||
this.overlays = [];
|
|
||||||
this.path = [];
|
|
||||||
},
|
|
||||||
draw(type) {
|
|
||||||
switch (type) {
|
|
||||||
case "marker": {
|
|
||||||
this.mouseTool.marker({
|
|
||||||
//同Marker的Option设置
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "polyline": {
|
|
||||||
this.mouseTool.polyline({
|
|
||||||
strokeColor: "#80d8ff",
|
|
||||||
//同Polyline的Option设置
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "polygon": {
|
|
||||||
this.mouseTool.polygon({
|
|
||||||
fillColor: "#00b0ff",
|
|
||||||
strokeColor: "#80d8ff",
|
|
||||||
borderWeight: 2,
|
|
||||||
strokeWeight: 4,
|
|
||||||
//同Polygon的Option设置
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "rectangle": {
|
|
||||||
this.mouseTool.rectangle({
|
|
||||||
fillColor: "#00b0ff",
|
|
||||||
strokeColor: "#80d8ff",
|
|
||||||
//同Polygon的Option设置
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "circle": {
|
|
||||||
this.mouseTool.circle({
|
|
||||||
fillColor: "#00b0ff",
|
|
||||||
strokeColor: "#80d8ff",
|
|
||||||
//同Circle的Option设置
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
surePotting() {
|
|
||||||
this.forms.points = [];
|
|
||||||
// this.forms.eventReportUnit = this.$refs.cascader.getCheckedNodes().label;
|
|
||||||
if (this.forms.plottingStatus == 1) {
|
|
||||||
this.polyEditor
|
|
||||||
.getTarget()
|
|
||||||
.getPath()
|
|
||||||
.map((e) => {
|
|
||||||
this.forms.points.push({lng: e.lng, lat: e.lat});
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.forms.points = [...this.path];
|
|
||||||
}
|
|
||||||
this.showMap = false;
|
|
||||||
},
|
|
||||||
save() {
|
|
||||||
this.$refs["rules"].validate((valid) => {
|
|
||||||
if (valid) {
|
|
||||||
this.instance
|
|
||||||
.post(
|
|
||||||
`/app/appgirdinfo/addOrUpdate`,
|
|
||||||
{
|
|
||||||
...this.forms,
|
|
||||||
},
|
|
||||||
null
|
|
||||||
)
|
|
||||||
.then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.cancel(true)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.log("error submit!!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
searchDetail() {
|
|
||||||
this.instance.post(`/app/appgirdinfo/queryDetailById`, null, {
|
|
||||||
params: {id: this.params.id},
|
|
||||||
}).then((res) => {
|
|
||||||
if (res?.data) {
|
|
||||||
this.forms = {...res.data};
|
|
||||||
this.parentGirdInfo = res.data.parentGirdInfo;
|
|
||||||
this.forms.parentGirdName = res.data.parentGirdInfo && res.data.parentGirdInfo.girdName;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.add-block {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
::v-deep .amap-copyright {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .amap-logo {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.above {
|
|
||||||
overflow: hidden;
|
|
||||||
padding: 8px 0;
|
|
||||||
|
|
||||||
.left {
|
|
||||||
width: 380px;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right {
|
|
||||||
width: 380px;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.footer-btn {
|
|
||||||
width: 92px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.map {
|
|
||||||
width: 780px;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.container {
|
|
||||||
width: 760px;
|
|
||||||
height: 420px;
|
|
||||||
border-radius: 2px;
|
|
||||||
border: 1px solid #d0d4dc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#panel {
|
|
||||||
position: absolute;
|
|
||||||
height: 400px;
|
|
||||||
right: 30px;
|
|
||||||
top: 20px;
|
|
||||||
width: 280px;
|
|
||||||
overflow: hidden;
|
|
||||||
z-index: 10000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tipinput {
|
|
||||||
position: absolute;
|
|
||||||
width: 200px;
|
|
||||||
height: 38px;
|
|
||||||
left: 20px;
|
|
||||||
top: 20px;
|
|
||||||
z-index: 10000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,695 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="app-grid-block">
|
|
||||||
<ai-list>
|
|
||||||
<template slot="title">
|
|
||||||
<ai-title title="网格区块" :isShowBottomBorder="true"></ai-title>
|
|
||||||
</template>
|
|
||||||
<template slot="left">
|
|
||||||
<ai-tree-menu title="网格层级" @search="(v) => $refs.tree.filter(v)">
|
|
||||||
<el-tree
|
|
||||||
:data="treeObj.treeList"
|
|
||||||
:props="treeObj.defaultProps"
|
|
||||||
@node-click="handleNodeClick"
|
|
||||||
node-key="id"
|
|
||||||
ref="tree"
|
|
||||||
:filter-node-method="filterNode"
|
|
||||||
default-expand-all
|
|
||||||
highlight-current
|
|
||||||
/>
|
|
||||||
</ai-tree-menu>
|
|
||||||
</template>
|
|
||||||
<template slot="content">
|
|
||||||
<ai-search-bar>
|
|
||||||
<template slot="left">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="searchObj.createTimeStr"
|
|
||||||
type="date"
|
|
||||||
@change="(page.current = 1), getList()"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
size="small"
|
|
||||||
placeholder="创建时间"
|
|
||||||
>
|
|
||||||
</el-date-picker>
|
|
||||||
</template>
|
|
||||||
<template slot="right">
|
|
||||||
<el-input
|
|
||||||
v-model="searchObj.girdName"
|
|
||||||
size="small"
|
|
||||||
placeholder="输入网格名称"
|
|
||||||
@keyup.enter.native="(page.current = 1), getList()"
|
|
||||||
clearable
|
|
||||||
@clear="(searchObj.girdName = '', page.current = 1), getList()"
|
|
||||||
suffix-icon="iconfont iconSearch"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</ai-search-bar>
|
|
||||||
<ai-search-bar bottomBorder>
|
|
||||||
<template slot="left">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
icon="iconfont iconAdd"
|
|
||||||
:disabled="info.girdLevel === '3'"
|
|
||||||
@click="(isEdit = false), toAdd()"
|
|
||||||
>新增
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
icon="iconfont iconDelete"
|
|
||||||
@click="deleteById(ids.join(','))"
|
|
||||||
:disabled="!Boolean(ids.length)"
|
|
||||||
>
|
|
||||||
删除
|
|
||||||
</el-button>
|
|
||||||
<ai-download
|
|
||||||
:instance="instance"
|
|
||||||
url="/app/appgirdinfo/exportGirdInfo"
|
|
||||||
:params="{ ...searchObj, ids: ids.join(',') }"
|
|
||||||
fileName="网格区块"
|
|
||||||
>
|
|
||||||
<el-button icon="iconfont iconExported" size="small"
|
|
||||||
>导出全部</el-button
|
|
||||||
>
|
|
||||||
</ai-download>
|
|
||||||
<ai-import
|
|
||||||
ref="import"
|
|
||||||
title="导入"
|
|
||||||
name="网格区块"
|
|
||||||
url="/app/appgirdinfo/downloadGirdInfo"
|
|
||||||
importUrl="/app/appgirdinfo/importGirdInfo"
|
|
||||||
suffixName="xlsx"
|
|
||||||
:customCliker="true"
|
|
||||||
:instance="instance"
|
|
||||||
>
|
|
||||||
<template slot="tips">
|
|
||||||
<p>
|
|
||||||
如果表格中已经存在数据,则会被本次导入的数据覆盖;不存在数据,系统将生成新的标准记录;
|
|
||||||
</p>
|
|
||||||
</template>
|
|
||||||
<el-button size="small" icon="iconfont iconImport"
|
|
||||||
>导入</el-button
|
|
||||||
>
|
|
||||||
</ai-import>
|
|
||||||
</template>
|
|
||||||
</ai-search-bar>
|
|
||||||
<ai-table
|
|
||||||
class="mt10"
|
|
||||||
:tableData="tableData"
|
|
||||||
:col-configs="colConfigs"
|
|
||||||
:total="page.total"
|
|
||||||
ref="aitableex"
|
|
||||||
:current.sync="page.current"
|
|
||||||
:size.sync="page.size"
|
|
||||||
@selection-change="(v) => (ids = v.map((e) => e.id))"
|
|
||||||
@getList="getList()"
|
|
||||||
>
|
|
||||||
<el-table-column
|
|
||||||
slot="selectId"
|
|
||||||
type="selection"
|
|
||||||
align="center"
|
|
||||||
width="40"
|
|
||||||
>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
label="操作"
|
|
||||||
slot="options"
|
|
||||||
align="center"
|
|
||||||
fixed="right"
|
|
||||||
width="160">
|
|
||||||
<template slot-scope="{ row }">
|
|
||||||
<div class="table-options">
|
|
||||||
<el-button type="text" @click="see(row)">编辑</el-button>
|
|
||||||
<el-button type="text" @click="poltting(row)" :disabled="row.girdLevel !== '2'">标绘</el-button>
|
|
||||||
<el-button type="text" @click="deleteById(row.id)">删除</el-button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</ai-table>
|
|
||||||
</template>
|
|
||||||
</ai-list>
|
|
||||||
<ai-dialog
|
|
||||||
title="网格范围"
|
|
||||||
:visible.sync="showMap"
|
|
||||||
:customFooter="true"
|
|
||||||
:destroyOnClose="true"
|
|
||||||
border
|
|
||||||
width="850px"
|
|
||||||
>
|
|
||||||
<div class="map">
|
|
||||||
<div class="tipinput">
|
|
||||||
<el-input
|
|
||||||
v-if="editRow.plottingStatus == 0"
|
|
||||||
v-model="searchAddress"
|
|
||||||
@change="addressChange"
|
|
||||||
clearable
|
|
||||||
placeholder="请输入关键字"
|
|
||||||
id="tipinput"
|
|
||||||
size="medium"
|
|
||||||
style="width: 200px"
|
|
||||||
></el-input>
|
|
||||||
</div>
|
|
||||||
<div id="panel" v-if="editRow.plottingStatus == 0"></div>
|
|
||||||
<div class="container" id="container"></div>
|
|
||||||
<el-button-group
|
|
||||||
style="margin-top: 8px"
|
|
||||||
v-if="editRow.plottingStatus == 1"
|
|
||||||
>
|
|
||||||
<el-button type="primary" size="mini" @click="beginPoltting()"
|
|
||||||
>开始编辑</el-button
|
|
||||||
>
|
|
||||||
<el-button size="mini" @click="finishPoltting()">结束编辑</el-button>
|
|
||||||
</el-button-group>
|
|
||||||
<el-button-group
|
|
||||||
style="margin-top: 8px"
|
|
||||||
v-if="editRow.plottingStatus == 0"
|
|
||||||
>
|
|
||||||
<el-button size="mini" @click="draw('polygon')"
|
|
||||||
>开始绘制多边形</el-button
|
|
||||||
>
|
|
||||||
<!-- <el-button size="mini" @click="close()">关闭绘制</el-button> -->
|
|
||||||
<el-button size="mini" @click="clear()">清除绘制</el-button>
|
|
||||||
</el-button-group>
|
|
||||||
</div>
|
|
||||||
<div class="dialog-footer" slot="footer">
|
|
||||||
<el-button size="medium" @click="showMap = false">取消</el-button>
|
|
||||||
<el-button type="primary" size="medium" @click="confirm()"
|
|
||||||
>确认</el-button
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</ai-dialog>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import AMapLoader from "@amap/amap-jsapi-loader";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "List",
|
|
||||||
label: "网格区块",
|
|
||||||
props: {
|
|
||||||
instance: Function,
|
|
||||||
dict: Object,
|
|
||||||
permissions: Function,
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
treeObj: {
|
|
||||||
treeList: [],
|
|
||||||
defaultProps: {
|
|
||||||
children: "girdList",
|
|
||||||
label: "girdName",
|
|
||||||
},
|
|
||||||
defaultExpandedKeys: [],
|
|
||||||
},
|
|
||||||
filterText: "",
|
|
||||||
page: {
|
|
||||||
current: 1,
|
|
||||||
size: 10,
|
|
||||||
total: 0,
|
|
||||||
},
|
|
||||||
searchObj: {
|
|
||||||
createTimeStr: "",
|
|
||||||
girdName: "",
|
|
||||||
},
|
|
||||||
tableData: [],
|
|
||||||
info: {},
|
|
||||||
ids: [],
|
|
||||||
showMap: false,
|
|
||||||
map: "",
|
|
||||||
polyEditor: "",
|
|
||||||
editRow: {},
|
|
||||||
searchAddress: "",
|
|
||||||
mouseTool: "",
|
|
||||||
placeSearch: "",
|
|
||||||
path: [],
|
|
||||||
overlays: [],
|
|
||||||
isEdit: false,
|
|
||||||
searchId: "",
|
|
||||||
fileList: [],
|
|
||||||
location: {}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getTreeList();
|
|
||||||
this.getList();
|
|
||||||
this.getCorpLocation()
|
|
||||||
this.dict.load("girdLevel", "girdType", "isLastLevel", "plottingStatus");
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
colConfigs() {
|
|
||||||
let _ = this;
|
|
||||||
return [
|
|
||||||
{ type: 'selection'},
|
|
||||||
{
|
|
||||||
prop: "girdName",
|
|
||||||
align: "left",
|
|
||||||
label: "网格名称",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: "girdCode",
|
|
||||||
align: "center",
|
|
||||||
label: "网格编码",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: "girdType",
|
|
||||||
align: "center",
|
|
||||||
label: "网格类型",
|
|
||||||
render(h, { row }) {
|
|
||||||
return h("span", {}, _.dict.getLabel("girdType", row.girdType) || '-');
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: "girdLevel",
|
|
||||||
align: "center",
|
|
||||||
label: "网格层级",
|
|
||||||
render(h, { row }) {
|
|
||||||
return h("span", {}, _.dict.getLabel("girdLevel", row.girdLevel) || '-');
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: "plottingStatus",
|
|
||||||
align: "center",
|
|
||||||
label: "标绘状态",
|
|
||||||
render(h, { row }) {
|
|
||||||
return h(
|
|
||||||
"span",
|
|
||||||
{
|
|
||||||
style: {
|
|
||||||
color: _.dict.getColor("plottingStatus", row.plottingStatus),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
_.dict.getLabel("plottingStatus", row.plottingStatus)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: "createTime",
|
|
||||||
align: "center",
|
|
||||||
label: "创建时间",
|
|
||||||
render(h, { row }) {
|
|
||||||
return h("span", {}, row.createTime.substring(0, 11));
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: "girdMemberNames",
|
|
||||||
align: "center",
|
|
||||||
width: 200,
|
|
||||||
label: "网格员",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getCorpLocation(){
|
|
||||||
this.instance.post("/app/appdvcpconfig/getCorpLocation").then(res=>{
|
|
||||||
if(res.code==0){
|
|
||||||
this.location = res.data
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
handleNodeClick(val) {
|
|
||||||
this.info = { ...val };
|
|
||||||
this.searchId = val.id;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
getTreeList() {
|
|
||||||
this.instance
|
|
||||||
.post("/app/appgirdinfo/listByTop", null, null)
|
|
||||||
.then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.treeObj.treeList = [...res.data];
|
|
||||||
this.info = { ...this.treeObj.treeList[0] };
|
|
||||||
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.treeObj.treeList.length && this.$refs.tree.setCurrentKey(this.treeObj.treeList[0].id)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
filterNode(value, data) {
|
|
||||||
if (!value) return true;
|
|
||||||
return data.girdName.indexOf(value) !== -1;
|
|
||||||
},
|
|
||||||
deleteById(ids) {
|
|
||||||
ids &&
|
|
||||||
this.$confirm("是否要删除该网格区块?", {
|
|
||||||
type: "error",
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
this.instance
|
|
||||||
.post("/app/appgirdinfo/delete", null, {
|
|
||||||
params: { ids },
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
if (res?.code == 0) {
|
|
||||||
this.$message.success("删除成功!");
|
|
||||||
|
|
||||||
this.getList();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {});
|
|
||||||
},
|
|
||||||
deleteTree(ids) {
|
|
||||||
ids &&
|
|
||||||
this.$confirm("是否要删除该网格区块?", {
|
|
||||||
type: "error",
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
this.instance
|
|
||||||
.post("/app/appgirdinfo/delete", null, {
|
|
||||||
params: { ids },
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
if (res?.code == 0) {
|
|
||||||
this.$message.success("删除成功!");
|
|
||||||
|
|
||||||
this.getTreeList();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {});
|
|
||||||
},
|
|
||||||
getList() {
|
|
||||||
this.instance
|
|
||||||
.post("/app/appgirdinfo/list", null, {
|
|
||||||
params: {
|
|
||||||
...this.searchObj,
|
|
||||||
...this.page,
|
|
||||||
parentGirdId: this.info.girdLevel === '0' ? '' : this.searchId,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
if (res?.data) {
|
|
||||||
this.tableData = res.data.records;
|
|
||||||
this.page.total = res.data.total;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
handleSelectionChange(val) {
|
|
||||||
this.ids = [];
|
|
||||||
val.map((e) => {
|
|
||||||
this.ids.push(e.id);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
//添加二级网格
|
|
||||||
addTwoLevel() {
|
|
||||||
this.info = { ...this.treeObj.treeList[0] };
|
|
||||||
this.toAdd()
|
|
||||||
},
|
|
||||||
toAdd() {
|
|
||||||
this.$emit('change', {
|
|
||||||
type: 'Add',
|
|
||||||
params: this.info,
|
|
||||||
isEdit: this.isEdit
|
|
||||||
})
|
|
||||||
},
|
|
||||||
goBack() {
|
|
||||||
this.isAdd = false;
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.getList();
|
|
||||||
this.getTreeList();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
poltting(row) {
|
|
||||||
this.showMap = true;
|
|
||||||
this.editRow = { ...row };
|
|
||||||
AMapLoader.load({
|
|
||||||
key: "b553334ba34f7ac3cd09df9bc8b539dc", // 申请好的Web端开发者Key,首次调用 load 时必填
|
|
||||||
version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
|
|
||||||
plugins: ["AMap.PolygonEditor", "AMap.MouseTool", "AMap.PlaceSearch"], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
|
|
||||||
AMapUI: {
|
|
||||||
// 是否加载 AMapUI,缺省不加载
|
|
||||||
version: "1.1", // AMapUI 缺省 1.1
|
|
||||||
plugins: [], // 需要加载的 AMapUI ui插件
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((AMap) => {
|
|
||||||
this.map = new AMap.Map("container", {
|
|
||||||
resizeEnable: true,
|
|
||||||
zoom: 14,
|
|
||||||
});
|
|
||||||
if (this.editRow.plottingStatus == 1) {
|
|
||||||
let path = [];
|
|
||||||
this.editRow.points.map((e, index) => {
|
|
||||||
path[index] = [e.lng, e.lat];
|
|
||||||
});
|
|
||||||
let polygon = new AMap.Polygon({
|
|
||||||
path: path,
|
|
||||||
strokeColor: "#FF33FF",
|
|
||||||
strokeWeight: 6,
|
|
||||||
strokeOpacity: 0.2,
|
|
||||||
fillOpacity: 0.4,
|
|
||||||
fillColor: "#1791fc",
|
|
||||||
zIndex: 50,
|
|
||||||
bubble: true,
|
|
||||||
});
|
|
||||||
this.map.add([polygon]);
|
|
||||||
this.map.setFitView();
|
|
||||||
this.polyEditor = new AMap.PolygonEditor(this.map, polygon);
|
|
||||||
} else {
|
|
||||||
this.mouseTool = new AMap.MouseTool(this.map);
|
|
||||||
this.placeSearch = new AMap.PlaceSearch({
|
|
||||||
pageSize: 3, // 单页显示结果条数
|
|
||||||
pageIndex: 1, // 页码
|
|
||||||
city: "", // 兴趣点城市
|
|
||||||
citylimit: false, //是否强制限制在设置的城市内搜索
|
|
||||||
map: this.map, // 展现结果的地图实例
|
|
||||||
panel: "panel", // 结果列表将在此容器中进行展示。
|
|
||||||
autoFitView: true, // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
|
|
||||||
});
|
|
||||||
this.map.setZoomAndCenter(14, [this.location.lng, this.location.lat], false, 600);
|
|
||||||
this.eventOn();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((e) => {
|
|
||||||
console.log(e);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
see(row) {
|
|
||||||
this.info = { ...row };
|
|
||||||
this.isEdit = true;
|
|
||||||
this.toAdd()
|
|
||||||
},
|
|
||||||
draw(type) {
|
|
||||||
switch (type) {
|
|
||||||
case "marker": {
|
|
||||||
this.mouseTool.marker({
|
|
||||||
//同Marker的Option设置
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "polyline": {
|
|
||||||
this.mouseTool.polyline({
|
|
||||||
strokeColor: "#80d8ff",
|
|
||||||
//同Polyline的Option设置
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "polygon": {
|
|
||||||
this.mouseTool.polygon({
|
|
||||||
fillColor: "#00b0ff",
|
|
||||||
strokeColor: "#80d8ff",
|
|
||||||
borderWeight: 2,
|
|
||||||
strokeWeight: 4,
|
|
||||||
//同Polygon的Option设置
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "rectangle": {
|
|
||||||
this.mouseTool.rectangle({
|
|
||||||
fillColor: "#00b0ff",
|
|
||||||
strokeColor: "#80d8ff",
|
|
||||||
//同Polygon的Option设置
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case "circle": {
|
|
||||||
this.mouseTool.circle({
|
|
||||||
fillColor: "#00b0ff",
|
|
||||||
strokeColor: "#80d8ff",
|
|
||||||
//同Circle的Option设置
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//map搜索
|
|
||||||
addressChange(val) {
|
|
||||||
this.placeSearch.search(val);
|
|
||||||
},
|
|
||||||
close() {
|
|
||||||
this.mouseTool.close(true);
|
|
||||||
},
|
|
||||||
clear() {
|
|
||||||
this.map.remove(this.overlays);
|
|
||||||
this.overlays = [];
|
|
||||||
this.path = [];
|
|
||||||
},
|
|
||||||
beginPoltting() {
|
|
||||||
this.polyEditor.open();
|
|
||||||
},
|
|
||||||
finishPoltting() {
|
|
||||||
this.polyEditor.close();
|
|
||||||
},
|
|
||||||
confirm() {
|
|
||||||
let path = [];
|
|
||||||
if (this.editRow.plottingStatus == 1) {
|
|
||||||
this.polyEditor
|
|
||||||
.getTarget()
|
|
||||||
.getPath()
|
|
||||||
.map((e) => {
|
|
||||||
path.push({ lng: e.lng, lat: e.lat });
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
path = [...this.path];
|
|
||||||
}
|
|
||||||
delete this.editRow.points;
|
|
||||||
this.instance
|
|
||||||
.post(
|
|
||||||
`/app/appgirdinfo/addOrUpdate`,
|
|
||||||
{
|
|
||||||
...this.editRow,
|
|
||||||
points: path,
|
|
||||||
},
|
|
||||||
null
|
|
||||||
)
|
|
||||||
.then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.getList();
|
|
||||||
this.showMap = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
eventOn() {
|
|
||||||
this.path = [];
|
|
||||||
this.overlays = [];
|
|
||||||
this.map.on("mousemove", this.showInfoMove, this);
|
|
||||||
this.mouseTool.on("draw", ({ type, obj }) => {
|
|
||||||
obj.getPath().map((e) => {
|
|
||||||
this.path.push({ lat: e.getLat(), lng: e.getLng() });
|
|
||||||
});
|
|
||||||
this.overlays.push(obj);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
resetSearch() {
|
|
||||||
Object.keys(this.searchObj).map((e) => {
|
|
||||||
this.searchObj[e] = "";
|
|
||||||
});
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.app-grid-block {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
::v-deep .el-tree {
|
|
||||||
background: transparent;
|
|
||||||
|
|
||||||
.el-tree-node__expand-icon.is-leaf {
|
|
||||||
color: transparent!important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-tree-node__content > .el-tree-node__expand-icon {
|
|
||||||
padding: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-tree-node__content {
|
|
||||||
height: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-tree__empty-text {
|
|
||||||
color: #222;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-tree-node__children .el-tree-node__content {
|
|
||||||
height: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-tree-node__content:hover {
|
|
||||||
background: #E8EFFF;
|
|
||||||
color: #222222;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.is-current > .el-tree-node__content {
|
|
||||||
&:hover {
|
|
||||||
background: #2266FF;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
background: #2266FF;
|
|
||||||
|
|
||||||
span {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mt10 {
|
|
||||||
padding: 8px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.map {
|
|
||||||
width: 780px;
|
|
||||||
position: relative;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.container {
|
|
||||||
width: 760px;
|
|
||||||
height: 420px;
|
|
||||||
border-radius: 2px;
|
|
||||||
border: 1px solid #d0d4dc;
|
|
||||||
}
|
|
||||||
|
|
||||||
#panel {
|
|
||||||
position: absolute;
|
|
||||||
height: 400px;
|
|
||||||
right: 30px;
|
|
||||||
top: 20px;
|
|
||||||
width: 280px;
|
|
||||||
overflow: hidden;
|
|
||||||
z-index: 10000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tipinput {
|
|
||||||
position: absolute;
|
|
||||||
width: 200px;
|
|
||||||
height: 38px;
|
|
||||||
left: 20px;
|
|
||||||
top: 20px;
|
|
||||||
z-index: 10000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .treePanel {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
.el-tree {
|
|
||||||
min-height: 0;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
|
||||||
width: 100%;
|
|
||||||
height: 32px;
|
|
||||||
background-color: #fff;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
span {
|
|
||||||
width: 33.33%;
|
|
||||||
text-align: center;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-button {
|
|
||||||
width: 33.33%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import component from './AppGridBlock.vue'
|
|
||||||
|
|
||||||
component.install = function (Vue) {
|
|
||||||
Vue.component(component.name, component)
|
|
||||||
}
|
|
||||||
export default component
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="AppGridMap">
|
|
||||||
<keep-alive :include="['List']">
|
|
||||||
<component
|
|
||||||
ref="component"
|
|
||||||
:is="component"
|
|
||||||
@change="onChange"
|
|
||||||
:params="params"
|
|
||||||
:instance="instance"
|
|
||||||
:dict="dict"
|
|
||||||
></component>
|
|
||||||
</keep-alive>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import List from "./components/list";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "AppGridMap",
|
|
||||||
label: "网格地图",
|
|
||||||
|
|
||||||
props: {
|
|
||||||
instance: Function,
|
|
||||||
dict: Object,
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
component: "List",
|
|
||||||
params: {},
|
|
||||||
include: [],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
|
||||||
List,
|
|
||||||
},
|
|
||||||
|
|
||||||
mounted() {},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
onChange(data) {
|
|
||||||
if (data.type === "Add") {
|
|
||||||
this.component = "Add";
|
|
||||||
this.params = data.params;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.type === "list") {
|
|
||||||
this.component = "List";
|
|
||||||
this.params = data.params;
|
|
||||||
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if (data.isRefresh) {
|
|
||||||
this.$refs.component.getList();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.AppGridMap {
|
|
||||||
height: 100%;
|
|
||||||
background: #f3f6f9;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,669 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="gridMap">
|
|
||||||
<ai-t-map :map.sync="map" ref="AiTMap" :lib.sync="mapLib" @loaded="onMapInit" :libraries="['geometry','service', 'tools']"/>
|
|
||||||
<div class="drawer" ref="drawer">
|
|
||||||
<div v-if="show" class="drawer-content">
|
|
||||||
<b>网格地图</b>
|
|
||||||
<div class="tree">
|
|
||||||
<div class="input">
|
|
||||||
<el-input placeholder="请输入网格名称" v-model="filterText" size="mini" suffix-icon="el-icon-search"/>
|
|
||||||
</div>
|
|
||||||
<header class="header">
|
|
||||||
<span>网格列表</span>
|
|
||||||
</header>
|
|
||||||
<div class="tree-div">
|
|
||||||
<el-tree
|
|
||||||
:data="treeObj.treeList"
|
|
||||||
:props="treeObj.defaultProps"
|
|
||||||
@node-click="handleNodeClick"
|
|
||||||
node-key="id"
|
|
||||||
ref="tree"
|
|
||||||
:expand-on-click-node="false"
|
|
||||||
:filter-node-method="filterNode"
|
|
||||||
default-expand-all
|
|
||||||
highlight-current>
|
|
||||||
</el-tree>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="rightBtn" :class="{show}" @click="show=!show">
|
|
||||||
<i class="iconfont iconArrow_Right"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
import {mapState} from 'vuex'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'AppGridMap',
|
|
||||||
label: "网格地图",
|
|
||||||
props: {
|
|
||||||
instance: Function,
|
|
||||||
dict: Object,
|
|
||||||
permissions: Function,
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
map: null,
|
|
||||||
mapLib: null,
|
|
||||||
show: true,
|
|
||||||
retryMapCount: 0,
|
|
||||||
polygons: [],
|
|
||||||
|
|
||||||
drawer: false,
|
|
||||||
filterText: "",
|
|
||||||
treeObj: {
|
|
||||||
treeList: [],
|
|
||||||
defaultProps: {
|
|
||||||
children: "girdList",
|
|
||||||
label: "girdName",
|
|
||||||
},
|
|
||||||
defaultExpandedKeys: [],
|
|
||||||
},
|
|
||||||
ops: {},
|
|
||||||
|
|
||||||
path: [],
|
|
||||||
searchObj: {
|
|
||||||
onlineStatus: "",
|
|
||||||
girdMemberName: "",
|
|
||||||
},
|
|
||||||
member: {
|
|
||||||
memberList: [],
|
|
||||||
},
|
|
||||||
currInfo: {},
|
|
||||||
infoWindowHtml: "",
|
|
||||||
marker: {},
|
|
||||||
activeId: null,
|
|
||||||
labels: []
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapState(['user']),
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.dict.load("onlineStatus")
|
|
||||||
this.getTreeList().then(() => {
|
|
||||||
this.getLeafNodes()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
filterText(val) {
|
|
||||||
this.$refs.tree.filter(val);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
filterNode(value, data) {
|
|
||||||
if (!value) return true;
|
|
||||||
return data.girdName.indexOf(value) !== -1;
|
|
||||||
},
|
|
||||||
getTreeList() {
|
|
||||||
return this.instance.post(`/app/appgirdinfo/listAll`).then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.treeObj.treeList = res.data;
|
|
||||||
|
|
||||||
this.$nextTick(() => {
|
|
||||||
res.data.length && this.$refs.tree.setCurrentKey(res.data[0].id)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
onMapInit () {
|
|
||||||
this.instance.post("/app/appdvcpconfig/getCorpLocation").then(res=>{
|
|
||||||
if (res.code === 0) {
|
|
||||||
this.map.setCenter(new this.mapLib.LatLng(res.data.lat, res.data.lng))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
getLeafNodes() {
|
|
||||||
this.instance.post(`/app/appgirdinfo/listAll2`).then((res) => {
|
|
||||||
if (res?.data) {
|
|
||||||
const arr = res.data.map(v => {
|
|
||||||
return {
|
|
||||||
id: v.id,
|
|
||||||
girdName: v.girdName,
|
|
||||||
points: v.points ? v.points.map(p => [p.lng, p.lat]) : []
|
|
||||||
}
|
|
||||||
}).filter(v => v.points.length)
|
|
||||||
|
|
||||||
this.renderGridMap(arr)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
handleNodeClick (val) {
|
|
||||||
if (val.girdLevel === '0') {
|
|
||||||
this.getLeafNodes()
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
this.instance.post(`/app/appgirdinfo/queryChildGirdInfoByGirdId?girdId=${val.id}`).then((res) => {
|
|
||||||
if (res?.data) {
|
|
||||||
const arr = res.data.map(v => {
|
|
||||||
return {
|
|
||||||
id: v.id,
|
|
||||||
girdName: v.girdName,
|
|
||||||
points: v.points ? v.points.map(p => [p.lng, p.lat]) : []
|
|
||||||
}
|
|
||||||
}).filter(v => v.points.length)
|
|
||||||
|
|
||||||
if (!arr.length) {
|
|
||||||
return this.$message.error('该网格还未标绘')
|
|
||||||
}
|
|
||||||
|
|
||||||
this.renderGridMap(arr)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
fitBounds(latLngList, count = 0) {
|
|
||||||
let {mapLib: TMap} = this
|
|
||||||
if (TMap) {
|
|
||||||
if (latLngList.length === 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
let boundsN = latLngList[0].getLat();
|
|
||||||
let boundsS = boundsN;
|
|
||||||
let boundsW = latLngList[0].getLng();
|
|
||||||
let boundsE = boundsW;
|
|
||||||
latLngList.forEach((point) => {
|
|
||||||
point.getLat() > boundsN && (boundsN = point.getLat());
|
|
||||||
point.getLat() < boundsS && (boundsS = point.getLat());
|
|
||||||
point.getLng() > boundsE && (boundsE = point.getLng());
|
|
||||||
point.getLng() < boundsW && (boundsW = point.getLng());
|
|
||||||
});
|
|
||||||
return new TMap.LatLngBounds(
|
|
||||||
new TMap.LatLng(boundsS, boundsW),
|
|
||||||
new TMap.LatLng(boundsN, boundsE)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
if (count < 5) {
|
|
||||||
this.fitBounds(latLngList, ++count)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
renderGridMap(paths) {
|
|
||||||
let {map, mapLib: TMap } = this
|
|
||||||
if (TMap) {
|
|
||||||
if (this.polygons.length > 0) {
|
|
||||||
this.polygons.forEach(e => e.destroy())
|
|
||||||
this.labels.forEach(e => {
|
|
||||||
e.destroy(e.id)
|
|
||||||
})
|
|
||||||
this.polygons = []
|
|
||||||
this.labels = []
|
|
||||||
}
|
|
||||||
if (paths?.length > 0) {
|
|
||||||
let bounds = []
|
|
||||||
paths.forEach((path, i) => {
|
|
||||||
let polygon = new TMap.MultiPolygon({
|
|
||||||
map, styles: {
|
|
||||||
default: new TMap.PolygonStyle({
|
|
||||||
showBorder: true,
|
|
||||||
borderColor: '#5088FF',
|
|
||||||
borderWidth: 2,
|
|
||||||
color: this.$colorUtils.Hex2RGBA('#5088FF', 0.1)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
id: path.id,
|
|
||||||
geometries: [{paths: path.points.map(e => new TMap.LatLng(e[1], e[0]))}]
|
|
||||||
})
|
|
||||||
this.polygons.push(polygon)
|
|
||||||
bounds.push(this.fitBounds(path.points.map(e => new TMap.LatLng(e[1], e[0]))))
|
|
||||||
|
|
||||||
polygon.on('click', e => {
|
|
||||||
// const id = e.target.id
|
|
||||||
// this.getGridInfo(id)
|
|
||||||
})
|
|
||||||
|
|
||||||
const points = path.points.map(e => new TMap.LatLng(e[1], e[0]))
|
|
||||||
|
|
||||||
var position = TMap.geometry.computeCentroid(points)
|
|
||||||
|
|
||||||
let label = new TMap.MultiLabel({
|
|
||||||
id: `label~${path.id}`,
|
|
||||||
data: path.id,
|
|
||||||
map: map,
|
|
||||||
styles: {
|
|
||||||
building: new TMap.LabelStyle({
|
|
||||||
color: '#3777FF',
|
|
||||||
size: 20,
|
|
||||||
alignment: 'center',
|
|
||||||
verticalAlignment: 'middle'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
geometries: [
|
|
||||||
{
|
|
||||||
id: `label-class-${i}`,
|
|
||||||
styleId: 'building',
|
|
||||||
position: position,
|
|
||||||
content: path.girdName,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
this.labels.push(label)
|
|
||||||
label.on('click', e => {
|
|
||||||
// this.getGridInfo(e.target.id.split('~')[1])
|
|
||||||
});
|
|
||||||
})
|
|
||||||
bounds = bounds.reduce((a, b) => {
|
|
||||||
return this.fitBounds([
|
|
||||||
a.getNorthEast(),
|
|
||||||
a.getSouthWest(),
|
|
||||||
b.getNorthEast(),
|
|
||||||
b.getSouthWest(),
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
map.fitBounds(bounds, {padding: 100})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
hasClass(ele, cls) {
|
|
||||||
return ele.className.match(new RegExp("(\\s|^)" + cls + "(\\s|$)"));
|
|
||||||
},
|
|
||||||
addClass(ele, cls) {
|
|
||||||
if (!this.hasClass(ele, cls)) ele.className += " " + cls;
|
|
||||||
},
|
|
||||||
removeClass(ele, cls) {
|
|
||||||
if (this.hasClass(ele, cls)) {
|
|
||||||
const reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
|
|
||||||
ele.className = ele.className.replace(reg, " ");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
changClass(ele, className) {
|
|
||||||
if (!this.hasClass(ele, className)) {
|
|
||||||
this.addClass(ele, className);
|
|
||||||
} else {
|
|
||||||
this.removeClass(ele, className);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
percentage() {
|
|
||||||
if (this.member.onlineNumber == 0) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
100 *
|
|
||||||
(this.member.onlineNumber / this.member.allMemberNumber)
|
|
||||||
).toFixed(2);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getMemberList() {
|
|
||||||
this.instance.post(`/app/appgirdmemberinfo/queryGirdMemberByMap`, this.searchObj).then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
let markers = [];
|
|
||||||
this.member = res.data;
|
|
||||||
this.member.memberList.map((e) => {
|
|
||||||
if (e.onlineStatus == "1") {
|
|
||||||
markers.push({lng: e.lng, lat: e.lat, name: e.name});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.initMap(null, null, markers);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
clickMember(marker) {
|
|
||||||
if (marker.onlineStatus == 1) {
|
|
||||||
this.activeId = marker.id;
|
|
||||||
this.marker = marker;
|
|
||||||
this.infoWindowContent(marker);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
infoWindowContent(marker) {
|
|
||||||
this.instance
|
|
||||||
.post(`/app/location/xyToAddress`, null, {
|
|
||||||
params: {
|
|
||||||
x: marker.lat,
|
|
||||||
y: marker.lng,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.infoWindowHtml = `<div class="info">
|
|
||||||
<p>
|
|
||||||
<span class="name">${marker.name}</span>
|
|
||||||
<span class="lat">${marker.lng},${marker.lat}</span>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<span class="lat">${res.data}</span>
|
|
||||||
</p>
|
|
||||||
<p class="address">
|
|
||||||
<span class="iconfont iconarea" id="addressSpan">当日轨迹</span>
|
|
||||||
</p>
|
|
||||||
</div>`;
|
|
||||||
this.initMap(false, marker);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
queryTrajectory() {
|
|
||||||
this.instance
|
|
||||||
.post(`/app/appgirdmembertrajectory/queryTrajectory`, null, {
|
|
||||||
params: {
|
|
||||||
userId: this.marker.userId,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
let path = [];
|
|
||||||
if (res.data) {
|
|
||||||
res.data.map((e, index) => {
|
|
||||||
path[index] = [e.lng, e.lat];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.initMap(path, this.marker);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.gridMap {
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.drawer-btn {
|
|
||||||
position: absolute;
|
|
||||||
left: 280px;
|
|
||||||
bottom: 0;
|
|
||||||
top: 0;
|
|
||||||
margin: auto;
|
|
||||||
width: 20px;
|
|
||||||
height: 24px;
|
|
||||||
border-top: 40px solid transparent;
|
|
||||||
border-bottom: 40px solid transparent;
|
|
||||||
border-left: 16px solid #333c53;
|
|
||||||
border-right: 0 solid transparent;
|
|
||||||
transition: all 0.5s ease-in-out;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
position: absolute;
|
|
||||||
font-size: 26px;
|
|
||||||
color: rgb(255, 255, 255);
|
|
||||||
left: -21px;
|
|
||||||
top: -14px;
|
|
||||||
transition: all 0.5s ease-in-out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-hide {
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.drawer {
|
|
||||||
width: 280px;
|
|
||||||
height: 100%;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1000;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
visibility: visible;
|
|
||||||
opacity: 1;
|
|
||||||
transition: all 0.5s ease-in-out;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.drawer-content {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
padding: 0 16px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
background: #333c53;
|
|
||||||
|
|
||||||
& > b {
|
|
||||||
color: #fff;
|
|
||||||
font-size: 18px;
|
|
||||||
line-height: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tree {
|
|
||||||
height: calc(100% - 28px - 76px);
|
|
||||||
border-radius: 4px;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
.map-search {
|
|
||||||
display: flex;
|
|
||||||
padding: 8px 0;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
::v-deep .el-input__inner {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.member-list {
|
|
||||||
width: 100%;
|
|
||||||
height: calc(100% - 44px - 28px);
|
|
||||||
overflow: auto;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
li {
|
|
||||||
width: 100%;
|
|
||||||
height: 32px;
|
|
||||||
display: flex;
|
|
||||||
padding: 0 8px;
|
|
||||||
align-items: center;
|
|
||||||
color: #fff;
|
|
||||||
margin: 0;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
span {
|
|
||||||
padding-right: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.active {
|
|
||||||
background: #1d2336;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
|
||||||
/*滚动条整体样式*/
|
|
||||||
width: 10px; /*高宽分别对应横竖滚动条的尺寸*/
|
|
||||||
height: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-thumb {
|
|
||||||
/*滚动条里面小方块*/
|
|
||||||
border-radius: 10px;
|
|
||||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
|
||||||
background: #1a1e2c;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-track {
|
|
||||||
/*滚动条里面轨道*/
|
|
||||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
|
||||||
border-radius: 10px;
|
|
||||||
background: #282f45;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.empty {
|
|
||||||
padding: 20px 0;
|
|
||||||
color: #7a88bb;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
width: 100%;
|
|
||||||
height: 28px;
|
|
||||||
padding: 0 16px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
color: #fff;
|
|
||||||
justify-content: space-between;
|
|
||||||
font-size: 14px;
|
|
||||||
background: #3e4a69;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input {
|
|
||||||
width: 100%;
|
|
||||||
padding: 8px 0;
|
|
||||||
|
|
||||||
::v-deep .el-input__inner {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-input__inner {
|
|
||||||
background-color: #282f45;
|
|
||||||
border: 1px solid #282f45;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tree-div {
|
|
||||||
width: 100%;
|
|
||||||
height: calc(100% - 44px - 28px);
|
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
|
||||||
/*滚动条整体样式*/
|
|
||||||
width: 10px; /*高宽分别对应横竖滚动条的尺寸*/
|
|
||||||
height: 1px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-thumb {
|
|
||||||
/*滚动条里面小方块*/
|
|
||||||
border-radius: 10px;
|
|
||||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
|
||||||
background: #1a1e2c;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-track {
|
|
||||||
/*滚动条里面轨道*/
|
|
||||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
|
|
||||||
border-radius: 10px;
|
|
||||||
background: #282f45;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
|
||||||
width: 100%;
|
|
||||||
height: 32px;
|
|
||||||
background-color: #fff;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
span {
|
|
||||||
width: 33.33%;
|
|
||||||
text-align: center;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-tree {
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.el-tree__empty-block {
|
|
||||||
background: #333c53;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-tree-node__label {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-tree-node__content {
|
|
||||||
background: #333c53;
|
|
||||||
}
|
|
||||||
|
|
||||||
.is-current > .el-tree-node__content {
|
|
||||||
.el-tree-node__label {
|
|
||||||
color: #5088ff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.hide {
|
|
||||||
left: -280px;
|
|
||||||
opacity: 0;
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
position: absolute;
|
|
||||||
top: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rightBtn {
|
|
||||||
width: 16px;
|
|
||||||
height: 80px;
|
|
||||||
background: url("https://cdn.cunwuyun.cn/monitor/drawerBtn.png");
|
|
||||||
color: #fff;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
transition: transform 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
&.show > .iconfont {
|
|
||||||
transform: rotate(180deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<style lang="scss">
|
|
||||||
.map {
|
|
||||||
.info {
|
|
||||||
width: 280px;
|
|
||||||
height: 98px;
|
|
||||||
background: #fff;
|
|
||||||
padding: 8px 0 0 12px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
line-height: 20px;
|
|
||||||
|
|
||||||
.name {
|
|
||||||
color: #333;
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lat {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.address {
|
|
||||||
color: #999;
|
|
||||||
line-height: 40px;
|
|
||||||
font-size: 12px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.title_info {
|
|
||||||
width: 68px;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: bold;
|
|
||||||
height: 20px;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 20px;
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.amap-marker-label {
|
|
||||||
border: 1px solid rgb(141, 139, 139);
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="AppGridMember">
|
|
||||||
<keep-alive :include="['List']">
|
|
||||||
<component
|
|
||||||
ref="component"
|
|
||||||
:is="component"
|
|
||||||
@change="onChange"
|
|
||||||
:params="params"
|
|
||||||
:instance="instance"
|
|
||||||
:dict="dict"
|
|
||||||
></component>
|
|
||||||
</keep-alive>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import List from "./components/list";
|
|
||||||
import Add from "./components/add";
|
|
||||||
import Family from "./components/Family";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "AppGridMember",
|
|
||||||
label: "网格管理员",
|
|
||||||
|
|
||||||
props: {
|
|
||||||
instance: Function,
|
|
||||||
dict: Object,
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
component: "List",
|
|
||||||
params: {},
|
|
||||||
include: [],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
|
||||||
Add,
|
|
||||||
List,
|
|
||||||
Family
|
|
||||||
},
|
|
||||||
|
|
||||||
mounted() {},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
onChange(data) {
|
|
||||||
if (data.type === "Add") {
|
|
||||||
this.component = "Add";
|
|
||||||
this.params = data.params;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.type === "Family") {
|
|
||||||
this.component = "Family"
|
|
||||||
this.params = data.params
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.type === "list") {
|
|
||||||
this.component = "List";
|
|
||||||
this.params = data.params;
|
|
||||||
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if (data.isRefresh) {
|
|
||||||
this.$refs.component.getList();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.AppGridMember {
|
|
||||||
height: 100%;
|
|
||||||
background: #f3f6f9;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,499 +0,0 @@
|
|||||||
<template>
|
|
||||||
<ai-list class="Family">
|
|
||||||
<template slot="title">
|
|
||||||
<ai-title title="责任家庭" isShowBack isShowBottomBorder @onBackClick="onBack"></ai-title>
|
|
||||||
</template>
|
|
||||||
<template slot="content">
|
|
||||||
<ai-search-bar class="search-bar">
|
|
||||||
<template #left>
|
|
||||||
<el-button size="small" type="primary" icon="iconfont iconAdd" @click="isShow = true">添加</el-button>
|
|
||||||
<el-button size="small" :disabled="!ids.length" icon="iconfont iconDelete" @click="removeAll">批量删除</el-button>
|
|
||||||
<el-select size="small" style="width: 200px;" v-model="search.girdId" placeholder="所属网格" clearable @change="getListInit()">
|
|
||||||
<el-option
|
|
||||||
v-for="(item,i) in girdList"
|
|
||||||
:key="i"
|
|
||||||
:label="item.girdName"
|
|
||||||
:value="item.id"
|
|
||||||
>
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
</template>
|
|
||||||
<template #right>
|
|
||||||
<el-input
|
|
||||||
v-model="search.name"
|
|
||||||
class="search-input"
|
|
||||||
size="small"
|
|
||||||
@keyup.enter.native="search.current = 1, getList()"
|
|
||||||
placeholder="姓名/身份证/联系方式"
|
|
||||||
clearable
|
|
||||||
@clear="search.current = 1, search.name = '', getList()"
|
|
||||||
suffix-icon="iconfont iconSearch">
|
|
||||||
</el-input>
|
|
||||||
</template>
|
|
||||||
</ai-search-bar>
|
|
||||||
<ai-table
|
|
||||||
:tableData="tableData"
|
|
||||||
:col-configs="colConfigs"
|
|
||||||
:total="total"
|
|
||||||
style="margin-top: 6px;"
|
|
||||||
:current.sync="search.current"
|
|
||||||
:size.sync="search.size"
|
|
||||||
@handleSelectionChange="handleSelectionChange"
|
|
||||||
@getList="getList">
|
|
||||||
<el-table-column slot="options" width="100px" fixed="right" label="操作" align="center">
|
|
||||||
<template slot-scope="{ row }">
|
|
||||||
<div class="table-options">
|
|
||||||
<el-button type="text" @click="remove(row.gmrId)">删除</el-button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</ai-table>
|
|
||||||
<ai-dialog
|
|
||||||
:visible.sync="isShow"
|
|
||||||
width="890px"
|
|
||||||
@close="closeDialog"
|
|
||||||
title="添加户主"
|
|
||||||
@onConfirm="onConfirm">
|
|
||||||
<ai-area-select clearable always-show :instance="instance" v-model="areaId" :disabled-level="disabledLevel" @change="search.current = 1, getUserList()"></ai-area-select>
|
|
||||||
<span style="margin-top:16px;"><span style="color:#f46;margin-right:4px;">*</span>网格:</span>
|
|
||||||
<el-select size="small" style="width: 280px;margin-top:16px;" v-model="girdId" placeholder="请选择网格" clearable>
|
|
||||||
<el-option
|
|
||||||
v-for="(item,i) in girdList"
|
|
||||||
:key="i"
|
|
||||||
:label="item.girdName"
|
|
||||||
:value="item.id"
|
|
||||||
>
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
<div class="AiWechatSelecter-container">
|
|
||||||
<div class="AiWechatSelecter-container__left" v-loading="isLoading">
|
|
||||||
<div class="AiWechatSelecter-header">
|
|
||||||
<div class="AiWechatSelecter-header__left">
|
|
||||||
<h2>户主信息列表</h2>
|
|
||||||
</div>
|
|
||||||
<el-input
|
|
||||||
class="search-input"
|
|
||||||
size="mini"
|
|
||||||
placeholder="请输入姓名/身份证号"
|
|
||||||
v-model="name"
|
|
||||||
clearable
|
|
||||||
@keyup.enter.native="getUserList()"
|
|
||||||
@clear="name = '', getUserList()"
|
|
||||||
suffix-icon="iconfont iconSearch">
|
|
||||||
</el-input>
|
|
||||||
</div>
|
|
||||||
<el-scrollbar class="AiWechatSelecter-list">
|
|
||||||
<el-checkbox-group v-model="chooseUser">
|
|
||||||
<el-checkbox
|
|
||||||
:label="`${item.name}~${item.id}`"
|
|
||||||
v-for="(item, index) in userList"
|
|
||||||
:key="index">
|
|
||||||
{{ item.name }}-{{ item.idNumber }}
|
|
||||||
</el-checkbox>
|
|
||||||
</el-checkbox-group>
|
|
||||||
<AiEmpty v-if="!this.userList.length"></AiEmpty>
|
|
||||||
</el-scrollbar>
|
|
||||||
</div>
|
|
||||||
<div class="AiWechatSelecter-container__right">
|
|
||||||
<div class="AiWechatSelecter-header AiWechatSelecter-header__right">
|
|
||||||
<h2>已选择</h2>
|
|
||||||
<el-button size="mini" icon="el-icon-delete" @click="clearAll">清空</el-button>
|
|
||||||
</div>
|
|
||||||
<el-scrollbar class="AiWechatSelecter-list">
|
|
||||||
<div class="tags-wrapper">
|
|
||||||
<el-tag
|
|
||||||
v-for="(item, index) in chooseUser"
|
|
||||||
:key="index"
|
|
||||||
closable
|
|
||||||
@close="del(item)"
|
|
||||||
size="small"
|
|
||||||
type="info">
|
|
||||||
{{ item.split('~')[0] }}
|
|
||||||
</el-tag>
|
|
||||||
</div>
|
|
||||||
</el-scrollbar>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ai-dialog>
|
|
||||||
</template>
|
|
||||||
</ai-list>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapState } from 'vuex'
|
|
||||||
export default {
|
|
||||||
name: 'Family',
|
|
||||||
|
|
||||||
props: {
|
|
||||||
instance: Function,
|
|
||||||
dict: Object,
|
|
||||||
params: Object
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
search: {
|
|
||||||
current: 1,
|
|
||||||
size: 10,
|
|
||||||
name: '',
|
|
||||||
girdId: ''
|
|
||||||
},
|
|
||||||
isLoading: false,
|
|
||||||
form: {
|
|
||||||
|
|
||||||
},
|
|
||||||
userList: [],
|
|
||||||
name: '',
|
|
||||||
chooseUser: [],
|
|
||||||
isShow: false,
|
|
||||||
total: 10,
|
|
||||||
colConfigs: [
|
|
||||||
{ type: 'selection', label: '' },
|
|
||||||
{ prop: 'name', label: '户主姓名', align: 'left', width: '200px' },
|
|
||||||
{ prop: 'idNumber', label: '身份证号', align: 'center' },
|
|
||||||
{ prop: 'phone', label: '联系方式', align: 'center' },
|
|
||||||
{ prop: 'girdName', label: '所属网格', align: 'center' },
|
|
||||||
{ prop: 'createTime', label: '添加时间', align: 'center' },
|
|
||||||
{ slot: 'options', label: '操作', align: 'center' }
|
|
||||||
],
|
|
||||||
tableData: [],
|
|
||||||
areaId: '',
|
|
||||||
ids: [],
|
|
||||||
disabledLevel: 0,
|
|
||||||
girdList: [],
|
|
||||||
girdId: '',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
|
||||||
...mapState(['user'])
|
|
||||||
},
|
|
||||||
|
|
||||||
created() {
|
|
||||||
this.areaId = this.user.info.areaId
|
|
||||||
this.disabledLevel = this.user.info.areaList.length
|
|
||||||
this.dict.load('epidemicDangerousAreaLevel').then(() => {
|
|
||||||
this.getGirdList()
|
|
||||||
this.getList()
|
|
||||||
this.getUserList()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
getGirdList() {
|
|
||||||
this.instance.post(`/app/appgirdmemberinfo/queryMyGirdListByLevel2?girdMemberId=${this.params.id}`).then(res => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.girdList = res.data
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getListInit() {
|
|
||||||
this.search.current = 1
|
|
||||||
this.getList()
|
|
||||||
},
|
|
||||||
getList () {
|
|
||||||
this.instance.post(`/app/appgirdmemberresident/listByGirdMember`, null, {
|
|
||||||
params: {
|
|
||||||
...this.search,
|
|
||||||
girdMemberId: this.params.id,
|
|
||||||
areaId: this.areaId
|
|
||||||
}
|
|
||||||
}).then(res => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.tableData = res.data.records
|
|
||||||
this.total = res.data.total
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
removeAll() {
|
|
||||||
if (!this.ids) {
|
|
||||||
return this.$message.error('请选择户主')
|
|
||||||
}
|
|
||||||
this.remove(this.ids.join(','))
|
|
||||||
},
|
|
||||||
handleSelectionChange(e) {
|
|
||||||
this.ids = e.map(v => v.gmrId)
|
|
||||||
},
|
|
||||||
|
|
||||||
clearAll () {
|
|
||||||
this.chooseUser = []
|
|
||||||
},
|
|
||||||
|
|
||||||
onConfirm () {
|
|
||||||
if(!this.girdId) {
|
|
||||||
return this.$message.error('请选择网格')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.chooseUser.length) {
|
|
||||||
return this.$message.error('请选择户主')
|
|
||||||
}
|
|
||||||
|
|
||||||
const residentList = this.chooseUser.map(v => {
|
|
||||||
return {
|
|
||||||
girdMemberId: this.params.id,
|
|
||||||
name: v.split('~')[0],
|
|
||||||
residentId: v.split('~')[1],
|
|
||||||
girdId: this.girdId
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.instance.post(`/app/appgirdmemberresident/add`, {
|
|
||||||
residentList
|
|
||||||
}).then(res => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.current = 1
|
|
||||||
this.getList()
|
|
||||||
this.$message.success('添加成功')
|
|
||||||
this.closeDialog()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
closeDialog() {
|
|
||||||
this.isShow = false
|
|
||||||
this.chooseUser = []
|
|
||||||
this.girdId = ''
|
|
||||||
this.name = ''
|
|
||||||
this.areaId = this.user.info.areaId
|
|
||||||
this.getUserList()
|
|
||||||
},
|
|
||||||
|
|
||||||
del (e) {
|
|
||||||
this.chooseUser.splice(this.chooseUser.indexOf(e), 1)
|
|
||||||
},
|
|
||||||
|
|
||||||
getUserList () {
|
|
||||||
this.isLoading = true
|
|
||||||
this.instance.post(`/app/appresident/list`, null, {
|
|
||||||
params: {
|
|
||||||
current: 1,
|
|
||||||
size: 200,
|
|
||||||
con: this.name,
|
|
||||||
householdName: 1,
|
|
||||||
areaId: this.areaId,
|
|
||||||
}
|
|
||||||
}).then(res => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.userList = res.data.records
|
|
||||||
}
|
|
||||||
|
|
||||||
this.isLoading = false
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
onBack () {
|
|
||||||
this.$emit('change', {
|
|
||||||
type: 'list'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
remove(id) {
|
|
||||||
this.$confirm('确定删除该数据?').then(() => {
|
|
||||||
this.instance.post(`/app/appgirdmemberresident/delete?ids=${id}`).then(res => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.$message.success('删除成功!')
|
|
||||||
this.getList()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.Family {
|
|
||||||
.AiWechatSelecter-container {
|
|
||||||
display: flex;
|
|
||||||
height: 380px;
|
|
||||||
margin-top: 20px;
|
|
||||||
|
|
||||||
::v-deep {
|
|
||||||
.el-icon-circle-close {
|
|
||||||
display: inline-block!important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tree-container {
|
|
||||||
& > span {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tree-user__item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
img {
|
|
||||||
width: 27px;
|
|
||||||
height: 27px;
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-tree {
|
|
||||||
background: transparent;
|
|
||||||
|
|
||||||
.el-tree-node {
|
|
||||||
margin-bottom: 8px;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-tree-node__content {
|
|
||||||
height: auto;
|
|
||||||
margin-top: 2px;
|
|
||||||
// align-items: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-tree-node__expand-icon {
|
|
||||||
height: 24px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.mask-btn__wrapper {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mask-btn {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.userlist-item {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
padding: 0 17px;
|
|
||||||
cursor: pointer;
|
|
||||||
user-select: none;
|
|
||||||
|
|
||||||
::v-deep .el-checkbox__label {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.userlist-item__left {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
span {
|
|
||||||
color: #222222;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
width: 40px;
|
|
||||||
height: 40px;
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
& > div {
|
|
||||||
width: 280px;
|
|
||||||
background: #FCFCFC;
|
|
||||||
border: 1px solid #D0D4DC;
|
|
||||||
}
|
|
||||||
|
|
||||||
.AiWechatSelecter-list {
|
|
||||||
height: calc(100% - 40px);
|
|
||||||
padding: 8px 0;
|
|
||||||
|
|
||||||
::v-deep .el-scrollbar__wrap {
|
|
||||||
margin-bottom: 0!important;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-checkbox-group {
|
|
||||||
padding: 0 8px;
|
|
||||||
|
|
||||||
.el-checkbox {
|
|
||||||
display: block;
|
|
||||||
margin-right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.AiWechatSelecter-container__left {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.AiWechatSelecter-container__right {
|
|
||||||
flex: 1;
|
|
||||||
margin-left: 20px;
|
|
||||||
|
|
||||||
.AiWechatSelecter-list {
|
|
||||||
.tags-wrapper {
|
|
||||||
padding: 0 8px;
|
|
||||||
}
|
|
||||||
.el-tag {
|
|
||||||
margin: 0 8px 8px 0px;
|
|
||||||
color: #222222;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.AiWechatSelecter-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
height: 40px;
|
|
||||||
padding: 0 8px 0 0;
|
|
||||||
border-bottom: 1px solid #D0D4DC;
|
|
||||||
background: #F5F7FA;
|
|
||||||
|
|
||||||
.AiWechatSelecter-header__left {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 8px;
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
height: 100%;
|
|
||||||
line-height: 40px;
|
|
||||||
color: #222222;
|
|
||||||
font-size: 14px;
|
|
||||||
text-align: center;
|
|
||||||
cursor: pointer;
|
|
||||||
border-bottom: 2px solid transparent;
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
color: #2266FF;
|
|
||||||
border-color: #2266FF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-button {
|
|
||||||
height: 28px;
|
|
||||||
padding: 7px 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-input {
|
|
||||||
width: 160px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.AiWechatSelecter-header__right {
|
|
||||||
padding: 0 8px;
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
color: #222222;
|
|
||||||
font-size: 14px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,543 +0,0 @@
|
|||||||
<template>
|
|
||||||
<section style="height: 100%">
|
|
||||||
<ai-detail class="add">
|
|
||||||
<template #title>
|
|
||||||
<ai-title :title="title" :isShowBack="true" :isShowBottomBorder="true" @onBackClick="cancel(false)"></ai-title>
|
|
||||||
</template>
|
|
||||||
<template #content>
|
|
||||||
<el-form
|
|
||||||
ref="rules"
|
|
||||||
:model="forms"
|
|
||||||
:rules="formRules"
|
|
||||||
size="small"
|
|
||||||
label-suffix=":"
|
|
||||||
label-width="136px">
|
|
||||||
<ai-card title="基础信息" >
|
|
||||||
<template #right v-if="title=='网格员详情'">
|
|
||||||
<span style="color:#2266FF;cursor: pointer;font-size: 12px;" class="iconfont iconEdit" v-if="editOne==false" @click="editOne=true">修改</span>
|
|
||||||
<span style="color:#2266FF;margin-left: 16px;cursor: pointer;font-size: 12px;" v-if="editOne==true" @click="searchDetail(),editOne=false">取消</span>
|
|
||||||
<span style="color:#2266FF;margin-left: 16px;cursor: pointer;font-size: 12px;" v-if="editOne==true" @click="save()">保存</span>
|
|
||||||
</template>
|
|
||||||
<template slot="content">
|
|
||||||
<div class="above" v-if="editOne==true">
|
|
||||||
<div class="left">
|
|
||||||
<el-form-item label="网格员姓名" prop="name" >
|
|
||||||
<el-input v-model="forms.name" placeholder="请选择网格员" disabled>
|
|
||||||
<template #append>
|
|
||||||
<ai-wechat-selecter :isMultiple="false" refs="addTags" :instance="instance" v-model="users" @change="getSelectPerson">
|
|
||||||
<el-button size="small" type="primary"><span style="color: #fff">选择成员</span></el-button>
|
|
||||||
</ai-wechat-selecter>
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="选用日期" prop="selectionDate" >
|
|
||||||
<el-date-picker
|
|
||||||
v-model="forms.selectionDate"
|
|
||||||
type="date"
|
|
||||||
style="width: 100%"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
size="medium"
|
|
||||||
placeholder="选择日期">
|
|
||||||
</el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="身份证号" prop="idNumber" >
|
|
||||||
<el-input v-model="forms.idNumber" placeholder="请输入…" maxlength="18" show-word-limit></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
|
||||||
<div class="right">
|
|
||||||
<el-form-item label="照片" prop="photo">
|
|
||||||
<!-- <ai-uploader :instance="instance" v-model="photoList" :limit="1" @change="photoChange"></ai-uploader> -->
|
|
||||||
<ai-avatar :instance="instance" v-model="forms.photo"/>
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="above" v-if="editOne==true">
|
|
||||||
<div class="left">
|
|
||||||
<el-form-item label="出生日期" prop="birthday" >
|
|
||||||
<el-date-picker
|
|
||||||
v-model="forms.birthday"
|
|
||||||
type="date"
|
|
||||||
style="width: 100%"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
size="medium"
|
|
||||||
placeholder="选择日期">
|
|
||||||
</el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="联系电话" prop="phone" >
|
|
||||||
<el-input v-model.number="forms.phone" placeholder="请输入…" maxlength="11" show-word-limit></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
|
||||||
<div class="right">
|
|
||||||
<el-form-item label="性别" prop="sex" >
|
|
||||||
<el-select size="medium" style="width: 100%" v-model="forms.sex" placeholder="请选择..." clearable>
|
|
||||||
<el-option
|
|
||||||
v-for="(item,i) in dict.getDict('sex')"
|
|
||||||
:key="i"
|
|
||||||
:label="item.dictName"
|
|
||||||
:value="item.dictValue"
|
|
||||||
>
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="电子邮箱" prop="mail" >
|
|
||||||
<el-input v-model="forms.mail" placeholder="请输入…"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<template v-if="editOne==false">
|
|
||||||
<div class="above">
|
|
||||||
<div class="left">
|
|
||||||
<ai-wrapper label-width="120px" :columnsNumber="1" style="margin-top: 16px;">
|
|
||||||
<ai-info-item label="网格员姓名:"><span >{{forms.name}}</span></ai-info-item>
|
|
||||||
<ai-info-item label="选用日期:"><span >{{forms.selectionDate}}</span></ai-info-item>
|
|
||||||
<ai-info-item label="身份证号:"><span >{{forms.idNumber}}</span></ai-info-item>
|
|
||||||
<ai-info-item label="性别:"><span >{{dict.getLabel('sex', forms.sex)}}</span></ai-info-item>
|
|
||||||
<ai-info-item label="出生日期:"><span >{{forms.birthday}}</span></ai-info-item>
|
|
||||||
<ai-info-item label="电子邮箱:"><span >{{forms.mail}}</span></ai-info-item>
|
|
||||||
</ai-wrapper>
|
|
||||||
</div>
|
|
||||||
<div class="right">
|
|
||||||
<ai-wrapper label-width="120px" :columnsNumber="1" style="margin-top: 16px;">
|
|
||||||
<ai-info-item label="照片:" v-if="forms.photo">
|
|
||||||
<span >
|
|
||||||
<ai-uploader :instance="instance" v-model="photoList" disabled :limit="1" @change="photoChange"></ai-uploader>
|
|
||||||
</span>
|
|
||||||
</ai-info-item>
|
|
||||||
<ai-info-item label="联系电话:"><span >{{forms.phone}}</span></ai-info-item>
|
|
||||||
</ai-wrapper>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</ai-card>
|
|
||||||
<ai-card title="关联信息" >
|
|
||||||
<template #right v-if="title=='网格员详情'">
|
|
||||||
<span style="color:#2266FF;cursor: pointer;font-size: 12px;" class="iconfont iconEdit" v-if="editTwo==false" @click="editTwo=true">修改</span>
|
|
||||||
<span style="color:#2266FF;margin-left: 16px;cursor: pointer;font-size: 12px;" v-if="editTwo==true" @click="searchDetail(),editTwo=false">取消</span>
|
|
||||||
<span style="color:#2266FF;margin-left: 16px;cursor: pointer;font-size: 12px;" v-if="editTwo==true" @click="save()">保存</span>
|
|
||||||
</template>
|
|
||||||
<template slot="content">
|
|
||||||
<template v-if="editTwo==true">
|
|
||||||
<el-form-item label="责任网格" prop="girdInfoList" style="margin-top: 8px;">
|
|
||||||
<el-form-item style="width: 100%" label-width="80px" :label="'网格' + (index + 1)" v-for="(item, index) in forms.girdInfoList" :key="'选项' + (index + 1)">
|
|
||||||
<div class="form-flex">
|
|
||||||
<el-select v-model="item.checkType" placeholder="请选择网格角色">
|
|
||||||
<el-option
|
|
||||||
v-for="item in options"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value">
|
|
||||||
</el-option>
|
|
||||||
</el-select>
|
|
||||||
<el-input disabled v-model="item.girdName" :maxlength="200" size="small" placeholder="请选择责任网格">
|
|
||||||
<template slot="append">
|
|
||||||
<el-button size="small" @click="currIndex = index, showGrid = true">选择网格</el-button>
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
<el-button type="danger" size="small" @click="removeGrid(index)">删除</el-button>
|
|
||||||
</div>
|
|
||||||
</el-form-item>
|
|
||||||
<el-button type="primary" size="small" @click="addGrid">添加选项</el-button>
|
|
||||||
<!-- <el-button size="small" @click="showGrid=true">选择网格</el-button> -->
|
|
||||||
</el-form-item>
|
|
||||||
<div class="above">
|
|
||||||
<div class="left">
|
|
||||||
<el-form-item label="是否特殊网格员" prop="isGirdMember" >
|
|
||||||
<el-radio-group v-model="forms.isGirdMember">
|
|
||||||
<el-radio label="0">否</el-radio>
|
|
||||||
<el-radio label="1">是</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="政治面貌" prop="politicsStatus" >
|
|
||||||
<el-select v-model="forms.politicsStatus" size="small" style="width: 100%" placeholder="请选择..." clearable>
|
|
||||||
<el-option v-for="(item,i) in dict.getDict('politicsStatus')" :key="i" :label="item.dictName" :value="item.dictValue"></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
|
||||||
<div class="right">
|
|
||||||
<el-form-item label="特殊网格员" prop="girdMemberType" v-if="forms.isGirdMember==1">
|
|
||||||
<el-select v-model="forms.girdMemberType" size="small" placeholder="请选择..." clearable>
|
|
||||||
<el-option v-for="(item,i) in dict.getDict('girdMemberType')" :key="i" :label="item.dictName" :value="item.dictValue"></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="学历" prop="education" >
|
|
||||||
<el-select v-model="forms.education" style="width: 100%" size="small" placeholder="请选择..." clearable>
|
|
||||||
<el-option v-for="(item,i) in dict.getDict('education')" :key="i" :label="item.dictName" :value="item.dictValue"></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<el-form-item label="个人简介" prop="introduction" >
|
|
||||||
<el-input
|
|
||||||
type="textarea"
|
|
||||||
maxlength="200"
|
|
||||||
show-word-limit
|
|
||||||
:rows="4"
|
|
||||||
placeholder="请输入内容"
|
|
||||||
v-model="forms.introduction">
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="人生格言" prop="motto" >
|
|
||||||
<el-input
|
|
||||||
type="textarea"
|
|
||||||
maxlength="200"
|
|
||||||
show-word-limit
|
|
||||||
:rows="4"
|
|
||||||
placeholder="请输入内容"
|
|
||||||
v-model="forms.motto">
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</template>
|
|
||||||
<template v-if="editTwo==false">
|
|
||||||
<ai-wrapper label-width="120px" :columnsNumber="2" style="margin-top: 16px;">
|
|
||||||
<ai-info-item label="责任网格:" style="width: 100%;"><span v-html="girdInfoStr || '-'"></span></ai-info-item>
|
|
||||||
<ai-info-item label="是否特殊网格员:">
|
|
||||||
<span>{{ !forms.isGirdMember ? '-' : forms.isGirdMember === '0' ? '否' : '是' }}</span>
|
|
||||||
</ai-info-item>
|
|
||||||
<ai-info-item label="特殊网格员:" v-if="forms.isGirdMember==1"><span >{{dict.getLabel('girdMemberType', forms.girdMemberType)}}</span></ai-info-item>
|
|
||||||
<ai-info-item label="政治面貌:"><span >{{dict.getLabel('politicsStatus', forms.politicsStatus)}}</span></ai-info-item>
|
|
||||||
<ai-info-item label="学历:"><span >{{dict.getLabel('education', forms.education)}}</span></ai-info-item>
|
|
||||||
<ai-info-item label="人生格言:" style="width: 100%;"><span >{{forms.motto}}</span></ai-info-item>
|
|
||||||
<ai-info-item label="个人简介:" style="width: 100%;"><span >{{forms.introduction}}</span></ai-info-item>
|
|
||||||
</ai-wrapper>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</ai-card>
|
|
||||||
</el-form>
|
|
||||||
<ai-dialog title="选择网格" :visible.sync="showGrid" :customFooter="true" :destroyOnClose="true" border width="720px">
|
|
||||||
<div class="grid">
|
|
||||||
<el-tree
|
|
||||||
:data="treeObj.treeList"
|
|
||||||
:props="treeObj.defaultProps"
|
|
||||||
node-key="id"
|
|
||||||
ref="tree"
|
|
||||||
:check-strictly="true"
|
|
||||||
show-checkbox
|
|
||||||
:default-checked-keys="currCheckedKeys"
|
|
||||||
default-expand-all
|
|
||||||
@check="onCheckChange">
|
|
||||||
</el-tree>
|
|
||||||
</div>
|
|
||||||
<div class="dialog-footer" slot="footer" >
|
|
||||||
<el-button size="medium" @click="showGrid=false">取消</el-button>
|
|
||||||
<el-button type="primary" size="medium" @click="getCheckedTree()">确认</el-button>
|
|
||||||
</div>
|
|
||||||
</ai-dialog>
|
|
||||||
</template>
|
|
||||||
<template #footer v-if="title=='添加网格员'">
|
|
||||||
<el-button @click="cancel(false)" class="delete-btn footer-btn" >取 消</el-button>
|
|
||||||
<el-button type="primary" @click="save()" class="footer-btn">提 交</el-button>
|
|
||||||
</template>
|
|
||||||
</ai-detail>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "add",
|
|
||||||
props: {
|
|
||||||
instance: Function,
|
|
||||||
dict: Object,
|
|
||||||
permissions: Function,
|
|
||||||
params: Object,
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
users: [],
|
|
||||||
currIndex: 0,
|
|
||||||
forms: {
|
|
||||||
birthday: "",
|
|
||||||
education: "",
|
|
||||||
girdId: "",
|
|
||||||
girdInfoList: [],
|
|
||||||
girdMemberType: "",
|
|
||||||
id: "",
|
|
||||||
wxUserId: '',
|
|
||||||
introduction: "",
|
|
||||||
isGirdMember: "",
|
|
||||||
mail: "",
|
|
||||||
motto: "",
|
|
||||||
name: "",
|
|
||||||
phone: "",
|
|
||||||
photo: "",
|
|
||||||
politicsStatus: "",
|
|
||||||
selectionDate: "",
|
|
||||||
sex: "",
|
|
||||||
userId: "",
|
|
||||||
},
|
|
||||||
options: [{
|
|
||||||
value: '2',
|
|
||||||
label: '网格长'
|
|
||||||
}, {
|
|
||||||
value: '1',
|
|
||||||
label: '网格员'
|
|
||||||
}],
|
|
||||||
showGrid: false,
|
|
||||||
treeObj: {
|
|
||||||
treeList: [],
|
|
||||||
defaultProps: {
|
|
||||||
children: "girdList",
|
|
||||||
label: "girdName",
|
|
||||||
},
|
|
||||||
checkedKeys: [],
|
|
||||||
},
|
|
||||||
girdInfoStr: '',
|
|
||||||
photoList: [],
|
|
||||||
title: "添加网格员",
|
|
||||||
editOne: false,
|
|
||||||
editTwo: false,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.beforeSelectTree()
|
|
||||||
if (this.params.id) {
|
|
||||||
this.searchDetail();
|
|
||||||
this.title = "网格员详情";
|
|
||||||
this.editOne = false;
|
|
||||||
this.editTwo = false;
|
|
||||||
} else {
|
|
||||||
this.title = "添加网格员";
|
|
||||||
this.editOne = true;
|
|
||||||
this.editTwo = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
currCheckedKeys () {
|
|
||||||
if (this.forms && this.forms.girdInfoList && this.forms.girdInfoList[this.currIndex] && this.forms.girdInfoList[this.currIndex].id) {
|
|
||||||
return [this.forms.girdInfoList[this.currIndex].id]
|
|
||||||
}
|
|
||||||
|
|
||||||
return []
|
|
||||||
},
|
|
||||||
formRules() {
|
|
||||||
let phonePass = (rule, value, callback) => {
|
|
||||||
let reg = /^(?:(?:\+|00)86)?1\d{10}$/;
|
|
||||||
if (value) {
|
|
||||||
if (reg.test(value)) {
|
|
||||||
callback();
|
|
||||||
} else {
|
|
||||||
callback(new Error("联系电话格式错误"));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
callback(new Error("请输入联系电话"));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
name: [
|
|
||||||
{ required: true, message: "请输入网格员姓名", trigger: "change" },
|
|
||||||
],
|
|
||||||
selectionDate: [
|
|
||||||
{ required: true, message: "请选择选用日期", trigger: "change" },
|
|
||||||
],
|
|
||||||
phone: [{ required: true, validator: phonePass, trigger: "blur" }],
|
|
||||||
girdInfoList: [
|
|
||||||
{ required: true, message: "请选择责任网络", trigger: "change" },
|
|
||||||
],
|
|
||||||
mail: [
|
|
||||||
{
|
|
||||||
type: "email",
|
|
||||||
message: "请输入正确的邮箱地址",
|
|
||||||
trigger: ["blur", "change"],
|
|
||||||
},
|
|
||||||
]
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
cancel (isRefresh) {
|
|
||||||
this.$emit('change', {
|
|
||||||
type: 'list',
|
|
||||||
isRefresh: !!isRefresh,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
onCheckChange (e) {
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs.tree.getCheckedKeys().forEach(v => {
|
|
||||||
this.$refs.tree.setChecked(v, false)
|
|
||||||
})
|
|
||||||
this.$refs.tree.setChecked(e.id, true)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
removeGrid (index) {
|
|
||||||
this.forms.girdInfoList.splice(index, 1)
|
|
||||||
},
|
|
||||||
|
|
||||||
addGrid () {
|
|
||||||
this.forms.girdInfoList.push({
|
|
||||||
id: '',
|
|
||||||
girdName: '',
|
|
||||||
checkType: ''
|
|
||||||
})
|
|
||||||
},
|
|
||||||
photoChange(val) {
|
|
||||||
this.forms.photo = val[0].url;
|
|
||||||
},
|
|
||||||
getSelectPerson(val) {
|
|
||||||
this.forms.name = val[0].name;
|
|
||||||
this.forms.phone = val[0].phone;
|
|
||||||
this.forms.userId = val[0].sysUserId
|
|
||||||
this.forms.wxUserId = val[0].id
|
|
||||||
},
|
|
||||||
getCheckedTree() {
|
|
||||||
if (!this.$refs.tree.getCheckedNodes().length) {
|
|
||||||
return this.$message.error('请选择网格')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.$refs.tree.getCheckedNodes().length > 1) {
|
|
||||||
return this.$message.error('不支持多选')
|
|
||||||
}
|
|
||||||
this.$set(this.forms.girdInfoList, this.currIndex, {
|
|
||||||
...this.$refs.tree.getCheckedNodes()[0],
|
|
||||||
checkType: this.forms.girdInfoList[this.currIndex].checkType
|
|
||||||
})
|
|
||||||
this.showGrid = false;
|
|
||||||
},
|
|
||||||
handleClose(tag) {
|
|
||||||
this.forms.girdInfoList.splice(this.forms.girdInfoList.indexOf(tag), 1);
|
|
||||||
},
|
|
||||||
beforeSelectTree() {
|
|
||||||
this.treeObj.checkedKeys = [];
|
|
||||||
this.instance.post(`/app/appgirdinfo/listAll`, null, null).then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.treeObj.treeList = res.data;
|
|
||||||
this.forms.girdInfoList.map((e) => {
|
|
||||||
this.treeObj.checkedKeys.push(e.id);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
save() {
|
|
||||||
this.$refs["rules"].validate((valid) => {
|
|
||||||
if (valid) {
|
|
||||||
for (let i = 0; i < this.forms.girdInfoList.length; i++) {
|
|
||||||
const currInfo = this.forms.girdInfoList[i]
|
|
||||||
const arr = JSON.parse(JSON.stringify(this.forms.girdInfoList))
|
|
||||||
arr.splice(i, 1)
|
|
||||||
const sameInfo = arr.filter(v => v.id === currInfo.id)
|
|
||||||
if (!currInfo.checkType) {
|
|
||||||
return this.$message.error('请选择网格员类型')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!currInfo.id) {
|
|
||||||
return this.$message.error('请选择网格')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currInfo.checkType === '1' && currInfo.girdLevel !== '2') {
|
|
||||||
return this.$message.error(`一级、二级网格不能添加网格员`)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sameInfo.length) {
|
|
||||||
return this.$message.error('不能选择同一网格重复绑定')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.instance.post(`/app/appgirdmemberinfo/addOrUpdate`,{
|
|
||||||
...this.forms,
|
|
||||||
girdInfoListStr: this.forms.girdInfoList.map(v => v.girdName).join(',')
|
|
||||||
}).then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
if (this.title == "添加网格员") {
|
|
||||||
this.cancel(true)
|
|
||||||
} else {
|
|
||||||
this.editOne = false
|
|
||||||
this.editTwo = false
|
|
||||||
this.searchDetail()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
searchDetail() {
|
|
||||||
this.instance
|
|
||||||
.post(`/app/appgirdmemberinfo/queryDetailById`, null, {
|
|
||||||
params: { id: this.params.id },
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.forms = {
|
|
||||||
...res.data,
|
|
||||||
girdInfoList: res.data.girdInfoList || []
|
|
||||||
};
|
|
||||||
this.users = [{
|
|
||||||
name: res.data.name,
|
|
||||||
phone: res.data.phone,
|
|
||||||
userId: res.data.id,
|
|
||||||
id: res.data.wxUserId
|
|
||||||
}]
|
|
||||||
this.girdInfoStr = ''
|
|
||||||
this.photoList = [{ url: this.forms.photo }];
|
|
||||||
if (res.data.girdInfoList) {
|
|
||||||
res.data.girdInfoList.forEach((e) => {
|
|
||||||
this.girdInfoStr = this.girdInfoStr + `${e.checkType === '1' ? '网格员' : '网格长'}-${e.girdName} `
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.add {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
.form-flex {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
& > .el-button {
|
|
||||||
margin-left: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-input {
|
|
||||||
width: 300px;
|
|
||||||
margin-left: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-form-item__content {
|
|
||||||
margin-left: 0!important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.ai-detail__title {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
.ai-detail__content {
|
|
||||||
.ai-detail__content--wrapper {
|
|
||||||
.el-form {
|
|
||||||
// background-color: #fff;
|
|
||||||
// padding: 0 60px;
|
|
||||||
.flex {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: space-between;
|
|
||||||
.el-form-item {
|
|
||||||
width: 48%;
|
|
||||||
}
|
|
||||||
.buildingTypes {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
::v-deep .el-tag {
|
|
||||||
margin-right: 8px;
|
|
||||||
color: #333333;
|
|
||||||
}
|
|
||||||
.footer-btn {
|
|
||||||
width: 92px;
|
|
||||||
}
|
|
||||||
.above{
|
|
||||||
display: flex;
|
|
||||||
.left, .right{
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,199 +0,0 @@
|
|||||||
<template>
|
|
||||||
<ai-list class="list">
|
|
||||||
<template slot="title">
|
|
||||||
<ai-title title="网格员管理" :isShowBottomBorder="true"></ai-title>
|
|
||||||
</template>
|
|
||||||
<template slot="content">
|
|
||||||
<ai-search-bar bottomBorder>
|
|
||||||
<template slot="left">
|
|
||||||
<el-date-picker
|
|
||||||
v-model="searchObj.selectionDate"
|
|
||||||
type="date"
|
|
||||||
@change="(page.current = 1), getList()"
|
|
||||||
value-format="yyyy-MM-dd"
|
|
||||||
size="small"
|
|
||||||
placeholder="选用时间">
|
|
||||||
</el-date-picker>
|
|
||||||
</template>
|
|
||||||
<template slot="right">
|
|
||||||
<el-input
|
|
||||||
v-model="searchObj.name"
|
|
||||||
size="small"
|
|
||||||
placeholder="网格员/责任网格"
|
|
||||||
@keyup.enter.native="(page.current = 1), getList()"
|
|
||||||
clearable
|
|
||||||
@clear="(searchObj.name = '', page.current = 1), getList()"
|
|
||||||
suffix-icon="iconfont iconSearch" />
|
|
||||||
</template>
|
|
||||||
</ai-search-bar>
|
|
||||||
<ai-search-bar style="padding: 16px 0 0">
|
|
||||||
<template slot="left">
|
|
||||||
<el-button
|
|
||||||
icon="iconfont iconAdd"
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
@click="add('')"
|
|
||||||
>添加</el-button
|
|
||||||
>
|
|
||||||
<el-button
|
|
||||||
icon="iconfont iconDelete"
|
|
||||||
@click="deleteById(ids.join(','))"
|
|
||||||
:disabled="!Boolean(ids.length)"
|
|
||||||
>删除</el-button
|
|
||||||
>
|
|
||||||
</template>
|
|
||||||
</ai-search-bar>
|
|
||||||
<ai-table
|
|
||||||
:tableData="tableData"
|
|
||||||
:col-configs="colConfigs"
|
|
||||||
:total="page.total"
|
|
||||||
ref="aitableex"
|
|
||||||
:current.sync="page.current"
|
|
||||||
:size.sync="page.size"
|
|
||||||
@selection-change="(v) => (ids = v.map((e) => e.id))"
|
|
||||||
@getList="getList()">
|
|
||||||
<el-table-column label="操作" slot="options" align="center" fixed="right" width="170">
|
|
||||||
<template slot-scope="{ row }">
|
|
||||||
<div class="table-options">
|
|
||||||
<el-button type="text" @click="toFamily(row.id)">责任家庭</el-button>
|
|
||||||
<el-button type="text" @click="add(row.id)">查看</el-button>
|
|
||||||
<el-button type="text" @click="deleteById(row.id)">删除</el-button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</ai-table>
|
|
||||||
</template>
|
|
||||||
</ai-list>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "list",
|
|
||||||
label: "网格员管理",
|
|
||||||
props: {
|
|
||||||
instance: Function,
|
|
||||||
dict: Object,
|
|
||||||
permissions: Function,
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
searchObj: {
|
|
||||||
name: "",
|
|
||||||
selectionDate: "",
|
|
||||||
},
|
|
||||||
page: {
|
|
||||||
current: 1,
|
|
||||||
size: 10,
|
|
||||||
total: 0,
|
|
||||||
},
|
|
||||||
goAdd: false,
|
|
||||||
tableData: [],
|
|
||||||
fileList: [],
|
|
||||||
ids: [],
|
|
||||||
detail: {},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.dict.load("sex", "girdMemberType", "politicsStatus", "education");
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
colConfigs() {
|
|
||||||
let _ = this;
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
type: "selection",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: "name",
|
|
||||||
label: "网格员姓名",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: "girdInfoListStr",
|
|
||||||
align: "center",
|
|
||||||
label: "责任网格",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: "phone",
|
|
||||||
align: "center",
|
|
||||||
label: "联系电话",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: "selectionDate",
|
|
||||||
align: "center",
|
|
||||||
label: "选用时间",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
this.instance
|
|
||||||
.post("/app/appgirdmemberinfo/list", null, {
|
|
||||||
params: {
|
|
||||||
...this.searchObj,
|
|
||||||
...this.page,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.tableData = res.data.records;
|
|
||||||
this.page.total = res.data.total;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
deleteById(ids) {
|
|
||||||
ids &&
|
|
||||||
this.$confirm("是否要删除该网格员?", {
|
|
||||||
type: "error",
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
this.instance
|
|
||||||
.post("/app/appgirdmemberinfo/delete", null, {
|
|
||||||
params: { ids },
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
if (res?.code == 0) {
|
|
||||||
this.$message.success("删除成功!");
|
|
||||||
this.getList();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {});
|
|
||||||
},
|
|
||||||
add(id) {
|
|
||||||
this.$emit('change', {
|
|
||||||
type: 'Add',
|
|
||||||
params: {
|
|
||||||
id: id || ''
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
toFamily (id) {
|
|
||||||
this.$emit('change', {
|
|
||||||
type: 'Family',
|
|
||||||
params: {
|
|
||||||
id
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
handleSelectionChange(val) {
|
|
||||||
this.ids = [];
|
|
||||||
val.map((e) => {
|
|
||||||
this.ids.push(e.id);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
resetSearch() {
|
|
||||||
Object.keys(this.searchObj).map((e) => {
|
|
||||||
this.searchObj[e] = "";
|
|
||||||
});
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
</style>
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="AppBroadcast">
|
|
||||||
<keep-alive :include="['List']">
|
|
||||||
<component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component>
|
|
||||||
</keep-alive>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import List from './components/List'
|
|
||||||
import Add from './components/Add'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
label: '播发记录',
|
|
||||||
name: 'AppBroadcast',
|
|
||||||
props: {
|
|
||||||
instance: Function,
|
|
||||||
dict: Object,
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
component: 'List',
|
|
||||||
params: {},
|
|
||||||
include: [],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
|
||||||
Add,
|
|
||||||
List
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onChange(data) {
|
|
||||||
if (data.type === 'add') {
|
|
||||||
this.component = 'Add'
|
|
||||||
this.params = data.params
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.type == 'list') {
|
|
||||||
this.component = 'List'
|
|
||||||
this.params = data.params
|
|
||||||
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if (data.isRefresh) {
|
|
||||||
this.$refs.component.getList()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.AppBroadcast {
|
|
||||||
height: 100%;
|
|
||||||
background: #f3f6f9;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,333 +0,0 @@
|
|||||||
<template>
|
|
||||||
<section style="height: 100%">
|
|
||||||
<ai-detail class="Add">
|
|
||||||
<!-- 返回按钮 -->
|
|
||||||
<template #title>
|
|
||||||
<ai-title title="添加广播" isShowBack isShowBottomBorder @onBackClick="cancel(false)"></ai-title>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #content>
|
|
||||||
<el-form :model="formData" :rules="formRules" ref="ruleForm" label-width="150px" label-suffix=":" align-items="center">
|
|
||||||
<ai-bar title="基础信息"></ai-bar>
|
|
||||||
<div class="flex">
|
|
||||||
<el-form-item label="播发内容" prop="mediaId">
|
|
||||||
<ai-select v-model="formData.mediaId" placeholder="播发内容" clearable :selectList="mediaList"></ai-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="播放设备" prop="serialNo">
|
|
||||||
<ai-select v-model="formData.serialNo" placeholder="播放设备" clearable :selectList="equipmentList"></ai-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="播发级别" prop="messageLevel">
|
|
||||||
<ai-select v-model="formData.messageLevel" placeholder="播发级别" clearable :selectList="$dict.getDict('dlbMessageUrgency')"></ai-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="播放方式" prop="taskType" class="buildingTypes">
|
|
||||||
<el-radio-group v-model="formData.taskType">
|
|
||||||
<el-radio label="0">立即播放</el-radio>
|
|
||||||
<el-radio label="1">定时播放</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="定时策略" prop="cyclingType" v-if="formData.taskType != 0">
|
|
||||||
<ai-select v-model="formData.cyclingType" placeholder="定时策略" clearable :selectList="$dict.getDict('dlbDyclingType')"></ai-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="播放天数" prop="checkList" class="buildingTypes" v-if="formData.taskType != 0 && formData.cyclingType == 2">
|
|
||||||
<el-checkbox-group v-model="formData.checkList">
|
|
||||||
<el-checkbox label="1">每周一</el-checkbox>
|
|
||||||
<el-checkbox label="2">每周二</el-checkbox>
|
|
||||||
<el-checkbox label="3">每周三</el-checkbox>
|
|
||||||
<el-checkbox label="4">每周四</el-checkbox>
|
|
||||||
<el-checkbox label="5">每周五</el-checkbox>
|
|
||||||
<el-checkbox label="6">每周六</el-checkbox>
|
|
||||||
<el-checkbox label="7">每周日</el-checkbox>
|
|
||||||
</el-checkbox-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="播放天数" prop="broadcastDay" v-if="formData.taskType != 0 && formData.cyclingType == 3">
|
|
||||||
<el-input v-model="formData.broadcastDay" placeholder="播放天数" clearable size="small" maxlength="4"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="开始日期" prop="startDate" v-if="formData.taskType != 0">
|
|
||||||
<el-date-picker v-model="formData.startDate" type="date" placeholder="选择日期" size="small" value-format="yyyy-MM-dd"></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="开始时间" prop="startTime" v-if="formData.taskType != 0">
|
|
||||||
<el-time-picker v-model="formData.startTime" placeholder="开始时间" size="small" :picker-options="{ start: newDate, minTime: newDate}" value-format="HH:mm:ss"></el-time-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="结束时间" prop="endTime" v-if="formData.taskType != 0">
|
|
||||||
<el-time-picker v-model="formData.endTime" placeholder="结束时间" size="small" :picker-options="{ start: formData.startTime, minTime: formData.startTime}" value-format="HH:mm:ss"></el-time-picker>
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
|
||||||
</el-form>
|
|
||||||
</template>
|
|
||||||
<template #footer>
|
|
||||||
<el-button @click="cancel">取消</el-button>
|
|
||||||
<el-button type="primary" @click="confirm()">提交</el-button>
|
|
||||||
</template>
|
|
||||||
</ai-detail>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapState } from 'vuex'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'Add',
|
|
||||||
components: {},
|
|
||||||
props: {
|
|
||||||
dict: Object,
|
|
||||||
params: Object,
|
|
||||||
instance: Function,
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
let startTimePass = (rule, value, callback) => {
|
|
||||||
if (value) {
|
|
||||||
var myDate = new Date();
|
|
||||||
var time = myDate.getHours() + ':' + myDate.getMinutes() + ':' + myDate.getSeconds()
|
|
||||||
if (this.timeToSec(value) - this.timeToSec(time)> 0) {
|
|
||||||
callback()
|
|
||||||
} else {
|
|
||||||
callback(new Error('开始时间要大于当前时间'));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
callback(new Error('请选择开始时间'));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let endTimePass = (rule, value, callback) => {
|
|
||||||
if (value) {
|
|
||||||
if (this.timeToSec(value) - this.timeToSec(this.formData.startTime)> 0) {
|
|
||||||
callback()
|
|
||||||
} else {
|
|
||||||
callback(new Error('结束时间要大于开始时间'));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
callback(new Error('请选择结束时间'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
formData: {
|
|
||||||
mediaId: '',
|
|
||||||
serialNo: '',
|
|
||||||
messageLevel: '',
|
|
||||||
cyclingType: '',
|
|
||||||
taskType: '0',
|
|
||||||
cyclingDate: '',
|
|
||||||
broadcastDay: '',
|
|
||||||
startDate: '',
|
|
||||||
startTime: '',
|
|
||||||
endTime: '',
|
|
||||||
checkList: []
|
|
||||||
},
|
|
||||||
formRules: {
|
|
||||||
mediaId: [
|
|
||||||
{ required: true, message: '请选择播发内容', trigger: 'change' }
|
|
||||||
],
|
|
||||||
serialNo: [
|
|
||||||
{ required: true, message: '请选择播放设备', trigger: 'change' }
|
|
||||||
],
|
|
||||||
messageLevel: [
|
|
||||||
{ required: true, message: '请选择播发级别', trigger: 'change' }
|
|
||||||
],
|
|
||||||
cyclingType: [
|
|
||||||
{ required: true, message: '请选择定时策略', trigger: 'change' }
|
|
||||||
],
|
|
||||||
taskType: [
|
|
||||||
{ required: true, message: '请选择播放方式', trigger: 'change' }
|
|
||||||
],
|
|
||||||
broadcastDay: [
|
|
||||||
{ required: true, message: '请输入播放天数', trigger: 'change' }
|
|
||||||
],
|
|
||||||
startDate: [
|
|
||||||
{ required: true, message: '请选择开始日期', trigger: 'change' }
|
|
||||||
],
|
|
||||||
startTime: [
|
|
||||||
{ required: true, validator: startTimePass, trigger: 'change' }
|
|
||||||
],
|
|
||||||
endTime: [
|
|
||||||
{ required: true, validator: endTimePass, trigger: 'change' }
|
|
||||||
],
|
|
||||||
checkList: [
|
|
||||||
{ required: true, message: '播放天数', trigger: 'change' }
|
|
||||||
],
|
|
||||||
},
|
|
||||||
mediaList: [],
|
|
||||||
equipmentList: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapState(['user']),
|
|
||||||
|
|
||||||
isEdit() {
|
|
||||||
return !!this.params.id
|
|
||||||
},
|
|
||||||
newDate() {
|
|
||||||
var myDate = new Date();
|
|
||||||
var time = myDate.getHours() + ':' + myDate.getMinutes() + ':' + myDate.getSeconds()
|
|
||||||
return time
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.dict.load('dlbMessageUrgency', 'dlbBroadTaskType', 'dlbDyclingType').then(() => {
|
|
||||||
this.getEquipmentList()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getMediaList() {
|
|
||||||
this.instance.post(`/app/appdlbresource/list?current=1&size=10000`).then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.mediaList = []
|
|
||||||
if(res.data && res.data.records.length) {
|
|
||||||
res.data.records.map((item) => {
|
|
||||||
let info = {
|
|
||||||
dictName: item.name,
|
|
||||||
dictValue: item.id
|
|
||||||
}
|
|
||||||
this.mediaList.push(info)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if(this.params.id) {
|
|
||||||
this.getDetail()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getEquipmentList() {
|
|
||||||
this.instance.post(`/app/appdlbquipment/getDlbDeviceList?current=1&size=10000&devStatus=5&keyword=`).then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.equipmentList = []
|
|
||||||
if(res.data && res.data.records.length) {
|
|
||||||
res.data.records.map((item) => {
|
|
||||||
let info = {
|
|
||||||
dictName: item.deviceName,
|
|
||||||
dictValue: item.serialNo
|
|
||||||
}
|
|
||||||
this.equipmentList.push(info)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
this.getMediaList()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
confirm() {
|
|
||||||
this.$refs['ruleForm'].validate((valid) => {
|
|
||||||
if (valid) {
|
|
||||||
if(this.formData.checkList.length) {
|
|
||||||
this.formData.cyclingDate = this.formData.checkList.join(',')
|
|
||||||
}
|
|
||||||
this.formData.coverageType = '4'
|
|
||||||
this.formData.id = ''
|
|
||||||
this.instance.post(`/app/appzyvideobroadcast/play`, {
|
|
||||||
...this.formData,
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.$message.success('提交成功')
|
|
||||||
setTimeout(() => {
|
|
||||||
this.cancel(true)
|
|
||||||
}, 1000)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getDetail() {
|
|
||||||
this.instance.post(`/app/appzyvideobroadcast/queryDetailById?id=${this.params.id}`).then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.formData = {
|
|
||||||
...res.data,
|
|
||||||
checkList: []
|
|
||||||
}
|
|
||||||
this.formData.mediaId = String(this.formData.mediaId)
|
|
||||||
this.formData.cyclingType = String(this.formData.cyclingType)
|
|
||||||
if(this.formData.cyclingDate) {
|
|
||||||
this.formData.checkList = this.formData.cyclingDate.split(',')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
timeToSec(time) {
|
|
||||||
var s = "";
|
|
||||||
var hour = time.split(":")[0];
|
|
||||||
var min = time.split(":")[1];
|
|
||||||
var second = time.split(":")[2];
|
|
||||||
s = Number(hour * 3600) + Number(min * 60) + Number(second)
|
|
||||||
return s;
|
|
||||||
},
|
|
||||||
// 返回按钮
|
|
||||||
cancel(isRefresh) {
|
|
||||||
this.$emit('change', {
|
|
||||||
type: 'list',
|
|
||||||
isRefresh: !!isRefresh,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.Add {
|
|
||||||
height: 100%;
|
|
||||||
.ai-detail__title {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
.ai-detail__content {
|
|
||||||
.ai-detail__content--wrapper {
|
|
||||||
.el-form {
|
|
||||||
background-color: #fff;
|
|
||||||
padding: 0 60px;
|
|
||||||
.flex {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: space-between;
|
|
||||||
.el-form-item {
|
|
||||||
width: 48%;
|
|
||||||
}
|
|
||||||
.buildingTypes {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .mapDialog {
|
|
||||||
.el-dialog__body {
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
.ai-dialog__content {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ai-dialog__content--wrapper {
|
|
||||||
padding: 0 !important;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
#map {
|
|
||||||
width: 100%;
|
|
||||||
height: 420px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.searchPlaceInput {
|
|
||||||
position: absolute;
|
|
||||||
width: 250px;
|
|
||||||
top: 30px;
|
|
||||||
left: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#searchPlaceOutput {
|
|
||||||
position: absolute;
|
|
||||||
width: 250px;
|
|
||||||
left: 25px;
|
|
||||||
height: initial;
|
|
||||||
top: 80px;
|
|
||||||
background: white;
|
|
||||||
z-index: 250;
|
|
||||||
max-height: 300px;
|
|
||||||
overflow-y: auto;
|
|
||||||
|
|
||||||
.auto-item {
|
|
||||||
text-align: left;
|
|
||||||
font-size: 14px;
|
|
||||||
padding: 8px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,156 +0,0 @@
|
|||||||
<template>
|
|
||||||
<section class="AppPetitionManage">
|
|
||||||
<ai-list>
|
|
||||||
<ai-title slot="title" title="播发记录" isShowBottomBorder/>
|
|
||||||
<template #content>
|
|
||||||
<ai-search-bar bottomBorder>
|
|
||||||
<template slot="left">
|
|
||||||
<ai-select v-model="search.messageType" placeholder="媒资类型" clearable
|
|
||||||
:selectList="$dict.getDict('dlbResourceType')"
|
|
||||||
@change=";(page.current = 1), getList()"></ai-select>
|
|
||||||
<ai-select v-model="search.messageUrgency" placeholder="级别" clearable
|
|
||||||
:selectList="$dict.getDict('dlbMessageUrgency')"
|
|
||||||
@change=";(page.current = 1), getList()"></ai-select>
|
|
||||||
</template>
|
|
||||||
<template slot="right">
|
|
||||||
<el-input v-model="search.messageName" size="small" placeholder="媒资名称" clearable
|
|
||||||
@keyup.enter.native=";(page.current = 1), getList()"
|
|
||||||
@clear=";(page.current = 1), (search.messageName = ''), getList()"
|
|
||||||
suffix-icon="iconfont iconSearch"/>
|
|
||||||
</template>
|
|
||||||
</ai-search-bar>
|
|
||||||
<ai-search-bar class="ai-search-ba mar-t10">
|
|
||||||
<template slot="left">
|
|
||||||
<!-- <el-button icon="iconfont iconAdd" type="primary" size="small" @click="onAdd('')">添加</el-button> -->
|
|
||||||
<!-- <el-button icon="iconfont iconDelete" size="small" @click="removeAll" :disabled="ids.length == 0">删除 </el-button> -->
|
|
||||||
</template>
|
|
||||||
</ai-search-bar>
|
|
||||||
<ai-table :tableData="tableData" :col-configs="colConfigs" :total="total" :dict="dict"
|
|
||||||
:current.sync="page.current" :size.sync="page.size" @getList="getList"
|
|
||||||
@selection-change="(v) => (ids = v.map((e) => e.id))">
|
|
||||||
<el-table-column slot="options" label="操作" align="center" width="180" fixed="right">
|
|
||||||
<template slot-scope="{ row }">
|
|
||||||
<el-button type="text" @click="onAdd(row.broadcastId)">复制</el-button>
|
|
||||||
<el-button type="text" @click="cancel(row.broadcastId)"
|
|
||||||
v-if="row.broadcastStatus == 0 || row.broadcastStatus == 1 || row.broadcastStatus == 2">撤回
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</ai-table>
|
|
||||||
</template>
|
|
||||||
</ai-list>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {mapState} from 'vuex'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'List',
|
|
||||||
props: {
|
|
||||||
dict: Object,
|
|
||||||
instance: Function,
|
|
||||||
params: Object,
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
isAdd: false,
|
|
||||||
page: {
|
|
||||||
current: 1,
|
|
||||||
size: 10,
|
|
||||||
},
|
|
||||||
total: 0,
|
|
||||||
search: {
|
|
||||||
messageName: '',
|
|
||||||
messageType: '',
|
|
||||||
messageUrgency: '',
|
|
||||||
},
|
|
||||||
id: '',
|
|
||||||
ids: [],
|
|
||||||
colConfigs: [
|
|
||||||
{prop: 'messageName', label: '媒资名称', width: 400},
|
|
||||||
{prop: 'messageType', label: '媒资类型', align: 'center', dict: "dlbResourceType"},
|
|
||||||
{prop: 'messageUrgency', label: '级别', align: 'center', dict: "dlbMessageUrgency"},
|
|
||||||
{prop: 'taskType', label: '播发方式', align: 'center', dict: "dlbBroadTaskType"},
|
|
||||||
{prop: 'startDate', label: '开始时间', align: 'center', width: 180},
|
|
||||||
{prop: 'broadcastStatus', label: '状态', align: 'center', dict: "dlbBroadcastStatus"},
|
|
||||||
{prop: 'areaName', label: '地区', align: 'center'},
|
|
||||||
{prop: 'createUserName', label: '创建人', align: 'center'},
|
|
||||||
{slot: 'options'},
|
|
||||||
],
|
|
||||||
tableData: [],
|
|
||||||
areaId: '',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
|
||||||
...mapState(['user']),
|
|
||||||
|
|
||||||
param() {
|
|
||||||
return {
|
|
||||||
...this.search,
|
|
||||||
areaId: this.user.info?.areaId,
|
|
||||||
ids: this.ids,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
created() {
|
|
||||||
this.areaId = this.user.info.areaId
|
|
||||||
this.dict.load('dlbResourceType', 'dlbMessageUrgency', 'dlbBroadTaskType', 'dlbBroadcastStatus', 'dlbMessageUrgency').then(() => {
|
|
||||||
this.getList()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
this.instance.post(`/app/appzyvideobroadcast/getBroadcastRecords`, null, {
|
|
||||||
params: {
|
|
||||||
...this.page,
|
|
||||||
...this.search,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.tableData = res.data.records
|
|
||||||
this.total = parseInt(res.data.total)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
onAdd(id) {
|
|
||||||
this.$emit('change', {
|
|
||||||
type: 'add',
|
|
||||||
params: {
|
|
||||||
id: id || ''
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
cancel(id) {
|
|
||||||
this.$confirm('确定撤回该广播?').then(() => {
|
|
||||||
this.instance.post(`/app/appzyvideobroadcast/getBroadcastRecall?broadcastId=${id}`).then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.$message.success('撤回成功!')
|
|
||||||
this.getList()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
removeAll() {
|
|
||||||
var id = this.ids.join(',')
|
|
||||||
this.remove(id)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.AppPetitionManage {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
.mar-t10 {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="AppEquipmentManage">
|
|
||||||
<keep-alive :include="['List']">
|
|
||||||
<component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component>
|
|
||||||
</keep-alive>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import List from './components/List'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
label: '广播设备管理',
|
|
||||||
name: 'AppEquipmentManage',
|
|
||||||
props: {
|
|
||||||
instance: Function,
|
|
||||||
dict: Object,
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
component: 'List',
|
|
||||||
params: {},
|
|
||||||
include: [],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
|
||||||
List
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onChange(data) {
|
|
||||||
if (data.type === 'add') {
|
|
||||||
this.component = 'Add'
|
|
||||||
this.params = data.params
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.type == 'list') {
|
|
||||||
this.component = 'List'
|
|
||||||
this.params = data.params
|
|
||||||
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if (data.isRefresh) {
|
|
||||||
this.$refs.component.getList()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.AppEquipmentManage {
|
|
||||||
height: 100%;
|
|
||||||
background: #f3f6f9;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,202 +0,0 @@
|
|||||||
<template>
|
|
||||||
<section class="AppPetitionManage">
|
|
||||||
<ai-list>
|
|
||||||
<ai-title slot="title" title="广播设备管理" isShowBottomBorder/>
|
|
||||||
<template #content>
|
|
||||||
<ai-search-bar bottomBorder>
|
|
||||||
<template slot="right">
|
|
||||||
<el-input v-model="search.keyword" size="small" placeholder="设备名称/设备编号" clearable
|
|
||||||
@keyup.enter.native=";(page.current = 1), getList()"
|
|
||||||
@clear=";(page.current = 1), (search.keyword = ''), getList()" suffix-icon="iconfont iconSearch"/>
|
|
||||||
</template>
|
|
||||||
</ai-search-bar>
|
|
||||||
<ai-search-bar class="ai-search-ba mar-t10">
|
|
||||||
<template slot="left">
|
|
||||||
<!-- <el-button icon="iconfont" type="primary" size="small">数据同步</el-button> -->
|
|
||||||
<!-- <el-button icon="iconfont iconDelete" size="small" @click="removeAll" :disabled="ids.length == 0">删除 </el-button> -->
|
|
||||||
</template>
|
|
||||||
</ai-search-bar>
|
|
||||||
<ai-table :tableData="tableData" :col-configs="colConfigs" :total="total" ref="aitableex"
|
|
||||||
:current.sync="page.current" :size.sync="page.size" @getList="getList"
|
|
||||||
@selection-change="(v) => (ids = v.map((e) => e.id))">
|
|
||||||
<el-table-column slot="options" label="操作" align="center" width="280" fixed="right">
|
|
||||||
<template slot-scope="{ row }">
|
|
||||||
<el-button type="text" @click="close(row.id)">停播</el-button>
|
|
||||||
<el-button type="text" @click="bind(row)">绑定行政区划</el-button>
|
|
||||||
<el-button type="text" @click="locate=true">地图标绘</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</ai-table>
|
|
||||||
</template>
|
|
||||||
</ai-list>
|
|
||||||
<el-dialog
|
|
||||||
title="绑定行政区划"
|
|
||||||
:visible.sync="bindVisible"
|
|
||||||
width="800px">
|
|
||||||
<ai-area-get :instance="instance" v-model="areaId" :root="user.info.areaId" @select="handleAreaSelect"/>
|
|
||||||
<span slot="footer" class="dialog-footer">
|
|
||||||
<el-button @click="bindVisible = false">取 消</el-button>
|
|
||||||
<el-button type="primary" @click="bindArea">确 定</el-button>
|
|
||||||
</span>
|
|
||||||
</el-dialog>
|
|
||||||
<locate-dialog v-model="locate" :ins="instance" @confirm="bindLocate"/>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {mapState} from 'vuex'
|
|
||||||
import LocateDialog from "../../../monitor/components/locateDialog";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'List',
|
|
||||||
components: {LocateDialog},
|
|
||||||
props: {
|
|
||||||
dict: Object,
|
|
||||||
instance: Function,
|
|
||||||
params: Object,
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
isAdd: false,
|
|
||||||
page: {
|
|
||||||
current: 1,
|
|
||||||
size: 10,
|
|
||||||
},
|
|
||||||
total: 0,
|
|
||||||
search: {
|
|
||||||
bind: '',
|
|
||||||
keyword: '',
|
|
||||||
},
|
|
||||||
id: '',
|
|
||||||
ids: [],
|
|
||||||
colConfigs: [
|
|
||||||
{
|
|
||||||
prop: 'deviceName',
|
|
||||||
label: '设备名称',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'areaName',
|
|
||||||
label: '所属行政区划',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'serialNo',
|
|
||||||
label: '设备编号',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'devStatus',
|
|
||||||
label: '设备状态',
|
|
||||||
width: '100',
|
|
||||||
align: 'center',
|
|
||||||
render: (h, {row}) => {
|
|
||||||
return h('span', null, this.dict.getLabel('dlbDevStatus', row.devStatus))
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'bind',
|
|
||||||
label: '是否绑定区划',
|
|
||||||
width: '120',
|
|
||||||
align: 'center',
|
|
||||||
render: (h, {row}) => {
|
|
||||||
return h('span', null, this.dict.getLabel('yesOrNo', row.bind))
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
slot: 'options',
|
|
||||||
label: '操作',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
tableData: [],
|
|
||||||
areaId: '',
|
|
||||||
bindVisible: false,
|
|
||||||
changeInfo: {},
|
|
||||||
locate: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
|
||||||
...mapState(['user']),
|
|
||||||
},
|
|
||||||
|
|
||||||
created () {
|
|
||||||
this.dict.load('dlbDevStatus', 'yesOrNo').then(() => {
|
|
||||||
this.getList()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
bind(item) {
|
|
||||||
this.areaId = ''
|
|
||||||
this.changeInfo = item
|
|
||||||
this.bindVisible = true
|
|
||||||
},
|
|
||||||
handleAreaSelect(v) {
|
|
||||||
this.changeInfo.areaName = v?.[0]?.label
|
|
||||||
},
|
|
||||||
bindArea() {
|
|
||||||
if (!this.areaId) {
|
|
||||||
return this.$message.error('请先选择行政区划')
|
|
||||||
}
|
|
||||||
this.changeInfo.areaId = this.areaId
|
|
||||||
this.instance.post(`/app/appdlbquipment/addOrUpdate`, this.changeInfo).then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.$message.success('绑定行政区划成功!')
|
|
||||||
this.bindVisible = false
|
|
||||||
this.getList()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
bindLocate(locate) {
|
|
||||||
if (locate) {
|
|
||||||
let {lat, lng} = locate.location, {changeInfo} = this
|
|
||||||
this.instance.post("/app/appdlbquipment/addOrUpdate", {
|
|
||||||
...changeInfo, lat, lng
|
|
||||||
}).then(res => {
|
|
||||||
if (res?.code == 0) {
|
|
||||||
this.$message.success("地图标绘成功!")
|
|
||||||
this.locate = true
|
|
||||||
this.getList()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
close(id) {
|
|
||||||
this.$confirm('确定停播该设备?').then(() => {
|
|
||||||
this.instance.post(`/app/appdlbquipment/stop?deviceId=${id}`).then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.$message.success('停播成功!')
|
|
||||||
this.getList()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getList() {
|
|
||||||
this.instance.post(`/app/appdlbquipment/getDlbDeviceList`, null, {
|
|
||||||
params: {
|
|
||||||
...this.page,
|
|
||||||
...this.search,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.tableData = res.data.records
|
|
||||||
this.total = parseInt(res.data.total)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.AppPetitionManage {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
.mar-t10 {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="AppMediaManage">
|
|
||||||
<keep-alive :include="['List']">
|
|
||||||
<component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component>
|
|
||||||
</keep-alive>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import List from './components/List'
|
|
||||||
import Add from './components/Add'
|
|
||||||
import Play from './components/Play'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
label: '媒资管理',
|
|
||||||
name: 'AppMediaManage',
|
|
||||||
props: {
|
|
||||||
instance: Function,
|
|
||||||
dict: Object,
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
component: 'List',
|
|
||||||
params: {},
|
|
||||||
include: [],
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
components: {
|
|
||||||
Add,
|
|
||||||
List,
|
|
||||||
Play
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onChange(data) {
|
|
||||||
if (data.type === 'add') {
|
|
||||||
this.component = 'Add'
|
|
||||||
this.params = data.params
|
|
||||||
}
|
|
||||||
if (data.type === 'Play') {
|
|
||||||
this.component = 'Play'
|
|
||||||
this.params = data.params
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.type == 'list') {
|
|
||||||
this.component = 'List'
|
|
||||||
this.params = data.params
|
|
||||||
|
|
||||||
this.$nextTick(() => {
|
|
||||||
if (data.isRefresh) {
|
|
||||||
this.$refs.component.getList()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.AppMediaManage {
|
|
||||||
height: 100%;
|
|
||||||
background: #f3f6f9;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,189 +0,0 @@
|
|||||||
<template>
|
|
||||||
<section style="height: 100%">
|
|
||||||
<ai-detail class="Add">
|
|
||||||
<!-- 返回按钮 -->
|
|
||||||
<template #title>
|
|
||||||
<ai-title title="添加媒资信息" isShowBack isShowBottomBorder @onBackClick="cancel(false)"></ai-title>
|
|
||||||
</template>
|
|
||||||
<template #content>
|
|
||||||
<el-form :model="formData" :rules="formRules" ref="ruleForm" label-width="150px" label-suffix=":" align-items="center">
|
|
||||||
<ai-bar title="基础信息"></ai-bar>
|
|
||||||
<div class="flex">
|
|
||||||
<el-form-item label="媒资类型" prop="type" class="buildingTypes">
|
|
||||||
<el-radio-group v-model="formData.type">
|
|
||||||
<el-radio label='1'>音频广播</el-radio>
|
|
||||||
<el-radio label='3'>文本广播</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="媒资名称" prop="name" class="buildingTypes">
|
|
||||||
<el-input size="small" v-model="formData.name" placeholder="请输入" maxlength="30" show-word-limit></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="文本内容" prop="content" class="buildingTypes" v-if="formData.type == 3">
|
|
||||||
<el-input size="small" type="textarea" :rows="2" v-model="formData.content" placeholder="请输入" maxlength="12000" show-word-limit></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="上传音频" prop="file" class="buildingTypes" v-if="formData.type == 1">
|
|
||||||
<ai-uploader
|
|
||||||
:isShowTip="true"
|
|
||||||
:instance="instance"
|
|
||||||
v-model="formData.file"
|
|
||||||
fileType="file"
|
|
||||||
acceptType=".mp3"
|
|
||||||
:limit="1">
|
|
||||||
<template slot="tips">最多上传1个附件,单个文件最大10MB<br/>支持.mp3格式
|
|
||||||
</template>
|
|
||||||
</ai-uploader>
|
|
||||||
<ai-audio :src="formData.file[0].url" style="width: 40px;height: 40px;margin-top:20px;" v-if="formData.file.length"></ai-audio>
|
|
||||||
</el-form-item>
|
|
||||||
</div>
|
|
||||||
</el-form>
|
|
||||||
</template>
|
|
||||||
<template #footer>
|
|
||||||
<el-button @click="cancel">取消</el-button>
|
|
||||||
<el-button type="primary" @click="confirm()">提交</el-button>
|
|
||||||
</template>
|
|
||||||
</ai-detail>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapState } from 'vuex'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'Add',
|
|
||||||
components: {},
|
|
||||||
props: {
|
|
||||||
dict: Object,
|
|
||||||
params: Object,
|
|
||||||
instance: Function,
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
formData: {
|
|
||||||
type: '1',
|
|
||||||
name: '',
|
|
||||||
content: '',
|
|
||||||
file: [],
|
|
||||||
url: ''
|
|
||||||
},
|
|
||||||
formRules: {
|
|
||||||
name: [
|
|
||||||
{ required: true, message: '请输入媒资名称', trigger: 'change' }
|
|
||||||
],
|
|
||||||
content: [
|
|
||||||
{ required: true, message: '请输入文本内容', trigger: 'change' }
|
|
||||||
],
|
|
||||||
file: [
|
|
||||||
{ required: true, message: '请上传音频', trigger: 'change' }
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapState(['user']),
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.instance.defaults.timeout = 6000000
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
confirm() {
|
|
||||||
this.$refs['ruleForm'].validate((valid) => {
|
|
||||||
if (valid) {
|
|
||||||
if(this.formData.file.length) {
|
|
||||||
this.formData.url = this.formData.file[0].url
|
|
||||||
}
|
|
||||||
this.instance.post(`/app/appdlbresource/addResource`, {...this.formData}).then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.$message.success('提交成功')
|
|
||||||
setTimeout(() => {
|
|
||||||
this.cancel(true)
|
|
||||||
}, 1000)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// 返回按钮
|
|
||||||
cancel(isRefresh) {
|
|
||||||
this.$emit('change', {
|
|
||||||
type: 'list',
|
|
||||||
isRefresh: !!isRefresh,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.Add {
|
|
||||||
height: 100%;
|
|
||||||
.ai-detail__title {
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
.ai-detail__content {
|
|
||||||
.ai-detail__content--wrapper {
|
|
||||||
.el-form {
|
|
||||||
background-color: #fff;
|
|
||||||
padding: 0 60px;
|
|
||||||
.flex {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
justify-content: space-between;
|
|
||||||
.el-form-item {
|
|
||||||
width: 48%;
|
|
||||||
}
|
|
||||||
.buildingTypes {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .mapDialog {
|
|
||||||
.el-dialog__body {
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
.ai-dialog__content {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ai-dialog__content--wrapper {
|
|
||||||
padding: 0 !important;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
#map {
|
|
||||||
width: 100%;
|
|
||||||
height: 420px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.searchPlaceInput {
|
|
||||||
position: absolute;
|
|
||||||
width: 250px;
|
|
||||||
top: 30px;
|
|
||||||
left: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#searchPlaceOutput {
|
|
||||||
position: absolute;
|
|
||||||
width: 250px;
|
|
||||||
left: 25px;
|
|
||||||
height: initial;
|
|
||||||
top: 80px;
|
|
||||||
background: white;
|
|
||||||
z-index: 250;
|
|
||||||
max-height: 300px;
|
|
||||||
overflow-y: auto;
|
|
||||||
|
|
||||||
.auto-item {
|
|
||||||
text-align: left;
|
|
||||||
font-size: 14px;
|
|
||||||
padding: 8px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,188 +0,0 @@
|
|||||||
<template>
|
|
||||||
<section class="AppPetitionManage">
|
|
||||||
<ai-list>
|
|
||||||
<ai-title slot="title" title="媒资管理" isShowBottomBorder/>
|
|
||||||
<template #content>
|
|
||||||
<ai-search-bar bottomBorder>
|
|
||||||
<template slot="left">
|
|
||||||
<ai-select v-model="search.type" placeholder="媒资类型" clearable :selectList="$dict.getDict('dlbResourceType')"
|
|
||||||
@change=";(page.current = 1), getList()"></ai-select>
|
|
||||||
</template>
|
|
||||||
<template slot="right">
|
|
||||||
<el-input v-model="search.name" size="small" placeholder="媒资名称" clearable
|
|
||||||
@keyup.enter.native=";(page.current = 1), getList()"
|
|
||||||
@clear=";(page.current = 1), (search.name = ''), getList()" suffix-icon="iconfont iconSearch"/>
|
|
||||||
</template>
|
|
||||||
</ai-search-bar>
|
|
||||||
<ai-search-bar class="ai-search-ba mar-t10">
|
|
||||||
<template slot="left">
|
|
||||||
<el-button icon="iconfont iconAdd" type="primary" size="small" @click="onAdd('')">添加</el-button>
|
|
||||||
<el-button icon="iconfont iconDelete" size="small" @click="removeAll" :disabled="ids.length == 0">删除
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
</ai-search-bar>
|
|
||||||
<ai-table :tableData="tableData" :col-configs="colConfigs" :total="total" ref="aitableex"
|
|
||||||
:current.sync="page.current" :size.sync="page.size" @getList="getList"
|
|
||||||
@selection-change="(v) => (ids = v.map((e) => e.id))">
|
|
||||||
<el-table-column slot="content" label="内容" width="200" show-overflow-tooltip>
|
|
||||||
<template slot-scope="{ row }">
|
|
||||||
<span type="text" v-if="row.type == 3">{{ row.content }}</span>
|
|
||||||
<ai-audio v-else-if="row.type == 1 && row.url" :src="row.url" skin="flat"/>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column slot="options" label="操作" align="center" width="180" fixed="right">
|
|
||||||
<div class="table-options" slot-scope="{ row }">
|
|
||||||
<el-button type="text" @click="play(row.id)">播发</el-button>
|
|
||||||
<el-button type="text" @click="remove(row.id)">删除</el-button>
|
|
||||||
</div>
|
|
||||||
</el-table-column>
|
|
||||||
</ai-table>
|
|
||||||
</template>
|
|
||||||
</ai-list>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {mapState} from 'vuex'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'List',
|
|
||||||
props: {
|
|
||||||
dict: Object,
|
|
||||||
instance: Function,
|
|
||||||
params: Object,
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
isAdd: false,
|
|
||||||
page: {
|
|
||||||
current: 1,
|
|
||||||
size: 10,
|
|
||||||
},
|
|
||||||
total: 0,
|
|
||||||
search: {
|
|
||||||
type: '',
|
|
||||||
name: '',
|
|
||||||
},
|
|
||||||
id: '',
|
|
||||||
ids: [],
|
|
||||||
colConfigs: [
|
|
||||||
{type: 'selection', width: 100, align: 'center'},
|
|
||||||
{
|
|
||||||
prop: 'name',
|
|
||||||
label: '媒资名称',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
prop: 'type',
|
|
||||||
label: '媒资类型',
|
|
||||||
width: '100',
|
|
||||||
align: 'center',
|
|
||||||
render: (h, {row}) => {
|
|
||||||
return h('span', null, this.dict.getLabel('dlbResourceType', row.type))
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
slot: 'content',
|
|
||||||
},
|
|
||||||
{prop: 'createTime', label: '创建时间', align: 'center'},
|
|
||||||
{
|
|
||||||
prop: 'createUserName',
|
|
||||||
label: '创建人',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
// { prop: 'liveBuildingArea', label: '状态', align: 'center',width: 120 },
|
|
||||||
// { prop: 'liveBuildingArea', label: '发布次数', align: 'center',width: 120 },
|
|
||||||
{
|
|
||||||
slot: 'options',
|
|
||||||
label: '操作',
|
|
||||||
align: 'center',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
tableData: [],
|
|
||||||
areaId: '',
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
|
||||||
...mapState(['user']),
|
|
||||||
param() {
|
|
||||||
return {
|
|
||||||
...this.search,
|
|
||||||
areaId: this.user.info?.areaId,
|
|
||||||
ids: this.ids,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.dict.load('dlbResourceType').then(() => {
|
|
||||||
this.getList()
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
getList() {
|
|
||||||
this.instance
|
|
||||||
.post(`/app/appdlbresource/list`, null, {
|
|
||||||
params: {
|
|
||||||
...this.page,
|
|
||||||
...this.search,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.tableData = res.data.records
|
|
||||||
this.total = res.data.total
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
play (id) {
|
|
||||||
this.$emit('change', {
|
|
||||||
type: 'Play',
|
|
||||||
params: {
|
|
||||||
id: id || ''
|
|
||||||
},
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// 添加
|
|
||||||
onAdd(id) {
|
|
||||||
this.$emit('change', {
|
|
||||||
type: 'add',
|
|
||||||
params: {
|
|
||||||
id: id || '',
|
|
||||||
areaId: this.areaId,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
// 删除
|
|
||||||
remove(id) {
|
|
||||||
this.$confirm('确定删除该数据?').then(() => {
|
|
||||||
this.instance.post(`/app/appdlbresource/delete?id=${id}`).then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.$message.success('删除成功!')
|
|
||||||
this.getList()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
removeAll() {
|
|
||||||
var id = this.ids.join(',')
|
|
||||||
this.remove(id)
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.AppPetitionManage {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
.mar-t10 {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,254 +0,0 @@
|
|||||||
<template>
|
|
||||||
<ai-detail>
|
|
||||||
<template #title>
|
|
||||||
<ai-title title="添加广播" isShowBack isShowBottomBorder @onBackClick="cancel(false)"></ai-title>
|
|
||||||
</template>
|
|
||||||
<template #content>
|
|
||||||
<ai-card title="基础信息">
|
|
||||||
<template #content>
|
|
||||||
<el-form class="ai-form" :model="formData" :rules="formRules" ref="ruleForm" label-width="120px">
|
|
||||||
<el-form-item label="播发内容" prop="mediaId">
|
|
||||||
<ai-select v-model="formData.mediaId" placeholder="播发内容" clearable :selectList="mediaList"></ai-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="播放设备" prop="serialNo">
|
|
||||||
<ai-select v-model="formData.serialNo" placeholder="播放设备" clearable
|
|
||||||
:selectList="equipmentList"></ai-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="播发级别" prop="messageLevel">
|
|
||||||
<ai-select v-model="formData.messageLevel" placeholder="播发级别" clearable
|
|
||||||
:selectList="$dict.getDict('dlbMessageUrgency')"></ai-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="播放方式" prop="taskType" class="buildingTypes">
|
|
||||||
<el-radio-group v-model="formData.taskType">
|
|
||||||
<el-radio label="0">立即播放</el-radio>
|
|
||||||
<el-radio label="1">定时播放</el-radio>
|
|
||||||
</el-radio-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="定时策略" prop="cyclingType" v-if="formData.taskType != 0">
|
|
||||||
<ai-select v-model="formData.cyclingType" placeholder="定时策略" clearable
|
|
||||||
:selectList="$dict.getDict('dlbDyclingType')"></ai-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="播放天数" prop="checkList" class="buildingTypes"
|
|
||||||
v-if="formData.taskType != 0 && formData.cyclingType == 2">
|
|
||||||
<el-checkbox-group v-model="formData.checkList">
|
|
||||||
<el-checkbox label="1">每周一</el-checkbox>
|
|
||||||
<el-checkbox label="2">每周二</el-checkbox>
|
|
||||||
<el-checkbox label="3">每周三</el-checkbox>
|
|
||||||
<el-checkbox label="4">每周四</el-checkbox>
|
|
||||||
<el-checkbox label="5">每周五</el-checkbox>
|
|
||||||
<el-checkbox label="6">每周六</el-checkbox>
|
|
||||||
<el-checkbox label="7">每周日</el-checkbox>
|
|
||||||
</el-checkbox-group>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="播放天数" prop="broadcastDay" v-if="formData.taskType != 0 && formData.cyclingType == 3">
|
|
||||||
<el-input v-model="formData.broadcastDay" placeholder="播放天数" clearable size="small"
|
|
||||||
maxlength="4"></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="开始日期" prop="startDate" v-if="formData.taskType != 0">
|
|
||||||
<el-date-picker v-model="formData.startDate" type="date" placeholder="选择日期" size="small"
|
|
||||||
value-format="yyyy-MM-dd"></el-date-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="开始时间" prop="startTime" v-if="formData.taskType != 0">
|
|
||||||
<el-time-picker v-model="formData.startTime" placeholder="开始时间" size="small"
|
|
||||||
:picker-options="{ start: newDate, minTime: newDate}"
|
|
||||||
value-format="HH:mm:ss"></el-time-picker>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="结束时间" prop="endTime" v-if="formData.taskType != 0">
|
|
||||||
<el-time-picker v-model="formData.endTime" placeholder="结束时间" size="small"
|
|
||||||
:picker-options="{ start: formData.startTime, minTime: formData.startTime}"
|
|
||||||
value-format="HH:mm:ss"></el-time-picker>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</template>
|
|
||||||
</ai-card>
|
|
||||||
</template>
|
|
||||||
<template #footer>
|
|
||||||
<el-button @click="cancel">取消</el-button>
|
|
||||||
<el-button type="primary" @click="confirm()">提交</el-button>
|
|
||||||
</template>
|
|
||||||
</ai-detail>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {mapState} from 'vuex'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'Add',
|
|
||||||
components: {},
|
|
||||||
props: {
|
|
||||||
dict: Object,
|
|
||||||
params: Object,
|
|
||||||
instance: Function,
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
let startTimePass = (rule, value, callback) => {
|
|
||||||
if (value) {
|
|
||||||
var myDate = new Date();
|
|
||||||
var time = myDate.getHours() + ':' + myDate.getMinutes() + ':' + myDate.getSeconds()
|
|
||||||
if (this.timeToSec(value) - this.timeToSec(time) > 0) {
|
|
||||||
callback()
|
|
||||||
} else {
|
|
||||||
callback(new Error('开始时间要大于当前时间'));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
callback(new Error('请选择开始时间'));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let endTimePass = (rule, value, callback) => {
|
|
||||||
if (value) {
|
|
||||||
if (this.timeToSec(value) - this.timeToSec(this.formData.startTime) > 0) {
|
|
||||||
callback()
|
|
||||||
} else {
|
|
||||||
callback(new Error('结束时间要大于开始时间'));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
callback(new Error('请选择结束时间'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
formData: {
|
|
||||||
mediaId: '',
|
|
||||||
serialNo: '',
|
|
||||||
messageLevel: '',
|
|
||||||
cyclingType: '',
|
|
||||||
taskType: '0',
|
|
||||||
cyclingDate: '',
|
|
||||||
broadcastDay: '',
|
|
||||||
startDate: '',
|
|
||||||
startTime: '',
|
|
||||||
endTime: '',
|
|
||||||
checkList: []
|
|
||||||
},
|
|
||||||
formRules: {
|
|
||||||
mediaId: [
|
|
||||||
{required: true, message: '请选择播发内容', trigger: 'change'}
|
|
||||||
],
|
|
||||||
serialNo: [
|
|
||||||
{required: true, message: '请选择播放设备', trigger: 'change'}
|
|
||||||
],
|
|
||||||
messageLevel: [
|
|
||||||
{required: true, message: '请选择播发级别', trigger: 'change'}
|
|
||||||
],
|
|
||||||
cyclingType: [
|
|
||||||
{required: true, message: '请选择定时策略', trigger: 'change'}
|
|
||||||
],
|
|
||||||
taskType: [
|
|
||||||
{required: true, message: '请选择播放方式', trigger: 'change'}
|
|
||||||
],
|
|
||||||
broadcastDay: [
|
|
||||||
{required: true, message: '请输入播放天数', trigger: 'change'}
|
|
||||||
],
|
|
||||||
startDate: [
|
|
||||||
{required: true, message: '请选择开始日期', trigger: 'change'}
|
|
||||||
],
|
|
||||||
startTime: [
|
|
||||||
{required: true, validator: startTimePass, trigger: 'change'}
|
|
||||||
],
|
|
||||||
endTime: [
|
|
||||||
{required: true, validator: endTimePass, trigger: 'change'}
|
|
||||||
],
|
|
||||||
checkList: [
|
|
||||||
{required: true, message: '播放天数', trigger: 'change'}
|
|
||||||
],
|
|
||||||
},
|
|
||||||
mediaList: [],
|
|
||||||
equipmentList: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapState(['user']),
|
|
||||||
|
|
||||||
isEdit() {
|
|
||||||
return !!this.params.id
|
|
||||||
},
|
|
||||||
newDate() {
|
|
||||||
var myDate = new Date();
|
|
||||||
return myDate.getHours() + ':' + myDate.getMinutes() + ':' + myDate.getSeconds()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.dict.load('dlbMessageUrgency', 'dlbBroadTaskType', 'dlbDyclingType')
|
|
||||||
Promise.all([this.getEquipmentList(), this.getMediaList()]).then(() => {
|
|
||||||
this.formData.mediaId = this.params.id
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getMediaList() {
|
|
||||||
return this.instance.post(`/app/appdlbresource/list?current=1&size=10000`).then((res) => {
|
|
||||||
if (res?.data) {
|
|
||||||
this.mediaList = res.data.records?.map((item) => ({
|
|
||||||
dictName: item.name,
|
|
||||||
dictValue: item.id
|
|
||||||
})) || []
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getEquipmentList() {
|
|
||||||
return this.instance.post(`/app/appdlbquipment/getDlbDeviceList?current=1&size=10000&devStatus=5`).then((res) => {
|
|
||||||
if (res?.data) {
|
|
||||||
this.equipmentList = res.data.records?.map((item) => ({
|
|
||||||
dictName: item.deviceName,
|
|
||||||
dictValue: item.serialNo
|
|
||||||
})) || []
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
confirm() {
|
|
||||||
this.$refs['ruleForm'].validate((valid) => {
|
|
||||||
if (valid) {
|
|
||||||
if (this.formData.checkList.length) {
|
|
||||||
this.formData.cyclingDate = this.formData.checkList.join(',')
|
|
||||||
}
|
|
||||||
this.formData.coverageType = '4'
|
|
||||||
this.formData.id = ''
|
|
||||||
this.instance.post(`/app/appzyvideobroadcast/play`, {
|
|
||||||
...this.formData,
|
|
||||||
})
|
|
||||||
.then((res) => {
|
|
||||||
if (res.code == 0) {
|
|
||||||
this.$message.success('提交成功')
|
|
||||||
setTimeout(() => {
|
|
||||||
this.cancel(true)
|
|
||||||
}, 1000)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getDetail() {
|
|
||||||
this.instance.post(`/app/appzyvideobroadcast/queryDetailById?id=${this.params.id}`).then((res) => {
|
|
||||||
if (res?.data) {
|
|
||||||
this.formData = {
|
|
||||||
...res.data,
|
|
||||||
checkList: []
|
|
||||||
}
|
|
||||||
this.formData.mediaId = String(this.formData.mediaId)
|
|
||||||
this.formData.cyclingType = String(this.formData.cyclingType)
|
|
||||||
if (this.formData.cyclingDate) {
|
|
||||||
this.formData.checkList = this.formData.cyclingDate.split(',')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
timeToSec(time) {
|
|
||||||
var s = "";
|
|
||||||
var hour = time.split(":")[0];
|
|
||||||
var min = time.split(":")[1];
|
|
||||||
var second = time.split(":")[2];
|
|
||||||
s = Number(hour * 3600) + Number(min * 60) + Number(second)
|
|
||||||
return s;
|
|
||||||
},
|
|
||||||
// 返回按钮
|
|
||||||
cancel(isRefresh) {
|
|
||||||
this.$emit('change', {
|
|
||||||
type: 'list',
|
|
||||||
isRefresh: !!isRefresh,
|
|
||||||
})
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
|
|
||||||
</style>
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
<template>
|
|
||||||
<section class="AppMonitorDevice">
|
|
||||||
<ai-list>
|
|
||||||
<ai-title slot="title" title="监控设备管理" isShowBottomBorder/>
|
|
||||||
<template #content>
|
|
||||||
<ai-search-bar>
|
|
||||||
<template #right>
|
|
||||||
<el-input prefix-icon="iconfont iconSearch" v-model="search.title" placeholder="设备名、MAC号" clearable
|
|
||||||
@change="page.current=1,getTableData()" size="small"/>
|
|
||||||
<el-button type="primary" icon="iconfont iconSearch" @click="page.current=1,getTableData()">查询</el-button>
|
|
||||||
<el-button icon="iconfont iconResetting" @click="search={},page.current=1,getTableData()">重置</el-button>
|
|
||||||
</template>
|
|
||||||
</ai-search-bar>
|
|
||||||
<ai-table :tableData="tableData" :colConfigs="colConfigs" :total="page.total" :current.sync="page.current"
|
|
||||||
:size.sync="page.size" @getList="getTableData">
|
|
||||||
<el-table-column label="操作" slot="options" align="center">
|
|
||||||
<el-row type="flex" slot-scope="{row}" align="middle" justify="center">
|
|
||||||
<ai-area v-model="row.areaId" :instance="instance" :inputClicker="false" customClicker
|
|
||||||
@change="handleSubmit(row)">
|
|
||||||
<el-button type="text">绑定</el-button>
|
|
||||||
</ai-area>
|
|
||||||
<el-button type="text" @click="handleLocate(row)">标绘</el-button>
|
|
||||||
<div/>
|
|
||||||
<el-button type="text" @click="handleShow(row)">设置</el-button>
|
|
||||||
</el-row>
|
|
||||||
</el-table-column>
|
|
||||||
</ai-table>
|
|
||||||
</template>
|
|
||||||
</ai-list>
|
|
||||||
<locate-dialog v-model="locate" :ins="instance" @confirm="v=>handleLocate(detail,v)"/>
|
|
||||||
<setting-dialog v-model="dialog" :ins="instance"/>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import LocateDialog from "../components/locateDialog";
|
|
||||||
import SettingDialog from "../components/settingDialog";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "AppMonitorDevice",
|
|
||||||
components: {SettingDialog, LocateDialog},
|
|
||||||
label: "监控设备管理",
|
|
||||||
props: {
|
|
||||||
instance: Function,
|
|
||||||
dict: Object,
|
|
||||||
permissions: Function
|
|
||||||
},
|
|
||||||
provide() {
|
|
||||||
return {
|
|
||||||
device: this
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
colConfigs() {
|
|
||||||
return [
|
|
||||||
{type: 'selection'},
|
|
||||||
{label: "设备名", prop: "deviceName"},
|
|
||||||
{label: "上级归属", prop: "areaName"},
|
|
||||||
{label: "设备型号", prop: "devModel"},
|
|
||||||
{label: "MAC号", prop: "devMac"},
|
|
||||||
{label: "标绘状态", render: (h, {row}) => h('span', null, row?.lat ? '已绑定' : '待绑定')},
|
|
||||||
{slot: "options"}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
isDetail() {
|
|
||||||
return !!this.$route.query?.id
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
search: {startTime: null, endTime: null, title: ""},
|
|
||||||
page: {current: 1, size: 10, total: 0},
|
|
||||||
tableData: [],
|
|
||||||
locate: false,
|
|
||||||
dialog: false,
|
|
||||||
detail: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.dict.load("zyDeviceBindStatus")
|
|
||||||
if (this.isDetail) {
|
|
||||||
//TODO 待补充
|
|
||||||
} else this.getTableData()
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getTableData() {
|
|
||||||
this.instance.post("/app/appzyvideoequipment/getVideoList", null, {
|
|
||||||
params: {...this.search, ...this.page}
|
|
||||||
}).then(res => {
|
|
||||||
if (res?.data) {
|
|
||||||
this.tableData = res.data.records
|
|
||||||
this.page.total = res.data.total
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
handleSubmit(row) {
|
|
||||||
return this.instance.post("/app/appzyvideoequipment/addOrUpdate", {
|
|
||||||
...row, id: row.deviceId
|
|
||||||
}).then(res => {
|
|
||||||
if (res?.code == 0) {
|
|
||||||
this.$message.success("提交成功!")
|
|
||||||
this.getTableData()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
handleShow(row) {
|
|
||||||
this.dialog = true
|
|
||||||
this.detail = row
|
|
||||||
},
|
|
||||||
handleLocate(row, locate) {
|
|
||||||
if (locate) {
|
|
||||||
let {lat, lng} = locate.location
|
|
||||||
this.handleSubmit({...row, lat, lng}).then(() => {
|
|
||||||
this.locate = false
|
|
||||||
this.getTableData()
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.locate = true
|
|
||||||
this.detail = row
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.AppMonitorDevice {
|
|
||||||
::v-deep .AiSearchBar {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,284 +0,0 @@
|
|||||||
<template>
|
|
||||||
<section class="AppMonitorManage">
|
|
||||||
<device-slider :show.sync="slider" :ins="instance" :dict="dict" @select="handleSelectMonitor"
|
|
||||||
:render-item="renderTreeItem" ref="DeviceSlider"/>
|
|
||||||
<div class="monitorPane">
|
|
||||||
<div class="headerBar">
|
|
||||||
<el-select default-first-option size="small" v-model="splitScreen">
|
|
||||||
<i slot="prefix" class="iconfont iconjdq_led_Led1"/>
|
|
||||||
<el-option v-for="(op,i) in splitOps" :key="i" v-bind="op"/>
|
|
||||||
</el-select>
|
|
||||||
<!-- <el-button icon="el-icon-full-screen" @click="handleFullscreen">全屏</el-button>-->
|
|
||||||
</div>
|
|
||||||
<div class="videoList">
|
|
||||||
<div class="videoBox" v-for="(m,i) in monitors" :key="i" :style="currentSplitStyle">
|
|
||||||
<iframe :src="m.url" allow="autoplay *; microphone *; fullscreen *" allowfullscreen allowtransparency
|
|
||||||
allowusermedia frameBorder="no"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<ai-dialog title="修改名称" :visible.sync="dialog" width="500px" @onConfirm="handleSubmit(selected)"
|
|
||||||
@closed="selected={}">
|
|
||||||
<el-form ref="form" :model="selected" label-width="80px" size="small" :rules="rules">
|
|
||||||
<el-form-item label="设备名称" prop="name">
|
|
||||||
<el-input v-model="selected.name" clearable/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</ai-dialog>
|
|
||||||
<locate-dialog v-model="locate" :ins="instance" @confirm="v=>handleLocate(selected,v)"/>
|
|
||||||
<ai-area custom-clicker :input-clicker="false" v-model="selected.areaId" :instance="instance" ref="BindArea"
|
|
||||||
@change="handleSubmit(selected)"/>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import DeviceSlider from "../components/deviceSlider";
|
|
||||||
import LocateDialog from "../components/locateDialog";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "AppMonitorManage",
|
|
||||||
components: {LocateDialog, DeviceSlider},
|
|
||||||
label: "监控实况",
|
|
||||||
props: {
|
|
||||||
instance: Function,
|
|
||||||
dict: Object,
|
|
||||||
permissions: Function
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
splitOps() {
|
|
||||||
return [
|
|
||||||
{label: "单分屏", value: 1, per: "100%"},
|
|
||||||
{label: "四分屏", value: 4, per: "49%"},
|
|
||||||
{label: "九分屏", value: 9, per: "32%"}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
currentSplitStyle() {
|
|
||||||
let per = this.splitOps.find(e => e.value == this.splitScreen)?.per || "100%"
|
|
||||||
return {width: per, height: per}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
slider: true,
|
|
||||||
fullscreen: false,
|
|
||||||
splitScreen: 1,
|
|
||||||
monitors: [],
|
|
||||||
dialog: false,
|
|
||||||
locate: false,
|
|
||||||
selected: {},
|
|
||||||
rules: {
|
|
||||||
name: [{required: true, message: "请填写 设备名称"}]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handleFullscreen() {
|
|
||||||
this.fullscreen = !this.fullscreen
|
|
||||||
this.$fullscreen(this.fullscreen)
|
|
||||||
},
|
|
||||||
handleSelectMonitor(monitor) {
|
|
||||||
let {id} = monitor,
|
|
||||||
index = this.monitors.findIndex(e => e.id == id)
|
|
||||||
if (index > -1) {
|
|
||||||
this.monitors.splice(index, 1)
|
|
||||||
this.monitors.map((e, i) => {
|
|
||||||
if (i > index) {
|
|
||||||
this.showMonitor(e, true)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else if (this.monitors.length >= this.splitScreen && this.splitScreen > 1) {
|
|
||||||
this.$message.warning("可分屏监控已满,请先取消其他的监控")
|
|
||||||
} else {
|
|
||||||
this.showMonitor(monitor)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
showMonitor(monitor, refresh = false) {
|
|
||||||
let {id: deviceId} = monitor
|
|
||||||
deviceId && this.instance.post("/app/appzyvideoequipment/getWebSdkUrl", null, {
|
|
||||||
params: {deviceId}
|
|
||||||
}).then(res => {
|
|
||||||
if (res?.data) {
|
|
||||||
let data = JSON.parse(res.data)
|
|
||||||
if (refresh) {
|
|
||||||
monitor.url = data.url
|
|
||||||
} else if (this.splitScreen == 1) {
|
|
||||||
this.monitors = [{...monitor, ...data}]
|
|
||||||
} else {
|
|
||||||
this.monitors.push({...monitor, ...data})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
renderTreeItem: function (h, {node, data}) {
|
|
||||||
let show = data.deviceStatus==1 ? 'show' : ''
|
|
||||||
if (node.isLeaf) {
|
|
||||||
return (
|
|
||||||
<div class="flexRow">
|
|
||||||
<i class={['iconfont', 'iconshipinjiankong', show]}/>
|
|
||||||
<div>{node.label}</div>
|
|
||||||
<el-dropdown class="menuBtn" onCommand={e => this.handleSliderOption(e, data)}>
|
|
||||||
<i class="iconfont iconMore"/>
|
|
||||||
<el-dropdown-menu slot="dropdown">
|
|
||||||
<el-dropdown-item command="edit">修改名称</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="area">行政地区</el-dropdown-item>
|
|
||||||
<el-dropdown-item command="locate">地图标绘</el-dropdown-item>
|
|
||||||
</el-dropdown-menu>
|
|
||||||
</el-dropdown>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
} else return (
|
|
||||||
<div class="flexRow">
|
|
||||||
<div>{node.label}</div>
|
|
||||||
{data.id != 'no_area' ? <div class="sta">
|
|
||||||
<p>{data.online || 0}</p>/{data.sum || 0}
|
|
||||||
</div>
|
|
||||||
: <div/>}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
},
|
|
||||||
handleSliderOption(command, data) {
|
|
||||||
this.selected = JSON.parse(JSON.stringify({...data, command}))
|
|
||||||
if (command == "edit") {//修改名称
|
|
||||||
this.dialog = true
|
|
||||||
} else if (command == "area") {//绑定areaId
|
|
||||||
this.$refs.BindArea?.chooseArea()
|
|
||||||
} else if (command == "locate") {//地图标绘
|
|
||||||
this.locate = true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleSubmit(row) {
|
|
||||||
delete row.createTime
|
|
||||||
return this.instance.post("/app/appzyvideoequipment/addOrUpdate", {
|
|
||||||
...row
|
|
||||||
}).then(res => {
|
|
||||||
if (res?.code == 0) {
|
|
||||||
this.$message.success("提交成功!")
|
|
||||||
this.dialog = false
|
|
||||||
this.$refs.DeviceSlider?.getDevices()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
handleLocate(row, locate) {
|
|
||||||
if (locate) {
|
|
||||||
let {lat, lng} = locate.location
|
|
||||||
this.handleSubmit({...row, lat, lng}).then(() => {
|
|
||||||
this.locate = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
this.monitors = []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.AppMonitorManage {
|
|
||||||
display: flex;
|
|
||||||
background: #202330;
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
.monitorPane {
|
|
||||||
color: #fff;
|
|
||||||
flex: 1;
|
|
||||||
min-width: 0;
|
|
||||||
padding: 20px 20px 20px 4px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
::v-deep .headerBar {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: flex-end;
|
|
||||||
gap: 8px;
|
|
||||||
margin-bottom: 24px;
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
color: #fff;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-input__icon {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-input__inner, .el-button {
|
|
||||||
color: #fff;
|
|
||||||
max-width: 100px;
|
|
||||||
background: #2C2F3E;
|
|
||||||
border: none;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: #26f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.videoList {
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-start;
|
|
||||||
align-content: flex-start;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
flex: 1;
|
|
||||||
min-height: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
gap: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.videoBox {
|
|
||||||
background: #000;
|
|
||||||
flex-shrink: 0;
|
|
||||||
|
|
||||||
iframe {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep.el-tree-node__content:hover {
|
|
||||||
.menuBtn {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .flexRow {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
font-size: 14px;
|
|
||||||
color: #fff;
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
color: #89b;
|
|
||||||
|
|
||||||
&.show {
|
|
||||||
color: #19D286;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.sta {
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
min-width: 0;
|
|
||||||
|
|
||||||
& > p {
|
|
||||||
color: #19D286;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.menuBtn {
|
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
right: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,211 +0,0 @@
|
|||||||
<template>
|
|
||||||
<section class="AppMonitorMap">
|
|
||||||
<device-slider :show.sync="slider" :ins="instance" :dict="dict" @list="v=>list=v" @select="markerClickEvent"/>
|
|
||||||
<div id="amap"/>
|
|
||||||
<div ref="selectedInfoWin" class="selected">
|
|
||||||
<b>{{ selected.deviceName }}</b>
|
|
||||||
<div>{{ selected.lng }},{{ selected.lat }}</div>
|
|
||||||
<div v-if="selected.address">{{ selected.address }}</div>
|
|
||||||
<div btn @click="handleShowMonitor">查看监控</div>
|
|
||||||
</div>
|
|
||||||
<el-dialog class="monitorDialog" :modal="false" :visible.sync="dialog" :title="selected.deviceName||'视频监控'"
|
|
||||||
width="640px" @closed="monitor=''">
|
|
||||||
<iframe v-if="monitor" :src="monitor" allow="autoplay *; microphone *; fullscreen *" allowfullscreen
|
|
||||||
allowtransparency allowusermedia frameBorder="no"/>
|
|
||||||
</el-dialog>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import DeviceSlider from "../components/deviceSlider";
|
|
||||||
import AMapLoader from "@amap/amap-jsapi-loader";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "AppMonitorMap",
|
|
||||||
components: {DeviceSlider},
|
|
||||||
label: "监控地图",
|
|
||||||
props: {
|
|
||||||
instance: Function,
|
|
||||||
dict: Object,
|
|
||||||
permissions: Function
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
slider: true,
|
|
||||||
AMap: null,
|
|
||||||
map: null,
|
|
||||||
selected: {},
|
|
||||||
list: [],
|
|
||||||
deviceToken: "",
|
|
||||||
dialog: false,
|
|
||||||
monitor: ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
list: {
|
|
||||||
immediate: true,
|
|
||||||
handler(v) {
|
|
||||||
if (v.length > 0) {
|
|
||||||
this.renderDevicesOnMap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
initMap() {
|
|
||||||
return new Promise(resolve => AMapLoader.load({
|
|
||||||
key: "b553334ba34f7ac3cd09df9bc8b539dc",
|
|
||||||
version: '2.0',
|
|
||||||
plugins: ['AMap.Marker', 'AMap.PlaceSearch'],
|
|
||||||
}).then(AMap => {
|
|
||||||
this.AMap = AMap
|
|
||||||
this.map = new this.AMap.Map('amap', {
|
|
||||||
zoom: 14,
|
|
||||||
})
|
|
||||||
resolve()
|
|
||||||
}))
|
|
||||||
},
|
|
||||||
renderDevicesOnMap() {
|
|
||||||
this.list?.map(e => {
|
|
||||||
if (this.AMap && e?.lat) {
|
|
||||||
e.marker = new this.AMap.Marker({
|
|
||||||
icon: this.$cdn + 'monitor/camera.png',
|
|
||||||
position: new this.AMap.LngLat(e.lng, e.lat)
|
|
||||||
}).on('click', () => this.markerClickEvent(e))
|
|
||||||
this.map.add(e.marker)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
markerClickEvent(device) {
|
|
||||||
if (device?.marker) {
|
|
||||||
this.map?.setCenter(new this.AMap.LngLat(device.lng, device.lat))
|
|
||||||
device.marker.setIcon(this.$cdn + 'monitor/cameraSelected.png')
|
|
||||||
this.selected = device
|
|
||||||
let win = new this.AMap.InfoWindow({
|
|
||||||
isCustom: true,
|
|
||||||
autoMove: true,
|
|
||||||
closeWhenClickMap: true,
|
|
||||||
content: this.$refs.selectedInfoWin
|
|
||||||
}).on('close', () => {
|
|
||||||
device.marker.setIcon(this.$cdn + 'monitor/camera.png')
|
|
||||||
this.selected = {}
|
|
||||||
})
|
|
||||||
win.open(this.map, new this.AMap.LngLat(device.lng, device.lat))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
getDeviceToken() {
|
|
||||||
this.instance.post("/app/appzyvideoequipment/getAppUserToken").then(res => {
|
|
||||||
if (res?.data) {
|
|
||||||
this.deviceToken = res.data
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
handleShowMonitor() {
|
|
||||||
this.dialog = true
|
|
||||||
this.instance.post("/app/appzyvideoequipment/getWebSdkUrl", null, {
|
|
||||||
params: {token: this.deviceToken, deviceId: this.selected.deviceId}
|
|
||||||
}).then(res => {
|
|
||||||
if (res?.data) {
|
|
||||||
let data = JSON.parse(res.data)
|
|
||||||
this.monitor = data.url
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.initMap().then(() => setTimeout(() => this.renderDevicesOnMap(), 1000))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.AppMonitorMap {
|
|
||||||
background: #202330;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.deviceSlider {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
z-index: 66;
|
|
||||||
}
|
|
||||||
|
|
||||||
#amap {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected {
|
|
||||||
background: #fff;
|
|
||||||
min-width: 280px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.1);
|
|
||||||
padding: 12px;
|
|
||||||
color: #999;
|
|
||||||
font-size: 12px;
|
|
||||||
|
|
||||||
b {
|
|
||||||
color: #333;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > * + * {
|
|
||||||
margin-top: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div[btn] {
|
|
||||||
cursor: pointer;
|
|
||||||
color: #89b;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .monitorDialog {
|
|
||||||
|
|
||||||
.el-dialog__header {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #FFF;
|
|
||||||
height: 40px;
|
|
||||||
padding: 0 16px;
|
|
||||||
background: linear-gradient(180deg, #313B5B 0%, #1B202F 100%);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
span {
|
|
||||||
color: #fff;
|
|
||||||
flex: 1;
|
|
||||||
min-width: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-dialog__headerbtn {
|
|
||||||
position: relative;
|
|
||||||
top: unset;
|
|
||||||
right: unset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-dialog__body {
|
|
||||||
padding: 0;
|
|
||||||
height: 360px;
|
|
||||||
}
|
|
||||||
|
|
||||||
iframe {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .amap-logo, ::v-deep .amap-copyright {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .amap-marker-label {
|
|
||||||
border-color: transparent;
|
|
||||||
box-shadow: 1px 1px 0 0 rgba(#999, .2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,233 +0,0 @@
|
|||||||
<template>
|
|
||||||
<section class="deviceSlider">
|
|
||||||
<div class="mainPane" v-if="show">
|
|
||||||
<div flex overview>
|
|
||||||
<b>监控设备</b>
|
|
||||||
<div>
|
|
||||||
<div>设备总数:{{ overview.total }}</div>
|
|
||||||
<div flex>在线设备:<p v-text="overview.online"/></div>
|
|
||||||
</div>
|
|
||||||
<el-progress type="circle" :width="40" :percentage="overview.percent" color="#19D286" :stroke-width="4"/>
|
|
||||||
</div>
|
|
||||||
<div flex search>
|
|
||||||
<el-select v-model="search.bind" size="mini" placeholder="全部" clearable @change="onChange">
|
|
||||||
<el-option v-for="(op,i) in dict.getDict('deviceStatus')" :key="i" :value="op.dictValue"
|
|
||||||
:label="op.dictName"/>
|
|
||||||
</el-select>
|
|
||||||
<el-input v-model="search.name" size="mini" placeholder="设备名称" prefix-icon="el-icon-search"
|
|
||||||
@change="handleTreeFilter" clearable/>
|
|
||||||
</div>
|
|
||||||
<div title>设备列表</div>
|
|
||||||
<div fill class="deviceList">
|
|
||||||
<el-scrollbar>
|
|
||||||
<el-tree ref="deviceTree" :data="treeData" :props="propsConfig" @node-click="handleNodeClick"
|
|
||||||
:render-content="renderItem" :filter-node-method="handleFilter"/>
|
|
||||||
</el-scrollbar>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="rightBtn" :class="{show}" @click="handleShow">
|
|
||||||
<i class="iconfont iconArrow_Right"/>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "deviceSlider",
|
|
||||||
props: {
|
|
||||||
show: Boolean,
|
|
||||||
ins: Function,
|
|
||||||
dict: Object,
|
|
||||||
renderItem: Function
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
overview() {
|
|
||||||
let total = this.list?.length || 0,
|
|
||||||
online = this.list?.filter(e => e.deviceStatus == 1)?.length || 0
|
|
||||||
return {
|
|
||||||
total, online,
|
|
||||||
percent: Math.ceil(online / total * 100) || 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
propsConfig() {
|
|
||||||
return {
|
|
||||||
label: 'name',
|
|
||||||
children: 'children'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
treeData() {
|
|
||||||
let {list, noArea, staData} = this
|
|
||||||
let meta = [staData?.reduce((t, e) => {
|
|
||||||
return t.type <= e.type ? t : e
|
|
||||||
}, {name: '读取中...'})]
|
|
||||||
meta.map(p => this.addChild(p, [...staData, ...list].map(s => ({
|
|
||||||
...s,
|
|
||||||
parentId: s.areaId || s.parent_id
|
|
||||||
}))))
|
|
||||||
return [...meta, {
|
|
||||||
id: 'no_area',
|
|
||||||
name: '未知区划',
|
|
||||||
children: noArea
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
list: [],
|
|
||||||
noArea: [],
|
|
||||||
staData: [],
|
|
||||||
name: '',
|
|
||||||
search: {
|
|
||||||
bind: ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handleShow() {
|
|
||||||
this.$emit('update:show', !this.show)
|
|
||||||
},
|
|
||||||
getDevices() {
|
|
||||||
this.ins.post("/app/appzyvideoequipment/tree", null, {
|
|
||||||
params: {size: 999}
|
|
||||||
}).then(res => {
|
|
||||||
if (res?.data) {
|
|
||||||
this.staData = res.data.count
|
|
||||||
this.list = res.data.list
|
|
||||||
this.noArea = res.data.noArea
|
|
||||||
this.$emit('list', this.list)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
handleNodeClick(data) {
|
|
||||||
this.$emit('select', data)
|
|
||||||
},
|
|
||||||
handleFilter(v, data) {
|
|
||||||
if (!v) {
|
|
||||||
return !this.search.bind ? true : data.deviceStatus === this.search.bind
|
|
||||||
}
|
|
||||||
|
|
||||||
return data?.name?.indexOf(v) > -1 && (!this.search.bind ? true : data.deviceStatus === this.search.bind)
|
|
||||||
},
|
|
||||||
handleTreeFilter(v) {
|
|
||||||
this.$refs.deviceTree?.filter(v)
|
|
||||||
},
|
|
||||||
|
|
||||||
onChange () {
|
|
||||||
this.$refs.deviceTree?.filter(this.search.name)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.dict.load("deviceStatus")
|
|
||||||
this.getDevices()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.deviceSlider {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-shrink: 0;
|
|
||||||
color: #fff;
|
|
||||||
|
|
||||||
div[flex] {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
div[fill] {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 0;
|
|
||||||
min-height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mainPane {
|
|
||||||
width: 280px;
|
|
||||||
height: 100%;
|
|
||||||
background: #333C53;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding-top: 16px;
|
|
||||||
overflow: hidden;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
b {
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div[overview], div[search] {
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: 12px;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 0 16px;
|
|
||||||
gap: 4px;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
|
|
||||||
::v-deep.el-input__inner {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
div[title] {
|
|
||||||
height: 28px;
|
|
||||||
background: #3E4A69;
|
|
||||||
padding: 0 16px;
|
|
||||||
line-height: 28px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep.deviceList {
|
|
||||||
padding: 0 8px;
|
|
||||||
|
|
||||||
.el-scrollbar {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
.el-scrollbar__wrap {
|
|
||||||
box-sizing: content-box;
|
|
||||||
padding-bottom: 17px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-progress__text, p {
|
|
||||||
color: #19D286;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-input__inner {
|
|
||||||
background: #282F45;
|
|
||||||
border: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-tree {
|
|
||||||
background: transparent;
|
|
||||||
color: #fff;
|
|
||||||
|
|
||||||
.el-tree-node:focus > .el-tree-node__content, .el-tree-node__content:hover {
|
|
||||||
background: rgba(#fff, .1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-input__icon {
|
|
||||||
color: #89b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.rightBtn {
|
|
||||||
width: 16px;
|
|
||||||
height: 80px;
|
|
||||||
background: url("https://cdn.cunwuyun.cn/monitor/drawerBtn.png");
|
|
||||||
color: #fff;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
transition: transform 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
&.show > .iconfont {
|
|
||||||
transform: rotate(180deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,176 +0,0 @@
|
|||||||
<template>
|
|
||||||
<section class="locateDialog">
|
|
||||||
<ai-dialog :visible.sync="dialog" title="标绘" @closed="$emit('visible',false),selected={}"
|
|
||||||
@opened="$nextTick(()=>initMap())"
|
|
||||||
@onConfirm="handleConfirm">
|
|
||||||
<div id="amap" v-if="dialog"/>
|
|
||||||
<div class="poi">
|
|
||||||
<el-input ref="poiInput" v-model="search" size="small" clearable @change="handleSearch" placeholder="请输入地点"/>
|
|
||||||
</div>
|
|
||||||
<el-form class="selected" v-if="!!selected.location" id="result" size="mini" label-suffix=":"
|
|
||||||
label-position="left">
|
|
||||||
<div class="header">
|
|
||||||
<i class="iconfont iconLocation"/>
|
|
||||||
<span v-html="[selected.location.lng, selected.location.lat].join(',')"/>
|
|
||||||
</div>
|
|
||||||
<el-form-item label="地点">{{ selected.name || "未知地名" }}</el-form-item>
|
|
||||||
<el-form-item label="类型" v-if="!!selected.type">{{ selected.type }}</el-form-item>
|
|
||||||
<el-form-item label="地址" v-if="!!selected.address">{{ selected.address }}</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</ai-dialog>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import AMapLoader from '@amap/amap-jsapi-loader'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "locateDialog",
|
|
||||||
model: {
|
|
||||||
prop: "visible",
|
|
||||||
event: "visible",
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
visible: Boolean
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
dialog: false,
|
|
||||||
search: "",
|
|
||||||
poi: null,
|
|
||||||
map: null,
|
|
||||||
AMap: null,
|
|
||||||
selected: {},
|
|
||||||
geo: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
visible(v) {
|
|
||||||
this.dialog = v
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
initMap() {
|
|
||||||
AMapLoader.load({
|
|
||||||
key: "b553334ba34f7ac3cd09df9bc8b539dc",
|
|
||||||
version: '2.0',
|
|
||||||
plugins: ['AMap.PlaceSearch', 'AMap.Marker', 'AMap.Geolocation'],
|
|
||||||
}).then(AMap => {
|
|
||||||
this.AMap = AMap
|
|
||||||
this.map = new AMap.Map('amap', {
|
|
||||||
zoom: 14,
|
|
||||||
}).on('click', res => {
|
|
||||||
this.map.clearMap()
|
|
||||||
this.selected = {location: res.lnglat}
|
|
||||||
this.poi?.searchNearBy('', res.lnglat, 100)
|
|
||||||
});
|
|
||||||
this.poi = new AMap.PlaceSearch().on('complete', ({poiList}) => {
|
|
||||||
this.map.clearMap()
|
|
||||||
if (poiList?.length > 0) {
|
|
||||||
poiList?.pois?.map(e => {
|
|
||||||
let marker = new AMap.Marker({
|
|
||||||
position: e.location,
|
|
||||||
}).on('click', () => this.selected = e)
|
|
||||||
this.map.add(marker)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
let marker = new AMap.Marker({
|
|
||||||
position: this.selected.location,
|
|
||||||
})
|
|
||||||
this.map.add(marker)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.geo = new AMap.Geolocation({
|
|
||||||
enableHighAccuracy: true,//是否使用高精度定位
|
|
||||||
zoomToAccuracy: true//定位成功后是否自动调整地图视野到定位点
|
|
||||||
})
|
|
||||||
this.map.addControl(this.geo)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
handleSearch(v) {
|
|
||||||
if (v) {
|
|
||||||
this.poi.searchNearBy(v, this.map.getCenter(), 50000)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleConfirm() {
|
|
||||||
if (this.selected?.location) {
|
|
||||||
this.$emit('confirm', this.selected)
|
|
||||||
} else {
|
|
||||||
this.$message.error('请先选择坐标位置')
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.dialog = this.visible
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.locateDialog {
|
|
||||||
::v-deep .el-dialog__body {
|
|
||||||
padding: 0;
|
|
||||||
height: 480px;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.ai-dialog__content--wrapper {
|
|
||||||
padding: 0 !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
#amap {
|
|
||||||
width: 100%;
|
|
||||||
height: 480px;
|
|
||||||
|
|
||||||
.amap-logo, .amap-copyright {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.amap-marker-label {
|
|
||||||
border-color: transparent;
|
|
||||||
box-shadow: 1px 1px 0 0 rgba(#999, .2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.poi {
|
|
||||||
position: absolute;
|
|
||||||
left: 10px;
|
|
||||||
top: 10px;
|
|
||||||
display: flex;
|
|
||||||
height: 32px;
|
|
||||||
flex-direction: column;
|
|
||||||
|
|
||||||
div {
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.selected {
|
|
||||||
position: absolute;
|
|
||||||
right: 16px;
|
|
||||||
top: 16px;
|
|
||||||
background: #fff;
|
|
||||||
min-width: 200px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
|
||||||
|
|
||||||
.header {
|
|
||||||
color: #fff;
|
|
||||||
background: #26f;
|
|
||||||
text-align: center;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
height: 32px;
|
|
||||||
font-size: 14px;
|
|
||||||
gap: 4px;
|
|
||||||
padding: 0 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-form-item {
|
|
||||||
padding: 0 8px;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
<template>
|
|
||||||
<section class="settingDialog">
|
|
||||||
<ai-dialog :visible.sync="dialog" title="基础设置" @close="$emit('visible',false)">
|
|
||||||
<el-form ref="deviceForm" size="small" label-width="140px">
|
|
||||||
<el-form-item label="设备名称" class="full">
|
|
||||||
<el-input v-model="form.name" clearable placeholder="设备名称"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="摄像头状态">
|
|
||||||
<el-radio v-model="form.status" label="开启"/>
|
|
||||||
<el-radio v-model="form.status" label="关闭"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="高清视频">
|
|
||||||
<el-radio v-model="form.status" label="开启"/>
|
|
||||||
<el-radio v-model="form.status" label="关闭"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="摄像头麦克风">
|
|
||||||
<el-radio v-model="form.status" label="开启"/>
|
|
||||||
<el-radio v-model="form.status" label="关闭"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="状态指示灯">
|
|
||||||
<el-radio v-model="form.status" label="开启"/>
|
|
||||||
<el-radio v-model="form.status" label="关闭"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="夜视">
|
|
||||||
<el-radio v-model="form.status" label="自动"/>
|
|
||||||
<el-radio v-model="form.status" label="开启"/>
|
|
||||||
<el-radio v-model="form.status" label="关闭"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="旋转180°">
|
|
||||||
<el-radio v-model="form.status" label="开启"/>
|
|
||||||
<el-radio v-model="form.status" label="关闭"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="WIFI网络" class="full">-</el-form-item>
|
|
||||||
<el-form-item label="MAC地址">(34:75:6b:c9:10)</el-form-item>
|
|
||||||
<el-form-item label="摄像头型号">C71</el-form-item>
|
|
||||||
<el-form-item label="固件">20.0326.251.2486</el-form-item>
|
|
||||||
<el-form-item label="嵌入式应用">2.3.37.8954</el-form-item>
|
|
||||||
<el-form-item label="IMEI">110003953100302</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</ai-dialog>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
name: "settingDialog",
|
|
||||||
model: {
|
|
||||||
prop: "visible",
|
|
||||||
event: "visible",
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
visible: Boolean,
|
|
||||||
detail: {default: () => ({})}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
dialog: false,
|
|
||||||
form: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
visible(v) {
|
|
||||||
this.dialog = v
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.form = JSON.parse(JSON.stringify(this.form))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.settingDialog {
|
|
||||||
.el-form {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .el-form-item {
|
|
||||||
width: 50%;
|
|
||||||
|
|
||||||
.el-form-item__label {
|
|
||||||
padding-right: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.full {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"AppAccount": "账号管理",
|
|
||||||
"AppDictionary": "数据字典",
|
|
||||||
"AppQyWxConfig": "企业微信配置",
|
|
||||||
"AppUserInfo": "个人中心",
|
|
||||||
"AppRightsManager": "权限管理",
|
|
||||||
"AppAccountRole": "账号角色",
|
|
||||||
"AppMenuManager": "菜单管理"
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "dvcp-shandong-apps",
|
|
||||||
"description": "shandong版本应用",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"main": "dist/dvcp-shandong-apps.common.js",
|
|
||||||
"files": [
|
|
||||||
"dist"
|
|
||||||
],
|
|
||||||
"publishConfig": {
|
|
||||||
"registry": "http://192.168.1.87:4873/"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"dvcp-dv-ui": "^2.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -65,10 +65,10 @@ module.exports = {
|
|||||||
//设置代理,可解决跨5
|
//设置代理,可解决跨5
|
||||||
'/lan': {
|
'/lan': {
|
||||||
// target: "https://gsgate.cunwuyun.cn/",
|
// target: "https://gsgate.cunwuyun.cn/",
|
||||||
// target: 'http://192.168.1.87:9000/',
|
target: 'http://192.168.1.87:9000/',
|
||||||
// target: "http://192.168.1.113:9998/",
|
// target: "http://192.168.1.113:9998/",
|
||||||
// target: "http://192.168.1.245:9000/",
|
// target: "http://192.168.1.245:9000/",
|
||||||
target: "http://192.168.1.34:19898",
|
// target: "http://192.168.1.34:19898",
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
pathRewrite: {
|
pathRewrite: {
|
||||||
//地址重写
|
//地址重写
|
||||||
|
|||||||
Reference in New Issue
Block a user