Browse Source

1657 1656 1655 1654 1653 1652 1651 1650 1649 1648 1647 1646 1645

tags/v1.2.0
zhangtao 1 year ago
parent
commit
65e9b61be8
31 changed files with 2166 additions and 12 deletions
  1. +0
    -8
      index.html
  2. +117
    -0
      src/api/basic/material.js
  3. +66
    -0
      src/api/basic/monitor.js
  4. +77
    -0
      src/api/early/fire.js
  5. +0
    -1
      src/components/DataTable/tools/Switch.vue
  6. +1
    -1
      src/components/Dialog/index.vue
  7. +3
    -0
      src/router/guard/permission-guard.js
  8. +24
    -0
      src/utils/dictionary.js
  9. +69
    -0
      src/utils/global.js
  10. +2
    -2
      src/utils/http/interceptors.js
  11. +61
    -0
      src/views/basic-manage/material/components/CustomForm.vue
  12. +145
    -0
      src/views/basic-manage/material/components/MaterialDrawer.vue
  13. +140
    -0
      src/views/basic-manage/material/components/MaterialModal.vue
  14. +157
    -0
      src/views/basic-manage/material/components/StoreModal.vue
  15. +100
    -0
      src/views/basic-manage/material/index.vue
  16. +29
    -0
      src/views/basic-manage/material/tools/form.js
  17. +22
    -0
      src/views/basic-manage/material/tools/materialForm.js
  18. +22
    -0
      src/views/basic-manage/material/tools/materialSearch.js
  19. +142
    -0
      src/views/basic-manage/material/tools/materialTable.js
  20. +12
    -0
      src/views/basic-manage/material/tools/search.js
  21. +140
    -0
      src/views/basic-manage/material/tools/table.js
  22. +68
    -0
      src/views/basic-manage/monitor/components/CustomForm.vue
  23. +158
    -0
      src/views/basic-manage/monitor/components/MonitorModal.vue
  24. +96
    -0
      src/views/basic-manage/monitor/index.vue
  25. +43
    -0
      src/views/basic-manage/monitor/tools/form.js
  26. +13
    -0
      src/views/basic-manage/monitor/tools/search.js
  27. +140
    -0
      src/views/basic-manage/monitor/tools/table.js
  28. +124
    -0
      src/views/early-warning/fire/components/FireModal.vue
  29. +64
    -0
      src/views/early-warning/fire/index.vue
  30. +36
    -0
      src/views/early-warning/fire/tools/search.js
  31. +95
    -0
      src/views/early-warning/fire/tools/table.js

+ 0
- 8
index.html View File

@@ -1,11 +1,3 @@
<!--
* @Author: whyafterme
* @Date: 2023-01-12 10:22:37
* @LastEditTime: 2023-01-14 15:20:35
* @LastEditors: whyafterme
* @Description:
* @FilePath: \forest\index.html
-->
<!DOCTYPE html>
<html lang="en">
<head>

+ 117
- 0
src/api/basic/material.js View File

@@ -0,0 +1,117 @@
import { defAxios as request } from '@/utils/http'

/**
* @description: 查询仓库列表
* @param {Object} params
* @return {Object}
*/
export function materialList(params) {
return request({
url: '/warehouse/list',
method: 'get',
params
})
}

/**
* @description: 分页查询仓库列表
* @param {Object} params
* @return {Object}
*/
export function materialPage(params) {
return request({
url: '/warehouse/page/list',
method: 'get',
params
})
}

/**
* @description: 添加仓库
* @param {String} params
* @return {*}
*/
export function createMaterial(data) {
return request({
url: '/warehouse/add',
method: 'post',
data
})
}

/**
* @description: 编辑仓库
* @param {String} params
* @return {*}
*/
export function updateMaterial(data) {
return request({
url: '/warehouse/edit',
method: 'put',
data
})
}

/**
* @description: 删除仓库
* @param {String} params
* @return {*}
*/
export function deleteMaterial(ids) {
return request({
url: `/warehouse/delete/${ids}`,
method: 'delete'
})
}

/**
* @description: 根据仓库查询物资列表
* @param {String} params
* @return {*}
*/
export function goodsList(params) {
return request({
url: `/goods/list/by/warehouseid`,
method: 'get',
params
})
}

/**
* @description: 添加物资
* @param {String} params
* @return {*}
*/
export function createGoods(data) {
return request({
url: '/goods/add',
method: 'post',
data
})
}

/**
* @description: 编辑物资
* @param {String} params
* @return {*}
*/
export function updateGoods(data) {
return request({
url: '/goods/edit',
method: 'put',
data
})
}

/**
* @description: 删除物资
* @param {String} params
* @return {*}
*/
export function deleteGoods(ids) {
return request({
url: `/goods/delete/${ids}`,
method: 'delete'
})
}


+ 66
- 0
src/api/basic/monitor.js View File

@@ -0,0 +1,66 @@
import { defAxios as request } from '@/utils/http'

/**
* @description: 查询摄像头列表
* @param {Object} params
* @return {Object}
*/
export function cameraList(params) {
return request({
url: '/camera/list',
method: 'get',
params
})
}

/**
* @description: 分页查询摄像头列表
* @param {Object} params
* @return {Object}
*/
export function cameraPage(params) {
return request({
url: '/camera/page',
method: 'get',
params
})
}

/**
* @description: 添加摄像头
* @param {String} params
* @return {*}
*/
export function createCamera(data) {
return request({
url: '/camera/add',
method: 'post',
data
})
}

/**
* @description: 编辑摄像头
* @param {String} params
* @return {*}
*/
export function updateCamera(data) {
return request({
url: '/camera/edit',
method: 'put',
data
})
}

/**
* @description: 删除摄像头
* @param {String} params
* @return {*}
*/
export function deleteCamera(ids) {
return request({
url: `/camera/delete/${ids}`,
method: 'delete'
})
}


+ 77
- 0
src/api/early/fire.js View File

@@ -0,0 +1,77 @@
import { defAxios as request } from '@/utils/http'

/**
* @description: 查询仓库列表
* @param {Object} params
* @return {Object}
*/
export function materialList(params) {
return request({
url: '/warehouse/list',
method: 'get',
params
})
}

/**
* @description: 分页查询预警列表
* @param {Object} params
* @return {Object}
*/
export function firePage(params) {
return request({
url: '/warning/index',
method: 'get',
params
})
}

/**
* @description: 查询预警问题详情
* @param {Number} id
* @return {Object}
*/
export function fireDetail(id) {
return request({
url: `/warning/details/${id}`,
method: 'get'
})
}

