policeSecurity/policeManagement/src/views/query/publicUnit.vue

668 lines
19 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div>
<TableProMax
:expandedRowRender="expandedRowRender"
:expand-column-width="50"
:defaultExpandAllRows="false"
ref="tableRef"
:request-api="reqApi"
:columns="columns"
:searchFormOptions="searchFormOptions"
:scroll="{ x }"
>
<template #tableHeader>
<a-space>
<a-button type="primary" @click="saveOrUpdateEnterprisesUnit">新增企事业单位</a-button>
</a-space>
</template>
</TableProMax>
<a-modal v-model:open="visible" :title="serviceTitle" @ok="submit" @cancel="closeModal">
<FormProMax ref="formRef" v-model:value="formParams" :form-item-options="formItemOptions" />
</a-modal>
</div>
</template>
<script setup lang="tsx">
import { deleteDataModal } from '@/components/tsx/ModalPro.tsx'
import { EnterprisesUnitSaveOrUpdateParams } from '@/types/views/unitManage/police/policeUnit.ts'
import MapContainer from '@/components/aMap/MapContainer.vue'
import { AutoComplete, Button, Input, message, Modal, Space } from 'ant-design-vue'
import { debounce } from 'lodash-es'
import FormProMax from '@/components/form/FormProMax.vue'
import api from '@/axios'
import { ref, reactive, computed, onMounted } from 'vue'
import TableProMax from '@/components/table/TableProMax.vue'
import { TableProMaxProps } from '@/types/components/table/index.ts'
import { ComponentExposed } from 'vue-component-type-helpers'
import { dictSelectNodes } from '@/config/dict.ts'
import { publicUnitPagerQueryParams } from '@/types/views/publicUnit.ts'
import { FormProMaxItemOptions } from '@/types/components/form//index.ts'
import { FormExpose } from 'ant-design-vue/es/form/Form'
import { serviceProjectSaveOrUpdateParams_ } from '@/types/views/serviceManagement'
type _FormType = EnterprisesUnitSaveOrUpdateParams & {
contactPersonInfoName?: string
contactPersonInfoTelephone?: string
}
type TableProps = TableProMaxProps<publicUnitPagerQueryParams>
const reqApi: TableProps['requestApi'] = (params) => api.post('/eu/pager', params) //分页
const tableRef = ref<ComponentExposed<typeof TableProMax>>(null)
const columns: TableProps['columns'] = [
{
dataIndex: 'name',
title: '单位名称',
},
{
dataIndex: 'provinceName',
title: '行政区划',
customRender: ({ record }) => {
return `${record?.provinceName}/${record?.cityName}/${record?.districtsName}/${record?.streetName}`
},
},
{
dataIndex: 'address',
title: '详细地址',
},
{
dataIndex: 'contactPersonInfo',
title: '联系人姓名',
customRender: ({ record }) => {
return record?.contactPersonInfo?.name
},
},
{
dataIndex: 'contactPersonInfo',
title: '联系人手机号',
customRender: ({ record }) => {
return record?.contactPersonInfo?.telephone
},
},
{
dataIndex: 'createTime',
title: '创建时间',
},
{
dataIndex: 'remark',
title: '备注',
},
{
dataIndex: 'opt',
title: '操作',
customRender: ({ record }) => (
<Space>
<Button
class='btn-warn'
onClick={() =>
saveOrUpdateEnterprisesUnit(
{
snowFlakeId: record.snowFlakeId,
policeUnitId: record.policeUnitId,
name: record.name,
type: record.type.value,
administrativeDivisionCodes: [record.province, record.city, record.districts, record.street].filter(Boolean),
address: record.address,
point: record.point,
contactPersonInfoName: record.contactPersonInfo?.name,
contactPersonInfoTelephone: record.contactPersonInfo?.telephone,
remark: record.remark,
},
tableRef.value?.requestGetTableData
)
}
>
编辑
</Button>
<Button
class='btn-danger'
onClick={() =>
deleteDataModal(record.name, async () => {
// const resp = await api.delete('/enterprisesUnit/deleteById', {
const resp = await api.delete('/eu/del_id', {
enterprisesUnitId: record.snowFlakeId,
})
message.success(resp.message)
await tableRef.value?.requestGetTableData()
})
}
>
删除
</Button>
</Space>
),
},
]
const x: number = columns.reduce((a, b) => a + (b.width as number), 0)
const saveOrUpdateEnterprisesUnit = (params: _FormType, callback: Function) => {
const _formRef = ref<FormExpose>(null)
const _mapRef = ref<ComponentExposed<typeof MapContainer>>(null)
const _formParams = ref<_FormType>({ ...params })
let city = ''
const initMarker = (map: AMap.Map) => {
//添加maker点 设置point
const maker = new AMap.Marker({
position: _formParams.value.point,
draggable: true,
})
maker.on('dragend', ({ lnglat }) => {
_formParams.value.point = lnglat
})
map.clearMap()
map.add(maker)
map.setFitView()
}
const autoAddress = ref<SelectNodeVo<string>[]>([])
const _formOptions = ref<FormProMaxItemOptions<_FormType>>({
name: {
type: 'custom',
label: '单位名称',
required: true,
customRender: () => {
return (
// AutoComplete 自动完成 组件
<AutoComplete
v-model:value={_formParams.value.name}
options={autoAddress.value}
onSelect={(_, options: SelectNodeVo<string>) => {
_formParams.value.point = options.extData?.location
_formParams.value.address = options.extData?.address
initMarker(_mapRef.value?.mapInstance)
}}
onSearch={debounce((val: string) => {
//@ts-ignore
const auto = new AMap.AutoComplete({
city: city,
// input: 'tipinput',
citylimit: true,
})
auto.search(val, (status, result) => {
if (status === 'complete') {
// 生成组件需要数据
autoAddress.value = result.tips?.map((e) => {
return {
value: e.name,
label: e.name,
extData: {
district: e.district,
address: e.address,
location: e.location,
},
} as SelectNodeVo<string>
})
} else {
autoAddress.value = []
}
})
}, 300)}
v-slots={{
option: (item: SelectNodeVo<string>) => {
return (
<div>
<p>{item.label}</p>
<p style={{ color: '#9a9c9d' }}>
{item.extData?.district} {item.extData?.address}
</p>
</div>
)
},
}}
>
<Input placeholder='请输入单位名称' />
</AutoComplete>
)
},
},
type: {
type: 'select',
label: '单位类型',
required: true,
// @ts-ignore
options: dictSelectNodes('EnterprisesUnitType'),
},
administrativeDivisionCodes: {
type: 'administrativeDivisionTree',
label: '行政区划',
required: true,
componentsProps: {
// @ts-ignore
displayRender: ({ labels }): string => {
city = labels[1]
return labels.join(' / ')
},
},
},
address: {
type: 'inputTextArea',
label: '详细地址',
},
map: {
type: 'custom',
label: '经纬度',
customRender: () => (
<MapContainer
ref={_mapRef}
plugins={['AMap.AutoComplete', 'AMap.PlaceSearch']}
style={{ width: '100%', height: '300px', position: 'relative' }}
initCallback={(map) => {
const contextMenu = new AMap.ContextMenu()
contextMenu.addItem(
'标记',
() => {
const { lng, lat } = contextMenu.getPosition()
_formParams.value.point = [lng, lat]
initMarker(map)
},
0
)
map.on('rightclick', ({ lnglat }) => {
contextMenu.open(map, lnglat)
})
if (_formParams.value.point) {
initMarker(map)
}
}}
></MapContainer>
),
},
contactPersonInfoName: {
type: 'input',
label: '联系人名称',
},
contactPersonInfoTelephone: {
type: 'input',
label: '联系人电话',
},
remark: {
type: 'inputTextArea',
label: '备注',
},
})
Modal.confirm({
title: params.snowFlakeId ? `${params.name}】 信息编辑` : '新增企事业单位',
width: 600,
icon: ' ',
centered: true,
content: () => <FormProMax ref={_formRef} v-model:value={_formParams.value} formItemOptions={_formOptions.value} />,
onOk: async () => {
await _formRef.value?.validate()
const resp = await api.post('/eu/add_upd', {
..._formParams.value,
contactPersonInfo: {
name: _formParams.value.contactPersonInfoName,
telephone: _formParams.value.contactPersonInfoTelephone,
},
})
message.success(resp.message)
await tableRef.value?.requestGetTableData()
callback && callback()
},
})
}
const searchFormOptions = reactive<TableProps['searchFormOptions']>({
name: {
type: 'input',
label: '名称',
},
treeSelect: {
// type: 'cascader',
type: 'administrativeDivisionTree',
label: '行政区划',
},
telephone: {
type: 'input',
label: '手机号',
},
})
type _TableProps = TableProMaxProps<any>
const isRecruitSecurityHidden = ref<boolean>(false)
const visible = ref(false)
const serviceTitle = ref('新增服务项目')
const idNumberDisabled = ref<boolean>(true)
const formRef = ref<FormExpose>(null)
const enterprisesUnitId = ref('')
const netType = computed(() => {
//@ts-ignore
return formParams.value.type === 'security' ? dictSelectNodes('ServiceProjectTwoType') : dictSelectNodes('UserType' as any)
})
const formParams = ref<{
snowFlakeId?: string
enterprisesUnitId: string
securityUnitId: string
administrativeDivisionCodes?: null
projectManagerMiniProgramUserId?: string
projectManagerMiniProgramUserName?: string
name: string
type: string
twoType?: number
outsourceName?: string
isFiling?: number
idNumber?: string
serviceArea?: number
buildingTotal?: number
houseTotal?: number
staffTotal?: number
securityUserTotal?: number
remark?: string
}>({
name: '',
enterprisesUnitId: null,
type: 'security',
securityUnitId: null,
})
const securityUnitIdList = ref<any>([])
const formItemOptions = ref<FormProMaxItemOptions<serviceProjectSaveOrUpdateParams_>>({
name: {
type: 'input',
label: '服务项目名称',
required: true,
},
securityUnitId: {
type: 'select',
label: '保安单位',
required: true,
options: securityUnitIdList,
},
type: {
type: 'radioGroup',
label: '服务类型',
//@ts-ignore
options: dictSelectNodes('ServiceProjectType'),
required: true,
componentsProps: {
onChange: (e) => {
if (e.target?.value === 'security') {
isRecruitSecurityHidden.value = false
formParams.value.twoType = null
} else {
formParams.value.twoType = null
isRecruitSecurityHidden.value = true
}
},
},
},
twoType: {
required: true,
type: 'radioGroup',
label: '二级类型',
options: netType,
componentsProps: {
onChange: (e) => {
if (e.target.value !== 'outsource') {
idNumberDisabled.value = true
formParams.value.outsourceName = ''
} else {
idNumberDisabled.value = false
}
},
},
},
outsourceName: {
type: 'input',
label: '外包公司名称',
hidden: idNumberDisabled as any,
},
isFiling: {
required: true,
type: 'radioGroup',
label: '是否备案',
options: dictSelectNodes('IsOrNot'),
},
idNumber: {
type: 'input',
label: '保安服务许可证',
},
serviceArea: {
type: 'inputNumber',
label: '服务区域面积',
},
buildingTotal: {
type: 'inputNumber',
label: '楼栋数量',
componentsProps: {
formatter: (value: any) => {
return Math.round(value) ? Math.round(value) : ('' as any)
},
min: 0,
},
},
houseTotal: {
type: 'inputNumber',
label: '户数',
componentsProps: {
formatter: (value: any) => {
return Math.round(value) ? Math.round(value) : ('' as any)
},
min: 0,
},
},
staffTotal: {
type: 'inputNumber',
label: '工作人员数量',
componentsProps: {
formatter: (value: any) => {
return Math.round(value) ? Math.round(value) : ('' as any)
},
min: 0,
},
},
securityUserTotal: {
type: 'inputNumber',
label: '保安人员数量',
componentsProps: {
formatter: (value: any) => {
return Math.round(value) ? Math.round(value) : ('' as any)
},
min: 0,
},
},
remark: {
type: 'inputTextArea',
label: '备注',
},
})
const _tableRef = ref<ComponentExposed<typeof TableProMax>>(null)
const expandedRowRender: TableProMaxProps['expandedRowRender'] = ({ record }) => {
const _columns: _TableProps['columns'] = [
{
dataIndex: 'name',
title: '服务项目名称',
},
{
dataIndex: 'type',
title: '服务类型',
customRender: ({ text }) => <a-tag>{text?.label}</a-tag>,
},
{
dataIndex: 'twoType',
title: '二级类型',
customRender: ({ text }) => <a-tag>{text?.label}</a-tag>,
},
{
dataIndex: 'outsourceName',
title: '外包公司名称',
customRender: ({ record }) => {
if (record.twoType.value === 'outsource') {
return record.outsourceName
}
},
},
{
dataIndex: 'isFiling',
title: '是否备案',
customRender: ({ text }) => <a-tag>{text?.label}</a-tag>,
},
{
dataIndex: 'idNumber',
title: '保安服务许可证',
},
{
dataIndex: 'serviceArea',
title: '服务区域面积',
},
{
dataIndex: 'buildingTotal',
title: '楼栋数量',
},
{
dataIndex: 'houseTotal',
title: '户数',
},
{
dataIndex: 'staffTotal',
title: '工作人员数量',
},
{
dataIndex: 'securityUserTotal',
title: '保安人员数量',
},
{
dataIndex: 'remark',
title: '备注',
},
{
dataIndex: 'createUserInfo',
title: '创建人',
customRender: ({ record }) => {
return (
<div>
<p>创建人{record.createUserInfo.name} </p>
<p>创建人单位{record.createUserInfo.unitName} </p>
</div>
)
},
},
{
dataIndex: 'createTime',
title: '创建时间',
},
{
dataIndex: 'opt',
title: '操作',
fixed: 'right',
customRender({ record }) {
return (
<a-space>
<a-button
class='btn-warn'
onClick={async () => {
visible.value = true
serviceTitle.value = '编辑服务项目'
idNumberDisabled.value = record.twoType.value !== 'outsource'
formParams.value.securityUnitId = record.securityUnitId //企事业单位id
formParams.value.enterprisesUnitId = record.enterprisesUnitId //企事业单位id
formParams.value.snowFlakeId = record.snowFlakeId //id
formParams.value.projectManagerMiniProgramUserId = record.projectManagerMiniProgramUserId //项目经理小程序用户id
formParams.value.name = record.name
formParams.value.type = record.type.value //服务类型
formParams.value.twoType = record.twoType.value //二级类型
formParams.value.outsourceName = record.outsourceName //外包公司名称
formParams.value.isFiling = record.isFiling.value //是否备案
formParams.value.remark = record.remark //备注
formParams.value.idNumber = record.idNumber //证件号(保安服务许可证/备案证
formParams.value.serviceArea = record.serviceArea //服务区域面积
formParams.value.buildingTotal = record.buildingTotal //楼栋数量
formParams.value.houseTotal = record.houseTotal //户数
formParams.value.staffTotal = record.staffTotal //工作人员数量
formParams.value.securityUserTotal = record.securityUserTotal //保安人员数量
}}
>
编辑
</a-button>
<a-popconfirm
title='确认删除账号吗?'
onConfirm={async () => {
const resp = await api.delete('/m2/eu/deleteSpById', {
serviceProjectId: record.snowFlakeId,
})
message.success(resp.message)
await _tableRef.value?.requestGetTableData()
}}
>
<a-button danger>删除</a-button>
</a-popconfirm>
</a-space>
)
},
},
]
const _reqApi: _TableProps['requestApi'] = async () => {
// @ts-ignore
return await api.get('/m2/eu/listSp', { enterprisesUnitId: record?.snowFlakeId })
}
return (
<TableProMax
ref={_tableRef}
size='small'
columns={_columns}
requestApi={_reqApi}
isPagination={false}
v-slots={{
tableHeader: (_) => {
return (
<Space>
<Button type={'primary'} onClick={() => addService(record)}>
新增服务项目
</Button>
</Space>
)
},
}}
/>
)
}
const closeModal = async () => {
visible.value = false
formParams.value = {
securityUnitId: '',
enterprisesUnitId: '',
administrativeDivisionCodes: '',
name: '',
type: 'security',
idNumber: '',
serviceArea: null,
buildingTotal: null,
houseTotal: null,
staffTotal: null,
securityUserTotal: null,
remark: '',
}
formRef.value.resetFields()
enterprisesUnitId.value = ''
serviceTitle.value = '新增服务项目'
idNumberDisabled.value = false
}
const submit = async () => {
await formRef.value.validate()
const serviceProjectSaveOrUpdateParams = { ...formParams.value }
const resp = await api.post('/m2/eu/add_upd_sp', serviceProjectSaveOrUpdateParams)
message.success(resp.message)
await _tableRef.value.requestGetTableData()
await closeModal()
}
onMounted(async () => {
const res = await api.get('/management/listSecurityUnit')
securityUnitIdList.value = res.data
})
const addService = function (record) {
formParams.value.enterprisesUnitId = record.snowFlakeId //企事业单位Id
visible.value = true
}
</script>