Merge branch 'dev' of http://git.sinoecare.com/sinoecare/digital_village_v2/dvcp_v2_webapp into dev
This commit is contained in:
@@ -12,6 +12,9 @@ instance.interceptors.request.use(config => {
|
|||||||
if (/\/xiushan/.test(location.pathname)) {
|
if (/\/xiushan/.test(location.pathname)) {
|
||||||
config.baseURL = "/xsjr"
|
config.baseURL = "/xsjr"
|
||||||
config.url = config.url.replace(/(app|auth|admin)\//, "")
|
config.url = config.url.replace(/(app|auth|admin)\//, "")
|
||||||
|
}else if (/project\/oms/.test(location.pathname)) {
|
||||||
|
config.baseURL = "/omsapi"
|
||||||
|
config.url = config.url.replace(/(app|auth|admin)\//, "")
|
||||||
}
|
}
|
||||||
if (!config.withoutToken && localStorage.getItem("ui-token")) {
|
if (!config.withoutToken && localStorage.getItem("ui-token")) {
|
||||||
config.headers['Authorization'] = ["Bearer", localStorage.getItem("ui-token")].join(" ")
|
config.headers['Authorization'] = ["Bearer", localStorage.getItem("ui-token")].join(" ")
|
||||||
|
|||||||
@@ -6,8 +6,6 @@
|
|||||||
"main": "lib/cw-webapps.common.js",
|
"main": "lib/cw-webapps.common.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "vue-cli-service serve",
|
"serve": "vue-cli-service serve",
|
||||||
"serve:oms": "npx cross-env NODE_ENV=oms vue-cli-service serve",
|
|
||||||
"build": "vue-cli-service build",
|
|
||||||
"lib": "vue-cli-service build --no-clean --target lib --dest lib packages/index.js&&npm unpublish --force&&npm publish",
|
"lib": "vue-cli-service build --no-clean --target lib --dest lib packages/index.js&&npm unpublish --force&&npm publish",
|
||||||
"lib:core": "vue-cli-service build --target lib --dest core/dist core/index.js --name vc-app-core&&npm unpublish --force&&npm publish",
|
"lib:core": "vue-cli-service build --target lib --dest core/dist core/index.js --name vc-app-core&&npm unpublish --force&&npm publish",
|
||||||
"lib:project": "node project/build.js",
|
"lib:project": "node project/build.js",
|
||||||
|
|||||||
@@ -14,10 +14,9 @@
|
|||||||
v-model="search.title"
|
v-model="search.title"
|
||||||
class="search-input"
|
class="search-input"
|
||||||
size="small"
|
size="small"
|
||||||
@keyup.enter.native="search.title = 1, search.title, getList()"
|
|
||||||
placeholder="请输入课程主题"
|
placeholder="请输入课程主题"
|
||||||
clearable
|
clearable
|
||||||
@clear="search.current = 1, search.title = '', getList()"
|
@change="search.current=1, getList()"
|
||||||
suffix-icon="iconfont iconSearch">
|
suffix-icon="iconfont iconSearch">
|
||||||
</el-input>
|
</el-input>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
<template #tabs>
|
<template #tabs>
|
||||||
<el-tabs v-model="activeName">
|
<el-tabs v-model="activeName">
|
||||||
<el-tab-pane v-for="op in tabs" :key="op.value" :name="op.value" :label="op.label">
|
<el-tab-pane v-for="op in tabs" :key="op.value" :name="op.value" :label="op.label">
|
||||||
<component v-if="op.value==activeName" :is="op.comp" :areaId="areaId" :active="activeName"/>
|
<component v-if="op.value==activeName" :is="op.comp" :areaId="areaId" :active="activeName"
|
||||||
|
:instance="instance" :dict="dict" :permissions="permissions"/>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</template>
|
</template>
|
||||||
@@ -20,6 +21,8 @@ import localResident from "./localResident";
|
|||||||
import ListTpl from "./listTpl";
|
import ListTpl from "./listTpl";
|
||||||
import MobileResident from "./mobileResident";
|
import MobileResident from "./mobileResident";
|
||||||
import ResidentSta from "./residentSta";
|
import ResidentSta from "./residentSta";
|
||||||
|
import auditList from "./auditList";
|
||||||
|
import auditDetail from "./audtiDetail";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "AppResident",
|
name: "AppResident",
|
||||||
@@ -34,7 +37,7 @@ export default {
|
|||||||
resident: this
|
resident: this
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {ResidentSta, MobileResident, ListTpl, localResident},
|
components: {ResidentSta, MobileResident, ListTpl, localResident, auditList, audtiDetail: auditDetail},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["user"]),
|
...mapState(["user"]),
|
||||||
tabs() {
|
tabs() {
|
||||||
@@ -50,6 +53,7 @@ export default {
|
|||||||
detail: details[e.dictName]
|
detail: details[e.dictName]
|
||||||
})),
|
})),
|
||||||
{label: "居民统计", value: "3", comp: ResidentSta},
|
{label: "居民统计", value: "3", comp: ResidentSta},
|
||||||
|
{label: "居民档案审核", value: "4", comp: auditList, detail: auditDetail}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
hideLevel() {
|
hideLevel() {
|
||||||
|
|||||||
@@ -100,7 +100,7 @@
|
|||||||
type="primary"
|
type="primary"
|
||||||
icon="iconfont iconAdd"
|
icon="iconfont iconAdd"
|
||||||
@click="gotoAdd()"
|
@click="gotoAdd()"
|
||||||
v-if="$permissions('app_appresident_edit')">
|
v-if="permissions('app_appresident_edit')">
|
||||||
添加
|
添加
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
icon="iconfont iconDelete"
|
icon="iconfont iconDelete"
|
||||||
:disabled="multipleSelection.length<=0"
|
:disabled="multipleSelection.length<=0"
|
||||||
@click="beforeDelete()"
|
@click="beforeDelete()"
|
||||||
v-if="$permissions('app_appresident_del')">
|
v-if="permissions('app_appresident_del')">
|
||||||
删除
|
删除
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
<el-button icon="iconfont iconImport">导入</el-button>
|
<el-button icon="iconfont iconImport">导入</el-button>
|
||||||
</ai-import>
|
</ai-import>
|
||||||
<ai-download :instance="resident.instance" :params="params" url="/app/appresident/export"
|
<ai-download :instance="resident.instance" :params="params" url="/app/appresident/export"
|
||||||
fileName="居民档案"/>
|
fileName="居民档案" v-if="permissions('app_appresident_export')"/>
|
||||||
</template>
|
</template>
|
||||||
</ai-search-bar>
|
</ai-search-bar>
|
||||||
|
|
||||||
@@ -164,7 +164,8 @@ export default {
|
|||||||
inject: ['resident'],
|
inject: ['resident'],
|
||||||
props: {
|
props: {
|
||||||
areaId: {default: ""},
|
areaId: {default: ""},
|
||||||
active: {default: ""},//人员类型
|
active: {default: ""},//人员类型,
|
||||||
|
permissions: Function
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(["user"]),
|
...mapState(["user"]),
|
||||||
|
|||||||
3
project/oms/apps.import.json
Normal file
3
project/oms/apps.import.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"AppForm": "配置表单"
|
||||||
|
}
|
||||||
33
project/oms/apps/AppArticles/AppArticles.vue
Normal file
33
project/oms/apps/AppArticles/AppArticles.vue
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<template>
|
||||||
|
<section class="AppArticles">
|
||||||
|
<component :is="currentComponent" :instance="instance" :dict="dict" :permissions="permissions"/>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Add from "./components/Add";
|
||||||
|
import Detail from "./components/Detail";
|
||||||
|
import Event from "./components/Event";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "AppArticles",
|
||||||
|
label: "村务公开(运营版)",
|
||||||
|
components: {Event, Detail, Add},
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
permissions: Function
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
currentComponent() {
|
||||||
|
return this.$route.hash == "#add" ? Add :
|
||||||
|
!!this.$route.query?.id ? Detail : Event
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.AppArticles {
|
||||||
|
}
|
||||||
|
</style>
|
||||||
227
project/oms/apps/AppArticles/components/Add.vue
Normal file
227
project/oms/apps/AppArticles/components/Add.vue
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
<template>
|
||||||
|
<ai-detail showFooter class="add-detail">
|
||||||
|
<template slot="title">
|
||||||
|
<ai-title :title="params.id ? '编辑村务公开' : '添加村务公开'" :isShowBack="true" @onBackClick="onBack"
|
||||||
|
:isShowBottomBorder="true"></ai-title>
|
||||||
|
</template>
|
||||||
|
<template slot="content">
|
||||||
|
<ai-card title="基础信息">
|
||||||
|
<template #content>
|
||||||
|
<el-form :model="form" label-width="120px" ref="form">
|
||||||
|
<el-form-item label="类型" prop="type" :rules="[{required: true, message: '请选择类型', trigger: 'change'}]">
|
||||||
|
<el-select size="small" placeholder="请选择" v-model="form.type" style="width: 240px;" clearable>
|
||||||
|
<el-option
|
||||||
|
v-for="(item,i) in dict.getDict('villInfoType')" :key="i"
|
||||||
|
:label="item.dictName"
|
||||||
|
:value="item.dictValue">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="标题" prop="title" :rules="[{required: true, message: '请输入标题', trigger: 'blur'}]">
|
||||||
|
<el-input type="textarea" :rows="2" v-model="form.title" clearable placeholder="请输入..." maxlength="100"
|
||||||
|
show-word-limit></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="正文" prop="content" :rules="[{required: true, message: '请输入正文', trigger: 'blur'}]">
|
||||||
|
<ai-editor v-model="form.content" :instance="instance"/>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- <el-form-item label="缩略图" prop="thumbUrl" :rules="[{required: true, message: '请上次缩略图', trigger: 'change'}]">
|
||||||
|
<ai-uploader
|
||||||
|
:isShowTip="true"
|
||||||
|
:instance="instance"
|
||||||
|
v-model="form.thumbUrl"
|
||||||
|
:limit="1"
|
||||||
|
:cropOps="cropOps"
|
||||||
|
is-crop>
|
||||||
|
<template slot="tips">最多上传1张图片,单个文件最大10MB,支持jpg、jpeg、png<br/>格式图片比例:1.6:1</template>
|
||||||
|
</ai-uploader>
|
||||||
|
</el-form-item> -->
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
</template>
|
||||||
|
<template slot="footer" class="footer">
|
||||||
|
<el-button class="delete-btn footer-btn" @click="cancel(false)">取消</el-button>
|
||||||
|
<el-button type="primary" size="small" @click="onSubmit()">保存</el-button>
|
||||||
|
</template>
|
||||||
|
</ai-detail>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {mapState} from 'vuex'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'Add',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
dict: Object,
|
||||||
|
instance: Function,
|
||||||
|
areaId: String
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
form: {
|
||||||
|
title: '',
|
||||||
|
type: '',
|
||||||
|
content: '',
|
||||||
|
fileIds: [],
|
||||||
|
thumbUrl: []
|
||||||
|
},
|
||||||
|
fileList: [],
|
||||||
|
isDetail: true,
|
||||||
|
cropOps: {
|
||||||
|
width: "336px",
|
||||||
|
height: "210px"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
...mapState(['user']),
|
||||||
|
params() {
|
||||||
|
return this.$route.query
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
if (this.params && this.params.id) {
|
||||||
|
this.getInfo()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
onBack() {
|
||||||
|
this.$router.push({})
|
||||||
|
},
|
||||||
|
|
||||||
|
getInfo() {
|
||||||
|
this.instance.post(`/appvillageinfo/queryDetailById?id=${this.params.id}`).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.form = {
|
||||||
|
...res.data
|
||||||
|
}
|
||||||
|
this.form.thumbUrl = res.data.thumbUrl ? JSON.parse(res.data.thumbUrl) : []
|
||||||
|
this.fileList = res.data.files || []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onSubmit() {
|
||||||
|
this.$refs.form.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.instance.post(`/appvillageinfo/addOrUpdate`, {
|
||||||
|
...this.form,
|
||||||
|
fileIds: this.fileList.map(v => v.id),
|
||||||
|
thumbUrl: this.form.thumbUrl.length ? JSON.stringify([{
|
||||||
|
url: this.form.thumbUrl[0].url
|
||||||
|
}]) : ''
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.$message.success(`${this.params.id ? '编辑成功' : '提交成功'}`)
|
||||||
|
setTimeout(() => {
|
||||||
|
this.cancel(true)
|
||||||
|
}, 800)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.add-detail {
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #F2F4F6 !important;
|
||||||
|
|
||||||
|
.map-wrapper {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 400px;
|
||||||
|
|
||||||
|
.search-input {
|
||||||
|
position: absolute;
|
||||||
|
top: 20px;
|
||||||
|
left: 20px;
|
||||||
|
z-index: 1111;
|
||||||
|
width: 220px !important;
|
||||||
|
height: 32px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#map {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 11;
|
||||||
|
width: 100%;
|
||||||
|
height: 400px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-form-item__content {
|
||||||
|
margin-left: 140px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-detail__form {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.el-input {
|
||||||
|
width: 328px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-form {
|
||||||
|
&:first-child {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-form__item, .add-detail__form {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 0 90px 0 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .ai-detail__footer {
|
||||||
|
background: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .ai-detail {
|
||||||
|
div {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .ai-detail__content--active {
|
||||||
|
padding: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.ai-detail__content--wrapper {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aibar {
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-form {
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .ai-wrapper {
|
||||||
|
align-items: inherit !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-btn {
|
||||||
|
width: 92px;
|
||||||
|
}
|
||||||
|
|
||||||
|
el-form {
|
||||||
|
padding-bottom: 80px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
77
project/oms/apps/AppArticles/components/Detail.vue
Normal file
77
project/oms/apps/AppArticles/components/Detail.vue
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
<template>
|
||||||
|
<ai-detail class="event-detail">
|
||||||
|
<template #title>
|
||||||
|
<ai-title title="村务公开详情" :isShowBack="true" @onBackClick="onBack" isShowBottomBorder>
|
||||||
|
</ai-title>
|
||||||
|
</template>
|
||||||
|
<template #content>
|
||||||
|
<ai-card :title="info.title" titlePosition="center">
|
||||||
|
<template #title>
|
||||||
|
<h2>{{ info.title }}</h2>
|
||||||
|
<p class="subTitle">{{ info.createDate }} {{ info.unitName || '-' }}</p>
|
||||||
|
</template>
|
||||||
|
<template #content>
|
||||||
|
<img class="cover" :src="info.thumbUrl[0].url" v-if="info.thumbUrl && info.thumbUrl.length">
|
||||||
|
<ai-article :value="info.content"></ai-article>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
</template>
|
||||||
|
</ai-detail>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'detail',
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
permissions: Function,
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
info: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
params() {
|
||||||
|
return this.$route.query
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getInfo()
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
getInfo() {
|
||||||
|
this.instance.post(`/appvillageinfo/queryDetailById?id=${this.params.id}`).then(res => {
|
||||||
|
if (res?.data) {
|
||||||
|
this.info = res.data
|
||||||
|
if (res.data.thumbUrl) {
|
||||||
|
this.info.thumbUrl = JSON.parse(res.data.thumbUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onBack() {
|
||||||
|
this.$router.push({})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.cover {
|
||||||
|
display: block;
|
||||||
|
width: 300px;
|
||||||
|
height: 140px;
|
||||||
|
margin: 20px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subTitle {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
269
project/oms/apps/AppArticles/components/Event.vue
Normal file
269
project/oms/apps/AppArticles/components/Event.vue
Normal file
@@ -0,0 +1,269 @@
|
|||||||
|
<template>
|
||||||
|
<section class="event">
|
||||||
|
<ai-list>
|
||||||
|
<ai-title slot="title" title="村务公开" isShowBottomBorder></ai-title>
|
||||||
|
<template slot="content">
|
||||||
|
<ai-search-bar>
|
||||||
|
<template slot="left">
|
||||||
|
<el-button icon="iconfont iconAdd" type="primary" size="small" @click="toAdd">添加</el-button>
|
||||||
|
</template>
|
||||||
|
<template slot="right">
|
||||||
|
<el-input
|
||||||
|
placeholder="请输入标题"
|
||||||
|
size="small"
|
||||||
|
clearable
|
||||||
|
v-model="search.title"
|
||||||
|
@keyup.enter.native="search.current = 1, getList()"
|
||||||
|
@clear="search.current = 1, search.title = '', getList()"
|
||||||
|
suffix-icon="iconfont iconSearch"/>
|
||||||
|
</template>
|
||||||
|
</ai-search-bar>
|
||||||
|
<div class="ai-table">
|
||||||
|
<ai-table
|
||||||
|
:tableData="tableData"
|
||||||
|
:col-configs="colConfigs"
|
||||||
|
:total="total"
|
||||||
|
:current.sync="search.current"
|
||||||
|
:size.sync="search.size"
|
||||||
|
@getList="getList">
|
||||||
|
<el-table-column slot="options" label="操作" align="center" width="250" fixed="right">
|
||||||
|
<template slot-scope="{ row }" class="fs-14">
|
||||||
|
<div class="table-options">
|
||||||
|
<el-button
|
||||||
|
type="text"
|
||||||
|
@click="publish(row)"
|
||||||
|
title="发布">
|
||||||
|
发布
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="text"
|
||||||
|
title="详情"
|
||||||
|
@click="toDetail(row.id)">
|
||||||
|
详情
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
type="text"
|
||||||
|
title="编辑"
|
||||||
|
@click="toEdit(row.id)">
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
@click="remove(row.id)"
|
||||||
|
type="text"
|
||||||
|
title="删除">
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</ai-table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</ai-list>
|
||||||
|
<ai-dialog title="请选择发布平台企业" :visible.sync="dialog" width="600px" @onConfirm="saveSaas">
|
||||||
|
<el-form ref="saasForm" :model="dialogForm" size="small" label-width="120px">
|
||||||
|
<el-form-item required label="saas平台" prop="saasId" :rules="[{required: true, message: '请选择saas平台'}]">
|
||||||
|
<el-select v-model="dialogForm.saasId" placeholder="请选择saas平台" style="width:100%;" @change="getCompanyList">
|
||||||
|
<el-option
|
||||||
|
v-for="item in saasList"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item required label="saas企业" prop="corpId" :rules="[{required: true, message: '请选择saas企业'}]">
|
||||||
|
<el-select v-model="dialogForm.corpId" placeholder="请选择saas企业" style="width:100%;" @change="selectCompany">
|
||||||
|
<el-option
|
||||||
|
v-for="item in companyList"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item required label="地区" prop="areaId" :rules="[{required: true, message: '请选择发布地区'}]">
|
||||||
|
<ai-area-get :instance="instance" v-model="dialogForm.areaId" :root="rootId"
|
||||||
|
:name.sync="dialogForm.areaName"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ai-dialog>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {mapState} from 'vuex'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'event',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
...mapState(['user']),
|
||||||
|
colConfigs() {
|
||||||
|
return [
|
||||||
|
{prop: 'type', label: '类型', formart: v => this.dict.getLabel('villInfoType', v)},
|
||||||
|
{prop: 'title', label: '标题', align: 'left'},
|
||||||
|
{prop: 'createDate', label: '创建时间', dateFormart: 'YYYY-MM-DD', align: 'center'},
|
||||||
|
{prop: 'createUser', label: '发布人', align: 'center'},
|
||||||
|
{slot: 'options', label: '操作'}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
search: {
|
||||||
|
current: 1,
|
||||||
|
size: 10,
|
||||||
|
title: ''
|
||||||
|
},
|
||||||
|
total: 0,
|
||||||
|
ids: [],
|
||||||
|
tableData: [],
|
||||||
|
dialog: false,
|
||||||
|
dialogForm: {},
|
||||||
|
saasList: [],
|
||||||
|
companyList: [],
|
||||||
|
rootId: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.dict.load('villInfoType').then(() => {
|
||||||
|
this.getList()
|
||||||
|
this.getsaasList()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
getsaasList() {
|
||||||
|
this.instance.post("/appSaas/page", null, {
|
||||||
|
params: {size: 10000}
|
||||||
|
}).then(res => {
|
||||||
|
if (res?.data) {
|
||||||
|
this.saasList = res.data?.records
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
getCompanyList() {
|
||||||
|
this.instance.post("/appCorp/page", null, {
|
||||||
|
params: {saasId: this.dialogForm.saasId, size: 10000}
|
||||||
|
}).then(res => {
|
||||||
|
if (res?.data) {
|
||||||
|
this.companyList = res.data.records
|
||||||
|
this.rootId = ''
|
||||||
|
this.dialogForm.areaId = ''
|
||||||
|
this.corpId = ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
selectCompany() {
|
||||||
|
this.companyList.map(item => {
|
||||||
|
if (item.id == this.dialogForm.corpId) {
|
||||||
|
this.rootId = item.areaId
|
||||||
|
this.dialogForm.areaId = item.areaId
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
getList() {
|
||||||
|
this.instance.post(`/appvillageinfo/list`, null, {
|
||||||
|
params: {
|
||||||
|
...this.search,
|
||||||
|
areaId: this.areaId
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
this.tableData = res.data.records
|
||||||
|
this.total = res.data.total
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
publish(params) {
|
||||||
|
this.dialogForm.id = params.id
|
||||||
|
this.dialog = true
|
||||||
|
},
|
||||||
|
|
||||||
|
toAdd() {
|
||||||
|
this.$router.push({hash: "#add"})
|
||||||
|
},
|
||||||
|
toEdit(id) {
|
||||||
|
this.$router.push({hash: "#add", query: {id}})
|
||||||
|
},
|
||||||
|
|
||||||
|
toDetail(id) {
|
||||||
|
this.$router.push({query: {id}})
|
||||||
|
},
|
||||||
|
|
||||||
|
remove(id) {
|
||||||
|
this.$confirm('确定删除该数据?').then(() => {
|
||||||
|
this.instance.post(`/app/appvillageinfo/delete?ids=${id}`).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message.success('删除成功!')
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
saveSaas() {
|
||||||
|
this.$refs.saasForm.validate(v => {
|
||||||
|
if (v) {
|
||||||
|
this.instance.post(`/appvillageinfo/sync?corpId=${this.dialogForm.corpId}&id=${this.dialogForm.id}&areaId=${this.dialogForm.areaId}`).then(res => {
|
||||||
|
if (res?.code == 0) {
|
||||||
|
this.dialog = false;
|
||||||
|
this.$message.success("发布成功")
|
||||||
|
this.dialogForm = {}
|
||||||
|
} else {
|
||||||
|
this.$message.error(res?.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.event {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
::v-deep th {
|
||||||
|
font-weight: bold !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .table-options {
|
||||||
|
span {
|
||||||
|
font-size: 14px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-btn {
|
||||||
|
margin-right: 16px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #2266FF;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child:hover {
|
||||||
|
color: #f46;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
35
project/oms/apps/AppCompany/AppCompany.vue
Normal file
35
project/oms/apps/AppCompany/AppCompany.vue
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<template>
|
||||||
|
<section class="AppCompany">
|
||||||
|
<component :is="currentComponent" :instance="instance" :dict="dict" :permissions="permissions"/>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import List from "./components/List";
|
||||||
|
import Sta from "./components/Statistics";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "AppCompany",
|
||||||
|
label: "企业管理",
|
||||||
|
components: {List, Sta},
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
permissions: Function
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
currentComponent() {
|
||||||
|
return this.$route.hash == "#sta" ? Sta : List
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.AppCompany {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
222
project/oms/apps/AppCompany/components/List.vue
Normal file
222
project/oms/apps/AppCompany/components/List.vue
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
<template>
|
||||||
|
<section class="list">
|
||||||
|
<ai-list>
|
||||||
|
<ai-title slot="title" title="企业管理" isShowBottomBorder/>
|
||||||
|
<template #content>
|
||||||
|
<ai-search-bar>
|
||||||
|
<template #left>
|
||||||
|
<el-select v-model="search.saasId" size="small" placeholder="请选择saas平台" @change="getDataInit">
|
||||||
|
<el-option
|
||||||
|
v-for="item in saasList"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</template>
|
||||||
|
</ai-search-bar>
|
||||||
|
<ai-search-bar>
|
||||||
|
<template #left>
|
||||||
|
<el-button type="primary" icon="iconfont iconAdd" @click="dialogForm = {}, dialog=true">添加</el-button>
|
||||||
|
</template>
|
||||||
|
<template #right>
|
||||||
|
<el-input size="small" placeholder="企业名称" v-model="search.name" clearable @change="getDataInit"/>
|
||||||
|
</template>
|
||||||
|
</ai-search-bar>
|
||||||
|
<ai-table :tableData="tableData" :total="page.total" :current.sync="page.current" :size.sync="page.size"
|
||||||
|
@getList="getTableData" :col-configs="colConfigs" :dict="dict"
|
||||||
|
@selection-change="v=>ids=v.filter(e=>e.id).map(e=>e.id)">
|
||||||
|
<el-table-column slot="options" align="center" label="操作" fixed="right" width="240px">
|
||||||
|
<div class="table-options" slot-scope="{ row }">
|
||||||
|
<el-button type="text" @click="handleEnter(row.accessUrl)">打开</el-button>
|
||||||
|
<el-button type="text" @click="handleSync(row.corpId)">同步</el-button>
|
||||||
|
<el-button type="text" @click="toStatistics(row)">统计</el-button>
|
||||||
|
<el-button type="text" @click="handleEdit(row)">编辑</el-button>
|
||||||
|
<el-button type="text" @click="handleDelete(row.id)">删除</el-button>
|
||||||
|
</div>
|
||||||
|
</el-table-column>
|
||||||
|
</ai-table>
|
||||||
|
</template>
|
||||||
|
</ai-list>
|
||||||
|
<ai-dialog :title="dialogTitle" :visible.sync="dialog" width="600px" @onConfirm="saveSaas">
|
||||||
|
<el-form ref="saasForm" :model="dialogForm" :rules="rules" size="small" label-width="120px">
|
||||||
|
<el-form-item required label="名称" prop="name">
|
||||||
|
<el-input v-model.trim="dialogForm.name" placeholder="请输入saas企业名称" clearable :maxLength="50"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item required label="saas平台" prop="saasId">
|
||||||
|
<el-select v-model="dialogForm.saasId" placeholder="请选择saas平台" style="width:100%;">
|
||||||
|
<el-option
|
||||||
|
v-for="item in saasList"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.id">
|
||||||
|
</el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item required label="地区" prop="areaId" :rules="[{required: true, message: '请选择发布地区'}]">
|
||||||
|
<ai-area-get :instance="instance" v-model="dialogForm.areaId" :name.sync="dialogForm.areaName"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item required label="企业CORP_ID" prop="corpId" :rules="[{required: true, message: '请输入企业CORP_ID'}]">
|
||||||
|
<el-input v-model.trim="dialogForm.corpId" placeholder="请输入企业CORP_ID" clearable :maxLength="50"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="AGENT_ID" prop="corpAgentId">
|
||||||
|
<el-input v-model.trim="dialogForm.corpAgentId" placeholder="请输入企业AGENT_ID" clearable :maxLength="50"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="CORP_SECRET" prop="corpSecret">
|
||||||
|
<el-input v-model.trim="dialogForm.corpSecret" placeholder="请输入企业CORP_SECRET" clearable :maxLength="50"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="企业通讯录SECRET" prop="corpAddressBookSecret">
|
||||||
|
<el-input v-model.trim="dialogForm.corpAddressBookSecret" placeholder="请输入企业通讯录SECRET" clearable
|
||||||
|
:maxLength="50"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="访问地址" prop="accessUrl" :rules="[{required: true, message: '请输入访问地址'}]">
|
||||||
|
<el-input v-model.trim="dialogForm.accessUrl" placeholder="请输入访问地址" clearable
|
||||||
|
:maxLength="255"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ai-dialog>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "list",
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
permissions: Function
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isEdit() {
|
||||||
|
return !!this.dialogForm.id
|
||||||
|
},
|
||||||
|
dialogTitle() {
|
||||||
|
return this.isEdit ? '修改saas企业' : '添加saas企业'
|
||||||
|
},
|
||||||
|
colConfigs() {
|
||||||
|
return [
|
||||||
|
{label: "名称", prop: "name"},
|
||||||
|
{label: "saas平台", prop: "saasName", align: 'center'},
|
||||||
|
{label: "地区", prop: "areaName", align: 'center'},
|
||||||
|
{label: "企业CORP_ID", prop: "corpId", align: 'center'},
|
||||||
|
{label: "访问地址", prop: "accessUrl"},
|
||||||
|
{label: "创建时间", prop: "createTime"},
|
||||||
|
{slot: "options"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
rules() {
|
||||||
|
return {
|
||||||
|
name: [{required: true, message: "请输入saas企业名称"}],
|
||||||
|
saasId: [{required: true, message: "请选择saas平台"}],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateRules() {
|
||||||
|
return {
|
||||||
|
password: [{required: true, message: "请输入平台密码"}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
page: {current: 1, size: 10, total: 0},
|
||||||
|
dialog: false,
|
||||||
|
dialogForm: {},
|
||||||
|
tableData: [],
|
||||||
|
search: {name: "", saasId: ''},
|
||||||
|
ids: [],
|
||||||
|
saasList: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getsaasList() {
|
||||||
|
this.instance.post("/appSaas/page", null, {
|
||||||
|
params: {size: 10000}
|
||||||
|
}).then(res => {
|
||||||
|
if (res?.data) {
|
||||||
|
this.saasList = res.data?.records
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getDataInit() {
|
||||||
|
this.page.current = 1
|
||||||
|
this.getTableData()
|
||||||
|
},
|
||||||
|
getTableData() {
|
||||||
|
this.instance.post("/appCorp/page", null, {
|
||||||
|
params: {...this.page, ...this.search}
|
||||||
|
}).then(res => {
|
||||||
|
if (res?.data) {
|
||||||
|
this.tableData = res.data.records
|
||||||
|
this.page.total = res.data.total
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 新增/修改
|
||||||
|
saveSaas() {
|
||||||
|
this.$refs.saasForm.validate(v => {
|
||||||
|
if (v) {
|
||||||
|
this.saasList.map(item => {
|
||||||
|
if (item.id == this.dialogForm.saasId) {
|
||||||
|
this.dialogForm.saasName = item.name
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.instance.post("/appCorp/addOrUpdate", this.dialogForm).then(res => {
|
||||||
|
if (res?.code == 0) {
|
||||||
|
this.dialog = false;
|
||||||
|
this.$message.success("保存成功")
|
||||||
|
this.getTableData();
|
||||||
|
} else {
|
||||||
|
this.$message.error(res?.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleEdit(row) {
|
||||||
|
this.dialogForm = row
|
||||||
|
this.dialog = true
|
||||||
|
},
|
||||||
|
handleDelete(ids) {
|
||||||
|
this.$confirm("是否要删除该Saas信息?").then(() => {
|
||||||
|
this.instance.post("/appCorp/delete", null, {
|
||||||
|
params: {ids}
|
||||||
|
}).then(res => {
|
||||||
|
if (res?.code == 0) {
|
||||||
|
this.getTableData();
|
||||||
|
this.$message.success("删除成功!");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).catch(() => 0)
|
||||||
|
},
|
||||||
|
handleSync(corpId) {
|
||||||
|
this.$confirm("是否确定同步该企业数据?").then(() => {
|
||||||
|
this.instance.post("/appCorpStat/syncData?corpId=" + corpId, null, {}).then(res => {
|
||||||
|
if (res?.code == 0) {
|
||||||
|
this.getTableData();
|
||||||
|
this.$message.success("同步成功!");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).catch(() => 0)
|
||||||
|
},
|
||||||
|
handleEnter(accessUrl) {
|
||||||
|
window.open(accessUrl, "_blank");
|
||||||
|
},
|
||||||
|
toStatistics(item) {
|
||||||
|
let {corpId} = item
|
||||||
|
this.$router.push({query: {corpId}, hash: "#sta"})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getsaasList()
|
||||||
|
this.getTableData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.list {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
380
project/oms/apps/AppCompany/components/Statistics.vue
Normal file
380
project/oms/apps/AppCompany/components/Statistics.vue
Normal file
@@ -0,0 +1,380 @@
|
|||||||
|
<template>
|
||||||
|
<ai-detail class="Statistics">
|
||||||
|
<template #title>
|
||||||
|
<ai-title title="企业统计" :isShowBack="true" @onBackClick="onBack" isShowBottomBorder>
|
||||||
|
</ai-title>
|
||||||
|
</template>
|
||||||
|
<template #content>
|
||||||
|
<ai-card title="基本信息">
|
||||||
|
<template #content>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="5">
|
||||||
|
<div class="title">群总数</div>
|
||||||
|
<div class="num">{{ info.groupCount }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="5">
|
||||||
|
<div class="title">成员总数</div>
|
||||||
|
<div class="num">{{ info.userCount }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="5">
|
||||||
|
<div class="title">成员活跃总数</div>
|
||||||
|
<div class="num">{{ info.activeCount }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="5">
|
||||||
|
<div class="title">居民总人数</div>
|
||||||
|
<div class="num">{{ info.residentCount }}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="4">
|
||||||
|
<div class="title">群成员总数</div>
|
||||||
|
<div class="num">{{ info.groupuserCount }}</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
<ai-card title="统计信息" class="chart-content">
|
||||||
|
<template #title>
|
||||||
|
<div class="tabs">
|
||||||
|
<div class="item" v-for="(item, index) in tabs" :key="index" :class="index == activeIndex ? 'active' : ''"
|
||||||
|
@click="tabClick(index)">{{ item }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #content>
|
||||||
|
<div class="echart" id="echart" v-if="activeIndex != 2 && activeIndex != 3"></div>
|
||||||
|
<div class="table" v-else-if="activeIndex == 2">
|
||||||
|
<ai-search-bar>
|
||||||
|
<template slot="right">
|
||||||
|
<el-input
|
||||||
|
v-model="innerMemberId"
|
||||||
|
size="small"
|
||||||
|
placeholder="输入群成员ID"
|
||||||
|
@keyup.enter.native="(page.current = 1), getTableData()"
|
||||||
|
clearable
|
||||||
|
prefix-icon="iconfont iconSearch"
|
||||||
|
/>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
icon="iconfont iconSearch"
|
||||||
|
size="small"
|
||||||
|
@click="(page.current = 1), getTableData()"
|
||||||
|
>查询
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
icon="el-icon-refresh-right"
|
||||||
|
size="small"
|
||||||
|
@click="resetSearch"
|
||||||
|
>重置
|
||||||
|
</el-button
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</ai-search-bar>
|
||||||
|
<ai-table :tableData="gropList" :total="page.total" :current.sync="page.current" :size.sync="page.size"
|
||||||
|
@getList="getTableData" :col-configs="colConfigs" :dict="dict">
|
||||||
|
<!-- <el-table-column slot="options" align="center" label="操作" fixed="right" width="240px">
|
||||||
|
<div class="table-options" slot-scope="{ row }">
|
||||||
|
<el-button type="text">打开</el-button>
|
||||||
|
</div>
|
||||||
|
</el-table-column> -->
|
||||||
|
</ai-table>
|
||||||
|
</div>
|
||||||
|
<div class="table" v-else-if="activeIndex == 3">
|
||||||
|
<ai-table :tableData="userList" :total="userPage.total" :current.sync="userPage.current"
|
||||||
|
:size.sync="userPage.size"
|
||||||
|
@getList="getUserTableData" :col-configs="userColConfigs" :dict="dict">
|
||||||
|
<!-- <el-table-column slot="options" align="center" label="操作" fixed="right" width="240px">
|
||||||
|
<div class="table-options" slot-scope="{ row }">
|
||||||
|
<el-button type="text">打开</el-button>
|
||||||
|
</div>
|
||||||
|
</el-table-column> -->
|
||||||
|
</ai-table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
</template>
|
||||||
|
</ai-detail>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as echarts from 'echarts'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'Statistics',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
permissions: Function,
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
info: {},
|
||||||
|
activeIndex: 0,
|
||||||
|
tabs: ['概览', '群统计', '群列表', '成员与好友统计'],
|
||||||
|
listData: [],
|
||||||
|
pieData: [],
|
||||||
|
myChart: null,
|
||||||
|
gropList: [],
|
||||||
|
page: {current: 1, size: 10, total: 0},
|
||||||
|
innerMemberId: '',
|
||||||
|
userList: [],
|
||||||
|
userPage: {current: 1, size: 10, total: 0}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
colConfigs() {
|
||||||
|
return [
|
||||||
|
{label: "群名", prop: "name", width: 200},
|
||||||
|
{label: "创建时间", prop: "createTime", align: 'center', width: 150},
|
||||||
|
{label: "群成员数", prop: "memberCount", align: 'center', width: 100},
|
||||||
|
{label: "群主ID", prop: "owner", align: 'center', width: 150},
|
||||||
|
{label: "群公告", prop: "notice"},
|
||||||
|
]
|
||||||
|
},
|
||||||
|
userColConfigs() {
|
||||||
|
return [
|
||||||
|
{label: "部门", prop: "departmentName"},
|
||||||
|
{label: "姓名", prop: "name", align: 'center'},
|
||||||
|
{label: "添加好友人数", prop: "residentCount", align: 'center'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
params() {
|
||||||
|
return this.$route.query || {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.getTableData()
|
||||||
|
this.getUserTableData()
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.getInfo()
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
chartInit() {
|
||||||
|
var option = {}
|
||||||
|
if (this.activeIndex != 1) {
|
||||||
|
option = {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'axis'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: ['群总数', '成员总数', '成员活跃总数', '居民总人数', '群成员总数']
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
left: '3%',
|
||||||
|
right: '4%',
|
||||||
|
bottom: '3%',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
data: this.listData[5],
|
||||||
|
},
|
||||||
|
yAxis: {
|
||||||
|
type: 'value'
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '群总数',
|
||||||
|
type: 'line',
|
||||||
|
data: this.listData[0]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '成员总数',
|
||||||
|
type: 'line',
|
||||||
|
data: this.listData[1]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '成员活跃总数',
|
||||||
|
type: 'line',
|
||||||
|
data: this.listData[2]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '居民总人数',
|
||||||
|
type: 'line',
|
||||||
|
data: this.listData[3]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '群成员总数',
|
||||||
|
type: 'line',
|
||||||
|
data: this.listData[4]
|
||||||
|
},
|
||||||
|
]
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
option = {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'item'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
orient: 'vertical',
|
||||||
|
left: 'left'
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: 'pie',
|
||||||
|
radius: '50%',
|
||||||
|
data: this.pieData,
|
||||||
|
emphasis: {
|
||||||
|
itemStyle: {
|
||||||
|
shadowBlur: 10,
|
||||||
|
shadowOffsetX: 0,
|
||||||
|
shadowColor: 'rgba(0, 0, 0, 0.5)'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
this.myChart.setOption(option);
|
||||||
|
},
|
||||||
|
getInfo() {
|
||||||
|
this.myChart = echarts.init(document.getElementById("echart"));
|
||||||
|
this.instance.post(`/appCorpStat/getLatestInfo?corpId=${this.params.corpId}`).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.info = res.data
|
||||||
|
this.getCharInfo()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getCharInfo() {
|
||||||
|
this.instance.post(`/appCorpStat/getLatestThreeMonthStat?corpId=${this.params.corpId}`).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
if (res.data && res.data.length) {
|
||||||
|
this.listData = []
|
||||||
|
this.listData[0] = res.data.map(v => v.groupCount)
|
||||||
|
this.listData[1] = res.data.map(v => v.userCount)
|
||||||
|
this.listData[2] = res.data.map(v => v.activeCount)
|
||||||
|
this.listData[3] = res.data.map(v => v.residentCount)
|
||||||
|
this.listData[4] = res.data.map(v => v.groupuserCount)
|
||||||
|
this.listData[5] = res.data.map(v => v.statDate)
|
||||||
|
this.chartInit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.instance.post(`/wxcp/wxgroup/groupStatistic?corpId=${this.params.corpId}`).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
if (res.data) {
|
||||||
|
this.pieData = []
|
||||||
|
Object.getOwnPropertyNames(res.data).forEach((key) => {
|
||||||
|
var e = {
|
||||||
|
value: res.data[key],
|
||||||
|
name: key
|
||||||
|
}
|
||||||
|
this.pieData.push(e)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
resetSearch() {
|
||||||
|
this.innerMemberId = ''
|
||||||
|
this.page.current = 1
|
||||||
|
this.getTableData()
|
||||||
|
},
|
||||||
|
getTableData() {
|
||||||
|
this.instance.post(`/wxcp/wxgroup/list?corpId=${this.params.corpId}¤t=${this.page.current}&size=${this.page.size}&innerMemberId=${this.innerMemberId}`,).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
if (res.data) {
|
||||||
|
this.gropList = res.data.records
|
||||||
|
this.page.total = res.data.total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getUserTableData() {
|
||||||
|
this.instance.post(`/wxcp/wxuser/userStat?corpId=${this.params.corpId}¤t=${this.userPage.current}&size=${this.userPage.size}&mainDepartment=1`,).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
if (res.data) {
|
||||||
|
this.userList = res.data.records
|
||||||
|
this.userPage.total = res.data.total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
onBack() {
|
||||||
|
this.$router.push({})
|
||||||
|
},
|
||||||
|
tabClick(index) {
|
||||||
|
this.activeIndex = index
|
||||||
|
this.myChart.dispose()
|
||||||
|
if (index != 2 && index != 3) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.myChart = echarts.init(document.getElementById("echart"));
|
||||||
|
this.chartInit()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.cover {
|
||||||
|
display: block;
|
||||||
|
width: 300px;
|
||||||
|
height: 140px;
|
||||||
|
margin: 20px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subTitle {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
line-height: 60px;
|
||||||
|
font-size: 18px;
|
||||||
|
text-align: center;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.num {
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: 700;
|
||||||
|
text-align: center;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs {
|
||||||
|
.item {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 20px;
|
||||||
|
line-height: 54px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active {
|
||||||
|
color: #26f;
|
||||||
|
border-bottom: 2px solid #26f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-content {
|
||||||
|
height: calc(100% - 240px);
|
||||||
|
|
||||||
|
::v-deep .ai-card__body {
|
||||||
|
height: calc(100% - 70px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.echart {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow-y: scroll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .ai-detail__content--wrapper {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
273
project/oms/apps/AppCorpStatistics/AppCorpStatistics.vue
Normal file
273
project/oms/apps/AppCorpStatistics/AppCorpStatistics.vue
Normal file
@@ -0,0 +1,273 @@
|
|||||||
|
<template>
|
||||||
|
<section class="AppCorpStatistics">
|
||||||
|
<ai-detail>
|
||||||
|
<!-- 标题 -->
|
||||||
|
<ai-title slot="title" title="企微统计" isShowBottomBorder />
|
||||||
|
<template #content>
|
||||||
|
<ai-tree-menu title="企微统计">
|
||||||
|
<el-tree
|
||||||
|
@node-click="nodeClick"
|
||||||
|
:props="props"
|
||||||
|
:load="loadNode"
|
||||||
|
lazy
|
||||||
|
:expand-on-click-node="false"
|
||||||
|
>
|
||||||
|
</el-tree>
|
||||||
|
</ai-tree-menu>
|
||||||
|
|
||||||
|
<div class="flex">
|
||||||
|
<el-row :gutter="20" class="el-row">
|
||||||
|
<el-col :span="5">
|
||||||
|
<div class="title">群总数</div>
|
||||||
|
<div class="num">{{info.groupCount}}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="5">
|
||||||
|
<div class="title">成员总数</div>
|
||||||
|
<div class="num">{{info.userCount}}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="5">
|
||||||
|
<div class="title">成员活跃总数</div>
|
||||||
|
<div class="num">{{info.activeCount}}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="5">
|
||||||
|
<div class="title">居民总人数</div>
|
||||||
|
<div class="num">{{info.residentCount}}</div>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="4">
|
||||||
|
<div class="title">群成员总数</div>
|
||||||
|
<div class="num">{{info.groupuserCount}}</div>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<div class="table">
|
||||||
|
<ai-search-bar>
|
||||||
|
<template slot="right">
|
||||||
|
<el-input
|
||||||
|
v-model="name"
|
||||||
|
size="small"
|
||||||
|
placeholder="输入企微名称"
|
||||||
|
@keyup.enter.native="(page.current = 1), getTableData()"
|
||||||
|
clearable
|
||||||
|
prefix-icon="iconfont iconSearch"
|
||||||
|
/>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
icon="iconfont iconSearch"
|
||||||
|
size="small"
|
||||||
|
@click="(page.current = 1), getTableData()"
|
||||||
|
>查询
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
icon="el-icon-refresh-right"
|
||||||
|
size="small"
|
||||||
|
@click="resetSearch"
|
||||||
|
>重置</el-button
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</ai-search-bar>
|
||||||
|
<ai-table :tableData="gropList" :total="page.total" :current.sync="page.current" :size.sync="page.size"
|
||||||
|
@getList="getTableData" :col-configs="colConfigs" :dict="dict">
|
||||||
|
</ai-table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</ai-detail>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapState } from 'vuex'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'AppCorpStatistics',
|
||||||
|
label: 'saas企微统计',
|
||||||
|
props: {
|
||||||
|
dict: Object,
|
||||||
|
instance: Function,
|
||||||
|
params: Object,
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
label: 'name',
|
||||||
|
children: 'zones',
|
||||||
|
isLeaf: 'leaf'
|
||||||
|
},
|
||||||
|
corpTotal: 0,
|
||||||
|
info: {},
|
||||||
|
gropList: [],
|
||||||
|
page: {current: 1, size: 10, total: 0},
|
||||||
|
areaId: '',
|
||||||
|
name: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
...mapState(['user']),
|
||||||
|
|
||||||
|
colConfigs() {
|
||||||
|
return [
|
||||||
|
{label: "企微名称", prop: "name", align: 'center', width:250},
|
||||||
|
{label: "地区", prop: "areaName", align: 'center', width:150},
|
||||||
|
{label: "创建时间", prop: "createTime", align: 'center', width:200},
|
||||||
|
{label: 'CORP_ID', prop: "corpId"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.getInfo()
|
||||||
|
this.getTableData()
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
loadNode(node, resolve) {
|
||||||
|
if (node.level == 0) {
|
||||||
|
this.instance.post(`/appCorpStat/getCorpStatTotal`).then((res) => {
|
||||||
|
if (res.data) {
|
||||||
|
return resolve([{ name: `全国 (${res.data})`}]);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var areaId = node.data.id
|
||||||
|
|
||||||
|
if(node.level == 1) { //全国
|
||||||
|
areaId = ''
|
||||||
|
}
|
||||||
|
this.instance.post(`/appCorpStat/getCorpStatByArea?areaId=${areaId}`).then((res) => {
|
||||||
|
if (res.data) {
|
||||||
|
res.data.map((item) => {
|
||||||
|
item.name = item.name + `(${item.total})`
|
||||||
|
})
|
||||||
|
resolve(res.data)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
nodeClick(list, node) {
|
||||||
|
if(node.data.id) {
|
||||||
|
this.areaId = node.data.id
|
||||||
|
this.page.current = 1
|
||||||
|
}else {
|
||||||
|
this.areaId = ''
|
||||||
|
}
|
||||||
|
this.getInfo()
|
||||||
|
this.getTableData()
|
||||||
|
},
|
||||||
|
|
||||||
|
resetSearch() {
|
||||||
|
this.name = ''
|
||||||
|
this.page.current = 1
|
||||||
|
this.getTableData()
|
||||||
|
},
|
||||||
|
|
||||||
|
getInfo() {
|
||||||
|
this.info = {}
|
||||||
|
this.instance.post(`/appCorpStat/getLatestInfo?areaId=${this.areaId}`).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.info = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
getTableData() {
|
||||||
|
this.gropList = []
|
||||||
|
this.page.total = 0
|
||||||
|
this.instance.post(`/appCorp/page?areaId=${this.areaId}¤t=${this.page.current}&size=${this.page.size}&name=${this.name}`,).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
if(res.data) {
|
||||||
|
this.gropList = res.data.records
|
||||||
|
this.page.total = res.data.total
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.AppCorpStatistics {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
.ai-detail {
|
||||||
|
::v-deep .ai-detail__content {
|
||||||
|
.ai-detail__content--wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
height: 100%;
|
||||||
|
max-width: 100%;
|
||||||
|
padding: 15px;
|
||||||
|
|
||||||
|
.AiTreeMenu {
|
||||||
|
width: 22%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex {
|
||||||
|
width: 78%;
|
||||||
|
margin-left: 10px;
|
||||||
|
padding: 15px;
|
||||||
|
background-color: #fff;
|
||||||
|
overflow-y: scroll;
|
||||||
|
|
||||||
|
.ai-search-ba {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-table {
|
||||||
|
margin-top: 0 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-tree {
|
||||||
|
.el-tree-node__content {
|
||||||
|
display: inline-flex;
|
||||||
|
min-width: 100%;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #e8efff;
|
||||||
|
color: #222222;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-current > .el-tree-node__content {
|
||||||
|
background: #2266ff;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #2266ff;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #fff;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title{
|
||||||
|
line-height: 60px;
|
||||||
|
font-size: 18px;
|
||||||
|
text-align: center;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
.num{
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: 700;
|
||||||
|
text-align: center;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-row{
|
||||||
|
background-color: #eee;
|
||||||
|
margin: 0 0 16px!important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
66
project/oms/apps/AppFeedback/AppFeedback.vue
Normal file
66
project/oms/apps/AppFeedback/AppFeedback.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: 'AppFeedback',
|
||||||
|
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>
|
||||||
74
project/oms/apps/AppFeedback/components/Detail.vue
Normal file
74
project/oms/apps/AppFeedback/components/Detail.vue
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<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>
|
||||||
|
<ai-wrapper>
|
||||||
|
<ai-info-item label="意见详情" isLine :value="info.opinion"></ai-info-item>
|
||||||
|
<ai-info-item label="联系人" isLine :value="info.contacts"></ai-info-item>
|
||||||
|
<ai-info-item label="联系方式" isLine :value="info.phone"></ai-info-item>
|
||||||
|
<ai-info-item label="反馈平台" isLine :value="info.sourceHost"></ai-info-item>
|
||||||
|
<ai-info-item label="图片" isLine>
|
||||||
|
<ai-uploader v-model="info.images" disabled :instance="instance" :limit="9"></ai-uploader>
|
||||||
|
</ai-info-item>
|
||||||
|
</ai-wrapper>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
</template>
|
||||||
|
</ai-detail>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'Detail',
|
||||||
|
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
params: Object
|
||||||
|
},
|
||||||
|
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
info: {},
|
||||||
|
id: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created () {
|
||||||
|
if (this.params && this.params.id) {
|
||||||
|
this.id = this.params.id
|
||||||
|
this.getInfo(this.params.id)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
getInfo (id) {
|
||||||
|
this.instance.post(`/appfeedback/queryDetailById?id=${id}`).then(res => {
|
||||||
|
if (res.code === 0) {
|
||||||
|
this.info = res.data
|
||||||
|
this.info.images = res.data.pictureUrl ? res.data.pictureUrl.split(',').map(v => {
|
||||||
|
return {
|
||||||
|
url: v
|
||||||
|
}
|
||||||
|
}) : []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
cancel (isRefresh) {
|
||||||
|
this.$emit('change', {
|
||||||
|
type: 'list',
|
||||||
|
isRefresh: !!isRefresh
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
</style>
|
||||||
126
project/oms/apps/AppFeedback/components/List.vue
Normal file
126
project/oms/apps/AppFeedback/components/List.vue
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
<template>
|
||||||
|
<ai-list class="notice">
|
||||||
|
<template slot="title">
|
||||||
|
<ai-title title="意见反馈" isShowBottomBorder></ai-title>
|
||||||
|
</template>
|
||||||
|
<template slot="content">
|
||||||
|
<ai-search-bar class="search-bar">
|
||||||
|
<template slot="right">
|
||||||
|
<el-input
|
||||||
|
v-model="search.opinion"
|
||||||
|
class="search-input"
|
||||||
|
size="small"
|
||||||
|
@keyup.enter.native="search.current = 1, getList()"
|
||||||
|
placeholder="内容描述/上报人"
|
||||||
|
clearable
|
||||||
|
@change="getList"
|
||||||
|
@clear="search.current = 1, search.opinion = '', 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="120px" fixed="right" label="操作" align="center">
|
||||||
|
<div class="table-options" slot-scope="{ row }">
|
||||||
|
<el-button type="text" @click="toDetail(row.id)">详情</el-button>
|
||||||
|
<el-button type="text" @click="remove(row.id)">删除</el-button>
|
||||||
|
</div>
|
||||||
|
</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,
|
||||||
|
opinion: ''
|
||||||
|
},
|
||||||
|
currIndex: -1,
|
||||||
|
areaList: [],
|
||||||
|
total: 10,
|
||||||
|
colConfigs: [
|
||||||
|
{prop: 'opinion', label: '内容描述', align: 'left'},
|
||||||
|
{prop: 'contacts', label: '上报人', align: 'center' },
|
||||||
|
{prop: 'phone', label: '联系方式', align: 'center'},
|
||||||
|
{prop: 'sourceHost', label: '平台', align: 'center' },
|
||||||
|
{prop: 'createTime', label: '发布时间', align: 'center' },
|
||||||
|
{slot: 'options', label: '操作'}
|
||||||
|
],
|
||||||
|
tableData: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
...mapState(['user'])
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.getList()
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
getList() {
|
||||||
|
this.instance.post(`/appfeedback/list`, null, {
|
||||||
|
params: {
|
||||||
|
...this.search
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.tableData = res.data.records
|
||||||
|
this.total = res.data.total
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
remove(id) {
|
||||||
|
this.$confirm('确定删除该数据?').then(() => {
|
||||||
|
this.instance.post(`/appfeedback/delete?ids=${id}`).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message.success('删除成功!')
|
||||||
|
this.getList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
toDetail (id) {
|
||||||
|
this.$emit('change', {
|
||||||
|
type: 'Detail',
|
||||||
|
params: {
|
||||||
|
id: id || ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
||||||
178
project/oms/apps/AppLicense/AppLicense.vue
Normal file
178
project/oms/apps/AppLicense/AppLicense.vue
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
<template>
|
||||||
|
<section class="AppLicense">
|
||||||
|
<ai-list>
|
||||||
|
<ai-title slot="title" title="证书管理" isShowBottomBorder/>
|
||||||
|
<template #content>
|
||||||
|
<ai-search-bar>
|
||||||
|
<template #left>
|
||||||
|
<el-button type="primary" icon="iconfont iconAdd" @click="dialogForm={},dialog=true">添加</el-button>
|
||||||
|
</template>
|
||||||
|
<template #right>
|
||||||
|
<el-input size="small" placeholder="搜索证书名称" v-model="search.condition" clearable
|
||||||
|
@change="page.current=1,getTableData()"/>
|
||||||
|
</template>
|
||||||
|
</ai-search-bar>
|
||||||
|
<ai-table :tableData="tableData" :total="page.total" :current.sync="page.current" :size.sync="page.size"
|
||||||
|
@getList="getTableData" :col-configs="colConfigs" :dict="dict"
|
||||||
|
@selection-change="v=>ids=v.filter(e=>e.id).map(e=>e.id)">
|
||||||
|
<el-table-column slot="options" align="center" label="操作" fixed="right" width="160px">
|
||||||
|
<el-row type="flex" justify="center" align="middle" slot-scope="{row}">
|
||||||
|
<el-button type="text" @click="handleDownload(row.id)">下载</el-button>
|
||||||
|
<el-button type="text" @click="handleDelete(row.id)">删除</el-button>
|
||||||
|
</el-row>
|
||||||
|
</el-table-column>
|
||||||
|
</ai-table>
|
||||||
|
</template>
|
||||||
|
</ai-list>
|
||||||
|
<!--添加证书-->
|
||||||
|
<ai-dialog :title="dialogTitle" :visible.sync="dialog" width="600px"
|
||||||
|
@onConfirm="saveLicense">
|
||||||
|
<el-form ref="licenseForm" :model="dialogForm" :rules="rules" size="small"
|
||||||
|
label-width="120px">
|
||||||
|
<el-form-item required label="证书名称" prop="name">
|
||||||
|
<el-input v-model.trim="dialogForm.name" placeholder="请输入证书名称" clearable
|
||||||
|
:maxLength="100"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="主板序列号" prop="mainBoard">
|
||||||
|
<el-input v-model.trim="dialogForm.mainBoard" placeholder="请输入主板序列号" clearable
|
||||||
|
:maxLength="50"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item required label="CPU" prop="cpu">
|
||||||
|
<el-input v-model.trim="dialogForm.cpu" placeholder="请输入CPU信息" clearable
|
||||||
|
:maxLength="50"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item required label="MAC地址" prop="mac">
|
||||||
|
<el-input v-model.trim="dialogForm.mac" placeholder="请输入MAC地址" clearable
|
||||||
|
:maxLength="100"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="IP地址" prop="ipAddress">
|
||||||
|
<el-input v-model.trim="dialogForm.ipAddress" placeholder="请输入IP地址" clearable
|
||||||
|
:maxLength="100"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="过期日期" prop="expireDate">
|
||||||
|
<el-input v-model.trim="dialogForm.expireDate" placeholder="请输入过期日期" clearable
|
||||||
|
:maxLength="20"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ai-dialog>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "AppLicense",
|
||||||
|
label: "证书管理",
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
permissions: Function
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isEdit() {
|
||||||
|
return !!this.dialogForm.id
|
||||||
|
},
|
||||||
|
dialogTitle() {
|
||||||
|
return this.isEdit ? '修改证书' : '添加证书'
|
||||||
|
},
|
||||||
|
colConfigs() {
|
||||||
|
return [
|
||||||
|
{label: "证书名称", prop: "name"},
|
||||||
|
{label: "CPU", prop: "cpu", align: 'center'},
|
||||||
|
{label: "MAC地址", prop: "mac"},
|
||||||
|
{label: "主板序列号", prop: "mainBoard"},
|
||||||
|
{label: "IP地址", prop: "ipAddress"},
|
||||||
|
{label: "过期日期", prop: "expireDate"},
|
||||||
|
{label: "创建时间", prop: "createTime"},
|
||||||
|
{slot: "options"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
rules() {
|
||||||
|
return {
|
||||||
|
name: [{required: true, message: "请输入证书名称"}],
|
||||||
|
cpu: [{required: true, message: "请输入CPU信息"}],
|
||||||
|
mac: [{required: true, message: "请输入MAC地址"}],
|
||||||
|
mainBoard: [{required: true, message: "请输入主板序列号"}],
|
||||||
|
ipAddress: [{required: true, message: "请输入IP地址"}],
|
||||||
|
expireDate: [{required: true, message: "请选择过期日期"}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
page: {current: 1, size: 10, total: 0},
|
||||||
|
dialog: false,
|
||||||
|
dialogForm: {},
|
||||||
|
tableData: [],
|
||||||
|
search: {condition: ""},
|
||||||
|
ids: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getTableData() {
|
||||||
|
this.instance.post("/sysLicense/page", null, {
|
||||||
|
params: {...this.page, ...this.search}
|
||||||
|
}).then(res => {
|
||||||
|
if (res?.data) {
|
||||||
|
this.tableData = res.data?.records
|
||||||
|
this.page.total = res.data.total
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 新增/修改
|
||||||
|
saveLicense() {
|
||||||
|
this.$refs.licenseForm.validate(v => {
|
||||||
|
if (v) {
|
||||||
|
this.instance.post("/sysLicense/save", this.dialogForm).then(res => {
|
||||||
|
if (res?.code == 0) {
|
||||||
|
this.dialog = false;
|
||||||
|
this.$message.success("保存成功")
|
||||||
|
this.getTableData();
|
||||||
|
} else {
|
||||||
|
this.$message.error(res?.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleDelete(ids) {
|
||||||
|
this.$confirm("是否要删除该证书信息?").then(() => {
|
||||||
|
this.instance.post("/sysLicense/delete", null, {
|
||||||
|
params: {ids}
|
||||||
|
}).then(res => {
|
||||||
|
if (res?.code == 0) {
|
||||||
|
this.getTableData();
|
||||||
|
this.$message.success("删除成功!");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).catch(() => 0)
|
||||||
|
},
|
||||||
|
handleDownload(id) {
|
||||||
|
this.instance.post("/sysLicense/create?id="+id, null, {responseType: 'blob'}).then(res => {
|
||||||
|
const link = document.createElement('a')
|
||||||
|
console.log(res.type)
|
||||||
|
let blob = new Blob([res], {type: res.type})
|
||||||
|
link.style.display = 'none'
|
||||||
|
link.href = URL.createObjectURL(blob)
|
||||||
|
link.setAttribute('download', 'license.lic')
|
||||||
|
document.body.appendChild(link)
|
||||||
|
link.click()
|
||||||
|
document.body.removeChild(link)
|
||||||
|
|
||||||
|
}).catch(() => {
|
||||||
|
this.$message.error("证书生成失败!");
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getTableData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.AppLicense {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
416
project/oms/apps/AppRoleRightsManager/AppRoleRightsManager.vue
Normal file
416
project/oms/apps/AppRoleRightsManager/AppRoleRightsManager.vue
Normal file
@@ -0,0 +1,416 @@
|
|||||||
|
<template>
|
||||||
|
<section class="AppRoleRightsManager">
|
||||||
|
<ai-list v-if="!showDetail">
|
||||||
|
<ai-title slot="title" title="角色管理" isShowBottomBorder/>
|
||||||
|
<template #content>
|
||||||
|
<ai-search-bar>
|
||||||
|
<template #right>
|
||||||
|
<el-input
|
||||||
|
size="small"
|
||||||
|
v-model="search.roleName"
|
||||||
|
placeholder="角色名称"
|
||||||
|
clearable
|
||||||
|
@change="searchList()"
|
||||||
|
suffix-icon="iconfont iconSearch"/>
|
||||||
|
</template>
|
||||||
|
</ai-search-bar>
|
||||||
|
<ai-search-bar>
|
||||||
|
<template #left>
|
||||||
|
<el-button size="small" type="primary" icon="iconfont iconAdd"
|
||||||
|
@click="$router.push({hash:'#add'})"
|
||||||
|
v-if="$permissions('admin_sysapprole_add')">
|
||||||
|
添加
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
size="small"
|
||||||
|
icon="iconfont iconDelete"
|
||||||
|
:disabled="!multipleSelection.length"
|
||||||
|
class="del-btn-list"
|
||||||
|
@click="deleteApp('all')"
|
||||||
|
v-if="$permissions('admin_sysapprole_del')"
|
||||||
|
>删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</ai-search-bar>
|
||||||
|
<ai-table :tableData="adminList" :colConfigs="colConfigs" :total="total" :current.sync="page.pageNum"
|
||||||
|
:size.sync="page.pageSize"
|
||||||
|
@getList="getTableData" :col-configs="colConfigs" :dict="dict"
|
||||||
|
@selection-change="v=>multipleSelection=v">
|
||||||
|
<el-table-column label="角色用户" slot="users" align="center">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<el-tooltip
|
||||||
|
effect="light"
|
||||||
|
placement="top"
|
||||||
|
:disabled="scope.row.users.length <= 2"
|
||||||
|
content="更多角色用户请点击详情按钮">
|
||||||
|
<span v-if="scope.row.users.length">
|
||||||
|
{{
|
||||||
|
scope.row.users
|
||||||
|
.slice(0, 2)
|
||||||
|
.map((e) => e.name + "(" + e.phone + ")")
|
||||||
|
.join(";")
|
||||||
|
}}
|
||||||
|
<span v-if="scope.row.users.length > 2">...</span>
|
||||||
|
</span>
|
||||||
|
<span v-else>-</span>
|
||||||
|
</el-tooltip>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column slot="options" label="操作" fixed="right" align="center">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<el-button type="text" @click="beforeCopy(row)" v-if="$permissions('admin_sysapprole_edit')">复制
|
||||||
|
</el-button>
|
||||||
|
<el-button type="text" @click="viewApp(row)" v-if="$permissions('admin_sysapprole_detail')">详情
|
||||||
|
</el-button>
|
||||||
|
<el-button type="text" @click="openRightsGraph(row)" v-if="$permissions('admin_sysapprole_detail')">关系图
|
||||||
|
</el-button>
|
||||||
|
<el-button type="text" @click="toAddAppRole(row)" v-if="$permissions('admin_sysapprole_edit')">编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button type="text" @click="deleteApp(row)" v-if="$permissions('admin_sysapprole_del')">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</ai-table>
|
||||||
|
<ai-dialog
|
||||||
|
title="应用角色详情"
|
||||||
|
:visible.sync="viewShow"
|
||||||
|
width="600px"
|
||||||
|
customFooter>
|
||||||
|
<ai-card title="基本信息">
|
||||||
|
<template #content>
|
||||||
|
<ai-wrapper>
|
||||||
|
<ai-info-item label="应用角色名称" :value="viewInfo.name" isLine/>
|
||||||
|
</ai-wrapper>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
<ai-card title="权限信息">
|
||||||
|
<template #content>
|
||||||
|
<div style="margin-bottom: 16px" v-text="roleList.map(e => e.name).join('、')"/>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
<ai-card title="角色账号">
|
||||||
|
<template #right>
|
||||||
|
<span style="text-align: right; color: #999">
|
||||||
|
共<span style="color: #26f" v-text="userList.length"/>个账号
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<template #content>
|
||||||
|
<div class="datail-table-body" v-if="userList.length">
|
||||||
|
<div class="datail-item" v-for="(item, index) in userList" :key="index">
|
||||||
|
<span class="item-name">{{ item.name }}</span>
|
||||||
|
<span style="color: #999">{{ item.phone }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
<template #footer>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
@click="toAddAppRole(viewInfo)"
|
||||||
|
v-if="$permissions('admin_sysapprole_edit')"
|
||||||
|
>编辑角色
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</ai-dialog>
|
||||||
|
<ai-dialog title="权限关系图" :visible.sync="rightsGraph" class="rightsGraphDialog" customFooter>
|
||||||
|
<rights-graph :instance="instance" :dict="dict" :app="selectApp"/>
|
||||||
|
<el-button slot="footer" @click="rightsGraph=false">关闭</el-button>
|
||||||
|
</ai-dialog>
|
||||||
|
<!--复制角色-->
|
||||||
|
<el-dialog
|
||||||
|
class="editStyle"
|
||||||
|
:visible.sync="copyDialog"
|
||||||
|
width="520px"
|
||||||
|
@close="dataInit()"
|
||||||
|
title="复制角色">
|
||||||
|
<el-form :model="form" label-width="80px">
|
||||||
|
<el-form-item label="角色名" :rules="[{ required: true, message: '', trigger: 'blur' }]">
|
||||||
|
<el-input
|
||||||
|
v-model="editName"
|
||||||
|
placeholder="请输入..."
|
||||||
|
size="small"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" style="text-align: center">
|
||||||
|
<el-button
|
||||||
|
style="width: 92px"
|
||||||
|
size="small"
|
||||||
|
@click="copyDialog = false"
|
||||||
|
>取消
|
||||||
|
</el-button
|
||||||
|
>
|
||||||
|
<el-button
|
||||||
|
style="width: 92px"
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
@click="copyFn()"
|
||||||
|
:disabled="!editName"
|
||||||
|
>
|
||||||
|
确认
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
</ai-list>
|
||||||
|
<rights-add v-else :instance="instance" :dict="dict" :permissions="permissions"/>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import RightsAdd from "./rightsAdd";
|
||||||
|
import RightsGraph from "./rightsGraph";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "AppRoleRightsManager",
|
||||||
|
components: {RightsGraph, RightsAdd},
|
||||||
|
label: "权限管理(运营平台版)",
|
||||||
|
provide() {
|
||||||
|
return {
|
||||||
|
top: this
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
permissions: Function,
|
||||||
|
actions: {
|
||||||
|
default: () => ({
|
||||||
|
list: '/admin/role/page',
|
||||||
|
apps: '/admin/role/list-all',
|
||||||
|
delete: '/admin/role/del',
|
||||||
|
detail: '/admin/role/queryById-checked',
|
||||||
|
modify: '/admin/role/modify',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
colConfigs() {
|
||||||
|
return [
|
||||||
|
{type: "selection"},
|
||||||
|
{label: "角色名", prop: "name", width: '100px'},
|
||||||
|
{label: "用户数量", prop: "roleCount", align: 'center', width: '80px'},
|
||||||
|
{slot: "users"},
|
||||||
|
{slot: "options"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
showDetail() {
|
||||||
|
return this.$route.hash == "#add"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
page: {pageNum: 1, pageSize: 10},
|
||||||
|
search: {roleName: ''},
|
||||||
|
adminList: [], //列表数据
|
||||||
|
total: 0,
|
||||||
|
multipleSelection: [],
|
||||||
|
delShow: false,
|
||||||
|
delParams: "",
|
||||||
|
delIds: [],
|
||||||
|
viewShow: false,
|
||||||
|
viewInfo: {},
|
||||||
|
roleList: [], //详情权限列表
|
||||||
|
row: {},
|
||||||
|
copyDialog: false,
|
||||||
|
titleDel: "",
|
||||||
|
form: {},
|
||||||
|
editName: "",
|
||||||
|
userList: [],
|
||||||
|
rightsGraph: false,
|
||||||
|
selectApp: {}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getTableData();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
//查询table列表
|
||||||
|
getTableData() {
|
||||||
|
this.adminList = [];
|
||||||
|
this.instance.post(this.actions.list, null, {
|
||||||
|
params: {...this.page, ...this.search}
|
||||||
|
}).then(res => {
|
||||||
|
if (res?.data) {
|
||||||
|
this.total = res.data.total;
|
||||||
|
this.adminList = res.data.records;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
//查询
|
||||||
|
searchList() {
|
||||||
|
this.page.pageNum = 1;
|
||||||
|
this.getTableData();
|
||||||
|
},
|
||||||
|
//添加按钮
|
||||||
|
toAddAppRole(item) {
|
||||||
|
this.$router.push({
|
||||||
|
hash: "#add",
|
||||||
|
query: {
|
||||||
|
id: item.id,
|
||||||
|
name: item.name
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
//删除
|
||||||
|
deleteApp(e) {
|
||||||
|
if (e == "all") {
|
||||||
|
this.multipleSelection.map((item) => {
|
||||||
|
this.delIds.push(item.id);
|
||||||
|
});
|
||||||
|
this.delParams = `ids=${this.delIds}`;
|
||||||
|
this.titleDel = "确定要执行删除操作吗?";
|
||||||
|
} else {
|
||||||
|
this.delParams = `ids=${e.id}`;
|
||||||
|
this.titleDel = "确定需要删除该角色吗?";
|
||||||
|
}
|
||||||
|
this.$confirm(this.titleDel, {
|
||||||
|
type: "error",
|
||||||
|
}).then(() => {
|
||||||
|
this.instance.post(`${this.actions.delete}?${this.delParams}`).then(res => {
|
||||||
|
if (res?.msg == "success") {
|
||||||
|
this.getTableData();
|
||||||
|
} else {
|
||||||
|
this.$message.error(res.msg);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}).catch(() => 0);
|
||||||
|
},
|
||||||
|
//查看信息
|
||||||
|
viewApp(e) {
|
||||||
|
this.userList = e.users;
|
||||||
|
this.viewInfo = e;
|
||||||
|
this.viewShow = true;
|
||||||
|
this.getRowInfo(this.viewInfo.appId, this.viewInfo.id);
|
||||||
|
},
|
||||||
|
//查询 row 信息
|
||||||
|
getRowInfo(appId, id) {
|
||||||
|
this.roleList = [];
|
||||||
|
this.instance.post(`${this.actions.detail}?id=${appId}&roleId=${id}`)
|
||||||
|
.then(res => {
|
||||||
|
if (res?.data) {
|
||||||
|
this.roleList = res.data.filter(e => e.checked)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
//复制
|
||||||
|
beforeCopy(row) {
|
||||||
|
this.row = row;
|
||||||
|
this.copyDialog = true;
|
||||||
|
this.getRowInfo(this.row.appId, this.row.id);
|
||||||
|
},
|
||||||
|
//确认复制
|
||||||
|
copyFn() {
|
||||||
|
let crr = [];
|
||||||
|
let appRoleList = this.roleList;
|
||||||
|
for (let i = 0; i < appRoleList.length; i++) {
|
||||||
|
if (appRoleList[i].checked) {
|
||||||
|
crr.push(appRoleList[i].id);
|
||||||
|
if (appRoleList[i].list.length) {
|
||||||
|
for (let j = 0; j < appRoleList[i].list.length; j++) {
|
||||||
|
if (appRoleList[i].list[j].checked) {
|
||||||
|
crr.push(appRoleList[i].list[j].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.instance.post(`${this.actions.modify}?menus=${crr}`, null, {
|
||||||
|
params: {
|
||||||
|
roleName: this.editName,
|
||||||
|
appId: this.row.appId,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((res) => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message({message: "复制成功", type: "success"});
|
||||||
|
this.copyDialog = false;
|
||||||
|
this.searchList()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
dataInit() {
|
||||||
|
this.multipleSelection = [];
|
||||||
|
this.row = {};
|
||||||
|
},
|
||||||
|
openRightsGraph(row) {
|
||||||
|
this.rightsGraph = true
|
||||||
|
this.selectApp = row
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.AppRoleRightsManager {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
|
||||||
|
::v-deep .ai-dialog {
|
||||||
|
.ai-card {
|
||||||
|
box-shadow: none;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
|
||||||
|
.aibar {
|
||||||
|
height: 40px;
|
||||||
|
background: #f3f6f9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-card__body {
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .rightsGraphDialog {
|
||||||
|
.el-dialog__body {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ai-dialog__content {
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .datail-table-body {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
.datail-item {
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 50%;
|
||||||
|
height: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
|
||||||
|
span {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-name {
|
||||||
|
width: 102px;
|
||||||
|
padding-left: 16px;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.datail-item:nth-of-type(2n - 1) {
|
||||||
|
border-right: 1px solid rgba(208, 212, 220, 1);
|
||||||
|
width: calc(50% - 1px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.padd-l0 {
|
||||||
|
padding-left: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pad-l16 {
|
||||||
|
padding-left: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
190
project/oms/apps/AppRoleRightsManager/rightsAdd.vue
Normal file
190
project/oms/apps/AppRoleRightsManager/rightsAdd.vue
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
<template>
|
||||||
|
<ai-detail class="rightsAdd">
|
||||||
|
<ai-title :title="addTitle" slot="title" isShowBottomBorder isShowBack @onBackClick="back"/>
|
||||||
|
<template #content>
|
||||||
|
<el-form size="small" ref="rightsForm" :model="form" label-width="120px" :rules="rules">
|
||||||
|
<ai-card title="基本信息">
|
||||||
|
<template #content>
|
||||||
|
<el-form-item label="应用角色名称" prop="roleName">
|
||||||
|
<el-input v-model="form.roleName" placeholder="请输入应用角色名称" clearable/>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
<ai-card title="权限信息">
|
||||||
|
<template #content>
|
||||||
|
<el-form-item label="权限列表" prop="menus">
|
||||||
|
<div class="roleList">
|
||||||
|
<el-input v-model="filterText" placeholder="请输入..." clearable suffix-icon="iconfont iconSearch"
|
||||||
|
@change="$refs.tree.filter(filterText)" :validate-event="false"/>
|
||||||
|
<div class="tree_list">
|
||||||
|
<el-tree class="filter-tree" ref="roleTree"
|
||||||
|
:data="roleList"
|
||||||
|
show-checkbox
|
||||||
|
:props="defaultProps"
|
||||||
|
default-expand-all
|
||||||
|
:check-strictly="false"
|
||||||
|
node-key="id"
|
||||||
|
:default-checked-keys="form.menus"
|
||||||
|
:filter-node-method="filterNode"
|
||||||
|
@check="handleMenusSelect"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="back()">取消</el-button>
|
||||||
|
<el-button type="primary" @click="confirm">保存</el-button>
|
||||||
|
</template>
|
||||||
|
</ai-detail>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "rightsAdd",
|
||||||
|
inject: ['top'],
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
permissions: Function
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
form: {},
|
||||||
|
roleName: '',
|
||||||
|
id: '',
|
||||||
|
appList: [],
|
||||||
|
roleList: [],
|
||||||
|
defaultProps: {
|
||||||
|
children: 'list',
|
||||||
|
label: 'name'
|
||||||
|
},
|
||||||
|
treeList: [],
|
||||||
|
filterText: '',
|
||||||
|
msgTitle: '添加'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
if (this.isEdit) {
|
||||||
|
let {id, name: roleName} = this.$route.query
|
||||||
|
this.form = {menus: [], id, roleName}
|
||||||
|
this.msgTitle = '编辑'
|
||||||
|
}
|
||||||
|
this.getPermissions()
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isEdit() {
|
||||||
|
return this.$route.query.id
|
||||||
|
},
|
||||||
|
addTitle() {
|
||||||
|
return this.isEdit ? '编辑应用角色' : '新增应用角色'
|
||||||
|
},
|
||||||
|
rules() {
|
||||||
|
return {
|
||||||
|
roleName: {required: true, message: '请输入应用角色名称'},
|
||||||
|
menus: {required: true, message: '请选择权限列表内容'},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
filterNode(value, data) {
|
||||||
|
if (!value) return true;
|
||||||
|
return data.name.indexOf(value) !== -1;
|
||||||
|
},
|
||||||
|
//应用名称选择 获取权限列表
|
||||||
|
getId(data) {
|
||||||
|
if (data.list.length) {
|
||||||
|
data.list.forEach(item => {
|
||||||
|
this.getId(item)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
if (data.checked) {
|
||||||
|
this.form.menus?.push(data.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getPermissions() {
|
||||||
|
this.filterText = ''
|
||||||
|
let {id: roleId} = this.form
|
||||||
|
this.instance.post(this.top.actions.detail, null, {
|
||||||
|
params: {roleId}
|
||||||
|
}).then(res => {
|
||||||
|
if (res?.data) {
|
||||||
|
this.roleList = res.data;
|
||||||
|
if (this.isEdit) {
|
||||||
|
this.roleList.forEach(e => this.getId(e))
|
||||||
|
}
|
||||||
|
this.roleList = this.roleList.filter(item => !(item.component && item.isApp == 0 && item.isMenu == 0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleMenusSelect(node, selected) {
|
||||||
|
this.$set(this.form, 'menus', [...selected?.checkedKeys])
|
||||||
|
this.$refs.rightsForm.validateField('menus')
|
||||||
|
},
|
||||||
|
//保存提交
|
||||||
|
confirm() {
|
||||||
|
this.$refs.rightsForm.validate(v => {
|
||||||
|
if (v) {
|
||||||
|
let menus = [this.$refs.roleTree?.getHalfCheckedKeys(), this.$refs.roleTree?.getCheckedKeys()]?.flat()?.toString()
|
||||||
|
this.instance.post(this.top.actions.modify, null, {
|
||||||
|
params: {...this.form, menus}
|
||||||
|
}).then(res => {
|
||||||
|
if (res?.msg == "success") {
|
||||||
|
this.$message.success(`${this.msgTitle}应用角色成功`)
|
||||||
|
this.back()
|
||||||
|
this.top.searchList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
//取消 返回
|
||||||
|
back() {
|
||||||
|
this.$router.push({})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.rightsAdd {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.el-form-item {
|
||||||
|
.el-select {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-error {
|
||||||
|
.roleList {
|
||||||
|
border-color: #f46;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.roleList {
|
||||||
|
background-color: #fcfcfc;
|
||||||
|
border-radius: 2px;
|
||||||
|
border: solid 1px #d0d4dc;
|
||||||
|
padding: 8px;
|
||||||
|
|
||||||
|
.input {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 5px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree_list {
|
||||||
|
padding: 5px;
|
||||||
|
height: 370px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
192
project/oms/apps/AppRoleRightsManager/rightsGraph.vue
Normal file
192
project/oms/apps/AppRoleRightsManager/rightsGraph.vue
Normal file
@@ -0,0 +1,192 @@
|
|||||||
|
<template>
|
||||||
|
<section class="rightsGraph">
|
||||||
|
<div id="RightGraph"/>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as echarts from "echarts";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "rightsGraph",
|
||||||
|
inject: ['top'],
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
app: Object
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
graphData() {
|
||||||
|
let data = [...this.users, ...this.nodes].map(e => {
|
||||||
|
if (e.x) {
|
||||||
|
return e
|
||||||
|
} else return {...e, ...this.renderPosition(e)}
|
||||||
|
})
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
data,
|
||||||
|
links: this.links,
|
||||||
|
categories: data.map(e => e.category).flat().map(name => ({name}))
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
graph: null,
|
||||||
|
nodes: [],
|
||||||
|
links: [],
|
||||||
|
users: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
graphData: {
|
||||||
|
deep: true, handler() {
|
||||||
|
this.refreshGraph()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
initGraph() {
|
||||||
|
let dom = document.querySelector("#RightGraph")
|
||||||
|
if (dom) {
|
||||||
|
this.graph = echarts.init(dom)
|
||||||
|
this.graph.setOption({
|
||||||
|
tooltip: {},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: 'graph',
|
||||||
|
layout: 'none',
|
||||||
|
roam: true,
|
||||||
|
label: {
|
||||||
|
show: true,
|
||||||
|
position: 'right',
|
||||||
|
formatter: '{b}'
|
||||||
|
},
|
||||||
|
labelLayout: {
|
||||||
|
hideOverlap: true,
|
||||||
|
},
|
||||||
|
scaleLimit: {
|
||||||
|
min: 0.4,
|
||||||
|
max: 4
|
||||||
|
},
|
||||||
|
lineStyle: {
|
||||||
|
color: 'target',
|
||||||
|
curveness: 0.1
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
focus: 'adjacency',
|
||||||
|
lineStyle: {
|
||||||
|
width: 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
this.graph.on('click', this.handleNodeClick)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
refreshGraph() {
|
||||||
|
this.graph?.setOption({
|
||||||
|
series: this.graphData
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getAppRoles(role) {
|
||||||
|
if (role) {
|
||||||
|
this.nodes.push({...role, category: '应用角色', value: "应用角色", symbolSize: 15})
|
||||||
|
} else this.instance.post(this.top.actions.list, null, {
|
||||||
|
params: {pageSize: 999}
|
||||||
|
}).then(res => {
|
||||||
|
if (res?.data) {
|
||||||
|
res.data.records.map(e => {
|
||||||
|
this.getUsers(e.users, e.id)
|
||||||
|
this.nodes.push({...e, category: '应用角色', value: "应用角色"})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getUsers(pending, source) {
|
||||||
|
pending?.map(e => {
|
||||||
|
if (!this.users.some(u => u.id == e.phone)) {
|
||||||
|
this.users.push({id: e.phone, name: e.name, symbolSize: 5, category: '用户', value: "用户"})
|
||||||
|
}
|
||||||
|
this.links.push({source, target: e.phone})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
getPermissions({id: roleId, name: category, dataIndex}) {
|
||||||
|
const addNodes = (list, source, category, pos) => {
|
||||||
|
list?.map(e => {
|
||||||
|
let node = {
|
||||||
|
...e,
|
||||||
|
symbolSize: 5,
|
||||||
|
category,
|
||||||
|
value: e.list?.length > 0 ? "应用" : "权限",
|
||||||
|
}
|
||||||
|
node = {...node, ...this.renderPosition(pos || node)}
|
||||||
|
this.nodes.splice(dataIndex, 0, node)
|
||||||
|
if (e.checked == 1) {
|
||||||
|
this.links.push({source, target: e.id})
|
||||||
|
}
|
||||||
|
addNodes(e.list, e.id, e.label, node)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
roleId && this.instance.post(this.top.actions.detail, null, {
|
||||||
|
params: {roleId}
|
||||||
|
}).then(res => {
|
||||||
|
if (res?.data) {
|
||||||
|
addNodes(res.data, roleId, category)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleNodeClick(v) {
|
||||||
|
let {data: role, dataIndex} = v
|
||||||
|
if (!this.nodes.some(e => e.category == role?.name)) {
|
||||||
|
role && this.getPermissions({...role, dataIndex})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
renderPosition(node) {
|
||||||
|
node = JSON.parse(JSON.stringify(node))
|
||||||
|
let pos = {x: 0, y: 0}
|
||||||
|
if (node?.x) {
|
||||||
|
pos.x = Math.max(this.graph?.getWidth() / 3 * 2, node.x) + 100 + Math.random() * 50
|
||||||
|
pos.y = node.y + Math.random() * 100 - 50
|
||||||
|
} else if (node.value == '应用角色') {
|
||||||
|
pos.x = this.graph?.getWidth() / 3 - 200 + Math.random() * 200
|
||||||
|
pos.y = this.graph?.getHeight() / 2 - 100 + Math.random() * 200
|
||||||
|
} else if (node.value == '应用') {
|
||||||
|
pos.x = this.graph?.getWidth() / 3 * 2 - 100 + Math.random() * 100
|
||||||
|
pos.y = Math.random() * this.graph?.getHeight()
|
||||||
|
} else if (node.value == '用户') {
|
||||||
|
pos.x = Math.random() * 50
|
||||||
|
pos.y = Math.random() * this.graph?.getHeight()
|
||||||
|
} else {
|
||||||
|
pos.x = this.graph?.getWidth() - 100 + Math.random() * 100
|
||||||
|
pos.y = Math.random() * this.graph?.getHeight()
|
||||||
|
}
|
||||||
|
return pos
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getAppRoles(this.app)
|
||||||
|
this.getUsers(this.app.users, this.app.id)
|
||||||
|
this.getPermissions(this.app)
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.initGraph()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.rightsGraph {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
::v-deep #RightGraph {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 500px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
197
project/oms/apps/AppSaas/AppSaas.vue
Normal file
197
project/oms/apps/AppSaas/AppSaas.vue
Normal file
@@ -0,0 +1,197 @@
|
|||||||
|
<template>
|
||||||
|
<section class="AppSaas">
|
||||||
|
<ai-list>
|
||||||
|
<ai-title slot="title" title="平台配置" isShowBottomBorder/>
|
||||||
|
<template #content>
|
||||||
|
<ai-search-bar>
|
||||||
|
<template #left>
|
||||||
|
<el-button type="primary" icon="iconfont iconAdd" @click="dialogForm = {}, dialog=true">添加</el-button>
|
||||||
|
</template>
|
||||||
|
<template #right>
|
||||||
|
<el-input size="small" placeholder="搜索名称" v-model="search.condition" clearable
|
||||||
|
@change="page.current=1,getTableData()"/>
|
||||||
|
</template>
|
||||||
|
</ai-search-bar>
|
||||||
|
<ai-table :tableData="tableData" :total="page.total" :current.sync="page.current" :size.sync="page.size"
|
||||||
|
@getList="getTableData" :col-configs="colConfigs" :dict="dict"
|
||||||
|
@selection-change="v=>ids=v.filter(e=>e.id).map(e=>e.id)">
|
||||||
|
<el-table-column slot="options" align="center" label="操作" fixed="right" width="240px">
|
||||||
|
<el-row type="flex" justify="center" align="middle" slot-scope="{row}">
|
||||||
|
<el-button type="text" @click="handleEnter(row.accessUrl)">打开</el-button>
|
||||||
|
<el-button type="text" @click="handleUpdate(row)">修改</el-button>
|
||||||
|
<el-button type="text" @click="handleUpdatePwd(row)">修改密码</el-button>
|
||||||
|
<el-button type="text" @click="handleDelete(row.id)">删除</el-button>
|
||||||
|
</el-row>
|
||||||
|
</el-table-column>
|
||||||
|
</ai-table>
|
||||||
|
</template>
|
||||||
|
</ai-list>
|
||||||
|
<!--添加SAAS平台-->
|
||||||
|
<ai-dialog :title="dialogTitle" :visible.sync="dialog" width="600px"
|
||||||
|
@onConfirm="saveSaas">
|
||||||
|
<el-form ref="saasForm" :model="dialogForm" :rules="rules" size="small"
|
||||||
|
label-width="120px">
|
||||||
|
<el-form-item required label="名称" prop="name">
|
||||||
|
<el-input v-model.trim="dialogForm.name" placeholder="请输入SaaS平台名称" clearable
|
||||||
|
:maxLength="50"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item required label="账号" prop="username">
|
||||||
|
<el-input v-model.trim="dialogForm.username" placeholder="请输入平台账号" clearable
|
||||||
|
:maxLength="50"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item required label="密码" prop="password" v-if="!isEdit" :rules="[{required: true, message: '请输入平台密码'}]">
|
||||||
|
<el-input v-model.trim="dialogForm.password" placeholder="请输入平台密码" clearable
|
||||||
|
:maxLength="100"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="访问地址" prop="accessUrl">
|
||||||
|
<el-input v-model.trim="dialogForm.accessUrl" placeholder="请输入访问地址" clearable
|
||||||
|
:maxLength="255"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ai-dialog>
|
||||||
|
<!--修改密码-->
|
||||||
|
<ai-dialog title="修改密码" :visible.sync="updateDialog" width="600px"
|
||||||
|
@onConfirm="updatePwd">
|
||||||
|
<el-form ref="updatePwdForm" :model="updatePwdForm" :rules="updateRules" size="small"
|
||||||
|
label-width="120px">
|
||||||
|
<el-form-item required label="密码" prop="password">
|
||||||
|
<el-input v-model.trim="updatePwdForm.password" placeholder="请输入平台密码" clearable
|
||||||
|
:maxLength="100"/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</ai-dialog>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "AppSaas",
|
||||||
|
label: "Saas平台管理",
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
permissions: Function
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isEdit() {
|
||||||
|
return !!this.dialogForm.id
|
||||||
|
},
|
||||||
|
dialogTitle() {
|
||||||
|
return this.isEdit ? '修改SaaS平台' : '添加SaaS平台'
|
||||||
|
},
|
||||||
|
colConfigs() {
|
||||||
|
return [
|
||||||
|
{label: "名称", prop: "name"},
|
||||||
|
{label: "账号", prop: "username", align: 'center'},
|
||||||
|
{label: "访问地址", prop: "accessUrl"},
|
||||||
|
{label: "创建时间", prop: "createTime"},
|
||||||
|
{slot: "options"}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
rules() {
|
||||||
|
return {
|
||||||
|
name: [{required: true, message: "请输入SaaS平台名称"}],
|
||||||
|
username: [{required: true, message: "请输入平台账号"}],
|
||||||
|
accessUrl: [{required: true, message: "请输入访问地址"}]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateRules() {
|
||||||
|
return {
|
||||||
|
password: [{required: true, message: "请输入平台密码"}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
page: {current: 1, size: 10, total: 0},
|
||||||
|
dialog: false,
|
||||||
|
updateDialog: false,
|
||||||
|
dialogForm: {},
|
||||||
|
updatePwdForm: {password: ''},
|
||||||
|
tableData: [],
|
||||||
|
search: {condition: ""},
|
||||||
|
ids: [],
|
||||||
|
currentSaas: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getTableData() {
|
||||||
|
this.instance.post("/appSaas/page", null, {
|
||||||
|
params: {...this.page, ...this.search}
|
||||||
|
}).then(res => {
|
||||||
|
if (res?.data) {
|
||||||
|
this.tableData = res.data?.records
|
||||||
|
this.page.total = res.data.total
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 新增/修改
|
||||||
|
saveSaas() {
|
||||||
|
this.$refs.saasForm.validate(v => {
|
||||||
|
if (v) {
|
||||||
|
this.instance.post("/appSaas/addOrUpdate", this.dialogForm).then(res => {
|
||||||
|
if (res?.code == 0) {
|
||||||
|
this.dialog = false;
|
||||||
|
this.$message.success("保存成功")
|
||||||
|
this.getTableData();
|
||||||
|
} else {
|
||||||
|
this.$message.error(res?.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 新增/修改
|
||||||
|
updatePwd() {
|
||||||
|
this.$refs.updatePwdForm.validate(v => {
|
||||||
|
if (v) {
|
||||||
|
this.updatePwdForm.id = this.currentSaas.id
|
||||||
|
this.instance.post("/appSaas/updatePwd", null, {params: this.updatePwdForm}).then(res => {
|
||||||
|
if (res?.code == 0) {
|
||||||
|
this.updateDialog = false;
|
||||||
|
this.$message.success("密码修改成功")
|
||||||
|
} else {
|
||||||
|
this.$message.error(res?.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
handleUpdatePwd(row) {
|
||||||
|
this.currentSaas = row
|
||||||
|
this.updatePwdForm.password = ''
|
||||||
|
this.updateDialog = true
|
||||||
|
},
|
||||||
|
handleUpdate(row) {
|
||||||
|
this.dialogForm = row
|
||||||
|
this.dialog = true
|
||||||
|
},
|
||||||
|
handleDelete(ids) {
|
||||||
|
this.$confirm("是否要删除该Saas信息?").then(() => {
|
||||||
|
this.instance.post("/appSaas/delete", null, {
|
||||||
|
params: {ids}
|
||||||
|
}).then(res => {
|
||||||
|
if (res?.code == 0) {
|
||||||
|
this.getTableData();
|
||||||
|
this.$message.success("删除成功!");
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).catch(() => 0)
|
||||||
|
},
|
||||||
|
handleEnter(accessUrl) {
|
||||||
|
window.open(accessUrl, "_blank");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getTableData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.AppSaas {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
8
project/oms/core.import.json
Normal file
8
project/oms/core.import.json
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"AppDictionary": "数据字典",
|
||||||
|
"AppRightsManager": "权限管理",
|
||||||
|
"AppMenuManager": "菜单管理",
|
||||||
|
"AppSystemAccount": "账号管理",
|
||||||
|
"AppQyWxConfig": "企业微信配置",
|
||||||
|
"AppUserInfo": "个人中心"
|
||||||
|
}
|
||||||
15
project/oms/package.json
Normal file
15
project/oms/package.json
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "dvcp-oms",
|
||||||
|
"description": "运营中心分包",
|
||||||
|
"version": "2.0.0",
|
||||||
|
"main": "dist/dvcp-oms.common.js",
|
||||||
|
"files": [
|
||||||
|
"dist"
|
||||||
|
],
|
||||||
|
"publishConfig": {
|
||||||
|
"registry": "http://192.168.1.87:4873/"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"dvcp-ui": "^1.42.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,5 +30,6 @@
|
|||||||
"AppPartyOrganization": "党组织管理",
|
"AppPartyOrganization": "党组织管理",
|
||||||
"AppPartyMember": "党员管理",
|
"AppPartyMember": "党员管理",
|
||||||
"AppLicence": "产品许可",
|
"AppLicence": "产品许可",
|
||||||
"AppContentManage": "内容中心"
|
"AppContentManage": "内容中心",
|
||||||
|
"AppResident": "居民档案"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,195 +0,0 @@
|
|||||||
<template>
|
|
||||||
<section class="AppResident">
|
|
||||||
<ai-list v-if="!showDetail" isTabs>
|
|
||||||
<ai-title slot="title" title="居民档案" :instance="instance" :hideLevel="hideLevel-1" isShowArea
|
|
||||||
v-model="areaId"/>
|
|
||||||
<template #tabs>
|
|
||||||
<el-tabs v-model="activeName">
|
|
||||||
<el-tab-pane v-for="op in tabs" :key="op.value" :name="op.value" :label="op.label">
|
|
||||||
<component v-if="op.value==activeName" :is="op.comp" :areaId="areaId" :active="activeName" :instance="instance" :dict="dict" />
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
</template>
|
|
||||||
</ai-list>
|
|
||||||
<component v-else :is="detailComponent" :instance="instance" :dict="dict" :permissions="permissions"/>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
<script>
|
|
||||||
import {mapState} from "vuex";
|
|
||||||
import localResident from "./localResident";
|
|
||||||
import ListTpl from "./listTpl";
|
|
||||||
import MobileResident from "./mobileResident";
|
|
||||||
import ResidentSta from "./residentSta";
|
|
||||||
import auditList from "./auditList";
|
|
||||||
import auditDetail from "./audtiDetail";
|
|
||||||
export default {
|
|
||||||
name: "AppResident",
|
|
||||||
label: "居民档案",
|
|
||||||
props: {
|
|
||||||
instance: Function,
|
|
||||||
dict: Object,
|
|
||||||
permissions: Function,
|
|
||||||
},
|
|
||||||
provide() {
|
|
||||||
return {
|
|
||||||
resident: this
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {ResidentSta, MobileResident, ListTpl, localResident, auditList, audtiDetail: auditDetail},
|
|
||||||
computed: {
|
|
||||||
...mapState(["user"]),
|
|
||||||
tabs() {
|
|
||||||
let details = {
|
|
||||||
"本地居民": localResident,
|
|
||||||
"流动人员": MobileResident,
|
|
||||||
}
|
|
||||||
return [
|
|
||||||
...this.dict.getDict('residentType').map(e => ({
|
|
||||||
label: e.dictName,
|
|
||||||
value: e.dictValue,
|
|
||||||
comp: ListTpl,
|
|
||||||
detail: details[e.dictName]
|
|
||||||
})),
|
|
||||||
{label: "居民统计", value: "3", comp: ResidentSta},
|
|
||||||
{label: "居民档案审核", value: "4", comp: auditList, detail: auditDetail}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
hideLevel() {
|
|
||||||
return this.user.info.areaList?.length || 0
|
|
||||||
},
|
|
||||||
showDetail() {
|
|
||||||
this.activeName = this.activeName || this.$route.query?.type || 0
|
|
||||||
return !!this.$route.query?.type || !!this.$route.query?.id
|
|
||||||
},
|
|
||||||
detailComponent() {
|
|
||||||
return this.tabs.find(e => e.value == this.activeName)?.detail || ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
areaId: '',
|
|
||||||
activeName: "0",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.activeName = this.$route.query?.type
|
|
||||||
this.areaId = JSON.parse(JSON.stringify(this.user.info.areaId))
|
|
||||||
this.dict.load('residentType', "sex", "faithType", "fileStatus",
|
|
||||||
"legality",
|
|
||||||
"education",
|
|
||||||
"maritalStatus",
|
|
||||||
"politicsStatus",
|
|
||||||
"householdName",
|
|
||||||
"nation",
|
|
||||||
"liveReason",
|
|
||||||
"certificateType",
|
|
||||||
"job",
|
|
||||||
"militaryStatus",
|
|
||||||
"householdRelation",
|
|
||||||
"logoutReason",
|
|
||||||
"nation",
|
|
||||||
"registerStatus",
|
|
||||||
"residentTipType",
|
|
||||||
"liveCategory",
|
|
||||||
"livePeriod",
|
|
||||||
"language",
|
|
||||||
"nationality");
|
|
||||||
},
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.AppResident {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background: rgba(243, 246, 249, 1);
|
|
||||||
|
|
||||||
.iconfont {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-content-box {
|
|
||||||
padding: 16px 0;
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
background-color: #f3f6f9;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list {
|
|
||||||
box-sizing: border-box;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: solid 1px #d8e0e8;
|
|
||||||
padding: 16px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 8px;
|
|
||||||
|
|
||||||
.searchBar {
|
|
||||||
padding: 8px 0;
|
|
||||||
|
|
||||||
.el-col {
|
|
||||||
margin-bottom: 8px;
|
|
||||||
|
|
||||||
span {
|
|
||||||
display: inline-block;
|
|
||||||
width: 100px;
|
|
||||||
height: 30px;
|
|
||||||
line-height: 30px;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 14px;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
border-radius: 2px;
|
|
||||||
border: solid 1px #d0d4dc;
|
|
||||||
border-right: none;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.addClass {
|
|
||||||
height: 64px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.dataStatistic {
|
|
||||||
width: 100%;
|
|
||||||
margin-top: 16px;
|
|
||||||
padding: 0 16px 16px 16px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.above {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
.data-item {
|
|
||||||
width: 32%;
|
|
||||||
height: 380px;
|
|
||||||
background: rgba(255, 255, 255, 1);
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 16px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
p {
|
|
||||||
position: absolute;
|
|
||||||
right: 16px;
|
|
||||||
top: 16px;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: bold;
|
|
||||||
|
|
||||||
span:nth-of-type(1) {
|
|
||||||
color: #999999;
|
|
||||||
}
|
|
||||||
|
|
||||||
span:nth-of-type(2) {
|
|
||||||
color: #333333;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,352 +0,0 @@
|
|||||||
<template>
|
|
||||||
<section class="listTpl">
|
|
||||||
<ai-list isTabs>
|
|
||||||
<template #content>
|
|
||||||
<ai-search-bar>
|
|
||||||
<template #left>
|
|
||||||
<ai-select placeholder="档案状态" v-model="search.fileStatus"
|
|
||||||
:selectList="resident.dict.getDict('fileStatus')"
|
|
||||||
@change="page.current=1,refreshTable()"/>
|
|
||||||
<ai-select placeholder="性别" v-model="search.sex"
|
|
||||||
:selectList="resident.dict.getDict('sex')"
|
|
||||||
@change="page.current=1,refreshTable()"/>
|
|
||||||
<ai-select placeholder="文化程度" v-model="search.education"
|
|
||||||
:selectList="resident.dict.getDict('education')"
|
|
||||||
@change="page.current=1,refreshTable()"/>
|
|
||||||
<ai-select placeholder="婚姻状况" v-model="search.maritalStatus"
|
|
||||||
:selectList="resident.dict.getDict('maritalStatus')"
|
|
||||||
@change="page.current=1,refreshTable()"/>
|
|
||||||
<ai-select placeholder="民族" v-model="search.nation"
|
|
||||||
:selectList="resident.dict.getDict('nation')"
|
|
||||||
@change="page.current=1,refreshTable()"/>
|
|
||||||
<el-date-picker
|
|
||||||
value-format="yyyy-MM-dd HH:mm:ss"
|
|
||||||
v-model="search.birthStart"
|
|
||||||
style="width:250px;border-radius:0;"
|
|
||||||
type="date"
|
|
||||||
size="small"
|
|
||||||
unlink-panels
|
|
||||||
placeholder="选择出生开始日期"
|
|
||||||
@change="page.current=1,refreshTable()"
|
|
||||||
/>
|
|
||||||
<el-date-picker
|
|
||||||
value-format="yyyy-MM-dd HH:mm:ss"
|
|
||||||
v-model="search.birthEnd"
|
|
||||||
style="width:250px;border-radius:0;"
|
|
||||||
type="date"
|
|
||||||
size="small"
|
|
||||||
placeholder="选择出生结束日期"
|
|
||||||
unlink-panels
|
|
||||||
@change="page.current=1,refreshTable()"
|
|
||||||
/>
|
|
||||||
<el-select
|
|
||||||
v-model="search.politicsStatus"
|
|
||||||
placeholder="政治面貌"
|
|
||||||
size="small"
|
|
||||||
@change="page.current=1,refreshTable()"
|
|
||||||
clearable
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(item,i) in resident.dict.getDict('politicsStatus')"
|
|
||||||
:key="i"
|
|
||||||
:label="item.dictName"
|
|
||||||
:value="item.dictValue"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
<el-select
|
|
||||||
v-model="search.householdName"
|
|
||||||
placeholder="是否户主"
|
|
||||||
size="small"
|
|
||||||
@change="page.current=1,refreshTable()"
|
|
||||||
clearable
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(item,i) in resident.dict.getDict('householdName')"
|
|
||||||
:key="i"
|
|
||||||
:label="item.dictName"
|
|
||||||
:value="item.dictValue"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
<el-select
|
|
||||||
v-model="search.faithType"
|
|
||||||
placeholder="宗教信仰"
|
|
||||||
@change="page.current=1,refreshTable()"
|
|
||||||
size="small"
|
|
||||||
clearable
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="(item,i) in resident.dict.getDict('faithType')"
|
|
||||||
:key="i"
|
|
||||||
:label="item.dictName"
|
|
||||||
:value="item.dictValue"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</template>
|
|
||||||
<template #right>
|
|
||||||
<el-input
|
|
||||||
size="small"
|
|
||||||
v-model="search.con"
|
|
||||||
placeholder="姓名/身份证/联系方式"
|
|
||||||
@keyup.enter.native="search.current = 1, refreshTable()"
|
|
||||||
@clear="search.current = 1, refreshTable()"
|
|
||||||
clearable
|
|
||||||
suffix-icon="iconfont iconSearch"/>
|
|
||||||
</template>
|
|
||||||
</ai-search-bar>
|
|
||||||
<ai-search-bar>
|
|
||||||
<template #left>
|
|
||||||
<el-button
|
|
||||||
size="small"
|
|
||||||
type="primary"
|
|
||||||
icon="iconfont iconAdd"
|
|
||||||
@click="gotoAdd()"
|
|
||||||
v-if="$permissions('app_appresident_edit')">
|
|
||||||
添加
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
size="small"
|
|
||||||
icon="iconfont iconDelete"
|
|
||||||
:disabled="multipleSelection.length<=0"
|
|
||||||
@click="beforeDelete()"
|
|
||||||
v-if="$permissions('app_appresident_del')">
|
|
||||||
删除
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
<template #right>
|
|
||||||
<ai-import :instance="resident.instance" :dict="resident.dict" type="appresident" name="居民档案"
|
|
||||||
:importParams="{residentType: active}" @success="refreshTable()">
|
|
||||||
<el-button icon="iconfont iconImport">导入</el-button>
|
|
||||||
</ai-import>
|
|
||||||
<ai-download :instance="resident.instance" :params="params" url="/app/appresident/export"
|
|
||||||
fileName="居民档案"/>
|
|
||||||
</template>
|
|
||||||
</ai-search-bar>
|
|
||||||
|
|
||||||
<ai-table :tableData="tableData" :col-configs="colConfigs" :dict="resident.dict"
|
|
||||||
:total="page.total" :current.sync="page.current" :size.sync="page.size"
|
|
||||||
@getList="refreshTable"
|
|
||||||
@selection-change="handleSelectionChange">
|
|
||||||
<el-table-column slot="idNumber" label="身份证号" show-overflow-tooltip align="center">
|
|
||||||
<template slot-scope="{row}">
|
|
||||||
<ai-id mode="show" v-model="row.idNumber" :showEyes="false"/>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column slot="fileStatus" label="档案状态" show-overflow-tooltip align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span v-if="scope.row.fileStatus==0" style="color:rgba(46,162,34,1);">正常</span>
|
|
||||||
<span v-if="scope.row.fileStatus==1" style="color:rgba(153,153,153,1);">已注销</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column slot="options" label="操作" show-overflow-tooltip align="center">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<div class="table-options">
|
|
||||||
<el-button
|
|
||||||
title="详情"
|
|
||||||
type="text"
|
|
||||||
v-if="$permissions('app_appresident_detail')"
|
|
||||||
@click="detailShow(scope.row)">
|
|
||||||
详情
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</ai-table>
|
|
||||||
</template>
|
|
||||||
</ai-list>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import {mapState} from "vuex";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "listTpl",
|
|
||||||
inject: ['resident'],
|
|
||||||
props: {
|
|
||||||
areaId: {default: ""},
|
|
||||||
active: {default: ""},//人员类型
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapState(["user"]),
|
|
||||||
params() {
|
|
||||||
let params = {
|
|
||||||
residentType: this.active
|
|
||||||
}
|
|
||||||
//导出搜索条件
|
|
||||||
if (this.deleteIds.length) {
|
|
||||||
params = {
|
|
||||||
...params,
|
|
||||||
areaId: this.areaId,
|
|
||||||
ids: this.deleteIds
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
params = {
|
|
||||||
areaId: this.areaId,
|
|
||||||
...params,
|
|
||||||
...this.search
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return params
|
|
||||||
},
|
|
||||||
colConfigs() {
|
|
||||||
return [
|
|
||||||
{type: "selection"},
|
|
||||||
{label: "姓名", prop: "name", align: "center"},
|
|
||||||
{label: "性别", prop: "sex", dict: 'sex', align: "center"},
|
|
||||||
{slot: "idNumber"},
|
|
||||||
{label: "年龄", prop: "age", align: "center"},
|
|
||||||
{label: "民族", prop: "nation", align: "center", dict: "nation"},
|
|
||||||
{label: "文化程度", prop: "education", align: "center", dict: "education"},
|
|
||||||
{label: "政治面貌", prop: "politicsStatus", align: "center", dict: "politicsStatus"},
|
|
||||||
{slot: "fileStatus"},
|
|
||||||
{slot: "options"}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
areaId(v) {
|
|
||||||
v && this.refreshTable()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
page: {current: 1, size: 10, total: 0},
|
|
||||||
search: {
|
|
||||||
fileStatus: "",
|
|
||||||
sex: "",
|
|
||||||
nation: "",
|
|
||||||
education: "",
|
|
||||||
politicsStatus: "",
|
|
||||||
birthStart: "",
|
|
||||||
birthEnd: "",
|
|
||||||
faithType: "",
|
|
||||||
householdName: "",
|
|
||||||
con: "",
|
|
||||||
maritalStatus: ""
|
|
||||||
},
|
|
||||||
style: {},
|
|
||||||
tableData: [],
|
|
||||||
multipleSelection: [],
|
|
||||||
deleteIds: [],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handleClick() {
|
|
||||||
this.tableData = [];
|
|
||||||
this.multipleSelection = [];
|
|
||||||
this.searchInit()
|
|
||||||
},
|
|
||||||
searchInit() {
|
|
||||||
let tempAreaId = this.search.areaId;
|
|
||||||
this.search = {
|
|
||||||
fileStatus: "",
|
|
||||||
sex: "",
|
|
||||||
nation: "",
|
|
||||||
education: "",
|
|
||||||
politicsStatus: "",
|
|
||||||
birth: [],
|
|
||||||
faithType: "",
|
|
||||||
householdName: "",
|
|
||||||
areaId: "",
|
|
||||||
con: "",
|
|
||||||
maritalStatus: ""
|
|
||||||
};
|
|
||||||
this.search.areaId = tempAreaId;
|
|
||||||
this.page = {current: 1, size: 10, total: 0};
|
|
||||||
this.refreshTable()
|
|
||||||
},
|
|
||||||
handleSelectionChange(val) {
|
|
||||||
this.deleteIds = [];
|
|
||||||
this.multipleSelection = val;
|
|
||||||
this.multipleSelection.forEach(e => {
|
|
||||||
this.deleteIds.push(e.id);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
exportrExcle() {
|
|
||||||
if (this.deleteIds.length == 0) {
|
|
||||||
if (this.search.birth) {
|
|
||||||
this.search.birth = this.search.birth.join(",");
|
|
||||||
}
|
|
||||||
this.resident.instance
|
|
||||||
.post(`/app/appresident/exportAll`, null, {
|
|
||||||
params: {
|
|
||||||
...this.search,
|
|
||||||
...this.page
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(res => {
|
|
||||||
if (res && res.code == 0) {
|
|
||||||
this.$message.success(res.data);
|
|
||||||
if (typeof this.search.birth == "string") {
|
|
||||||
this.search.birth = this.search.birth.split(",");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
this.resident.instance.post(`/app/appresident/exportByIds`, {
|
|
||||||
ids: this.deleteIds,
|
|
||||||
areaId: this.user.info.areaId
|
|
||||||
}).then(res => {
|
|
||||||
if (res?.code == 0) {
|
|
||||||
this.$message.success(res.data);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleSizeChange(val) {
|
|
||||||
this.page.size = val;
|
|
||||||
this.refreshTable()
|
|
||||||
},
|
|
||||||
detailShow(row) {
|
|
||||||
this.$router.push({query: {type: this.active, id: row.id}})
|
|
||||||
},
|
|
||||||
gotoAdd() {
|
|
||||||
this.$router.push({query: {type: this.active}})
|
|
||||||
},
|
|
||||||
refreshTable() {
|
|
||||||
this.resident.instance.post(`/app/appresident/list`, null, {
|
|
||||||
params: {...this.search, ...this.page, areaId: this.areaId, residentType: this.active}
|
|
||||||
}).then(res => {
|
|
||||||
if (res?.data) {
|
|
||||||
this.tableData = res.data.records
|
|
||||||
this.page.total = res.data.total
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
beforeDelete() {
|
|
||||||
this.$confirm("确定要执行删除操作吗?", {type: "error"})
|
|
||||||
.then(() => {
|
|
||||||
this.deletePersonFn();
|
|
||||||
this.deleteIds = [];
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
});
|
|
||||||
},
|
|
||||||
deletePersonFn() {
|
|
||||||
this.resident.instance.post(`/app/appresident/deleteBody`, {
|
|
||||||
ids: this.deleteIds
|
|
||||||
}).then(res => {
|
|
||||||
if (res && res.code == 0) {
|
|
||||||
this.$message.success("删除成功");
|
|
||||||
if (
|
|
||||||
this.page.current == Math.ceil(this.page.total / this.page.size)
|
|
||||||
) {
|
|
||||||
this.page.total = this.page.total - this.deleteIds.length;
|
|
||||||
this.page.current = Math.ceil(this.page.total / this.page.size);
|
|
||||||
}
|
|
||||||
this.refreshTable();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.refreshTable()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.listTpl {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,445 +0,0 @@
|
|||||||
<template>
|
|
||||||
<section class="residentSta">
|
|
||||||
<div class="dataStatistic">
|
|
||||||
<div class="above">
|
|
||||||
<div class="data-item">
|
|
||||||
<div id="LocalResident" v-if="showStatis"/>
|
|
||||||
<ai-empty v-else/>
|
|
||||||
<h5 v-if="LocalResidentData">
|
|
||||||
更新时间:{{ statisticData.更新时间 }}
|
|
||||||
</h5>
|
|
||||||
</div>
|
|
||||||
<div class="data-item" style="width:66%;">
|
|
||||||
<div id="ResidentDistribution" v-if="showStatis"/>
|
|
||||||
<ai-empty v-else/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="above" style="margin-top:24px;">
|
|
||||||
<div class="data-item">
|
|
||||||
<div id="SexRatio" v-if="showStatis"/>
|
|
||||||
<ai-empty v-else/>
|
|
||||||
<div rightTop><i v-html="'有效数据:'"/> {{ LocalResidentData }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="data-item">
|
|
||||||
<div id="MaritalSta" v-if="showStatis"/>
|
|
||||||
<ai-empty v-else/>
|
|
||||||
<div rightTop><i v-html="'有效数据:'"/>{{ LocalResidentData }}</div>
|
|
||||||
</div>
|
|
||||||
<div class="data-item">
|
|
||||||
<div id="AgeDistribution" v-if="showStatis"/>
|
|
||||||
<ai-empty v-else/>
|
|
||||||
<div rightTop><i v-html="'有效数据:'"/>{{ LocalResidentData }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import * as echarts from 'echarts'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "residentSta",
|
|
||||||
inject: ['resident'],
|
|
||||||
props: {
|
|
||||||
areaId: String
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
LocalResidentData() {
|
|
||||||
return this.statisticData?.总人数 || 0
|
|
||||||
},
|
|
||||||
AgeDistributionData() {
|
|
||||||
return this.statisticData?.年龄层次 || []
|
|
||||||
},
|
|
||||||
MaritalStaData() {
|
|
||||||
return this.statisticData?.婚姻状况 || []
|
|
||||||
},
|
|
||||||
SexRatioData() {
|
|
||||||
return this.statisticData?.男女比例 || []
|
|
||||||
},
|
|
||||||
ResidentDistributionData() {
|
|
||||||
return this.statisticData?.人口分布 || []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
statisticData: {},
|
|
||||||
showStatis: true,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
areaId(v) {
|
|
||||||
v && this.getStaData()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getStaData() {
|
|
||||||
this.resident.instance.post(`/app/appresident/queryCustInfoByAreaId`, null, {
|
|
||||||
params: {
|
|
||||||
areaId: this.areaId
|
|
||||||
}
|
|
||||||
}).then(res => {
|
|
||||||
if (res?.data) {
|
|
||||||
this.statisticData = res.data;
|
|
||||||
this.showStatis = this.LocalResidentData > 0;
|
|
||||||
this.showLocalResident();
|
|
||||||
this.showSexRatio();
|
|
||||||
this.showAgeDistribution();
|
|
||||||
this.showResidentDistribution();
|
|
||||||
this.showMaritalSta();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
showAgeDistribution() {
|
|
||||||
//年龄分布
|
|
||||||
let myChart = echarts.init(document.getElementById("AgeDistribution"));
|
|
||||||
if (!this.showStatis) {
|
|
||||||
return myChart.dispose();
|
|
||||||
}
|
|
||||||
myChart.setOption({
|
|
||||||
title: {
|
|
||||||
text: "年龄层次统计",
|
|
||||||
subtext: "",
|
|
||||||
x: "left"
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
trigger: "item",
|
|
||||||
formatter: "{a} <br/>{b} : {c} ({d}%)"
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
orient: "vertical",
|
|
||||||
bottom: "bottom",
|
|
||||||
data: this.AgeDistributionData.map(e => e.v1)
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: "年龄层次统计",
|
|
||||||
type: "pie",
|
|
||||||
radius: ["40%", "55%"],
|
|
||||||
center: ["50%", "50%"],
|
|
||||||
data: this.AgeDistributionData.map(e => ({value: e.v2 * 1, name: e.v1})),
|
|
||||||
itemStyle: {
|
|
||||||
emphasis: {
|
|
||||||
shadowBlur: 10,
|
|
||||||
shadowOffsetX: 0,
|
|
||||||
shadowColor: "rgba(0, 0, 0, 0.5)"
|
|
||||||
},
|
|
||||||
normal: {
|
|
||||||
color: function (params) {
|
|
||||||
//自定义颜色
|
|
||||||
var colorList = [
|
|
||||||
"#FB3C3C",
|
|
||||||
"#fc5947",
|
|
||||||
"#81E84F",
|
|
||||||
"#3C76FF",
|
|
||||||
"#6995FF",
|
|
||||||
"#FFD500",
|
|
||||||
"#FEF517",
|
|
||||||
"#B1E598",
|
|
||||||
"#81E84F",
|
|
||||||
"#B1E598",
|
|
||||||
"#FEBB8E"
|
|
||||||
];
|
|
||||||
return colorList[params.dataIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
},
|
|
||||||
showLocalResident() {
|
|
||||||
//本地居民
|
|
||||||
let myChart = echarts.init(document.getElementById("LocalResident"));
|
|
||||||
if (!this.showStatis) {
|
|
||||||
return myChart.dispose();
|
|
||||||
}
|
|
||||||
let option = {
|
|
||||||
title: {
|
|
||||||
text: "本地居民",
|
|
||||||
subtext: "",
|
|
||||||
x: "left"
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
trigger: "item",
|
|
||||||
formatter: "{a} <br/>{b}: {c} ({d}%)"
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: "本地居民",
|
|
||||||
type: "pie",
|
|
||||||
radius: ["50%", "65%"],
|
|
||||||
avoidLabelOverlap: false,
|
|
||||||
label: {
|
|
||||||
normal: {
|
|
||||||
show: true,
|
|
||||||
position: "center",
|
|
||||||
textStyle: {
|
|
||||||
fontSize: "40",
|
|
||||||
fontWeight: "normal",
|
|
||||||
color: "#333333"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
emphasis: {
|
|
||||||
show: true,
|
|
||||||
textStyle: {
|
|
||||||
fontSize: "40",
|
|
||||||
fontWeight: "normal",
|
|
||||||
color: "#333333"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
labelLine: {
|
|
||||||
normal: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data: [{value: this.LocalResidentData, name: this.LocalResidentData}],
|
|
||||||
itemStyle: {
|
|
||||||
emphasis: {
|
|
||||||
shadowBlur: 10,
|
|
||||||
shadowOffsetX: 0,
|
|
||||||
shadowColor: "rgba(0, 0, 0, 0.5)"
|
|
||||||
},
|
|
||||||
normal: {
|
|
||||||
color: function (params) {
|
|
||||||
//自定义颜色
|
|
||||||
var colorList = ["#5088FF"];
|
|
||||||
return colorList[params.dataIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
myChart.setOption(option);
|
|
||||||
},
|
|
||||||
showMaritalSta() {
|
|
||||||
//婚姻状况
|
|
||||||
let myChart = echarts.init(document.getElementById("MaritalSta"));
|
|
||||||
if (!this.showStatis) {
|
|
||||||
return myChart.dispose();
|
|
||||||
}
|
|
||||||
let option = {
|
|
||||||
color: [
|
|
||||||
"#FB3C3C",
|
|
||||||
"#FC5947",
|
|
||||||
"#FE8B3F",
|
|
||||||
"#3C76FF",
|
|
||||||
"#6995FF",
|
|
||||||
"#FFD500",
|
|
||||||
"#FEF517",
|
|
||||||
"#B1E598",
|
|
||||||
"#81E84F",
|
|
||||||
"#B1E598",
|
|
||||||
"#FEBB8E"
|
|
||||||
],
|
|
||||||
backgroundColor: "#FFFFFF",
|
|
||||||
title: {
|
|
||||||
text: "婚姻状况统计",
|
|
||||||
x: "left"
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
trigger: "item",
|
|
||||||
formatter: "{a} <br/>{b} : {c} ({d}%)"
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
orient: "vertical",
|
|
||||||
bottom: "bottom",
|
|
||||||
width: "auto",
|
|
||||||
height: 50,
|
|
||||||
data: this.MaritalStaData.map(e => e.v1)
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: "婚姻状况",
|
|
||||||
type: "pie",
|
|
||||||
radius: ["40%", "55%"],
|
|
||||||
center: ["50%", "50%"],
|
|
||||||
data: this.MaritalStaData.map(e => ({value: e.v2 * 1, name: e.v1})),
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
myChart.setOption(option);
|
|
||||||
},
|
|
||||||
showResidentDistribution() {
|
|
||||||
//人口分布/居民分布
|
|
||||||
let myChart = echarts.init(document.getElementById("ResidentDistribution"));
|
|
||||||
if (!this.showStatis) {
|
|
||||||
return myChart.dispose();
|
|
||||||
}
|
|
||||||
let option = {
|
|
||||||
title: {
|
|
||||||
text: "人口分布统计",
|
|
||||||
subtext: "",
|
|
||||||
x: "left"
|
|
||||||
},
|
|
||||||
color: ["#5088FF"],
|
|
||||||
tooltip: {
|
|
||||||
trigger: "axis",
|
|
||||||
axisPointer: {
|
|
||||||
// 坐标轴指示器,坐标轴触发有效
|
|
||||||
type: "shadow" // 默认为直线,可选为:'line' | 'shadow'
|
|
||||||
},
|
|
||||||
formatter: "{a} <br/>{b} : {c} "
|
|
||||||
},
|
|
||||||
grid: {
|
|
||||||
left: "3%",
|
|
||||||
right: "4%",
|
|
||||||
bottom: "3%",
|
|
||||||
containLabel: true
|
|
||||||
},
|
|
||||||
xAxis: [
|
|
||||||
{
|
|
||||||
type: "category",
|
|
||||||
data: this.ResidentDistributionData.map(e => e.name),
|
|
||||||
axisTick: {
|
|
||||||
alignWithLabel: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
yAxis: [
|
|
||||||
{
|
|
||||||
type: "value"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
dataZoom: [
|
|
||||||
{
|
|
||||||
id: "dataZoomX",
|
|
||||||
type: "slider",
|
|
||||||
xAxisIndex: [0],
|
|
||||||
filterMode: "filter"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: "人口数量",
|
|
||||||
type: "bar",
|
|
||||||
barWidth: "16",
|
|
||||||
data: this.ResidentDistributionData.map(e => e.v1)
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
myChart.setOption(option);
|
|
||||||
},
|
|
||||||
showSexRatio() {
|
|
||||||
//男女比例
|
|
||||||
let myChart = echarts.init(document.getElementById("SexRatio"));
|
|
||||||
if (!this.showStatis) {
|
|
||||||
return myChart.dispose();
|
|
||||||
}
|
|
||||||
myChart.setOption({
|
|
||||||
title: {
|
|
||||||
text: "男女比例统计",
|
|
||||||
subtext: "",
|
|
||||||
x: "left"
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
trigger: "item",
|
|
||||||
formatter: "{a} <br/>{b} : {c} ({d}%)"
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
orient: "vertical",
|
|
||||||
bottom: "bottom",
|
|
||||||
data: this.SexRatioData.map(e => e.v1)
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: "男女比例",
|
|
||||||
type: "pie",
|
|
||||||
radius: ["40%", "55%"],
|
|
||||||
center: ["50%", "50%"],
|
|
||||||
data: this.SexRatioData.map(e => ({value: e.v2 * 1, name: e.v1})),
|
|
||||||
itemStyle: {
|
|
||||||
emphasis: {
|
|
||||||
shadowBlur: 10,
|
|
||||||
shadowOffsetX: 0,
|
|
||||||
shadowColor: "rgba(0, 0, 0, 0.5)"
|
|
||||||
},
|
|
||||||
normal: {
|
|
||||||
color: function (params) {
|
|
||||||
//自定义颜色
|
|
||||||
let colorList = [
|
|
||||||
"#FB3C3C",
|
|
||||||
"#3C76FF",
|
|
||||||
"#3C76FF",
|
|
||||||
"#FC5947",
|
|
||||||
"#6995FF",
|
|
||||||
"#FB3C3C",
|
|
||||||
"#FE8B3F",
|
|
||||||
"#B1E598",
|
|
||||||
"#81E84F",
|
|
||||||
"#FEBB8E"
|
|
||||||
];
|
|
||||||
return colorList[params.dataIndex];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getStaData()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.residentSta {
|
|
||||||
height: 100%;
|
|
||||||
|
|
||||||
.dataStatistic {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
overflow-y: auto;
|
|
||||||
padding: 16px 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.above {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
.data-item {
|
|
||||||
width: 32%;
|
|
||||||
height: 380px;
|
|
||||||
background: rgba(255, 255, 255, 1);
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 16px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
div[rightTop] {
|
|
||||||
position: absolute;
|
|
||||||
right: 16px;
|
|
||||||
top: 16px;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #333;
|
|
||||||
|
|
||||||
& > i {
|
|
||||||
font-style: normal;
|
|
||||||
color: #999;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
& > h5 {
|
|
||||||
width: 100%;
|
|
||||||
color: #999;
|
|
||||||
text-align: center;
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#LocalResident, #MaritalSta, #ResidentDistribution, #SexRatio, #AgeDistribution {
|
|
||||||
width: 100%;
|
|
||||||
height: 95%
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
35
project/xiushan/apps/AppMassMessage/AppMassMessage.vue
Normal file
35
project/xiushan/apps/AppMassMessage/AppMassMessage.vue
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<template>
|
||||||
|
<section class="AppMassMessage">
|
||||||
|
<component :is="currentComponent" :instance="instance" :dict="dict" :permissions="permissions"/>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import PumDetail from "./mmDetail";
|
||||||
|
import PumList from "./mmList";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "AppMassMessage",
|
||||||
|
components: {PumList, PumDetail},
|
||||||
|
label: "群众留言",
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
permissions: Function
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
currentComponent() {
|
||||||
|
return !!this.$route.query.id ? PumDetail : PumList
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.AppMassMessage {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
110
project/xiushan/apps/AppMassMessage/mmDetail.vue
Normal file
110
project/xiushan/apps/AppMassMessage/mmDetail.vue
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
<template>
|
||||||
|
<section class="mmDetail">
|
||||||
|
<ai-detail>
|
||||||
|
<ai-title slot="title" title="留言详情" isShowBottomBorder isShowBack @onBackClick="$router.push({query:{}})">
|
||||||
|
<template #rightBtn>
|
||||||
|
<el-button type="primary">回复留言</el-button>
|
||||||
|
<el-button>关闭留言</el-button>
|
||||||
|
</template>
|
||||||
|
</ai-title>
|
||||||
|
<template #content>
|
||||||
|
<el-form size="small">
|
||||||
|
<ai-card class="header">
|
||||||
|
<template #title>
|
||||||
|
<b v-text="detail.title||'标题'"/>
|
||||||
|
<el-row type="flex">
|
||||||
|
<el-form-item label="留言编号">{{ detail.createTime || "-" }}</el-form-item>
|
||||||
|
<el-form-item label="留言时间">{{ detail.createTime || "-" }}</el-form-item>
|
||||||
|
<el-form-item label="留言人">{{ detail.createUserName || "-" }}</el-form-item>
|
||||||
|
</el-row>
|
||||||
|
<ai-icon type="svg" :icon="statusImages[detail.status||0]"/>
|
||||||
|
</template>
|
||||||
|
<template #content>
|
||||||
|
<div v-html="detail.content"/>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
<ai-card title="沟通记录">
|
||||||
|
<template #content>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
</ai-detail>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: "mmDetail",
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
permissions: Function
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
statusImages() {
|
||||||
|
return {
|
||||||
|
0: "iconno_response",
|
||||||
|
1: "iconreplied",
|
||||||
|
2: "iconfinished"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
detail: {},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getDetail() {
|
||||||
|
let {id} = this.$route.query
|
||||||
|
this.instance.post("/appportaluserenterprise/queryDetailById", null, {
|
||||||
|
params: {id}
|
||||||
|
}).then(res => {
|
||||||
|
if (res?.data) {
|
||||||
|
this.detail = res.data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getDetail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.mmDetail {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
::v-deep.header {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.el-form-item {
|
||||||
|
width: 33%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.aibar {
|
||||||
|
height: auto;
|
||||||
|
|
||||||
|
.aibar-left {
|
||||||
|
width: 100%;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
b {
|
||||||
|
line-height: 56px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.AiIcon {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: 80px;
|
||||||
|
height: 80px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
96
project/xiushan/apps/AppMassMessage/mmList.vue
Normal file
96
project/xiushan/apps/AppMassMessage/mmList.vue
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
<template>
|
||||||
|
<section class="mmList">
|
||||||
|
<ai-list>
|
||||||
|
<ai-title slot="title" title="群众留言" isShowBottomBorder/>
|
||||||
|
<template #content>
|
||||||
|
<ai-search-bar>
|
||||||
|
<template #left>
|
||||||
|
<ai-select v-model="search.type" placeholder="留言状态"/>
|
||||||
|
<ai-select v-model="search.type" placeholder="留言类型"/>
|
||||||
|
</template>
|
||||||
|
<template #right>
|
||||||
|
<el-input size="small" placeholder="搜索企业名称、法人姓名、登录账号" v-model="search.enterpriseName" clearable
|
||||||
|
@change="page.current=1,getTableData()"/>
|
||||||
|
</template>
|
||||||
|
</ai-search-bar>
|
||||||
|
<ai-table :tableData="tableData" :total="page.total" :current.sync="page.current" :size.sync="page.size"
|
||||||
|
@getList="getTableData" :col-configs="colConfigs" :dict="dict">
|
||||||
|
<el-table-column slot="options" label="操作" fixed="right" align="center">
|
||||||
|
<template slot-scope="{row}">
|
||||||
|
<el-button v-if="row.status==0" type="text" @click="handleEnable(row)">公示</el-button>
|
||||||
|
<el-button v-else-if="row.status==1" type="text" @click="handleEnable(row)">取消公示</el-button>
|
||||||
|
<el-button type="text" @click="showDetail(row.id)">详情</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</ai-table>
|
||||||
|
</template>
|
||||||
|
</ai-list>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {mapState} from "vuex";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "mmList",
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
dict: Object,
|
||||||
|
permissions: Function
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(['user'])
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
search: {name: ""},
|
||||||
|
page: {current: 1, size: 10, total: 0},
|
||||||
|
tableData: [],
|
||||||
|
colConfigs: [
|
||||||
|
{label: "标题", prop: "enterpriseName"},
|
||||||
|
{label: "类型", prop: "enterpriseType", dict: "enterpriseType"},
|
||||||
|
{label: "内容", prop: "content"},
|
||||||
|
{label: "留言人", prop: "createUserName"},
|
||||||
|
{label: "留言提交时间", prop: "createTime"},
|
||||||
|
{label: "最后回复时间", prop: "loginAccount"},
|
||||||
|
{slot: "options"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getTableData() {
|
||||||
|
this.instance.post("/appportaluserenterprise/list", null, {
|
||||||
|
params: {...this.page, ...this.search, status: 1}
|
||||||
|
}).then(res => {
|
||||||
|
if (res?.data) {
|
||||||
|
this.tableData = res.data?.records
|
||||||
|
this.page.total = res.data.total
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
showDetail(id) {
|
||||||
|
this.$router.push({query: {id}})
|
||||||
|
},
|
||||||
|
handleEnable(row) {
|
||||||
|
let status = (Number(row.status) + 1) % 2
|
||||||
|
this.$confirm(`是否要${this.dict.getLabel('portalUserStatus', status)}留言?`).then(() => {
|
||||||
|
this.instance.post("/appportaluser/addOrUpdate", {...row, status}).then(res => {
|
||||||
|
if (res?.code == 0) {
|
||||||
|
this.$message.success(this.dict.getLabel('portalUserStatus', status) + "成功!")
|
||||||
|
this.getTableData()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}).catch(() => 0)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getTableData()
|
||||||
|
this.search.areaId = this.user.info.areaId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.mmList {
|
||||||
|
}
|
||||||
|
</style>
|
||||||
195
project/xiushan/apps/AppUserInfo/AppUserInfo.vue
Normal file
195
project/xiushan/apps/AppUserInfo/AppUserInfo.vue
Normal file
@@ -0,0 +1,195 @@
|
|||||||
|
<template>
|
||||||
|
<section class="AppUserInfo">
|
||||||
|
<ai-detail>
|
||||||
|
<ai-title slot="title" title="个人中心" isShowBottomBorder/>
|
||||||
|
<template #content>
|
||||||
|
<ai-card title="个人资料">
|
||||||
|
<template #right>
|
||||||
|
<span style="color:#999" v-text="'(如需修改基本信息,请联系管理员)'"/>
|
||||||
|
</template>
|
||||||
|
<template #content>
|
||||||
|
<el-row type="flex" justify="space-between">
|
||||||
|
<ai-wrapper>
|
||||||
|
<ai-info-item label="姓名" :value="user.info.name"/>
|
||||||
|
<ai-info-item label="手机号码" :value="user.info.phone"/>
|
||||||
|
<ai-info-item label="角色" :value="user.info.roleName"/>
|
||||||
|
<ai-info-item label="部门" :value="user.info.departName"/>
|
||||||
|
<ai-info-item label="职位" :value="user.info.position"/>
|
||||||
|
</ai-wrapper>
|
||||||
|
<ai-avatar :value="user.info.avatar" :editable="false"/>
|
||||||
|
</el-row>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
<ai-card title="数据权限">
|
||||||
|
<template #right>
|
||||||
|
<span style="color:#999" v-text="'(如需修改基本信息,请联系管理员)'"/>
|
||||||
|
</template>
|
||||||
|
<template #content>
|
||||||
|
<ai-wrapper>
|
||||||
|
<ai-info-item label="所属地区" :value="areaName" isLine/>
|
||||||
|
</ai-wrapper>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
<ai-card title="密码设置">
|
||||||
|
<template #right>
|
||||||
|
<el-button type="text" @click="submitForm">保存</el-button>
|
||||||
|
</template>
|
||||||
|
<template #content>
|
||||||
|
<el-form :model="form" ref="ruleForm" :rules="rules" label-width="100px" size="small">
|
||||||
|
<el-form-item label="绑定手机:" prop="phone">
|
||||||
|
<el-row type="flex" align="middle">
|
||||||
|
<span>{{ user.info.phone }}</span>
|
||||||
|
<el-button type="primary" style="margin-left: 8px" @click="getCode(user.info.phone,true)"
|
||||||
|
:disabled="codeBtn">获取验证码
|
||||||
|
<span v-if="num>0&&codeBtn" style="color:red;">({{ num }}s)</span>
|
||||||
|
</el-button>
|
||||||
|
</el-row>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="验证码:" prop="code">
|
||||||
|
<el-input v-model.trim="form.code" clearable placeholder="请输入短信验证码"/>
|
||||||
|
<el-input style="position: fixed; bottom: -9999px"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="新密码:" prop="pass">
|
||||||
|
<el-input type="password" auto-complete="new-password" v-model.trim="form.pass" clearable
|
||||||
|
placeholder="8-16位,需要包含字母和数字及特殊字符(~!@#$%^&*,.?_-)"
|
||||||
|
show-password/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="确认密码:" prop="checkPass">
|
||||||
|
<el-input type="password" auto-complete="new-password" placeholder="再次输入密码"
|
||||||
|
v-model.trim="form.checkPass" clearable
|
||||||
|
show-password/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
</ai-card>
|
||||||
|
</template>
|
||||||
|
</ai-detail>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {mapMutations, mapState} from "vuex";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "AppUserInfo",
|
||||||
|
label: "个人中心(秀山版本)",
|
||||||
|
props: {
|
||||||
|
instance: Function,
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState(['user']),
|
||||||
|
rules() {
|
||||||
|
const validatePass = (rule, value, callback) => {
|
||||||
|
const reg = /^(?=.*\d)(?=.*[a-zA-Z])(?=.*[~!@#$%^&*,.?_-])[\da-zA-Z~!@#$%^&*,.?_-]{8,16}$/;
|
||||||
|
if (!reg.test(value)) {
|
||||||
|
callback(new Error('数字和字母及特殊字符(~!@#$%^&*,.?_-)组合,长度8到16位'));
|
||||||
|
} else {
|
||||||
|
if (this.form.checkPass !== '') {
|
||||||
|
this.$refs.ruleForm.validateField('checkPass');
|
||||||
|
}
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
currentPass: [
|
||||||
|
{required: true, message: '请填写当前密码', trigger: 'blur'}
|
||||||
|
],
|
||||||
|
code: [
|
||||||
|
{required: true, message: '请填写验证码', trigger: 'blur'}
|
||||||
|
],
|
||||||
|
pass: [
|
||||||
|
{validator: validatePass, trigger: 'blur', required: true}
|
||||||
|
],
|
||||||
|
checkPass: [
|
||||||
|
{
|
||||||
|
validator: (r, v, cb) => v ? v != this.form.pass ? cb('两次输入密码不一致') : cb() : cb('请再次输入密码'),
|
||||||
|
trigger: 'blur',
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
areaName(){
|
||||||
|
return this.user?.info?.areaList?.join("")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
form: {},
|
||||||
|
timer: null,
|
||||||
|
codeBtn: false,
|
||||||
|
num: 60,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
...mapMutations(['SignOut']),
|
||||||
|
getCode(phone, flag) {
|
||||||
|
const TEL_REGEXP = /^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\d{8}$/;
|
||||||
|
if (TEL_REGEXP.test(phone)) {
|
||||||
|
this.instance.post(`/admin/user/checkPhone`, null, {
|
||||||
|
params: {phone, flag}
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
this.$message.success("请查看手机短信!");
|
||||||
|
this.timer = setInterval(() => {
|
||||||
|
if (this.num > 0) {
|
||||||
|
this.codeBtn = true;
|
||||||
|
this.num--;
|
||||||
|
} else if (this.num == 0) {
|
||||||
|
this.codeBtn = false;
|
||||||
|
this.num = 60;
|
||||||
|
clearInterval(this.timer);
|
||||||
|
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.$message.error("验证码发送失败!");
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.$message.error("手机号格式错误!");
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
submitForm() {
|
||||||
|
this.$refs.ruleForm.validate(v => {
|
||||||
|
if (v) {
|
||||||
|
let {pass: newPwd, code} = this.form
|
||||||
|
this.instance.post(`/admin/user/update-pwd`, null, {
|
||||||
|
params: {
|
||||||
|
phone: this.user.info.phone,
|
||||||
|
newPwd, code
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
if (res?.code == 0) {
|
||||||
|
this.$confirm("村微提醒您,更换密码成功!", {
|
||||||
|
showCancelButton: false
|
||||||
|
}).then(() => this.SignOut()).catch(() => 0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.AppUserInfo {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
::v-deep .ai-list__content--wrapper {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .el-input__inner {
|
||||||
|
|
||||||
|
-webkit-text-security: disc !important;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"AppDictionary": "数据字典",
|
"AppDictionary": "数据字典",
|
||||||
"AppUserInfo": "个人中心",
|
|
||||||
"AppRightsManager": "权限管理",
|
"AppRightsManager": "权限管理",
|
||||||
"AppAccountRole": "账号角色",
|
"AppAccountRole": "账号角色",
|
||||||
"AppMenuManager": "菜单管理"
|
"AppMenuManager": "菜单管理"
|
||||||
|
|||||||
@@ -71,15 +71,12 @@ module.exports = {
|
|||||||
'^/lan': '/'
|
'^/lan': '/'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'/oms': {
|
'/omsapi': {
|
||||||
target: 'http://192.168.1.87:19898',
|
target: 'http://192.168.1.87:19898',
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
pathRewrite: {
|
pathRewrite: {
|
||||||
//地址重写
|
//地址重写
|
||||||
'^/oms/app/': '/',
|
'^/omsapi': '/'
|
||||||
'^/oms/auth/': '/',
|
|
||||||
'^/oms/admin/': '/',
|
|
||||||
'^/oms': '/'
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'/xsjr': {
|
'/xsjr': {
|
||||||
|
|||||||
Reference in New Issue
Block a user