19 Commits

Author SHA1 Message Date
aixianling
a5dbdbe778 Merge branch 'dev' into vite
# Conflicts:
#	examples/router/autoRoutes.js
#	package.json
#	packages/bigscreen/designer/components/Add.vue
#	project/dv/apps/AppGridDV.vue
#	vue.config.js
2022-08-23 11:14:38 +08:00
aixianling
cef8dad5f0 Merge branch 'dev' into vite 2022-07-07 09:33:20 +08:00
aixianling
da8e8f0d65 Merge branch 'dev' into vite
# Conflicts:
#	examples/main.js
#	examples/router/autoRoutes.js
#	package.json
#	packages/bigscreen/designer/AppDesigner.vue
#	packages/bigscreen/designer/components/Add.vue
#	packages/bigscreen/designer/components/Layout.vue
#	packages/bigscreen/designer/components/List.vue
#	packages/bigscreen/designer/components/SourceData.vue
#	packages/bigscreen/designer/components/form/DataConfig.vue
#	packages/bigscreen/designer/config.js
#	packages/bigscreen/viewer/AppGigscreenViewer.vue
#	packages/conv/creditScore/scoreManage/scoreChange.vue
#	packages/index.js
#	project/dv/apps/AppGridDV.vue
#	project/dvui/components/AiMonitor/dhVideo.vue
#	project/dvui/components/AiSwiper.vue
#	project/dvui/layout/AiDvBackground.vue
#	project/dvui/layout/AiDvSummary/AiDvSummary.vue
#	project/dvui/layout/AiDvWrapper/AiDvWrapper.vue
#	project/dvui/package.json
#	public/index.html
#	vue.config.js
2022-07-07 09:01:40 +08:00
aixianling
e91d1f73dc Merge branch 'dev' into vite
# Conflicts:
#	examples/App.vue
#	examples/router/autoRoutes.js
#	examples/utils/index.js
#	package.json
#	packages/wechat/AppProjectActivities/components/Event.vue
#	project/dv/apps/AppHomesteadDV.vue
#	vue.config.js
2022-05-10 20:06:15 +08:00
aixianling
d0e18eb2f6 提交一下 2022-05-10 15:11:52 +08:00
aixianling
82535aff40 3.0第一个产品库 2022-05-10 14:43:49 +08:00
aixianling
65fb4ac65b 修复favicon 2022-05-10 11:35:25 +08:00
aixianling
93d0e0aafe 修复刷新异常 2022-05-10 11:27:19 +08:00
aixianling
1eb9c532f3 Merge branch 'dev' into vite 2022-05-10 11:15:51 +08:00
aixianling
3174382666 Merge branch 'dev' into vite 2022-05-10 09:56:50 +08:00
aixianling
92890111ee BUG 29560 2022-05-10 09:36:35 +08:00
aixianling
9b35506181 Merge branch 'dev' into vite 2022-05-10 09:21:34 +08:00
aixianling
73f300cd7a 先提交一波 2022-05-10 09:21:07 +08:00
aixianling
2f79210970 Merge branch 'dev' into vite
# Conflicts:
#	package.json
#	packages/bigscreen/designer/AppDesigner.vue
#	packages/bigscreen/designer/components/Add.vue
#	packages/bigscreen/designer/components/Layout.vue
#	packages/bigscreen/designer/components/RenderElement.vue
#	packages/bigscreen/viewer/AppGigscreenViewer.vue
#	project/dvui/layout/AiDvPanel/AiDvPanel.vue
#	project/dvui/layout/AiDvWrapper/AiDvWrapper.vue
2022-05-09 14:36:16 +08:00
aixianling
8744f115cf Merge branch 'dev' into vite
# Conflicts:
#	packages/IntelligentSecurity/AppISManage/AppISManage.vue
#	vue.config.js
2022-04-28 18:42:05 +08:00
aixianling
2174909bb8 Merge remote-tracking branch 'origin/dev' into vite 2022-04-28 08:56:10 +08:00
aixianling
bd512c3caa 优化体验 2022-04-27 19:36:32 +08:00
aixianling
861e7c688f Merge branch 'dev' into vite 2022-04-27 18:20:28 +08:00
aixianling
4f0178c627 web端产品库 vite版本 2022-04-27 18:18:57 +08:00
159 changed files with 872 additions and 16295 deletions

24
.gitignore vendored
View File

@@ -1,24 +1,28 @@
.DS_Store # Logs
node_modules logs
/dist *.log
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log* npm-debug.log*
yarn-debug.log* yarn-debug.log*
yarn-error.log* yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files # Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea .idea
.vscode .DS_Store
*.suo *.suo
*.ntvs* *.ntvs*
*.njsproj *.njsproj
*.sln *.sln
*.sw? *.sw?
/package-lock.json /package-lock.json
/lib /lib
.prettierrc .prettierrc

View File

@@ -1,13 +0,0 @@
# 忽略目录
examples/
packages/
subPackages/
core/
public/
project/
.idea/
# 忽略指定文件
vue.config.js
babel.config.js
*.map

View File

@@ -1,3 +0,0 @@
# dvcp_v2_webapp
村微2.0 前端应用库

View File

@@ -1,11 +0,0 @@
module.exports = {
presets: [
'@vue/app',
],
plugins: [
// 可选链插件, 其他babel插件也是一样的安装方式
"@babel/plugin-proposal-optional-chaining",
"@babel/plugin-proposal-nullish-coalescing-operator",
"@babel/plugin-proposal-logical-assignment-operators"
]
}

View File

@@ -11,7 +11,6 @@ import store from './store';
import dataV from '@jiaminghi/data-view'; import dataV from '@jiaminghi/data-view';
import dvui from '../project/dvui/entries' import dvui from '../project/dvui/entries'
Vue.use(dataV);
Vue.use(ui); Vue.use(ui);
Vue.use(vcUI); Vue.use(vcUI);
Vue.use(dvui) Vue.use(dvui)

View File

