You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

666 lines
20 KiB

<template>
<content-wrap>
<section class="view-wrapper" v-loading="loading">
<section class="flex-1">
<section class="mb-40px">
<section class="title-wrapper"> 基本信息</section>
<el-form :rules="formRules" :model="formData" ref="formRef" label-width="100px">
<section class="base-form">
<el-form-item label="企业名称" prop="enterprisesName">
<el-input
v-model="formData.enterprisesName"
placeholder="请输入企业名称"
:readonly="isView"
/>
</el-form-item>
<el-form-item label="所属区域" prop="region">
<el-input v-if="isView" :readonly="isView" v-model="formData.region" />
<el-select v-model="formData.region" placeholder="请选择所属区域" clearable v-else>
<el-option
v-for="dict in getStrDictOptions(DICT_TYPE.ENTERPRISES_AREA)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="企业地址" prop="address">
<el-input v-if="isView" :readonly="isView" v-model="formData.address" />
<el-input
v-model="formData.address"
placeholder="请选择企业地址"
readonly
@click="getGaps"
v-else
>
<template #append>
<Icon icon="ep:position" @click.stop="getGaps" />
</template>
</el-input>
</el-form-item>
<el-form-item label="行业类别" prop="tagIds">
<el-input v-if="isView" :readonly="isView" v-model="formData.tagIds" />
<el-select
v-else
v-model="formData.tagIds"
placeholder="请选择行业类型"
clearable
multiple
collapse-tags
collapse-tags-tooltip
>
<el-option
v-for="dict in typeList"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
<el-form-item label="企业介绍" class="form-textarea" prop="introduction">
<el-input
v-model="formData.introduction"
placeholder="请输入企业介绍"
type="textarea"
maxlength="500"
show-word-limit
resize="none"
:readonly="isView"
/>
</el-form-item>
<el-form-item label="环保负责人" prop="contactName">
<el-input
v-model="formData.contactName"
placeholder="请输入负责人名称"
:readonly="isView"
/>
</el-form-item>
<el-form-item label="联系方式" prop="environmentalContactPhone">
<el-input
v-model="formData.environmentalContactPhone"
placeholder="请输入负责人联系方式"
:readonly="isView"
/>
</el-form-item>
<el-form-item label="企业照片" prop="photo" class="form-photo">
<section v-if="isView" class="flex gap-20px">
<el-image
v-for="(p, index) in formData.photo"
:src="p.url"
:key="index"
:preview-src-list="formData.photo.map((i) => i.url)"
:initial-index="index"
fit="contain"
class="w-148px h-148px border-solid border-1 border-color-#ccc border-rounded-8px"
/>
</section>
<FileUploader
v-else
v-model="formData.photo"
:limit="6"
height="148px"
width="148px"
ref="fileUploadRef"
/>
</el-form-item>
<section class="form-sub-title"> 执法配置</section>
<el-form-item label="执法人员" prop="userId">
<el-input v-if="isView" readonly v-model="formData.inviterName" />
<el-select
v-else
v-model="formData.userId"
placeholder="请选择执法人员"
filterable
clearable
>
<el-option
v-for="item in userList"
:key="item.userId"
:label="item.realName"
:value="item.userId"
popper-class="user-wrapper"
>
<el-avatar :src="item.avatar" :size="30" /> <span>{{ item.realName }}</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="签到半径" prop="signRadius">
<el-input-number
v-model="formData.signRadius"
:min="10"
:step="1"
placeholder="请输入执法半径"
controls-position="right"
class="!w-100%"
:readonly="isView"
>
<template #suffix>
<span>米</span>
</template>
</el-input-number>
</el-form-item>
</section>
</el-form>
</section>
</section>
<section>
<section class="title-wrapper"> 相关资质 </section>
<section class="prove-wrapper">
<section
class="prove"
v-for="(prove, index) in proveList"
:key="index"
@click="editProve(prove.id)"
>
<section class="image-wrapper">
<el-image
:src="prove.files[0].url"
:preview-src-list="prove.files[0]"
:initial-index="0"
class="h-100% w-100%"
/>
<section class="operation">
<section class="item" @click.stop="imagePreview(prove.files[0].url)">
<Icon icon="ep:zoom-in" :size="24" />
放大
</section>
<section class="item" @click.stop="deleteProve(prove.id)" v-if="!isView">
<Icon icon="ep:delete" :size="24" />
删除
</section>
</section>
</section>
<section class="flex flex-col gap-4px items-center">
<span class="font-bold">
{{ getDictLabel(DICT_TYPE.ENTERPRISES_QUA, prove.qualificationName) }}
</span>
<span class="text-14px">{{ prove.enterpriseAuth }}</span>
<span class="text-14px color-#606266" v-if="prove.qualificationName != 99">
{{ formatDate(prove.expiryDate, 'YYYY年M月D日') }}到期
</span>
<span v-else>永久</span>
</section>
</section>
<section class="add-prove" @click="addProve" v-if="!isView">
<Icon icon="ep:plus" :size="30" />
</section>
</section>
</section>
</section>
<section class="flex items-center justify-center gap-20px" v-if="!isView">
<el-button @click="submit" type="primary">保存信息</el-button>
<el-button @click="router.go(-1)">返回列表</el-button>
</section>
</content-wrap>
<content-wrap v-if="isView" title="执法记录">
<section class="flex flex-col gap-20px">
<el-table :data="logList" v-loading="logLoading" :span-method="logSpanMethod" border>
<el-table-column label="任务名称" prop="title" />
<el-table-column label="执法人员" prop="inspectNames" />
<el-table-column label="进度状态">
<template #default="{ row }">
<dict-tag :value="row.status" :type="DICT_TYPE.INSPECTIONS_STATUS" />
</template>
</el-table-column>
<el-table-column label="执法时间" prop="time" :formatter="dateFormatter" />
<el-table-column label="结果反馈" width="100" align="center">
<template #default="{ row }">
<span v-if="row.status === 1">-</span>
<el-link type="primary" v-else @click="showInspection(row.inspectionsId)">详情 </el-link>
</template>
</el-table-column>
</el-table>
<el-pagination
:total="logTotal"
:show-page-size="false"
layout="total, prev, pager, next"
v-model:current-page="logParams.pageNo"
v-model:page-size="logParams.pageSize"
@change="getLogList"
class="ml-auto"
/>
</section>
</content-wrap>
<GpsDialog ref="GpsDialogRef" @success="setGps" />
<ProveForm ref="proveFormRef" @add-prove="setProve" @success="getProveList" />
<InspectionForm ref="inspectionRef" />
</template>
<script setup lang="ts">
import { getStrDictOptions, DICT_TYPE, getDictLabel } from '@/utils/dict'
import { TagLibraryApi } from '@/api/system/taglibrary'
import { getEnterpriseManager } from '@/api/system/user'
import GpsDialog from './components/getGpsByAmap.vue'
import ProveForm from '@/views/qualification/prove.vue'
import { dateFormatter, formatDate } from '@/utils/formatTime'
import { EnterprisesApi } from '@/api/enterprises'
import { EnterpriseQualificationApi } from '@/api/qualification'
import { createImageViewer } from '@/components/ImageViewer'
import { EnterpriseInspectionsApi } from '@/api/enterpriseinspections'
import InspectionForm from '@/views/enterpriseinspections/EnterpriseInspectionsForm.vue'
/** 企业 表单 */
defineOptions({ name: 'UpdateEnterprises' })
//行业类别
const typeList = ref([] as any)
const userList = ref([] as any)
const message = useMessage()
const GpsDialogRef = ref()
const router = useRouter()
const proveFormRef = ref()
const route = useRoute()
const loading = ref(false)
const formRef = ref()
const isView = ref(false)
const formData = ref({
id: undefined,
departmentId: undefined,
userId: undefined,
type: undefined,
region: undefined,
enterprisesName: undefined,
address: undefined,
contactName: undefined,
enterprisesStatus: undefined,
environmentalContactPhone: undefined,
registrationNumber: undefined,
introduction: undefined,
establishmentDate: undefined,
gpsLocation: undefined,
searchQuery: undefined,
managerDeptId: undefined,
ides: undefined,
startUserSelectAssignees: undefined,
enterpriseUserId: undefined,
tagIds: undefined,
photo: [] as any,
signRadius: 30
} as any)
const formRules = reactive({
type: [{ required: true, message: '企业类型不能为空', trigger: 'change' }],
enterprisesName: [{ required: true, message: '企业名称不能为空', trigger: 'blur' }],
contactName: [{ required: true, message: '负责人不能为空', trigger: 'blur' }],
environmentalContactPhone: [
{ required: true, message: '企业环保负责人联系电话不能为空', trigger: 'blur' }
],
userId: [
{
required: true,
message: '请选择执法人员',
trigger: 'change'
}
],
signRadius: [
{
required: true,
message: '请输入执法半径',
trigger: 'change'
}
],
photo: [
{
required: true,
validator: (rule, value, callback) => {
if (value.length > 0) {
callback()
} else {
callback(new Error('企业照片不能为空'))
}
},
trigger: 'change'
}
],
introduction: [
{
required: true,
message: '请输入企业介绍',
trigger: 'change'
}
],
address: [
{
required: true,
message: '请输入企业地址',
trigger: 'change'
}
],
tagIds: [
{
required: true,
message: '请选择行业类别',
trigger: 'change'
}
],
region: [
{
required: true,
message: '请选择所属区域',
trigger: 'change'
}
]
} as any)
const fileUploadRef = ref()
const proveList: any = ref([])
const logList = ref([])
const logTotal = ref(0)
const logLoading = ref(false)
const logSpanArr: any = ref([])
const inspectionRef = ref()
const logParams: any = reactive({
pageSize: 5,
pageNo: 1,
enterpriseId: undefined
})
/** 查询搜索项列表 */
const getSelectOption = async () => {
userList.value = await getEnterpriseManager()
const res = await TagLibraryApi.tagLibraryList('hy')
typeList.value = res[0].children.map((t) => {
return {
label: t.tagName,
value: t.id
}
})
}
const setGps = (gps: any) => {
formData.value.gpsLocation = [gps.location.lat, gps.location.lng]
formData.value.address = `${gps.district}${gps.address}`
}
const getGaps = () => {
if (formData.value.gpsLocation) {
unref(GpsDialogRef).open({
name: formData.value.enterprisesName,
address: formData.value.address,
location: {
lat: formData.value.gpsLocation[0],
lng: formData.value.gpsLocation[1]
}
})
} else {
unref(GpsDialogRef).open()
}
}
const addProve = () => {
unref(proveFormRef).open({ enterpriseId: formData.value.id })
}
const submit = async () => {
const validate = await unref(formRef).validate()
if (!validate) return
loading.value = true
await unref(fileUploadRef).handlerUpload()
if (formData.value.id) {
const data = {
...formData.value,
fileIds: formData.value.photo.map((i) => i.id),
gpsLocation: formData.value.gpsLocation.join(',')
}
EnterprisesApi.updateEnterprises(data).then(() => {
message.success('保存成功')
loading.value = false
getDetail()
})
} else {
const data = {
...formData.value,
fileIds: formData.value.photo.map((i) => i.id),
gpsLocation: formData.value.gpsLocation.join(','),
qualis: proveList.value.map((p) => {
return {
...p,
files: p.files.map((f) => f.id)
}
})
}
EnterprisesApi.createEnterprises(data).then((res) => {
formData.value.id = res
message.success('保存成功')
loading.value = false
})
}
}
const setProve = (prove) => {
proveList.value.push(prove)
}
const editProve = (id) => {
if (isView) return
unref(proveFormRef).open({ id })
}
const getDetail = () => {
EnterprisesApi.enterpriseDetail(formData.value.id).then((res) => {
formData.value = res
formData.value.photo = formData.value.files
formData.value.gpsLocation = formData.value.gpsLocation.split(',')
formData.value.tagIds = res.tagObjList.map((i) => i.id)
if (isView) {
formData.value.region = getDictLabel(DICT_TYPE.ENTERPRISES_AREA, formData.value.region)
formData.value.tagIds = res.tagObjList.map((i) => i.tagName).join(',')
}
})
}
const getProveList = () => {
EnterpriseQualificationApi.getEnterpriseQualificationPage({
pageSize: -1,
enterpriseId: formData.value.id
}).then((res) => {
proveList.value = res.list.map((i) => {
return {
...i,
files: i.qualificationFiles
}
})
})
}
const deleteProve = (id: any) => {
EnterpriseQualificationApi.deleteEnterpriseQualification(id).then(() => {
message.success('删除成功')
getProveList()
})
}
const getLogList = () => {
logLoading.value = true
EnterpriseInspectionsApi.getListByEnterpriseId(logParams).then((res) => {
logLoading.value = false
logTotal.value = res.total
logList.value = res.list
getSpanArr(logList.value)
})
}
// 查看图片
const imagePreview = (imgUrl: string) => {
createImageViewer({
zIndex: 9999999,
urlList: [imgUrl]
})
}
const logSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
if (columnIndex == 0) {
const _row = logSpanArr.value[rowIndex]
const _col = _row > 0 ? 1 : 0
return { rowspan: _row, colspan: _col }
}
}
const showInspection = (id) => {
unref(inspectionRef).open({ id })
}
const getSpanArr = (data) => {
logSpanArr.value = []
let pos = 0
for (var i = 0; i < data.length; i++) {
if (i === 0) {
logSpanArr.value.push(1)
pos = 0
} else {
// 判断当前元素与上一个元素是否相同 inAccessCode(批次字段)
if (data[i].taskId === data[i - 1].taskId) {
logSpanArr.value[pos] += 1
logSpanArr.value.push(0)
} else {
logSpanArr.value.push(1)
pos = i
}
}
}
}
getSelectOption()
onMounted(() => {
if (route.query.id) {
formData.value.id = route.query.id
getDetail()
getProveList()
}
if (route.query.view) {
isView.value = true
logParams.enterpriseId = route.query.id
getLogList()
}
})
</script>
<style lang="scss" scoped>
.view-wrapper {
display: flex;
flex-flow: row nowrap;
gap: 40px;
.title-wrapper {
font-size: 16px;
line-height: 140%;
font-weight: 700;
margin-bottom: 40px;
}
.form-photo {
grid-column: span 2;
}
.base-form {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 40px;
.el-form-item--large {
margin-bottom: 0;
}
.form-textarea {
grid-row: span 2;
::v-deep(.el-textarea) {
height: 100%;
.el-textarea__inner {
height: 100%;
white-space: pre-wrap;
&::-webkit-scrollbar {
width: 4px;
}
&::-webkit-scrollbar-thumb {
background-color: #ccc;
border-radius: 10px;
}
&::-webkit-scrollbar-track {
background-color: transparent;
}
&::-webkit-scrollbar-button {
display: none;
height: 2px;
}
}
}
}
.form-sub-title {
font-size: 16px;
line-height: 140%;
font-weight: 700;
grid-column: span 2;
}
:deep(
.el-input-number.is-controls-right[class*='large'] [class*='decrease'],
.el-input-number.is-controls-right[class*='large'] [class*='increase']
) {
--el-input-number-controls-height: 50%;
}
:deep(.el-input__suffix-inner > :first-child) {
margin-right: 8px;
}
:deep(.el-input-number .el-input__inner) {
text-align: left;
}
}
.prove-wrapper {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20px;
.prove {
width: 200px;
height: 238px;
border: 1px solid #ccc;
border-radius: 8px;
overflow: hidden;
padding: 12px;
.image-wrapper {
position: relative;
height: 130px;
margin-bottom: 12px;
border-radius: 6px;
overflow: hidden;
&:hover {
.operation {
opacity: 1;
}
}
.operation {
cursor: pointer;
opacity: 0;
position: absolute;
inset: 0;
background-color: rgba(0, 0, 0, 0.7);
display: flex;
justify-content: center;
align-items: center;
gap: 20px;
color: #fff;
font-size: 14px;
transition: var(--el-transition-time);
.item {
display: flex;
flex-flow: column nowrap;
align-items: center;
gap: 8px;
&:hover {
color: var(--el-color-primary);
}
}
}
}
}
.add-prove {
width: 200px;
height: 238px;
border: 1px dashed #ccc;
border-radius: 8px;
display: flex;
justify-content: center;
align-items: center;
color: #ccc;
transition: all 0.2s;
&:hover {
color: var(--el-color-primary);
border-color: var(--el-color-primary);
cursor: pointer;
}
}
}
}
</style>