提交
This commit is contained in:
parent
b64e9a4e0d
commit
1576a9417b
@ -5,7 +5,7 @@
|
||||
"author": "Zheng Jie",
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"dev": "SET NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
|
||||
"dev": "vue-cli-service serve",
|
||||
"build:prod": "vue-cli-service build",
|
||||
"build:stage": "vue-cli-service build --mode staging",
|
||||
"preview": "node build/index.js --preview",
|
||||
|
48
eladmin-web/src/api/bus/busDevice/busDevice.js
Normal file
48
eladmin-web/src/api/bus/busDevice/busDevice.js
Normal file
@ -0,0 +1,48 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function add(data) {
|
||||
return request({
|
||||
url: 'api/busDevice',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function del(ids) {
|
||||
return request({
|
||||
url: 'api/busDevice/',
|
||||
method: 'delete',
|
||||
data: ids
|
||||
})
|
||||
}
|
||||
|
||||
export function edit(data) {
|
||||
return request({
|
||||
url: 'api/busDevice',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function getQrCode(id) {
|
||||
return request({
|
||||
url: 'api/busDevice/getQrCode?id=' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function getDeviceTree(pid) {
|
||||
return request({
|
||||
url: 'api/busDevice/getDeviceTree?pid=' + pid,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function getChild(id) {
|
||||
return request({
|
||||
url: 'api/busDevice/child?id=' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export default { add, edit, del, getDeviceTree }
|
27
eladmin-web/src/api/bus/busDeviceCommand/busDeviceCommand.js
Normal file
27
eladmin-web/src/api/bus/busDeviceCommand/busDeviceCommand.js
Normal file
@ -0,0 +1,27 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function add(data) {
|
||||
return request({
|
||||
url: 'api/busDeviceCommand',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function del(ids) {
|
||||
return request({
|
||||
url: 'api/busDeviceCommand/',
|
||||
method: 'delete',
|
||||
data: ids
|
||||
})
|
||||
}
|
||||
|
||||
export function edit(data) {
|
||||
return request({
|
||||
url: 'api/busDeviceCommand',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export default { add, edit, del }
|
42
eladmin-web/src/api/bus/busUser/busUser.js
Normal file
42
eladmin-web/src/api/bus/busUser/busUser.js
Normal file
@ -0,0 +1,42 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function add(data) {
|
||||
return request({
|
||||
url: 'api/busUser',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function del(ids) {
|
||||
return request({
|
||||
url: 'api/busUser/',
|
||||
method: 'delete',
|
||||
data: ids
|
||||
})
|
||||
}
|
||||
|
||||
export function edit(data) {
|
||||
return request({
|
||||
url: 'api/busUser',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function updUserCommands(data) {
|
||||
return request({
|
||||
url: 'api/busUser/updUserCommands',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function get(id) {
|
||||
return request({
|
||||
url: 'api/busUser/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export default { add, edit, del, get }
|
@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div style="display: inline-block">
|
||||
<el-button v-permission="permission.edit" :loading="crud.status.cu === 2" :disabled="disabledEdit" size="mini" type="primary" icon="el-icon-edit" @click.stop="crud.toEdit(data)" />
|
||||
<el-button v-permission="permission.edit" :loading="crud.status.cu === 2" :disabled="disabledEdit" size="mini" type="primary" icon="el-icon-edit" title="修改" @click.stop="crud.toEdit(data)" />
|
||||
<el-popover v-model="pop" v-permission="permission.del" placement="top" width="180" trigger="manual" @show="onPopoverShow" @hide="onPopoverHide">
|
||||
<p>{{ msg }}</p>
|
||||
<div style="text-align: right; margin: 0">
|
||||
<el-button size="mini" type="text" @click="doCancel">取消</el-button>
|
||||
<el-button :loading="crud.dataStatus[crud.getDataId(data)].delete === 2" type="primary" size="mini" @click="crud.doDelete(data)">确定</el-button>
|
||||
</div>
|
||||
<el-button slot="reference" :disabled="disabledDle" type="danger" icon="el-icon-delete" size="mini" @click.stop="toDelete" />
|
||||
<el-button slot="reference" :disabled="disabledDle" type="danger" icon="el-icon-delete" size="mini" @click.stop="toDelete" title="删除"/>
|
||||
</el-popover>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -77,7 +77,7 @@ export default {
|
||||
calculable: true,
|
||||
series: [
|
||||
{
|
||||
name: '案件类型统计',
|
||||
name: '设备指令统计',
|
||||
type: 'pie',
|
||||
roseType: 'radius',
|
||||
radius: [15, 95],
|
||||
|
178
eladmin-web/src/views/bus/busDevice/index.vue
Normal file
178
eladmin-web/src/views/bus/busDevice/index.vue
Normal file
@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!--工具栏-->
|
||||
<div class="head-container">
|
||||
|
||||
<div v-if="crud.props.searchToggle">
|
||||
<!-- 搜索 -->
|
||||
<el-input v-model="query.deviceSn" size="small" placeholder="输入设备号" style="width: 180px;" class="filter-item" @keyup.enter.native="crud.toQuery"/>
|
||||
<el-input v-model="query.model" size="small" placeholder="输入型号" style="width: 180px;" class="filter-item" @keyup.enter.native="crud.toQuery"/>
|
||||
<el-input v-model="query.brand" size="small" placeholder="输入品牌" style="width: 180px;" class="filter-item" @keyup.enter.native="crud.toQuery"/>
|
||||
<el-select v-model="query.type" size="small" placeholder="选择类型" class="filter-item" style="width: 180px" @change="crud.toQuery">
|
||||
<el-option key="" label="全部" value=""/>
|
||||
<el-option v-for="item in typeList" :key="item.value" :label="item.label" :value="item.value"/>
|
||||
</el-select>
|
||||
<rrOperation/>
|
||||
</div>
|
||||
|
||||
<!--如果想在工具栏加入更多按钮,可以使用插槽方式, slot = 'left' or 'right'-->
|
||||
<crudOperation :permission="permission" />
|
||||
<!--表单组件-->
|
||||
<el-dialog :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" width="500px">
|
||||
<el-form ref="form" :model="form" :rules="rules" size="small" label-width="80px">
|
||||
<el-form-item label="设备号" prop="deviceSn">
|
||||
<el-input v-model="form.deviceSn" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="型号" prop="model">
|
||||
<el-input v-model="form.model" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="品牌">
|
||||
<el-input v-model="form.brand" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="固件版本">
|
||||
<el-input v-model="form.firmwareVersion" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="放置位置">
|
||||
<el-input v-model="form.location" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="类型">
|
||||
<el-select v-model="form.type" size="small" placeholder="设备类型" class="filter-item" style="width: 370px">
|
||||
<el-option v-for="item in typeList" :key="item.value" :label="item.label" :value="item.value"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注">
|
||||
<el-input v-model="form.remark" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="text" @click="crud.cancelCU">取消</el-button>
|
||||
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确认</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<el-dialog :visible.sync="qrCodeVisible" width="500px">
|
||||
<div style="text-align: center"><img :src="baseApi + '/file/image/' + qrCodeUrl" /></div>
|
||||
<div style="text-align: center;"><h4 style="text-align: center;">可以截图保存,有效期只有一小时</h4></div>
|
||||
</el-dialog>
|
||||
|
||||
<!--表格渲染-->
|
||||
<el-table ref="table" v-loading="crud.loading" :data="crud.data" size="small" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="deviceSn" label="设备序列号" />
|
||||
<el-table-column prop="model" label="型号" />
|
||||
<el-table-column prop="brand" label="品牌" />
|
||||
<el-table-column prop="firmwareVersion" label="固件版本" />
|
||||
<el-table-column prop="location" label="放置位置" />
|
||||
<el-table-column prop="status" label="设备状态">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.status==1">在线</span>
|
||||
<span v-else-if="scope.row.status==2">离线</span>
|
||||
<span v-else>故障</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="type" label="类型">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.type==1">打印机</span>
|
||||
<span v-else>摄像头</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" />
|
||||
<el-table-column v-if="checkPer(['admin','busDevice:edit','busDevice:del'])" label="操作" width="250px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<udOperation
|
||||
:data="scope.row"
|
||||
:permission="permission"
|
||||
/>
|
||||
<el-button type="success" size="mini" title="设备指令" @click="openCommandData(scope.row.id)"><svg-icon icon-class="chain" /></el-button>
|
||||
<el-button type="warning" size="mini" title="生成二维码" @click="createQrCode(scope.row.id)"><svg-icon icon-class="exit-fullscreen" /></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--分页组件-->
|
||||
<pagination />
|
||||
|
||||
<!-- 子窗口(模态框组件) -->
|
||||
<commandPage :visible.sync="showCommandData" :data="deviceId" @close="closeCommandPage" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import crudBusDevice, { getQrCode } from '@/api/bus/busDevice/busDevice'
|
||||
import commandPage from '@/views/bus/busDeviceCommand/index'
|
||||
import CRUD, { presenter, header, form, crud } from '@crud/crud'
|
||||
import rrOperation from '@crud/RR.operation'
|
||||
import crudOperation from '@crud/CRUD.operation'
|
||||
import udOperation from '@crud/UD.operation'
|
||||
import pagination from '@crud/Pagination'
|
||||
import {mapGetters} from "vuex";
|
||||
|
||||
const defaultForm = { id: null, deviceSn: null, model: null, brand: null, firmwareVersion: null, location: null, status: null, onlineTime: null, offlineTime: null, totalPrintTime: null, remark: null, type: null, createBy: null, updateBy: null, createTime: null, updateTime: null }
|
||||
export default {
|
||||
name: 'BusDevice',
|
||||
components: { pagination, crudOperation, rrOperation, udOperation, commandPage },
|
||||
mixins: [presenter(), header(), form(defaultForm), crud()],
|
||||
cruds() {
|
||||
return CRUD({ title: '', url: 'api/busDevice', idField: 'id', sort: 'id,desc', crudMethod: { ...crudBusDevice }})
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
qrCodeUrl: '',
|
||||
qrCodeVisible: false,
|
||||
permission: {
|
||||
add: ['admin', 'busDevice:add'],
|
||||
edit: ['admin', 'busDevice:edit'],
|
||||
del: ['admin', 'busDevice:del']
|
||||
},
|
||||
typeList: [
|
||||
{ 'label': '打印机', 'value': 1 },
|
||||
{ 'label': '摄像头', 'value': 2 }
|
||||
],
|
||||
rules: {
|
||||
deviceSn: [
|
||||
{ required: true, message: '设备序列号不能为空', trigger: 'blur' }
|
||||
],
|
||||
model: [
|
||||
{ required: true, message: '型号不能为空', trigger: 'blur' }
|
||||
]
|
||||
},
|
||||
showCommandData: false,
|
||||
commandData: [],
|
||||
commandPage: { page: 1, size: 8, total: 0 },
|
||||
deviceId: 0
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.crud.optShow.download = false
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'baseApi'
|
||||
])
|
||||
},
|
||||
methods: {
|
||||
async createQrCode(id) {
|
||||
await getQrCode(id).then(res => {
|
||||
this.qrCodeVisible = true
|
||||
this.qrCodeUrl = res
|
||||
})
|
||||
},
|
||||
openCommandData(id) {
|
||||
this.showCommandData = true
|
||||
this.deviceId = id
|
||||
},
|
||||
closeCommandPage() {
|
||||
this.showCommandData = false
|
||||
},
|
||||
// 钩子:在获取表格数据之前执行,false 则代表不获取数据
|
||||
[CRUD.HOOK.beforeRefresh]() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
133
eladmin-web/src/views/bus/busDeviceCommand/index.vue
Normal file
133
eladmin-web/src/views/bus/busDeviceCommand/index.vue
Normal file
@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<el-dialog :visible.sync="visible" title="设备命令" @close="updCommandData">
|
||||
<div class="app-container">
|
||||
<!--工具栏-->
|
||||
<div class="head-container">
|
||||
|
||||
<!--如果想在工具栏加入更多按钮,可以使用插槽方式, slot = 'left' or 'right'-->
|
||||
<crudOperation :permission="permission" />
|
||||
|
||||
<!--表单组件-->
|
||||
<el-dialog :close-on-click-modal="false" :before-close="crud.cancelCU" :visible.sync="crud.status.cu > 0" :title="crud.status.title" append-to-body style="width: 1000px; margin-left: 25%">
|
||||
<el-form ref="form" :model="form" :rules="rules" size="small" label-width="80px">
|
||||
<el-form-item label="设备ID" prop="deviceId" hidden="hidden">
|
||||
<el-input v-model="form.deviceId" />
|
||||
</el-form-item>
|
||||
<el-form-item label="指令名称" prop="commandName">
|
||||
<el-input v-model="form.commandName" style="width: 370px;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="指令类型" prop="commandType">
|
||||
<el-select v-model="form.commandType" size="small" placeholder="类型" class="filter-item" style="width: 370px">
|
||||
<el-option v-for="item in commandTypes" :key="item.value" :label="item.label" :value="item.value"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="指令参数">
|
||||
<el-input v-model="form.commandParams" style="width: 370px;" rows="3" type="textarea"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="指令描述">
|
||||
<el-input v-model="form.description" style="width: 370px;" rows="3" type="textarea"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button type="text" @click="crud.cancelCU">取消</el-button>
|
||||
<el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">确认</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
<!--表格渲染-->
|
||||
<el-table ref="table" v-loading="crud.loading" :data="crud.data" size="small" style="width: 100%; height: 400px" @selection-change="crud.selectionChangeHandler" >
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="commandName" label="指令名称" />
|
||||
<el-table-column prop="commandType" label="指令类型" >
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.commandType==1">控制</span>
|
||||
<span v-else-if="scope.row.commandType==2">查询</span>
|
||||
<span v-else>校准</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="commandParams" label="指令参数" />
|
||||
<el-table-column prop="description" label="指令描述" />
|
||||
<el-table-column v-if="checkPer(['admin','busDeviceCommand:edit','busDeviceCommand:del'])" label="操作" width="150px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<udOperation
|
||||
:data="scope.row"
|
||||
:permission="permission"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--分页组件-->
|
||||
<pagination />
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import crudBusDeviceCommand from '@/api/bus/busDeviceCommand/busDeviceCommand'
|
||||
import CRUD, { presenter, header, form, crud } from '@crud/crud'
|
||||
import crudOperation from '@crud/CRUD.operation'
|
||||
import udOperation from '@crud/UD.operation'
|
||||
import pagination from '@crud/Pagination'
|
||||
|
||||
const defaultForm = { id: null, deviceId: null, commandName: null, commandType: null, description: null, isSystem: null, commandParams: null, createBy: null, updateBy: null, createTime: null, updateTime: null }
|
||||
export default {
|
||||
name: 'BusDeviceCommand',
|
||||
components: { pagination, crudOperation, udOperation },
|
||||
props: {
|
||||
visible: { type: Boolean, default: false },
|
||||
data: { type: Number, required: true }
|
||||
},
|
||||
mixins: [presenter(), header(), form(defaultForm), crud()],
|
||||
cruds() {
|
||||
return CRUD({ title: '指令', url: 'api/busDeviceCommand', idField: 'id', sort: 'id,desc', crudMethod: { ...crudBusDeviceCommand }})
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
commandTypes: [
|
||||
{ 'label': '控制', 'value': 1 },
|
||||
{ 'label': '查询', 'value': 2 },
|
||||
{ 'label': '校准', 'value': 3 }
|
||||
],
|
||||
permission: {
|
||||
add: ['admin', 'busDeviceCommand:add'],
|
||||
edit: ['admin', 'busDeviceCommand:edit'],
|
||||
del: ['admin', 'busDeviceCommand:del']
|
||||
},
|
||||
rules: {
|
||||
commandName: [
|
||||
{required: true, message: '指令名称不能为空', trigger: 'blur'}
|
||||
],
|
||||
commandType: [
|
||||
{required: true, message: '指令类型不能为空', trigger: 'blur'}
|
||||
],
|
||||
commandParams: [
|
||||
{required: true, message: '指令参数不能为空', trigger: 'blur'}
|
||||
],
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
data(newVal) {
|
||||
defaultForm.deviceId = newVal
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.crud.optShow.download = false
|
||||
},
|
||||
methods: {
|
||||
updCommandData() {
|
||||
this.visible = false
|
||||
this.$emit('update:visible', false)
|
||||
},
|
||||
// 钩子:在获取表格数据之前执行,false 则代表不获取数据
|
||||
[CRUD.HOOK.beforeRefresh]() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
244
eladmin-web/src/views/bus/busUser/index.vue
Normal file
244
eladmin-web/src/views/bus/busUser/index.vue
Normal file
@ -0,0 +1,244 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<!--工具栏-->
|
||||
<div class="head-container">
|
||||
<div v-if="crud.props.searchToggle">
|
||||
<!-- 搜索 -->
|
||||
<el-input v-model="query.nickname" size="small" placeholder="输入用户昵称" style="width: 180px;" class="filter-item" @keyup.enter.native="crud.toQuery"/>
|
||||
<el-input v-model="query.phone" size="small" placeholder="输入手机号" style="width: 180px;" class="filter-item" @keyup.enter.native="crud.toQuery"/>
|
||||
<el-select v-model="query.status" size="small" placeholder="选择状态" class="filter-item" style="width: 180px" @change="crud.toQuery">
|
||||
<el-option key="" label="全部" value=""/>
|
||||
<el-option v-for="item in statusList" :key="item.value" :label="item.label" :value="item.value"/>
|
||||
</el-select>
|
||||
<rrOperation />
|
||||
</div>
|
||||
<!--如果想在工具栏加入更多按钮,可以使用插槽方式, slot = 'left' or 'right'-->
|
||||
<crudOperation :permission="permission" />
|
||||
</div>
|
||||
|
||||
<el-row :gutter="15">
|
||||
<!--用户管理-->
|
||||
<el-col :xs="24" :sm="24" :md="16" :lg="16" :xl="17" style="margin-bottom: 10px">
|
||||
<el-card class="box-card" shadow="never">
|
||||
<div slot="header" class="clearfix">
|
||||
<span class="role-span">用户列表</span>
|
||||
</div>
|
||||
<el-table ref="table" v-loading="crud.loading" highlight-current-row style="width: 100%;" :data="crud.data" @selection-change="crud.selectionChangeHandler" @current-change="handleCurrentChange">
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column prop="nickname" label="用户昵称" />
|
||||
<el-table-column prop="avatar" label="头像" >
|
||||
<template slot-scope="{row}">
|
||||
<el-image
|
||||
:src=" baseApi + row.avatar"
|
||||
:preview-src-list="[baseApi + row.avatar]"
|
||||
fit="contain"
|
||||
lazy
|
||||
class="el-avatar"
|
||||
>
|
||||
<div slot="error">
|
||||
<i class="el-icon-document" />
|
||||
</div>
|
||||
</el-image>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="phone" label="手机号码" />
|
||||
<el-table-column prop="status" label="状态">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.status==1" style="color: #13ce66">正常</span>
|
||||
<span v-else style="color: #ff6d6d">禁止</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="sex" label="性别">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.sex==0">未知</span>
|
||||
<span v-else-if="scope.row.sex==1">男</span>
|
||||
<span v-else>女</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" />
|
||||
<el-table-column v-if="checkPer(['admin','busUser:edit','busUser:del'])" label="操作" width="150px" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-button v-if="scope.row.status==1" type="danger" size="mini" title="禁用" @click="setStatus(scope.row.id, 0)"><svg-icon icon-class="lock"/></el-button>
|
||||
<el-button v-else type="success" size="mini" title="启用" @click="setStatus(scope.row.id, 1)"><svg-icon icon-class="unlock"/></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<!--分页组件-->
|
||||
<pagination />
|
||||
</el-card>
|
||||
</el-col>
|
||||
|
||||
<!-- 设备 -->
|
||||
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="7">
|
||||
<el-card class="box-card" shadow="never">
|
||||
<div slot="header" class="clearfix">
|
||||
<el-tooltip class="item" effect="dark" content="选择指定用户分配指令" placement="top">
|
||||
<span class="role-span">设备分配</span>
|
||||
</el-tooltip>
|
||||
<el-button
|
||||
|
||||
:disabled="!showButton"
|
||||
:loading="deviceLoading"
|
||||
icon="el-icon-check"
|
||||
size="mini"
|
||||
style="float: right; padding: 6px 9px"
|
||||
type="primary"
|
||||
@click="saveUserDevice"
|
||||
>保存</el-button>
|
||||
</div>
|
||||
<el-tree
|
||||
ref="device"
|
||||
lazy
|
||||
:data="deviceData"
|
||||
:default-checked-keys="deviceCommandIds"
|
||||
:load="getDeviceDatas"
|
||||
:props="defaultProps"
|
||||
check-strictly
|
||||
accordion
|
||||
show-checkbox
|
||||
node-key="id"
|
||||
@check="deviceChange"
|
||||
/>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import crudBusUser, { edit, updUserCommands } from '@/api/bus/busUser/busUser'
|
||||
import { getDeviceTree, getChild } from '@/api/bus/busDevice/busDevice'
|
||||
import CRUD, { presenter, header, form, crud } from '@crud/crud'
|
||||
import rrOperation from '@crud/RR.operation.vue'
|
||||
import crudOperation from '@crud/CRUD.operation.vue'
|
||||
import udOperation from '@crud/UD.operation.vue'
|
||||
import pagination from '@crud/Pagination.vue'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
const defaultForm = { id: null, realName: null, nickname: null, avatar: null, phone: null, status: null, token: null, sex: null, createBy: null, updateBy: null, createTime: null, updateTime: null }
|
||||
export default {
|
||||
name: 'BusUser',
|
||||
components: { pagination, crudOperation, rrOperation, udOperation },
|
||||
mixins: [presenter(), header(), form(defaultForm), crud()],
|
||||
cruds() {
|
||||
return CRUD({ title: 'busUser', url: 'api/busUser', idField: 'id', sort: 'id,desc', crudMethod: { ...crudBusUser }})
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
thisUserId: 0,
|
||||
defaultProps: { children: 'children', label: 'label', isLeaf: 'leaf' },
|
||||
showButton: false,
|
||||
deviceLoading: false,
|
||||
deviceData: [],
|
||||
deviceCommandIds: [],
|
||||
permission: {
|
||||
del: ['admin', 'busUser:del']
|
||||
},
|
||||
statusList: [
|
||||
{ 'label': '正常', 'value': 1 },
|
||||
{ 'label': '禁用', 'value': 0 }
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'baseApi'
|
||||
])
|
||||
},
|
||||
created() {
|
||||
this.crud.optShow = { add: false, edit: false, del: true, download: false, reset: true }
|
||||
},
|
||||
methods: {
|
||||
getDeviceDatas(node, resolve) {
|
||||
setTimeout(() => {
|
||||
getDeviceTree(node.data.id ? node.data.id : 0).then(res => {
|
||||
resolve(res)
|
||||
})
|
||||
}, 100)
|
||||
},
|
||||
// 触发单选
|
||||
handleCurrentChange(val) {
|
||||
if (val) {
|
||||
const _this = this
|
||||
// 清空菜单的选中
|
||||
this.$refs.device.setCheckedKeys([])
|
||||
// 保存当前的角色id
|
||||
this.thisUserId = val.id
|
||||
// 初始化默认选中的key
|
||||
this.deviceCommandIds = []
|
||||
val.commands.forEach(function(data) {
|
||||
_this.deviceCommandIds.push(data.id)
|
||||
})
|
||||
this.showButton = true
|
||||
}
|
||||
},
|
||||
// 保存用户设备
|
||||
saveUserDevice() {
|
||||
this.deviceLoading = true
|
||||
const userCommand = { id: this.thisUserId, commands: [] }
|
||||
// 得到已选中的 key 值
|
||||
this.deviceCommandIds.forEach(function(id) {
|
||||
const command = { id: id }
|
||||
userCommand.commands.push(command)
|
||||
})
|
||||
updUserCommands(userCommand).then(() => {
|
||||
this.crud.notify('保存成功', CRUD.NOTIFICATION_TYPE.SUCCESS)
|
||||
this.deviceLoading = false
|
||||
this.refreshUser()
|
||||
}).catch(err => {
|
||||
this.deviceLoading = false
|
||||
console.log(err.response.data.message)
|
||||
})
|
||||
},
|
||||
// 改变数据
|
||||
refreshUser() {
|
||||
// 无刷新更新 表格数据
|
||||
crudBusUser.get(this.thisUserId).then(res => {
|
||||
for (let i = 0; i < this.crud.data.length; i++) {
|
||||
if (res.id === this.crud.data[i].id) {
|
||||
this.crud.data[i] = res
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
deviceChange(device) {
|
||||
// 获取该节点的所有子节点,id 包含自身
|
||||
getChild(device.id).then(childIds => {
|
||||
// 判断是否在 menuIds 中,如果存在则删除,否则添加
|
||||
if (this.deviceCommandIds.indexOf(device.id) !== -1) {
|
||||
for (let i = 0; i < childIds.length; i++) {
|
||||
const index = this.deviceCommandIds.indexOf(childIds[i])
|
||||
if (index !== -1) {
|
||||
this.deviceCommandIds.splice(index, 1)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < childIds.length; i++) {
|
||||
const index = this.deviceCommandIds.indexOf(childIds[i])
|
||||
if (index === -1) {
|
||||
this.deviceCommandIds.push(childIds[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
this.$refs.device.setCheckedKeys(this.deviceCommandIds)
|
||||
})
|
||||
},
|
||||
async setStatus(id, status) {
|
||||
const params = { id: id, status: status }
|
||||
await edit(params).then(res => {
|
||||
this.crud.notify('操作成功', 'success')
|
||||
})
|
||||
this.crud.toQuery()
|
||||
},
|
||||
// 钩子:在获取表格数据之前执行,false 则代表不获取数据
|
||||
[CRUD.HOOK.beforeRefresh]() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@ -46,7 +46,7 @@
|
||||
</div>
|
||||
<div class="card-panel-description">
|
||||
<div class="card-panel-text">
|
||||
执法数据
|
||||
指令数据
|
||||
</div>
|
||||
<count-to :start-val="0" :end-val="groupData.law" :duration="3600" class="card-panel-num" />
|
||||
</div>
|
||||
|
@ -20,5 +20,22 @@
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>${hutool.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 生成二维码 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>core</artifactId>
|
||||
<version>3.4.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.zxing</groupId>
|
||||
<artifactId>javase</artifactId>
|
||||
<version>3.4.1</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,28 @@
|
||||
package me.zhengjie.utils;
|
||||
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
public class CRC32Utils {
|
||||
|
||||
public static String getUnsignedCRC32(String input) {
|
||||
CRC32 crc32 = new CRC32();
|
||||
crc32.update(input.getBytes());
|
||||
int value = (int) crc32.getValue();
|
||||
// 将int转换为long以避免潜在的符号扩展问题
|
||||
int unsignedValue = value & 0xFFFFFFFF;
|
||||
String hexString = formatCrcToHex(unsignedValue);
|
||||
return "0x" + hexString; // 0x8abd91cc
|
||||
}
|
||||
|
||||
private static String formatCrcToHex(int crc) {
|
||||
// 方法一:采用String.format
|
||||
String format = String.format("%08x", crc);
|
||||
return format.toUpperCase();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String text = "{\"Name\":\"4KL200URH300.4K\",\"MachineName\":\"3DPLUS\",\"MachineType\":\"Spade\",\"MainboardID\":\"12345678\",\"ProtocolVersion\":\"V3.0.0\",\"FirmwareVersion\":\"V1.0.0\"}";
|
||||
String crc32Value = getUnsignedCRC32(text);
|
||||
System.out.println("CRC-32 (unsigned): " + crc32Value);
|
||||
}
|
||||
}
|
@ -63,4 +63,9 @@ public interface CacheKey {
|
||||
* 数据字典
|
||||
*/
|
||||
String DICT_NAME = "dict::name:";
|
||||
|
||||
/**
|
||||
* 二维码
|
||||
*/
|
||||
String QR_CODE = "qrCode:";
|
||||
}
|
||||
|
@ -75,11 +75,11 @@ public class FileUtil extends cn.hutool.core.io.FileUtil {
|
||||
*/
|
||||
private static final DecimalFormat DF = new DecimalFormat("0.00");
|
||||
|
||||
public static final String IMAGE = "图片";
|
||||
public static final String TXT = "文档";
|
||||
public static final String MUSIC = "音乐";
|
||||
public static final String VIDEO = "视频";
|
||||
public static final String OTHER = "其他";
|
||||
public static final String IMAGE = "image";
|
||||
public static final String TXT = "txt";
|
||||
public static final String MUSIC = "music";
|
||||
public static final String VIDEO = "video";
|
||||
public static final String OTHER = "others";
|
||||
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,82 @@
|
||||
package me.zhengjie.utils;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.stereotype.Component;
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.EncodeHintType;
|
||||
import com.google.zxing.MultiFormatWriter;
|
||||
import com.google.zxing.WriterException;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class QrCodeUtil {
|
||||
|
||||
//CODE_WIDTH:二维码宽度,单位像素
|
||||
private static final int CODE_WIDTH = 400;
|
||||
//CODE_HEIGHT:二维码高度,单位像素
|
||||
private static final int CODE_HEIGHT = 400;
|
||||
//FRONT_COLOR:二维码前景色,0x000000 表示黑色
|
||||
private static final int FRONT_COLOR = 0x000000;
|
||||
//BACKGROUND_COLOR:二维码背景色,0xFFFFFF 表示白色
|
||||
//演示用 16 进制表示,和前端页面 CSS 的取色是一样的,注意前后景颜色应该对比明显,如常见的黑白
|
||||
private static final int BACKGROUND_COLOR = 0xFFFFFF;
|
||||
//文件类型
|
||||
private static final String FILE_FORMAT = "png";
|
||||
|
||||
public MultipartFile getQrCode(String content, String orderCode) {
|
||||
try {
|
||||
if (StringUtils.isBlank(content)) { return null; }
|
||||
content = content.trim();
|
||||
// 核心代码-生成二维码
|
||||
BufferedImage image = getBufferedImage(content);
|
||||
MultipartFile multipartFile = toMultipartFile(image, orderCode);
|
||||
return multipartFile;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static MultipartFile toMultipartFile(BufferedImage image, String orderCode) throws Exception {
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
ImageIO.write(image, FILE_FORMAT, byteArrayOutputStream);
|
||||
byte[] byteArray = byteArrayOutputStream.toByteArray();
|
||||
// 使用MockMultipartFile来创建MultipartFile
|
||||
return new MockMultipartFile(orderCode, orderCode + "." + FILE_FORMAT , "image/png", byteArray);
|
||||
}
|
||||
|
||||
//核心代码-生成二维码
|
||||
private static BufferedImage getBufferedImage(String content) throws WriterException {
|
||||
//com.google.zxing.EncodeHintType:编码提示类型,枚举类型
|
||||
Map<EncodeHintType, Object> hints = new HashMap<>();
|
||||
//EncodeHintType.CHARACTER_SET:设置字符编码类型
|
||||
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
|
||||
//EncodeHintType.ERROR_CORRECTION:设置误差校正
|
||||
//ErrorCorrectionLevel:误差校正等级,L = ~7% correction、M = ~15% correction、Q = ~25% correction、H = ~30% correction
|
||||
//不设置时,默认为 L 等级,等级不一样,生成的图案不同,但扫描的结果是一样的
|
||||
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
|
||||
//EncodeHintType.MARGIN:设置二维码边距,单位像素,值越小,二维码离四周越近
|
||||
hints.put(EncodeHintType.MARGIN, 1);
|
||||
MultiFormatWriter multiFormatWriter = new MultiFormatWriter();
|
||||
BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, CODE_WIDTH, CODE_HEIGHT, hints);
|
||||
BufferedImage bufferedImage = new BufferedImage(CODE_WIDTH, CODE_HEIGHT, BufferedImage.TYPE_INT_BGR);
|
||||
for (int x = 0; x < CODE_WIDTH; x++) {
|
||||
for (int y = 0; y < CODE_HEIGHT; y++) {
|
||||
bufferedImage.setRGB(x, y, bitMatrix.get(x, y) ? FRONT_COLOR : BACKGROUND_COLOR);
|
||||
}
|
||||
}
|
||||
return bufferedImage;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
package me.zhengjie.modules.front.rest;
|
||||
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.zhengjie.annotation.Log;
|
||||
import me.zhengjie.annotation.rest.AnonymousPostMapping;
|
||||
import me.zhengjie.modules.front.domain.dto.LoginVo;
|
||||
import me.zhengjie.modules.front.service.WeChatService;
|
||||
import me.zhengjie.modules.security.service.dto.JwtUserDto;
|
||||
import me.zhengjie.modules.system.service.BusDeviceService;
|
||||
import me.zhengjie.utils.SecurityUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
|
||||
@Slf4j
|
||||
@RestController("DeviceController")
|
||||
@RequestMapping("api/front/device")
|
||||
@Api(tags = "微信:设备管理")
|
||||
public class DeviceController {
|
||||
|
||||
@Autowired private BusDeviceService busDeviceService;
|
||||
|
||||
@Log("绑定设备")
|
||||
@ApiOperation(value = "绑定设备")
|
||||
@GetMapping(value = "/binding")
|
||||
public ResponseEntity<Object> binding(@RequestParam String code) {
|
||||
busDeviceService.binding(code);
|
||||
return new ResponseEntity<>("绑定成功", HttpStatus.OK);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -6,6 +6,8 @@ import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
public interface WeChatService {
|
||||
|
||||
String getQrCode(Long deviceId, String code);
|
||||
|
||||
LoginVo authorizeLogin(String code, HttpServletRequest request);
|
||||
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import com.alibaba.fastjson2.JSONObject;
|
||||
import me.zhengjie.exception.BadRequestException;
|
||||
import me.zhengjie.modules.front.domain.dto.LoginVo;
|
||||
import me.zhengjie.modules.front.domain.dto.WeChatMiniAuthorizeVo;
|
||||
import me.zhengjie.modules.front.service.CusUserService;
|
||||
import me.zhengjie.modules.front.service.WeChatService;
|
||||
import me.zhengjie.modules.security.config.SecurityProperties;
|
||||
import me.zhengjie.modules.security.security.TokenProvider;
|
||||
@ -14,13 +13,15 @@ import me.zhengjie.modules.security.service.OnlineUserService;
|
||||
import me.zhengjie.modules.security.service.dto.JwtUserDto;
|
||||
import me.zhengjie.modules.system.domain.BusUser;
|
||||
import me.zhengjie.modules.system.mapper.BusUserMapper;
|
||||
import me.zhengjie.utils.DateUtil;
|
||||
import me.zhengjie.utils.RestTemplateUtils;
|
||||
import me.zhengjie.modules.system.service.BusUserService;
|
||||
import me.zhengjie.service.LocalStorageService;
|
||||
import me.zhengjie.utils.*;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.time.LocalDateTime;
|
||||
@ -38,14 +39,22 @@ public class WeChatServiceImpl implements WeChatService {
|
||||
@Value("${weChat.secret}")
|
||||
private String secret;
|
||||
|
||||
@Autowired private QrCodeUtil qrCodeUtil;
|
||||
@Autowired private BusUserMapper BusUserMapper;
|
||||
@Autowired private RestTemplateUtils restTemplateUtil;
|
||||
@Autowired private TokenProvider tokenProvider;
|
||||
@Autowired private SecurityProperties properties;
|
||||
@Autowired private OnlineUserService onlineUserService;
|
||||
@Autowired private CusUserService BusUserService;
|
||||
private static final String WECHAT_MINI_SNS_AUTH_CODE2SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code";
|
||||
@Autowired private BusUserService busUserService;
|
||||
@Autowired private LocalStorageService localStorageService;
|
||||
private static final String DEFAULT_AVATAR = "/avatar/avatar.png";
|
||||
private static final String WECHAT_MINI_SNS_AUTH_CODE2SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code";
|
||||
|
||||
@Override
|
||||
public String getQrCode(Long deviceId, String code) {
|
||||
MultipartFile mFile = qrCodeUtil.getQrCode(code, code);
|
||||
return localStorageService.createFile(code, mFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LoginVo authorizeLogin(String code, HttpServletRequest request) {
|
||||
@ -74,7 +83,7 @@ public class WeChatServiceImpl implements WeChatService {
|
||||
loginVo.setPhone(BusUser.getPhone());
|
||||
loginVo.setAvatar(BusUser.getAvatar());
|
||||
// 生成令牌
|
||||
JwtUserDto jwtUserDto = BusUserService.addUserCache(BusUser);
|
||||
JwtUserDto jwtUserDto = busUserService.addUserCache(BusUser);
|
||||
String token = tokenProvider.createToken(jwtUserDto);
|
||||
loginVo.setToken(properties.getTokenStartWith() + token);
|
||||
// 保存在线信息
|
||||
|
@ -0,0 +1,46 @@
|
||||
package me.zhengjie.modules.security.config;
|
||||
|
||||
import me.zhengjie.modules.security.config.handler.DeviceWebSocketHandler;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.socket.config.annotation.EnableWebSocket;
|
||||
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
|
||||
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
|
||||
import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;
|
||||
|
||||
|
||||
/**
|
||||
* WebSocket配置类,启用WebSocket功能并注册处理器
|
||||
*/
|
||||
@Configuration
|
||||
@EnableWebSocket
|
||||
public class WebSocketConfig implements WebSocketConfigurer {
|
||||
|
||||
private final DeviceWebSocketHandler deviceWebSocketHandler;
|
||||
|
||||
public WebSocketConfig(DeviceWebSocketHandler deviceWebSocketHandler) {
|
||||
this.deviceWebSocketHandler = deviceWebSocketHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册WebSocket处理器,配置端点和允许的源
|
||||
* @param registry WebSocket处理器注册器
|
||||
*/
|
||||
@Override
|
||||
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
|
||||
registry.addHandler(deviceWebSocketHandler, "/ws/device")
|
||||
.setAllowedOrigins("*");
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置WebSocket容器参数,设置消息缓冲区大小
|
||||
* @return WebSocket容器工厂Bean
|
||||
*/
|
||||
@Bean
|
||||
public ServletServerContainerFactoryBean createWebSocketContainer() {
|
||||
ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
|
||||
container.setMaxTextMessageBufferSize(8192);
|
||||
container.setMaxBinaryMessageBufferSize(8192);
|
||||
return container;
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package me.zhengjie.modules.security.config.handler;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.socket.CloseStatus;
|
||||
import org.springframework.web.socket.TextMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import org.springframework.web.socket.handler.TextWebSocketHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* 处理客户端WebSocket连接的处理器
|
||||
* 管理客户端会话并转发设备状态变化
|
||||
*/
|
||||
@Component
|
||||
public class DeviceWebSocketHandler extends TextWebSocketHandler {
|
||||
|
||||
// 存储所有活跃的WebSocket会话,键为会话ID
|
||||
private final ConcurrentHashMap<String, WebSocketSession> sessions = new ConcurrentHashMap<>();
|
||||
private final ThirdPartyWebSocketClient thirdPartyClient;
|
||||
|
||||
public DeviceWebSocketHandler(ThirdPartyWebSocketClient thirdPartyClient) {
|
||||
this.thirdPartyClient = thirdPartyClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理来自客户端的文本消息
|
||||
* @param session 客户端会话
|
||||
* @param message 收到的消息
|
||||
* @throws IOException 发送消息失败时抛出
|
||||
*/
|
||||
@Override
|
||||
protected void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
|
||||
String payload = message.getPayload();
|
||||
// 将客户端指令转发给第三方WebSocket服务
|
||||
thirdPartyClient.sendCommand(payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户端连接建立后的回调方法
|
||||
* @param session 新建立的会话
|
||||
*/
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) {
|
||||
sessions.put(session.getId(), session);
|
||||
// 可在此处添加连接初始化逻辑
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户端连接关闭后的回调方法
|
||||
* @param session 关闭的会话
|
||||
* @param status 关闭状态
|
||||
*/
|
||||
@Override
|
||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
|
||||
sessions.remove(session.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知所有客户端设备状态变化
|
||||
* @param deviceId 设备ID
|
||||
* @param status 设备状态
|
||||
*/
|
||||
public void notifyDeviceChange(String deviceId, String status) {
|
||||
sessions.forEach((id, session) -> {
|
||||
try {
|
||||
// 向客户端发送JSON格式的设备状态消息
|
||||
session.sendMessage(new TextMessage(
|
||||
String.format("{\"deviceId\": \"%s\", \"status\": \"%s\"}", deviceId, status)
|
||||
));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,148 @@
|
||||
package me.zhengjie.modules.security.config.handler;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.web.socket.client.WebSocketClient;
|
||||
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
|
||||
import org.springframework.web.socket.handler.TextWebSocketHandler;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import org.springframework.web.socket.TextMessage;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 与第三方WebSocket服务通信的客户端
|
||||
* 负责建立连接、订阅设备和处理消息
|
||||
*/
|
||||
@Component
|
||||
public class ThirdPartyWebSocketClient extends TextWebSocketHandler {
|
||||
|
||||
@Value("${thirdparty.ws.url}")
|
||||
private String thirdPartyWsUrl;
|
||||
|
||||
private WebSocketSession session;
|
||||
// 存储已订阅的设备,键为设备ID,值为订阅状态
|
||||
private final ConcurrentHashMap<String, String> subscribedDevices = new ConcurrentHashMap<>();
|
||||
private final DeviceWebSocketHandler deviceHandler;
|
||||
private final ScheduledExecutorService reconnectExecutor = Executors.newSingleThreadScheduledExecutor();
|
||||
|
||||
public ThirdPartyWebSocketClient(DeviceWebSocketHandler deviceHandler) {
|
||||
this.deviceHandler = deviceHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bean初始化后连接到第三方WebSocket服务
|
||||
*/
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
connect();
|
||||
}
|
||||
|
||||
/**
|
||||
* 建立与第三方WebSocket服务的连接
|
||||
*/
|
||||
private void connect() {
|
||||
WebSocketClient client = new StandardWebSocketClient();
|
||||
try {
|
||||
session = client.doHandshake(this, thirdPartyWsUrl).get();
|
||||
System.out.println("Connected to third-party WebSocket server");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
// 连接失败,安排重连
|
||||
scheduleReconnect();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安排重连任务
|
||||
*/
|
||||
private void scheduleReconnect() {
|
||||
reconnectExecutor.schedule(this::connect, 5, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订阅指定设备的状态变化
|
||||
* @param deviceId 设备ID
|
||||
*/
|
||||
public void subscribeDevice(String deviceId) {
|
||||
if (session != null && session.isOpen()) {
|
||||
try {
|
||||
// 发送订阅消息到第三方服务
|
||||
session.sendMessage(new TextMessage(
|
||||
String.format("{\"action\": \"subscribe\", \"deviceId\": \"%s\"}", deviceId)
|
||||
));
|
||||
subscribedDevices.put(deviceId, "subscribed");
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 向第三方服务发送指令
|
||||
* @param command 指令内容
|
||||
*/
|
||||
public void sendCommand(String command) {
|
||||
if (session != null && session.isOpen()) {
|
||||
try {
|
||||
session.sendMessage(new TextMessage(command));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理从第三方服务接收到的文本消息
|
||||
* @param session 会话
|
||||
* @param message 收到的消息
|
||||
*/
|
||||
@Override
|
||||
protected void handleTextMessage(WebSocketSession session, TextMessage message) {
|
||||
String payload = message.getPayload();
|
||||
// 处理设备状态变化消息
|
||||
processDeviceStatusChange(payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析设备状态变化消息并通知客户端
|
||||
* @param payload 消息内容
|
||||
*/
|
||||
private void processDeviceStatusChange(String payload) {
|
||||
// 解析消息并提取设备ID和状态
|
||||
String deviceId = extractDeviceId(payload);
|
||||
String status = extractStatus(payload);
|
||||
|
||||
if (deviceId != null && status != null) {
|
||||
// 通知所有连接的客户端设备状态变化
|
||||
deviceHandler.notifyDeviceChange(deviceId, status);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从消息中提取设备ID
|
||||
* 需要根据第三方服务的消息格式实现具体解析逻辑
|
||||
* @param payload 消息内容
|
||||
* @return 设备ID
|
||||
*/
|
||||
private String extractDeviceId(String payload) {
|
||||
// TODO: 实现JSON解析逻辑
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从消息中提取设备状态
|
||||
* 需要根据第三方服务的消息格式实现具体解析逻辑
|
||||
* @param payload 消息内容
|
||||
* @return 设备状态
|
||||
*/
|
||||
private String extractStatus(String payload) {
|
||||
// TODO: 实现JSON解析逻辑
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Tz
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.system.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import lombok.Data;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
import java.sql.Timestamp;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
import java.util.Set;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import me.zhengjie.modules.system.domain.dto.BusTreeVo;
|
||||
|
||||
/**
|
||||
* @description /
|
||||
* @author tz
|
||||
* @date 2025-05-20
|
||||
**/
|
||||
@Data
|
||||
@TableName("bus_device")
|
||||
public class BusDevice implements Serializable {
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
@ApiModelProperty(value = "设备唯一标识")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "设备序列号(唯一)")
|
||||
private String deviceSn;
|
||||
|
||||
@ApiModelProperty(value = "型号")
|
||||
private String model;
|
||||
|
||||
@ApiModelProperty(value = "品牌")
|
||||
private String brand;
|
||||
|
||||
@ApiModelProperty(value = "固件版本")
|
||||
private String firmwareVersion;
|
||||
|
||||
@ApiModelProperty(value = "放置位置")
|
||||
private String location;
|
||||
|
||||
@ApiModelProperty(value = "设备状态(1=在线,2=离线,3=故障)")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "最近上线时间")
|
||||
private Timestamp onlineTime;
|
||||
|
||||
@ApiModelProperty(value = "最近下线时间")
|
||||
private Timestamp offlineTime;
|
||||
|
||||
@ApiModelProperty(value = "累计时长(分钟)")
|
||||
private Integer totalPrintTime;
|
||||
|
||||
@ApiModelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
@ApiModelProperty(value = "类型:1打印机,2摄像头")
|
||||
private Integer type;
|
||||
|
||||
@ApiModelProperty(value = "创建者")
|
||||
private String createBy;
|
||||
|
||||
@ApiModelProperty(value = "更新者")
|
||||
private String updateBy;
|
||||
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private Timestamp createTime;
|
||||
|
||||
@ApiModelProperty(value = "更新时间")
|
||||
private Timestamp updateTime;
|
||||
|
||||
public void copy(BusDevice source){
|
||||
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Tz
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.system.domain;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
import java.sql.Timestamp;
|
||||
|
||||
/**
|
||||
* @description /
|
||||
* @author tz
|
||||
* @date 2025-05-21
|
||||
**/
|
||||
@Data
|
||||
@TableName("bus_device_command")
|
||||
public class BusDeviceCommand implements Serializable {
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
@ApiModelProperty(value = "指令唯一标识")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty(value = "指令代码(唯一)")
|
||||
private Long deviceId;
|
||||
|
||||
@ApiModelProperty(value = "指令名称")
|
||||
private String commandName;
|
||||
|
||||
@ApiModelProperty(value = "指令类型(1=控制,2=查询,3=校准)")
|
||||
private Integer commandType;
|
||||
|
||||
@ApiModelProperty(value = "指令描述")
|
||||
private String description;
|
||||
|
||||
@ApiModelProperty(value = "是否为系统指令(1=是,2=否)")
|
||||
private Integer isSystem;
|
||||
|
||||
@ApiModelProperty(value = "指令参数(JSON格式)")
|
||||
private String commandParams;
|
||||
|
||||
@ApiModelProperty(value = "创建者")
|
||||
private String createBy;
|
||||
|
||||
@ApiModelProperty(value = "更新者")
|
||||
private String updateBy;
|
||||
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private Timestamp createTime;
|
||||
|
||||
@ApiModelProperty(value = "更新时间")
|
||||
private Timestamp updateTime;
|
||||
|
||||
public void copy(BusDeviceCommand source){
|
||||
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
|
||||
}
|
||||
}
|
@ -18,15 +18,19 @@ package me.zhengjie.modules.system.domain;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import me.zhengjie.base.BaseEntity;
|
||||
import me.zhengjie.modules.system.domain.dto.BusTreeVo;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@ -61,6 +65,10 @@ public class BusUser extends BaseEntity implements Serializable {
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private Timestamp createTime;
|
||||
|
||||
@TableField(exist = false)
|
||||
@ApiModelProperty(value = "指令", hidden = true)
|
||||
private List<BusTreeVo> commands;
|
||||
|
||||
public void copy(BusUser source){
|
||||
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
|
||||
}
|
||||
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Tz
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.system.domain;
|
||||
|
||||
import lombok.Data;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
import java.sql.Timestamp;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
/**
|
||||
* @description /
|
||||
* @author tz
|
||||
* @date 2025-05-23
|
||||
**/
|
||||
@Data
|
||||
@TableName("bus_user_device_command")
|
||||
public class BusUserCommand implements Serializable {
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
@ApiModelProperty(value = "操作记录唯一标识")
|
||||
private Long id;
|
||||
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "用户ID(外键)")
|
||||
private Long userId;
|
||||
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "设备ID(外键)")
|
||||
private Long deviceId;
|
||||
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "指令ID(外键)")
|
||||
private Long commandId;
|
||||
|
||||
@ApiModelProperty(value = "创建者")
|
||||
private String createBy;
|
||||
|
||||
@ApiModelProperty(value = "更新者")
|
||||
private String updateBy;
|
||||
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private Timestamp createTime;
|
||||
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "更新时间")
|
||||
private Timestamp updateTime;
|
||||
|
||||
public void copy(BusUserCommand source){
|
||||
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
|
||||
}
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Tz
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.system.domain;
|
||||
|
||||
import lombok.Data;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
import java.sql.Timestamp;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.Serializable;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
|
||||
/**
|
||||
* @description /
|
||||
* @author tz
|
||||
* @date 2025-05-23
|
||||
**/
|
||||
@Data
|
||||
@TableName("bus_user_device")
|
||||
public class BusUserDevice implements Serializable {
|
||||
|
||||
@TableId(value = "id", type = IdType.AUTO)
|
||||
@ApiModelProperty(value = "绑定记录唯一标识")
|
||||
private Long id;
|
||||
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "用户ID(外键)")
|
||||
private Long userId;
|
||||
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "设备ID(外键)")
|
||||
private Long deviceId;
|
||||
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "是否为主用户(1=是,2=否)")
|
||||
private Integer isPrimary;
|
||||
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "绑定状态(1=有效,2=失效)")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty(value = "创建者")
|
||||
private String createBy;
|
||||
|
||||
@ApiModelProperty(value = "更新者")
|
||||
private String updateBy;
|
||||
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "创建时间")
|
||||
private Timestamp createTime;
|
||||
|
||||
@NotNull
|
||||
@ApiModelProperty(value = "更新时间")
|
||||
private Timestamp updateTime;
|
||||
|
||||
public void copy(BusUserDevice source){
|
||||
BeanUtil.copyProperties(source,this, CopyOptions.create().setIgnoreNullValue(true));
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Tz
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.system.domain.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author tz
|
||||
* @date 2025-05-21
|
||||
**/
|
||||
@Data
|
||||
public class BusCommandQueryCriteria {
|
||||
|
||||
@ApiModelProperty(value = "页码", example = "1")
|
||||
private Integer page = 1;
|
||||
|
||||
@ApiModelProperty(value = "每页数据量", example = "10")
|
||||
private Integer size = 10;
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Tz
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.system.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import me.zhengjie.modules.system.domain.BusDevice;
|
||||
|
||||
/**
|
||||
* @author tz
|
||||
* @date 2025-05-20
|
||||
**/
|
||||
@Data
|
||||
public class BusDeviceQueryCriteria extends BusDevice {
|
||||
|
||||
@ApiModelProperty(value = "页码", example = "1")
|
||||
private Integer page = 1;
|
||||
|
||||
@ApiModelProperty(value = "每页数据量", example = "10")
|
||||
private Integer size = 10;
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Tz
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.system.domain.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author tz
|
||||
* @date 2025-05-21
|
||||
**/
|
||||
@Data
|
||||
public class BusTreeVo {
|
||||
|
||||
@ApiModelProperty(value = "标识")
|
||||
private String id;
|
||||
|
||||
@ApiModelProperty(value = "上级")
|
||||
private String pid;
|
||||
|
||||
@ApiModelProperty(value = "名称")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
@ApiModelProperty(value = "子节点数目", hidden = true)
|
||||
private Integer subCount = 0;
|
||||
|
||||
@ApiModelProperty(value = "标签名称")
|
||||
public String getLabel() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "是否有子节点")
|
||||
public Boolean getHasChildren() {
|
||||
return subCount > 0;
|
||||
}
|
||||
|
||||
@ApiModelProperty(value = "是否为叶子")
|
||||
public Boolean getLeaf() {
|
||||
return subCount <= 0;
|
||||
}
|
||||
|
||||
}
|
@ -17,17 +17,19 @@ package me.zhengjie.modules.system.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import me.zhengjie.modules.system.domain.BusUser;
|
||||
|
||||
/**
|
||||
* @author tz
|
||||
* @date 2025-05-19
|
||||
**/
|
||||
@Data
|
||||
public class BusUserQueryCriteria{
|
||||
public class BusUserQueryCriteria extends BusUser {
|
||||
|
||||
@ApiModelProperty(value = "页码", example = "1")
|
||||
private Integer page = 1;
|
||||
|
||||
@ApiModelProperty(value = "每页数据量", example = "10")
|
||||
private Integer size = 10;
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
///*
|
||||
// * Copyright 2019-2025 Tz
|
||||
// *
|
||||
// * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// * you may not use this file except in compliance with the License.
|
||||
// * You may obtain a copy of the License at
|
||||
// *
|
||||
// * http://www.apache.org/licenses/LICENSE-2.0
|
||||
// *
|
||||
// * Unless required by applicable law or agreed to in writing, software
|
||||
// * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// * See the License for the specific language governing permissions and
|
||||
// * limitations under the License.
|
||||
// */
|
||||
//package me.zhengjie.modules.system.domain.enums;
|
||||
//
|
||||
///**
|
||||
// * @author ZhangHouYing
|
||||
// * @date 2019-08-10 9:56
|
||||
// */
|
||||
//public enum MsgType {
|
||||
// /** 连接 */
|
||||
// CONNECT,
|
||||
// /** 关闭 */
|
||||
// CLOSE,
|
||||
// /** 信息 */
|
||||
// INFO,
|
||||
// /** 错误 */
|
||||
// ERROR
|
||||
//}
|
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Tz
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.system.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.zhengjie.modules.system.domain.BusDevice;
|
||||
import me.zhengjie.modules.system.domain.BusDeviceCommand;
|
||||
import me.zhengjie.modules.system.domain.dto.BusCommandQueryCriteria;
|
||||
import me.zhengjie.modules.system.domain.dto.BusTreeVo;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
/**
|
||||
* @author tz
|
||||
* @date 2025-05-21
|
||||
**/
|
||||
@Mapper
|
||||
public interface BusCommandMapper extends BaseMapper<BusDeviceCommand> {
|
||||
|
||||
IPage<BusDeviceCommand> findAll(@Param("criteria") BusCommandQueryCriteria criteria, Page<Object> page);
|
||||
|
||||
List<BusDeviceCommand> findAll(@Param("criteria") BusCommandQueryCriteria criteria);
|
||||
|
||||
List<BusTreeVo> getCommandByDeviceId(@Param("pid") Long pid);
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Tz
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.system.mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import me.zhengjie.modules.system.domain.BusDevice;
|
||||
import me.zhengjie.modules.system.domain.dto.BusDeviceQueryCriteria;
|
||||
import me.zhengjie.modules.system.domain.dto.BusTreeVo;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
|
||||
/**
|
||||
* @author tz
|
||||
* @date 2025-05-20
|
||||
**/
|
||||
@Mapper
|
||||
public interface BusDeviceMapper extends BaseMapper<BusDevice> {
|
||||
|
||||
IPage<BusDevice> findAll(@Param("criteria") BusDeviceQueryCriteria criteria, Page<Object> page);
|
||||
|
||||
List<BusDevice> findAll(@Param("criteria") BusDeviceQueryCriteria criteria);
|
||||
|
||||
List<BusTreeVo> getDevice();
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Tz
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.system.mapper;
|
||||
|
||||
|
||||
import me.zhengjie.modules.system.domain.BusUserCommand;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author tz
|
||||
* @date 2025-05-23
|
||||
**/
|
||||
@Mapper
|
||||
public interface BusUserCommandMapper extends BaseMapper<BusUserCommand> {
|
||||
|
||||
void bindingCommand(@Param("userId") Long id, @Param("commandIds") List<Long> commandIds);
|
||||
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Tz
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.system.mapper;
|
||||
|
||||
|
||||
import me.zhengjie.modules.system.domain.BusUserDevice;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author tz
|
||||
* @date 2025-05-23
|
||||
**/
|
||||
@Mapper
|
||||
public interface BusUserDeviceMapper extends BaseMapper<BusUserDevice> {
|
||||
|
||||
void bindingDevice(@Param("userId") Long id, @Param("deviceIds") List<Long> deviceIds);
|
||||
|
||||
}
|
@ -18,6 +18,7 @@ package me.zhengjie.modules.system.mapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import me.zhengjie.modules.system.domain.BusUser;
|
||||
import me.zhengjie.modules.system.domain.dto.BusTreeVo;
|
||||
import me.zhengjie.modules.system.domain.dto.BusUserQueryCriteria;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
@ -38,4 +39,5 @@ public interface BusUserMapper extends BaseMapper<BusUser> {
|
||||
|
||||
List<BusUser> findAll(@Param("criteria") BusUserQueryCriteria criteria);
|
||||
|
||||
List<BusTreeVo> getUserCommands(@Param("userId") Long id);
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Tz
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.system.rest;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import me.zhengjie.annotation.Log;
|
||||
import me.zhengjie.modules.system.domain.BusDeviceCommand;
|
||||
import me.zhengjie.modules.system.domain.dto.BusCommandQueryCriteria;
|
||||
import me.zhengjie.modules.system.service.BusCommandService;
|
||||
import me.zhengjie.utils.PageResult;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author tz
|
||||
* @date 2025-05-21
|
||||
**/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@Api(tags = "系统:设备指令")
|
||||
@RequestMapping("/api/busDeviceCommand")
|
||||
public class BusCommandController {
|
||||
|
||||
private final BusCommandService busDeviceCommandService;
|
||||
|
||||
@GetMapping
|
||||
@ApiOperation("查询busCommand")
|
||||
@PreAuthorize("@el.check('busDeviceCommand:list')")
|
||||
public ResponseEntity<PageResult<BusDeviceCommand>> queryBusDeviceCommand(BusCommandQueryCriteria criteria){
|
||||
Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
|
||||
return new ResponseEntity<>(busDeviceCommandService.queryAll(criteria,page),HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Log("新增busCommand")
|
||||
@ApiOperation("新增busCommand")
|
||||
@PreAuthorize("@el.check('busDeviceCommand:add')")
|
||||
public ResponseEntity<Object> createBusDeviceCommand(@Validated @RequestBody BusDeviceCommand resources){
|
||||
busDeviceCommandService.create(resources);
|
||||
return new ResponseEntity<>(HttpStatus.CREATED);
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Log("修改busCommand")
|
||||
@ApiOperation("修改busCommand")
|
||||
@PreAuthorize("@el.check('busDeviceCommand:edit')")
|
||||
public ResponseEntity<Object> updateBusDeviceCommand(@Validated @RequestBody BusDeviceCommand resources){
|
||||
busDeviceCommandService.update(resources);
|
||||
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
@Log("删除busCommand")
|
||||
@ApiOperation("删除busCommand")
|
||||
@PreAuthorize("@el.check('busDeviceCommand:del')")
|
||||
public ResponseEntity<Object> deleteBusDeviceCommand(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
|
||||
busDeviceCommandService.deleteAll(ids);
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
}
|
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Tz
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.system.rest;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import me.zhengjie.annotation.Log;
|
||||
import me.zhengjie.modules.system.domain.BusDevice;
|
||||
import me.zhengjie.modules.system.domain.BusDeviceCommand;
|
||||
import me.zhengjie.modules.system.domain.Menu;
|
||||
import me.zhengjie.modules.system.domain.dto.BusDeviceQueryCriteria;
|
||||
import me.zhengjie.modules.system.domain.dto.BusTreeVo;
|
||||
import me.zhengjie.modules.system.service.BusCommandService;
|
||||
import me.zhengjie.modules.system.service.BusDeviceService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import io.swagger.annotations.*;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import me.zhengjie.utils.PageResult;
|
||||
|
||||
/**
|
||||
* @author tz
|
||||
* @date 2025-05-20
|
||||
**/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@Api(tags = "系统:设备管理")
|
||||
@RequestMapping("/api/busDevice")
|
||||
public class BusDeviceController {
|
||||
|
||||
private final BusDeviceService busDeviceService;
|
||||
private final BusCommandService busCommandService;
|
||||
|
||||
@ApiOperation("根据ID返回所有子节点ID,包含自身ID")
|
||||
@GetMapping(value = "/child")
|
||||
public ResponseEntity<Object> child(@RequestParam String id) {
|
||||
Long newId = Long.parseLong(id.replace("d", "").replace("c", ""));
|
||||
Set<BusTreeVo> menuSet = new HashSet<>();
|
||||
BusTreeVo set = new BusTreeVo();
|
||||
if (id.contains("d")) {
|
||||
BusDevice entity = busDeviceService.getById(newId);
|
||||
List<BusTreeVo> list = busDeviceService.getDeviceTree(newId);
|
||||
set.setId("d" + newId);
|
||||
set.setPid("0");
|
||||
set.setName("品牌:" + entity.getBrand() + " | " + "型号:" + entity.getModel());
|
||||
set.setRemark(entity.getLocation() + "[" + (entity.getType().equals(1) ? "3D打印机" : "摄像头") + "]");
|
||||
menuSet.add(set);
|
||||
menuSet.addAll(list);
|
||||
} else {
|
||||
BusDeviceCommand entity = busCommandService.getById(newId);
|
||||
set.setId("c" + newId);
|
||||
set.setPid("d" + entity.getDeviceId());
|
||||
set.setName(entity.getCommandName());
|
||||
set.setRemark(entity.getDescription());
|
||||
menuSet.add(set);
|
||||
}
|
||||
Set<String> ids = menuSet.stream().map(BusTreeVo::getId).collect(Collectors.toSet());
|
||||
return new ResponseEntity<>(ids,HttpStatus.OK);
|
||||
}
|
||||
|
||||
@ApiOperation("查询设备指令Tree")
|
||||
@GetMapping(value = "/getDeviceTree")
|
||||
public ResponseEntity<List<BusTreeVo>> getDeviceTree(@RequestParam String pid) {
|
||||
pid = pid.replace("d", "").replace("c", "");
|
||||
return new ResponseEntity<>(busDeviceService.getDeviceTree(Long.parseLong(pid)), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("getQrCode")
|
||||
@ApiOperation("查询busDevice")
|
||||
@PreAuthorize("@el.check('busDevice:qrCode')")
|
||||
public ResponseEntity<String> getQrCode(BusDeviceQueryCriteria criteria) {
|
||||
String qrCodeUrl = busDeviceService.getQrCode(criteria.getId());
|
||||
return new ResponseEntity<>(qrCodeUrl, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@ApiOperation("查询busDevice")
|
||||
@PreAuthorize("@el.check('busDevice:list')")
|
||||
public ResponseEntity<PageResult<BusDevice>> queryBusDevice(BusDeviceQueryCriteria criteria){
|
||||
Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
|
||||
return new ResponseEntity<>(busDeviceService.queryAll(criteria, page), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Log("新增busDevice")
|
||||
@ApiOperation("新增busDevice")
|
||||
@PreAuthorize("@el.check('busDevice:add')")
|
||||
public ResponseEntity<Object> createBusDevice(@Validated @RequestBody BusDevice resources){
|
||||
busDeviceService.create(resources);
|
||||
return new ResponseEntity<>(HttpStatus.CREATED);
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@Log("修改busDevice")
|
||||
@ApiOperation("修改busDevice")
|
||||
@PreAuthorize("@el.check('busDevice:edit')")
|
||||
public ResponseEntity<Object> updateBusDevice(@Validated @RequestBody BusDevice resources){
|
||||
busDeviceService.update(resources);
|
||||
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
@Log("删除busDevice")
|
||||
@ApiOperation("删除busDevice")
|
||||
@PreAuthorize("@el.check('busDevice:del')")
|
||||
public ResponseEntity<Object> deleteBusDevice(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
|
||||
busDeviceService.deleteAll(ids);
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package me.zhengjie.modules.system.rest;
|
||||
|
||||
import me.zhengjie.modules.system.service.socket.DeviceService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/api/printer")
|
||||
public class BusDeviceSocketController {
|
||||
|
||||
@Autowired DeviceService deviceService;
|
||||
|
||||
/**
|
||||
* 订阅设备状态变化的HTTP接口
|
||||
* @param deviceId 设备ID
|
||||
*/
|
||||
@PostMapping("/{deviceId}/subscribe")
|
||||
public void subscribe(@PathVariable String deviceId) {
|
||||
deviceService.subscribeToDevice(deviceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 向设备发送指令的HTTP接口
|
||||
* @param deviceId 设备ID
|
||||
* @param command 指令内容
|
||||
*/
|
||||
@PostMapping("/{deviceId}/command")
|
||||
public void sendCommand(@PathVariable String deviceId, @RequestBody String command) {
|
||||
deviceService.sendDeviceCommand(deviceId, command);
|
||||
}
|
||||
}
|
@ -17,7 +17,9 @@ package me.zhengjie.modules.system.rest;
|
||||
|
||||
import me.zhengjie.annotation.Log;
|
||||
import me.zhengjie.modules.system.domain.BusUser;
|
||||
import me.zhengjie.modules.system.domain.dto.BusTreeVo;
|
||||
import me.zhengjie.modules.system.domain.dto.BusUserQueryCriteria;
|
||||
import me.zhengjie.modules.system.service.BusUserDeviceService;
|
||||
import me.zhengjie.modules.system.service.BusUserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import java.util.List;
|
||||
@ -36,27 +38,44 @@ import me.zhengjie.utils.PageResult;
|
||||
**/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@Api(tags = "busUser")
|
||||
@Api(tags = "系统:系统用户")
|
||||
@RequestMapping("/api/busUser")
|
||||
public class BusUserController {
|
||||
|
||||
private final BusUserService busUserService;
|
||||
private final BusUserDeviceService busUserDeviceService;
|
||||
|
||||
@Log("修改用户设备指令")
|
||||
@ApiOperation("修改用户设备指令")
|
||||
@PutMapping(value = "/updUserCommands")
|
||||
@PreAuthorize("@el.check('roles:edit')")
|
||||
public ResponseEntity<Object> updUserCommands(@RequestBody BusUser busUser) {
|
||||
busUserDeviceService.updUserCommands(busUser);
|
||||
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
|
||||
@ApiOperation("查询用户信息")
|
||||
@GetMapping(value = "/{id}")
|
||||
@PreAuthorize("@el.check('busUser:list')")
|
||||
public ResponseEntity<BusUser> findUserById(@PathVariable Long id) {
|
||||
BusUser busUser = busUserService.getById(id);
|
||||
List<BusTreeVo> userCommands = busUserService.getUserCommands(busUser.getId());
|
||||
busUser.setCommands(userCommands);
|
||||
return new ResponseEntity<>(busUser, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping
|
||||
@ApiOperation("查询busUser")
|
||||
@PreAuthorize("@el.check('busUser:list')")
|
||||
public ResponseEntity<PageResult<BusUser>> queryBusUser(BusUserQueryCriteria criteria){
|
||||
Page<Object> page = new Page<>(criteria.getPage(), criteria.getSize());
|
||||
return new ResponseEntity<>(busUserService.queryAll(criteria,page),HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@Log("新增busUser")
|
||||
@ApiOperation("新增busUser")
|
||||
@PreAuthorize("@el.check('busUser:add')")
|
||||
public ResponseEntity<Object> createBusUser(@Validated @RequestBody BusUser resources){
|
||||
busUserService.create(resources);
|
||||
return new ResponseEntity<>(HttpStatus.CREATED);
|
||||
PageResult<BusUser> result = busUserService.queryAll(criteria, page);
|
||||
List<BusUser> content = result.getContent();
|
||||
for (BusUser busUser : content) {
|
||||
List<BusTreeVo> userCommands = busUserService.getUserCommands(busUser.getId());
|
||||
busUser.setCommands(userCommands);
|
||||
}
|
||||
return new ResponseEntity<>(result, HttpStatus.OK);
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@ -68,12 +87,4 @@ public class BusUserController {
|
||||
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
|
||||
@DeleteMapping
|
||||
@Log("删除busUser")
|
||||
@ApiOperation("删除busUser")
|
||||
@PreAuthorize("@el.check('busUser:del')")
|
||||
public ResponseEntity<Object> deleteBusUser(@ApiParam(value = "传ID数组[]") @RequestBody List<Long> ids) {
|
||||
busUserService.deleteAll(ids);
|
||||
return new ResponseEntity<>(HttpStatus.OK);
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Tz
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.system.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import me.zhengjie.modules.system.domain.BusDeviceCommand;
|
||||
import me.zhengjie.modules.system.domain.dto.BusCommandQueryCriteria;
|
||||
import me.zhengjie.utils.PageResult;
|
||||
|
||||
/**
|
||||
* @description 服务接口
|
||||
* @author tz
|
||||
* @date 2025-05-21
|
||||
**/
|
||||
public interface BusCommandService extends IService<BusDeviceCommand> {
|
||||
|
||||
/**
|
||||
* 查询数据分页
|
||||
* @param criteria 条件
|
||||
* @param page 分页参数
|
||||
* @return PageResult
|
||||
*/
|
||||
PageResult<BusDeviceCommand> queryAll(BusCommandQueryCriteria criteria, Page<Object> page);
|
||||
|
||||
/**
|
||||
* 查询所有数据不分页
|
||||
* @param criteria 条件参数
|
||||
* @return List<BusDeviceCommandDto>
|
||||
*/
|
||||
List<BusDeviceCommand> queryAll(BusCommandQueryCriteria criteria);
|
||||
|
||||
/**
|
||||
* 创建
|
||||
* @param resources /
|
||||
*/
|
||||
void create(BusDeviceCommand resources);
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param resources /
|
||||
*/
|
||||
void update(BusDeviceCommand resources);
|
||||
|
||||
/**
|
||||
* 多选删除
|
||||
* @param ids /
|
||||
*/
|
||||
void deleteAll(List<Long> ids);
|
||||
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Tz
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.system.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import me.zhengjie.modules.system.domain.BusDevice;
|
||||
import me.zhengjie.modules.system.domain.Menu;
|
||||
import me.zhengjie.modules.system.domain.dto.BusDeviceQueryCriteria;
|
||||
import me.zhengjie.modules.system.domain.dto.BusTreeVo;
|
||||
import me.zhengjie.utils.PageResult;
|
||||
|
||||
/**
|
||||
* @description 服务接口
|
||||
* @author tz
|
||||
* @date 2025-05-20
|
||||
**/
|
||||
public interface BusDeviceService extends IService<BusDevice> {
|
||||
|
||||
/**
|
||||
* 查询数据分页
|
||||
* @param criteria 条件
|
||||
* @param page 分页参数
|
||||
* @return PageResult
|
||||
*/
|
||||
PageResult<BusDevice> queryAll(BusDeviceQueryCriteria criteria, Page<Object> page);
|
||||
|
||||
/**
|
||||
* 查询所有数据不分页
|
||||
* @param criteria 条件参数
|
||||
* @return List<BusDeviceDto>
|
||||
*/
|
||||
List<BusDevice> queryAll(BusDeviceQueryCriteria criteria);
|
||||
|
||||
/**
|
||||
* 创建
|
||||
* @param resources /
|
||||
*/
|
||||
void create(BusDevice resources);
|
||||
|
||||
/**
|
||||
* 编辑
|
||||
* @param resources /
|
||||
*/
|
||||
void update(BusDevice resources);
|
||||
|
||||
/**
|
||||
* 多选删除
|
||||
* @param ids /
|
||||
*/
|
||||
void deleteAll(List<Long> ids);
|
||||
|
||||
String getQrCode(Long id);
|
||||
|
||||
void binding(String code);
|
||||
|
||||
List<BusTreeVo> getDeviceTree(Long pid);
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Tz
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.system.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import me.zhengjie.modules.system.domain.BusUser;
|
||||
import me.zhengjie.modules.system.domain.BusUserDevice;
|
||||
|
||||
/**
|
||||
* @description 服务接口
|
||||
* @author tz
|
||||
* @date 2025-05-23
|
||||
**/
|
||||
public interface BusUserDeviceService extends IService<BusUserDevice> {
|
||||
|
||||
void updUserCommands(BusUser busUser);
|
||||
|
||||
}
|
@ -15,16 +15,12 @@
|
||||
*/
|
||||
package me.zhengjie.modules.system.service;
|
||||
|
||||
import me.zhengjie.domain.BusUser;
|
||||
import me.zhengjie.domain.dto.BusUserQueryCriteria;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import me.zhengjie.modules.security.service.dto.JwtUserDto;
|
||||
import me.zhengjie.modules.system.domain.BusUser;
|
||||
import me.zhengjie.modules.system.domain.dto.BusTreeVo;
|
||||
import me.zhengjie.modules.system.domain.dto.BusUserQueryCriteria;
|
||||
import me.zhengjie.utils.PageResult;
|
||||
|
||||
@ -69,4 +65,7 @@ public interface BusUserService extends IService<BusUser> {
|
||||
* @param ids /
|
||||
*/
|
||||
void deleteAll(List<Long> ids);
|
||||
|
||||
List<BusTreeVo> getUserCommands(Long id);
|
||||
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Tz
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.system.service.impl;
|
||||
|
||||
import me.zhengjie.modules.system.domain.BusDeviceCommand;
|
||||
import me.zhengjie.modules.system.domain.dto.BusCommandQueryCriteria;
|
||||
import me.zhengjie.modules.system.mapper.BusCommandMapper;
|
||||
import me.zhengjie.modules.system.service.BusCommandService;
|
||||
import me.zhengjie.utils.FileUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import me.zhengjie.utils.PageUtil;
|
||||
import java.util.List;
|
||||
import me.zhengjie.utils.PageResult;
|
||||
|
||||
/**
|
||||
* @description 服务实现
|
||||
* @author tz
|
||||
* @date 2025-05-21
|
||||
**/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class BusCommandServiceImpl extends ServiceImpl<BusCommandMapper, BusDeviceCommand> implements BusCommandService {
|
||||
|
||||
private final BusCommandMapper busDeviceCommandMapper;
|
||||
|
||||
@Override
|
||||
public PageResult<BusDeviceCommand> queryAll(BusCommandQueryCriteria criteria, Page<Object> page){
|
||||
return PageUtil.toPage(busDeviceCommandMapper.findAll(criteria, page));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BusDeviceCommand> queryAll(BusCommandQueryCriteria criteria){
|
||||
return busDeviceCommandMapper.findAll(criteria);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void create(BusDeviceCommand resources) {
|
||||
busDeviceCommandMapper.insert(resources);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void update(BusDeviceCommand resources) {
|
||||
BusDeviceCommand busDeviceCommand = getById(resources.getId());
|
||||
busDeviceCommand.copy(resources);
|
||||
busDeviceCommandMapper.updateById(busDeviceCommand);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteAll(List<Long> ids) {
|
||||
busDeviceCommandMapper.deleteBatchIds(ids);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Tz
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.system.service.impl;
|
||||
|
||||
import me.zhengjie.exception.BadRequestException;
|
||||
import me.zhengjie.modules.front.service.WeChatService;
|
||||
import me.zhengjie.modules.system.domain.BusDevice;
|
||||
import me.zhengjie.modules.system.domain.Menu;
|
||||
import me.zhengjie.modules.system.domain.dto.BusDeviceQueryCriteria;
|
||||
import me.zhengjie.modules.system.domain.dto.BusTreeVo;
|
||||
import me.zhengjie.modules.system.mapper.BusCommandMapper;
|
||||
import me.zhengjie.modules.system.mapper.BusDeviceMapper;
|
||||
import me.zhengjie.modules.system.service.BusDeviceService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import me.zhengjie.utils.CacheKey;
|
||||
import me.zhengjie.utils.RedisUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import me.zhengjie.utils.PageUtil;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import me.zhengjie.utils.PageResult;
|
||||
|
||||
/**
|
||||
* @description 服务实现
|
||||
* @author tz
|
||||
* @date 2025-05-20
|
||||
**/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class BusDeviceServiceImpl extends ServiceImpl<BusDeviceMapper, BusDevice> implements BusDeviceService {
|
||||
|
||||
private final BusDeviceMapper busDeviceMapper;
|
||||
private final BusCommandMapper busCommandMapper;
|
||||
private final WeChatService weChatService;
|
||||
private final RedisUtils redisUtils;
|
||||
|
||||
@Override
|
||||
public PageResult<BusDevice> queryAll(BusDeviceQueryCriteria criteria, Page<Object> page){
|
||||
return PageUtil.toPage(busDeviceMapper.findAll(criteria, page));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BusDevice> queryAll(BusDeviceQueryCriteria criteria){
|
||||
return busDeviceMapper.findAll(criteria);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void create(BusDevice resources) {
|
||||
busDeviceMapper.insert(resources);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void update(BusDevice resources) {
|
||||
BusDevice busDevice = getById(resources.getId());
|
||||
busDevice.copy(resources);
|
||||
busDeviceMapper.updateById(busDevice);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteAll(List<Long> ids) {
|
||||
busDeviceMapper.deleteBatchIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getQrCode(Long id) {
|
||||
String code = (new Random().nextInt(900000) + 100000) + "";
|
||||
String qrCode = weChatService.getQrCode(id, code);
|
||||
redisUtils.set(CacheKey.QR_CODE + code, id, 1, TimeUnit.DAYS);
|
||||
return qrCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void binding(String code) {
|
||||
if (null == redisUtils.get(CacheKey.QR_CODE + code)) {
|
||||
throw new BadRequestException("二维码已过期,请联系管理员");
|
||||
}
|
||||
Long deviceId = Long.parseLong(redisUtils.get(CacheKey.QR_CODE + code).toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BusTreeVo> getDeviceTree(Long pid) {
|
||||
List<BusTreeVo> result;
|
||||
if(pid != null && !pid.equals(0L)){
|
||||
result = busCommandMapper.getCommandByDeviceId(pid);
|
||||
} else {
|
||||
result = busDeviceMapper.getDevice();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2019-2025 Tz
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package me.zhengjie.modules.system.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import me.zhengjie.modules.system.domain.BusUser;
|
||||
import me.zhengjie.modules.system.domain.BusUserCommand;
|
||||
import me.zhengjie.modules.system.domain.BusUserDevice;
|
||||
import me.zhengjie.modules.system.domain.dto.BusTreeVo;
|
||||
import me.zhengjie.modules.system.mapper.BusUserCommandMapper;
|
||||
import me.zhengjie.modules.system.mapper.BusUserDeviceMapper;
|
||||
import me.zhengjie.modules.system.service.BusUserDeviceService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @description 服务实现
|
||||
* @author tz
|
||||
* @date 2025-05-23
|
||||
**/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class BusUserDeviceServiceImpl extends ServiceImpl<BusUserDeviceMapper, BusUserDevice> implements BusUserDeviceService {
|
||||
|
||||
private final BusUserDeviceMapper busUserDeviceMapper;
|
||||
private final BusUserCommandMapper busUserCommandMapper;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void updUserCommands(BusUser busUser) {
|
||||
List<BusTreeVo> commands = busUser.getCommands();
|
||||
if (null == commands || commands.isEmpty()) { return; }
|
||||
List<BusTreeVo> userDevices = commands.stream().filter(i -> i.getId().contains("d")).collect(Collectors.toList());
|
||||
List<BusTreeVo> userCommands = commands.stream().filter(i -> i.getId().contains("c")).collect(Collectors.toList());
|
||||
List<BusUserDevice> oldUserDevices = busUserDeviceMapper.selectList(new LambdaQueryWrapper<BusUserDevice>().eq(BusUserDevice::getUserId, busUser.getId()));
|
||||
List<BusUserCommand> oldUserCommands = busUserCommandMapper.selectList(new LambdaQueryWrapper<BusUserCommand>().eq(BusUserCommand::getUserId, busUser.getId()));
|
||||
if (!oldUserDevices.isEmpty()) {
|
||||
List<Long> delIds = oldUserDevices.stream().map(i -> i.getId()).collect(Collectors.toList());
|
||||
busUserDeviceMapper.deleteBatchIds(delIds);
|
||||
}
|
||||
if (!oldUserCommands.isEmpty()) {
|
||||
List<Long> delIds = oldUserCommands.stream().map(i -> i.getId()).collect(Collectors.toList());
|
||||
busUserCommandMapper.deleteBatchIds(delIds);
|
||||
}
|
||||
if (!userDevices.isEmpty()) {
|
||||
List<Long> deviceIds = userDevices.stream().map(i -> Long.parseLong(i.getId().replace("d", ""))).collect(Collectors.toList());
|
||||
busUserDeviceMapper.bindingDevice(busUser.getId(), deviceIds);
|
||||
}
|
||||
if (!userCommands.isEmpty()) {
|
||||
List<Long> commandIds = userCommands.stream().map(i -> Long.parseLong(i.getId().replace("c", ""))).collect(Collectors.toList());
|
||||
busUserCommandMapper.bindingCommand(busUser.getId(), commandIds);
|
||||
}
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@ import me.zhengjie.modules.security.service.UserCacheManager;
|
||||
import me.zhengjie.modules.security.service.dto.JwtUserDto;
|
||||
import me.zhengjie.modules.system.domain.BusUser;
|
||||
import me.zhengjie.modules.system.domain.User;
|
||||
import me.zhengjie.modules.system.domain.dto.BusTreeVo;
|
||||
import me.zhengjie.modules.system.domain.dto.BusUserQueryCriteria;
|
||||
import me.zhengjie.modules.system.mapper.BusUserMapper;
|
||||
import me.zhengjie.modules.system.service.BusUserService;
|
||||
@ -29,6 +30,8 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import me.zhengjie.utils.PageUtil;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import me.zhengjie.utils.PageResult;
|
||||
@ -75,6 +78,11 @@ public class BusUserServiceImpl extends ServiceImpl<BusUserMapper, BusUser> impl
|
||||
busUserMapper.deleteBatchIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BusTreeVo> getUserCommands(Long id) {
|
||||
return busUserMapper.getUserCommands(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JwtUserDto addUserCache(BusUser BusUser) {
|
||||
String openId = BusUser.getToken();
|
||||
|
@ -0,0 +1,37 @@
|
||||
package me.zhengjie.modules.system.service.socket;
|
||||
|
||||
import me.zhengjie.modules.security.config.handler.ThirdPartyWebSocketClient;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 设备管理服务,提供与设备相关的业务逻辑
|
||||
*/
|
||||
@Service
|
||||
public class DeviceService {
|
||||
|
||||
private final ThirdPartyWebSocketClient webSocketClient;
|
||||
|
||||
public DeviceService(ThirdPartyWebSocketClient webSocketClient) {
|
||||
this.webSocketClient = webSocketClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* 订阅设备状态变化
|
||||
* @param deviceId 设备ID
|
||||
*/
|
||||
public void subscribeToDevice(String deviceId) {
|
||||
webSocketClient.subscribeDevice(deviceId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 向设备发送指令
|
||||
* @param deviceId 设备ID
|
||||
* @param command 指令内容
|
||||
*/
|
||||
public void sendDeviceCommand(String deviceId, String command) {
|
||||
// 构建符合第三方服务格式的指令
|
||||
String formattedCommand = String.format("{\"deviceId\": \"%s\", \"command\": \"%s\"}",
|
||||
deviceId, command);
|
||||
webSocketClient.sendCommand(formattedCommand);
|
||||
}
|
||||
}
|
@ -104,8 +104,13 @@ swagger:
|
||||
|
||||
# 微信信息配置
|
||||
weChat:
|
||||
appId: 1231321
|
||||
secret: 123123
|
||||
appId: wx583d0c321ef43dfe
|
||||
secret: 1b5eca11a1058361b0f14c5933ef6bd6
|
||||
|
||||
# socket地址
|
||||
thirdparty:
|
||||
ws:
|
||||
url: ws://127.0.0.1:3030/websocket
|
||||
|
||||
# 文件存储路径
|
||||
file:
|
||||
|
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="me.zhengjie.modules.system.mapper.BusCommandMapper">
|
||||
<resultMap id="BaseResultMap" type="me.zhengjie.modules.system.domain.BusDeviceCommand">
|
||||
<id column="id" property="id"/>
|
||||
<result column="device_id" property="deviceId"/>
|
||||
<result column="command_name" property="commandName"/>
|
||||
<result column="command_type" property="commandType"/>
|
||||
<result column="description" property="description"/>
|
||||
<result column="is_system" property="isSystem"/>
|
||||
<result column="command_params" property="commandParams"/>
|
||||
<result column="create_by" property="createBy"/>
|
||||
<result column="update_by" property="updateBy"/>
|
||||
<result column="create_time" property="createTime"/>
|
||||
<result column="update_time" property="updateTime"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="getCommandByDeviceId" resultType="me.zhengjie.modules.system.domain.dto.BusTreeVo">
|
||||
select CONCAT('c', id) id, CONCAT('d', device_id) pid, command_name name, description remark from bus_device_command where device_id = #{pid} order by id desc
|
||||
</select>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id, device_id, command_name, command_type, description, is_system, command_params, create_by, update_by, create_time, update_time
|
||||
</sql>
|
||||
|
||||
<select id="findAll" resultMap="BaseResultMap">
|
||||
select
|
||||
<include refid="Base_Column_List"/>
|
||||
from bus_device_command
|
||||
<where>
|
||||
</where>
|
||||
order by id desc
|
||||
</select>
|
||||
</mapper>
|
@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="me.zhengjie.modules.system.mapper.BusDeviceMapper">
|
||||
<resultMap id="BaseResultMap" type="me.zhengjie.modules.system.domain.BusDevice">
|
||||
<id column="id" property="id"/>
|
||||
<result column="device_sn" property="deviceSn"/>
|
||||
<result column="model" property="model"/>
|
||||
<result column="brand" property="brand"/>
|
||||
<result column="firmware_version" property="firmwareVersion"/>
|
||||
<result column="location" property="location"/>
|
||||
<result column="status" property="status"/>
|
||||
<result column="online_time" property="onlineTime"/>
|
||||
<result column="offline_time" property="offlineTime"/>
|
||||
<result column="total_print_time" property="totalPrintTime"/>
|
||||
<result column="remark" property="remark"/>
|
||||
<result column="type" property="type"/>
|
||||
<result column="create_by" property="createBy"/>
|
||||
<result column="update_by" property="updateBy"/>
|
||||
<result column="create_time" property="createTime"/>
|
||||
<result column="update_time" property="updateTime"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="getDevice" resultType="me.zhengjie.modules.system.domain.dto.BusTreeVo">
|
||||
select CONCAT('d', id) id, 0 pid, CONCAT('品牌:', brand, ' | ', '型号:', model) name, CONCAT(location, '[', IF(type=1, '3D打印机', '摄像头'), ']') remark,
|
||||
(select count(*) from bus_device_command dc where dc.device_id = bus_device.id) subCount
|
||||
from bus_device order by id desc
|
||||
</select>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id, device_sn, model, brand, firmware_version, location, status, online_time, offline_time, total_print_time, remark, type, create_by, update_by, create_time, update_time
|
||||
</sql>
|
||||
|
||||
<select id="findAll" resultMap="BaseResultMap">
|
||||
select
|
||||
<include refid="Base_Column_List"/>
|
||||
from bus_device
|
||||
<where>
|
||||
<if test="criteria.deviceSn != null and criteria.deviceSn != ''"> and device_sn like concat('%', #{criteria.deviceSn}, '%') </if>
|
||||
<if test="criteria.model != null and criteria.model != ''"> and model like concat('%', #{criteria.model}, '%') </if>
|
||||
<if test="criteria.brand != null and criteria.brand != ''"> and brand like concat('%', #{criteria.brand}, '%') </if>
|
||||
<if test="criteria.type != null"> and type = #{criteria.type} </if>
|
||||
</where>
|
||||
order by id desc
|
||||
</select>
|
||||
</mapper>
|
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="me.zhengjie.modules.system.mapper.BusUserCommandMapper">
|
||||
<resultMap id="BaseResultMap" type="me.zhengjie.modules.system.domain.BusUserCommand">
|
||||
<id column="id" property="id"/>
|
||||
<result column="user_id" property="userId"/>
|
||||
<result column="device_id" property="deviceId"/>
|
||||
<result column="command_id" property="commandId"/>
|
||||
<result column="create_by" property="createBy"/>
|
||||
<result column="update_by" property="updateBy"/>
|
||||
<result column="create_time" property="createTime"/>
|
||||
<result column="update_time" property="updateTime"/>
|
||||
</resultMap>
|
||||
|
||||
<insert id="bindingCommand">
|
||||
insert into bus_user_device_command (user_id, device_id, command_id)
|
||||
select #{userId}, device_id, id from bus_device_command where id in
|
||||
<foreach collection="commandIds" item="id" index="index" open="(" close=")" separator=",">
|
||||
#{id}
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id, user_id, device_id, command_id, create_by, update_by, create_time, update_time
|
||||
</sql>
|
||||
|
||||
<select id="findAll" resultMap="BaseResultMap">
|
||||
select
|
||||
<include refid="Base_Column_List"/>
|
||||
from bus_user_device_command
|
||||
<where>
|
||||
</where>
|
||||
order by id desc
|
||||
</select>
|
||||
</mapper>
|
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||
<mapper namespace="me.zhengjie.modules.system.mapper.BusUserDeviceMapper">
|
||||
<resultMap id="BaseResultMap" type="me.zhengjie.modules.system.domain.BusUserDevice">
|
||||
<id column="id" property="id"/>
|
||||
<result column="user_id" property="userId"/>
|
||||
<result column="device_id" property="deviceId"/>
|
||||
<result column="is_primary" property="isPrimary"/>
|
||||
<result column="status" property="status"/>
|
||||
<result column="create_by" property="createBy"/>
|
||||
<result column="update_by" property="updateBy"/>
|
||||
<result column="create_time" property="createTime"/>
|
||||
<result column="update_time" property="updateTime"/>
|
||||
</resultMap>
|
||||
|
||||
<insert id="bindingDevice">
|
||||
insert into bus_user_device (user_id, device_id) values
|
||||
<foreach collection="deviceIds" item="id" index="index" separator=",">
|
||||
(#{userId}, #{id})
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id, user_id, device_id, is_primary, status, create_by, update_by, create_time, update_time
|
||||
</sql>
|
||||
|
||||
<select id="findAll" resultMap="BaseResultMap">
|
||||
select
|
||||
<include refid="Base_Column_List"/>
|
||||
from bus_user_device
|
||||
<where>
|
||||
</where>
|
||||
order by id desc
|
||||
</select>
|
||||
</mapper>
|
@ -16,6 +16,12 @@
|
||||
<result column="update_time" property="updateTime"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="getUserCommands" resultType="me.zhengjie.modules.system.domain.dto.BusTreeVo">
|
||||
select CONCAT('d', d.id) id, 0 pid, CONCAT('品牌:', d.brand, ' | ', '型号:', d.model) name, CONCAT(d.location, '[', IF(d.type=1, '3D打印机', '摄像头'), ']') remark from bus_user_device ud inner join bus_device d on ud.device_id = d.id where ud.user_id = #{userId}
|
||||
union all
|
||||
select CONCAT('c', dc.id) id, CONCAT('d', dc.device_id) pid, dc.command_name name, dc.description remark from bus_user_device_command udc inner join bus_device_command dc on udc.command_id = dc.id where udc.user_id = #{userId}
|
||||
</select>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id, real_name, nickname, avatar, phone, status, token, sex, create_by, update_by, create_time, update_time
|
||||
</sql>
|
||||
@ -25,6 +31,9 @@
|
||||
<include refid="Base_Column_List"/>
|
||||
from bus_user
|
||||
<where>
|
||||
<if test="criteria.nickname != null and criteria.nickname != ''"> and nickname like concat('%', #{criteria.nickname}, '%') </if>
|
||||
<if test="criteria.phone != null and criteria.phone != ''"> and phone like concat('%', #{criteria.phone}, '%') </if>
|
||||
<if test="criteria.status != null"> and status = #{criteria.status} </if>
|
||||
</where>
|
||||
order by id desc
|
||||
</select>
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
<select id="getPieChatData" resultType="me.zhengjie.modules.system.domain.dto.DashboardDataVo">
|
||||
select t.text, t.value from (
|
||||
select case_type text, count(*) value from bus_law_enforcement GROUP BY case_type ORDER BY value desc
|
||||
select CONCAT(d.brand, ' | ', d.model) text, count(cl.id) value from bus_device d LEFT JOIN bus_command_log cl on d.id = cl.device_id GROUP BY d.id ORDER BY value desc
|
||||
) t limit 10
|
||||
</select>
|
||||
|
||||
@ -47,13 +47,13 @@
|
||||
select '前七天' text, count(1) value from sys_role where DATE(create_time) = CURDATE() - INTERVAL 7 DAY
|
||||
</if>
|
||||
<if test="type == 'law'">
|
||||
select '前一天' text, count(1) value from bus_law_enforcement where DATE(create_time) = CURDATE() - INTERVAL 1 DAY UNION ALL
|
||||
select '前两天' text, count(1) value from bus_law_enforcement where DATE(create_time) = CURDATE() - INTERVAL 2 DAY UNION ALL
|
||||
select '前三天' text, count(1) value from bus_law_enforcement where DATE(create_time) = CURDATE() - INTERVAL 3 DAY UNION ALL
|
||||
select '前四天' text, count(1) value from bus_law_enforcement where DATE(create_time) = CURDATE() - INTERVAL 4 DAY UNION ALL
|
||||
select '前五天' text, count(1) value from bus_law_enforcement where DATE(create_time) = CURDATE() - INTERVAL 5 DAY UNION ALL
|
||||
select '前六天' text, count(1) value from bus_law_enforcement where DATE(create_time) = CURDATE() - INTERVAL 6 DAY UNION ALL
|
||||
select '前七天' text, count(1) value from bus_law_enforcement where DATE(create_time) = CURDATE() - INTERVAL 7 DAY
|
||||
select '前一天' text, count(1) value from bus_command_log where DATE(create_time) = CURDATE() - INTERVAL 1 DAY UNION ALL
|
||||
select '前两天' text, count(1) value from bus_command_log where DATE(create_time) = CURDATE() - INTERVAL 2 DAY UNION ALL
|
||||
select '前三天' text, count(1) value from bus_command_log where DATE(create_time) = CURDATE() - INTERVAL 3 DAY UNION ALL
|
||||
select '前四天' text, count(1) value from bus_command_log where DATE(create_time) = CURDATE() - INTERVAL 4 DAY UNION ALL
|
||||
select '前五天' text, count(1) value from bus_command_log where DATE(create_time) = CURDATE() - INTERVAL 5 DAY UNION ALL
|
||||
select '前六天' text, count(1) value from bus_command_log where DATE(create_time) = CURDATE() - INTERVAL 6 DAY UNION ALL
|
||||
select '前七天' text, count(1) value from bus_command_log where DATE(create_time) = CURDATE() - INTERVAL 7 DAY
|
||||
</if>
|
||||
</select>
|
||||
|
||||
|
@ -10,8 +10,8 @@
|
||||
<modules>
|
||||
<module>eladmin-common</module>
|
||||
<module>eladmin-logging</module>
|
||||
<module>eladmin-tools</module>
|
||||
<module>eladmin-system</module>
|
||||
<module>eladmin-tools</module>
|
||||
<module>eladmin-generator</module>
|
||||
</modules>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user