@@ -1,16 +1,17 @@
import store from "../store"; import store from "../store";
import appEntry from "../views/appEntry";
import {waiting} from "../utils"; import {waiting} from "../utils";
import appEntry from "../views/apps/appEntry";
import router from "./router"; import router from "./router";
import axios from "./axios"; import axios from "./axios";
export default { export default {
routes: () => store.state.apps, routes: [],
init() { init() {
//约束正则式 //约束正则式
store.commit("cleanApps") store.commit("cleanApps")
this.routes = []
// 自动化本工程应用 // 自动化本工程应用
this.loadApps() return this.loadApps()
}, },
loadApps() { loadApps() {
//新App的自动化格式 //新App的自动化格式

View File

@@ -1,13 +1,13 @@
import Vue from 'vue'
import VueRouter from 'vue-router' import VueRouter from 'vue-router'
import autoRoutes from './autoRoutes' import autoRoutes from './autoRoutes'
import Vue from "vue";
Vue.use(VueRouter)
autoRoutes.init() autoRoutes.init()
Vue.use(VueRouter)
export default new VueRouter({ export default new VueRouter({
mode: 'history', mode: 'history',
hashbang: false, hashbang: false,
routes: autoRoutes.routes(), routes: [{path: "/", redirect: "/v", name: "产品库", component: import('../App')}],
scrollBehavior(to) { scrollBehavior(to) {
if (to.hash) { if (to.hash) {
return { return {

15
index.html Normal file
View File

@@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>村务云应用库-展示页面</title>
<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js" referrerpolicy="origin"></script>
<script src="https://open.work.weixin.qq.com/wwopen/js/jwxwork-1.0.0.js" referrerpolicy="origin"></script>
</head>
<body>
<div id="app"></div>
<script type="module" src="/examples/main.js"></script>
</body>
</html>

View File

@@ -1,13 +1,13 @@
{ {
"name": "cw-webapps", "name": "dvcp-vite-webapps",
"version": "2.0.0",
"private": false, "private": false,
"author": "kubbo", "version": "0.0.0",
"main": "lib/cw-webapps.common.js", "main": "lib/dvcp-vite-webapps.umd.js",
"scripts": { "scripts": {
"dev": "vue-cli-service serve", "dev": "vite",
"lib": "vue-cli-service build --no-clean --target lib --dest lib packages/index.js&&npm unpublish --force&&npm publish", "preview": "vite preview",
"lib:core": "vue-cli-service build --target lib --dest core/dist core/index.js --name dvcp-core&&npm unpublish dvcp-core --force&&npm publish core/", "lib": "vite build --outDir lib --emptyOutDir&&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",
"lib:all": "node project/allProject.js&&npm unpublish --workspaces --force&&npm publish --workspaces", "lib:all": "node project/allProject.js&&npm unpublish --workspaces --force&&npm publish --workspaces",
"ui": "npm i dvcp-ui@latest" "ui": "npm i dvcp-ui@latest"
@@ -15,79 +15,22 @@
"workspaces": [ "workspaces": [
"project/*" "project/*"
], ],
"dependencies": {
"@amap/amap-jsapi-loader": "^1.0.1",
"@jiaminghi/c-render": "^0.4.3",
"@jiaminghi/charts": "^0.2.18",
"@jiaminghi/data-view": "^2.10.0",
"bin-code-editor": "^0.9.0",
"dayjs": "^1.8.35",
"dvcp-ui": "^1.42.2",
"echarts": "^5.1.2",
"mp4box": "^0.4.1",
"print-js": "^1.0.63",
"serialize-javascript": "^6.0.0",
"sortablejs": "^1.12.0",
"vue-draggable-resizable": "^2.3.0",
"vue-json-editor": "^1.4.3",
"vue-ruler-tool": "^1.2.4",
"vuedraggable": "^2.24.3"
},
"publishConfig": {
"registry": "http://192.168.1.87:4873/"
},
"devDependencies": { "devDependencies": {
"@babel/plugin-proposal-logical-assignment-operators": "^7.10.4",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4",
"@babel/plugin-proposal-optional-chaining": "^7.10.4",
"@vue/cli-plugin-babel": "^3.6.0",
"@vue/cli-plugin-eslint": "^3.6.0",
"@vue/cli-service": "^3.6.0",
"axios": "^0.19.2",
"babel-eslint": "^10.1.0",
"core-js": "^2.6.11",
"element-ui": "^2.15.9",
"eslint": "^5.16.0",
"eslint-plugin-vue": "^5.0.0",
"image-webpack-loader": "^6.0.0",
"inquirer": "^6.5.2",
"readline": "^1.3.0",
"sass": "~1.32.12",
"sass-loader": "^7.3.1",
"uglifyjs-webpack-plugin": "^2.2.0",
"v-viewer": "^1.6.4", "v-viewer": "^1.6.4",
"vite": "^2.9.5",
"vite-plugin-vue2": "^2.0.0",
"vue": "^2.6.14", "vue": "^2.6.14",
"vue-router": "^3.3.4", "vue-router": "^3.3.4",
"vue-style-loader": "^4.1.3",
"vue-template-compiler": "^2.6.14", "vue-template-compiler": "^2.6.14",
"vuex": "^3.5.1", "vuex-persistedstate": "^3.2.1"
"vuex-persistedstate": "^2.7.1"
}, },
"vetur": { "dependencies": {
"attributes": "./attributes.json" "dvcp-dv-ui": "^2.0.1",
}, "dvcp-ui": "^1.42.2",
"eslintConfig": { "element-ui": "^2.15.8",
"root": true, "mp4box": "^0.4.1",
"env": { "print-js": "^1.0.63",
"node": true "sass": "^1.51.0",
}, "vue-draggable-resizable": "^2.3.0"
"extends": [ }
"plugin:vue/essential",
"eslint:recommended"
],
"rules": {},
"parserOptions": {
"parser": "babel-eslint"
}
},
"postcss": {
"plugins": {
"autoprefixer": {}
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
} }

View File

@@ -1,81 +0,0 @@
<template>
<section class="AppDesigner">
<component :is="currentPage" v-bind="$props"/>
</section>
</template>
<script>
import List from './components/List.vue'
import Add from './components/Add'
import SourceData from './components/SourceData'
import Preview from "./components/preview";
export default {
name: 'AppDesigner',
label: '大屏设计',
components: {Preview, List, Add, SourceData},
props: {
instance: Function,
dict: Object,
permissions: Function,
urlPrefix: {
type: String,
default: '/app'
}
},
computed: {
currentPage() {
const {hash} = this.$route
return hash == "#sourceData" ? SourceData :
hash == "#add" ? Add :
hash == "#preview" ? Preview : List
},
tabs() {
return [
{label: '大屏列表', name: 'FormList', comp: List, permission: ''}
].filter(() => {
return true
})
}
},
data() {
return {
currIndex: '0',
componentName: '',
params: {},
areaId: '',
isShowDetail: false
}
},
methods: {
onChange(data) {
if (data.type === 'list') {
this.componentName = 'List'
this.isShowDetail = false
this.params = data.params
}
if (data.type === 'add') {
this.componentName = 'Add'
this.isShowDetail = true
this.params = data.params
}
if (data.type === 'SourceData') {
this.componentName = 'SourceData'
this.isShowDetail = true
this.params = data.params
}
}
},
}
</script>
<style lang="scss" scoped>
.AppDesigner {
height: 100%;
}
</style>

View File

@@ -1,300 +0,0 @@
<template>
<ai-detail>
<template slot="title">
<ai-title :title="id ? '编辑项目' : '添加项目'" isShowBack isShowBottomBorder @onBackClick="cancel"/>
</template>
<template slot="content">
<el-form ref="form" :model="form" label-width="110px" label-position="right">
<ai-card title="基本信息">
<template #content>
<div class="ai-form">
<el-form-item label="名称" prop="name" :rules="[{ required: true, message: '请输入大屏项目名称', trigger: 'blur' }]">
<el-input size="small" :maxlength="30" placeholder="请输入大屏项目名称" v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="描述" style="width: 100%;" prop="description">
<el-input size="small" :maxlength="200" :rows="5" type="textarea" style="width: 100%;" placeholder="请输入描述" v-model="form.description"></el-input>
</el-form-item>
<el-form-item label="是否开启" style="width: 100%;" prop="status">
<el-switch
v-model="form.status"
active-value="1"
inactive-value="0">
</el-switch>
</el-form-item>
</div>
</template>
</ai-card>
<ai-card title="大屏">
<template #right>
<el-button @click="add('')" type="primary">添加大屏</el-button>
<el-button @click="dialog=true" type="primary">定制大屏</el-button>
</template>
<template #content>
<ai-table
:tableData="tableData"
:col-configs="colConfigs"
:total="total"
style="margin-top: 6px;"
:border="true"
row-key="id"
:isShowPagination="false"
@getList="() => {}">
<el-table-column slot="options" label="状态" align="center">
<template slot-scope="{ row }">
<el-switch
v-model="row.status"
active-value="1"
@change="() => onStatusChange(row.id)">
</el-switch>
</template>
</el-table-column>
<el-table-column slot="options" width="160px" fixed="right" label="操作" align="center">
<template slot-scope="{ row, column, $index }">
<div class="table-options">
<el-button type="text" @click="toEdit(row.id, row.isCustom, row)">编辑</el-button>
<el-button type="text" @click="toViewer(row.id)">预览</el-button>
<el-button type="text" @click="remove($index)">删除</el-button>
</div>
</template>
</el-table-column>
</ai-table>
</template>
</ai-card>
</el-form>
<Layout
v-if="isShowLayout"
:instance="instance"
:dict="dict"
:params="query"
@change="onChange"
:urlPrefix="urlPrefix"
:theme="config.theme"
@close="isShowLayout = false">
</Layout>
<ai-dialog :visible.sync="dialog" title="定制大屏" @closed="custom={}" @onConfirm="handleCustomizedDV">
<el-form ref="CustomDVFrom" size="small" :model="custom" :rules="rules" label-width="80px">
<el-form-item label="大屏标题" prop="title">
<el-input v-model="custom.title" clearable placeholder="请填写"/>
</el-form-item>
<el-form-item label="选择大屏" prop="dv">
<ai-select v-model="custom.dv" :selectList="dict.getDict('customizedDVs')"/>
</el-form-item>
<el-form-item label="静态数据">
<el-input type="textarea" rows="5" v-model="custom.meta"/>
</el-form-item>
</el-form>
</ai-dialog>
</template>
<template #footer>
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="confirm">提交</el-button>
</template>
</ai-detail>
</template>
<script>
import Layout from './Layout.vue'
import Sortable from 'sortablejs'
export default {
name: 'Add',
props: {
instance: Function,
dict: Object,
urlPrefix: String
},
inject: {
home: {default: ''}
},
components: {
Layout
},
data() {
return {
info: {},
department: [],
form: {
name: '',
relationLsIds: '',
relationLsNames: '',
status: '1',
description: ''
},
screenId: '',
query: {},
total: 0,
colConfigs: [
{prop: 'title', label: '标题'},
{prop: 'id', label: 'ID'}
],
tableData: [],
isShowLayout: false,
id: '',
dialog: false,
custom: {},
rules: {
dv: [{required: true, message: "请选择 定制大屏"}],
title: [{required: true, message: "请输入 大屏标题"}],
},
config: {
backgroundImage: []
}
}
},
created() {
this.dict.load('customizedDVs')
this.getInfo()
},
methods: {
getInfo() {
let {id} = this.$route.query
this.instance.post(`${this.urlPrefix}/appdiylargescreen/queryLargeScreenProjectDetailById?id=${id}`).then(res => {
if (res?.data) {
this.form = {
...res.data
}
if (res.data.relationLsIds) {
this.tableData = res.data.lsList.map(v => {
let conf = JSON.parse(v.config || '') || {}
return {
id: v.id,
title: v.title,
dv: conf.custom || '',
meta: JSON.stringify(conf.meta),
isCustom: !!conf.custom,
status: v.status
}
})
this.total = res.data.lsList.length
this.$nextTick(() => {
this.rowDrop()
})
}
}
})
},
onStatusChange (id) {
this.instance.post(`${this.urlPrefix}/appdiylargescreen/enableLargeScreen?id=${id}`).then(res => {
if (res.code === 0) {
this.getInfo()
this.$message.success('操作成功')
}
})
},
rowDrop() {
const tbody = document.querySelector('.el-table__body-wrapper tbody')
const _this = this
Sortable.create(tbody, {
onEnd({newIndex, oldIndex}) {
const currRow = _this.tableData.splice(oldIndex, 1)[0]
_this.tableData.splice(newIndex, 0, currRow)
}
})
},
toViewer(id) {
this.$router.push({query: {id}, hash: "#preview"})
},
onChange(e) {
const ids = this.tableData.map(v => v.id)
if (ids.indexOf(e.id) < 0) {
this.tableData.push({
title: e.title,
id: e.id
})
} else {
const index = this.tableData.findIndex(v => v.id === e.id)
this.$set(this.tableData[index], 'title', e.title)
}
},
add() {
this.query = {
id: '',
name: this.form.name
}
this.isShowLayout = true
},
toEdit(id, isCustom, form) {
if (!isCustom) {
this.query = {
id,
name: this.form.name
}
this.isShowLayout = true
} else {
this.dialog = true
this.custom = {
...form,
}
}
},
remove(index) {
this.tableData.splice(index, 1)
},
confirm() {
this.$refs.form.validate((valid) => {
if (valid) {
const ids = this.tableData.map(v => v.id).join(',')
const names = this.tableData.map(v => v.name).join(',')
this.instance.post(`${this.urlPrefix}/appdiylargescreen/addOrUpdateLargeScreenProject`, {
...this.form,
relationLsIds: ids,
relationLsNames: names
}).then(res => {
if (res.code == 0) {
this.$message.success('提交成功')
this.home && this.home.refreshDvOptions && this.home.refreshDvOptions()
setTimeout(() => {
this.cancel()
}, 600)
}
})
}
})
},
cancel() {
this.$router.push({})
},
handleCustomizedDV() {
this.$refs.CustomDVFrom.validate(v => {
if (v) {
this.instance.post(`${this.urlPrefix}/appdiylargescreen/addOrUpdateLargeScreen`, {
config: JSON.stringify({
custom: this.custom.dv,
meta: JSON.parse(this.custom.meta?.replace(/\\n/g, '') || null)
}),
status: 1,
id: this.custom.id,
title: this.custom.title,
}).then(res => {
if (res?.code == 0 && res?.data) {
this.$message.success('保存成功')
this.onChange(res.data)
this.dialog = false
}
})
}
})
}
}
}
</script>
<style scoped lang="scss">
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -1,167 +0,0 @@
<template>
<ai-list>
<ai-title slot="title" title="大屏列表" isShowBottomBorder/>
<template slot="content">
<ai-search-bar>
<template #left>
<ai-select
v-model="search.status"
@change="search.current = 1, getList()"
placeholder="发布状态"
:selectList="dict.getDict('cwpStatus')">
</ai-select>
<el-button type="primary" @click="toEdit('')">添加大屏</el-button>
<el-button type="primary" @click="toAddData">数据源管理</el-button>
</template>
<template #right>
<el-input
v-model="search.name"
size="small"
placeholder="请输入模板名称或创建人"
clearable
v-throttle="() => {search.current = 1, getList()}"
@clear="search.current = 1, search.title = '', getList()"
suffix-icon="iconfont iconSearch">
</el-input>
</template>
</ai-search-bar>
<ai-table
:tableData="tableData"
:col-configs="colConfigs"
:total="total"
v-loading="loading"
style="margin-top: 6px;"
:current.sync="search.current"
:size.sync="search.size"
@getList="getList">
<el-table-column slot="options" width="160px" fixed="right" label="操作" align="center">
<template slot-scope="{ row }">
<div class="table-options">
<el-button type="text" @click="toEdit(row.id)">编辑</el-button>
<el-button type="text" @click="copy(row.id)">复制</el-button>
</div>
</template>
</el-table-column>
</ai-table>
<ai-dialog
:visible.sync="isShowAdd"
width="780px"
title="复制大屏"
@close="onClose"
@onConfirm="onConfirm">
<el-form ref="form" :model="form" label-width="110px" label-position="right">
<div class="ai-form" :model="form" label-width="110px" label-position="right">
<el-form-item label="名称" prop="name" style="width: 100%;" :rules="[{ required: true, message: '请输入名称', trigger: 'blur' }]">
<el-input size="small" placeholder="请输入名称" v-model="form.name"></el-input>
</el-form-item>
</div>
</el-form>
</ai-dialog>
</template>
</ai-list>
</template>
<script>
export default {
name: 'FormList',
props: {
instance: Function,
dict: Object,
areaId: String,
urlPrefix: String
},
data() {
return {
search: {
current: 1,
status: '',
size: 10,
name: ''
},
form: {
name: ''
},
id: '',
isShowAdd: false,
colConfigs: [
{prop: 'name', label: '模板名称'},
{prop: 'createUserName', align: 'center', label: '创建人'},
{prop: 'description', align: 'center', label: '描述'},
{prop: 'status', align: 'center', label: '状态', formart: v => this.dict.getLabel('cwpStatus', v)},
{prop: 'createTime', align: 'center', label: '创建时间'}
],
tableData: [],
total: 0,
loading: false
}
},
created() {
this.dict.load('cwpStatus').then(() => {
this.getList()
})
},
mounted() {
this.loading = true
},
methods: {
copy(id) {
this.id = id
this.isShowAdd = true
},
onClose() {
this.id = ''
this.form.name = ''
},
onConfirm() {
this.$refs.form.validate((valid) => {
if (valid) {
this.instance.post(`${this.urlPrefix}/appdiylargescreen/copyLargeScreenProject`, null, {
params: {
...this.form,
id: this.id
}
}).then(res => {
if (res.code === 0) {
this.$message.success('复制成功')
this.isShowAdd = false
this.getList()
}
})
}
})
},
getList() {
this.instance.post(`${this.urlPrefix}/appdiylargescreen/allLargeScreenProjectByPage`, null, {
params: {
...this.search
}
}).then(res => {
if (res.code == 0) {
this.tableData = res.data.records
this.total = res.data.total
this.loading = false
} else {
this.loading = false
}
}).catch(() => {
this.loading = false
})
},
toEdit(id) {
this.$router.push({hash: "#add", query: {id}})
},
toAddData() {
this.$router.push({hash: "#sourceData"})
}
}
}
</script>

View File

@@ -1,459 +0,0 @@
<template>
<ai-detail>
<template slot="title">
<ai-title title="数据源" isShowBack isShowBottomBorder @onBackClick="cancel">
</ai-title>
</template>
<template slot="content">
<ai-card title="数据源列表">
<template #right>
<el-button type="primary" @click="isShow = true">添加数据源</el-button>
</template>
<template #content>
<ai-search-bar class="search-bar">
<template slot="right">
<el-input
v-model="search.name"
size="small"
v-throttle="() => {search.current = 1, getList()}"
placeholder="请输入名字"
clearable
@clear="search.current = 1, search.name = '', getList()"
suffix-icon="iconfont iconSearch">
</el-input>
</template>
</ai-search-bar>
<ai-table
:tableData="tableData"
:col-configs="colConfigs"
:total="total"
style="margin-top: 6px;"
:border="true"
:current.sync="search.current"
:size.sync="search.size"
@getList="getList">
<el-table-column slot="options" width="160px" fixed="right" label="操作" align="center">
<template slot-scope="{ row }">
<div class="table-options">
<el-button type="text" @click="toEdit(row)">编辑</el-button>
<el-button type="text" @click="remove(row.id)">删除</el-button>
</div>
</template>
</el-table-column>
</ai-table>
</template>
</ai-card>
<ai-dialog
:visible.sync="isShow"
width="920px"
title="数据源"
@close="onClose"
@onConfirm="onConfirm">
<el-form ref="form" :model="form" label-width="110px" label-position="right">
<div class="ai-form">
<el-form-item label="数据源描述" style="width: 100%;" prop="description" :rules="[{ required: true, message: '请输入数据源描述', trigger: 'blur' }]">
<el-input
size="small"
placeholder="请输入数据源描述"
v-model="form.description">
</el-input>
</el-form-item>
<el-form-item label="类型" style="width: 100%;" prop="dataRange" :rules="[{ required: true, message: '请选择数据范围', trigger: 'change' }]">
<el-radio-group v-model="form.type">
<el-radio label="0">村微应用</el-radio>
<el-radio label="1">SQL</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="form.type === '1'" label="sql语句" style="width: 100%;" prop="description"
:rules="[{ required: true, message: '请输入sql语句', trigger: 'blur' }]">
<el-input
:rows="8"
size="small"
type="textarea"
placeholder="请输入数据源描述"
v-model="form.sqlContent">
</el-input>
</el-form-item>
<el-form-item v-if="form.type === '0'" label="村微应用" style="width: 100%;" prop="appId"
:rules="[{ required: true, message: '请选择村微应用', trigger: 'change' }]">
<el-select size="small" style="width: 100%;" v-model="form.appId" placeholder="请选择村微应用" @change="onAppChange">
<el-option
v-for="item in appList"
:key="item.id"
:label="item.appName"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item v-if="form.type === '0'" label="数据范围" style="width: 100%;" prop="dataRange"
:rules="[{ required: true, message: '请选择数据范围', trigger: 'change' }]">
<el-radio-group v-model="form.dataRange">
<el-radio label="0">全部</el-radio>
<el-radio label="1">自定义条数</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="数据条数" style="width: 100%;" v-if="form.dataRange === '1' && form.type === '0'" prop="count"
:rules="[{ required: true, message: '请输入数据条数', trigger: 'blur' }]">
<el-input
size="small"
placeholder="请输入数据条数"
v-model="form.count">
</el-input>
</el-form-item>
<div v-if="form.type === '0'">
<el-form-item :label="'统计项' + index" style="width: 100%;" v-for="(item, index) in form.statisticsConfigs" :key="'statisticsConfigs' + index">
<div class="form-flex">
<div>
<el-select size="small" style="width: 160px;" v-model="item.fieldName" @change="e => onChooseField('statisticsConfigs', e, index)"
placeholder="请选择" clearable>
<el-option
v-for="(item, index) in filedList"
:key="index"
:label="item.fieldCnName"
:value="item.fieldName">
</el-option>
</el-select>
<el-select size="small" style="margin: 0 10px; width: 160px;" v-model="item.calcType" placeholder="请选择" clearable>
<el-option
v-for="item in dict.getDict('diyLargeScreenDatasourceCalcType2')"
:key="item.id"
:label="item.dictName"
:value="item.dictValue">
</el-option>
</el-select>
<el-input size="small" style="width: 165px;" placeholder="请输入别名" v-model="item.alias"></el-input>
</div>
<el-button type="danger" v-if="index > 0" @click="removeConfig('statisticsConfigs', index)">删除</el-button>
</div>
</el-form-item>
</div>
<el-form-item style="width: 100%;" v-if="form.type === '0'">
<el-button type="primary" @click="add('statisticsConfigs')">添加统计项</el-button>
</el-form-item>
<div v-if="form.type === '0'">
<el-form-item :label="'分组' + index" style="width: 100%;" v-for="(item, index) in form.groupConfigs" :key="'groupConfigs' + item.fieldName">
<div class="form-flex">
<div>
<el-select size="small" style="width: 160px;" v-model="item.fieldName" placeholder="请选择" clearable>
<el-option
v-for="item in filedList"
:key="item.id"
:label="item.fieldCnName"
:value="item.fieldName">
</el-option>
</el-select>
</div>
<el-button type="danger" @click="removeConfig('groupConfigs', index)">删除</el-button>
</div>
</el-form-item>
</div>
<el-form-item style="width: 100%;" v-if="form.type === '0'">
<el-button type="primary" @click="add('groupConfigs')">添加分组</el-button>
</el-form-item>
<div v-if="form.type === '0'">
<el-form-item :label="'统计项' + index" style="width: 100%;" v-for="(item, index) in form.orderConfigs" :key="'orderConfigs' + item.fieldName">
<div class="form-flex">
<div>
<el-select size="small" style="width: 160px;" v-model="item.fieldName" placeholder="请选择" clearable>
<el-option
v-for="item in filedList"
:key="item.id"
:label="item.fieldCnName"
:value="item.fieldName">
</el-option>
</el-select>
<el-select size="small" style="width: 160px; margin-left: 10px;" v-model="item.orderType" placeholder="请选择" clearable>
<el-option
v-for="item in orderTypeDict"
:key="item.id"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
<el-button type="danger" @click="removeConfig('orderConfigs', index)">删除</el-button>
</div>
</el-form-item>
</div>
<el-form-item style="width: 100%;" v-if="form.type === '0'">
<el-button type="primary" @click="add('orderConfigs')">添加排序</el-button>
</el-form-item>
</div>
</el-form>
</ai-dialog>
</template>
</ai-detail>
</template>
<script>
export default {
name: 'SourceData',
props: {
instance: Function,
dict: Object,
params: Object,
urlPrefix: String
},
data() {
return {
isShow: false,
search: {
current: 1,
size: 10,
name: ''
},
total: 0,
colConfigs: [
{prop: 'appName', label: '应用名'},
{prop: 'appTableName', align: 'center', label: '表名'},
{prop: 'description', align: 'center', label: '描述'},
{prop: 'type', align: 'center', label: '类型', formart: v => v === '0' ? '村微应用' : 'sql语句'},
{prop: 'createUserName', align: 'center', label: '创建人'},
{prop: 'createTime', align: 'center', label: '创建时间'}
],
tableData: [],
filedList: [],
appList: [],
form: {
orderType: 'asc',
dataRange: '0',
type: '0',
sqlContent: '',
appId: '',
description: '',
appName: '',
appTableName: '',
count: '100',
statisticsConfigs: [{
alias: '',
calcType: '',
dictCode: '',
fieldCnName: '',
fieldName: ''
}],
orderConfigs: [{
alias: '',
calcType: '',
dictCode: '',
fieldCnName: '',
fieldName: ''
}],
groupConfigs: [{
alias: '',
calcType: '',
dictCode: '',
fieldCnName: '',
fieldName: ''
}]
},
id: '',
orderTypeDict: [
{
value: 'asc',
label: '升序'
},
{
value: 'desc',
label: '降序'
}
]
}
},
created() {
this.dict.load(['diyLargeScreenDatasourceCalcType2']).then(() => {
this.getList()
this.getAppList()
})
},
methods: {
getInfo(id) {
this.instance.post(`${this.urlPrefix}/wxcp/wxuser/queryDetailById?id=${id}`).then(res => {
if (res.code === 0) {
this.form = {
...res.data
}
}
})
},
onChooseField(type, fieldName, index) {
const dictCode = this.filedList.filter(v => v.fieldName === fieldName)[0].dictCode
this.$set(this.form[type][index], 'dictCode', dictCode)
},
add(type) {
this.form[type].push({
alias: '',
calcType: '',
dictCode: '',
fieldCnName: '',
fieldName: ''
})
},
removeConfig(type, index) {
this.form[type].splice(index, 1)
},
toEdit(e) {
this.id = e.id
this.instance.post(`${this.urlPrefix}/appdiylargescreen/queryDatasourceDetailById?id=${e.id}`).then(res => {
if (res.code === 0) {
this.form = {
...res.data
}
this.form.dataRange = this.form.dataRange === '0' ? '0' : '1'
this.form.count = res.data.dataRange
this.filedList = this.appList.filter(v => v.id === res.data.appId).length && this.appList.filter(v => v.id === res.data.appId)[0].fields.map(item => {
let value = []
res.data.configs.forEach(v => {
if (v.fieldName === item.fieldName) {
value.push(v.calcType)
}
})
return {
...item,
value
}
})
this.isShow = true
}
})
},
remove(id) {
this.$confirm('确定删除该数据?').then(() => {
this.instance.post(`${this.urlPrefix}/appquestionnairetemplate/delete?id=${id}`).then(res => {
if (res.code == 0) {
this.$message.success('删除成功!')
this.getList()
}
})
})
},
getList() {
this.instance.post(`${this.urlPrefix}/appdiylargescreen/allDatasourceByPage`, null, {
params: {
...this.search
}
}).then(res => {
if (res.code == 0) {
this.tableData = res.data.records
this.total = res.data.total
}
})
},
getAppList() {
this.instance.post(`${this.urlPrefix}/appdiylargescreen/allDatasourceApp`).then(res => {
if (res.code === 0) {
this.appList = res.data
}
})
},
onClose() {
this.id = ''
this.form.orderType = 'asc'
this.form.dataRange = 0
this.form.appId = ''
this.form.description = ''
this.form.appName = ''
this.form.appTableName = ''
this.form.count = 100
},
onAppChange(e) {
const value = this.appList.filter(v => v.id === e)[0]
this.form.appTableName = value.appTableName
this.form.appName = value.appName
this.form.statisticsConfigs = [{
alias: '',
calcType: '',
dictCode: '',
fieldCnName: '',
fieldName: ''
}]
this.form.orderConfigs = [{
alias: '',
calcType: '',
dictCode: '',
fieldCnName: '',
fieldName: ''
}]
this.form.groupConfigs = [{
alias: '',
calcType: '',
dictCode: '',
fieldCnName: '',
fieldName: ''
}]
this.filedList = value.fields.map(v => {
return {
...v,
value: ''
}
})
},
onConfirm() {
this.$refs.form.validate((valid) => {
if (valid) {
let configs = []
if (this.filedList.length) {
this.filedList.forEach(item => {
if (item.value.length) {
item.value.forEach(v => {
configs.push({
alias: item.fieldCnName,
calcType: v,
fieldCnName: item.fieldCnName,
fieldName: item.fieldName,
dictCode: item.dictCode,
orderType: this.orderType
})
})
}
})
}
this.instance.post(`${this.urlPrefix}/appdiylargescreen/addOrUpdateDatasource`, {
...this.form,
configs,
id: this.id ? this.id : '',
dataRange: this.form.dataRange === '0' ? 0 : this.form.count
}).then(res => {
if (res.code === 0) {
this.$message.success(this.id ? '编辑成功' : '添加成功')
this.search.current = 1
this.isShow = false
this.getList()
}
})
}
})
},
cancel() {
this.$router.push({})
}
}
}
</script>
<style scoped lang="scss">
.form-flex {
display: flex;
justify-content: space-between;
align-items: center;
}
</style>

View File

@@ -1,463 +0,0 @@
<template>
<div class="layout-config__group--wrapper">
<ai-dialog
append-to-body
:visible.sync="isShowEditor"
width="1000px"
class="layout-config__edit"
title="编辑器"
@onConfirm="onConfirm">
<div>
<code-editor v-model="json" :lint="true" auto-format height="440px"></code-editor>
</div>
</ai-dialog>
<div class="layout-config__group" v-if="options.monitorType !== 'hik' && options.monitorType !== 'dahua'">
<h2>基础设置</h2>
<div class="layout-config__item">
<label>数据类型</label>
<div class="layout-config__item--right">
<el-select size="mini" v-model="options.dataType" placeholder="请选择数据类型">
<el-option
v-for="item in dataTypes"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
</div>
<div class="layout-config__code" v-if="options.dataType === 'staticData'">
<el-button @click="showEditor" class="layout-config__code--btn" title="编辑" type="text" icon="iconfont iconjdq_led_edit"></el-button>
<vue-json-editor
:value="options.staticData"
:show-btns="false"
mode="view"
lang="zh">
</vue-json-editor>
</div>
<template v-else-if="options.dataType === 'dynamicData'">
<div class="layout-config__item">
<label>数据源</label>
<div class="layout-config__item--right">
<el-select size="mini" v-model="options.sourceDataId" placeholder="请选择数据源" @change="onDataChange">
<el-option
v-for="item in sourceData"
:key="item.id"
:label="item.description"
:value="item.id">
</el-option>
</el-select>
</div>
</div>
</template>
<template v-else>
<div class="layout-config__item">
<label>接口地址</label>
<div class="layout-config__item--right">
<el-input size="mini" v-model="options.api" @blur="onApiChange"></el-input>
</div>
</div>
</template>
</div>
<div class="layout-config__group" v-if="options.monitorType === 'hik' || options.monitorType === 'dahua'">
<h2>基础设置</h2>
<div class="layout-config__item">
<label>视频地址</label>
<div class="layout-config__item--right">
<el-input size="mini" v-model="options.src"></el-input>
</div>
</div>
</div>
<div class="layout-config__group" v-if="options.dataType !== 'staticData' && options.type === 'monitor' && (options.monitorType === 'cmcc' || options.monitorType === 'slw')">
<h2>字段设置</h2>
<div class="layout-config__item">
<label>监控视频</label>
<div class="layout-config__item--right">
<el-select size="mini" v-model="options.moniterId" placeholder="请选择监控视频" @change="onMoniterId">
<el-option
v-for="(item, index) in monitorList"
:key="index"
:label="item.name"
:value="item.id">
</el-option>
</el-select>
</div>
</div>
</div>
<div class="layout-config__group" v-if="options.dataType !== 'staticData' && options.type !== 'monitor' && keys.length && options.type !== 'table'">
<h2>字段设置</h2>
<div class="layout-config__item">
<label>X轴设置</label>
<div class="layout-config__item--right">
<el-select size="mini" v-model="options.dataX" placeholder="请选择X轴" @change="onChooseChange">
<el-option
v-for="(item, index) in keys"
:key="index"
:label="item"
:value="item">
</el-option>
</el-select>
</div>
</div>
<div class="layout-config__item">
<label>Y轴设置</label>
<div class="layout-config__item--right">
<el-select size="mini" multiple :multiple-limit="options.type.indexOf('pie') > -1 ? 1 : 100" v-model="options.dataY" collapse-tags placeholder="请选择Y轴" @change="onChooseChange">
<el-option
v-for="(item, index) in keys"
:key="index"
:label="item"
:value="item">
</el-option>
</el-select>
</div>
</div>
</div>
</div>
</template>
<script>
import vueJsonEditor from 'vue-json-editor'
import { CodeEditor } from 'bin-code-editor'
import 'bin-code-editor/lib/styles/index.css'
export default {
name: 'dataCofing',
props: {
options: Object,
instance: Function,
dict: Object,
params: Object,
urlPrefix: String
},
data () {
return {
dataTypes: [
{
value: 'staticData',
label: '静态数据'
},
{
value: 'dynamicData',
label: '动态数据'
},
{
value: 'apiData',
label: '接口'
}
],
isShowEditor: false,
json: {},
sourceDataId: '',
sourceData: [],
keys: [],
monitorList: [],
list: [],
jsonData: `{"title":"测试json数据","children":[{"name":"子项名称", "desc":"子项说明" },{"name":"子项名称1", "desc":"子项说明1" }]}`
}
},
components: {
vueJsonEditor,
CodeEditor
},
mounted () {
this.getDataList()
if ((this.options.dataY && this.options.dataY.length && this.options.dataX) || this.options.type === 'monitor') {
const api = this.options.dataType === 'apiData' ? this.options.api : `${this.urlPrefix}/appdiylargescreen/statisticsByLsid?id=${this.options.sourceDataId}`
this.instance.post(api).then(res => {
if (res.code == 0) {
if (res.data.length && this.options.type !== 'monitor') {
this.list = res.data
this.keys = Object.keys(res.data[0])
this.$nextTick(() => {
this.onChooseChange()
})
} else if (this.options.type === 'monitor') {
this.monitorList = res.data
if (this.options.src) {
const obj = res.data.filter(v => this.options.title === v.name)
if (obj.length) {
this.options.src = obj[0].url
}
}
}
}
})
}
},
methods: {
showEditor () {
this.json = JSON.stringify(this.options.staticData)
this.isShowEditor = true
},
onMoniterId (e) {
this.instance.post(`${this.urlPrefix}/appzyvideoequipment/getWebSdkUrl?deviceId=${e}`).then(res => {
if (res.code == 0) {
this.options.src = JSON.parse(res.data).url
}
})
},
getDataList () {
this.instance.post(`${this.urlPrefix}/appdiylargescreen/allDatasourceByPage`, null, {
params: {
current: 1,
size: 10000
}
}).then(res => {
if (res.code == 0) {
this.sourceData = res.data.records
}
})
},
onApiChange () {
this.options.dataX = ''
this.options.dataY = []
this.instance.post(this.options.api).then(res => {
if (res.code == 0) {
if (res.data.length) {
if (this.options.type === 'table') {
const keys = Object.keys(res.data[0])
const list = res.data
this.options.apiData = keys.map(v => {
let obj = {}
list.forEach((item, index) => {
obj[`v${index}`] = item[v]
})
return {
row: v,
...obj
}
})
} else if (this.options.type === 'summary') {
if (this.options.display === 'summary9') {
this.options.apiData = res.data
} else {
this.options.apiData = Object.keys(res.data[0]).map(item => {
return {
key: item,
value: res.data[0][item]
}
})
}
} else if (this.options.type === 'monitor') {
this.monitorList = res.data
} else {
this.list = res.data
this.keys = Object.keys(res.data[0])
}
}
} else {
this.options.dynamicData = []
}
})
},
onChooseChange () {
let arr = []
if (this.options.dataX && this.options.dataY.length) {
this.list.forEach(item => {
let obj = {}
this.options.dataY.forEach(v => {
obj[v] = item[v]
})
arr.push({
[this.options.dataX]: item[this.options.dataX],
...obj
})
})
this.options[this.options.dataType] = arr
}
},
onDataChange (e) {
this.options.dataX = ''
this.options.dataY = []
this.instance.post(`${this.urlPrefix}/appdiylargescreen/statisticsByLsid?id=${e}`).then(res => {
if (res.code == 0) {
if (res.data.length) {
if (this.options.type === 'table') {
const keys = Object.keys(res.data[0])
const list = res.data
this.options.dynamicData = keys.map(v => {
let obj = {}
list.forEach((item, index) => {
obj[`v${index}`] = item[v]
})
return {
row: v,
...obj
}
})
} else if (this.options.type === 'summary') {
this.options.dynamicData = Object.keys(res.data[0]).map(item => {
return {
key: item,
value: res.data[0][item]
}
})
} else {
this.list = res.data
this.keys = Object.keys(res.data[0])
}
} else {
this.options.dynamicData = []
}
}
})
},
onConfirm () {
this.$set(this.options, 'staticData', JSON.parse(this.json))
this.isShowEditor = false
this.$emit('change')
}
}
}
</script>
<style lang="scss">
.el-dialog__body {
.jsoneditor-vue {
height: 480px;
.jsoneditor-poweredBy {
display: none;
}
}
}
.layout-config__group--wrapper {
.layout-config__code .jsoneditor-vue {
.jsoneditor-menu {
display: none;
}
.jsoneditor {
border: 1px solid #030411;
background: #0e1013;
}
.jsoneditor-field {
color: gray;
}
.jsoneditor-tree button:focus {
background-color: transparent;
outline: none;
}
}
.layout-config__group {
padding: 10px 10px 20px;
border-bottom: 1px solid #000000;
&:last-child {
border: none;
}
.layout-config__code {
position: relative;
padding-left: 10px;
.layout-config__code--btn {
position: absolute;
right: 0;
top: 0;
color: gray;
z-index: 1;
&:hover {
opacity: 0.8 ;
}
}
}
& > h2 {
margin-bottom: 20px;
color: #FFFFFF;
font-size: 15px;
font-weight: 700;
}
}
.layout-config__item {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
&:last-child {
margin-bottom: 0;
}
label {
flex-shrink: 0;
width: 60px;
color: #FFFFFF;
font-size: 12px;
text-align: right;
}
.layout-config__item--right {
display: flex;
align-items: center;
justify-content: flex-end;
width: 200px;
text-align: right;
}
.el-select .el-tag {
color: #fff;
background: transparent;
}
input {
background: #262C33;
font-size: 12px;
color: #fff;
border: 1px solid #030411;
}
.el-input__icon {
color: #fff;
}
.el-switch__label {
color: #fff;
}
.el-select {
width: 100%;
&:last-child {
margin-right: 0;
}
input {
background: #262C33;
font-size: 12px;
color: #fff;
border: 1px solid #030411;
}
.el-input__icon {
color: #fff;
}
}
}
}
</style>

View File

@@ -1,734 +0,0 @@
const components = [
{
type: 'chart',
label: '图表',
list: [
{
label: '柱状图',
type: 'bar',
list: [
{
code: 'widget-linechart',
type: 'barChart1',
label: '柱状图1',
title: '柱状图',
border: 'border1',
icon: 'icontext_box',
value: '',
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/bar1.png',
width: 500,
sourceDataId: '',
height: 300,
dataX: '',
zIndex: 1,
dataY: [],
top: 0,
left: 0,
api: '',
apiData: [],
dataType: 'staticData',
staticData: [
{name: '阿斯达', v1: 23},
{name: '水电费', v1: 12},
{name: '凡哥', v1: 67},
{name: '党费', v1: 98}
],
config: 'barChart1',
dynamicData: []
},
{
code: 'widget-linechart',
type: 'barChart2',
label: '柱状图2',
icon: 'icontext_box',
value: '',
title: '柱状图2',
width: 500,
border: 'border1',
sourceDataId: '',
height: 300,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/bar2.png',
dataX: '',
dataY: [],
top: 0,
zIndex: 1,
left: 0,
dataType: 'staticData',
api: '',
apiData: [],
staticData: [
{name: '阿斯达', v1: 23},
{name: '水电费', v1: 12},
{name: '凡哥', v1: 67},
{name: '党费', v1: 98}
],
config: 'barChart2',
dynamicData: []
},
{
code: 'widget-linechart',
type: 'barChart3',
label: '柱状图3',
title: '柱状图3',
icon: 'icontext_box',
value: '',
width: 500,
sourceDataId: '',
height: 300,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/bar3.png',
dataX: '',
dataY: [],
border: 'border1',
top: 0,
left: 0,
zIndex: 1,
dataType: 'staticData',
api: '',
apiData: [],
staticData: [
{name: '阿斯达', v1: 23},
{name: '水电费', v1: 12},
{name: '凡哥', v1: 67},
{name: '党费', v1: 98}
],
config: 'barChart3',
dynamicData: []
},
{
code: 'widget-linechart',
type: 'barChart5',
label: '柱状图4',
title: '柱状图4',
icon: 'icontext_box',
value: '',
width: 500,
sourceDataId: '',
height: 300,
dataX: '',
dataY: [],
zIndex: 1,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/bar5.png',
top: 0,
left: 0,
border: 'border1',
api: '',
apiData: [],
dataType: 'staticData',
staticData: [
{name: '阿斯达', v1: 23},
{name: '水电费', v1: 12},
{name: '凡哥', v1: 67},
{name: '党费', v1: 98}
],
config: 'barChart5',
dynamicData: []
},
{
code: 'widget-linechart',
type: 'barChart7',
label: '柱状图5',
title: '柱状图5',
icon: 'icontext_box',
value: '',
width: 500,
sourceDataId: '',
height: 300,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/bar7.png',
dataX: '',
zIndex: 1,
dataY: [],
top: 0,
left: 0,
api: '',
apiData: [],
dataType: 'staticData',
staticData: [
{name: '阿斯达', v1: 23},
{name: '水电费', v1: 12},
{name: '凡哥', v1: 67},
{name: '党费', v1: 98}
],
config: 'barChart7',
dynamicData: []
},
{
code: 'widget-linechart',
type: 'barChart8',
label: '柱状图6',
title: '柱状图6',
icon: 'icontext_box',
value: '',
width: 500,
sourceDataId: '',
border: 'border1',
height: 300,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/bar8.png',
dataX: '',
dataY: [],
zIndex: 1,
top: 0,
left: 0,
api: '',
apiData: [],
dataType: 'staticData',
staticData: [
{name: '阿斯达', v1: 23},
{name: '水电费', v1: 12},
{name: '凡哥', v1: 67},
{name: '党费', v1: 98}
],
config: 'barChart8',
dynamicData: []
},
{
code: 'widget-linechart',
type: 'barChart9',
label: '柱状图7',
title: '柱状图7',
border: 'border1',
icon: 'icontext_box',
value: '',
width: 500,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/bar9.png',
sourceDataId: '',
height: 300,
dataX: '',
dataY: [],
zIndex: 1,
top: 0,
left: 0,
api: '',
apiData: [],
dataType: 'staticData',
staticData: [
{name: '阿斯达', v1: 23},
{name: '水电费', v1: 12},
{name: '凡哥', v1: 67},
{name: '党费', v1: 98}
],
config: 'barChart9',
dynamicData: []
}
]
},
{
label: '折线图',
type: 'line',
list: [
{
code: 'widget-linechart',
type: 'lineChart1',
label: '折线图1',
title: '折线图1',
border: 'border1',
icon: 'icontext_box',
value: '',
width: 500,
height: 300,
top: 0,
left: 0,
zIndex: 1,
api: '',
apiData: [],
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/line1.png',
dataX: '',
dataY: [],
dataType: 'staticData',
staticData: [
{name: '阿斯达', v1: 23, v2: 33},
{name: '水电费', v1: 12, v2: 34},
{name: '凡哥', v1: 67, v2: 25},
{name: '党费', v1: 98, v2: 85}
],
config: 'lineChart1',
sourceDataId: '',
dynamicData: []
},
{
code: 'widget-linechart',
type: 'lineChart2',
label: '折线图2',
title: '折线图2',
border: 'border1',
icon: 'icontext_box',
value: '',
width: 500,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/line2.png',
height: 300,
top: 0,
left: 0,
dataX: '',
dataY: [],
zIndex: 1,
api: '',
apiData: [],
dataType: 'staticData',
staticData: [
{name: '阿斯达', v1: 23, v2: 33},
{name: '水电费', v1: 12, v2: 34},
{name: '凡哥', v1: 67, v2: 25},
{name: '党费', v1: 98, v2: 85}
],
config: 'lineChart2',
sourceDataId: '',
dynamicData: []
},
{
code: 'widget-linechart',
type: 'lineChart3',
label: '折线图3',
title: '折线图3',
icon: 'icontext_box',
border: 'border1',
value: '',
width: 500,
height: 300,
zIndex: 1,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/line3.png',
top: 0,
left: 0,
dataX: '',
dataY: [],
api: '',
apiData: [],
dataType: 'staticData',
staticData: [
{name: '阿斯达', v1: 23, v2: 33},
{name: '水电费', v1: 12, v2: 34},
{name: '凡哥', v1: 67, v2: 25},
{name: '党费', v1: 98, v2: 85}
],
config: 'lineChart3',
sourceDataId: '',
dynamicData: []
},
{
code: 'widget-linechart',
type: 'lineChart4',
label: '折线图4',
title: '折线图4',
icon: 'icontext_box',
value: '',
border: 'border1',
width: 500,
height: 300,
zIndex: 1,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/line4.png',
top: 0,
left: 0,
dataX: '',
dataY: [],
api: '',
apiData: [],
dataType: 'staticData',
staticData: [
{name: '阿斯达', v1: 23, v2: 33},
{name: '水电费', v1: 12, v2: 34},
{name: '凡哥', v1: 67, v2: 25},
{name: '党费', v1: 98, v2: 85}
],
config: 'lineChart4',
sourceDataId: '',
dynamicData: []
},
{
code: 'widget-linechart',
type: 'lineChart5',
label: '折线图5',
title: '折线图5',
icon: 'icontext_box',
value: '',
border: 'border1',
width: 500,
height: 300,
zIndex: 1,
top: 0,
left: 0,
dataX: '',
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/line5.png',
dataY: [],
api: '',
apiData: [],
dataType: 'staticData',
staticData: [
{name: '阿斯达', v1: 23, v2: 33},
{name: '水电费', v1: 12, v2: 34},
{name: '凡哥', v1: 67, v2: 25},
{name: '党费', v1: 98, v2: 85}
],
config: 'lineChart5',
sourceDataId: '',
dynamicData: []
}
]
},
{
label: '饼图',
type: 'pie',
list: [
{
code: 'widget-linechart',
type: 'pieChart2',
config: 'pieChart2',
label: '饼图',
title: '饼图',
icon: 'icontext_box',
value: '',
border: 'border1',
width: 500,
height: 300,
zIndex: 1,
top: 0,
left: 0,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/pie.png',
dataX: '',
dataY: [],
api: '',
apiData: [],
dataType: 'staticData',
staticData: [
{name: '阿斯达', v1: 23, v2: 33},
{name: '水电费', v1: 12, v2: 34},
{name: '凡哥', v1: 67, v2: 25},
{name: '党费', v1: 98, v2: 85}
],
sourceDataId: '',
dynamicData: []
},
{
code: 'widget-linechart',
type: 'pieChart1',
label: '饼图',
title: '饼图',
icon: 'icontext_box',
value: '',
border: 'border1',
width: 500,
height: 300,
zIndex: 1,
top: 0,
left: 0,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/pie.png',
dataX: '',
dataY: [],
api: '',
apiData: [],
dataType: 'staticData',
staticData: [
{name: '阿斯达', v1: 23, v2: 33},
{name: '水电费', v1: 12, v2: 34},
{name: '凡哥', v1: 67, v2: 25},
{name: '党费', v1: 98, v2: 85}
],
config: 'pieChart1',
sourceDataId: '',
dynamicData: []
},
{
code: 'widget-linechart',
type: 'pieChart3',
label: '饼图',
title: '饼图',
icon: 'icontext_box',
value: '',
border: 'border1',
width: 500,
height: 300,
zIndex: 1,
top: 0,
left: 0,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/pie.png',
dataX: '',
dataY: [],
api: '',
apiData: [],
dataType: 'staticData',
staticData: [
{name: '阿斯达', v1: 23, v2: 33},
{name: '水电费', v1: 12, v2: 34},
{name: '凡哥', v1: 67, v2: 25},
{name: '党费', v1: 98, v2: 85}
],
config: 'pieChart1',
sourceDataId: '',
dynamicData: []
}
]
}
]
},
{
type: 'table',
label: '表格',
list: [
{
label: '表格',
type: 'table',
list: [
{
type: 'table',
label: '表格',
title: '表格',
border: 'border1',
width: 650,
height: 400,
zIndex: 1,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/table.png',
dataX: '',
dataY: [],
rowNum: 7,
isShowIndex: '1',
sourceDataId: '',
api: '',
apiData: [],
dataType: 'staticData',
dynamicData: [],
staticData: [
{name: '列1', v: 23, v2: 3},
{name: '列2', v: 12, v2: 4},
{name: '列2', v: 12, v2: 4}
]
}
]
}
]
},
{
type: 'ai3d', label: "3D", list: [
{
label: "3D楼栋", type: 'building', list: [{
type: 'building1', label: "楼栋模型1",
width: 840,
height: 800,
zIndex: 1,
title: "楼栋模型1",
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/total.png'
}]
}
]
},
{
type: 'other',
label: '其他',
list: [
{
label: '地图',
type: 'map',
list: [
{
type: 'map',
label: '地图',
display: 'map',
width: 840,
height: 534,
left: 0,
top: 0,
mask: '2',
pulseLines: 1,
mapStyle: "e51987628aee5206d4c9ca8c6e98b4f7",
areaId: '',
zIndex: 1,
apiData: [],
dataType: 'staticData',
dynamicData: [],
staticData: [
{
content: '中卫慧通',
lng: 117.1339399,
lat: 36.7190487,
地区: '中卫慧通',
经度: 117.1339399,
纬度: 36.7190487
}
],
api: '',
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/map.png'
}
]
},
{
label: '党组织',
type: 'partyOrg',
list: [
{
type: 'partyOrg',
label: '党组织',
width: 840,
height: 800,
zIndex: 1,
top: 0,
left: 0,
dataX: '',
dataY: [],
title: '党组织',
border: 'border3',
sourceDataId: '',
dataType: 'staticData',
staticData: [
{
key: '个人服务办理',
value: 247
},
{
key: '同比上月',
value: 247
}
],
dynamicData: [],
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/total.png'
}
]
},
{
label: '边框',
type: 'panel',
list: [
{
type: 'panel',
label: '边框',
title: '边框',
border: 'border0',
width: 400,
height: 400,
isZoom: false,
zIndex: 1,
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/border.png'
}
]
},
{
label: '装饰',
type: 'display',
list: [
{
type: 'display',
label: '装饰',
display: 'display0',
width: 840,
height: 540,
isZoom: false,
zIndex: 1,
title: '标题',
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/display.png',
sourceDataId: '',
dataType: 'staticData',
staticData: [
{
label: '个人服务办理',
value: 247
},
{
label: '同比上月',
value: 247
}
]
}
]
},
{
label: '轮播图',
type: 'swiper',
list: [
{
type: 'swiper',
label: '轮播图',
width: 400,
height: 300,
zIndex: 1,
border: 'border2',
dataType: 'staticData',
staticData: [
{
img: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/pie.png',
title: '湖羊',
content: `歙县众城湖羊养殖专业合作社
徐晓红 - 18273645627
歙县郑村镇唐跃村碉墅`
}
],
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/swiper.png'
}
]
},
{
label: '视频播放器',
type: 'video',
list: [
{
type: 'video',
label: '视频播放器',
width: 400,
height: 300,
zIndex: 1,
src: '',
border: 'border2',
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/swiper.png'
}
]
},
{
label: '数据统计',
type: 'summary',
list: [
{
type: 'summary',
label: '数据统计',
display: 'summary0',
width: 480,
height: 240,
zIndex: 1,
top: 0,
left: 0,
dataX: '',
dataY: [],
summaryTitle: '',
border: 'border3',
sourceDataId: '',
title: '数据统计',
dataType: 'staticData',
staticData: [
{
key: '个人服务办理',
value: 247
},
{
key: '同比上月',
value: 247
}
],
dynamicData: [],
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/total.png'
}
]
},
{
label: '视频监控',
type: 'monitor',
list: [
{
type: 'monitor',
label: '视频监控',
src: '',
width: 480,
height: 240,
zIndex: 1,
top: 0,
left: 0,
title: '',
moniterId: '',
monitorType: 'cmcc',
api: '/app/appzyvideoequipment/list2',
border: 'border2',
sourceDataId: '',
dataType: 'staticData',
staticData: '',
dynamicData: '',
thumb: 'https://cdn.cunwuyun.cn/dvcp/dv/tpl/video.png'
}
]
}
]
}
]
export {components}

View File

@@ -1,211 +0,0 @@
<template>
<section class="AppGigscreenViewer">
<div v-if="!component">
<div
class="component-item"
:style="{
width: item.width + 'px',
height: item.height + 'px',
left: item.left * scale + 'px',
top: item.top * scale + 'px',
position: 'absolute',
zIndex: item.zIndex,
transform: `scale(${scale})`
}"
v-for="(item, index) in componentList"
:key="index">
<ai-dv-render :instance="instance" :data="item" :index="index" :theme="dashboard.theme"/>
</div>
</div>
<components v-else :is="component" :dict="dict" :instance="instance" :nav="meta"/>
</section>
</template>
<script>
export default {
name: 'AppGigscreenViewer',
label: '大屏预览',
props: {
instance: Function,
dict: Object,
id: String,
urlPrefix: {
type: String,
default: '/app'
}
},
watch: {
id(v) {
this.getInfo(v)
}
},
data() {
return {
component: '',
dashboard: {
title: '大屏',
width: 1920,
height: 1080,
backgroundColor: '',
theme: '0',
backgroundImage: []
},
componentList: [],
scale: 1,
meta: {}
}
},
created() {
this.getInfo(this.id)
},
mounted() {
this.$nextTick(() => {
let content = document.querySelector('#dv-full-screen-container')
if (content) {
const transform = content.style.transform
const scale = transform.replace('scale', '').replace('(', '').replace(')', '')
if (scale == 1) {
this.scale = document.body.clientWidth / 1920
}
}
})
},
methods: {
getInfo(id) {
this.component = null
id && this.instance.post(`${this.urlPrefix}/appdiylargescreen/queryLargeScreenDetailById?id=${id}`).then(res => {
if (res?.data) {
const config = JSON.parse(res.data.config)
if (config.custom) {
this.component = config.custom
this.meta = config?.meta || {}
} else {
this.componentList = JSON.parse(res.data.config).config
this.dashboard = JSON.parse(res.data.config).dashboard
this.componentList.forEach((item, index) => {
if (item.dataType !== 'staticData' && ((item.type.indexOf('Chart') > -1) || ['display', 'table', 'map', 'summary'].includes(item.type))) {
this.getSourceData(item, index)
}
if (item.type === 'monitor' && item.monitorType === 'cmcc') {
this.instance.post(`${this.urlPrefix}/appzyvideoequipment/getWebSdkUrl?deviceId=${item.moniterId}`).then(res => {
if (res.code == 0) {
this.$set(this.componentList[index], 'src', JSON.parse(res.data).url)
}
})
}
if (item.type === 'monitor' && item.monitorType === 'slw') {
this.instance.post(`${this.urlPrefix}/appzyvideoequipment/getWebSdkUrl?deviceId=${item.moniterId}`).then(res => {
if (res.code == 0) {
this.$set(this.componentList[index], 'src', res.data)
}
})
}
})
}
}
})
},
getSourceData(item, index) {
const api = item.dataType === 'apiData' ? item.api : `${this.urlPrefix}/appdiylargescreen/statisticsByLsid?id=${item.sourceDataId}`
this.instance.post(api).then(res => {
if (res.code == 0) {
if (res.data.length) {
const keys = Object.keys(res.data[0])
const list = res.data
let dynamicData = []
if (item.type === 'table') {
dynamicData = keys.map(v => {
let obj = {}
list.forEach((item, index) => {
obj[`v${index}`] = item[v]
})
return {
row: v,
...obj
}
})
} else if (item.type === 'summary') {
if (item.display === 'summary9') {
dynamicData = res.data
} else {
dynamicData = Object.keys(res.data[0]).map(item => {
return {
key: item,
value: res.data[0][item]
}
})
}
} else if (item.dataType === 'dynamicData' && !item.dataX && !item.dataY.length) {
dynamicData = Object.keys(res.data[0]).map(item => {
return {
label: item,
value: res.data[0][item]
}
})
} else {
if (item.dataX && item.dataY.length) {
list.forEach(i => {
let obj = {}
item.dataY.forEach(v => {
obj[v] = i[v]
})
dynamicData.push({
[item.dataX]: i[item.dataX],
...obj
})
})
} else {
dynamicData = res.data
}
}
this.$set(this.componentList[index], item.dataType, dynamicData)
} else {
this.$set(this.componentList[index], item.dataType, [])
}
}
})
},
close() {
this.$emit('close')
}
}
}
</script>
<style lang="scss">
.AppGigscreenViewer {
position: relative;
height: 100%;
background: transparent !important;
.component-item {
transform-origin: 0 0;
}
.dv-scroll-board {
height: calc(100%) !important;
.header-item {
color: #7e8697;
font-size: 16px;
}
.index {
display: inline-block;
width: 26px;
height: 26px;
line-height: 26px;
font-size: 16px;
background-color: #4F57FF !important;
}
}
.vdr {
border: none;
}
}
</style>

View File

@@ -54,7 +54,7 @@
</div> </div>
</template> </template>
<script> <script lang="jsx">
import {mapState} from "vuex" import {mapState} from "vuex"
export default { export default {

View File

@@ -34,12 +34,12 @@
</section> </section>
</template> </template>
<script> <script lang="jsx">
import { mapState } from 'vuex' import {mapState} from 'vuex'
import DeviceSlider from '../components/deviceSlider' import DeviceSlider from "../components/deviceSlider"
import LocateDialog from '../components/locateDialog' import LocateDialog from "../components/locateDialog"
import AiMonitor from '../components/AiSlwVideo' import AiMonitor from "../components/AiSlwVideo"
import Synergy from '../components/Synergy' import Synergy from "../components/Synergy"
export default { export default {
name: 'AppISManage', name: 'AppISManage',

View File

@@ -26,168 +26,169 @@
</el-form> </el-form>
</ai-dialog> </ai-dialog>
<locate-dialog v-model="locate" :ins="instance" :latlng="latlng" @confirm="v=>handleLocate(selected,v)"/> <locate-dialog v-model="locate" :ins="instance" :latlng="latlng" @confirm="v=>handleLocate(selected,v)"/>
<ai-area custom-clicker :input-clicker="false" v-model="selected.areaId" :hideLevel="disabledLevel" :instance="instance" ref="BindArea" <ai-area custom-clicker :input-clicker="false" v-model="selected.areaId" :hideLevel="disabledLevel"
:instance="instance" ref="BindArea"
@change="handleSubmit(selected)"/> @change="handleSubmit(selected)"/>
</section> </section>
</template> </template>
<script> <script lang="jsx">
import { mapState } from 'vuex' import {mapState} from 'vuex'
import DeviceSlider from "../components/deviceSlider"; import DeviceSlider from "../components/deviceSlider";
import LocateDialog from "../components/locateDialog"; import LocateDialog from "../components/locateDialog";
export default { export default {
name: "AppMonitorManage", name: "AppMonitorManage",
components: {LocateDialog, DeviceSlider}, components: {LocateDialog, DeviceSlider},
label: "监控实况", label: "监控实况",
props: { props: {
instance: Function, instance: Function,
dict: Object, dict: Object,
permissions: Function permissions: Function
},
computed: {
splitOps() {
return [
{label: "单分屏", value: 1, per: "100%"},
{label: "四分屏", value: 4, per: "49%"},
{label: "九分屏", value: 9, per: "32%"}
]
}, },
computed: { currentSplitStyle() {
splitOps() { let per = this.splitOps.find(e => e.value == this.splitScreen)?.per || "100%"
return [ return {width: per, height: per}
{label: "单分屏", value: 1, per: "100%"},
{label: "四分屏", value: 4, per: "49%"},
{label: "九分屏", value: 9, per: "32%"}
]
},
currentSplitStyle() {
let per = this.splitOps.find(e => e.value == this.splitScreen)?.per || "100%"
return {width: per, height: per}
},
...mapState(['user'])
}, },
...mapState(['user'])
},
data() { data() {
return { return {
slider: true, slider: true,
fullscreen: false, fullscreen: false,
splitScreen: 1, splitScreen: 1,
monitors: [], monitors: [],
dialog: false, dialog: false,
locate: false, locate: false,
selected: { selected: {
areaId: '' areaId: ''
}, },
latlng: null, latlng: null,
disabledLevel: 0, disabledLevel: 0,
rules: { rules: {
name: [{required: true, message: "请填写 设备名称"}] name: [{required: true, message: "请填写 设备名称"}]
}
} }
}, }
},
created () { created() {
this.selected.areaId = this.user.info.areaId this.selected.areaId = this.user.info.areaId
this.disabledLevel = this.user.info.areaList.length this.disabledLevel = this.user.info.areaList.length
}, },
methods: { methods: {
handleFullscreen() { handleFullscreen() {
this.fullscreen = !this.fullscreen this.fullscreen = !this.fullscreen
this.$fullscreen(this.fullscreen) this.$fullscreen(this.fullscreen)
}, },
handleSelectMonitor(monitor) { handleSelectMonitor(monitor) {
let {id} = monitor, let {id} = monitor,
index = this.monitors.findIndex(e => e.id == id) index = this.monitors.findIndex(e => e.id == id)
if (index > -1) { if (index > -1) {
this.monitors.splice(index, 1) this.monitors.splice(index, 1)
this.monitors.map((e, i) => { this.monitors.map((e, i) => {
if (i > index) { if (i > index) {
this.showMonitor(e, true) this.showMonitor(e, true)
}
})
} else if (this.monitors.length >= this.splitScreen && this.splitScreen > 1) {
this.$message.warning("可分屏监控已满,请先取消其他的监控")
} else {
this.showMonitor(monitor)
}
},
showMonitor(monitor, refresh = false) {
let {id: deviceId} = monitor
deviceId && this.instance.post("/app/appzyvideoequipment/getWebSdkUrl", null, {
params: {deviceId}
}).then(res => {
if (res?.data) {
let data = JSON.parse(res.data)
if (refresh) {
monitor.url = data.url
} else if (this.splitScreen == 1) {
this.monitors = [{...monitor, ...data}]
} else {
this.monitors.push({...monitor, ...data})
}
} }
}) })
}, } else if (this.monitors.length >= this.splitScreen && this.splitScreen > 1) {
renderTreeItem: function (h, {node, data}) { this.$message.warning("可分屏监控已满,请先取消其他的监控")
let show = data.deviceStatus==1 ? 'show' : '' } else {
if (node.isLeaf) { this.showMonitor(monitor)
return ( }
<div class="flexRow"> },
<i class={['iconfont', 'iconshipinjiankong', show]}/> showMonitor(monitor, refresh = false) {
<div>{node.label}</div> let {id: deviceId} = monitor
<el-dropdown class="menuBtn" onCommand={e => this.handleSliderOption(e, data)}> deviceId && this.instance.post("/app/appzyvideoequipment/getWebSdkUrl", null, {
<i class="iconfont iconMore"/> params: {deviceId}
<el-dropdown-menu slot="dropdown"> }).then(res => {
<el-dropdown-item command="edit">修改名称</el-dropdown-item> if (res?.data) {
<el-dropdown-item command="area">行政地区</el-dropdown-item> let data = JSON.parse(res.data)
<el-dropdown-item command="locate">地图标绘</el-dropdown-item> if (refresh) {
</el-dropdown-menu> monitor.url = data.url
</el-dropdown> } else if (this.splitScreen == 1) {
</div> this.monitors = [{...monitor, ...data}]
) } else {
} else return ( this.monitors.push({...monitor, ...data})
}
}
})
},
renderTreeItem: function (h, {node, data}) {
let show = data.deviceStatus == 1 ? 'show' : ''
if (node.isLeaf) {
return (
<div class="flexRow"> <div class="flexRow">
<i class={['iconfont', 'iconshipinjiankong', show]}/>
<div>{node.label}</div> <div>{node.label}</div>
{data.id != 'no_area' ? <div class="sta"> <el-dropdown class="menuBtn" onCommand={e => this.handleSliderOption(e, data)}>
<p>{data.online || 0}</p>/{data.sum || 0} <i class="iconfont iconMore"/>
</div> <el-dropdown-menu slot="dropdown">
: <div/>} <el-dropdown-item command="edit">修改名称</el-dropdown-item>
<el-dropdown-item command="area">行政地区</el-dropdown-item>
<el-dropdown-item command="locate">地图标绘</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div> </div>
) )
}, } else return (
handleSliderOption(command, data) { <div class="flexRow">
this.selected = JSON.parse(JSON.stringify({...data, command})) <div>{node.label}</div>
if (command == "edit") {//修改名称 {data.id != 'no_area' ? <div class="sta">
this.dialog = true <p>{data.online || 0}</p>/{data.sum || 0}
} else if (command == "area") {//绑定areaId </div>
this.$refs.BindArea?.chooseArea() : <div/>}
} else if (command == "locate") {//地图标绘 </div>
this.latlng = data.lat && data.lng ? { )
lat: data.lat, },
lng: data.lng handleSliderOption(command, data) {
} : '' this.selected = JSON.parse(JSON.stringify({...data, command}))
this.locate = true if (command == "edit") {//修改名称
} this.dialog = true
}, } else if (command == "area") {//绑定areaId
handleSubmit(row) { this.$refs.BindArea?.chooseArea()
delete row.createTime } else if (command == "locate") {//地图标绘
return this.instance.post("/app/appzyvideoequipment/addOrUpdate", { this.latlng = data.lat && data.lng ? {
...row lat: data.lat,
}).then(res => { lng: data.lng
if (res?.code == 0) { } : ''
this.$message.success("提交成功!") this.locate = true
this.dialog = false
this.$refs.DeviceSlider?.getDevices()
}
})
},
handleLocate(row, locate) {
if (locate) {
let {lat, lng} = locate.location
this.handleSubmit({...row, lat, lng}).then(() => {
this.locate = false
})
}
} }
}, },
beforeDestroy() { handleSubmit(row) {
this.monitors = [] delete row.createTime
return this.instance.post("/app/appzyvideoequipment/addOrUpdate", {
...row
}).then(res => {
if (res?.code == 0) {
this.$message.success("提交成功!")
this.dialog = false
this.$refs.DeviceSlider?.getDevices()
}
})
},
handleLocate(row, locate) {
if (locate) {
let {lat, lng} = locate.location
this.handleSubmit({...row, lat, lng}).then(() => {
this.locate = false
})
}
} }
},
beforeDestroy() {
this.monitors = []
} }
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@@ -11,22 +11,16 @@ const install = function (Vue, params) {
if (install.installed) return if (install.installed) return
// 遍历注册全局组件 // 遍历注册全局组件
let apps = [] let apps = []
let contexts = require.context('.', true, /\.(\/.+)\/App[^\/]+\.vue$/) let contexts = import.meta.glob('./**/App*.vue')
if (contexts) { if (contexts) {
contexts.keys().map(e => { Object.keys(contexts).map(path => {
if (contexts(e).default) { if (/App[A-Z]\w+\.vue/.test(path)) {
if (params?.apps) { return contexts?.[path]()?.then(file => {
if (params?.apps.includes(contexts(e).default.name)) { apps.push(file.default)
apps.push(contexts(e).default) return Vue.component(file.default.name, file.default)
Vue.component(contexts(e).default.name, contexts(e).default) })
}
} else {
apps.push(contexts(e).default)
Vue.component(contexts(e).default.name, contexts(e).default)
}
} }
}) })
!!params?.showList && console.log(apps.map(e => e.name))
} }
core?.map(app => { core?.map(app => {
apps.push(app.component) apps.push(app.component)

View File

@@ -7,63 +7,67 @@
<template #content> <template #content>
<ai-search-bar> <ai-search-bar>
<template slot="left"> <template slot="left">
<el-button type="primary" icon="iconfont iconAdd" @click="handleAdd" <el-button type="primary" icon="iconfont iconAdd" @click="handleAdd">添加</el-button>
>添加</el-button
>
</template> </template>
<template slot="right"> <template slot="right">
<el-input <el-input
v-model="search.title" v-model="search.title"
class="search-input" class="search-input"
size="small" size="small"
placeholder="请输入课程主题" placeholder="请输入课程主题"
clearable clearable
v-throttle=" v-throttle="
() => { () => {
(search.current = 1), getList(); (search.current = 1), getList();
} }
" "
@clear="(search.current = 1), (search.title = ''), getList()" @clear="(search.current = 1), (search.title = ''), getList()"
suffix-icon="iconfont iconSearch" suffix-icon="iconfont iconSearch"
> >
</el-input> </el-input>
</template> </template>
</ai-search-bar> </ai-search-bar>
<ai-table <ai-table
:tableData="tableData" :tableData="tableData"
:col-configs="colConfigs" :col-configs="colConfigs"
stripe stripe
:total="total" :total="total"
:current.sync="page.current" :current.sync="page.current"
:size.sync="page.size" :size.sync="page.size"
style="margin-top: 10px" style="margin-top: 10px"
@getList="getList" @getList="getList"
:dict="dict"
> >
<el-table-column <el-table-column
slot="options" slot="options"
label="操作" label="操作"
align="center" align="center"
width="230px" width="230px"
fixed="right" fixed="right"
> >
<div slot-scope="{ row }" class="table-options"> <div slot-scope="{ row }" class="table-options">
<el-button <el-button
type="text" type="text"
:title="row.status == 0 ? '发布' : '取消发布'" :title="row.status == 0 ? '发布' : '取消发布'"
@click="handleChange(row)" @click="handleChange(row)"
>{{ row.status == 0 ? "发布" : "取消发布" }}</el-button >{{ row.status == 0 ? "发布" : "取消发布" }}
</el-button
> >
<el-button type="text" title="添加" @click="handleAddSeries(row)" <el-button type="text" title="添加" @click="handleAddSeries(row)"
>添加剧集</el-button >添加剧集
</el-button
> >
<el-button type="text" title="详情" @click="handleDetail(row)" <el-button type="text" title="详情" @click="handleDetail(row)"
>详情</el-button >详情
</el-button
> >
<el-button type="text" title="编辑" @click="handleEdit(row)" <el-button type="text" title="编辑" @click="handleEdit(row)"
>编辑</el-button >编辑
</el-button
> >
<el-button type="text" title="删除" @click="handleDelete(row)" <el-button type="text" title="删除" @click="handleDelete(row)"
>删除</el-button >删除
</el-button
> >
</div> </div>
</el-table-column> </el-table-column>
@@ -71,14 +75,14 @@
</template> </template>
</ai-list> </ai-list>
<component <component
:is="comp" :is="comp"
v-else v-else
:row="row" :row="row"
:instance="instance" :instance="instance"
:dict="dict" :dict="dict"
:permissions="permissions" :permissions="permissions"
@back="back" @back="back"
:isEdit="isEdit" :isEdit="isEdit"
></component> ></component>
</section> </section>
</template> </template>
@@ -86,12 +90,12 @@
<script> <script>
import partyClassAdd from "./components/partyClassAdd"; import partyClassAdd from "./components/partyClassAdd";
import seriesManage from "./components/seriesManage"; import seriesManage from "./components/seriesManage";
import { mapState } from "vuex"; import {mapState} from "vuex";
export default { export default {
name: "AppPartyHistoryClass", name: "AppPartyHistoryClass",
label: "党员学习", label: "党员学习",
components: { partyClassAdd, seriesManage }, components: {partyClassAdd, seriesManage},
props: { props: {
instance: Function, instance: Function,
dict: Object, dict: Object,
@@ -121,37 +125,21 @@ export default {
...mapState(["user"]), ...mapState(["user"]),
colConfigs() { colConfigs() {
return [ return [
{ label: "课程主题", prop: "title" }, {label: "课程主题", prop: "title"},
{ {label: "更新状态", dict: "classroomUpdateStatus", prop: "updateStatus"},
label: "更新状态", {label: "更新时间", prop: "updateDate"},
render: (h, { row }) => [ {label: "发布时间", prop: "createDate"},
<span> {label: "发布状态", prop: "status", dict: "newsCenterStatus"},
{" "} {label: "发布组织", prop: "organizationName"},
{this.dict.getLabel( {slot: "options"},
"classroomUpdateStatus",
row.updateStatus
)}{" "}
</span>,
],
},
{ label: "更新时间", prop: "updateDate" },
{ label: "发布时间", prop: "createDate" },
{
label: "发布状态",
render: (h, { row }) => [
<span> {this.dict.getLabel("newsCenterStatus", row.status)} </span>,
],
},
{ label: "发布组织", prop: "organizationName" },
{ slot: "options" },
]; ];
}, },
}, },
methods: { methods: {
handleChange(row) { handleChange(row) {
this.$confirm(`是否确定要${row.status == 0 ? "发布" : "取消发布"}?`).then( this.$confirm(`是否确定要${row.status == 0 ? "发布" : "取消发布"}?`).then(
(_) => { (_) => {
this.instance this.instance
.post("/app/apppartyclassroom/addOrUpdate", { .post("/app/apppartyclassroom/addOrUpdate", {
id: row.id, id: row.id,
status: row.status == 0 ? 1 : 0, status: row.status == 0 ? 1 : 0,
@@ -159,12 +147,12 @@ export default {
.then((res) => { .then((res) => {
if (res.code == 0) { if (res.code == 0) {
this.$message.success( this.$message.success(
`${row.status == 0 ? "发布成功" : "取消发布成功"}` `${row.status == 0 ? "发布成功" : "取消发布成功"}`
); );
this.getList(); this.getList();
} }
}); });
} }
); );
}, },
handleAddSeries(row) { handleAddSeries(row) {
@@ -172,20 +160,20 @@ export default {
this.comp = "seriesManage"; this.comp = "seriesManage";
this.row = row; this.row = row;
}, },
handleDelete({ id }) { handleDelete({id}) {
this.$confirm("确定要删除吗?").then((_) => { this.$confirm("确定要删除吗?").then((_) => {
this.instance this.instance
.post("/app/apppartyclassroom/delete", null, { .post("/app/apppartyclassroom/delete", null, {
params: { params: {
ids: id, ids: id,
}, },
}) })
.then((res) => { .then((res) => {
if (res.code == 0) { if (res.code == 0) {
this.$message.success("删除成功"); this.$message.success("删除成功");
this.getList(); this.getList();
} }
}); });
}); });
}, },
handleEdit(row) { handleEdit(row) {
@@ -228,18 +216,18 @@ export default {
}, },
getList() { getList() {
this.instance this.instance
.post("/app/apppartyclassroom/list", null, { .post("/app/apppartyclassroom/list", null, {
params: { params: {
...this.page, ...this.page,
...this.search, ...this.search,
}, },
}) })
.then((res) => { .then((res) => {
if (res?.data) { if (res?.data) {
this.tableData = res.data.records; this.tableData = res.data.records;
this.total = res.data.total; this.total = res.data.total;
} }
}); });
}, },
}, },
created() { created() {

View File

@@ -70,7 +70,7 @@ export default {
...mapState(["user"]), ...mapState(["user"]),
colConfigs() { colConfigs() {
return [ return [
{label: "类型", render: (h, {row}) => [< span> {row.type == 1 ? '单选题' : '多选题'} < /span>]}, {label: "类型", render: (h, {row}) =>h('p',row.type == 1 ? '单选题' : '多选题')},
{label: "题目", prop: "title"}, {label: "题目", prop: "title"},
{label: "创建时间", prop: "createDate"}, {label: "创建时间", prop: "createDate"},
{slot: "options"} {slot: "options"}

View File

@@ -26,6 +26,7 @@
:total="total" :total="total"
:current.sync="page.current" :current.sync="page.current"
:size.sync="page.size" :size.sync="page.size"
:dict="dict"
@getList="getList"> @getList="getList">
<el-table-column slot="option" label="操作" fixed="right" width="300" align="center"> <el-table-column slot="option" label="操作" fixed="right" width="300" align="center">
<template slot-scope="{ row }"> <template slot-scope="{ row }">
@@ -80,7 +81,7 @@
{prop: 'viewTotal', label: '浏览数', align: 'center'}, {prop: 'viewTotal', label: '浏览数', align: 'center'},
{prop: 'publishUserName', label: '发布人'}, {prop: 'publishUserName', label: '发布人'},
{prop: 'publishTime', label: '发布时间'}, {prop: 'publishTime', label: '发布时间'},
{prop: 'status', label: '发布状态', align: 'center',render:(h,{row})=>[<span>{this.$dict.getLabel('newsCenterStatus',row.status)}</span>]}, {prop: 'status', label: '发布状态', align: 'center',dict:"newsCenterStatus"},
{slot: 'option'}, {slot: 'option'},
] ]
} }

View File

@@ -15,13 +15,14 @@
</el-button> </el-button>
</template> </template>
</ai-search-bar> </ai-search-bar>
<ai-table :tableData="tableData" <ai-table :tableData="tableData"
:col-configs="colConfigs" :col-configs="colConfigs"
:total="total" :total="total"
ref="aitableex" ref="aitableex"
:current.sync="search.current" :current.sync="search.current"
:size.sync="search.size" :size.sync="search.size"
@getList="getAppLeaveMessage"> :dict="dict"
@getList="getAppLeaveMessage">
<el-table-column label="是否公示" slot="isPublic" align="center" width="150"> <el-table-column label="是否公示" slot="isPublic" align="center" width="150">
<template v-slot="{row}"> <template v-slot="{row}">
<el-switch v-model="row.isPublic" @change="onChange(row)" active-value="0" inactive-value="1" <el-switch v-model="row.isPublic" @change="onChange(row)" active-value="0" inactive-value="1"
@@ -31,7 +32,9 @@
<el-table-column label="操作" slot="options" align="center" width="150"> <el-table-column label="操作" slot="options" align="center" width="150">
<template v-slot="{row}"> <template v-slot="{row}">
<el-button type="text" title="详情" @click="toDetail(row.id)" v-if="$permissions('app_appleavemessagereply_detail')">详情</el-button> <el-button type="text" title="详情" @click="toDetail(row.id)"
v-if="$permissions('app_appleavemessagereply_detail')">详情
</el-button>
</template> </template>
</el-table-column> </el-table-column>
</ai-table> </ai-table>
@@ -123,7 +126,6 @@ export default {
onChange({id, isPublic}) { onChange({id, isPublic}) {
this.instance.post(`/app/appleavemessage/public?id=${id}`).then(res => { this.instance.post(`/app/appleavemessage/public?id=${id}`).then(res => {
if (res.code == 0) { if (res.code == 0) {
console.log(isPublic)
this.$message.success(isPublic == 1 ? "已公示" : "不公示") this.$message.success(isPublic == 1 ? "已公示" : "不公示")
this.getAppLeaveMessage() this.getAppLeaveMessage()
} }
@@ -213,15 +215,14 @@ export default {
...mapState(['user']), ...mapState(['user']),
colConfigs() { colConfigs() {
return [ return [
{ prop: 'msgCode', label: '编号', align: 'center' }, {prop: 'msgCode', label: '编号', align: 'center'},
{ prop: 'title', label: '标题', align: 'center' }, {prop: 'title', label: '标题', align: 'center'},
{ prop: 'type', label: '类型', align: 'center', {prop: 'type', label: '类型', align: 'center', dict: "leaveMessageType"},
render:(h,{row})=>[<span>{this.dict.getLabel('leaveMessageType', row.type)}</span>] }, {prop: 'leaveName', label: '留言人', align: 'center'},
{ prop: 'leaveName', label: '留言', align: 'center' }, {prop: 'createTime', label: '留言提交时间', align: 'center'},
{ prop: 'createTime', label: '留言提交时间', align: 'center' }, {prop: 'lastReplyTime', label: '最后回复时间', align: 'center'},
{ prop: 'lastReplyTime', label: '最后回复时间', align: 'center' }, {slot: 'isPublic'},
{ slot: 'isPublic'}, {slot: 'options'},
{ slot: 'options'},
] ]
} }
} }

View File

@@ -7,58 +7,62 @@
<el-select v-model="search.department" placeholder="请选择所属部门" @change="page.current=1,getList()" <el-select v-model="search.department" placeholder="请选择所属部门" @change="page.current=1,getList()"
size="small" clearable> size="small" clearable>
<el-option <el-option
v-for="(item,i) in dict.getDict('hbDepartment')" :key="i" v-for="(item,i) in dict.getDict('hbDepartment')" :key="i"
:label="item.dictName" :label="item.dictName"
:value="item.dictValue"> :value="item.dictValue">
</el-option> </el-option>
</el-select> </el-select>
<el-select v-model="search.classificationId" placeholder="请选择所属分类" @change="page.current=1,getList()" <el-select v-model="search.classificationId" placeholder="请选择所属分类" @change="page.current=1,getList()"
size="small" clearable> size="small" clearable>
<el-option <el-option
v-for="(item,i) in classList" :key="i" v-for="(item,i) in classList" :key="i"
:label="item.name" :label="item.name"
:value="item.id"> :value="item.id">
</el-option> </el-option>
</el-select> </el-select>
</template> </template>
<template #right> <template #right>
<el-input <el-input
v-model="search.processName" v-model="search.processName"
size="small" size="small"
placeholder="事项名称/创建人" placeholder="事项名称/创建人"
@clear="search={},page.current=1,getList()" @clear="search={},page.current=1,getList()"
v-throttle="() => {page.current = 1, getList()}" v-throttle="() => {page.current = 1, getList()}"
clearable clearable
suffix-icon="iconfont iconSearch"/> suffix-icon="iconfont iconSearch"/>
</template> </template>
</ai-search-bar> </ai-search-bar>
<ai-search-bar> <ai-search-bar>
<template #left> <template #left>
<el-button type="primary" icon="iconfont iconAdd" @click="goPage(tab.value==0 ? 'addConfig':'guidance')">添加{{tab.value==0?'事项':'办事指南'}}</el-button> <el-button type="primary" icon="iconfont iconAdd" @click="goPage(tab.value==0 ? 'addConfig':'guidance')">
添加{{ tab.value == 0 ? '事项' : '办事指南' }}
</el-button>
</template> </template>
</ai-search-bar> </ai-search-bar>
<ai-table <ai-table
:tableData="tableData" :tableData="tableData"
:col-configs="colConfigs" :col-configs="colConfigs"
:header-cell-style="{fontWeight:'bold',color:'#333'}" :header-cell-style="{fontWeight:'bold',color:'#333'}"
:total="page.total" :total="page.total"
:current.sync="page.current" :current.sync="page.current"
:size.sync="page.size" :size.sync="page.size"
@getList="getList"> :dict="dict"
@getList="getList">
<el-table-column label="是否启用" slot="processDefStatus" align="center" width="150"> <el-table-column label="是否启用" slot="processDefStatus" align="center" width="150">
<template v-slot="{row}"> <template v-slot="{row}">
<el-switch <el-switch
v-model="row.processDefStatus" v-model="row.processDefStatus"
@change="onChange(row)" active-value="1" inactive-value="0" @change="onChange(row)" active-value="1" inactive-value="0"
active-color="#5088FF" active-color="#5088FF"
inactive-color="#D0D4DC"> inactive-color="#D0D4DC">
</el-switch> </el-switch>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" slot="options" align="center" width="150"> <el-table-column label="操作" slot="options" align="center" width="150">
<template v-slot="{row}"> <template v-slot="{row}">
<div class="table-options"> <div class="table-options">
<el-button type="text" title="编辑" @click="goPage(tab.value==0 ? 'addConfig':'guidance',row)">编辑</el-button> <el-button type="text" title="编辑" @click="goPage(tab.value==0 ? 'addConfig':'guidance',row)">编辑
</el-button>
<el-button type="text" title="删除" @click="delInfo(row)">删除</el-button> <el-button type="text" title="删除" @click="delInfo(row)">删除</el-button>
</div> </div>
</template> </template>
@@ -70,145 +74,141 @@
</template> </template>
<script> <script>
import day from 'dayjs' import day from 'dayjs'
export default { export default {
name: "configList", name: "configList",
props: { props: {
instance: Function, instance: Function,
dict: Object, dict: Object,
permissions: Function, permissions: Function,
tab: Object, tab: Object,
}, },
data() { data() {
return { return {
search: { search: {
department: "", department: "",
classificationId: "", classificationId: "",
processName: "", processName: "",
},
page: {current: 1, size: 10},
total: 0,
row: {},
tableData: [],
classList: [],
}
},
computed: {
colConfigs() {
return [
{
prop: 'processName',
align: 'left',
label: '事项名称',
}, },
page: {current: 1, size: 10}, {
total: 0, prop: 'department',
row: {}, align: 'left',
tableData: [], label: '所属部门',
classList: [], dict: "hbDepartment"
} },
{
prop: 'classificationName',
align: 'center',
label: '所属分类',
},
{
prop: 'timeLimit',
align: 'center',
label: '办结时限(日)',
},
{
prop: 'createUserName',
align: 'center',
label: '创建人',
},
{
prop: 'createTime',
align: 'center',
label: '最后修改时间',
render: (h, {row}) => h('p', day(row.createTime).format("YYYY-MM-DD HH:mm"))
},
{slot: 'processDefStatus', align: 'center', label: '是否启用',},
{slot: 'options', align: 'center', label: '操作',},
].filter(e => this.tab.value == 0 ? true : (e.prop != "timeLimit"))
}, },
computed: { },
colConfigs() { methods: {
return [ goPage(comp, row = {}) {
{ this.$emit("goPage", {comp, row})
prop: 'processName',
align: 'left',
label: '事项名称',
},
{
prop: 'department',
align: 'left',
label: '所属部门',
render: (h, {row}) => [ < span > {this.dict.getLabel('hbDepartment', row.department)} < /span>]
},
{
prop: 'classificationName',
align: 'center',
label: '所属分类',
},
{
prop: 'timeLimit',
align: 'center',
label: '办结时限(日)',
},
{
prop: 'createUserName',
align: 'center',
label: '创建人',
},
{
prop: 'createTime',
align: 'center',
label: '最后修改时间',
render: (h, {row}) => [ < span > {day(row.createTime
).
format("YYYY-MM-DD HH:mm")
}<
/span>]
},
{slot: 'processDefStatus', align:'center', label:'是否启用',},
{ slot: 'options',align:'center',label:'操作',},
].filter(e=>this.tab.value==0 ? true : (e.prop!="timeLimit"))
},
}, },
methods: { /**
goPage(comp, row = {}) { * 获取分类
this.$emit("goPage", {comp, row}) */
}, getClassification() {
/** this.instance.post(`/app/zwspapprovalclassification/list`, null, {
* 获取分类 params: {
*/ current: 1,
getClassification() { status: 1,
this.instance.post(`/app/zwspapprovalclassification/list`, null, { size: 9999
params:{ }
current: 1, }).then(res => {
status: 1, if (res && res.data) {
size: 9999 this.classList = res.data.records
} }
}).then(res => { })
if (res && res.data) { },
this.classList = res.data.records /**
} * 删除
}) * */
}, delInfo({id}) {
/** this.$confirm("是否删除").then(() => {
* 删除 this.instance.post(`/app/approval-process-def/delete?id=${id}`).then(res => {
* */
delInfo({id}) {
this.$confirm("是否删除").then(() => {
this.instance.post(`/app/approval-process-def/delete?id=${id}`).then(res => {
if (res.code == 0) {
this.$message.success("删除成功")
this.getList()
}
})
})
},
/**
* 启用,停用
*/
onChange({id, processDefStatus}) {
this.instance.post(`/app/approval-process-def/enable-disable`, null, {
params: {id}
}).then(res => {
if (res.code == 0) { if (res.code == 0) {
this.$message.success(processDefStatus == 0 ? "不启用" : "已启用") this.$message.success("删除成功")
this.getList() this.getList()
} }
}) })
}, })
},
/**
* 启用,停用
*/
onChange({id, processDefStatus}) {
this.instance.post(`/app/approval-process-def/enable-disable`, null, {
params: {id}
}).then(res => {
if (res.code == 0) {
this.$message.success(processDefStatus == 0 ? "不启用" : "已启用")
this.getList()
}
})
},
getList() { getList() {
this.instance.post(`/app/approval-process-def/list`, null, { this.instance.post(`/app/approval-process-def/list`, null, {
params: { params: {
...this.page, ...this.page,
...this.search, ...this.search,
processType: this.tab.value processType: this.tab.value
}, },
}).then(res => { }).then(res => {
if (res?.data) { if (res?.data) {
this.tableData = res.data.records this.tableData = res.data.records
this.page.total = res.data.total; this.page.total = res.data.total;
} }
}) })
},
}, },
mounted() { },
this.getList() mounted() {
this.getClassification() this.getList()
}, this.getClassification()
} },
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.config-list { .config-list {
height: 100%; height: 100%;
} }
</style> </style>

View File

@@ -53,6 +53,7 @@
:total="total" :total="total"
:current.sync="search.current" :current.sync="search.current"
:size.sync="search.size" :size.sync="search.size"
:dict="dict"
@getList="getList"> @getList="getList">
<el-table-column slot="readUserName" label="姓名" align="center"> <el-table-column slot="readUserName" label="姓名" align="center">
<template slot-scope="{ row }"> <template slot-scope="{ row }">
@@ -103,9 +104,8 @@ export default {
{slot: "unitName"}, {slot: "unitName"},
{ {
prop: "readStatus", label: "查阅状态", align: "center", prop: "readStatus", label: "查阅状态", align: "center",
render: (h, {row}) => [<span render: (h, {row}) => h('p', {color: this.dict.getColor("announcementReadStatus", row.readStatus)}, this.dict.getLabel("announcementReadStatus", row.readStatus))
style={{color: this.dict.getColor("announcementReadStatus", row.readStatus)}}>{this.dict.getLabel("announcementReadStatus", row.readStatus)}</span>] }
},
]; ];
} }
}, },

View File

@@ -40,6 +40,7 @@
:total="total" :total="total"
:current.sync="search.current" :current.sync="search.current"
:size.sync="search.size" :size.sync="search.size"
:dict="dict"
@getList="getList"> @getList="getList">
<el-table-column slot="releaseUserName" label="发布人" align="center"> <el-table-column slot="releaseUserName" label="发布人" align="center">
<template slot-scope="{ row }"> <template slot-scope="{ row }">
@@ -123,17 +124,20 @@ export default {
{prop: 'title', label: '标题'}, {prop: 'title', label: '标题'},
{ {
prop: 'readNum', label: '查询状态', align: 'center', prop: 'readNum', label: '查询状态', align: 'center',
render: (h, {row}) => [<span class='status' render: (h, {row}) => h('p', {
onClick={this.showDialog.bind(this, row)}>{row.readNum}人已读</span>, class: 'status', on: {
<span class='status' onClick={this.showDialog.bind(this, row)}>{row.unReadNum}人未读</span>] click() {
this.showDialog(row)
}
}
}, `${row.readNum || 0}人已读,${row.unReadNum}人未读`)
}, },
{slot: 'releaseUserName'}, {slot: 'releaseUserName'},
{slot: 'unitName'}, {slot: 'unitName'},
{prop: 'releaseTime', label: '发布时间', align: 'center'}, {prop: 'releaseTime', label: '发布时间', align: 'center'},
{ {
prop: 'status', label: '发布状态', align: 'center', prop: 'status', label: '发布状态', align: 'center',
render: (h, {row}) => [<span render: (h, {row}) => h('p', {color: this.dict.getColor("announcementStatus", row.status)}, this.dict.getLabel("announcementStatus", row.status))
style={{color: this.dict.getColor("announcementStatus", row.status)}}>{this.dict.getLabel("announcementStatus", row.status)}</span>]
}, },
{slot: 'options'}, {slot: 'options'},
]; ];

View File

@@ -13,13 +13,13 @@
</div> </div>
</div> </div>
<div class="header-right"> <div class="header-right">
<!-- <div class="header-right__item">--> <!-- <div class="header-right__item">-->
<!-- <span>成员总数</span>--> <!-- <span>成员总数</span>-->
<!-- <h3>{{ chartData.groupSum}}</h3>--> <!-- <h3>{{ chartData.groupSum}}</h3>-->
<!-- </div>--> <!-- </div>-->
<div class="header-right__item"> <div class="header-right__item">
<span>成员总数</span> <span>成员总数</span>
<h3>{{chartData.today && chartData.today.total }}</h3> <h3>{{ chartData.today && chartData.today.total }}</h3>
</div> </div>
<div class="header-right__item"> <div class="header-right__item">
<span>今日新增</span> <span>今日新增</span>
@@ -27,13 +27,13 @@
</div> </div>
<div class="header-right__item"> <div class="header-right__item">
<span>今日流失</span> <span>今日流失</span>
<h3>{{chartData.today && chartData.today.decrease}}</h3> <h3>{{ chartData.today && chartData.today.decrease }}</h3>
</div> </div>
</div> </div>
</div> </div>
<div class="detail-top__content"> <div class="detail-top__content">
<ai-wrapper <ai-wrapper
label-width="80px"> label-width="80px">
<ai-info-item label="群主" :value="info.ownerName"></ai-info-item> <ai-info-item label="群主" :value="info.ownerName"></ai-info-item>
<ai-info-item label="群公告" :value="info.notice" isLine></ai-info-item> <ai-info-item label="群公告" :value="info.notice" isLine></ai-info-item>
<ai-info-item label="群聊标签" isLine> <ai-info-item label="群聊标签" isLine>
@@ -53,14 +53,25 @@
<ai-card title="成员列表"> <ai-card title="成员列表">
<template slot="content"> <template slot="content">
<ai-table <ai-table
:tableData="tableData" :tableData="tableData"
:col-configs="colConfigs" :col-configs="colConfigs"
:total="total" :total="total"
border border
ref="aitableex" ref="aitableex"
@getList="getDynamicInfo" @getList="getDynamicInfo"
:current.sync="search.current" :current.sync="search.current"
:size.sync="search.size"> :size.sync="search.size"
:dict="dict">
<el-table-column slot="member" label="成员">
<template slot-scope="{row}">
<el-row type="flex" align="middle">
<img class="avatar" :src='row.avatar || "https://cdn.cunwuyun.cn/dvcp/h5/defaultAvatar.png"'/>
<div v-text="row.memberName"/>
<span :style="{color: row.customerType == 1 ? '#2EA222' : '#3C7FC8', marginLeft: '8px'}"
v-text="(row.customerType == 1 ? '@微信' : '@' + row.corpName)|| ''"/>
</el-row>
</template>
</el-table-column>
<el-table-column slot="options" label="操作" width="100" align="center"> <el-table-column slot="options" label="操作" width="100" align="center">
<template slot-scope="{ row }"> <template slot-scope="{ row }">
<el-button type="text" v-if="row.type==2 && row.avatar" @click="toDetail(row)">居民详情</el-button> <el-button type="text" v-if="row.type==2 && row.avatar" @click="toDetail(row)">居民详情</el-button>
@@ -74,304 +85,300 @@
</template> </template>
<script> <script>
import * as echarts from 'echarts' import * as echarts from 'echarts'
export default { export default {
name: 'Detail', name: 'Detail',
props: { props: {
instance: Function, instance: Function,
dict: Object, dict: Object,
params: Object params: Object
}, },
computed: { computed: {
colConfigs() { colConfigs() {
return [ return [
{ {slot: "member"},
prop: 'memberName', label: '成员',render:(h,{row})=>[<img class="avatar" src={row.avatar || "https://cdn.cunwuyun.cn/dvcp/h5/defaultAvatar.png"} />, {prop: 'type', label: '类型', dict: "wxGroupMemberType"},
<span>{row.memberName}</span>, {prop: 'joinTime', label: '入群时间'},
<span style={{color:row.customerType==1 ? '#2EA222' : '#3C7FC8',marginLeft:'8px'}}>{ row.customerType?(row.customerType==1 ? '@微信' : '@' + row.corpName):'' }</span>], {prop: 'joinScene', label: '入群方式', dict: "wxGroupMemberJoinScene"},
{slot: "options"},
]
}
},
data() {
return {
isShow: false,
info: {},
search: {
current: 1,
size: 10
}, },
{prop: 'type', label: '类型',render:(h,{row})=>[<span>{this.dict.getLabel("wxGroupMemberType",row.type)}</span>]}, total: 0,
{prop: 'joinTime', label: '入群时间'}, tableData: [],
{prop: 'joinScene', label: '入群方式',render:(h,{row})=>[<span>{this.dict.getLabel("wxGroupMemberJoinScene",row.joinScene)}</span>]}, chart: null,
{slot: "options"}, chartData: {},
] }
} },
},
data() { created() {
return { this.dict.load("wxGroupMemberJoinScene", "wxGroupMemberType")
isShow: false, },
info: {},
search: { mounted() {
current: 1, if (this.params && this.params.id) {
size: 10 this.getInfo()
this.getDynamicInfo()
this.getChart()
}
},
methods: {
getChart() {
this.instance.post(`/app/wxcp/wxgroup/groupStatistic`, null, {
params: {
id: this.params.id
}
}).then(res => {
if (res && res.data) {
this.chartData = res.data
this.initChart()
}
})
},
initChart() {
this.chart = echarts.init(document.getElementById('lineChart'))
this.setOptions()
},
setOptions() {
const x = Object.keys(this.chartData.list)
const y = Object.values(this.chartData.list)
this.chart.setOption({
tooltip: {
trigger: 'axis'
}, },
total: 0, legend: {
tableData: [], type: "plain"
chart: null, },
chartData: {}, grid: {
} left: '20px',
}, right: '38px',
bottom: '14px',
created() { top: '30px',
this.dict.load("wxGroupMemberJoinScene", "wxGroupMemberType") containLabel: true
}, },
color: ['#2266FF', '#22AA99', '#F8B425'],
mounted() { xAxis: {
if (this.params && this.params.id) { type: 'category',
this.getInfo() axisLabel: {
this.getDynamicInfo() align: 'center',
this.getChart() padding: [2, 0, 0, 0],
} interval: 0,
}, fontSize: 14,
color: '#666666'
methods: {
getChart() {
this.instance.post(`/app/wxcp/wxgroup/groupStatistic`, null, {
params: {
id: this.params.id
}
}).then(res => {
if (res && res.data) {
this.chartData = res.data
this.initChart()
}
})
},
initChart() {
this.chart = echarts.init(document.getElementById('lineChart'))
this.setOptions()
},
setOptions() {
const x = Object.keys(this.chartData.list)
const y = Object.values(this.chartData.list)
this.chart.setOption({
tooltip: {
trigger: 'axis'
}, },
legend: { boundaryGap: false,
type: "plain" axisLine: {
}, lineStyle: {
grid: { color: '#E1E5EF'
left: '20px',
right: '38px',
bottom: '14px',
top: '30px',
containLabel: true
},
color: ['#2266FF', '#22AA99', '#F8B425'],
xAxis: {
type: 'category',
axisLabel: {
align: 'center',
padding: [2, 0, 0, 0],
interval: 0,
fontSize: 14,
color: '#666666'
},
boundaryGap: false,
axisLine: {
lineStyle: {
color: '#E1E5EF'
}
},
data: x
},
yAxis: {
axisTick: {
length: 0,
show: false
},
splitLine: {
show: true,
lineStyle: {
color: ['#E1E5EF'],
width: 1,
type: 'solid'
}
},
nameTextStyle: {
color: '#666666',
align: 'left'
},
axisLine: {
show: false
},
axisLabel: {
color: '#666666'
},
type: 'value'
},
series: [
{
name: '成员总数',
type: 'line',
data: y.map(v => v.total)
},
{
name: '新增成员数',
type: 'line',
data: y.map(v => v.increase)
},
{
name: '流失成员数',
type: 'line',
data: y.map(v => v.decrease)
} }
] },
}) data: x
}, },
yAxis: {
getInfo() { axisTick: {
this.instance.post(`/app/wxcp/wxgroup/getDetail?id=${this.params.id}`).then(res => { length: 0,
if (res && res.data) { show: false
this.info = res.data },
splitLine: {
show: true,
lineStyle: {
color: ['#E1E5EF'],
width: 1,
type: 'solid'
}
},
nameTextStyle: {
color: '#666666',
align: 'left'
},
axisLine: {
show: false
},
axisLabel: {
color: '#666666'
},
type: 'value'
},
series: [
{
name: '成员总数',
type: 'line',
data: y.map(v => v.total)
},
{
name: '新增成员数',
type: 'line',
data: y.map(v => v.increase)
},
{
name: '流失成员数',
type: 'line',
data: y.map(v => v.decrease)
} }
}) ]
}, })
},
getDynamicInfo() { getInfo() {
this.instance.post(`/app/wxcp/wxgroup/listMember?groupId=${this.params.id}`, null, { this.instance.post(`/app/wxcp/wxgroup/getDetail?id=${this.params.id}`).then(res => {
params: { if (res && res.data) {
...this.search this.info = res.data
} }
}).then(res => { })
if (res.code === 0) { },
this.tableData = res.data.records
this.total = res.data.total
}
})
},
toDetail(row) { getDynamicInfo() {
this.$router.push({ this.instance.post(`/app/wxcp/wxgroup/listMember?groupId=${this.params.id}`, null, {
name: '68', params: {
query: { ...this.search
id: row.userId, }
type: 'Detail' }).then(res => {
} if (res.code === 0) {
}) this.tableData = res.data.records
}, this.total = res.data.total
}
})
},
cancel(isRefresh) { toDetail(row) {
this.$emit('change', { this.$router.push({
type: 'list', name: '68',
isRefresh: isRefresh ? true : false query: {
}) id: row.userId,
} type: 'Detail'
}
})
},
cancel(isRefresh) {
this.$emit('change', {
type: 'list',
isRefresh: isRefresh ? true : false
})
} }
} }
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.AppResidentManage { .AppResidentManage {
::v-deep .ai-detail__content--wrapper { ::v-deep .ai-detail__content--wrapper {
max-width: 100% !important; max-width: 100% !important;
padding: 20px; padding: 20px;
}
h2, h3 {
margin: 0;
}
.detail-top {
padding: 30px 40px;
background: #FFFFFF;
box-shadow: 0px 4px 6px -2px rgba(15, 15, 21, 0.15);
border-radius: 2px;
margin-bottom: 20px;
.detail-top__content {
padding-top: 32px;
} }
h2, h3 { .detail-top__header {
margin: 0; display: flex;
} justify-content: space-between;
align-items: center;
padding-bottom: 32px;
border-bottom: 1px solid #EEEEEE;
.detail-top { .header-right {
padding: 30px 40px; .header-right__item {
background: #FFFFFF; width: 120px;
box-shadow: 0px 4px 6px -2px rgba(15, 15, 21, 0.15); margin-right: 8px;
border-radius: 2px; text-align: center;
margin-bottom: 20px; }
.detail-top__content { div {
padding-top: 32px; text-align: center;
&:last-child {
margin-right: 0;
}
span {
display: block;
margin-bottom: 10px;
color: #888888;
}
}
.el-button {
height: 28px;
margin-left: 8px;
border-radius: 14px;
font-size: 12px;
padding: 7px 15px;
}
} }
.detail-top__header { .header-left, .header-right {
display: flex; display: flex;
justify-content: space-between;
align-items: center; align-items: center;
padding-bottom: 32px; }
border-bottom: 1px solid #EEEEEE;
.header-right { .header-left {
.header-right__item { img {
width: 120px; width: 64px;
margin-right: 8px; height: 64px;
text-align: center; margin-right: 16px;
}
div {
text-align: center;
&:last-child {
margin-right: 0;
}
span {
display: block;
margin-bottom: 10px;
color: #888888;
}
}
.el-button {
height: 28px;
margin-left: 8px;
border-radius: 14px;
font-size: 12px;
padding: 7px 15px;
}
} }
.header-left, .header-right { h2 {
display: flex; margin-bottom: 6px;
align-items: center; color: #222222;
font-size: 16px;
} }
.header-left { p {
img { color: #2EA222;
width: 64px; font-size: 14px;
height: 64px;
margin-right: 16px;
}
h2 {
margin-bottom: 6px;
color: #222222;
font-size: 16px;
}
p {
color: #2EA222;
font-size: 14px;
}
} }
} }
} }
#lineChart {
width: 100%;
height: 336px;
}
.table-tags {
.el-tag {
margin-right: 8px;
&:last-child {
margin-right: 0;
}
}
}
::v-deep .avatar {
width: 40px;
height: 40px;
vertical-align: middle;
margin-right: 8px;
object-fit: fill;
}
} }
#lineChart {
width: 100%;
height: 336px;
}
.table-tags {
.el-tag {
margin-right: 8px;
&:last-child {
margin-right: 0;
}
}
}
::v-deep .avatar {
width: 40px;
height: 40px;
vertical-align: middle;
margin-right: 8px;
object-fit: fill;
}
}
</style> </style>

View File

@@ -1,4 +0,0 @@
{
"AppGigscreenViewer": "大屏预览组件",
"AppDesigner": "大屏设计"
}

View File

@@ -1,133 +0,0 @@
<template>
<section class="AppCentralTaskDV">
<!-- <ai-dv-background :src="bgImage"/>-->
<div class="coreTask">
<div class="leftBox">
<div class="boxTitle">{{ coreTaskData.titleText }}</div>
<dv-scroll-board v-if="refresh" :config="coreTaskData"/>
</div>
</div>
</section>
</template>
<script>
import {scrollBoard} from '@jiaminghi/data-view'
import bgImage from '../assets/centralTask/bg.png'
import Vue from "vue";
Vue.use(scrollBoard)
export default {
name: "AppCentralTaskDV",
label: "数据大屏-重点工作",
props: {
nav: {default: () => ({})}
},
inject: {
dv: {default: ""}
},
computed: {
coreTaskData() {
return {
headerHeight: 52,
header: ['基层组织建设', "社区治理", "便民服务效能", "城市管理"],
headerBGC: 'rgba(0, 113, 255, 0.5)',
oddRowBGC: "rgba(5, 65, 139, 0.5)",
evenRowBGC: "rgba(5, 65, 139, 0.5)",
waitTime: 6000,
align: ["center", "start", "center", "center"],
rowNum: 5,
...this.nav.data,
}
},
},
data() {
return {bgImage, refresh: true}
},
watch: {
nav: {
deep: true,
handler() {
this.refresh = false
this.$nextTick(() => this.refresh = true)
}
}
}
}
</script>
<style lang="scss" scoped>
.AppCentralTaskDV {
height: 100%;
padding: 0 0 60px;
box-sizing: border-box;
display: flex;
flex-direction: column;
.coreTask {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
gap: 53px;
margin-top: 56px;
.leftBox {
width: 100%;
height: 100%;
background-image: url("../assets/centralTask/box.png");
background-size: 100% 100%;
background-repeat: no-repeat;
display: flex;
flex-direction: column;
align-items: center;
padding: 0 40px 42px;
box-sizing: border-box;
}
}
.boxTitle {
height: 68px;
width: 534px;
background-image: url("../assets/centralTask/titleBox.png");
text-align: center;
font-size: 22px;
font-weight: 400;
color: #71F8FF;
transform: translateY(-32px);
line-height: 68px;
}
::v-deep .dv-scroll-board {
width: 100%;
flex: 1;
min-height: 0;
border-radius: 6px;
overflow: hidden;
.header {
color: #9FDBFB;
font-size: 20px;
.header-item {
text-align: center;
border: 1px solid #054596;
}
}
.row-item {
color: #68F0FC;
font-size: 18px;
overflow: hidden;
.ceil {
border: 1px solid #054596;
border-top: none;
position: relative;
line-height: 30px;
white-space: normal;
padding: 20px;
}
}
}
}
</style>

View File

@@ -1,479 +0,0 @@
<template>
<section class="AppGovInteractionDV">
<el-row type="flex" justify="space-between" align="bottom">
<div flex class="framePane column top">
<div class="titlePane" v-text="'事件内容'"/>
<div class="fill">
<dv-scroll-board :config="topLeftData"/>
</div>
</div>
<div class="centerTopPane" id="centerTopPane">
<b class="title gradientFont">事件统计</b>
<el-row type="flex" justify="space-between" align="middle"
v-for="(row,i) in topCenterData" :key="i">
<div class="dataPane" v-for="(op,j) in row" :key="j">
<span class="gradientFont" v-text="op.label"/>
<dv-digital-flop class="gradientFont" :config="op.v1"/>
</div>
</el-row>
</div>
<div flex class="framePane column top">
<div class="titlePane" v-text="'政务微信群'"/>
<div class="totalPane" flex>
<div class="dataPanel fill" flex v-for="(op,i) in rightTopData.total" :key="i">
<span v-text="op.label"/>
<b v-text="op.v1"/>
</div>
</div>
<div class="fill">
<ai-echart class="chart" :data="rightTopData.list" :ops="rightTopData.ops"/>
</div>
</div>
</el-row>
<div flex class="gap fill">
<div flex class="framePane fill column" v-for="c in charts" :key="c.id">
<div class="titlePane" v-text="c.label"/>
<div class="fill">
<ai-echart class="chart" :data="chartData[c.id]" :ops="c.ops"/>
</div>
</div>
</div>
</section>
</template>
<script>
import {digitalFlop, scrollBoard} from '@jiaminghi/data-view'
import Vue from "vue";
Vue.use(digitalFlop)
Vue.use(scrollBoard)
export default {
name: "AppGovInteractionDV",
label: "数据大屏-政民互动",
props: {
instance: Function
},
computed: {
topCenterData() {
let meta = [
[{label: "待受理", name: 'pending'}, {label: "累计上报", name: 'total_case'}],
[{label: "办理中", name: 'processing'}, {label: "累计受理", name: 'total_accepted'}],
[{label: "今日上报", name: "added_today"}, {label: "累计办结", name: 'total_solved'}],
[{label: "今日办结", name: 'solved_today'}, {label: "累计办结率", name: 'total_solved_percent'}],
]
return meta.map(e => e.map(s => {
let v1 = {
number: [this.meta.residentCategoryReport?.[s.name] || 0],
style: {
fontFamily: 'dineng',
fontWeight: 'bold',
fontSize: 40,
gradientType: 'linear',
gradientColor: ['#fff', '#fff', '#6BC7FF'],
gradientParams: [0, 0, 0, 40],
gradientWith: 'fill',
gradientStops: [0, .18, 1]
}
}
if (s.name == 'total_solved_percent') {
v1 = {
...v1,
number: [v1.number * 100], content: '{nt}%'
}
}
return {...s, v1}
}))
},
topLeftData() {
let statusColor = {
0: 'doing',
1: 'done',
2: 'pending',
},
statusLabel = {
0: '处理中',
1: '已处理'
},
list = this.meta.residentOrderList?.map(e => {
let status = e.process_list.slice(-1)?.[0]?.status
return {
...e, status, statusLabel: statusLabel[status]
}
})
return {
oddRowBGC: 'transparent',
evenRowBGC: 'transparent',
rowNum: 10,
data: list?.map(e => [`
<div flex class="eventItem">
<span class="tag ${statusColor[e.status]}">${e.statusLabel}</span>
<div class="fill">${e.desc}</div>
</div>`]) || []
}
},
rightTopData() {
let obj = this.meta.groupMap?.list || {},
list = Object.keys(obj).map(e => {
let {total, increase, decrease} = obj?.[e],
time = this.$moment(e).format('MM-DD')
return {time, total, increase, decrease}
})
return {
total: [
{label: '群聊总数', v1: this.meta.groupMap?.groupSum || 0},
{label: '群成员数', v1: this.meta.groupMap?.today?.total || 0},
],
ops: {
color: ['rgba(54, 165, 255, 0.2)', 'rgba(28, 212, 68, 0.2)', 'rgba(255, 215, 109, 0.2)'],
legend: {
itemWidth: 16,
itemHeight: 16,
textStyle: {color: '#82C5FF', padding: [0, 0, 0, 8], fontSize: 14},
icon: 'rect',
itemGap: 40
},
tooltip: {},
xAxis: {
type: 'category', axisTick: false,
nameGap: 20,
axisLabel: {color: '#fff'},
axisLine: {lineStyle: {color: '#263763'}}
},
// 声明一个 Y 轴,数值轴。
yAxis: {
nameGap: 30, minInterval: 1,
splitLine: {lineStyle: {color: '#263763'}},
axisLabel: {color: 'rgba(255,255,255,.8)'}
},
series: [
{
type: 'line', name: "群成员数", symbol: 'none', lineStyle: {color: '#36A5FF', borderWidth: 1},
itemStyle: {borderColor: '#36A5FF', borderWidth: 1},
},
{
type: 'line', name: "新增人数", symbol: 'none', lineStyle: {color: '#1CD444', borderWidth: 1},
itemStyle: {borderColor: '#1CD444', borderWidth: 1},
},
{
type: 'line', name: "退群人数", symbol: 'none', lineStyle: {color: '#FFD76D', borderWidth: 1},
itemStyle: {borderColor: '#FFD76D', borderWidth: 1},
}
],
grid: {left: 60, bottom: 58, right: 20}
},
list
}
},
chartData() {
return {
EventType: this.meta.residentCategoryReportList?.map(e => {
let {category_name: name, total_case, total_solved} = e
return {name, total_case, total_solved}
}) || [],
EventSource: this.meta.unitReportList?.map(e => {
let {grid_name: name, total_case, total_solved} = e
return {name, total_case, total_solved}
}) || []
}
},
},
data() {
return {
charts: [
{
label: "事件类型", id: "EventType", ops: {
color: ['rgba(54, 165, 255, 0.2)', 'rgba(28, 212, 68, 0.2)'],
legend: {
itemWidth: 16,
itemHeight: 16,
textStyle: {color: '#82C5FF', padding: [0, 0, 0, 8], fontSize: 14},
icon: 'rect',
itemGap: 40
},
tooltip: {},
xAxis: {
type: 'category', nameGap: 20, axisTick: false,
axisLabel: {color: '#fff'},
axisLine: {lineStyle: {color: '#263763'}}
},
// 声明一个 Y 轴,数值轴。
yAxis: {
nameGap: 23, minInterval: 1,
splitLine: {lineStyle: {color: '#263763'}},
axisLabel: {color: 'rgba(255,255,255,.8)'}
},
series: [
{
type: 'bar',
name: "累计受理",
barWidth: 10,
barGap: '20%',
itemStyle: {borderColor: '#36A5FF', borderWidth: 1}
},
{
type: 'bar',
name: "累计办结",
barWidth: 10,
barGap: '20%',
itemStyle: {borderColor: '#1CD444', borderWidth: 1}
}
],
grid: {left: 40, bottom: 58, right: 20}
}
},
{
label: "上报来源", id: "EventSource", ops: {
color: ['rgba(54, 165, 255, 0.2)', 'rgba(28, 212, 68, 0.2)'],
legend: {
itemWidth: 16,
itemHeight: 16,
textStyle: {color: '#82C5FF', padding: [0, 0, 0, 8], fontSize: 14},
icon: 'rect',
itemGap: 40
},
tooltip: {},
xAxis: {
type: 'category', axisTick: false,
nameGap: 20,
axisLabel: {color: '#fff'},
axisLine: {lineStyle: {color: '#263763'}}
},
// 声明一个 Y 轴,数值轴。
yAxis: {
nameGap: 30, minInterval: 1,
splitLine: {lineStyle: {color: '#263763'}},
axisLabel: {color: 'rgba(255,255,255,.8)'}
},
series: [
{
type: 'line', name: "事件数", symbol: 'none', lineStyle: {color: '#36A5FF', borderWidth: 1},
itemStyle: {borderColor: '#36A5FF', borderWidth: 1, show: false},
areaStyle: {
color: {
type: 'linear', x2: 0, y2: 1, colorStops: [
{offset: 0, color: 'rgba(37, 161, 255, 0.5)'}, {offset: 1, color: 'rgba(37, 161, 255, 0)'}]
}
}
},
{
type: 'line', name: "办理数", symbol: 'none', lineStyle: {color: '#1CD444', borderWidth: 1},
itemStyle: {borderColor: '#1CD444', borderWidth: 1, show: false},
areaStyle: {
color: {
type: 'linear', x2: 0, y2: 1, colorStops: [
{offset: 0, color: 'rgba(37, 206, 55, 0.5)'}, {offset: 1, color: 'rgba(37, 206, 55, 0)'}]
}
}
}
],
grid: {left: 40, bottom: 58, right: 20}
}
},
],
meta: {},
}
},
methods: {
getData() {
this.instance.post("/app/statistics/governmentPeople/queryResidentReport").then(res => {
if (res?.data) this.meta = res.data
})
},
},
created() {
this.getData()
}
}
</script>
<style lang="scss" scoped>
.AppGovInteractionDV {
height: 100%;
padding: 6px 0 10px;
gap: 20px;
font-size: 16px;
color: #82C5FF;
display: flex;
flex-direction: column;
::v-deep .eventItem {
width: 100%;
color: #82C5FF;
& > .fill {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
::v-deep .communityEvent {
list-style-type: circle;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
height: 40px;
line-height: 40px;
padding-left: 1px;
color: #82C5FF;
}
::v-deep .tag {
padding: 0 10px;
border-radius: 4px;
margin-right: 10px;
font-size: 14px;
line-height: 28px;
color: #fff;
box-sizing: border-box;
&.doing {
background-image: radial-gradient(rgba(#1B1BD6, .4), #208FFF);
}
&.pending {
background-image: radial-gradient(rgba(#FF9333, .4), #FFE959);
}
&.done {
background-image: radial-gradient(rgba(#1BD622, .4), #2CFF7C);
}
}
.centerTopPane {
background-image: url("../assets/govInteraction/globe_map.png");
background-repeat: no-repeat;
background-size: 100% 100%;
height: 540px;
width: 940px;
flex-shrink: 0;
position: relative;
padding: 30px 50px 50px;
box-sizing: border-box;
.title {
font-size: 60px;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
::v-deep .gradientFont {
background-image: linear-gradient(180deg, #FFFFFF 0%, #FFFFFF 18%, #6BC7FF 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
.el-row {
&:first-of-type, &:last-of-type {
margin: 0 110px;
}
}
::v-deep .dataPane {
width: 122px;
height: 114px;
background-image: url("../assets/govInteraction/kuaikuai.png");
background-repeat: no-repeat;
background-size: 100% 80px;
background-position: bottom center;
display: flex;
flex-direction: column;
align-items: center;
font-weight: bold;
& > b {
font-size: 50px;
line-height: 50px;
span {
font-weight: normal;
font-size: 32px;
}
}
& > span {
font-size: 18px;
line-height: 18px;
}
}
}
.framePane {
width: 100%;
height: 100%;
background: rgba(7, 11, 35, 0.4);
border: 1px solid #14345F;
display: flex;
flex-direction: column;
&.top {
width: 440px;
height: 520px;
}
& > .fill {
width: 100%;
height: 100%;
padding: 20px;
box-sizing: border-box;
overflow-y: auto;
}
}
.titlePane {
width: 100%;
background-image: url("../assets/govInteraction/title.png");
background-repeat: no-repeat;
background-size: 309px 100%;
height: 60px;
padding-left: 30px;
color: #fff;
font-weight: bold;
font-size: 20px;
line-height: 48px;
}
.chart {
width: 100%;
}
.el-image {
width: 100%;
height: 100%;
}
.totalPane {
width: 100%;
.dataPanel {
height: 60px;
background: linear-gradient(270deg, rgba(119, 169, 255, 0.1) 0%, rgba(66, 112, 255, 0.25) 100%);
border-radius: 4px;
padding: 0 10px;
font-size: 16px;
justify-content: space-between;
margin-left: 20px;
& > span {
white-space: nowrap;
}
& > b {
font-size: 24px;
color: #fff;
font-family: Arial-BoldMT, Arial, serif;
}
&:last-of-type {
margin-right: 20px;
}
}
}
}
</style>

View File

@@ -1,852 +0,0 @@
<template>
<div class="griddv">
<div class="left">
<div class="griddv-title">
<h2>网格列表</h2>
</div>
<div class="griddv-tree">
<el-tree
:data="treeList"
:props="defaultProps"
@node-click="handleNodeClick"
node-key="id"
ref="tree"
default-expand-all
:expand-on-click-node="false"
highlight-current>
</el-tree>
</div>
</div>
<div class="middle" :class="[girdLevel == '2' ? 'middle-active' : '']" ref="container" v-loading="isLoading"
element-loading-background="rgba(0, 0, 0, 0.5)">
<div
ref="middleTree"
id="tree"
class="tree"
:style="{left: x, top: y, transform: `scale(${scale}) translate(-50%, -50%) `, 'transform-origin': `${0} ${0}`}">
<ai-okr-tree ref="VueOkrTree" v-if="chartData.length"
:data="chartData"
node-key="id"
show-collapsable
aniamte
animate-name="okr-fade-in-linear"
:render-content="renderContent"
default-expand-all/>
</div>
</div>
<div class="right">
<div class="right-top">
<div class="griddv-title">
<h2>网格内人员情况</h2>
</div>
<div class="right-chart">
<ai-echart
style="height: 100%; width: 100%;"
:data="userInfo"
:ops="barChart1">
</ai-echart>
</div>
</div>
<div class="right-bottom">
<div class="griddv-title">
<h2>事件上报情况</h2>
</div>
<div class="right-chart">
<ai-echart
style="height: 100%; width: 100%;"
:data="eventInfo"
:ops="pieChart">
</ai-echart>
</div>
</div>
</div>
<el-dialog :visible.sync="isShowInfo" width="640px" :close-on-click-modal="false" :modal-append-to-body="false">
<template slot="title">
<h2>家庭信息</h2>
<img src="../assets/grid/close.png" @click="isShowInfo = false">
</template>
<div class="grid-info">
<div class="grid-info__title">
<h2>家庭地址</h2>
<span>{{ residentInfo.currentAreaName }}</span>
</div>
<ai-table
style="width: 558px"
:tableData="tableData"
:col-configs="colConfigs"
:total="total"
:isShowPagination="false"
:current.sync="search.current"
:size.sync="search.size"
@getList="() => {}">
</ai-table>
</div>
</el-dialog>
</div>
</template>
<script>
import pieChart from 'dvcp-dv-ui/components/AiEchart/template/pie/pieChart2'
import barChart1 from 'dvcp-dv-ui/components/AiEchart/template/bar/barChart1'
import AiOkrTree from "dvcp-dv-ui/components/AiOkrTree/AiOkrTree"
export default {
name: 'AppGridDV',
label: '网格数据大屏',
components: {AiOkrTree},
props: {
instance: Function,
dict: Object,
},
data() {
return {
isLoading: false,
treeList: [],
search: {
size: 100,
current: 1
},
barChart1,
userInfo: [],
eventInfo: [],
pieChart,
total: 0,
isShowInfo: false,
defaultProps: {
children: 'girdList',
label: 'girdName',
},
colConfigs: [
{prop: 'name', label: '姓名', align: 'center', width: 120},
{
prop: 'householdRelation',
label: '与户主关系',
align: 'center',
render: (h, {row}) => {
return h('span', {
style: {
color: row.householdName === '1' ? '#1DE94D' : '#A8D7F3'
}
}, row.householdName === '1' ? '户主' : (this.dict.getLabel('householdRelation', row.householdRelation) || '-'))
},
formart: v => this.dict.getLabel('householdRelation', v)
},
{
prop: 'idNumber',
label: '身份证号',
align: 'center',
width: 220,
formart: v => v ? v.replace(/^(\d{10})\d{4}(.{4}$)/g, `$1${Array(5).join('*')}$2`) : '-'
},
{prop: 'phone', label: '联系方式', align: 'center'}
],
girdId: '',
residentInfo: {},
tableData: [],
chartData: [],
girdLevel: '0',
scale: 1,
x: '50%',
y: '50%',
offsetX: 0,
offsetY: 0,
defaultUrl: 'https://cdn.cunwuyun.cn/dvcp/dv/avatar.png'
}
},
created() {
this.dict.load('householdRelation')
this.getTreeList()
this.getGirdInfo()
},
mounted() {
this.bindEvent()
},
destroyed() {
document.querySelector('body').removeEventListener('mousewheel', this.onMousewheel)
document.querySelector('body').removeEventListener('mouseup', this.onMouseUp)
document.querySelector('body').removeEventListener('mousedown', this.onMousedown)
document.querySelector('body').removeEventListener('mousemove', this.onMouseMove)
},
methods: {
bindEvent() {
document.querySelector('body').addEventListener('mousewheel', this.onMousewheel, true)
document.querySelector('body').addEventListener('mouseup', this.onMouseUp, true)
document.querySelector('body').addEventListener('mousedown', this.onMousedown, true)
document.querySelector('body').addEventListener('mousemove', this.onMouseMove, true)
},
onMousewheel(event) {
if (!event) return false
const elClass = event.target.className
if (elClass === 'tree' || elClass === 'middle' || (elClass && (elClass.indexOf('chart') > -1 || elClass.indexOf('user') > -1))) {
var dir = event.deltaY > 0 ? 'Up' : 'Down'
if (dir === 'Up') {
this.scale = this.scale - 0.2 <= 0.1 ? 0.1 : this.scale - 0.2
} else {
this.scale = this.scale + 0.2
}
}
return false
},
onMousedown(e) {
const elClass = e.target.className
if ((elClass && (elClass.indexOf('chart') > -1 || elClass.indexOf('user') > -1))) {
const left = document.querySelector('#tree').offsetLeft
const top = document.querySelector('#tree').offsetTop
this.isMove = true
this.offsetX = e.clientX - left
this.offsetY = e.clientY - top
}
},
onMouseMove(e) {
if (!this.isMove) return
this.x = (e.clientX - this.offsetX) + 'px'
this.y = (e.clientY - this.offsetY) + 'px'
},
onMouseUp() {
this.isMove = false
},
debounce(func, wait = 1000) {
let timeout
return function (event) {
clearTimeout(timeout)
timeout = setTimeout(() => {
func.call(this, event)
}, wait)
}
},
handleNodeClick(e) {
this.girdLevel = e.girdLevel
this.isLoading = true
this.getGirdInfo(e.id, e.girdLevel)
this.getStatisticsInfo(e.id)
},
getStatisticsInfo(id) {
this.instance.post(`/app/appgirdmemberinfo/girdMemberAndResidentStatistic?girdId=${id}`).then((res) => {
if (res.code == 0) {
this.userInfo = [
{
'name': '网格长',
'人数': res.data['网格长'] || 0
},
{
'name': '网格员',
'人数': res.data['网格员'] || 0
},
{
'name': '责任家庭数',
'人数': res.data['责任家庭数'] || 0
}
]
}
})
this.instance.post(`/app/appclapeventinfo/clapEventStatistic?girdId=${id}`).then((res) => {
if (res.code == 0) {
this.eventInfo = Object.keys(res.data).map(v => {
return {
'事件类型': v,
v1: res.data[v]
}
})
}
})
},
renderContent(h, node) {
return h('div', {
class: 'userlist-container'
}, [h('div', {
class: `userlist ${node.data.label === '子节点' ? 'last-level' : ''} ${node.data.girdLevel > 1 ? 'userlist-wrapper' : ''} userlist-${node.data.girdLevel}`
}, node.data.userList.map(v => {
return h('div', {
class: `user-item user-item-${v.girdLevel}`
}, [h('img', {
class: 'user-img',
attrs: {
src: v.photo || this.defaultUrl
},
on: {
dragstart: e => {
e.preventDefault()
e.stopPropagation()
return false
}
}
}), h('p', {
class: 'user-p',
attrs: {
title: v.label,
'data-id': v.id
},
on: {
click: () => {
if (node.data.label === '子节点') {
this.getResidentInfo(v.id)
}
}
}
}, v.label), h('span', {
class: 'user-span',
style: {
display: v.girdLevel === '2' ? 'block' : 'none',
fontSize: v.girdLevel === '2' ? '12px' : ''
}
}, v.checkType ? (v.checkType === '1' ? '网格员' : '网格长') : '-')])
})), h('div', {
class: 'user-gridName',
style: {
display: node.data.label === '子节点' ? 'none' : 'block',
color: 'rgba(255, 255, 255, 0.8)',
fontSize: '12px',
margin: '4px 0'
}
}, node.data.label)])
},
getResidentInfo(id) {
this.isLoading = true
this.instance.post(`/app/appresident/detail?id=${id}`).then((res) => {
if (res.code == 0) {
this.residentInfo.resident = res.data
this.tableData = res.data.family || []
this.isShowInfo = true
}
this.isLoading = false
})
},
autoScale() {
const treeWidth = this.$refs.middleTree.offsetWidth
const containerWidth = this.$refs.container.offsetWidth
this.scale = treeWidth < containerWidth ? 1 : containerWidth / treeWidth
this.x = '50%'
this.y = '50%'
},
getGirdInfo(id) {
this.instance.post(`/app/appgirdinfo/listAllGirdAndMemberByTop?id=${id || ''}`).then((res) => {
if (res.code == 0) {
const chartData = this.formatList([res.data])
this.chartData = chartData
this.$nextTick(() => {
if (id) {
this.getUserList(id, chartData[0].id)
} else {
this.isLoading = false
this.autoScale()
}
})
}
})
},
getUserList(id, parentId) {
this.instance.post(`/app/appgirdmemberresident/listByGirdMember`, null, {
params: {
size: 1000,
girdId: id
}
}).then(res => {
if (res.code == 0) {
const userList = res.data.records.map(v => {
return {
...v,
isLast: true,
label: v.name
}
})
this.isLoading = false
if (!userList.length) {
this.autoScale()
return false
}
const node = this.$refs.VueOkrTree.getNode(parentId)
this.$refs.VueOkrTree.append({
id: new Date().getTime(),
label: '子节点',
userList: userList || []
}, node)
this.$nextTick(() => {
this.autoScale()
})
}
})
},
formatList(list) {
return list.map(item => {
let userList = []
const girdMemberManageList = item.girdMemberManageList ? item.girdMemberManageList.map(v => {
return {
...v,
label: v.name,
id: v.id,
checkType: '2',
girdName: item.girdName,
girdLevel: item.girdLevel,
isUser: true
}
}) : []
const girdMemberList = item.girdMemberList ? item.girdMemberList.map(v => {
return {
...v,
label: v.name,
id: v.id,
checkType: '1',
girdName: item.girdName,
girdLevel: item.girdLevel,
isUser: true
}
}) : []
if (this.girdLevel === '2' && item.girdLevel === '2' && girdMemberList.length) {
userList = girdMemberManageList
item.girdList = [{
girdLevel: '2',
id: item.id,
isUser: false,
userList: girdMemberList,
label: item.girdName,
children: []
}]
} else {
userList = [...girdMemberManageList, ...girdMemberList]
}
if (!userList.length) {
userList = [{
label: '-',
id: item.id,
girdLevel: item.girdLevel,
girdName: item.girdName
}]
}
const obj = {
label: item.girdName,
id: `${new Date().getTime()}-${item.id}`,
girdLevel: item.girdLevel,
isUser: false,
userList: userList,
children: item.girdList || []
}
if (obj.children && obj.children.length && this.girdLevel !== '2') {
obj.children = this.formatList(obj.children)
}
return obj
})
},
getTreeList() {
this.instance.post('/app/appgirdinfo/listAll').then((res) => {
if (res.code == 0) {
this.treeList = [...res.data]
this.$nextTick(() => {
this.$refs.tree.setCurrentKey(res.data[0].id)
this.getStatisticsInfo(res.data[0].id)
})
}
})
}
}
}
</script>
<style lang="scss" scoped>
.griddv {
display: flex;
align-items: center;
height: 100%;
user-select: none;
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
border-radius: 5px;
background: rgba(93, 163, 255, 0.1);
}
::-webkit-scrollbar-thumb {
border-radius: 5px;
background: rgba(173, 208, 255, 0.5);
}
.grid-info {
width: 100%;
.grid-info__title {
display: flex;
align-items: center;
margin-bottom: 20px;
h2, span {
color: #fff;
font-size: 14px;
font-weight: 500;
}
}
}
::v-deep .el-dialog__body {
padding: 10px 40px 30px;
.el-table {
background-color: transparent;
}
.el-table__body tr td:first-child .cell, .ai-table .el-table__header tr th:first-child .cell {
padding-left: 0 !important;
}
.el-table th, .el-table tr {
color: #fff;
font-size: 14px;
background-color: rgba(28, 39, 65, 0.9);
}
.el-table__row--striped, .el-table--striped .el-table__body tr.el-table__row--striped td {
background-color: transparent !important;
}
.el-table__header-wrapper {
display: none;
}
.el-table--enable-row-hover .el-table__body tr:hover > td, .el-table-filter {
background-color: transparent;
}
}
::v-deep .el-dialog {
position: absolute;
top: 50%;
left: 50%;
margin: 0 !important;
transform: translate(-50%, -50%);
background: rgba(2, 13, 43, 0.9);
box-shadow: 0px 2px 10px 0px rgba(0, 0, 0, 0.5), inset 0px 0px 10px 0px #2C7CFF;
border: 1px solid #2D65C9;
.el-dialog__header {
display: flex;
align-items: center;
justify-content: space-between;
background: transparent;
box-shadow: none;
h2 {
color: #fff;
font-size: 18px;
}
img {
cursor: pointer;
width: 16px;
height: 16px;
&:hover {
opacity: 0.6;
}
}
}
.el-dialog__headerbtn {
display: none;
}
}
::v-deep .userlist-container {
.userlist {
display: flex;
align-items: center;
justify-content: center;
padding: 10px;
background: rgba(76, 166, 255, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
.user-item {
margin-right: 10px;
color: #fff;
font-size: 0;
&:last-child {
margin-right: 0;
}
img {
width: 58px;
height: 80px;
object-fit: cover;
user-select: none;
}
p {
max-width: 120px;
margin: 4px 0 0 0;
font-size: 19px;
text-align: center;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
span {
display: block;
max-width: 120px;
font-size: 17px;
color: #9DD3FF;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&.user-item-0 {
img {
width: 86px;
height: 120px;
}
}
&.user-item-2 {
p {
line-height: 14px;
font-size: 12px;
margin-bottom: 4px;
}
span {
line-height: 14px;
}
img {
width: 40px;
height: 56px;
}
}
}
&.userlist-2 {
justify-content: space-between;
max-width: 130px;
flex-wrap: wrap;
padding-bottom: 0;
width: fit-content;
margin: 0 auto;
.user-item {
width: 48px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-bottom: 10px;
&:nth-of-type(2n) {
margin-right: 0;
}
}
}
&.last-level {
flex-wrap: wrap;
max-width: 690px;
font-size: 0;
background: rgba(0, 0, 0, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
padding: 12px 12px 0 12px;
box-sizing: border-box;
.user-item {
margin-bottom: 12px;
}
img {
display: none;
}
p {
padding: 8px;
font-size: 12px;
background: #0B477D;
border-radius: 4px;
}
span {
display: none !important;
}
}
}
}
* {
box-sizing: border-box;
}
.griddv-title {
display: flex;
width: 320px;
height: 62px;
background-image: url(../assets/grid/title-bg.png);
background-size: 100% 100%;
h2 {
width: 100%;
height: 50px;
line-height: 50px;
padding-left: 24px;
font-weight: 600;
font-size: 20px;
letter-spacing: 1px;
color: #fff;
}
}
& > div {
height: 100%;
}
.right {
display: flex;
justify-content: space-between;
flex-direction: column;
width: 440px;
margin-left: 20px;
& > div {
flex: 1;
width: 100%;
padding-bottom: 20px;
background: rgba(7, 11, 35, 0.4);
border: 1px solid #2D50B5;
box-sizing: border-box;
.right-chart {
height: calc(100% - 82px);
padding: 0 20px;
}
&:last-child {
margin-top: 20px;
}
}
}
.middle {
position: relative;
flex: 1;
margin-left: 20px;
background: rgba(7, 11, 35, 0.4);
border: 1px solid #2D50B5;
overflow: hidden;
#tree {
display: flex;
position: absolute;
align-items: center;
justify-content: center;
left: 50%;
top: 50%;
padding: 20px;
overflow: hidden;
width: max-content;
height: 300%;
}
::v-deep .org-chart-container {
display: flex;
justify-content: center;
.org-chart-node-children:before, .org-chart-node:after, .org-chart-node:last-child:before,
.org-chart-node.is-leaf:before {
border-radius: 0;
border-color: #9CD7FF !important;
}
.vertical .org-chart-node:after, .vertical .org-chart-node:before {
border-radius: 0;
border-color: #9CD7FF !important;
}
.org-chart-node-label-inner {
padding: 0 !important;
}
.org-chart-node-btn {
margin-left: 0;
transform: translateX(-50%);
}
.org-chart-node {
// max-width: 500px;
}
}
::v-deep .org-chart-node-children {
display: flex;
justify-content: center;
}
}
.left {
width: 320px;
background: rgba(7, 11, 35, 0.4);
border: 1px solid #2D50B5;
.griddv-tree {
height: calc(100% - 62px);
overflow-y: auto;
margin: 0 8px;
padding-bottom: 8px;
}
::v-deep .el-tree {
background: transparent;
.el-tree-node__expand-icon {
color: #eaeff9;
}
.el-tree-node__expand-icon.is-leaf {
color: transparent;
}
.el-tree-node__content {
height: 32px;
color: #eaeff9;
font-size: 14px;
user-select: none;
font-weight: normal !important;
background: transparent;
}
.is-current > .el-tree-node__content, .el-tree-node__content:hover {
background: linear-gradient(270deg, #4895D9 0%, #2D52CA 100%);
}
}
}
}
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,522 +0,0 @@
<template>
<section class="AppVideoMonitoringDV">
<el-row type="flex" justify="space-between" class="body">
<div class="left-wrap column" flex>
<div class="left-top fill">
<label class="label">设备统计</label>
<dv-scroll-board :header="config.header" :config="config" class="table"/>
</div>
<div class="left-bottom">
<label class="label">电子地图</label>
<ai-map :areaId="user.info.areaId"/>
</div>
</div>
<div class="center-wrap column" flex>
<div flex style="width: 100%">
<div :span="6" class="card fill" v-for="(item,index) in cardList" :key="index">
<span>{{ item.label }}</span>
<span>{{ item.value }}</span>
</div>
</div>
<div class="center-bottom fill">
<label class="label">视频监控</label>
<div class="video-wrap">
<div class="item" v-for="(item,index) in videoData.slice(0,2)"
:key="index">
<template v-if="flag">
<iframe class="video" :src="item.url" allow="autoplay *; microphone *; fullscreen *"
allowfullscreen allowtransparency="true" allowusermedia="true" frameBorder="no"></iframe>
</template>
<template v-else>
<div class="video"></div>
</template>
<div class="info">
<span>{{ item.name }}</span>
</div>
</div>
</div>
<div class="video-wrap">
<div class="item" v-for="(item,index) in videoData.slice(2,4)"
:key="index">
<template v-if="flag">
<iframe class="video" :src="item.url" allow="autoplay *; microphone *; fullscreen *"
allowfullscreen allowtransparency="true" allowusermedia="true" frameBorder="no"></iframe>
</template>
<template v-else>
<div class="video"></div>
</template>
<div class="info">
<span>{{ item.name }}</span>
</div>
</div>
</div>
</div>
</div>
<div class="right-wrap column" flex>
<div class="right-top fill">
<label class="label">人员统计</label>
<label class="total">人员总数
<span>0</span>
<span></span>
</label>
<dv-scroll-board :config="config1" class="total-table"/>
</div>
<div class="right-middle">
<label class="label">动作告警统计</label>
<div class="tag">
<span></span>
</div>
<ai-echart :ops="getOpt()"/>
<div class="info">
今日
<span>0</span>
<span></span>
本月
<span>0</span>
<span></span>
</div>
</div>
<div class="right-bottom">
<label class="label">声音告警统计</label>
<div class="tag">
<span></span>
</div>
<ai-echart :ops="getOpt('1')"/>
<div class="info">
今日
<span style="color:#00FFDF">0</span>
<span></span>
本月
<span style="color:#00FFDF">0</span>
<span></span>
</div>
</div>
</div>
</el-row>
</section>
</template>
<script>
import {mapState} from "vuex";
import Vue from "vue";
import {scrollBoard} from "@jiaminghi/data-view";
Vue.use(scrollBoard)
export default {
name: "AppVideoMonitoringDV",
label: "数据大屏-平安小区",
inject: {
dv: {default: ""}
},
props: {
instance: Function
},
computed: {
...mapState(['user']),
cardList() {
return [
{label: "总设备数", value: "0"},
{label: "在线设备", value: "0"},
{label: "离线设备", value: "0"},
{label: "设备在线率", value: "0%"},
]
},
},
data() {
return {
meta: {},
config: {
data: [
],
columnWidth: [60, 140],
header: ["机构", "设备在线率"],
headerBGC: '',
headerHeight: 41,
oddRowBGC: "",
evenRowBGC: "",
align: ["center", "center", "center"],
rowNum: 10,
index: true,
indexHeader: "排名"
},
config1: {
data: [
['普通用户', '-'],
['村级管理员', '-'],
['超级管理员', '-'],
['测试', '-'],
],
headerHeight: 41,
oddRowBGC: "",
evenRowBGC: "",
align: ["left", "left", "right"],
index: true,
rowNum: 6,
columnWidth: [50]
},
start: 0,
end: 40,
start1: 0,
end1: 40,
interval: null,
videoData: [],
flag: false,
}
},
methods: {
jsonObj(val) {
return JSON.parse(val || "{}")?.url
},
getOpt(type = "0") {
let opt = {
"0": {
xData: ['2020/7/1', "2020/7/2", "2020/7/3", "2020/7/4", "2020/7/5", "2020/7/6", "2020/7/7", "2020/7/8", "2020/7/9", "2020/7/10", "2020/7/11"],
yData: Array(11).fill(0),
color: "#FFEA2F",
areaStyle: 'rgba(255,234,47,0.2)',
unit: '',
},
"1": {
xData: ["1:00", "2:00", "3:00", "4:00", "5:00", "6:00", "7:00", "8:00", "9:00", "10:00"],
yData: Array(10).fill(0),
color: "#13B5B1",
areaStyle: 'rgba(255,234,47,0.2)',
unit: '次',
},
}
return {
grid: {
top: "5%",
left: "16%",
right: "3%",
bottom: "12%"
},
xAxis: {
show: true,
boundaryGap: false,
type: 'category',
axisLabel: {
show: true,
textStyle: {
color: "#5E9CEA",
fontSize: 12
}
},
axisLine: {
show: false
},
axisTick: {
show: false
},
data: opt[type]["xData"]
},
yAxis: {
type: 'value',
show: true,
axisTick: {
show: false
},
axisLine: {
show: false
},
splitLine: {
show: true,
lineStyle: {
color: ['#103066'],
}
},
axisLabel: {
show: true,
formatter: (val) => `${val}${opt[type]["unit"]}`,
textStyle: {
color: "#5E9CEA",
fontSize: 12
}
},
},
series: [{
symbol: "none",
data: opt[type]["yData"],
type: 'line',
itemStyle: {
normal: {
color: opt[type]["color"],
areaStyle: {
color: {
type: 'linear', x2: 0, y2: 1, colorStops: [
{offset: 0, color: opt[type]["areaStyle"]}, {offset: 1, color: '#000000'}]
}
}
}
}
}]
}
},
getWebSdkUrlForScreen() {
this.instance.post(`/app/appzyvideoequipment/getWebSdkUrlForTianQiaoScreen`).then(res => {
if (res.code == 0) {
this.videoData = res.data
this.flag = true
}
})
}
},
beforeDestroy() {
this.interval && clearInterval(this.interval);
},
mounted() {
// this.getWebSdkUrlForScreen()
},
}
</script>
<style lang="scss" scoped>
.AppVideoMonitoringDV {
height: 100%;
padding: 6px 0 10px;
display: flex;
flex-direction: column;
gap: 24px;
.body {
height: 100%;
.left-wrap {
width: 307px;
height: 100%;
.left-top {
width: 100%;
background-image: url("../assets/videoMonitor/box1.png");
background-size: 100% 100%;
position: relative;
overflow: hidden;
.table {
box-sizing: border-box;
padding: 63px 17px 17px;
}
}
.left-bottom {
width: 100%;
height: 311px;
background-image: url("../assets/videoMonitor/box2.png");
background-size: 100% 100%;
margin-top: 7px;
display: flex;
align-items: center;
justify-content: center;
position: relative;
.AiMap {
width: 274px;
height: 247px;
margin-top: 40px;
}
}
}
.center-wrap {
width: 1183px;
height: 100%;
.card {
height: 93.3px;
display: flex;
align-items: center;
justify-content: center;
background-image: url("../assets/videoMonitor/card.png");
background-size: 100% 100%;
margin-right: 24px;
&:last-child {
margin-right: 0;
}
& > span:first-child {
font-size: 20px;
font-weight: 400;
color: #FFFFFF;
}
& > span:last-child {
font-size: 38px;
font-family: dineng, serif;
font-weight: bold;
color: #00EDFF;
margin-left: 13px;
}
}
.center-bottom {
width: 100%;
height: 789px;
background-image: url("../assets/videoMonitor/middlebox.png");
background-size: 100% 100%;
margin-top: 40px;
position: relative;
box-sizing: border-box;
padding: 61px;
.video-wrap {
width: 100%;
height: 344px;
display: flex;
justify-content: space-between;
margin-bottom: 12px;
.item {
.video {
width: 522px;
height: 296px;
object-fit: fill;
vertical-align: bottom;
border: 2px solid #122C7D;
}
.info {
height: 48px;
display: flex;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
padding: 0 12px;
background-color: #071153;
font-size: 14px;
color: #FFFFFF;
}
}
}
}
}
.right-wrap {
width: 297px;
height: 100%;
.right-top {
width: 100%;
height: 333px;
background-image: url("../assets/videoMonitor/box3.png");
background-size: 100% 100%;
position: relative;
overflow: hidden;
.total {
font-size: 16px;
color: #979AB7;
display: inline-block;
margin: 65px 0 16px 23px;
& > span:nth-child(1) {
font-size: 28px;
font-family: dineng, serif;
font-weight: bold;
color: #01CAFF;
}
& > span:nth-child(2) {
font-size: 16px;
color: #01CAFF;
}
}
.total-table {
height: 200px;
box-sizing: border-box;
padding: 0 23px;
}
}
.right-middle, .right-bottom {
width: 100%;
height: 276px;
background-image: url("../assets/videoMonitor/box4.png");
background-size: 100% 100%;
margin: 19px 0;
position: relative;
overflow: hidden;
.tag {
margin: 28px 18px 0 0;
display: flex;
justify-content: flex-end;
font-size: 12px;
color: #5E9CEA;
& > span {
font-size: 12px;
color: #FFFFFF;
display: inline-block;
width: 34px;
height: 17px;
text-align: center;
line-height: 18px;
margin-left: 14px;
}
}
::v-deep .AiEchart {
width: 251px;
height: 175px;
margin: 11px auto 0;
}
.info {
font-size: 12px;
color: #FFFFFF;
line-height: 24px;
box-sizing: border-box;
padding: 15px 19px 0;
& > span:nth-child(2n+1) {
font-size: 18px;
font-weight: 400;
line-height: 24px;
color: #FFE930;
}
& > span:nth-child(2n) {
font-size: 14px;
font-weight: 400;
color: #FFE930;
line-height: 24px;
margin: 0 5px;
}
& > span:nth-child(2) {
margin-right: 22px;
}
}
}
.right-bottom {
margin: 0;
}
}
}
.label {
position: absolute;
left: 24px;
top: 23px;
font-size: 16px;
font-weight: 600;
color: #FFFFFF;
}
::v-deep .index {
background-color: transparent !important;
}
::v-deep .header {
background: url("../assets/videoMonitor/titlebox.png");
}
::v-deep .row-item div:nth-child(3) {
font-size: 13px;
color: #00CDFF;
}
}
</style>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 362 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 693 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

View File

@@ -1,12 +0,0 @@
{
"name": "dvcp-dv",
"description": "大屏应用",
"version": "1.0.0",
"main": "dist/dvcp-dv.common.js",
"publishConfig": {
"registry": "http://192.168.1.87:4873/"
},
"dependencies": {
"dvcp-dv-ui": "^2.0.0"
}
}

View File

@@ -1,91 +0,0 @@
export default {
legend: {
right: 0,
itemHeight: 5,
itemWidth: 16,
textStyle: { color: '#fff' }
},
yAxis: {
nameGap: 23,
minInterval: 1,
splitLine: { lineStyle: { color: 'rgba(255,255,255,.2)', type: 'dashed' } },
axisLabel: { color: '#fff' },
axisPointer: { show: false }
},
axisPointer: {
type: 'shadow',
triggerTooltip: false,
shadowStyle: { color: 'rgba(46, 153, 255, .2)' }
},
color: [
{
type: 'linear',
x: 0,
x2: 0,
y: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(66, 187, 255, 1)' },
{ offset: 1, color: 'rgba(37, 143, 255, 0.2)' }
]
},
{
type: 'linear',
x: 0,
x2: 0,
y: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(66, 255, 254, 1)' },
{ offset: 1, color: 'rgba(37, 255, 246, 0.2)' }
]
},
{
type: 'linear',
x: 0,
x2: 0,
y: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(97, 253, 185, 1)' },
{ offset: 1, color: 'rgba(97, 253, 185, 0.2)' }
]
},
{
type: 'linear',
x: 0,
x2: 0,
y: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(253, 108, 57, 1)' },
{ offset: 1, color: 'rgba(253, 108, 57, 0.2)' }
]
},
{
type: 'linear',
x: 0,
x2: 0,
y: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(248, 187, 25, 1)' },
{ offset: 1, color: 'rgba(55, 39, 5, 1)' }
]
}
],
daemon: {
type: 'bar',
label: {
show: true,
position: 'top',
color: '#fff',
formatter: e => {
return e.data[e.seriesName] || ''
}
},
barWidth: 16,
barCategoryGap: 40,
itemStyle: {}
}
}

View File

@@ -1,24 +0,0 @@
export default {
legend: {
right: 0, itemGap: 16,
textStyle: {color: '#fff', padding: [0, 0, 0, 8], fontSize: 14},
itemWidth: 16, itemHeight: 5
},
grid: {
left: 50, right: 0
},
tooltip: {
trigger: 'axis', backgroundColor: 'rgba(14, 51, 111, 0.9)', borderColor: '#1A6ABC',
textStyle: {color: '#fff'}
},
yAxis: {
nameGap: 23, minInterval: 1,
splitLine: {lineStyle: {color: 'rgba(255,255,255,.2)', type: 'dashed'}},
axisLabel: {color: '#fff'}, axisPointer: {show: false}
},
axisPointer: {
type: 'shadow', show: true,
shadowStyle: {color: 'rgba(46, 153, 255, .2)'}
},
daemon: {type: 'bar', barWidth: 2, barGap: 4}
}

View File

@@ -1,33 +0,0 @@
export default {
legend: {show: false},
yAxis: {
nameGap: 23, minInterval: 1,
splitLine: {lineStyle: {color: 'rgba(255,255,255,.2)', type: 'dashed'}},
axisLabel: {color: '#fff'}, axisPointer: {show: false}
},
axisPointer: {
type: 'none', show: true, triggerTooltip: false,
},
daemon: {
type: 'bar', label: {show: true, position: 'insideBottom', color: '#fff'},
barWidth: 24,
showBackground: true,
backgroundStyle: {
color: 'rgba(123, 165, 255, .2)'
},
itemStyle: {
color: {
type: 'linear', x: 0, x2: 0, y: 0, y2: 1,
colorStops: [{offset: 0, color: '#42BBFF'}, {offset: 1, color: 'rgba(37, 143, 255, 0.2)'}]
}
},
emphasis: {
itemStyle: {
color: {
type: 'linear', x: 0, x2: 0, y: 0, y2: 1,
colorStops: [{offset: 0, color: '#42FFFE'}, {offset: 1, color: 'rgba(37, 255, 246, 0.2)'}]
}
}
}
}
}

View File

@@ -1,23 +0,0 @@
export default {
legend: {
right: 0, itemGap: 16,
textStyle: {color: '#fff', padding: [0, 0, 0, 8], fontSize: 14},
itemWidth: 16, itemHeight: 5
},
grid: {
left: 50, right: 0
},
tooltip: {
trigger: 'axis', backgroundColor: 'rgba(14, 51, 111, 0.9)', borderColor: '#1A6ABC',
textStyle: {color: '#fff'}
},
yAxis: {
nameGap: 23, minInterval: 1,
splitLine: {lineStyle: {color: 'rgba(255,255,255,.2)', type: 'dashed'}},
axisLabel: {color: '#fff'}, axisPointer: {show: false}
},
axisPointer: {
type: 'none', show: true, triggerTooltip: false,
},
daemon: {type: 'bar', barWidth: 12, stack: 'stack'}
}

View File

@@ -1,45 +0,0 @@
export default {
legend: {show: false},
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(14, 51, 111, 0.9)', borderColor: '#1A6ABC', textStyle: {color: '#fff'},
axisPointer: {
type: 'shadow', shadowStyle: {color: 'rgba(46, 153, 255, .2)'},
label: {show: true, backgroundColor: 'transparent', fontSize: 14, margin: 1, color: '#28FBFF'}
}
},
yAxis: {
type: 'category',
axisLabel: {color: '#fff', fontSize: 14},
axisTick: {show: false},
axisLine: {show: false},
},
xAxis: {
nameGap: 23, minInterval: 1,
splitLine: {lineStyle: {color: 'rgba(255,255,255,.2)', type: 'dashed'}},
axisLabel: {color: '#fff', fontSize: 14},
},
daemon: {
type: 'bar', barWidth: 10, barGap: '40%',
label: {show: true, position: 'insideRight', color: '#fff', fontSize: 14},
showBackground: true,
backgroundStyle: {
color: 'rgba(123, 165, 255, .2)'
},
itemStyle: {
color: {
type: 'linear', x: 0, x2: 1, y: 0, y2: 0,
colorStops: [{offset: 0, color: 'rgba(37, 143, 255,.5)'}, {offset: 1, color: 'rgba(43, 199, 255, 1)'}]
}
},
emphasis: {
label: {color: '#28FBFF', position: 'right'},
itemStyle: {
color: {
type: 'linear', x: 0, x2: 1, y: 0, y2: 0,
colorStops: [{offset: 0, color: 'rgba(37, 255, 246, 0.5)'}, {offset: 1, color: '#28FBFF'}]
}
}
}
}
}

View File

@@ -1,36 +0,0 @@
import tools from "../tools";
export default {
legend: {
right: 0, itemGap: 16,
textStyle: {color: '#fff', padding: [0, 0, 0, 8], fontSize: 14},
itemWidth: 16, itemHeight: 5
},
grid: {
left: 50, right: 0
},
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(14, 51, 111, 0.9)', borderColor: '#1A6ABC', textStyle: {color: '#fff'}
},
yAxis: {
type: 'category',
axisLabel: {color: '#fff', fontSize: 14},
axisLine: {lineStyle: {color: 'rgba(255,255,255,.5)'}},
axisPointer: {show: false},
},
xAxis: {
nameGap: 23, minInterval: 1,
splitLine: {lineStyle: {color: 'rgba(255,255,255,.2)', type: 'dashed'}},
axisLabel: {color: '#fff', fontSize: 14},
},
daemon: {
type: 'bar', barWidth: 10,
itemStyle: {
color: ({color}) => ({
type: 'linear', x: 0, x2: 1, y: 0, y2: 0,
colorStops: [{offset: 0, color: tools.$colorUtils.Hex2RGBA(color, .5)}, {offset: 1, color}]
})
},
}
}

View File

@@ -1,29 +0,0 @@
export default {
legend: {
right: 0, itemGap: 16,
textStyle: {color: '#fff', padding: [0, 0, 0, 8], fontSize: 14},
itemWidth: 16, itemHeight: 5
},
grid: {
left: 80, right: 0
},
tooltip: {
backgroundColor: 'rgba(14, 51, 111, 0.9)', borderColor: '#1A6ABC', textStyle: {color: '#fff'},
},
yAxis: {
type: 'category',
axisLabel: {color: '#fff', fontSize: 14, margin: 23},
axisTick: {show: false},
axisLine: {show: false},
},
xAxis: {
nameGap: 23, minInterval: 1,
splitLine: {lineStyle: {color: 'rgba(255,255,255,.2)', type: 'dashed'}},
axisLabel: {color: '#fff', fontSize: 14},
},
daemon: {
type: 'bar', barWidth: 10, barGap: '40%', stack: 'stack',
showBackground: true,
backgroundStyle: {color: 'rgba(123, 165, 255, .2)'}
}
}

View File

@@ -1,40 +0,0 @@
import tools from '../tools';
export default {
legend: { show: false },
grid: {
left: 50,
right: 0
},
tooltip: {
trigger: 'axis',
backgroundColor: 'rgba(14, 51, 111, 0.9)',
borderColor: '#1A6ABC',
textStyle: { color: '#fff' },
axisPointer: { type: 'cross' }
},
yAxis: {
nameGap: 23,
minInterval: 1,
splitLine: { lineStyle: { color: 'rgba(255,255,255,.2)', type: 'dashed' } },
axisLabel: { color: '#fff' },
axisPointer: { snap: true }
},
daemon: (color) => ({
showSymbol: false,
lineStyle: { shadowBlur: 4, shadowOffsetY: 2 },
areaStyle: {
color: {
type: 'linear',
x: 0,
x2: 0,
y: 0,
y2: 1,
colorStops: [
{ offset: 0, color: tools.$colorUtils.Hex2RGBA(color, 0.5) },
{ offset: 1, color: tools.$colorUtils.Hex2RGBA(color, 0.5) }
]
}
}
})
};

View File

@@ -1,27 +0,0 @@
import tools from "../tools";
export default {
legend: {
right: 0, itemGap: 16,
textStyle: {color: '#fff', padding: [0, 0, 0, 8], fontSize: 14},
},
grid: {
left: 50, right: 0
},
tooltip: {
trigger: 'axis', backgroundColor: 'rgba(14, 51, 111, 0.9)', borderColor: '#1A6ABC',
textStyle: {color: '#fff'}
},
daemon: color => ({
showSymbol: false,
lineStyle: {shadowBlur: 4, shadowOffsetY: 2},
areaStyle: {
color: {
type: 'linear', x: 0, x2: 0, y: 0, y2: 1, colorStops: [
{offset: 0, color: tools.$colorUtils.Hex2RGBA(color, .5)},
{offset: 1, color: tools.$colorUtils.Hex2RGBA(color, 0)},
]
}
}
})
}

View File

@@ -1,16 +0,0 @@
export default {
legend: {
right: 0, itemGap: 16,
textStyle: {color: '#fff', padding: [0, 0, 0, 8], fontSize: 14},
},
grid: {
left: 50, right: 0
},
tooltip: {
trigger: 'axis', backgroundColor: 'rgba(14, 51, 111, 0.9)', borderColor: '#1A6ABC',
textStyle: {color: '#fff'}
},
daemon: {
lineStyle: {shadowBlur: 4, shadowOffsetY: 2},
}
}

View File

@@ -1,19 +0,0 @@
export default {
legend: {
right: 0, itemGap: 16,
textStyle: {color: '#fff', padding: [0, 0, 0, 8], fontSize: 14},
},
grid: {
left: 50, right: 0
},
tooltip: {
trigger: 'axis', backgroundColor: 'rgba(14, 51, 111, 0.9)', borderColor: '#1A6ABC',
textStyle: {color: '#fff'}
},
daemon: {
lineStyle: {shadowBlur: 4, shadowOffsetY: 2},
emphasis: {
focus: 'self'
}
}
}

View File

@@ -1,31 +0,0 @@
import tools from "../tools";
export default {
legend: {show: false},
grid: {
left: 50, right: 0
},
tooltip: {
trigger: 'axis', backgroundColor: 'rgba(14, 51, 111, 0.9)', borderColor: '#1A6ABC',
textStyle: {color: '#fff'},
axisPointer: {type: 'cross'}
},
yAxis: {
nameGap: 23, minInterval: 1,
splitLine: {lineStyle: {color: 'rgba(255,255,255,.2)', type: 'dashed'}},
axisLabel: {color: '#fff'},
axisPointer: {snap: true}
},
daemon: color=> ({
showSymbol: false, smooth: true,
lineStyle: {shadowBlur: 4, shadowOffsetY: 2},
areaStyle: {
color: {
type: 'linear', x: 0, x2: 0, y: 0, y2: 1, colorStops: [
{offset: 0, color: tools.$colorUtils.Hex2RGBA(color, .5)},
{offset: 1, color: tools.$colorUtils.Hex2RGBA(color, 0)},
]
}
}
})
}

View File

@@ -1,96 +0,0 @@
export default {
legend: {
bottom: 0,
itemGap: 14,
itemWidth: 16,
itemHeight: 5,
textStyle: {color: "#fff", fontSize: 14}
},
grid: {
height: 260
},
xAxis: {show: false},
yAxis: {show: false},
tooltip: {
backgroundColor: "rgba(14, 51, 111, 0.9)",
borderColor: "#1A6ABC",
textStyle: {color: "#fff"}
},
series: {
type: "pie",
minShowLabelAngle: 10,
radius: [70, 81],
itemStyle: {
borderColor: "#fff",
borderWidth: 2
},
label: {
color: "#A8D7F3",
fontSize: 14,
formatter: "{name|{b}}\n{v|{d}%}",
minMargin: 5,
edgeDistance: 10,
lineHeight: 22,
rich: {
v: {
color: "#fff"
}
}
},
labelLine: {},
labelLayout: function (params) {
let points = params.labelLinePoints,
isLeft = points[2][0] < points[1][0]
points[2][0] =
points[2][0] + (params.labelRect.width + 4) * (isLeft ? -1 : 1)
return {
labelLinePoints: points
}
}
},
render: (h, params) => {
const formatNum = num => {
if (num >= 10000000) {
return num / 10000000 + "千万"
}
if (num >= 10000) {
return num / 10000 + "万"
}
return parseFloat(num.toFixed(2))
}
let total = params.data.reduce((t, e) => {
return t + Number(Object.values(e)?.[1] || 0)
}, 0)
return h(
"div",
{
style: {
height: "162px",
width: "162px",
color: "#8BCCFF",
left: "50%",
top: "50%",
display: "flex",
alignItems: "center",
justifyContent: "center",
flexDirection: "column",
position: "absolute",
transform: "translate(-50%,-50%)",
backgroundImage: `url('https://cdn.cunwuyun.cn/dvcp/dv/tpl/pie2Circle.png')`,
backgroundPosition: "center"
}
},
[
h(
"span",
{style: {fontSize: "28px", color: "#fff", fontFamily: "DIN"}},
formatNum(total)
),
h("span", null, "总量")
]
)
}
}

View File

@@ -1,24 +0,0 @@
export default {
$colorUtils: {
Hex2RGBA(color, alpha = 1) {
let hex = 0;
if (color.charAt(0) == "#") {
if (color.length == 4) {
//检测诸如#FFF简写格式
color = "#" + color.charAt(1).repeat(2) +
color.charAt(2).repeat(2) +
color.charAt(3).repeat(2);
}
hex = parseInt(color.slice(1), 16);
}
let r = hex >> 16 & 0xFF;
let g = hex >> 8 & 0xFF;
let b = hex & 0xFF;
return `rgba(${r},${g},${b},${alpha})`;
},
RGBtoHex(r, g, b) {
let hex = r << 16 | g << 8 | b;
return "#" + hex.toString(16);
}
}
}

View File

@@ -1,48 +0,0 @@
<template>
<section class="AiMonitor">
<template v-if="type=='cmcc'">
<iframe :src="src" allow="autoplay *; microphone *; fullscreen *" allowfullscreen allowtransparency
allowusermedia frameBorder="no"/>
</template>
<hikversion-monitor v-else-if="type=='hik'" :src="src"/>
<dhVideo v-else-if="type=='dahua'" :src="src"/>
<slwVideo v-else-if="type=='slw'" :src="src"/>
</section>
</template>
<script>
import HikversionMonitor from "./hikversionMonitor";
import dhVideo from "./dhVideo";
import slwVideo from "./slwVideo";
export default {
name: "AiMonitor",
components: {HikversionMonitor, dhVideo, slwVideo},
props: {
/**
* 视频源
*/
src: {default: ""},
/**
* 组件类型
* cmcc 中移物联,hik 海康威视
* @values cmcc,hik
*/
type: {default: "cmcc"},
}
}
</script>
<style lang="scss" scoped>
.AiMonitor {
width: 100%;
height: 100%;
min-width: 100px;
min-height: 60px;
iframe {
width: 100%;
height: 100%;
}
}
</style>

View File

@@ -1,81 +0,0 @@
<template>
<div class="dh-video" style="height: 100%;">
<video :id="id" autoplay class="video-js vjs-default-skin" style="width: 100%; height: 100%;" controls>
<source :src="src">
</video>
</div>
</template>
<script>
import videojs from 'video.js'
import 'videojs-contrib-hls'
import 'video.js/dist/video-js.css'
export default {
props: ['src'],
data () {
return {
isInit: false,
id: `video-${Math.ceil(Math.random() * 1000000)}`
}
},
watch: {
src: {
handler(val) {
if (val) {
this.$nextTick(() => {
videojs(this.id, {
autoplay: true
}, function () { console.log('videojs播放器初始化成功') })
})
}
},
immediate: true,
deep: true
}
},
mounted () {
if (this.src) {
this.$nextTick(() => {
videojs(this.id, {
autoplay: true
}, function () {
this.isInit = true
console.log('videojs播放器初始化成功')
})
})
}
}
}
</script>
<style lang="scss" scoped>
.dh-video {
width: 100%;
height: 100%;
.video-js {
width: 100%!important;
height: 100%!important;
}
::v-deep .video-js {
width: 100%!important;
height: 100%!important;
.vjs-big-play-button {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
& > div {
width: 100%!important;
height: 100%!important;
}
}
</style>

View File

@@ -1,169 +0,0 @@
<template>
<section class="hikversionMonitor">
<div id="monitorIns">
<el-link v-if="needSetupPlugin" href="https://cdn.cunwuyun.cn/wsr/lib/VideoWebPlugin.exe" type="primary">
请检查是否安装视频插件,如果没有请点击下载视频插件并安装
</el-link>
<div v-else>视频插件未启动正在尝试启动请稍候...</div>
</div>
</section>
</template>
<script>
export default {
name: "hikversionMonitor",
props: {
src: {default: ""},
list: {default: () => []}
},
data() {
return {
monitorIns: null,
initCount: 0
}
},
computed: {
needSetupPlugin() {
return this.initCount >= 3
}
},
methods: {
getMonitorWidth() {
let {width} = document.querySelector("#monitorIns")?.getBoundingClientRect()
return width
},
getMonitorHeight() {
let {height} = document.querySelector("#monitorIns")?.getBoundingClientRect()
return height
},
initSDK() {
this.$nextTick(() => {
let width = this.getMonitorWidth(), height = this.getMonitorHeight()
if (width) {
this.monitorIns = new WebControl({
szPluginContainer: "monitorIns", // 指定容器id
iServicePortStart: 15900, // 指定起止端口号,建议使用该值
iServicePortEnd: 15909,
szClassId: "23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用于IE10使用ActiveX的clsid
cbConnectSuccess: () => { // 创建WebControl实例成功
this.monitorIns.JS_StartService("window", { // WebControl实例创建成功后需要启动服务
dllPath: "./VideoPluginConnect.dll" // 值"./VideoPluginConnect.dll"写死
}).then(() => { // 启动插件服务成功
this.monitorIns.JS_CreateWnd("monitorIns", width, height).then(() => { //JS_CreateWnd创建视频播放窗口宽高可设定
this.monitorIns.JS_RequestInterface({
funcName: "getRSAPubKey",
argument: JSON.stringify({
keyLength: 1024
})
}).then((oData) => {
if (oData.responseMsg.data) {
let encrypt = new JSEncrypt();
encrypt.setPublicKey(oData.responseMsg.data);
let secret = encrypt.encrypt("JSqHo9JUgPLQxfCIjsmQ");
this.monitorIns.JS_RequestInterface({
funcName: "init",
argument: JSON.stringify({
appkey: "23335895", //API网关提供的appkey
secret, //API网关提供的secret
ip: "124.128.246.74", //API网关IP地址
playMode: 0, //初始播放模式0-预览1-回放
port: 1443, //端口
snapDir: ".", //抓图存储路径
videoDir: ".", //紧急录像或录像剪辑存储路径
layout: "1x1", //布局
enableHTTPS: 1, //是否启用HTTPS协议
encryptedFields: "secret", //加密字段
showToolbar: 1, //是否显示工具栏
showSmart: 1, //是否显示智能信息
buttonIDs: "0,16,256,257,258,259,260,512,513,514,515,516,517,768,769" //自定义工具条按钮
})
}).then(() => {
this.monitorIns.JS_Resize(width, height); // 初始化后resize一次规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
this.startPreview()
})
}
})
});
}, (...args) => {
// 启动插件服务失败
console.log(args)
})
},
cbConnectError: () => {
this.monitorIns = null
WebControl.JS_WakeUp("VideoWebPlugin://");
this.initCount++
if (!this.needSetupPlugin) {
setTimeout(() => {
this.initSDK()
}, 3000)
}
}
})
}
})
},
startPreview() {
const layout = len =>
len <= 1 ? '1x1' :
len == 2 ? '1x2' :
len == 3 ? '1+2' :
len == 4 ? '2x2' :
len < 6 ? '1+5' :
len == 7 ? '3+4' :
len == 8 ? '1+7' :
len == 9 ? '3x3' :
len == 10 ? '1+9' :
len <= 16 ? '4x4' : '4x6'
let list = this.src?.split(",")
this.monitorIns?.JS_RequestInterface({
funcName: "setLayout",
argument: JSON.stringify({layout: layout(list.length)})
}).then(() => {
this.monitorIns?.JS_RequestInterface({
funcName: "startMultiPreviewByCameraIndexCode",
argument: JSON.stringify({
list: list.map((cameraIndexCode, i) => ({
cameraIndexCode, //监控点编号
streamMode: 0, //主子码流标识
transMode: 1, //传输协议
gpuMode: 0, //是否开启GPU硬解
wndId: i + 1 //可指定播放窗口
}))
})
})
})
},
},
watch: {
src(v) {
v && this.monitorIns?.JS_RequestInterface({funcName: "stopAllPreview"}).then(() => this.startPreview())
}
},
mounted() {
this.$injectLib("https://cdn.cunwuyun.cn/wsr/lib/jsencrypt.min.js")
this.$injectLib("https://cdn.cunwuyun.cn/wsr/lib/jsWebControl-1.0.0.min.js", () => {
this.initSDK()
})
},
beforeDestroy() {
this.monitorIns?.JS_DestroyWnd()
}
}
</script>
<style lang="scss" scoped>
.hikversionMonitor {
color: #fff;
height: 100%;
#monitorIns {
height: 100%;
background: #000;
display: flex;
justify-content: center;
align-items: center;
}
}
</style>

View File

@@ -1,90 +0,0 @@
<template>
<div class="slw">
<iframe
v-if="isShow"
:id="id"
allow="autoplay *; microphone *; fullscreen *" allowfullscreen allowtransparency key="" allowusermedia frameBorder="no"
style="width: 100%; height: 100%;"
:src="`https://cdn.cunwuyun.cn/jssdk/slw/index.html?url=${src}`"></iframe>
</div>
</template>
<script>
export default {
props: ['src'],
name: 'slwVideo',
data () {
return {
isShow: true,
id: `video-${new Date().getTime()}`
}
},
watch: {
src: {
handler (val) {
if (val) {
this.isShow = false
this.$nextTick(() => {
this.isShow = true
})
}
},
immediate: true,
deep: true
}
},
mounted () {
window.addEventListener('message', e => {
if (e.data.type && e.data.name === 'fullscreen') {
this.requestFullScreen(document.getElementById(this.id))
}
if (!e.data.type && e.data.name === 'fullscreen') {
this.exitFullscreen()
}
}, false)
},
methods: {
exitFullscreen () {
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.msExitFullscreen) {
document.msExitFullscreen()
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen()
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen()
}
},
requestFullScreen (element) {
var requestMethod = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || element.msRequestFullScreen;
if (requestMethod) {
requestMethod.call(element);
} else if (typeof window.ActiveXObject !== 'undefined') {
var wscript = new ActiveXObject('WScript.Shell')
if (wscript !== null) {
wscript.SendKeys('{F11}')
}
}
}
}
}
</script>
<style lang="scss" scoped>
.slw {
width: 100%;
height: 100%;
iframe {
border: none;
}
}
</style>

File diff suppressed because one or more lines are too long

View File

@@ -1,92 +0,0 @@
<template>
<div class="swiper">
<el-carousel height="100%" indicator-position="none">
<el-carousel-item v-for="(item, index) in data" :key="index">
<img :src="item.img">
<div class="swiper-content" v-if="item.title">
<h2>{{ item.title }}</h2>
<p>{{ item.content }}</p>
</div>
</el-carousel-item>
</el-carousel>
</div>
</template>
<script>
export default {
name: 'AiSwiper',
props: {
data: {
type: Array,
default: () => []
},
width: {
type: String,
default: '100%'
},
heigth: {
type: String,
default: '100%'
}
},
data () {
return {
}
},
mounted () {
},
methods: {
}
}
</script>
<style lang="scss" scoped>
.swiper {
width: 100%;
height: 100%;
padding: 20px 0 0;
::v-deep .el-carousel {
height: 100%;
}
img {
width: 100%;
height: 100%;
}
.swiper-content {
position: absolute;
bottom: 0;
left: 0;
z-index: 1;
width: 100%;
padding: 10px;
text-align: center;
background: linear-gradient(180deg, rgba(0, 0, 0, 0.1) 0%, #000000 100%);
h2 {
margin-bottom: 4px;
color: #fff;
text-align: center;
font-size: 18px;
}
p {
line-height: 22px;
white-space: pre-line;
color: #B6DFFF;
font-size: 14px;
text-align: center;
}
}
}
</style>

View File

@@ -1,30 +0,0 @@
const apps = []
const install = function (Vue) {
if (install.installed) return Promise.resolve()
else {
let contexts = require.context('.', true, /(\/.+)\/Ai[^\/]+\.vue$/)
if (contexts) {
contexts.keys().map(e => {
if (contexts(e).default) {
let mod = apps.find(a => a.name == contexts(e).default.name)
if (mod) {
mod.component = contexts(e).default
} else {
apps.push({name: contexts(e).default.name, component: contexts(e).default})
}
}
})
}
apps.map(e => {
Vue.component(e.name, e.component)
})
}
}
// 判断是否是直接引入文件
if (typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
export default {
// 导出的对象必须具有 install才能被 Vue.use() 方法安装
install
}

View File

@@ -1,32 +0,0 @@
<template>
<section class="AiDvBackground" :style="{opacity:alpha}">
<img class="bgImage" :src="src"/>
</section>
</template>
<script>
export default {
name: "AiDvBackground",
props: {
src: String,
alpha: {default: 1}
}
}
</script>
<style lang="scss" scoped>
.AiDvBackground {
top: 0;
left: 0;
bottom: 0;
right: 0;
position: absolute;
pointer-events: none;
//z-index: -1;
.bgImage {
width: 100%;
height: 100%;
}
}
</style>

View File

@@ -1,131 +0,0 @@
<template>
<section class="AiDvDisplay">
<div class="display-top">
<img class="left" src="https://cdn.cunwuyun.cn/dvcp/dv/img/display-icon.svg">
<h2>{{ title }}</h2>
<img class="right" src="https://cdn.cunwuyun.cn/dvcp/dv/img/display-icon.svg">
</div>
<component class="background" :is="type"/>
<div class="displayPanel">
<div class="animation">
<component class="item" v-for="(op,i) in list" :key="i" :is="item" v-bind="op" :style="{transform:getPos(i)}"/>
</div>
</div>
</section>
</template>
<script>
import Display0 from './components/Display0'
import DisplayItem from "./components/displayItem";
export default {
name: 'AiDvDisplay',
components: {DisplayItem, Display0},
props: {
type: {default: 'display0'},
item: {default: 'DisplayItem'},
title: {
default: '数据统计'
},
list: {default: () => []},
},
data () {
return {
}
},
methods: {
getPos(i) {
let unit = this.list.length > 0 ? 2 * Math.PI / this.list.length : 0,
corner = this.list.length > 0 ? 360 / this.list.length : 0
return `translateZ(${250 * Math.cos(unit * i)}px) translateX(${250 * Math.sin(unit * i)}px) rotateY(${corner * i}deg)`
}
}
}
</script>
<style lang="scss" scoped>
.AiDvDisplay {
position: relative;
width: 100%;
height: 100%;
.display-top {
position: relative;
width: 840px;
background-image: url(asset/display-top.svg);
background-size: 1420px 142px;
background-position: center;
text-align: center;
overflow: hidden;
.left {
position: absolute;
left: 280px;
top: 50%;
z-index: 1;
width: 35px;
height: 22px;
background-image: url(asset/display-icon.svg);
background-size: 100% 100%;
transform: translate(0, -50%);
}
.right {
position: absolute;
right: 280px;
top: 50%;
z-index: 1;
width: 35px;
height: 22px;
background-image: url(asset/display-icon.svg);
background-size: 100% 100%;
transform: translate(0, -50%) rotate(180deg);
transform-origin: center;
}
h2 {
line-height: 75px;
margin: 0;
font-size: 36px;
color: #FFFFFF;
text-shadow: 0px 4px 20px #345FFF;
background: linear-gradient(180deg, #FFFFFF 0%, #A1E4FF 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.displayPanel {
position: absolute;
width: 160px;
height: 160px;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
z-index: 9;
.animation {
animation: rotate3D 30s infinite linear;
transform-style: preserve-3d;
&:hover {
animation-play-state: paused;
}
}
.item {
position: absolute;
}
}
}
@keyframes rotate3D {
from {
transform: rotateY(0deg);
}
to {
transform: rotateY(360deg);
}
}
</style>

View File

@@ -1,25 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="35px" height="22px" viewBox="0 0 35 22" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>形状结合</title>
<defs>
<path d="M1072,220 L1072,228 L1068,224 L1072,220 Z M1064,220 L1064,228 L1060,224 L1064,220 Z M1056,220 L1056,228 L1052,224 L1056,220 Z" id="path-1"></path>
<filter x="-60.0%" y="-150.0%" width="220.0%" height="400.0%" filterUnits="objectBoundingBox" id="filter-2">
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="4" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 1 0 0 0 0 0.760001846 0 0 0 0 0.291006098 0 0 0 1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
<filter x="-50.0%" y="-125.0%" width="200.0%" height="350.0%" filterUnits="objectBoundingBox" id="filter-3">
<feGaussianBlur stdDeviation="2" in="SourceAlpha" result="shadowBlurInner1"></feGaussianBlur>
<feOffset dx="0" dy="0" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
<feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
<feColorMatrix values="0 0 0 0 1 0 0 0 0 0.97961238 0 0 0 0 0.9078125 0 0 0 1 0" type="matrix" in="shadowInnerInner1"></feColorMatrix>
</filter>
</defs>
<g id="钟祥大屏" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="形状结合" transform="translate(-1045.000000, -213.000000)">
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
<use fill="#FFC143" fill-rule="evenodd" xlink:href="#path-1"></use>
<use fill="black" fill-opacity="1" filter="url(#filter-3)" xlink:href="#path-1"></use>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,36 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="1478px" height="142px" viewBox="0 0 1478 142" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 2</title>
<defs>
<linearGradient x1="100%" y1="50%" x2="0%" y2="50%" id="linearGradient-1">
<stop stop-color="#5A86FF" stop-opacity="0" offset="0%"></stop>
<stop stop-color="#5AACFF" offset="36.7624563%"></stop>
<stop stop-color="#7EEFFF" offset="50.0376124%"></stop>
<stop stop-color="#5AACFF" offset="62.9709649%"></stop>
<stop stop-color="#5A86FF" offset="100%"></stop>
</linearGradient>
<path d="M547,0.25 C556.749607,0.25 565.858022,4.76380868 571.818048,12.456132 L572.118303,12.85 C577.460114,19.9724141 585.628339,24.4148226 594.493503,25.038944 L594.977736,25.069194 L800,39.9977736 L594.814342,27.814741 C585.045723,27.2819072 576.001062,22.5266807 570.024678,14.8021845 L569.718303,14.4 C564.430381,7.34943641 556.184331,3.14910303 547.389942,3.00389299 L547,3 C483.876874,3 434.876874,3 400,3 C365.099096,3 316.099096,3 253,3 C244.186796,3 235.797203,7.07663928 230.404401,14.0250247 L230.118303,14.4 C224.248419,22.2265123 215.269839,27.1053605 205.52688,27.7834215 L205.022264,27.814741 L0,39.9977736 L204.858871,25.069194 C213.748674,24.5842957 221.980256,20.260414 227.424142,13.235831 L227.718303,12.85 C233.568068,5.05031402 242.693181,0.406510872 252.423056,0.253884 L253,0.25 C316.068383,0.0833333333 365.068383,3.55271368e-15 400,3.55271368e-15 C434.846161,3.55271368e-15 483.846161,0.0833333333 547,0.25 Z" id="path-2"></path>
<filter x="-45.4%" y="-147.5%" width="190.9%" height="479.4%" filterUnits="objectBoundingBox" id="filter-3">
<feMorphology radius="1" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1"></feMorphology>
<feOffset dx="0" dy="8" in="shadowSpreadOuter1" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="20" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 0 0 0 0 0 0.254665854 0 0 0 0 0.715268342 0 0 0 1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
<linearGradient x1="0%" y1="49.1111111%" x2="100%" y2="50%" id="linearGradient-4">
<stop stop-color="#0085FF" stop-opacity="0.502840909" offset="0%"></stop>
<stop stop-color="#0085FF" stop-opacity="0" offset="100%"></stop>
</linearGradient>
</defs>
<g id="钟祥大屏" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="公共招聘" transform="translate(-221.000000, -146.000000)">
<g id="编组-2" transform="translate(560.000000, 180.000000)">
<g id="路径-3备份" fill-rule="nonzero">
<use fill="black" fill-opacity="1" filter="url(#filter-3)" xlink:href="#path-2"></use>
<use fill="url(#linearGradient-1)" xlink:href="#path-2"></use>
</g>
<path d="M190.442478,46.7350415 L194.690265,47.0710935 L200,54 L195.752212,53.663948 L190.442478,46.7350415 Z M181.946903,46.0629376 L186.19469,46.3989895 L191.504425,53.3278961 L187.256637,52.9918441 L181.946903,46.0629376 Z M173.451327,45.3919885 L177.699115,45.7280404 L183.00885,52.656947 L178.761062,52.320895 L173.451327,45.3919885 Z M164.955752,44.7198845 L169.20354,45.0559365 L174.513274,51.984843 L170.265487,51.6487911 L164.955752,44.7198845 Z M156.460177,44.0489354 L160.707965,44.3849874 L166.017699,51.3138939 L161.769912,50.9778419 L156.460177,44.0489354 Z M147.964602,43.3768315 L152.212389,43.7128834 L157.522124,50.64179 L153.274336,50.305738 L147.964602,43.3768315 Z M139.469027,42.7047275 L143.716814,43.0407795 L149.026549,49.969686 L144.778761,49.6336341 L139.469027,42.7047275 Z M130.973451,42.0326236 L135.221239,42.3686756 L140.530973,49.2975821 L136.283186,48.9615301 L130.973451,42.0326236 Z M122.477876,41.3605197 L126.725664,41.6965716 L132.035398,48.6254782 L127.787611,48.2894262 L122.477876,41.3605197 Z M113.982301,40.6884157 L118.230088,41.0244677 L123.539823,47.9533742 L119.292035,47.6173223 L113.982301,40.6884157 Z M105.486726,40.0163118 L109.734513,40.3523638 L115.044248,47.2812703 L110.79646,46.9452183 L105.486726,40.0163118 Z M96.9911504,39.3442079 L101.238938,39.6802598 L106.548673,46.6091664 L102.300885,46.2731144 L96.9911504,39.3442079 Z M88.4955752,38.6721039 L92.7433628,39.0081559 L98.0530973,45.9370624 L93.8053097,45.6010105 L88.4955752,38.6721039 Z M80,38 L84.2477876,38.336052 L89.5575221,45.2649585 L85.3097345,44.9289065 L80,38 Z" id="形状" fill="url(#linearGradient-4)" transform="translate(140.000000, 46.000000) scale(-1, 1) translate(-140.000000, -46.000000) "></path>
<path d="M710.442478,46.7350415 L714.690265,47.0710935 L720,54 L715.752212,53.663948 L710.442478,46.7350415 Z M701.946903,46.0629376 L706.19469,46.3989895 L711.504425,53.3278961 L707.256637,52.9918441 L701.946903,46.0629376 Z M693.451327,45.3919885 L697.699115,45.7280404 L703.00885,52.656947 L698.761062,52.320895 L693.451327,45.3919885 Z M684.955752,44.7198845 L689.20354,45.0559365 L694.513274,51.984843 L690.265487,51.6487911 L684.955752,44.7198845 Z M676.460177,44.0489354 L680.707965,44.3849874 L686.017699,51.3138939 L681.769912,50.9778419 L676.460177,44.0489354 Z M667.964602,43.3768315 L672.212389,43.7128834 L677.522124,50.64179 L673.274336,50.305738 L667.964602,43.3768315 Z M659.469027,42.7047275 L663.716814,43.0407795 L669.026549,49.969686 L664.778761,49.6336341 L659.469027,42.7047275 Z M650.973451,42.0326236 L655.221239,42.3686756 L660.530973,49.2975821 L656.283186,48.9615301 L650.973451,42.0326236 Z M642.477876,41.3605197 L646.725664,41.6965716 L652.035398,48.6254782 L647.787611,48.2894262 L642.477876,41.3605197 Z M633.982301,40.6884157 L638.230088,41.0244677 L643.539823,47.9533742 L639.292035,47.6173223 L633.982301,40.6884157 Z M625.486726,40.0163118 L629.734513,40.3523638 L635.044248,47.2812703 L630.79646,46.9452183 L625.486726,40.0163118 Z M616.99115,39.3442079 L621.238938,39.6802598 L626.548673,46.6091664 L622.300885,46.2731144 L616.99115,39.3442079 Z M608.495575,38.6721039 L612.743363,39.0081559 L618.053097,45.9370624 L613.80531,45.6010105 L608.495575,38.6721039 Z M600,38 L604.247788,38.336052 L609.557522,45.2649585 L605.309735,44.9289065 L600,38 Z" id="形状" fill="url(#linearGradient-4)"></path>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 500 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="128px" height="128px" viewBox="0 0 128 128" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 3</title>
<defs>
<linearGradient x1="100%" y1="0%" x2="0%" y2="100%" id="linearGradient-1">
<stop stop-color="#00DDF2" stop-opacity="0" offset="0%"></stop>
<stop stop-color="#00E0C9" offset="100%"></stop>
</linearGradient>
<linearGradient x1="0%" y1="0%" x2="100%" y2="100%" id="linearGradient-2">
<stop stop-color="#FFE457" stop-opacity="0" offset="0%"></stop>
<stop stop-color="#FFDC2C" offset="100%"></stop>
</linearGradient>
<linearGradient x1="0%" y1="0%" x2="100%" y2="100%" id="linearGradient-3">
<stop stop-color="#FFDC2C" offset="0%"></stop>
<stop stop-color="#FFE457" stop-opacity="0" offset="100%"></stop>
</linearGradient>
<linearGradient x1="100%" y1="0%" x2="0%" y2="100%" id="linearGradient-4">
<stop stop-color="#00E0C9" offset="0%"></stop>
<stop stop-color="#00DDF2" stop-opacity="0" offset="100%"></stop>
</linearGradient>
</defs>
<g id="大屏" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="农产品推荐" transform="translate(-896.000000, -416.000000)" fill-rule="nonzero">
<g id="编组-13" transform="translate(880.000000, 400.000000)">
<g id="编组-3" transform="translate(22.000000, 22.000000)">
<path d="M122,58 C122,92.9927617 93.9164341,121.426255 59.058357,121.991426 L58,122 L58,110 C86.4316189,110 109.533832,87.1821027 109.993033,58.8599151 L110,58 L122,58 Z" id="路径" fill="url(#linearGradient-1)"></path>
<path d="M58,-6 C92.9927617,-6 121.426255,22.0835659 121.991426,56.941643 L122,58 L110,58 C110,29.5683811 87.1821027,6.46616762 58.8599151,6.00696651 L58,6 L58,-6 Z" id="路径" fill="url(#linearGradient-2)"></path>
<path d="M6,58 C6,86.4316189 28.8178973,109.533832 57.1400849,109.993033 L58,110 L58,122 C23.0072383,122 -5.42625523,93.9164341 -5.99142583,59.058357 L-6,58 L6,58 Z" id="路径" fill="url(#linearGradient-3)"></path>
<path d="M58,-6 L58,6 C29.5683811,6 6.46616762,28.8178973 6.00696651,57.1400849 L6,58 L-6,58 C-6,23.0072383 22.0835659,-5.42625523 56.941643,-5.99142583 L58,-6 Z" id="路径" fill="url(#linearGradient-4)"></path>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -1,49 +0,0 @@
<template>
<div class="display0">
<div class="display0-container">
<div class="display0-content">
<img src="https://cdn.cunwuyun.cn/dvcp/dv/img/display0-left.png">
<img src="https://cdn.cunwuyun.cn/dvcp/dv/img/display0-left.png">
</div>
</div>
</div>
</template>
<script>
export default {
name: 'display0',
data () {
return {
}
}
}
</script>
<style lang="scss" scoped>
.display0 {
position: relative;
width: 840px;
height: 465px;
background: url(./../asset/display0-bg.png) no-repeat center;
background-size: cover;
.display0-content {
display: flex;
position: absolute;
top: 50%;
width: 100%;
height: 465px;
transform: translateY(-50%);
align-items: center;
justify-content: space-between;
background: url(./../asset/display0-bg.png) no-repeat center;
background-size: cover;
img:last-child {
position: relative;
transform: rotate(180deg);
}
}
}
</style>

View File

@@ -1,64 +0,0 @@
<template>
<section class="displayItem">
<span class="num" v-text="value"/>
<span v-text="label"/>
</section>
</template>
<script>
export default {
name: "displayItem",
props: {
label: {default: "标题"},
value: {default: 0},
}
}
</script>
<style lang="scss" scoped>
.displayItem {
width: 160px;
height: 160px;
color: #fff;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 15px;
font-weight: bold;
line-height: 26px;
position: relative;
background-image: url("./../asset/displayItem-bg.svg");
background-repeat: no-repeat;
background-position: center;
&:before {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
content: " ";
background-image: url("./../asset/displayItem-bg1.svg");
background-repeat: no-repeat;
background-position: center;
animation: rotate 4s infinite linear;
background-color: transparent;
}
.num {
font-family: DIN;
font-size: 32px;
line-height: 32px;
}
}
@keyframes rotate {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
</style>

View File

@@ -1,41 +0,0 @@
<template>
<section class="AiDvPanel">
<component :is="border" :title="title" v-if="border">
<template v-if="$slots.title" #title>
<slot name="title"/>
</template>
<slot/>
</component>
<slot style="width: 100%; height: 100%;" v-else></slot>
</section>
</template>
<script>
import Border1 from "./borders/border1";
import Border0 from "./borders/border0";
import Border2 from "./borders/border2";
import Border3 from "./borders/border3";
import Border4 from "./borders/border4";
import Border5 from "./borders/border5";
export default {
name: "AiDvPanel",
components: { Border0, Border1, Border2, Border3, Border4, Border5 },
props: {
title: {default: "请传入标题"},
border: {default: "border0"}
},
mounted() {
},
}
</script>
<style lang="scss" scoped>
.AiDvPanel {
height: 100%;
* {
box-sizing: border-box;
}
}
</style>

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="560px" height="280px" version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>矩形备份 58</title>
<defs>
<polygon id="path-1" points="680 760 690 750 1230 750 1240 760 1240 1020 1230 1030 690 1030 680 1020"></polygon>
<filter x="-2.7%" y="-5.4%" width="105.4%" height="110.7%" filterUnits="objectBoundingBox" id="filter-2">
<feMorphology radius="10" operator="erode" in="SourceAlpha" result="shadowSpreadInner1"></feMorphology>
<feGaussianBlur stdDeviation="10" in="shadowSpreadInner1" result="shadowBlurInner1"></feGaussianBlur>
<feOffset dx="0" dy="0" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
<feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1"
result="shadowInnerInner1"></feComposite>
<feColorMatrix values="0 0 0 0 0.239634146 0 0 0 0 0.473717493 0 0 0 0 1 0 0 0 1 0" type="matrix"
in="shadowInnerInner1"></feColorMatrix>
</filter>
</defs>
<g id="钟祥大屏" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" opacity="0.5">
<g id="矩形备份-58" transform="translate(-680.000000, -750.000000)">
<use fill="#0B2949" fill-rule="evenodd" xlink:href="#path-1"></use>
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,82 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="166px" height="48px" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 8</title>
<defs>
<polygon id="path-1" points="1 0 165 0 165 31 155 40 11 40 1 31"></polygon>
<filter x="-4.6%" y="-18.8%" width="109.1%" height="137.5%" filterUnits="objectBoundingBox" id="filter-2">
<feMorphology radius="5" operator="erode" in="SourceAlpha" result="shadowSpreadInner1"></feMorphology>
<feGaussianBlur stdDeviation="5" in="shadowSpreadInner1" result="shadowBlurInner1"></feGaussianBlur>
<feOffset dx="0" dy="0" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
<feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
<feColorMatrix values="0 0 0 0 0.0340090302 0 0 0 0 0.105477684 0 0 0 0 0.340155118 0 0 0 1 0" type="matrix" in="shadowInnerInner1"></feColorMatrix>
</filter>
<polygon id="path-3" points="72 4 94 4 98 0 68 0"></polygon>
<filter x="-20.0%" y="-150.0%" width="140.0%" height="400.0%" filterUnits="objectBoundingBox" id="filter-4">
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="2" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 1 0 0 0 0 0.607194757 0 0 0 0 0.291006098 0 0 0 1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
<filter x="-20.0%" y="-150.0%" width="140.0%" height="400.0%" filterUnits="objectBoundingBox" id="filter-5">
<feGaussianBlur stdDeviation="2" in="SourceAlpha" result="shadowBlurInner1"></feGaussianBlur>
<feOffset dx="0" dy="0" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
<feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
<feColorMatrix values="0 0 0 0 1 0 0 0 0 0.97961238 0 0 0 0 0.9078125 0 0 0 1 0" type="matrix" in="shadowInnerInner1"></feColorMatrix>
</filter>
<polygon id="path-6" points="76 38 90 38 92 40 74 40"></polygon>
<filter x="-33.3%" y="-300.0%" width="166.7%" height="700.0%" filterUnits="objectBoundingBox" id="filter-7">
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="2" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 1 0 0 0 0 0.607194757 0 0 0 0 0.291006098 0 0 0 1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
<filter x="-33.3%" y="-300.0%" width="166.7%" height="700.0%" filterUnits="objectBoundingBox" id="filter-8">
<feGaussianBlur stdDeviation="2" in="SourceAlpha" result="shadowBlurInner1"></feGaussianBlur>
<feOffset dx="0" dy="0" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
<feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
<feColorMatrix values="0 0 0 0 1 0 0 0 0 0.97961238 0 0 0 0 0.9078125 0 0 0 1 0" type="matrix" in="shadowInnerInner1"></feColorMatrix>
</filter>
</defs>
<g id="钟祥大屏" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="画板" transform="translate(-878.000000, -726.000000)">
<g id="编组-8" transform="translate(878.000000, 730.000000)">
<g id="矩形">
<use fill-opacity="0.8" fill="#0B2949" fill-rule="evenodd" xlink:href="#path-1"></use>
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
</g>
<path d="M3,23 L1,20 L1,12.333 L0,11 L0,0 L30,0 L27,3 L17,3 L17,2 L11,2 L10,3 L3,3 L3,10 L5,10 L5,12 L3,12 L3,14 L5,14 L5,16 L3,16 L3,18 L5,18 L5,20 L3,20 L3,23 Z" id="形状结合" fill="#2B6EFF" fill-rule="nonzero"></path>
<path d="M139,23 L137,20 L137,12.333 L136,11 L136,0 L166,0 L163,3 L153,3 L153,2 L147,2 L146,3 L139,3 L139,10 L141,10 L141,12 L139,12 L139,14 L141,14 L141,16 L139,16 L139,18 L141,18 L141,20 L139,20 L139,23 Z" id="形状结合备份" fill="#2B6EFF" fill-rule="nonzero" transform="translate(151.000000, 11.500000) scale(-1, 1) translate(-151.000000, -11.500000) "></path>
<polygon id="矩形" fill="#51AAFF" points="38 0 42 0 40 2 36 2"></polygon>
<polygon id="矩形备份-74" fill="#51AAFF" transform="translate(127.000000, 1.000000) scale(-1, 1) translate(-127.000000, -1.000000) " points="126 0 130 0 128 2 124 2"></polygon>
<polygon id="矩形备份-64" fill="#51AAFF" points="32 0 36 0 34 2 30 2"></polygon>
<polygon id="矩形备份-75" fill="#51AAFF" transform="translate(121.000000, 1.000000) scale(-1, 1) translate(-121.000000, -1.000000) " points="120 0 124 0 122 2 118 2"></polygon>
<polygon id="矩形备份-61" fill="#51AAFF" points="44 0 48 0 46 2 42 2"></polygon>
<polygon id="矩形备份-76" fill="#51AAFF" transform="translate(133.000000, 1.000000) scale(-1, 1) translate(-133.000000, -1.000000) " points="132 0 136 0 134 2 130 2"></polygon>
<polygon id="矩形备份-62" fill="#2B6EFF" fill-rule="nonzero" points="50 0 66 0 69 3 47 3"></polygon>
<polygon id="矩形备份-73" fill="#2B6EFF" fill-rule="nonzero" points="100 0 116 0 119 3 97 3"></polygon>
<g id="矩形备份-63">
<use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-3"></use>
<use fill="#FFC143" fill-rule="evenodd" xlink:href="#path-3"></use>
<use fill="black" fill-opacity="1" filter="url(#filter-5)" xlink:href="#path-3"></use>
</g>
<polygon id="矩形备份-68" fill="#2B6EFF" points="28 37 39 37 39 40 25 40"></polygon>
<polygon id="矩形备份-79" fill="#2B6EFF" transform="translate(134.000000, 38.500000) scale(-1, 1) translate(-134.000000, -38.500000) " points="130 37 141 37 141 40 127 40"></polygon>
<polygon id="矩形备份-70" fill="#2B6EFF" transform="translate(56.500000, 38.500000) scale(-1, -1) translate(-56.500000, -38.500000) " points="56 37 60 37 57 40 53 40"></polygon>
<polygon id="矩形备份-81" fill="#2B6EFF" transform="translate(95.500000, 38.500000) scale(1, -1) translate(-95.500000, -38.500000) " points="95 37 99 37 96 40 92 40"></polygon>
<polygon id="矩形备份-71" fill="#2B6EFF" transform="translate(63.500000, 38.500000) scale(-1, -1) translate(-63.500000, -38.500000) " points="63 37 67 37 64 40 60 40"></polygon>
<polygon id="矩形备份-82" fill="#2B6EFF" transform="translate(102.500000, 38.500000) scale(1, -1) translate(-102.500000, -38.500000) " points="102 37 106 37 103 40 99 40"></polygon>
<polygon id="矩形备份-72" fill="#2B6EFF" transform="translate(70.500000, 38.500000) scale(-1, -1) translate(-70.500000, -38.500000) " points="70 37 74 37 71 40 67 40"></polygon>
<polygon id="矩形备份-83" fill="#2B6EFF" transform="translate(109.500000, 38.500000) scale(1, -1) translate(-109.500000, -38.500000) " points="109 37 113 37 110 40 106 40"></polygon>
<polygon id="矩形备份-65" fill="#2B6EFF" fill-rule="nonzero" points="4 32 10 37 16 37 18 40 10 40 1 32 1 28 0 26.6037002 0 23 4 28"></polygon>
<polygon id="矩形备份-77" fill="#2B6EFF" fill-rule="nonzero" transform="translate(157.000000, 31.500000) scale(-1, 1) translate(-157.000000, -31.500000) " points="152 32 158 37 164 37 166 40 158 40 149 32 149 28 148 26.6037002 148 23 152 28"></polygon>
<rect id="矩形" fill="#2B6EFF" x="16" y="39" width="20" height="1"></rect>
<rect id="矩形备份-78" fill="#2B6EFF" transform="translate(140.000000, 39.500000) scale(-1, 1) translate(-140.000000, -39.500000) " x="130" y="39" width="20" height="1"></rect>
<polygon id="矩形备份-69" fill="#2B6EFF" points="38 39 51 39 50 40 38 40"></polygon>
<polygon id="矩形备份-80" fill="#2B6EFF" transform="translate(121.500000, 39.500000) scale(-1, 1) translate(-121.500000, -39.500000) " points="115 39 128 39 127 40 115 40"></polygon>
<g id="矩形">
<use fill="black" fill-opacity="1" filter="url(#filter-7)" xlink:href="#path-6"></use>
<use fill="#FFC143" fill-rule="evenodd" xlink:href="#path-6"></use>
<use fill="black" fill-opacity="1" filter="url(#filter-8)" xlink:href="#path-6"></use>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -1,34 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="580px" height="40px" viewBox="0 0 580 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>矩形</title>
<defs>
<rect id="path-1" x="40" y="740" width="580" height="40"></rect>
<pattern id="pattern-2" width="12.0397351" height="12.0397351" x="27.9602649" y="727.960265" patternUnits="userSpaceOnUse">
<use xlink:href="#image-3" transform="scale(0.250827815,0.250827815)"></use>
</pattern>
<image id="image-3" width="48" height="48" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAMKADAAQAAAABAAAAMAAAAADbN2wMAAABX0lEQVRoBe3Y7Q2CMBAGYGu3gOgOJrAQcRAHUXcwrsEcrFH7agpB+ex5cJfQH9ISvfO5xkjP5Hnudn445+5lWZ4xxZo4TJZlV2NMEeJwxbdpml6QxCc7JUlyqKrqGZJSroiDeIjLGd/6JEfuJJzx7VKV4kJYbK9mxBugGVEDtCJaAI2IH4A2RCdAE6IXoAUxCNCAGAVIR0wCSEZMBkhFzAJIRMwGSENEASQhogFSECSABAQZsDYCAIMvQR1rHYqs7x7ckJwKwOfXQKAr8dDYjQhn7D0q5xcF+jiYYk0cDv0l9IFCHM74W18oVLnrusRvYusLdVX++x7nTtR/ZJxJAOKKXwM4k4Qd4UC0ABoRPwBtiE6AJkQvQAtiEKABMQqQjpgEkIyYDJCKmAWQiJgNkIaIAkhCRAOkIEgACQgyYG0EAP84yLM976NAGH2P4ltf6FOf5rWvUrjfvCt+9h3/BX5SBuUP9sYWAAAAAElFTkSuQmCC"></image>
<filter x="-0.3%" y="-5.0%" width="100.7%" height="110.0%" filterUnits="objectBoundingBox" id="filter-4">
<feOffset dx="0" dy="4" in="SourceAlpha" result="shadowOffsetInner1"></feOffset>
<feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
<feColorMatrix values="0 0 0 0 0.121683836 0 0 0 0 0.302967066 0 0 0 0 0.653362772 0 0 0 0.504234047 0" type="matrix" in="shadowInnerInner1" result="shadowMatrixInner1"></feColorMatrix>
<feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetInner2"></feOffset>
<feComposite in="shadowOffsetInner2" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner2"></feComposite>
<feColorMatrix values="0 0 0 0 0.333333333 0 0 0 0 0.476619275 0 0 0 0 0.862745098 0 0 0 1 0" type="matrix" in="shadowInnerInner2" result="shadowMatrixInner2"></feColorMatrix>
<feOffset dx="0" dy="-2" in="SourceAlpha" result="shadowOffsetInner3"></feOffset>
<feComposite in="shadowOffsetInner3" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner3"></feComposite>
<feColorMatrix values="0 0 0 0 0.22745098 0 0 0 0 0.344729535 0 0 0 0 0.588235294 0 0 0 0.250355114 0" type="matrix" in="shadowInnerInner3" result="shadowMatrixInner3"></feColorMatrix>
<feMerge>
<feMergeNode in="shadowMatrixInner1"></feMergeNode>
<feMergeNode in="shadowMatrixInner2"></feMergeNode>
<feMergeNode in="shadowMatrixInner3"></feMergeNode>
</feMerge>
</filter>
</defs>
<g id="钟祥大屏" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="矩形" transform="translate(-40.000000, -740.000000)">
<use fill-opacity="0.2" fill="#004CA0" fill-rule="evenodd" xlink:href="#path-1"></use>
<use fill-opacity="0.5" fill="url(#pattern-2)" fill-rule="evenodd" style="mix-blend-mode: multiply;" xlink:href="#path-1"></use>
<use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-1"></use>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>路径备份</title>
<defs>
<polygon id="path-1" points="1826 14 1826 15 1821 15 1821 20 1820 20 1820 14"></polygon>
<filter x="-150.0%" y="-150.0%" width="400.0%" height="400.0%" filterUnits="objectBoundingBox" id="filter-2">
<feMorphology radius="1" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1"></feMorphology>
<feOffset dx="0" dy="0" in="shadowSpreadOuter1" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="2" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 0.088934077 0 0 0 0 0.269903162 0 0 0 0 0.86962183 0 0 0 1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
</defs>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="头部导航备份" transform="translate(-1814.000000, -8.000000)" fill-rule="nonzero">
<g id="路径备份" transform="translate(1823.000000, 17.000000) scale(-1, 1) translate(-1823.000000, -17.000000) ">
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
<use fill="#E8F9FF" xlink:href="#path-1"></use>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="26px" height="36px" viewBox="0 0 26 36" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>矩形</title>
<defs>
<polygon id="path-1" points="606 756 610 760 606 764"></polygon>
<filter x="-412.5%" y="-259.3%" width="956.1%" height="618.6%" filterUnits="objectBoundingBox" id="filter-2">
<feMorphology radius="1.5" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1"></feMorphology>
<feOffset dx="0" dy="0" in="shadowSpreadOuter1" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="4" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 0.088934077 0 0 0 0 0.269903162 0 0 0 0 0.86962183 0 0 0 1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
</defs>
<g id="钟祥大屏" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="画板" transform="translate(-595.000000, -742.000000)" fill-rule="nonzero">
<g id="矩形" transform="translate(608.000000, 760.000000) scale(-1, 1) translate(-608.000000, -760.000000) ">
<use fill="black" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"></use>
<use fill="#E8F9FF" xlink:href="#path-1"></use>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1,59 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="528px" height="41px" viewBox="0 0 528 41" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>编组 2备份</title>
<defs>
<linearGradient x1="-1.11022302e-14%" y1="50%" x2="100%" y2="50%" id="linearGradient-1">
<stop stop-color="#0085FF" stop-opacity="0" offset="0%"></stop>
<stop stop-color="#0085FF" stop-opacity="0.502840909" offset="100%"></stop>
</linearGradient>
<polygon id="path-2" points="8 7 0 14 0 0"></polygon>
<filter x="-150.0%" y="-85.7%" width="400.0%" height="271.4%" filterUnits="objectBoundingBox" id="filter-3">
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="4" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 1 0 0 0 0 0.760001846 0 0 0 0 0.291006098 0 0 0 1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
<filter x="-125.0%" y="-71.4%" width="350.0%" height="242.9%" filterUnits="objectBoundingBox" id="filter-4">
<feGaussianBlur stdDeviation="2" in="SourceAlpha" result="shadowBlurInner1"></feGaussianBlur>
<feOffset dx="0" dy="0" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
<feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
<feColorMatrix values="0 0 0 0 1 0 0 0 0 0.97961238 0 0 0 0 0.9078125 0 0 0 1 0" type="matrix" in="shadowInnerInner1"></feColorMatrix>
</filter>
<polygon id="path-5" points="16 7 8 14 8 0"></polygon>
<filter x="-150.0%" y="-85.7%" width="400.0%" height="271.4%" filterUnits="objectBoundingBox" id="filter-6">
<feOffset dx="0" dy="0" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
<feGaussianBlur stdDeviation="4" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
<feColorMatrix values="0 0 0 0 1 0 0 0 0 0.760001846 0 0 0 0 0.291006098 0 0 0 1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
</filter>
<filter x="-125.0%" y="-71.4%" width="350.0%" height="242.9%" filterUnits="objectBoundingBox" id="filter-7">
<feGaussianBlur stdDeviation="2" in="SourceAlpha" result="shadowBlurInner1"></feGaussianBlur>
<feOffset dx="0" dy="0" in="shadowBlurInner1" result="shadowOffsetInner1"></feOffset>
<feComposite in="shadowOffsetInner1" in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowInnerInner1"></feComposite>
<feColorMatrix values="0 0 0 0 1 0 0 0 0 0.97961238 0 0 0 0 0.9078125 0 0 0 1 0" type="matrix" in="shadowInnerInner1"></feColorMatrix>
</filter>
<linearGradient x1="-1.11022302e-14%" y1="50%" x2="100%" y2="50%" id="linearGradient-8">
<stop stop-color="#0085FF" stop-opacity="0" offset="0%"></stop>
<stop stop-color="#0085FF" stop-opacity="0.502840909" offset="100%"></stop>
</linearGradient>
</defs>
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="饼图" transform="translate(-32.000000, -121.000000)">
<g id="编组-2备份" transform="translate(40.000000, 129.000000)">
<polygon id="矩形" fill="url(#linearGradient-1)" points="1 9 273 9 255 27 1 27"></polygon>
<g id="三角形" opacity="0.300000012">
<use fill="black" fill-opacity="1" filter="url(#filter-3)" xlink:href="#path-2"></use>
<use fill="#FFC143" fill-rule="evenodd" xlink:href="#path-2"></use>
<use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-2"></use>
</g>
<g id="三角形备份">
<use fill="black" fill-opacity="1" filter="url(#filter-6)" xlink:href="#path-5"></use>
<use fill="#FFC143" fill-rule="evenodd" xlink:href="#path-5"></use>
<use fill="black" fill-opacity="1" filter="url(#filter-7)" xlink:href="#path-5"></use>
</g>
<polygon id="矩形" fill="#0085FF" opacity="0.25" points="278 13 520 13 520 21 270 21"></polygon>
<polygon id="矩形" fill="#0085FF" opacity="0.100000001" points="270 21 520 21 520 29 262 29"></polygon>
<polygon id="矩形" fill="url(#linearGradient-8)" points="278 13 398 13 390 21 270 21"></polygon>
<polygon id="路径-3" fill="#0085FF" fill-rule="nonzero" opacity="0.5" points="520 11 520 13 278 13 258 33 1 33 1 31 257.17 31 277.18 11"></polygon>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.7 KiB

View File

@@ -1,42 +0,0 @@
<template>
<section class="border0">
<div class="title">
<slot v-if="$slots.title" name="title"/>
<b v-else v-text="title"/>
</div>
<div class="slot">
<slot />
</div>
</section>
</template>
<script>
export default {
name: "border0",
props: {title: String}
}
</script>
<style lang="scss" scoped>
.border0 {
height: 100%;
.title {
padding-left: 30px;
background-image: url("./../asset/titleBg.svg");
background-repeat: no-repeat;
height: 41px;
margin-bottom: 10px;
& > b {
font-size: 24px;
color: #fff;
line-height: 32px;
letter-spacing: 2px;
}
}
.slot {
height: calc(100% - 51px);
}
}
</style>

View File

@@ -1,65 +0,0 @@
<template>
<section class="border1">
<dv-border-box1 :color="['#2B6EFF']">
<div class="bg">
<div class="header" v-text="title"/>
<div class="slot">
<slot/>
</div>
</div>
</dv-border-box1>
</section>
</template>
<script>
import {borderBox1} from '@jiaminghi/data-view'
import Vue from "vue";
Vue.use(borderBox1)
export default {
name: "border1",
props: {title: String}
}
</script>
<style lang="scss" scoped>
.border1 {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
.bg {
position: relative;
margin: 15px 20px;
background-image: url("./../asset/border1Bg.svg");
background-size: 100% calc(100%);
background-repeat: no-repeat;
padding: 30px 20px 0 20px;
box-sizing: border-box;
height: calc(100% - 40px);
.header {
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%, -50%);
height: 48px;
min-width: 166px;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
font-size: 16px;
background-image: url("./../asset/border1Title.svg");
background-size: 100%;
background-repeat: no-repeat;
}
}
.slot {
height: calc(100% - 20px);
}
}
</style>

View File

@@ -1,115 +0,0 @@
<template>
<section class="border2">
<div class="corner left-bottom"></div>
<div class="corner right-bottom"></div>
<div class="bg">
<div class="header">
<img src="https://cdn.cunwuyun.cn/dvcp/dv/img/sanjiaoxing.svg" />
<h2>{{ title }}</h2>
<img class="header-right" src="https://cdn.cunwuyun.cn/dvcp/dv/img/sanjiaoxing.svg" />
</div>
<div class="slot">
<slot/>
</div>
</div>
</section>
</template>
<script>
export default {
name: 'border2',
props: {title: String},
data () {
return {
}
}
}
</script>
<style lang="scss" scoped>
.border2 {
position: relative;
width: 100%;
height: 100%;
background: linear-gradient(180deg, rgba(7, 29, 62, 0.2) 0%, rgba(15, 69, 124, 0.2) 100%);
* {
box-sizing: border-box;
}
.corner {
height: 18px;
width: 18px;
position: absolute;
display: block;
background-image: url(./../asset/corner.svg);
background-repeat: no-repeat;
}
.corner.left-top {
left: -6px;
top: -6px;
transform: rotateY(180deg);
}
.corner.right-top {
right: -6px;
top: -6px;
}
.corner.left-bottom {
left: -6px;
bottom: -6px;
transform: rotateX(180deg) rotateY(180deg);
}
.corner.right-bottom {
right: -6px;
bottom: -6px;
transform: rotateX(180deg);
}
.bg {
position: relative;
height: 100%;
background-repeat: no-repeat;
box-sizing: border-box;
&:after {
position: absolute;
bottom: 0;
left: 0;
z-index: 1;
width: 100%;
height: 28px;
background-size: 100% 100%;
content: ' ';
}
.header {
display: flex;
position: relative;
align-items: center;
justify-content: space-between;
height: 40px;
line-height: 40px;
text-align: center;
background: url(./../asset/border2Title.svg) no-repeat;
background-size: cover;
.header-right {
position: relative;
transform-origin: center;
transform: rotate(180deg);
}
h2 {
font-size: 18px;
color: #fff;
font-weight: normal;
}
}
.slot {
height: calc(100% - 40px);
padding: 0 20px 20px;
}
}
}
</style>

View File

@@ -1,140 +0,0 @@
<template>
<section class="border3">
<div class="bg">
<div class="bg-wrapper"></div>
<div class="header">
<div class="header-border">
<div class="point"></div>
<div class="point"></div>
<div class="point"></div>
</div>
<h2>{{ title }}</h2>
<div class="header-border">
<div class="point"></div>
<div class="point"></div>
<div class="point"></div>
</div>
</div>
<div class="bottom">
<div class="bottom-left">
<div class="point"></div>
<div class="point"></div>
<div class="point"></div>
</div>
<div class="bottom-right">
<div class="point"></div>
<div class="point"></div>
<div class="point"></div>
</div>
</div>
<div class="slot">
<slot/>
</div>
</div>
</section>
</template>
<script>
export default {
name: 'border3',
props: {title: String}
}
</script>
<style lang="scss" scoped>
.border3 {
width: 100%;
height: 100%;
box-sizing: border-box;
* {
box-sizing: border-box;
}
.bg {
position: relative;
height: 100%;
.bg-wrapper {
position: absolute;
top: 12px;
width: 100%;
height: calc(100% - 12px);
background: rgba(11, 24, 73, 0.3);
}
.bottom-left, .bottom-right, .header-border {
display: flex;
align-items: center;
position: relative;
justify-content: space-between;
width: 24%;
height: 1px;
.point {
width: 4px;
height: 1px;
background: #FFCD68;
}
}
.bottom {
display: flex;
justify-content: space-between;
position: absolute;
bottom: 0;
left: 0;
z-index: 1;
width: 100%;
height: 1px;
background: rgba(0, 133, 255, 0.5);
}
.header {
display: flex;
position: relative;
align-items: center;
justify-content: space-between;
height: 24px;
line-height: 24px;
text-align: center;
.header-border {
position: relative;
display: flex;
align-items: center;
width: 30%;
height: 1px;
background: rgba(0, 133, 255, 0.5);
}
h2 {
position: relative;
font-size: 18px;
color: #fff;
letter-spacing: 2px;
&::after {
position: absolute;
top: 50%;
left: 50%;
width: 120px;
height: 12px;
transform: translate(-50%, -50%);
content: ' ';
background: url(./../asset/border3Title.png) no-repeat;
background-size: 100% 100%;
opacity: 0.8;
}
}
}
.slot {
position: relative;
z-index: 1;
height: calc(100% - 34px);
padding: 0;
}
}
}
</style>

View File

@@ -1,45 +0,0 @@
<template>
<section class="border4">
<div class="slot">
<slot/>
</div>
<div class="title">{{ title }}</div>
</section>
</template>
<script>
export default {
name: 'border4',
props: {title: String}
}
</script>
<style lang="scss" scoped>
.border4 {
width: 100%;
height: 100%;
background: rgba(33, 73, 157, 0.15);
border-radius: 6px;
border: 1px solid #274A7E;
box-sizing: border-box;
overflow: hidden;
.slot {
width: 100%;
height: calc(100% - 48px);
}
.title {
height: 48px;
line-height: 48px;
padding: 0 10px;
color: #82C5FF;
font-size: 16px;
text-align: center;
}
* {
box-sizing: border-box;
}
}
</style>

Some files were not shown because too many files have changed in this diff Show More