/**
* @description: 预警心跳
* @param {String} params
* @return {*}
*/
export function fireHeart() {
return request({
url: '/warning/notice',
method: 'get'
})
}

/**
* @description: 预警通知与处理
* @param {String} params
* @return {*}
*/
export function updateWarning(id, status) {
return request({
url: `/warning/status/${id}/${status}`,
method: 'put',
hideMessage: true
})
}

/**
* @description: 删除仓库
* @param {String} params
* @return {*}
*/
export function deleteMaterial(ids) {
return request({
url: `/warehouse/delete/${ids}`,
method: 'delete'
})
}


+ 0
- 1
src/components/DataTable/tools/Switch.vue View File

@@ -27,7 +27,6 @@ export default defineComponent({
return value
})
const getSwitchProps = computed(() => {
console.log(111)
return {
...unref(props)
}

+ 1
- 1
src/components/Dialog/index.vue View File

@@ -38,7 +38,7 @@ class Dialog {
negativeText: '取消',
onPositiveClick: option.confirm,
onNegativeClick: option.cancel,
onMaskClick: option.cancel,
onMaskClick: option.mask ?? option.cancel,
...option
})
}

+ 3
- 0
src/router/guard/permission-guard.js View File

@@ -3,6 +3,7 @@ import { usePermissionStore } from '@/store/modules/permission.js'
import { NOT_FOUND_ROUTE, REDIRECT_ROUTE } from '@/router/routes'
import { getQuestion } from '@/utils/question.js'
import { getQuestionList } from '@/utils/dictionary.js'
import { getTimer, timerHeart } from '@/utils/global.js'
import { getToken } from '@/utils/token'

