Browse Source

Merge remote-tracking branch 'origin/dev-V1.10.0' into dev-V1.10.0

dev-V1.10.0
niujiyi 1 week ago
parent
commit
da0acbe30d
  1. 2
      zdxt-web-client/zdxt-admin-plus-ui/src/views/efcode/trend/high-frequency/components/FreqPane.vue
  2. 4
      zdxt-web-client/zdxt-admin-plus-ui/src/views/supervision/statistical/city-direct/index.vue
  3. 6
      zdxt-web-client/zdxt-efcode-enterprise-app/src/api/enterprise/index.js
  4. 337
      zdxt-web-client/zdxt-efcode-enterprise-app/src/views/enterprise/enforcement/enforcementEvaluateDetail.vue
  5. 22
      zdxt-web-client/zdxt-efcode-enterprise-app/src/views/enterprise/enforcement/enforcementRegistrationList.vue

2
zdxt-web-client/zdxt-admin-plus-ui/src/views/efcode/trend/high-frequency/components/FreqPane.vue

@ -348,7 +348,7 @@ defineExpose({ calcTableHeight });
v-if="detailEnterprise"
:closable="false"
show-icon
:title="`所属区:${detailEnterprise.district || '-'} | 所属街道:${detailEnterprise.street || '-'} | 行政执法次数:${detailEnterprise.xzzfcs ?? 0}次 | 时段:${queryParams.year}年${queryParams.month}`"
:title="`所属区:${detailEnterprise.district || '-'} | 所属街道:${detailEnterprise.street || '-'} | 行政执法次数:${detailEnterprise.xzzfcs ?detailEnterprise.xzzfcs : detailEnterprise.jccs}次 | 时段:${queryParams.year}年${queryParams.month}`"
type="info"
class="mb-4"
/>

4
zdxt-web-client/zdxt-admin-plus-ui/src/views/supervision/statistical/city-direct/index.vue

@ -105,12 +105,12 @@
</div>
</div>
<div class="count_com count_rev">
<h4>评价</h4>
<h4>反馈</h4>
<div class="count_list">
<div class="count_row"><span>满意</span><span>{{ stats.eva?.high ?? '-' }}</span><span>{{ evaRates.high }}%</span></div>
<div class="count_row"><span>较满意</span><span>{{ stats.eva?.mid ?? '-' }}</span><span>{{ evaRates.mid }}%</span></div>
<div class="count_row"><span>不满意</span><span>{{ stats.eva?.low ?? '-' }}</span><span>{{ evaRates.low }}%</span></div>
<div class="count_row"><span>未评价</span><span>{{ stats.eva?.un ?? '-' }}</span><span>{{ evaRates.un }}%</span></div>
<div class="count_row"><span>未反馈</span><span>{{ stats.eva?.un ?? '-' }}</span><span>{{ evaRates.un }}%</span></div>
</div>
</div>
</div>

6
zdxt-web-client/zdxt-efcode-enterprise-app/src/api/enterprise/index.js

