oms接入3.0产品库

This commit is contained in:
aixianling
2022-03-14 11:38:06 +08:00
parent fcb6bbf956
commit 66fad244d9
17 changed files with 2666 additions and 7 deletions

View File

@@ -0,0 +1,223 @@
<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) {
this.$emit('change', {
type: 'Statistics',
params: item
})
},
},
created() {
this.getsaasList()
this.getTableData()
}
}
</script>
<style lang="scss" scoped>
.list {
height: 100%;
}
</style>

View File

@@ -0,0 +1,364 @@
<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,
params: Object
},
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'}
]
}
},
mounted() {
this.getInfo()
this.getTableData()
this.getUserTableData()
},
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}&current=${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}&current=${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.$emit('change', {
type: 'list'
})
},
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>