const WHITE_LIST = ['/login', '/redirect']
@@ -18,8 +19,10 @@ export function createPermissionGuard(router) {
const hasUsers = !!Object.keys(userStore.userInfoMsg).length
const hasRoutes = !!permissionStore.permissionRoutes.length
const hasQuestions = getQuestion()
const hasTimerHearts = getTimer()
if (!hasUsers) { await userStore.getUserInfo() }
if (!hasQuestions) { await getQuestionList() }
if (!hasTimerHearts) { await timerHeart() }
if (hasRoutes) {
next()
} else {

+ 24
- 0
src/utils/dictionary.js View File

@@ -78,6 +78,30 @@ export const MENU_STATUS = [
{ label: '停用', value: 2 }
]

export const MONITOR_OPTIONS = [
{ label: '枪机', value: 1 },
{ label: '球机', value: 2 }
]

export const MATERIAL_TYPE = [
{ label: '个人防护装备', value: 1 },
{ label: '搜救装备', value: 2 },
{ label: '医疗及防疫设备及常用应急药品', value: 3 },
{ label: '应急照明设备', value: 4 },
{ label: '灭火处置设备', value: 5 }
]

export const EARLY_SOURCE = [
{ label: '无人机巡检', value: 1 },
{ label: '监控识别', value: 2 },
{ label: '人工上报', value: 3 }
]
export const FIRE_STATUS = [
{ label: '待确认', value: 1 },
{ label: '确认', value: 2 },
{ label: '忽略', value: 3 }
]

export const getQuestionList = async function() {
const res = await getQuestionType()
if (res.code === 0) {

+ 69
- 0
src/utils/global.js View File

@@ -0,0 +1,69 @@
import { getToken } from './token.js'
import { fireHeart, updateWarning } from '@/api/early/fire.js'
import { router } from '@/router/index.js'
import { ref } from 'vue'
const hasModal = ref(false)
const hasTimer = ref(false)

export const getTimer = () => {
return hasTimer.value
}

export const timerHeart = async function() {
if (getToken()) {
hasTimer.value = true
const res = await fireHeart()
if (res.code === 0) {
const list = res.data ?? []
const ids = list.map(item => item.id)
const dealList = []
if (res.data && !hasModal.value) {
hasModal.value = true
$dialog.confirm(
{
type: 'success',
title: '火情通知',
showIcon: false,
maskClosable: false,
positiveText: '处理',
negativeText: '忽略',
content: `发现疑似火灾,请及时处理`,
confirm: () => {
router.push({ path: '/' })
hasModal.value = false
ids.forEach(item => {
dealList.push(dealWarnings(item, 2))
})
Promise.all(dealList)
},
cancel: () => {
hasModal.value = false
ids.forEach(item => {
dealList.push(dealWarnings(item, 3))
})
Promise.all(dealList)
},
mask: () => {

}
}
)
}
setTimeout(() => {
timerHeart()
}, 5000)
}
} else {
hasModal.value = false
hasTimer.value = false
}
}

const dealWarnings = function(id, status) {
return new Promise((resolve, reject) => {
updateWarning(id, status)
.then(res => {
resolve()
})
})
}

+ 2
- 2
src/utils/http/interceptors.js View File

@@ -35,7 +35,7 @@ export function setupInterceptor(service) {

service.interceptors.response.use(
(response) => {
const { method } = response?.config
const { method, hideMessage = false } = response?.config
const { code } = response?.data
const { currentRoute } = router
switch (code) {
@@ -43,7 +43,7 @@ export function setupInterceptor(service) {
$message.error(response.data.msg)
break
case 0:
if (method !== 'get') {
if (method !== 'get' && !hideMessage) {
$message.success(response.data.msg)
}
break

+ 61
- 0
src/views/basic-manage/material/components/CustomForm.vue View File

@@ -0,0 +1,61 @@
<template>
<div class="custom-form">
<n-grid x-gap="12" :cols="2">
<n-gi>
<n-form-item class="hidden__feedback">
<n-input v-model:value="longitude" placeholder="请输入经度" clearable @blur="handleBlur" />
</n-form-item>
</n-gi>
<n-gi>
<n-form-item class="hidden__feedback">
<n-input v-model:value="latitude" placeholder="请输入纬度" clearable @blur="handleBlur" />
</n-form-item>
</n-gi>
</n-grid>
</div>
</template>

<script>
import { reactive, watch, toRefs } from 'vue'
export default {
name: 'CustomForm',
props: {
value: {
type: Object,
default: () => {}
}
},
emits: ['done'],
setup(props, { emit }) {
const data = reactive({
longitude: '',
latitude: '',
...props.value
})

// watch(data, (val) => {
// emit('done', val)
// })

const handleBlur = () => {
emit('done', data)
}

return {
...toRefs(data),
handleBlur
}
}
}

</script>
<style scoped lang='scss'>
.custom-form{
width: 100%;
}
::v-deep(.hidden__feedback){
.n-form-item-feedback-wrapper{
display: none;
}
}
</style>

+ 145
- 0
src/views/basic-manage/material/components/MaterialDrawer.vue View File

@@ -0,0 +1,145 @@
<template>
<n-drawer v-bind="getDrawerOptions" @update:show="handleDrawerColse">
<n-drawer-content closable title="物资管理">
<HeadSearch :info="search" @search="handleSearch" @reset="handleSearch" />
<DataTable
ref="tableRef"
:columns="columns"
:row-key="(row) => row.id"
:request="loadDataTable"
size="large"
>
<template #tableTitle>
<n-button type="primary" @click="handleModal"> 新建 </n-button>
</template>
</DataTable>

<!-- 新增、编辑弹窗 -->
<MaterialModal v-if="modalShow" v-model:visible="modalShow" :type="modalType" :warehouse-id="data.id" :data="rowData" @reload="handleSearch" />
</n-drawer-content>
</n-drawer>

</template>

<script>
import table from '../tools/materialTable.js'
import { search } from '../tools/materialSearch.js'
import HeadSearch from '@/components/Search/index.vue'
import DataTable from '@/components/DataTable/index.vue'
import MaterialModal from './MaterialModal.vue'
import { defineComponent, reactive, unref, toRefs, computed, watch } from 'vue'
import { goodsList } from '@/api/basic/material.js'

export default defineComponent({
name: 'LiveDrawer',
components: { HeadSearch, MaterialModal, DataTable },
props: {
/* 可见 */
visible: {
type: Boolean,
default: false
},
/* 选中的数据 */
data: {
type: Object,
default: () => {}
}
},
emits: {
'update:visible': null
},
setup(props, { emit }) {
const data = reactive({
...toRefs(search),
...toRefs(table),
warehouseId: null
})

/* 获取抽屉的信息 */
const getDrawerOptions = computed(() => {
return {
show: props.visible,
width: '100%',
placement: 'right'
}
})
/* 关闭抽屉 */
function handleDrawerColse() {
emit('update:visible', false)
}

const loadDataTable = async(res) => {
const _params = {
...unref(data.searchParams),
warehouseId: props.data.id,
...res
}
return await goodsList(_params)
}

// 新增
function handleModal() {
data.rowData = null
data.modalType = 'create'
data.modalShow = true
}

return {
...toRefs(data),
getDrawerOptions,
handleDrawerColse,
loadDataTable,
handleModal
}
}
})
</script>

<style scoped lang='scss'>
.report__container{
width: 900px;
margin: 0 auto 40px auto;
.report__item{
margin-bottom: 40px;
.report__item--title{
font-size: 18px;
color: #333333;
line-height: 44px;
}
.n-grid{
border-top: 1px solid rgba(216, 216, 216, 1);
border-left: 1px solid rgba(216, 216, 216, 1);
>div{
position: relative;
text-align: center;
font-size: 14px;
color: #333333;
line-height: 20px;
padding: 6px 12px;
word-wrap: break-word;
word-break: normal;
border-right: 1px solid rgba(216, 216, 216, 1);
border-bottom: 1px solid rgba(216, 216, 216, 1);
&:nth-child(2n-1){
span{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
background: rgba(228, 231, 237, 1);
}
}
}
}
.report__operate{
text-align: center;
}
}
::v-deep(.n-image){
width: 100%;
img{
width: 100%;
}
}
</style>

+ 140
- 0
src/views/basic-manage/material/components/MaterialModal.vue View File

@@ -0,0 +1,140 @@
<template>
<Modal
:options="getModalOptions"
:on-positive-click="handleConfirm"
:on-negative-click="handleClose"
:on-close="handleClose"
>
<template #Context>
<n-form
ref="formRef"
:model="materialForm"
:rules="materialRules"
:label-width="100"
label-placement="left"
require-mark-placement="left"
:disabled="disabled"
>
<template v-for="(item,index) in getFormOptions" :key="index">
<n-form-item :label="item.label" :path="item.key">
<n-input v-if="item.type === 'input'" v-model:value="materialForm[item.key]" v-bind="item.props" />
<n-select v-if="item.type === 'select'" v-model:value="materialForm[item.key]" v-bind="item.props" />
</n-form-item>
</template>
</n-form>
</template>
</Modal>
</template>

<script>
import { form } from '../tools/materialForm.js'
import { defineComponent, ref, reactive, computed, toRefs } from 'vue'
import Modal from '@/components/Modal/index.vue'
import { createGoods, updateGoods } from '@/api/basic/material.js'

export default defineComponent({
name: 'UserModal',
components: { Modal },
props: {
visible: {
type: Boolean,
default: false
},
type: {
type: String,
default: 'create'
},
warehouseId: {
type: Number,
default: null
},
data: {
type: Object,
default: () => null
}
},
emits: {
'update:visible': null,
'reload': null
},
setup(props, { emit }) {
const MODAL_TYPE = {
'create': '新增物资',
'preview': '物资详情',
'update': '编辑物资'
}
const { materialForm, materialRules } = form
const formRef = ref()
const data = reactive({
materialForm: {
...materialForm,
...props.data,
warehouseId: props.warehouseId
},
materialRules: {
...materialRules
},
disabled: props.type === 'preview'
})
const getModalOptions = computed(() => {
return {
show: props.visible,
title: MODAL_TYPE[props.type],
negativeText: '取消',
positiveText: '确认'
}
})

const getFormOptions = computed(() => {
return {
...form.formItem
}
})

function handleConfirm() {
formRef.value?.validate((errors) => {
if (!errors) {
const params = {
...data.materialForm
}
if (params.id) {
updateGoods(params)
.then(res => {
if (res.code === 0) {
emit('reload')
handleClose()
}
})
} else {
/* 新增 */
createGoods(params)
.then(res => {
if (res.code === 0) {
emit('reload')
handleClose()
}
})
}
} else {
$message.error('请完善必填信息')
}
})
}

/* 关闭弹窗 */
const handleClose = () => {
emit('update:visible', false)
}
return {
...toRefs(data),
formRef,
getModalOptions,
getFormOptions,
handleConfirm,
handleClose
}
}
})
</script>
<style scoped lang='scss'>
</style>

+ 157
- 0
src/views/basic-manage/material/components/StoreModal.vue View File

@@ -0,0 +1,157 @@
<template>
<Modal
:options="getModalOptions"
:on-positive-click="handleConfirm"
:on-negative-click="handleClose"
:on-close="handleClose"
>
<template #Context>
<n-form
ref="formRef"
:model="materialForm"
:rules="materialRules"
:label-width="100"
label-placement="left"
require-mark-placement="left"
:disabled="disabled"
>
<template v-for="(item,index) in getFormOptions" :key="index">
<n-form-item :label="item.label" :path="item.key">
<n-input v-if="item.type === 'input'" v-model:value="materialForm[item.key]" v-bind="item.props" />
<CustomForm v-if="item.type === 'customPos'" v-model:value="materialForm" @done="validatePartial" />
</n-form-item>
</template>
</n-form>
</template>
</Modal>
</template>

<script>
import { form, changeMessage } from '../tools/form.js'
import { defineComponent, ref, reactive, computed, toRefs } from 'vue'
import Modal from '@/components/Modal/index.vue'
import CustomForm from './CustomForm.vue'
import { createMaterial, updateMaterial } from '@/api/basic/material.js'
export default defineComponent({
name: 'UserModal',
components: { Modal, CustomForm },
props: {
visible: {
type: Boolean,
default: false
},
type: {
type: String,
default: 'create'
},
data: {
type: Object,
default: () => null
}
},
emits: {
'update:visible': null,
'reload': null
},
setup(props, { emit }) {
const MODAL_TYPE = {
'create': '新建仓库',
'preview': '仓库详情',
'update': '编辑仓库'
}
const { materialForm, materialRules } = form
const formRef = ref()
const data = reactive({
materialForm: {
...materialForm,
...props.data,
customPos: props?.data?.id ? 'pass' : null
},
materialRules: {
...materialRules
},
disabled: props.type === 'preview'
})
const getModalOptions = computed(() => {
return {
show: props.visible,
title: MODAL_TYPE[props.type],
negativeText: '取消',
positiveText: '确认'
}
})

const getFormOptions = computed(() => {
return {
...form.formItem
}
})

const validatePartial = (form) => {
data.materialForm.customPos = null
if (form.longitude && form.latitude) {
data.materialForm.customPos = 'pass'
const { latitude, longitude } = form
data.materialForm.longitude = Number(longitude)
data.materialForm.latitude = Number(latitude)
}
formRef.value?.validate(
(errors) => {
if (errors) {
console.error(1111)
}
},
(rule) => {
return rule?.key === 'custom'
}
)
}

function handleConfirm() {
formRef.value?.validate((errors) => {
if (!errors) {
const params = {
...data.materialForm
}
if (params.id) {
updateMaterial(params)
.then(res => {
if (res.code === 0) {
emit('reload')
handleClose()
}
})
} else {
/* 新增 */
createMaterial(params)
.then(res => {
if (res.code === 0) {
emit('reload')
handleClose()
}
})
}
} else {
$message.error('请完善必填信息')
}
})
}

/* 关闭弹窗 */
const handleClose = () => {
emit('update:visible', false)
}
return {
...toRefs(data),
formRef,
getModalOptions,
getFormOptions,
validatePartial,
handleConfirm,
handleClose
}
}
})
</script>
<style scoped lang='scss'>
</style>

+ 100
- 0
src/views/basic-manage/material/index.vue View File

@@ -0,0 +1,100 @@
<template>
<div>
<n-card>
<headSearch :info="search" @search="handleSearch" @reset="handleSearch" />
<data-table
ref="tableRef"
:columns="columns"
:row-key="(row) => row.id"
:request="loadDataTable"
size="large"
@update:checked-row-keys="handleCheck"
>
<template #tableTitle>
<n-button type="primary" @click="handleModal"> 新建 </n-button>
</template>
</data-table>
</n-card>
</div>

<!-- 新增、编辑弹窗 -->
<StoreModal v-if="modalShow" v-model:visible="modalShow" :type="modalType" :data="rowData" @reload="handleSearch" />

<MaterialDrawer v-model:visible="drawerShow" :data="rowData" />

</template>
<script>
import { search } from './tools/search.js'
import table from './tools/table.js'
import headSearch from '@/components/Search/index.vue'
import dataTable from '@/components/DataTable/index.vue'
import StoreModal from './components/StoreModal.vue'
import MaterialDrawer from './components/MaterialDrawer.vue'
import { materialPage } from '@/api/basic/material.js'
import { unref, ref, toRefs, reactive, onUnmounted } from 'vue'

export default {
name: 'MenuPage',
components: { dataTable, StoreModal, MaterialDrawer, headSearch },
setup() {
const data = reactive({
...toRefs(table),
...toRefs(search)
})

const loadDataTable = async(res) => {
const _params = {
...unref(data.searchParams),
...res
}
return await materialPage(_params)
}

// 新增
function handleModal() {
data.rowData = null
data.modalType = 'create'
data.modalShow = true
}

// 选择表格数据
const selectedIds = ref([])
function handleCheck(rowKeys) {
selectedIds.value = rowKeys
}

// 批量删除
function deleteComplex() {
if (selectedIds.value.length) {
data.deleteData(selectedIds.value)
} else {
$message.warning('请至少选中一条数据')
}
}

onUnmounted(() => {
data.searchParams = null
})

return {
...toRefs(data),
loadDataTable,
handleModal,
selectedIds,
deleteComplex,
handleCheck
}
},
methods: {

}
}
</script>

<style scoped lang='scss'>
</style>
<style scoped lang='scss'>
.n-button + .n-button {
margin-left: 10px;
}
</style>

+ 29
- 0
src/views/basic-manage/material/tools/form.js View File

@@ -0,0 +1,29 @@
import { reactive } from 'vue'
export const form = reactive({
materialForm: {
warehouseName: null,
customPos: null
},
materialRules: {
warehouseName: [{ required: true, message: '请输入仓库名称', trigger: 'blur' }],
customPos: [{ key: 'custom', required: true, message: '请输入仓库位置', trigger: ['blur', 'change'] }]
},
formItem: [
{ type: 'input', key: 'warehouseName', label: '仓库名称', props: { maxlength: '20', placeholder: '请输入仓库名称', clearable: true }},
{ type: 'customPos', key: 'customPos', label: '仓库位置' }
]
})

export const changeMessage = (type) => {
const list = form.materialRules.customPos
switch (type) {
case 'lng':
list[0].message = '请输入经度'
break
case 'lat':
list[0].message = '请输入纬度'
break
default:
list[0].message = '请输入经度'
}
}

+ 22
- 0
src/views/basic-manage/material/tools/materialForm.js View File

@@ -0,0 +1,22 @@
import { reactive } from 'vue'
import { MATERIAL_TYPE } from '@/utils/dictionary.js'
export const form = reactive({
materialForm: {
goodsName: null,
goodsType: null,
goodsStock: null,
goodsAction: null
},
materialRules: {
goodsName: [{ required: true, message: '请输入物资名称', trigger: 'blur' }],
goodsType: [{ required: true, message: '请选择物资类型', type: 'number', trigger: 'blur' }],
goodsStock: [{ required: true, message: '请输入物资库存', trigger: 'blur' }]
},
formItem: [
{ type: 'input', key: 'goodsName', label: '物资名称', props: { maxlength: '20', placeholder: '请输入物资名称', clearable: true }},
{ type: 'select', key: 'goodsType', label: '物资类型', props: { options: MATERIAL_TYPE, placeholder: '请选择物资类型' }},
{ type: 'input', key: 'goodsStock', label: '物资库存', props: { maxlength: '20', placeholder: '请输入物资库存,如12箱', clearable: true }},
{ type: 'input', key: 'goodsAction', label: '物资作用', props: { type: 'textarea', autosize: { maxlength: '200', minRows: 3, maxRows: 3 }}}
]
})


+ 22
- 0
src/views/basic-manage/material/tools/materialSearch.js View File

@@ -0,0 +1,22 @@
import { reactive } from 'vue'
import { MATERIAL_TYPE } from '@/utils/dictionary.js'
export const search = reactive({
search: [
{
label: '物资名称',
key: 'goodsName',
props: {
placeholder: '请输入物资名称'
}
},
{
label: '物资类型',
type: 'select',
key: 'goodsType',
props: {
placeholder: '请选择物资类型',
options: MATERIAL_TYPE
}
}
]
})

+ 142
- 0
src/views/basic-manage/material/tools/materialTable.js View File

@@ -0,0 +1,142 @@
import { h, ref, reactive } from 'vue'
import TableImage from '@/components/DataTable/tools/Image.vue'
import TableTags from '@/components/DataTable/tools/Tags.vue'
import TableSwitch from '@/components/DataTable/tools/Switch.vue'
import TableAction from '@/components/DataTable/tools/Action.vue'
import { deleteGoods } from '@/api/basic/material.js'

/* 注册table */
const tableRef = ref()
const searchParams = ref()

function handleSearch(params) {
searchParams.value = { ...params }
tableRef.value.reFetch({ searchParams })
}

/**
* @description: 获取数据及操作
* @param {*} row 单行数据
* @param {*} type 操作类型 create:创建,preview:预览,edit:编辑
* @return {*}
*/
function getRowData(row, type) {
data.rowData = row
data.modalType = type
data.modalShow = true
}

/**
* @description: 删除物资接口
* @param {Array} ids 物资id集合
* @return {*}
*/
function deleteData(ids) {
deleteGoods(ids).then((res) => {
if (res.code === 0) {
handleSearch()
}
}).catch(e => {
console.log(e)
})
}

const data = reactive({
tableRef,
searchParams,
rowData: {},
modalType: 'create',
modalShow: false,
handleSearch,
deleteData,
columns: [
{
title: '序号',
key: 'key',
render: (_, index) => {
return `${index + 1}`
},
align: 'center'
},
{
title: '物资名称',
key: 'goodsName',
align: 'center'
},
{
title: '物资类型',
key: 'goodsType',
align: 'center'
},
{
title: '物资库存',
key: 'goodsStock',
align: 'center'
},
{
title: '物资作用',
key: 'goodsAction',
align: 'center'
},
{
title: '编辑人',
key: 'updateUser',
align: 'center'
},
{
title: '编辑时间',
key: 'updateTime',
align: 'center',
width: 160
},
// {
// title: '角色',
// key: 'roleList',
// align: 'center',
// render(row) {
// return h(TableTags, {
// data: row.roles,
// rowKey: 'name'
// })
// }
// },
{
title: '操作',
align: 'center',
width: 150,
fixed: 'right',
render(row) {
return h(TableAction, {
actions: [
{
label: '修改',
type: 'button',
props: {
type: 'primary',
text: true,
onClick: getRowData.bind(null, row, 'update')
},
auth: 'basic_list'
},
{
label: '删除',
type: 'popconfirm',
auth: 'basic_list',
tip: '确定删除这条数据吗?',
props: {
onPositiveClick: deleteData.bind(null, [row.id])
},
ButtonProps: {
text: true,
type: 'primary'
}
}
],
align: 'center'
})
}
}
]
})

export default data

+ 12
- 0
src/views/basic-manage/material/tools/search.js View File

@@ -0,0 +1,12 @@
import { reactive } from 'vue'
export const search = reactive({
search: [
{
label: '仓库名称',
key: 'warehouseName',
props: {
placeholder: '请输入仓库名称'
}
}
]
})

+ 140
- 0
src/views/basic-manage/material/tools/table.js View File

@@ -0,0 +1,140 @@
import { h, ref, reactive } from 'vue'
import TableAction from '@/components/DataTable/tools/Action.vue'
import { deleteMaterial } from '@/api/basic/material.js'

/* 注册table */
const tableRef = ref()
const searchParams = ref()

function handleSearch(params) {
searchParams.value = { ...params }
tableRef.value.reFetch({ searchParams })
}

/**
* @description: 获取数据及操作
* @param {*} row 单行数据
* @param {*} type 操作类型 create:创建,preview:预览,edit:编辑
* @return {*}
*/
function getRowData(row, type) {
data.rowData = row
data.modalType = type
data.modalShow = true
}

/**
* @description: 获取数据及操作
* @param {*} row 单行数据
* @param {*} type 操作类型 create:创建,preview:预览,edit:编辑
* @return {*}
*/
function openDrawer(row, type) {
data.rowData = row
data.drawerShow = true
}

/**
* @description: 删除用户接口
* @param {Array} ids 用户id集合
* @return {*}
*/
function deleteData(ids) {
deleteMaterial(ids).then((res) => {
if (res.code === 0) {
handleSearch()
}
}).catch(e => {
console.log(e)
})
}

const data = reactive({
tableRef,
searchParams,
rowData: {},
modalType: 'create',
modalShow: false,
drawerShow: false,
handleSearch,
deleteData,
columns: [
{
title: '序号',
key: 'key',
render: (_, index) => {
return `${index + 1}`
},
align: 'center'
},
{
title: '仓库名称',
key: 'warehouseName',
align: 'center'
},
{
title: '仓库位置',
key: 'location',
align: 'center'
},
{
title: '编辑人',
key: 'updateUser',
align: 'center'
},
{
title: '编辑时间',
key: 'updateTime',
align: 'center',
width: 160
},
{
title: '操作',
align: 'center',
width: 150,
fixed: 'right',
render(row) {
return h(TableAction, {
actions: [
{
label: '修改',
type: 'button',
props: {
type: 'primary',
text: true,
onClick: getRowData.bind(null, row, 'update')
},
auth: 'basic_list'
},
{
label: '物资管理',
type: 'button',
props: {
type: 'primary',
text: true,
onClick: openDrawer.bind(null, row)
},
auth: 'basic_list'
},
{
label: '删除',
type: 'popconfirm',
auth: 'basic_list',
tip: '确定删除这条数据吗?',
props: {
onPositiveClick: deleteData.bind(null, [row.id])
},
ButtonProps: {
text: true,
type: 'primary'
}
}
],
align: 'center'
})
}
}
]
})

export default data

+ 68
- 0
src/views/basic-manage/monitor/components/CustomForm.vue View File

@@ -0,0 +1,68 @@
<template>
<div class="custom-form">
<n-grid x-gap="12" :cols="2">
<n-gi>
<n-form-item class="hidden__feedback">
<n-input v-model:value="longitude" placeholder="请输入经度" clearable @blur="handleBlur" />
</n-form-item>
</n-gi>
<n-gi>
<n-form-item class="hidden__feedback">
<n-input v-model:value="latitude" placeholder="请输入纬度" clearable @blur="handleBlur" />
</n-form-item>
</n-gi>
</n-grid>
<!-- <n-grid x-gap="12" :cols="1">
<n-gi>
<n-form-item class="hidden__feedback">
<n-input v-model:value="address" placeholder="请输入安装位置" clearable @blur="handleBlur" />
</n-form-item>
</n-gi>
</n-grid> -->
</div>
</template>

<script>
import { reactive, watch, toRefs } from 'vue'
export default {
name: 'CustomForm',
props: {
value: {
type: Object,
default: () => {}
}
},
emits: ['done'],
setup(props, { emit }) {
const data = reactive({
longitude: '',
latitude: '',
...props.value
})

// watch(data, (val) => {
// emit('done', val)
// })

const handleBlur = () => {
emit('done', data)
}

return {
...toRefs(data),
handleBlur
}
}
}

</script>
<style scoped lang='scss'>
.custom-form{
width: 100%;
}
::v-deep(.hidden__feedback){
.n-form-item-feedback-wrapper{
display: none;
}
}
</style>

+ 158
- 0
src/views/basic-manage/monitor/components/MonitorModal.vue View File

@@ -0,0 +1,158 @@
<template>
<Modal
:options="getModalOptions"
:on-positive-click="handleConfirm"
:on-negative-click="handleClose"
:on-close="handleClose"
>
<template #Context>
<n-form
ref="formRef"
:model="monitorForm"
:rules="monitorRules"
:label-width="100"
label-placement="left"
require-mark-placement="left"
:disabled="disabled"
>
<template v-for="(item,index) in getFormOptions" :key="index">
<n-form-item :label="item.label" :path="item.key">
<n-input v-if="item.type === 'input'" v-model:value="monitorForm[item.key]" v-bind="item.props" />
<n-select v-if="item.type === 'select'" v-model:value="monitorForm[item.key]" v-bind="item.props" />
<CustomForm v-if="item.type === 'customPos'" v-model:value="monitorForm" @done="validatePartial" />
</n-form-item>
</template>
</n-form>
</template>
</Modal>
</template>

<script>
import { form, changeMessage } from '../tools/form.js'
import { defineComponent, ref, reactive, computed, toRefs } from 'vue'
import Modal from '@/components/Modal/index.vue'
import CustomForm from './CustomForm.vue'
import { createCamera, updateCamera } from '@/api/basic/monitor.js'
export default defineComponent({
name: 'UserModal',
components: { Modal, CustomForm },
props: {
visible: {
type: Boolean,
default: false
},
type: {
type: String,
default: 'create'
},
data: {
type: Object,
default: () => null
}
},
emits: {
'update:visible': null,
'reload': null
},
setup(props, { emit }) {
const MODAL_TYPE = {
'create': '新建设备',
'preview': '设备详情',
'update': '编辑设备'
}
const { monitorForm, monitorRules } = form
const formRef = ref()
const data = reactive({
monitorForm: {
...monitorForm,
...props.data,
customPos: props?.data?.id ? 'pass' : null
},
monitorRules: {
...monitorRules
},
disabled: props.type === 'preview'
})
const getModalOptions = computed(() => {
return {
show: props.visible,
title: MODAL_TYPE[props.type],
negativeText: '取消',
positiveText: '确认'
}
})

const getFormOptions = computed(() => {
return {
...form.formItem
}
})

const validatePartial = (form) => {
data.monitorForm.customPos = null
if (form.longitude && form.latitude) {
data.monitorForm.customPos = 'pass'
const { latitude, longitude } = form
data.monitorForm.longitude = Number(longitude)
data.monitorForm.latitude = Number(latitude)
}
formRef.value?.validate(
(errors) => {
if (errors) {
console.error(1111)
}
},
(rule) => {
return rule?.key === 'custom'
}
)
}

function handleConfirm() {
formRef.value?.validate((errors) => {
if (!errors) {
const params = {
...data.monitorForm
}
if (params.id) {
updateCamera(params)
.then(res => {
if (res.code === 0) {
emit('reload')
handleClose()
}
})
} else {
/* 新增 */
createCamera(params)
.then(res => {
if (res.code === 0) {
emit('reload')
handleClose()
}
})
}
} else {
$message.error('请完善必填信息')
}
})
}

/* 关闭弹窗 */
const handleClose = () => {
emit('update:visible', false)
}
return {
...toRefs(data),
formRef,
getModalOptions,
getFormOptions,
validatePartial,
handleConfirm,
handleClose
}
}
})
</script>
<style scoped lang='scss'>
</style>

+ 96
- 0
src/views/basic-manage/monitor/index.vue View File

@@ -0,0 +1,96 @@
<template>
<div>
<n-card>
<headSearch :info="search" @search="handleSearch" @reset="handleSearch" />
<data-table
ref="tableRef"
:columns="columns"
:row-key="(row) => row.id"
:request="loadDataTable"
size="large"
@update:checked-row-keys="handleCheck"
>
<template #tableTitle>
<n-button type="primary" @click="handleModal"> 新建 </n-button>
</template>
</data-table>
</n-card>
</div>

<!-- 新增、编辑弹窗 -->
<MonitorModal v-if="modalShow" v-model:visible="modalShow" :type="modalType" :data="rowData" @reload="handleSearch" />
</template>
<script>
import { search } from './tools/search.js'
import table from './tools/table.js'
import headSearch from '@/components/Search/index.vue'
import dataTable from '@/components/DataTable/index.vue'
import MonitorModal from './components/MonitorModal.vue'
import { cameraPage } from '@/api/basic/monitor.js'
import { unref, ref, toRefs, reactive, onUnmounted } from 'vue'

export default {
name: 'MenuPage',
components: { dataTable, MonitorModal, headSearch },
setup() {
const data = reactive({
...toRefs(table),
...toRefs(search)
})

const loadDataTable = async(res) => {
const _params = {
...unref(data.searchParams),
...res
}
return await cameraPage(_params)
}

// 新增
function handleModal() {
data.rowData = null
data.modalType = 'create'
data.modalShow = true
}

// 选择表格数据
const selectedIds = ref([])
function handleCheck(rowKeys) {
selectedIds.value = rowKeys
}

// 批量删除
function deleteComplex() {
if (selectedIds.value.length) {
data.deleteData(selectedIds.value)
} else {
$message.warning('请至少选中一条数据')
}
}

onUnmounted(() => {
data.searchParams = null
})

return {
...toRefs(data),
loadDataTable,
handleModal,
selectedIds,
deleteComplex,
handleCheck
}
},
methods: {

}
}
</script>

<style scoped lang='scss'>
</style>
<style scoped lang='scss'>
.n-button + .n-button {
margin-left: 10px;
}
</style>

+ 43
- 0
src/views/basic-manage/monitor/tools/form.js View File

@@ -0,0 +1,43 @@
import { reactive } from 'vue'
import { MONITOR_OPTIONS } from '@/utils/dictionary.js'
export const form = reactive({
monitorForm: {
cameraName: null,
cameraType: null,
customPos: null,
longitude: null,
latitude: null,
flvUrl: null,
remark: null
},
monitorRules: {
cameraName: [{ required: true, message: '请输入设备名称', trigger: 'blur' }],
cameraType: [{ required: true, message: '请选择设备机型', type: 'number', trigger: 'blur' }],
customPos: [{ key: 'custom', required: true, message: '请输入经纬度', trigger: ['blur', 'change'] }],
flvUrl: [{ required: true, message: '请输入摄像头地址', trigger: 'blur', pattern: /^https:\/\/(([a-zA-Z0-9_-])+(\.)?)*(:\d+)?(\/((\.)?(\?)?=?&?[a-zA-Z0-9_-](\?)?)*)*$/i }]
},
formItem: [
{ type: 'input', key: 'cameraName', label: '设备名称', props: { maxlength: '20', placeholder: '请输入设备名称', clearable: true }},
{ type: 'select', key: 'cameraType', label: '设备机型', props: { options: MONITOR_OPTIONS, placeholder: '请选择设备机型' }},
{ type: 'customPos', key: 'customPos', label: '安装位置' },
{ type: 'input', key: 'flvUrl', label: '摄像头地址', props: { maxlength: '20', placeholder: '请输入https://', clearable: true }},
{ type: 'input', key: 'remark', label: '备注', props: { type: 'textarea', autosize: { maxlength: '200', minRows: 3, maxRows: 3 }}}
]
})

export const changeMessage = (type) => {
const list = form.monitorRules.customPos
switch (type) {
case 'lng':
list[0].message = '请输入经度'
break
case 'lat':
list[0].message = '请输入纬度'
break
case 'address':
list[0].message = '请输入安装位置'
break
default:
list[0].message = '请输入经纬度'
}
}

+ 13
- 0
src/views/basic-manage/monitor/tools/search.js View File

@@ -0,0 +1,13 @@
import { reactive } from 'vue'

export const search = reactive({
search: [
{
label: '设备名称',
key: 'cameraName',
props: {
placeholder: '请输入设备名称'
}
}
]
})

+ 140
- 0
src/views/basic-manage/monitor/tools/table.js View File

@@ -0,0 +1,140 @@
import { h, ref, reactive } from 'vue'
import TableTags from '@/components/DataTable/tools/Tags.vue'
import TableAction from '@/components/DataTable/tools/Action.vue'
import { MONITOR_OPTIONS } from '@/utils/dictionary.js'
import { deleteCamera } from '@/api/basic/monitor.js'

/* 注册table */
const tableRef = ref()
const searchParams = ref()

function handleSearch(params) {
searchParams.value = { ...params }
tableRef.value.reFetch({ searchParams })
}

/**
* @description: 获取数据及操作
* @param {*} row 单行数据
* @param {*} type 操作类型 create:创建,preview:预览,edit:编辑
* @return {*}
*/
function getRowData(row, type) {
data.rowData = row
data.modalType = type
data.modalShow = true
}

/**
* @description: 删除用户接口
* @param {Array} ids 用户id集合
* @return {*}
*/
function deleteData(ids) {
deleteCamera(ids).then((res) => {
if (res.code === 0) {
handleSearch()
}
}).catch(e => {
console.log(e)
})
}

const data = reactive({
tableRef,
searchParams,
rowData: {},
modalType: 'create',
modalShow: false,
handleSearch,
deleteData,
columns: [
{
title: '序号',
key: 'key',
render: (_, index) => {
return `${index + 1}`
},
align: 'center'
},
{
title: '设备名称',
key: 'cameraName',
align: 'center'
},
{
title: '设备机型',
key: 'cameraType',
align: 'center',
render(row) {
return h(TableTags, {
data: row.cameraType,
filters: MONITOR_OPTIONS
})
}
},
{
title: '所在位置',
key: 'location',
align: 'center',
width: 160
},
{
title: '备注',
key: 'remark',
align: 'center',
width: 160
},
{
title: '编辑时间',
key: 'updateTime',
align: 'center',
width: 160
},
{
title: '编辑人',
key: 'updateUser',
align: 'center',
width: 160
},
{
title: '操作',
align: 'center',
width: 150,
fixed: 'right',
render(row) {
return h(TableAction, {
actions: [
{
label: '修改',
type: 'button',
props: {
type: 'primary',
text: true,
onClick: getRowData.bind(null, row, 'update')
},
auth: 'basic_list'
},

{
label: '删除',
type: 'popconfirm',
auth: 'basic_list',
tip: '确定删除这条数据吗?',
props: {
onPositiveClick: deleteData.bind(null, [row.id])
},
ButtonProps: {
text: true,
type: 'primary'
}
}
],
align: 'center'
})
}
}
]
})

export default data

+ 124
- 0
src/views/early-warning/fire/components/FireModal.vue View File

@@ -0,0 +1,124 @@
<template>
<Modal
:options="getModalOptions"
:on-positive-click="handleConfirm"
:on-negative-click="handleClose"
:on-close="handleClose"
>
<template #Context>
<n-grid x-gap="12" :cols="2">
<n-gi>
<!-- :src="fireDetail.fileOriginalUrl" -->
<n-image
width="340"
src="https://07akioni.oss-cn-beijing.aliyuncs.com/07akioni.jpeg"
/>
</n-gi>
<n-gi>
<div class="flex__content">
<p class="content">火灾位置:{{ fireDetail.location }}</p>
<p class="content">发现方式:{{ fireDetail.discoveryWay }}</p>
<p class="content">上报时间:{{ fireDetail.createTime }}</p>
</div>
</n-gi>
</n-grid>
<p class="title">火灾核实记录</p>
<div>
<p v-for="(item,index) in fireDetail.warningRecordVOList" :key="index" class="content">
{{ `${item.recordStartTime} ${item.airportName}执行任务,` }}
</p>
</div>
<p class="title">处理记录</p>
<p class="content">{{ fireDetail.checkResult }}</p>
<p class="content">处理人:{{ fireDetail.checkUser }}</p>
<p class="content">处理时间:{{ fireDetail.checkTime }}</p>
</template>
</Modal>
</template>

<script>
import { defineComponent, ref, reactive, computed, toRefs, onMounted } from 'vue'
import Modal from '@/components/Modal/index.vue'
import { fireDetail } from '@/api/early/fire.js'
export default defineComponent({
name: 'UserModal',
components: { Modal },
props: {
visible: {
type: Boolean,
default: false
},
type: {
type: String,
default: 'create'
},
data: {
type: Object,
default: () => null
}
},
emits: {
'update:visible': null,
'reload': null
},
setup(props, { emit }) {
const data = reactive({
fireDetail: {

}
})

const getModalOptions = computed(() => {
return {
show: props.visible,
width: 800,
title: '火灾隐患',
negativeText: '取消',
positiveText: '确认'
}
})

const handleClose = () => {
emit('update:visible', false)
}

onMounted(async() => {
const res = await fireDetail(props.data.id)
if (res.code === 0) {
data.fireDetail = res.data
} else {
handleClose()
}
})

return {
...toRefs(data),
getModalOptions,
handleClose
}
}
})
</script>
<style scoped lang='scss'>
.n-grid{
margin-bottom: 20px;
}
.flex__content{
display: flex;
flex-direction: column;
padding-top: 20px;
.content{
font-size: 18px;
}
}
.title{
font-size: 18px;
font-weight: bold;
margin: 5px 0;
border-bottom: 1px dashed rgba(0,0,0,0.3);
}
.content{
padding: 0 5px;
font-size: 16px;
}
</style>

+ 64
- 0
src/views/early-warning/fire/index.vue View File

@@ -0,0 +1,64 @@
<template>
<div>
<n-card>
<HeadSearch :info="search" @search="handleSearch" @reset="handleSearch" />
<DataTable
ref="tableRef"
:columns="columns"
:row-key="(row) => row.id"
:request="loadDataTable"
size="large"
/>
</n-card>
</div>

<!-- 新增、编辑弹窗 -->
<FireModal v-if="modalShow" v-model:visible="modalShow" :type="modalType" :data="rowData" @reload="handleSearch" />
</template>
<script>
import { search } from './tools/search.js'
import table from './tools/table.js'
import HeadSearch from '@/components/Search/index.vue'
import DataTable from '@/components/DataTable/index.vue'
import FireModal from './components/FireModal.vue'
import { firePage } from '@/api/early/fire.js'
import { unref, toRefs, reactive, onUnmounted } from 'vue'

export default {
name: 'MenuPage',
components: { HeadSearch, DataTable, FireModal },
setup() {
const data = reactive({
...toRefs(table),
...toRefs(search)
})

const loadDataTable = async(res) => {
const _params = {
...unref(data.searchParams),
...res
}
return await firePage(_params)
}
onUnmounted(() => {
data.searchParams = null
})

return {
...toRefs(data),
loadDataTable
}
},
methods: {

}
}
</script>

<style scoped lang='scss'>
</style>
<style scoped lang='scss'>
.n-button + .n-button {
margin-left: 10px;
}
</style>

+ 36
- 0
src/views/early-warning/fire/tools/search.js View File

@@ -0,0 +1,36 @@
import { reactive } from 'vue'
import { EARLY_SOURCE, FIRE_STATUS } from '@/utils/dictionary.js'

export const search = reactive({
search: [
{
label: '预警来源',
key: 'discoveryWay',
type: 'select',
props: {
placeholder: '请选择预警来源',
options: EARLY_SOURCE
}
},
{
label: '火灾状态',
key: 'status',
type: 'select',
props: {
placeholder: '请选择火灾状态',
options: FIRE_STATUS
}
},
{
label: '预警时间',
key: 'time',
type: 'date',
value: null,
props: {
type: 'daterange',
valueFormat: 'yyyy-MM-dd',
format: 'yyyy-MM-dd'
}
}
]
})

+ 95
- 0
src/views/early-warning/fire/tools/table.js View File

@@ -0,0 +1,95 @@
import { h, ref, reactive } from 'vue'
import TableAction from '@/components/DataTable/tools/Action.vue'

/* 注册table */
const tableRef = ref()
const searchParams = ref()

function handleSearch(params) {
searchParams.value = { ...params }
if (params?.time?.length) {
searchParams.value = {
...params,
startTime: params.time[0],
endTime: params.time[1]
}
}
delete searchParams.value.time
tableRef.value.reFetch({ searchParams })
}

/**
* @description: 获取数据及操作
* @param {*} row 单行数据
* @param {*} type 操作类型 create:创建,preview:预览,edit:编辑
* @return {*}
*/
function getRowData(row, type) {
data.rowData = row
data.modalType = type
data.modalShow = true
}

const data = reactive({
tableRef,
searchParams,
rowData: {},
modalType: 'create',
modalShow: false,
handleSearch,
columns: [
{
title: '序号',
key: 'key',
render: (_, index) => {
return `${index + 1}`
},
align: 'center'
},
{
title: '预警时间',
key: 'waringTime',
align: 'center'
},
{
title: '预警来源',
key: 'discoverWayName',
align: 'center'
},
{
title: '火灾位置',
key: 'location',
align: 'center'
},
{
title: '火灾核实',
key: 'statusName',
align: 'center'
},
{
title: '操作',
align: 'center',
width: 150,
fixed: 'right',
render(row) {
return h(TableAction, {
actions: [
{
label: '详情',
type: 'button',
props: {
type: 'primary',
text: true,
onClick: getRowData.bind(null, row, 'update')
},
auth: 'basic_list'
}
],
align: 'center'
})
}
}
]
})

export default data

Loading…
Cancel
Save