@ -25,6 +25,9 @@ export const getEnterpriseEnforcementRegistrationList = (params, success, error)
//执法登记列表
export const queryEnforcementRegistrationPageList = (params, success, error) => _get(enterpriseAppBaseUrl+"/enforcement_registration/queryEnforcementRegistrationPageList",params,success,error)
//非行政执法登记列表(独立接口,与行政接口解耦)
export const queryNonEnforcementRegistrationList = (params, success, error) => _get(enterpriseAppBaseUrl+"/nonEnfRegistraionInfo/list",params,success,error)
//执法信息详情
export const getLawDetail = (params, success, error) => _get(enterpriseAppBaseUrl+"/lawEnforcementCase/lawDetail",params,success,error)
@ -40,6 +43,9 @@ export const submitEvaluate = (params, success, error) => _post(enterpriseAppBas
//企业消息 / 执法消息详情
export const getEnforcementRegistrationDetailById = (params, success, error) => _get(enterpriseAppBaseUrl + "/enforcement_registration/queryDetailById", params, success, error)
//非行政执法登记详情(独立接口)
export const queryNonEnforcementRegistrationDetailById = (params, success, error) => _get(enterpriseAppBaseUrl + "/nonEnfRegistraionInfo/queryById", params, success, error)
//普法服务列表
export const getEducationServicesList = (params, success, error) => _get(enterpriseAppBaseUrl +"/enforcementcode/educationServices/list",params,success,error)

337
zdxt-web-client/zdxt-efcode-enterprise-app/src/views/enterprise/enforcement/enforcementEvaluateDetail.vue

@ -1,194 +1,175 @@
<template>
<div class="evaluate-detail-page">
<!-- 顶部导航栏 -->
<!-- <van-nav-bar :title="detail.title || '执法反馈'" left-text="关闭" left-arrow @click-left="onClickLeft" /> -->
<!-- 内容区域 -->
<div class="content-area">
<!-- 企业信息卡片 -->
<div class="info-card">
<div class="card-title">企业信息</div>
<div class="info-row">
<span class="info-label">企业名称</span>
<span class="info-value">{{ detail.enterpriseName }}</span>
</div>
<div class="info-row">
<span class="info-label">统一社会信用代码</span>
<span class="info-value">{{ detail.enterpriseNumber }}</span>
<!-- 非行政执法详情 -->
<template v-if="!isAdmin">
<div class="content-area">
<!-- 企业信息卡片 -->
<div class="info-card">
<div class="card-title">企业信息</div>
<div class="info-row">
<span class="info-label">企业名称</span>
<span class="info-value">{{ detail.enterpriseName || '-' }}</span>
</div>
<div class="info-row">
<span class="info-label">统一社会信用代码</span>
<span class="info-value">{{ detail.enterpriseNumber || '-' }}</span>
</div>
</div>
</div>
<!-- 执法信息卡片 -->
<div class="info-card">
<div class="card-title">执法信息 <span class="union-tag" v-if="detail.isRealUnion === 1">联</span></div>
<div class="info-row">
<span class="info-label">执法单位</span>
<span class="info-value">{{ detail.bureauDeptName }}</span>
</div>
<div class="info-row">
<span class="info-label">执法人员</span>
<div class="info-value enforcer-value">
<div class="enforcer-line">
<span class="enforcer-name">{{ parseEnforcer(detail.lawEnforcer).name }}</span>
<span v-if="parseEnforcer(detail.lawEnforcer).phone" class="enforcer-id">{{ parseEnforcer(detail.lawEnforcer).phone }}</span>
</div>
<div v-for="(enforcer, index) in detail.lawEnforcer2Show ? detail.lawEnforcer2Show.split(','): detail.lawEnforcer2List" :key="index" class="enforcer-line">
<span class="enforcer-name">{{ parseEnforcer(enforcer).name }}</span>
<span v-if="parseEnforcer(enforcer).phone" class="enforcer-id">{{ parseEnforcer(enforcer).phone }}</span>
<!-- 入企信息卡片 -->
<div class="info-card">
<div class="card-title">入企信息</div>
<div class="info-row">
<span class="info-label">入企单位</span>
<span class="info-value">{{ detail.bureauDeptName || '-' }}</span>
</div>
<div class="info-row">
<span class="info-label">入企人员</span>
<div class="info-value enforcer-value">
<div class="enforcer-line">
<span class="enforcer-name">{{ parseEnforcer(detail.lawEnforcer).name }}</span>
<span v-if="parseEnforcer(detail.lawEnforcer).phone" class="enforcer-id">{{ parseEnforcer(detail.lawEnforcer).phone }}</span>
</div>
<div class="enforcer-line">
<span class="enforcer-name">{{ parseEnforcer(detail.lawEnforcerOther).name }}</span>
<span v-if="parseEnforcer(detail.lawEnforcerOther).phone" class="enforcer-id">{{ parseEnforcer(detail.lawEnforcerOther).phone }}</span>
</div>
</div>
</div>
</div>
<div class="info-row">
<span class="info-label">执法类别</span>
<span class="info-value">{{ getDictText('law_enforce_category', detail.lawEnforceCategory) }}</span>
</div>
<div class="info-row">
<span class="info-label">任务来源</span>
<span class="info-value">{{ getDictText('check_category', detail.checkCategory) }}</span>
</div>
<div class="info-row">
<span class="info-label">执法事项</span>
<span class="info-value">{{ detail.lawEnforcementItemText }}</span>
</div>
<div class="info-row">
<span class="info-label">执法时间</span>
<span class="info-value">{{ detail.enforcementTime }}</span>
</div>
<!-- <div class="info-row">
<span class="info-label">受委托执法</span>
<span class="info-value">
<van-radio-group v-model="detail.hasAuto" direction="horizontal" disabled>
<van-radio :name="1" shape="square">是</van-radio>
<van-radio :name="0" shape="square">否</van-radio>
</van-radio-group>
</span>
</div> -->
<!-- <div class="info-row">
<span class="info-label">委托行政机关</span>
<span class="info-value">{{ detail.entrustDeptName }}</span>
</div> -->
<!-- <div class="info-row result-row">
<span class="info-label">结果</span>
<span class="info-value">
<span class="result-tag" :class="detail.reslut === 0 ? 'pass' : 'fail'">{{ detail.reslut === 0 ?
'合格' : '不合格'
}}</span>
<span class="view-detail-link" @click="onViewCaseDetail">查看案件详情 ></span>
</span>
</div> -->
</div>
<div class="info-card">
<div class="info-has-auto">
<span class="info-label has-auto-label">受委托执法</span>
<span class="info-value">
<van-radio-group v-model="detail.hasAuto" direction="horizontal" disabled>
<van-radio :name="1" shape="square">是</van-radio>
<van-radio :name="0" shape="square">否</van-radio>
</van-radio-group>
</span>
</div>
<div class="info-row" v-if="detail.hasAuto">
<span class="info-label has-auto-label">委托行政机关</span>
<span class="info-value">{{ detail.entrustDeptName }}</span>
<div class="info-row">
<span class="info-label">入企事由</span>
<span class="info-value">{{ detail.lawEnforcementItemText}}</span>
</div>
<div class="info-row">
<span class="info-label">入企事项</span>
<span class="info-value">{{ detail.lawEnforcementTypeText }}</span>
</div>
<div class="info-row">
<span class="info-label">入企时间</span>
<span class="info-value">{{ detail.enforcementTime }}</span>
</div>
</div>
</div>
<!-- 附件卡片 -->
<div class="info-card" v-if="detail.attachments && detail.attachments.length > 0">
<div class="card-title">附件</div>
<div class="attachment-list">
<div class="attachment-item" v-for="(file, idx) in detail.attachments" :key="idx">
<van-icon name="description" size="20" color="#999" />
<span class="attachment-name">{{ file.name }}</span>
</template>
<!-- 行政执法详情(原内容) -->
<template v-else>
<!-- 顶部导航栏 -->
<!-- <van-nav-bar :title="detail.title || '执法反馈'" left-text="关闭" left-arrow @click-left="onClickLeft" /> -->
<!-- 内容区域 -->
<div class="content-area">
<!-- 企业信息卡片 -->
<div class="info-card">
<div class="card-title">企业信息</div>
<div class="info-row">
<span class="info-label">企业名称</span>
<span class="info-value">{{ detail.enterpriseName }}</span>
</div>
<div class="info-row">
<span class="info-label">统一社会信用代码</span>
<span class="info-value">{{ detail.enterpriseNumber }}</span>
</div>
</div>
</div>
<!-- 反馈卡片(已反馈:仅当后端返回 enterpriseEvaluateInfoVo 有数据时显示;待反馈:始终显示) -->
<div class="evaluate-card" v-if="showEvaluateCard">
<!-- <div class="card-title">反馈</div> -->
<!-- 表情选择 -->
<!-- <div class="emoji-section">
<div class="emoji-item" :class="{ active: evaluateForm.satisfactionLevel === 3, disabled: readonly }"
@click="!readonly && (evaluateForm.satisfactionLevel = 3)">
<img class="emoji-img" :src="evaluateForm.satisfactionLevel === 3 ? veryGoodImg : veryGoodDisImg"
alt="满意" />
<span class="emoji-label">满意</span>
<!-- 执法信息卡片 -->
<div class="info-card">
<div class="card-title">执法信息 <span class="union-tag" v-if="detail.isRealUnion === 1">联</span></div>
<div class="info-row">
<span class="info-label">执法单位</span>
<span class="info-value">{{ detail.bureauDeptName }}</span>
</div>
<div class="emoji-item" :class="{ active: evaluateForm.satisfactionLevel === 2, disabled: readonly }"
@click="!readonly && (evaluateForm.satisfactionLevel = 2)">
<img class="emoji-img" :src="evaluateForm.satisfactionLevel === 2 ? goodImg : goodDisImg"
alt="较满意" />
<span class="emoji-label">较满意</span>
<div class="info-row">
<span class="info-label">执法人员</span>
<div class="info-value enforcer-value">
<div class="enforcer-line">
<span class="enforcer-name">{{ parseEnforcer(detail.lawEnforcer).name }}</span>
<span v-if="parseEnforcer(detail.lawEnforcer).phone" class="enforcer-id">{{ parseEnforcer(detail.lawEnforcer).phone }}</span>
</div>
<div v-for="(enforcer, index) in detail.lawEnforcer2Show ? detail.lawEnforcer2Show.split(','): detail.lawEnforcer2List" :key="index" class="enforcer-line">
<span class="enforcer-name">{{ parseEnforcer(enforcer).name }}</span>
<span v-if="parseEnforcer(enforcer).phone" class="enforcer-id">{{ parseEnforcer(enforcer).phone }}</span>
</div>
</div>
</div>
<div class="info-row">
<span class="info-label">执法类别</span>
<span class="info-value">{{ getDictText('law_enforce_category', detail.lawEnforceCategory) }}</span>
</div>
<div class="emoji-item" :class="{ active: evaluateForm.satisfactionLevel === 1, disabled: readonly }"
@click="!readonly && (evaluateForm.satisfactionLevel = 1)">
<img class="emoji-img" :src="evaluateForm.satisfactionLevel === 1 ? badImg : badDisImg"
alt="不满意" />
<span class="emoji-label">不满意</span>
<div class="info-row">
<span class="info-label">任务来源</span>
<span class="info-value">{{ getDictText('check_category', detail.checkCategory) }}</span>
</div>
</div> -->
<!-- 星级评分 -->
<!-- <div class="rating-section">
<div class="rating-row">
<span class="rating-label">执法文明</span>
<van-rate v-model="evaluateForm.civility" :size="20" color="#ffd21e" void-icon="star"
void-color="#eee" :readonly="readonly" />
<span class="rating-text">{{ getRatingText(evaluateForm.civility) }}</span>
<div class="info-row">
<span class="info-label">执法事项</span>
<span class="info-value">{{ detail.lawEnforcementItemText }}</span>
</div>
<div class="rating-row">
<span class="rating-label">执法效率</span>
<van-rate v-model="evaluateForm.efficiency" :size="20" color="#ffd21e" void-icon="star"
void-color="#eee" :readonly="readonly" />
<span class="rating-text">{{ getRatingText(evaluateForm.efficiency) }}</span>
<div class="info-row">
<span class="info-label">执法时间</span>
<span class="info-value">{{ detail.enforcementTime }}</span>
</div>
<div class="rating-row">
<span class="rating-label">执法态度</span>
<van-rate v-model="evaluateForm.attitude" :size="20" color="#ffd21e" void-icon="star"
void-color="#eee" :readonly="readonly" />
<span class="rating-text">{{ getRatingText(evaluateForm.attitude) }}</span>
</div>
<div class="info-card">
<div class="info-has-auto">
<span class="info-label has-auto-label">受委托执法</span>
<span class="info-value">
<van-radio-group v-model="detail.hasAuto" direction="horizontal" disabled>
<van-radio :name="1" shape="square">是</van-radio>
<van-radio :name="0" shape="square">否</van-radio>
</van-radio-group>
</span>
</div>
<div class="rating-row">
<span class="rating-label">合 法 性</span>
<van-rate v-model="evaluateForm.legality" :size="20" color="#ffd21e" void-icon="star"
void-color="#eee" :readonly="readonly" />
<span class="rating-text">{{ getRatingText(evaluateForm.legality) }}</span>
<div class="info-row" v-if="detail.hasAuto">
<span class="info-label has-auto-label">委托行政机关</span>
<span class="info-value">{{ detail.entrustDeptName }}</span>
</div>
</div>
<!-- 附件卡片 -->
<div class="info-card" v-if="detail.attachments && detail.attachments.length > 0">
<div class="card-title">附件</div>
<div class="attachment-list">
<div class="attachment-item" v-for="(file, idx) in detail.attachments" :key="idx">
<van-icon name="description" size="20" color="#999" />
<span class="attachment-name">{{ file.name }}</span>
</div>
</div>
</div> -->
<!-- 其他问题开关 -->
<div class="switch-section">
<span class="switch-label">反馈</span>
<van-switch v-model="evaluateForm.hasOtherIssues" size="20" active-color="#2b7de9"
:disabled="readonly" />
</div>
<!-- 问题列表 -->
<div class="question-list" v-if="evaluateForm.hasOtherIssues">
<div class="question-item" v-for="(q, idx) in questionList" :key="idx" v-show="!q.isOther">
<div class="question-text">{{ idx + 1 }}、{{ q.text }}</div>
<div class="question-options">
<div class="option-btn" :class="{ active: q.answer === '是', disabled: readonly }"
@click="!readonly && setAnswer(q, '是')">
<img :src="q.answer === '是' ? badUnselectImg : badSelectImg" alt="是" />
<span>是</span>
</div>
<div class="option-btn" :class="{ active: q.answer === '否', disabled: readonly }"
@click="!readonly && setAnswer(q, '否')">
<img :src="q.answer === '否' ? goodUnselectImg : goodSelectImg" alt="否" />
<span>否</span>
<!-- 反馈卡片(已反馈:仅当后端返回 enterpriseEvaluateInfoVo 有数据时显示;待反馈:始终显示) -->
<div class="evaluate-card" v-if="showEvaluateCard">
<!-- 其他问题开关 -->
<div class="switch-section">
<span class="switch-label">反馈</span>
<van-switch v-model="evaluateForm.hasOtherIssues" size="20" active-color="#2b7de9"
:disabled="readonly" />
</div>
<!-- 问题列表 -->
<div class="question-list" v-if="evaluateForm.hasOtherIssues">
<div class="question-item" v-for="(q, idx) in questionList" :key="idx" v-show="!q.isOther">
<div class="question-text">{{ idx + 1 }}、{{ q.text }}</div>
<div class="question-options">
<div class="option-btn" :class="{ active: q.answer === '是', disabled: readonly }"
@click="!readonly && setAnswer(q, '是')">
<img :src="q.answer === '是' ? badUnselectImg : badSelectImg" alt="是" />
<span>是</span>
</div>
<div class="option-btn" :class="{ active: q.answer === '否', disabled: readonly }"
@click="!readonly && setAnswer(q, '否')">
<img :src="q.answer === '否' ? goodUnselectImg : goodSelectImg" alt="否" />
<span>否</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 底部提交按钮(仅待反馈状态显示) -->
<div class="footer-bar" v-if="!readonly">
<van-button type="primary" block round @click="onSubmit">提交反馈</van-button>
</div>
<!-- 底部提交按钮(仅待反馈状态显示) -->
<div class="footer-bar" v-if="!readonly">
<van-button type="primary" block round @click="onSubmit">提交反馈</van-button>
</div>
</template>
</div>
</template>
@ -209,6 +190,7 @@ import badUnselectImg from '@/assets/images/onbad.png';
import {
getEvaluateDetail,
getEnforcementRegistrationDetailById,
queryNonEnforcementRegistrationDetailById,
submitEvaluate,
} from '@/api/enterprise';
import { loadDict, getDictText } from '@/util/dictUtil';
@ -218,6 +200,8 @@ const router = useRouter();
const route = useRoute();
const id = route.query.id;
// 行政/非行政分流标识:列表页跳过来时 lawType='1' 表示行政
const isAdmin = computed(() => String(route.query.lawType || '1') === '1');
// 只读标识:hasEvaluate=1 已反馈只能查看,0/空 为待反馈可提交
const readonly = computed(() => String(route.query.hasEvaluate) === '1');
// 已反馈返回的反馈信息对象(后端 enterpriseEvaluateInfoVo)
@ -253,7 +237,6 @@ const detail = ref({
result: '',
attachments: [],
});
// ========== 反馈表单(默认值:满意=3 / 5 星 / 其他问题打开)==========
// 满意度数值:1=不满意,2=较满意,3=满意
const evaluateForm = ref({
@ -308,12 +291,24 @@ const getEnforcers = (data) => {
// 获取执法详情
const fetchRegistrationDetail = () => {
if (!id) return;
getEnforcementRegistrationDetailById({ id }, (res) => {
const lawType = String(route.query.lawType || '');
const isAdmin = lawType === '1';
const api = isAdmin
? getEnforcementRegistrationDetailById
: queryNonEnforcementRegistrationDetailById;
api({ id }, (res) => {
// 兼容多种返回包裹:行政接口是 { data: { enforcementRegistrationVo, enterpriseEvaluateInfoVo } }
// 非行政接口可能是 { data: 详情对象 } 或 直接就是详情对象,这里做统一兜底
const data = (res && (res.data || res.rows?.[0] || res)) || {};
detail.value = data.enforcementRegistrationVo
|| {};
// 保存企业反馈信息(可能为 null),用于已反馈识别反馈卡片是否显示
evaluateInfo.value = data.enterpriseEvaluateInfoVo || null;
// 详情对象:优先取行政接口的 enforcementRegistrationVo,否则 data 本身就是详情
const detailData = data.enforcementRegistrationVo
|| data.nonEnforcementRegistrationVo
|| data.vo
|| data;
detail.value = detailData;
// 反馈信息
evaluateInfo.value = data.enterpriseEvaluateInfoVo || data.evaluateInfo || null;
// 已反馈:将后端反馈数据回填到表单供只读展示
if (evaluateInfo.value) fillEvaluateFormFromInfo(evaluateInfo.value);
}, () => {

22
zdxt-web-client/zdxt-efcode-enterprise-app/src/views/enterprise/enforcement/enforcementRegistrationList.vue

@ -67,7 +67,7 @@
</template>
<script setup name="enforcementRegistrationList">
import { queryEnforcementRegistrationPageList } from '@/api/enterprise';
import { queryEnforcementRegistrationPageList, queryNonEnforcementRegistrationList } from '@/api/enterprise';
import { showToast } from 'vant';
import 'vant/es/toast/style';
import SearchFilterBar from '@/components/common/SearchFilterBar.vue';
@ -128,12 +128,15 @@ const getEnforcers = (item) => {
// ========== 加载数据 ==========
const fetchList = () => {
const isAdmin = activeTab.value === '1';
const params = {
pageNum: pageNum.value,
pageSize: pageSize.value,
lawType: activeTab.value,
// enterpriseNumber: useCommon.enterpriseNumber,
};
// 仅行政接口需传 lawType 区分,非行政接口本身已独立
if (isAdmin) {
params.lawType = activeTab.value;
}
if (searchText.value) {
params.searchValue = searchText.value;
}
@ -144,7 +147,11 @@ const fetchList = () => {
params.dateSearch = dateSearch.value;
}
queryEnforcementRegistrationPageList(params, (res) => {
const api = isAdmin
? queryEnforcementRegistrationPageList
: queryNonEnforcementRegistrationList;
api(params, (res) => {
// 兼容数组 / 包裹格式
let rows = [];
let total = 0;
@ -156,6 +163,10 @@ const fetchList = () => {
rows = res.rows;
total = res.total || rows.length;
ok = res.code ? res.code === 200 : true;
} else if (res && res.data && Array.isArray(res.data.rows)) {
rows = res.data.rows;
total = res.data.total || rows.length;
ok = res.code ? res.code === 200 : true;
} else if (res && Array.isArray(res.data)) {
rows = res.data;
total = res.total || rows.length;
@ -231,7 +242,7 @@ const onSearchFilter = ({ searchText: st, dateType: dt, dateSearch: ds }) => {
const toDetailView = (item) => {
router.push({
path: '/enterprise/enforcementEvaluateDetail',
query: { id: item.id, hasEvaluate: 1 }
query: { id: item.id, hasEvaluate: 1, lawType: activeTab.value }
});
};
@ -242,6 +253,7 @@ const toEvaluate = (id, checkItem) => {
query: {
id,
hasEvaluate: 0,
lawType: activeTab.value,
// lawEnforcementItemText: checkItem,
}
});

Loading…
Cancel
Save