Browse Source

feat: 增加巡查

dev
上官小雨 5 months ago
parent
commit
2b6928a04b
  1. 1
      zdxt-web-client/zdxt-admin-nos-plus-ui/.prettierrc
  2. 20
      zdxt-web-client/zdxt-efcode-nos-enforcement-app/.prettierrc
  3. 5
      zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/api/nos/enfDemo.js
  4. 2
      zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/components/FooterBar.vue
  5. 50
      zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/components/enforcement/nos/AttachmentTaskSource.vue
  6. 54
      zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/components/enforcement/nos/EnforcementInfoSection.vue
  7. 9
      zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/router/nos/nos-base-router.js
  8. 26
      zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/views/enforcement/nos/components/NosDetailMaterialsTab.vue
  9. 21
      zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/views/enforcement/nos/components/NosDetailTaskTab.vue
  10. 534
      zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/views/enforcement/nos/nosAdd.vue
  11. 15
      zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/views/enforcement/nos/nosDetail.vue
  12. 44
      zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/views/enforcement/nos/nosEvaluateList.vue
  13. 14
      zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/views/enforcement/nos/nosList.vue
  14. 2
      zdxt-web-client/zdxt-efcode-nos-enforcement-app/vite-env/.env.enforcement-dev
  15. 11
      zdxt-web-client/zdxt-efcode-nos-enterprise-app/src/views/enterprise/nos/components/NosDetailTaskTab.vue
  16. 10
      zdxt-web-client/zdxt-efcode-nos-enterprise-app/src/views/enterprise/nos/nosDetail.vue
  17. 1
      zdxt-web-client/zdxt-efcode-nos-enterprise-app/src/views/enterprise/nos/nosList.vue
  18. 2
      zdxt-web-client/zdxt-efcode-nos-enterprise-app/vite-env/.env.enterprise-dev

1
zdxt-web-client/zdxt-admin-nos-plus-ui/.prettierrc

@ -16,5 +16,6 @@
"proseWrap": "preserve",
"htmlWhitespaceSensitivity": "css",
"vueIndentScriptAndStyle": false,
"singleAttributePerLine": false,
"endOfLine": "auto"
}

20
zdxt-web-client/zdxt-efcode-nos-enforcement-app/.prettierrc

@ -0,0 +1,20 @@
{
"printWidth": 150,
"tabWidth": 2,
"useTabs": false,
"semi": true,
"singleQuote": true,
"quoteProps": "preserve",
"jsxSingleQuote": false,
"bracketSameLine": false,
"trailingComma": "none",
"bracketSpacing": true,
"embeddedLanguageFormatting": "auto",
"arrowParens": "always",
"requirePragma": false,
"insertPragma": false,
"proseWrap": "preserve",
"htmlWhitespaceSensitivity": "css",
"vueIndentScriptAndStyle": false,
"endOfLine": "auto"
}

5
zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/api/nos/enfDemo.js

@ -6,7 +6,7 @@ const baseUrl = "/app-enf";
export const listEnfDemo = (params) =>
_get("/enforcementcode/enfDemo/list", params);
// 非现场api
// 非现场api
// 新增非现场执法任务
export const nosAddApi = (params, success, error) => _post("/app-enf/nos-law-enforcement-task/add", params, success, error);
// 分页查询非现场执法任务
@ -19,3 +19,6 @@ export const nosApproveApi = (params, success, error) => _post("/app-enf/nos-law
export const nosTypeApi = (params, success, error) => _post("/app-enf/nos-law-enforcement-task/type", params, success, error);
//查询非现场执法项目任务来源列表
export const nosTaskSourceListApi = (params, success, error) => _post("/app-enf/task-source/list", params, success, error);
//查询已评价的任务
export const nosTaskHasCommentPageApi = (params, success, error) => _post("/app-enf/nos-law-enforcement-task/has-comment/page", params, success, error);

2
zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/components/FooterBar.vue

@ -79,7 +79,7 @@ const tabs = [
{
key: "message",
label: "消息",
route: "/enforcement/message",
route: "/enforcement/nos/evaluate",
path: '<path d="M12 22c1.1 0 2-.9 2-2h-4c0 1.1.89 2 2 2zm6-6v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.63 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z"/>'
},
{

50
zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/components/enforcement/nos/AttachmentTaskSource.vue

@ -12,6 +12,7 @@
<!-- 任务来源 -->
<van-field
:class="formData.taskTypeId == 5 ? 'usci-code-field' : ''"
:model-value="taskSourceName"
is-link
readonly
@ -20,15 +21,16 @@
placeholder="请选择"
@click="$emit('showTaskSourcePicker')"
clearable
:rules="[{ required: true, message: '请选择任务来源' }]"
required />
:rules="[{ required: formData.taskTypeId != 5, message: '请选择任务来源' }]"
:required="formData.taskTypeId != 5"
/>
</div>
</template>
<script setup name="AttachmentTaskSource">
import { computed } from "vue"
import { uploadFile } from "@/util/fileUpload"
import { toFullFileUrl } from "@/util/fileUrl"
import { computed } from 'vue';
import { uploadFile } from '@/util/fileUpload';
import { toFullFileUrl } from '@/util/fileUrl';
const props = defineProps({
formData: {
@ -39,29 +41,29 @@ const props = defineProps({
type: Array,
default: () => []
}
})
});
const taskSourceName = computed(() => {
const option = props.taskSourceOptions.find((item) => item.value === props.formData.taskSourceId)
return option?.text || ""
})
const option = props.taskSourceOptions.find((item) => item.value === props.formData.taskSourceId);
return option?.text || '';
});
const emit = defineEmits(["showTaskSourcePicker", "open-picker"])
const emit = defineEmits(['showTaskSourcePicker', 'open-picker']);
// 附件上传处理
const onAfterReadImage = (file) => {
const files = Array.isArray(file) ? file : [file]
const files = Array.isArray(file) ? file : [file];
files.forEach((f) => {
uploadFile(f, (res) => {
const data = res && res.data ? res.data : res
const filePath = typeof data === "string" ? data : (data && (data.url || data.fileUrl || data.path)) || ""
const data = res && res.data ? res.data : res;
const filePath = typeof data === 'string' ? data : (data && (data.url || data.fileUrl || data.path)) || '';
if (filePath) {
f.url = toFullFileUrl(filePath)
f.status = "done"
f.url = toFullFileUrl(filePath);
f.status = 'done';
}
})
})
}
});
});
};
</script>
<style lang="less" scoped>
@ -107,20 +109,24 @@ const onAfterReadImage = (file) => {
border-radius: 0.1rem;
}
}
:deep(.van-cell){
padding-left: 10px;
padding-right: 10px;
:deep(.van-cell) {
padding-left: 10px;
padding-right: 10px;
}
.label-required-placeholder .form-label {
position: relative;
padding-left: 0.1rem;
&::before {
content: "*";
content: '*';
color: transparent;
font-size: 0.32rem;
margin-right: 0.08rem;
font-weight: bold;
}
}
:deep(.usci-code-field .van-field__label) {
padding-left: 8px; // 按需调整
box-sizing: border-box;
}
</style>

54
zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/components/enforcement/nos/EnforcementInfoSection.vue

@ -1,19 +1,20 @@
<template>
<div class="section">
<div class="section-title">执法信息</div>
<div class="section-title">{{ formData.taskTypeId == 1 ? '执法信息' : '巡查信息' }}</div>
<!-- 执法单位 -->
<van-field
v-model="formData.lawEnforcementAgency"
name="lawEnforcementAgency"
label="执法单位"
placeholder="请输入执法单位"
:rules="[{ required: true, message: '请填写执法单位' }]"
required />
:label="formData.taskTypeId == 1 ?'执法单位' : '巡查单位'"
:placeholder="formData.taskTypeId == 1 ? '请输入执法单位' : '请输入巡查单位'"
:class="formData.taskTypeId == 5 ? 'usci-code-field' : ''"
:required="formData.taskTypeId != 5"
disabled />
<!-- 执法人员 -->
<div class="form-row required">
<div class="form-label"><span class="required-mark">*</span>执法人员</div>
<div class="form-label"><span class="required-mark" :class="{ 'required-mark--placeholder': formData.taskTypeId == 5 }">*</span>{{ formData.taskTypeId == 1 ? '执法人员' : '参与人员' }}</div>
<div class="form-value person-select">
<div class="person-item default-person">
<span>{{ defaultPerson?.lawEnforcerName }} {{ defaultPerson?.lawEnforcerId }}</span>
@ -31,7 +32,12 @@
</div>
</div>
<!-- 隐藏字段用于验证执法人员 -->
<van-field v-model="hasPerson" name="enforcementPerson" :rules="[{ required: true, message: '请选择执法人员' }]" style="display: none" />
<van-field
v-if="formData.taskTypeId != 5"
v-model="hasPerson"
name="enforcementPerson"
:rules="[{ required: true, message: '请选择执法人员' }]"
style="display: none" />
<!-- 执法类别 -->
<van-field
@ -40,22 +46,22 @@
readonly
:disabled="categoryDisabled"
name="taskTypeId"
class="usci-code-field"
label="类  别"
placeholder="请选择"
@click="onCategoryClick"
:clearable="!categoryDisabled"
:rules="[{ required: true, message: '请选择类别' }]"
required />
/>
<!-- 执法事项 -->
<van-field
v-model="formData.lawEnforcementMatters"
name="lawEnforcementMatters"
label="执法事项"
placeholder="请输入执法事项"
v-if="formData.taskTypeId == 1 || formData.taskTypeId == 5"
:label="formData.taskTypeId == 1 ? '执法事项' : '巡查事项'"
:placeholder="formData.taskTypeId == 1 ? '请输入执法事项' : '请输入巡查事项'"
type="textarea"
:rules="[{ required: true, message: '请填写执法事项' }]"
required
class="usci-code-field"
rows="2"
autosize
maxlength="1000"
@ -64,7 +70,7 @@
<!-- 检查要求 / 备案文件 / 验证文件 -->
<template v-if="requirementLabel">
<div class="form-row required material-header-row">
<div class="form-label"><span class="required-mark">*</span>{{ requirementLabel }}</div>
<div class="form-label"><span class="required-mark" :class="{ 'required-mark--placeholder': formData.taskTypeId == 5 }">*</span>{{ requirementLabel }}</div>
<div class="form-value">
<span class="material-hint">指定企业要上传的材料名称(例如:营业执照)</span>
</div>
@ -81,7 +87,7 @@
</div>
</template>
<van-field
v-if="requirementLabel"
v-if="requirementLabel && formData.taskTypeId != 5"
v-model="hasMaterialRequirement"
name="checkItemList"
:rules="[{ required: true, message: `请填写${requirementLabel}` }]"
@ -89,7 +95,7 @@
<!-- 执法依据 -->
<div class="form-row required">
<div class="form-label"><span class="required-mark">*</span>执法依据</div>
<div class="form-label"><span class="required-mark" :class="{ 'required-mark--placeholder': formData.taskTypeId == 5 }">*</span>执法依据</div>
<div class="form-value basis-select">
<div v-for="(basis, index) in formData.legalBasis" :key="index" class="basis-item-add">
<span @click="$emit('openBasisPicker', index)" :class="{ placeholder: !basis }">
@ -109,13 +115,14 @@
<van-field
v-model="formData.deadline"
name="deadline"
:class="formData.taskTypeId == 5 ? 'usci-code-field' : ''"
label="截止时间"
placeholder="请选择截止时间"
is-link
readonly
:rules="[{ required: true, message: '请选择截止时间' }]"
:rules="[{ required: formData.taskTypeId != 5, message: '请选择截止时间' }]"
@click="$emit('showTimePicker')"
required />
:required="formData.taskTypeId != 5" />
<!-- 联合执法 -->
</div>
@ -156,7 +163,8 @@ const onCategoryClick = () => {
const CATEGORY_REQUIREMENT_LABEL_MAP = {
行政检查: "检查要求",
材料备案: "备案文件",
材料验证: "验证文件"
材料验证: "验证文件",
巡查: "巡查要求"
}
// 根据类别动态显示 label(独立 category prop,避免 keep-alive 下嵌套对象追踪失效)
@ -240,6 +248,10 @@ const removeMaterialRow = (index) => {
font-size: 0.32rem;
margin-right: 0.08rem;
font-weight: bold;
&--placeholder {
visibility: hidden;
}
}
@ -473,4 +485,8 @@ const removeMaterialRow = (index) => {
padding-left: 10px;
padding-right: 10px;
}
:deep(.usci-code-field .van-field__label) {
padding-left: 8px; // 按需调整
box-sizing: border-box;
}
</style>

9
zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/router/nos/nos-base-router.js

@ -27,6 +27,15 @@ const routes = [
isKeepAlive: false,
},
},
// 非现场消息
{
path: "/enforcement/nos/evaluate",
name: "nosEvaluate",
component: () => import("@/views/enforcement/nos/nosEvaluateList.vue"),
meta: {
isKeepAlive: false,
},
},
];
export { routes };

26
zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/views/enforcement/nos/components/NosDetailMaterialsTab.vue

@ -7,6 +7,18 @@
<div class="empty-text-sub">等待企业上传材料</div>
</div>
</template>
<template v-else-if="Number(taskStatus) === 5">
<div class="empty-state">
<van-image :src="noDataImg" width="151" height="120" />
<div class="empty-text-main">暂无资料上传</div>
<div class="empty-text-sub"></div>
</div>
<div class="result-card">
<div class="result-title">检查结果</div>
<div class="readonly-result-text">检查结果:已办结(<span class="overdue-text">超期</span>)</div>
<div class="readonly-result-text" v-if="overdueCheckTime">检查时间:{{ overdueCheckTime }}</div>
</div>
</template>
<template v-else>
<div
v-for="(item, index) in taskItemList"
@ -218,12 +230,18 @@ const props = defineProps({
type: [Number, String],
default: ''
},
taskDeadline: {
type: String,
default: '',
},
evaluateData: {
type: Object,
default: null,
}
});
const overdueCheckTime = computed(() => props.taskDeadline || '');
const evaluateForm = ref({
satisfactionLevel: 3, // 3: 满意, 2: 一般, 1: 不满意
commentReason: "",
@ -333,6 +351,14 @@ const onPreview = (url, itemValue) => {
font-size: 14px;
color: #969799;
}
.empty-text-overdue {
color: #ee0a24;
}
}
.overdue-text {
color: #ee0a24;
}
.detail-materials-tab {

21
zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/views/enforcement/nos/components/NosDetailTaskTab.vue

@ -35,11 +35,11 @@
<div class="section">
<div class="section-title">检查对象</div>
<div class="detail-row">
<span class="detail-label">执法单位</span>
<span class="detail-label">{{ detail.taskTypeId != 5 ? '执法单位' : '巡查单位' }}</span>
<span class="detail-value">{{ detail.enforcementUnit }}</span>
</div>
<div class="detail-row">
<span class="detail-label">执法人员</span>
<span class="detail-label">{{ detail.taskTypeId != 5 ? '执法人员' : '参与人员' }}</span>
<div class="detail-value">
<p v-for="(person, index) in detail.enforcementPerson" :key="index" class="detail-text">
{{ person }}
@ -49,11 +49,13 @@
</div>
<div class="section">
<div class="section-title">执法信息</div>
<div class="section-title">{{ detail.taskTypeId != 5 ? '执法信息' : '巡查信息' }}</div>
<div class="detail-row">
<span class="detail-label">企业名称</span>
<div class="detail-value">
<p v-if="detail.enterpriseName" class="detail-text">{{ detail.enterpriseName }}</p>
<p v-if="detail.enterpriseName" class="detail-text">
{{ detail.enterpriseName }}
</p>
<p v-if="detail.enterpriseNumber" class="detail-text">({{ detail.enterpriseNumber }})</p>
</div>
</div>
@ -61,8 +63,8 @@
<span class="detail-label">类  别</span>
<span class="detail-value">{{ detail.category }}</span>
</div>
<div class="detail-row">
<span class="detail-label">执法事项</span>
<div class="detail-row" v-if="detail.taskTypeId == 1 || detail.taskTypeId == 5">
<span class="detail-label">{{ detail.taskTypeId == 1 ? '执法事项' : '巡查事项' }}</span>
<span class="detail-value">{{ detail.enforcementMatter }}</span>
</div>
<div v-if="requirementLabel" class="detail-row">
@ -100,14 +102,14 @@
const CATEGORY_REQUIREMENT_LABEL_MAP = {
行政检查: '检查要求',
材料备案: '备案文件',
材料验证: '验证文件',
材料验证: '验证文件'
};
const props = defineProps({
detail: {
type: Object,
required: true,
},
required: true
}
});
const emit = defineEmits(['download-notice']);
@ -204,6 +206,7 @@ const onDownloadNotice = (url) => {
justify-content: space-between;
gap: 8px;
margin-bottom: 8px;
&:last-child {
margin-bottom: 0;
}

534
zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/views/enforcement/nos/nosAdd.vue

@ -32,7 +32,8 @@
@open-basis-picker="handleOpenBasisPicker"
@add-basis="handleAddBasis"
@remove-basis="handleRemoveBasis"
@add-person="handleAddPerson" />
@add-person="handleAddPerson"
/>
<!-- 底部按钮 -->
<div class="bottom-buttons">
@ -53,49 +54,51 @@
@confirm-task-source="handleTaskSourceConfirm"
@select-person="handleSelectPerson"
@select-basis="handleSelectBasis"
@select-time="handleSelectTime" />
@select-time="handleSelectTime"
/>
</div>
</template>
<script setup name="EnforcementRegister">
import { ref, reactive, computed, onMounted, onActivated, onDeactivated } from "vue"
import { useRouter, useRoute } from "vue-router"
import { showConfirmDialog, showSuccessToast, showToast } from "vant"
import EnterpriseInfoSection from "@/components/enforcement/nos/EnterpriseInfoSection.vue"
import EnforcementInfoSection from "@/components/enforcement/nos/EnforcementInfoSection.vue"
import RegisterPopups from "@/components/enforcement/nos/RegisterPopups.vue"
import AttachmentTaskSource from "@/components/enforcement/nos/AttachmentTaskSource.vue"
import { nosAddApi, nosTaskSourceListApi } from "@/api/nos/enfDemo"
import { toFullFileUrl, toRelativeFilePath } from "@/util/fileUrl"
const router = useRouter()
const route = useRoute()
import { ref, reactive, computed, onMounted, onActivated, onDeactivated } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { showConfirmDialog, showSuccessToast, showToast } from 'vant';
import EnterpriseInfoSection from '@/components/enforcement/nos/EnterpriseInfoSection.vue';
import EnforcementInfoSection from '@/components/enforcement/nos/EnforcementInfoSection.vue';
import RegisterPopups from '@/components/enforcement/nos/RegisterPopups.vue';
import AttachmentTaskSource from '@/components/enforcement/nos/AttachmentTaskSource.vue';
import { nosAddApi, nosTaskSourceListApi } from '@/api/nos/enfDemo';
import { toFullFileUrl, toRelativeFilePath } from '@/util/fileUrl';
const router = useRouter();
const route = useRoute();
// ========== 状态定义 ==========
// 补录模式(必填为true)
const isSignMode = ref(true)
const isSignMode = ref(true);
/** 创建空的企业信息对象 */
const createDefaultEnterpriseData = () => ({
enterpriseName: "",
usciCode: "",
enterpriseId: ""
})
enterpriseName: '',
usciCode: '',
enterpriseId: ''
});
// 企业数据
const enterpriseData = ref(createDefaultEnterpriseData())
const enterpriseData = ref(createDefaultEnterpriseData());
// 表单数据(字段名与 NosLawEnforcementTaskSaveBO 一致)
const formData = reactive({
lawEnforcementAgency: '',
lawEnforcementAgency: $globalStore.useCommon.bureauUnitName,
taskTypeId: null,
taskSourceId: "",
lawEnforcementMatters: "",
checkItemList: [""],
legalBasis: [""],
deadline: "",
taskSourceId: '',
lawEnforcementMatters: '',
checkItemList: [''],
legalBasis: [''],
deadline: '',
proclamation: []
})
});
// 执法人员
const lawEnforcer = ref([
@ -105,9 +108,9 @@ const lawEnforcer = ref([
lawEnforcerId: $globalStore.useCommon.userId,
lawEnforcerIdCard: null
}
])
]);
const additionalLawEnforcers = ref([])
const additionalLawEnforcers = ref([]);
// 弹窗显示状态
const showPopups = reactive({
@ -118,124 +121,135 @@ const showPopups = reactive({
person: false,
basis: false,
time: false
})
});
// 当前编辑索引(用于人员和执法依据)
const currentEditIndex = ref(-1)
const currentEditIndex = ref(-1);
// 选项数据(仅三种类别)
const categoryOptions = [
{ text: "行政检查", value: 1 },
{ text: "材料备案", value: 2 },
{ text: "材料验证", value: 3 }
]
{ text: '行政检查', value: 1 },
{ text: '材料备案', value: 2 },
{ text: '材料验证', value: 3 },
{ text: '巡查', value: 5 }
];
// 从列表页带入 tab 时锁定类别
const categoryDisabled = ref(false)
const categoryDisabled = ref(false);
// 切换 tab / 类别时强制刷新执法信息区块(keep-alive 场景)
const enforcementSectionKey = computed(() => `${route.query.tab || ""}_${formData.taskTypeId}`)
const enforcementSectionKey = computed(() => `${route.query.tab || ''}_${formData.taskTypeId}`);
const taskTypeName = computed(() => categoryOptions.find((item) => item.value === formData.taskTypeId)?.text || "")
const taskTypeName = computed(() => categoryOptions.find((item) => item.value === formData.taskTypeId)?.text || '');
const DRAFT_STORAGE_PREFIX = "nos_add_draft_"
const lastActiveTab = ref("")
const DRAFT_STORAGE_PREFIX = 'nos_add_draft_';
const lastActiveTab = ref('');
/** 从路由 query 中读取 tab 参数(兼容数组形式) */
const getRouteTabValue = () => {
const rawTab = route.query.tab
return Array.isArray(rawTab) ? rawTab[0] : rawTab
}
const rawTab = route.query.tab;
return Array.isArray(rawTab) ? rawTab[0] : rawTab;
};
/** 将路由 tab 解析为任务类别 ID(taskTypeId) */
const getTabTaskTypeId = () => {
const tabValue = getRouteTabValue()
if (tabValue === undefined || tabValue === null || tabValue === "") return null
const parsedValue = Number(tabValue)
return Number.isFinite(parsedValue) ? parsedValue : null
}
const tabValue = getRouteTabValue();
if (tabValue === undefined || tabValue === null || tabValue === '') return null;
const parsedValue = Number(tabValue);
return Number.isFinite(parsedValue) ? parsedValue : null;
};
const getPageTabKey = () => getRouteTabValue() || "default"
/** 获取当前页签标识,用于草稿隔离存储 */
const getPageTabKey = () => getRouteTabValue() || 'default';
const getDraftStorageKey = (tab = getPageTabKey()) => `${DRAFT_STORAGE_PREFIX}${tab}`
/** 生成当前 Tab 对应的 sessionStorage 草稿键名 */
const getDraftStorageKey = (tab = getPageTabKey()) => `${DRAFT_STORAGE_PREFIX}${tab}`;
/** 创建表单默认值(含当前用户所属执法单位) */
const createDefaultFormData = () => ({
lawEnforcementAgency: $globalStore.useCommon.bureauUnitName,
taskTypeId: null,
taskSourceId: "",
lawEnforcementMatters: "",
checkItemList: [""],
legalBasis: [""],
deadline: "",
taskSourceId: '',
lawEnforcementMatters: '',
checkItemList: [''],
legalBasis: [''],
deadline: '',
proclamation: []
})
});
/** 默认任务截止时间:次日,格式 YYYY-MM-DD */
const getDefaultEnforcementTime = () => {
const tomorrow = new Date()
tomorrow.setDate(tomorrow.getDate() + 1)
return `${tomorrow.getFullYear()}-${String(tomorrow.getMonth() + 1).padStart(2, "0")}-${String(tomorrow.getDate()).padStart(2, "0")}`
}
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
return `${tomorrow.getFullYear()}-${String(tomorrow.getMonth() + 1).padStart(2, '0')}-${String(tomorrow.getDate()).padStart(2, '0')}`;
};
/** uploader 展示用(幂等,可多次调用) */
const serializeProclamation = (proclamation = []) =>
proclamation.map((file) => ({
url: toFullFileUrl(file?.url || file?.filePath || ""),
status: file?.status || "done",
name: file?.name || file?.fileName || "",
url: toFullFileUrl(file?.url || file?.filePath || ''),
status: file?.status || 'done',
name: file?.name || file?.fileName || '',
isImage: file?.isImage
}))
}));
/** 草稿持久化用相对路径,避免 sessionStorage 中重复叠加 /api */
const persistProclamationForDraft = (proclamation = []) =>
proclamation.map((file) => ({
url: toRelativeFilePath(file?.url || file?.filePath || ""),
status: file?.status || "done",
name: file?.name || file?.fileName || "",
url: toRelativeFilePath(file?.url || file?.filePath || ''),
status: file?.status || 'done',
name: file?.name || file?.fileName || '',
isImage: file?.isImage
}))
}));
/** 将草稿/历史字段名统一映射为 formData 结构 */
const normalizeFormData = (data = {}) => {
const categoryNameToId = Object.fromEntries(categoryOptions.map((item) => [item.text, item.value]))
const checkItemList = data.checkItemList ?? (data.materialRequirements || []).map((item) => (typeof item === "string" ? item : item?.name || ""))
const categoryNameToId = Object.fromEntries(categoryOptions.map((item) => [item.text, item.value]));
const checkItemList = data.checkItemList ?? (data.materialRequirements || []).map((item) => (typeof item === 'string' ? item : item?.name || ''));
return {
lawEnforcementAgency: data.lawEnforcementAgency ?? data.enforcementUnit ?? "",
lawEnforcementAgency: data.lawEnforcementAgency ?? '',
taskTypeId: data.taskTypeId ?? categoryNameToId[data.category] ?? null,
taskSourceId: data.taskSourceId ?? data.taskSource ?? "",
lawEnforcementMatters: data.lawEnforcementMatters ?? data.enforcementMatter ?? "",
checkItemList: checkItemList.length ? checkItemList : [""],
legalBasis: [...(data.legalBasis || data.enforcementBases || [""])],
deadline: data.deadline ?? data.enforcementTime ?? "",
taskSourceId: data.taskSourceId ?? data.taskSource ?? '',
lawEnforcementMatters: data.lawEnforcementMatters ?? data.enforcementMatter ?? '',
checkItemList: checkItemList.length ? checkItemList : [''],
legalBasis: [...(data.legalBasis || data.enforcementBases || [''])],
deadline: data.deadline ?? data.enforcementTime ?? '',
proclamation: data.proclamation ?? data.fileList ?? []
}
}
};
};
/** 将标准化后的数据写入响应式 formData */
const applyFormData = (data) => {
const defaults = createDefaultFormData()
const normalized = normalizeFormData(data)
const defaults = createDefaultFormData();
const normalized = normalizeFormData(data);
Object.assign(formData, defaults, normalized, {
checkItemList: [...normalized.checkItemList],
legalBasis: [...normalized.legalBasis],
proclamation: serializeProclamation(normalized.proclamation)
})
}
});
};
/** 重置表单、企业及执法人员等全部页面状态 */
const resetFormState = () => {
applyFormData(createDefaultFormData())
formData.deadline = getDefaultEnforcementTime()
enterpriseData.value = createDefaultEnterpriseData()
additionalLawEnforcers.value = []
categoryDisabled.value = false
}
applyFormData(createDefaultFormData());
formData.deadline = getDefaultEnforcementTime();
enterpriseData.value = createDefaultEnterpriseData();
additionalLawEnforcers.value = [];
categoryDisabled.value = false;
};
/** 根据列表页带入的 tab 锁定任务类别并禁止修改 */
const applyTabCategoryFromRoute = () => {
const taskTypeId = getTabTaskTypeId()
const taskTypeId = getTabTaskTypeId();
if (taskTypeId !== null) {
formData.taskTypeId = taskTypeId
categoryDisabled.value = true
formData.taskTypeId = taskTypeId;
categoryDisabled.value = true;
}
}
};
/** 将当前填写内容持久化到 sessionStorage 草稿 */
const saveDraftToStorage = (tab = getPageTabKey()) => {
const draft = {
formData: {
@ -249,109 +263,119 @@ const saveDraftToStorage = (tab = getPageTabKey()) => {
additionalLawEnforcers: JSON.parse(JSON.stringify(additionalLawEnforcers.value)),
categoryDisabled: categoryDisabled.value,
isSignMode: isSignMode.value
}
sessionStorage.setItem(getDraftStorageKey(tab), JSON.stringify(draft))
}
};
sessionStorage.setItem(getDraftStorageKey(tab), JSON.stringify(draft));
};
/** 从 sessionStorage 读取指定 Tab 的草稿 */
const loadDraftFromStorage = (tab = getPageTabKey()) => {
try {
const raw = sessionStorage.getItem(getDraftStorageKey(tab))
return raw ? JSON.parse(raw) : null
const raw = sessionStorage.getItem(getDraftStorageKey(tab));
return raw ? JSON.parse(raw) : null;
} catch (e) {
console.error("读取新增页草稿失败", e)
return null
console.error('读取新增页草稿失败', e);
return null;
}
}
};
/** 清除指定 Tab 的本地草稿 */
const clearDraftFromStorage = (tab = getPageTabKey()) => {
sessionStorage.removeItem(getDraftStorageKey(tab))
}
sessionStorage.removeItem(getDraftStorageKey(tab));
};
/** 将草稿对象还原到页面各响应式状态 */
const restoreDraft = (draft) => {
applyFormData(draft.formData)
const draftEnterprise = draft.enterpriseData || {}
applyFormData(draft.formData);
const draftEnterprise = draft.enterpriseData || {};
enterpriseData.value = {
enterpriseName: draftEnterprise.enterpriseName || "",
usciCode: draftEnterprise.usciCode || draftEnterprise.enterpriseNumber || "",
enterpriseId: draftEnterprise.enterpriseId || ""
}
lawEnforcer.value = draft.lawEnforcer || lawEnforcer.value
additionalLawEnforcers.value = draft.additionalLawEnforcers || draft.additionalPersons || []
categoryDisabled.value = !!draft.categoryDisabled
isSignMode.value = !!draft.isSignMode
}
enterpriseName: draftEnterprise.enterpriseName || '',
usciCode: draftEnterprise.usciCode || draftEnterprise.enterpriseNumber || '',
enterpriseId: draftEnterprise.enterpriseId || ''
};
lawEnforcer.value = draft.lawEnforcer || lawEnforcer.value;
additionalLawEnforcers.value = draft.additionalLawEnforcers || draft.additionalPersons || [];
categoryDisabled.value = !!draft.categoryDisabled;
isSignMode.value = !!draft.isSignMode;
};
/** 非补录模式下,从扫码缓存恢复企业信息 */
const initEnterpriseFromCache = () => {
if (isSignMode.value) return
const cached = sessionStorage.getItem("enterpriseScanData")
if (!cached) return
if (isSignMode.value) return;
const cached = sessionStorage.getItem('enterpriseScanData');
if (!cached) return;
try {
const parsed = JSON.parse(cached)
const parsed = JSON.parse(cached);
enterpriseData.value = {
enterpriseName: parsed.enterpriseName || "",
usciCode: parsed.usciCode || parsed.enterpriseNumber || "",
enterpriseId: parsed.enterpriseId || ""
}
enterpriseName: parsed.enterpriseName || '',
usciCode: parsed.usciCode || parsed.enterpriseNumber || '',
enterpriseId: parsed.enterpriseId || ''
};
} catch (e) {
console.error("解析企业缓存数据失败", e)
console.error('解析企业缓存数据失败', e);
}
}
};
/**
* 页面进入时的初始化逻辑(keep-alive 场景)
* - Tab 切换时先保存旧 Tab 草稿再重置
* - 优先恢复当前 Tab 草稿,否则应用路由类别并设置默认截止时间
*/
const handlePageEnter = () => {
const tab = getPageTabKey()
const tab = getPageTabKey();
if (lastActiveTab.value && lastActiveTab.value !== tab) {
saveDraftToStorage(lastActiveTab.value)
resetFormState()
saveDraftToStorage(lastActiveTab.value);
resetFormState();
}
lastActiveTab.value = tab
lastActiveTab.value = tab;
const draft = loadDraftFromStorage(tab)
const draft = loadDraftFromStorage(tab);
if (draft) {
restoreDraft(draft)
return
restoreDraft(draft);
return;
}
applyTabCategoryFromRoute()
applyTabCategoryFromRoute();
if (!formData.deadline) {
formData.deadline = getDefaultEnforcementTime()
formData.deadline = getDefaultEnforcementTime();
}
}
};
const taskSourceOptions = ref([])
const taskSourceOptions = ref([]);
/** 拉取任务来源下拉选项 */
const fetchTaskSourceList = () => {
nosTaskSourceListApi(
{},
(res) => {
if (res.code === 200) {
const list = res.rows ?? res.data ?? []
const list = res.rows ?? res.data ?? [];
taskSourceOptions.value = list.map((item) => ({
text: item.sourceName,
value: item.id
}))
}));
}
},
(err) => {
console.error("获取任务来源列表失败", err)
console.error('获取任务来源列表失败', err);
}
)
}
);
};
// ========== 事件处理函数 ==========
// 关闭弹窗(保持 reactive 对象的响应式)
/** 关闭指定类型的弹窗 */
const handleClosePopup = (type) => {
showPopups[type] = false
}
showPopups[type] = false;
};
// 打开人员选择器
/** 打开执法人员选择弹窗,index 为额外人员列表中的编辑下标 */
const handleOpenPersonPicker = (index) => {
currentEditIndex.value = index
showPopups.person = true
}
currentEditIndex.value = index;
showPopups.person = true;
};
// 选择人员
/** 确认选择执法人员:新增或替换 additionalLawEnforcers 中对应项 */
const handleSelectPerson = (person) => {
if (currentEditIndex.value === -1) {
additionalLawEnforcers.value.push({
@ -359,105 +383,105 @@ const handleSelectPerson = (person) => {
lawEnforcerId: person.lawEnforcerId,
lawEnforcerPhone: person.lawEnforcerPhone,
lawEnforcerIdCard: person.lawEnforcerIdCard
})
});
} else {
additionalLawEnforcers.value[currentEditIndex.value] = {
lawEnforcerName: person.lawEnforcerName,
lawEnforcerId: person.lawEnforcerId,
lawEnforcerPhone: person.lawEnforcerPhone,
lawEnforcerIdCard: person.lawEnforcerIdCard
}
};
}
showPopups.person = false
}
showPopups.person = false;
};
// 删除额外人员
/** 删除指定下标的额外执法人员 */
const handleRemovePerson = (index) => {
additionalLawEnforcers.value.splice(index, 1)
}
additionalLawEnforcers.value.splice(index, 1);
};
// 添加额外人员
/** 在额外执法人员列表末尾追加空行 */
const handleAddPerson = () => {
additionalLawEnforcers.value.push({})
}
additionalLawEnforcers.value.push({});
};
// 打开执法依据选择器
/** 打开执法依据选择弹窗,index 为 legalBasis 中的编辑下标 */
const handleOpenBasisPicker = (index) => {
currentEditIndex.value = index
showPopups.basis = true
}
currentEditIndex.value = index;
showPopups.basis = true;
};
// 添加执法依据
/** 在执法依据列表末尾追加空项 */
const handleAddBasis = () => {
formData.legalBasis.push("")
}
formData.legalBasis.push('');
};
// 删除执法依据
/** 删除指定下标的执法依据(至少保留一项) */
const handleRemoveBasis = (index) => {
if (formData.legalBasis.length > 1) {
formData.legalBasis.splice(index, 1)
formData.legalBasis.splice(index, 1);
}
}
};
// 选择执法依据
/** 将选中的执法依据写入 legalBasis 对应下标 */
const handleSelectBasis = (basis) => {
const index = currentEditIndex.value
const index = currentEditIndex.value;
if (index >= 0 && index < formData.legalBasis.length) {
formData.legalBasis[index] = basis.name
formData.legalBasis[index] = basis.name;
}
showPopups.basis = false
}
showPopups.basis = false;
};
// 选择截止时间(格式:YYYY-MM-DD)
/** 确认选择任务截止时间(格式:YYYY-MM-DD) */
const handleSelectTime = (time) => {
formData.deadline = time
showPopups.time = false
}
formData.deadline = time;
showPopups.time = false;
};
// 选择企业
/** 确认选择检查对象企业并回填 enterpriseData */
const handleSelectEnterprise = (enterprise) => {
enterpriseData.value = {
enterpriseName: enterprise.enterpriseName,
usciCode: enterprise.usciCode,
enterpriseId: enterprise.enterpriseId
}
showPopups.enterprise = false
}
};
showPopups.enterprise = false;
};
// 类别选择确认
/** 确认选择任务类别(taskTypeId) */
const handleCategoryConfirm = ({ selectedOptions }) => {
formData.taskTypeId = selectedOptions[0]?.value ?? null
showPopups.category = false
}
formData.taskTypeId = selectedOptions[0]?.value ?? null;
showPopups.category = false;
};
// 任务来源选择确认
/** 确认选择任务来源(taskSourceId) */
const handleTaskSourceConfirm = ({ selectedOptions }) => {
formData.taskSourceId = selectedOptions[0]?.value || ""
showPopups.taskSource = false
}
formData.taskSourceId = selectedOptions[0]?.value || '';
showPopups.taskSource = false;
};
// 返回上一页(保留草稿,在 onDeactivated 中持久化)
/** 返回上一页(草稿在 onDeactivated 中自动保存) */
const goBack = () => {
router.back()
}
router.back();
};
// 重置表单并清除当前 Tab 草稿
/** 二次确认后重置表单并清除当前 Tab 草稿 */
const handleReset = () => {
showConfirmDialog({
title: "确认重置",
message: "重置后将清空已填写内容和附件,是否继续?",
width: "80%"
title: '确认重置',
message: '重置后将清空已填写内容和附件,是否继续?',
width: '80%'
})
.then(() => {
clearDraftFromStorage()
resetFormState()
applyTabCategoryFromRoute()
showSuccessToast("已重置")
clearDraftFromStorage();
resetFormState();
applyTabCategoryFromRoute();
showSuccessToast('已重置');
})
.catch(() => {})
}
.catch(() => {});
};
// 组装执法人员列表
/** 合并主执法人员与额外人员,过滤空项后返回提交结构 */
const buildLawEnforcerList = () => {
const list = [...lawEnforcer.value, ...additionalLawEnforcers.value]
.filter((item) => item?.lawEnforcerName)
@ -466,20 +490,20 @@ const buildLawEnforcerList = () => {
lawEnforcerName: item.lawEnforcerName,
lawEnforcerPhone: item.lawEnforcerPhone,
lawEnforcerIdCard: item.lawEnforcerIdCard
}))
return list
}
}));
return list;
};
// 将上传附件转换为 proclamation
/** 将 uploader 附件列表转换为接口所需的 proclamation 结构 */
const buildProclamation = () =>
(formData.proclamation || [])
.filter((file) => file && file.url)
.map((file) => ({
fileName: file.name || file.file?.name || "",
fileName: file.name || file.file?.name || '',
filePath: toRelativeFilePath(file.url)
}))
}));
// 构建提交参数(NosLawEnforcementTaskSaveBO)
/** 组装新增任务接口入参(NosLawEnforcementTaskSaveBO) */
const buildSubmitPayload = () => ({
checkItemList: formData.checkItemList.filter((item) => item?.trim()),
deadline: formData.deadline,
@ -493,81 +517,85 @@ const buildSubmitPayload = () => ({
taskSourceId: formData.taskSourceId,
taskTypeId: formData.taskTypeId,
usciCode: enterpriseData.value.usciCode
})
});
// 取消
/** 二次确认后清空草稿、重置表单并返回列表 */
const handleCancel = () => {
showConfirmDialog({
title: "确认取消",
message: "取消后将清空已填写内容,是否继续?",
width: "80%"
title: '确认取消',
message: '取消后将清空已填写内容,是否继续?',
width: '80%'
})
.then(() => {
clearDraftFromStorage()
resetFormState()
applyTabCategoryFromRoute()
router.back()
clearDraftFromStorage();
resetFormState();
applyTabCategoryFromRoute();
router.back();
})
.catch(() => {})
}
.catch(() => {});
};
// 提交表单
/** 校验附件上传状态后,二次确认并调用新增任务接口 */
const onSubmit = () => {
// 有未上传完的附件则拦截
const uploadingFile = (formData.proclamation || []).find((img) => img && img.status === "uploading")
const uploadingFile = (formData.proclamation || []).find((img) => img && img.status === 'uploading');
if (uploadingFile) {
showToast("附件上传中,请稍后")
return
showToast('附件上传中,请稍后');
return;
}
showConfirmDialog({
title: "确认提交",
message: "确认提交吗?提交后将无法修改。",
width: "80%"
title: '确认提交',
message: '确认提交吗?提交后将无法修改。',
width: '80%'
})
.then(() => {
const payload = buildSubmitPayload()
console.log("提交数据:", payload)
const payload = buildSubmitPayload();
console.log('提交数据:', payload);
nosAddApi(
payload,
(res) => {
console.log(res)
clearDraftFromStorage()
resetFormState()
applyTabCategoryFromRoute()
showSuccessToast("提交成功")
clearDraftFromStorage();
resetFormState();
applyTabCategoryFromRoute();
showSuccessToast('提交成功');
setTimeout(() => {
router.back()
}, 500)
router.back();
}, 500);
},
(err) => {
console.log(err)
console.log(err);
showToast(err?.message || '提交失败');
}
)
);
})
.catch(() => {
// 用户取消
})
}
});
};
// ========== 生命周期(keep-alive:onMounted 仅一次,onActivated 每次进入) ==========
/** 首次挂载:恢复扫码企业缓存并加载任务来源 */
onMounted(() => {
initEnterpriseFromCache()
fetchTaskSourceList()
})
initEnterpriseFromCache();
fetchTaskSourceList();
});
/** 每次从缓存激活:恢复或初始化当前 Tab 表单 */
onActivated(() => {
handlePageEnter()
})
handlePageEnter();
});
/** 离开页面时自动保存当前 Tab 草稿 */
onDeactivated(() => {
saveDraftToStorage(lastActiveTab.value || getPageTabKey())
})
saveDraftToStorage(lastActiveTab.value || getPageTabKey());
});
// 路由 push 到本页时触发(与项目 keep-alive 约定一致)
/** 路由 push 到本页时触发(与项目 keep-alive 约定一致) */
$globalConfigure(() => {
handlePageEnter()
})
handlePageEnter();
});
</script>
<style lang="less" scoped>

15
zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/views/enforcement/nos/nosDetail.vue

@ -1,6 +1,6 @@
<template>
<div class="nos-detail-page app_content">
<van-nav-bar fixed placeholder title="执法监督码">
<!-- <van-nav-bar fixed placeholder title="执法监督码">
<template #left>
<van-icon name="arrow-left" class="nav-icon" @click.stop="onBack" />
<van-icon name="cross" class="nav-icon nav-icon--close" @click.stop="onClose" />
@ -8,7 +8,7 @@
<template #right>
<van-icon name="ellipsis" class="nav-icon" />
</template>
</van-nav-bar>
</van-nav-bar> -->
<van-form @submit="onSubmit" scroll-to-error class="detail-form">
<van-tabs
@ -32,6 +32,7 @@
v-model:task-item-list="taskItemList"
v-model:inspect-result="inspectResult"
:task-status="taskDetail.taskStatus"
:task-deadline="taskDetail.deadline"
:evaluate-data="evaluateData"
/>
</div>
@ -59,10 +60,11 @@ const router = useRouter();
const route = useRoute();
const TAB_TASK_TITLE_MAP = {
inspection: '行政检查任务',
filing: '材料备案任务',
verify: '材料验证任务',
pending: '待核实案件',
1: '行政检查任务',
2: '材料备案任务',
3: '材料验证任务',
4: '待核实案件',
5: '巡查任务',
};
const activeTab = ref('task');
@ -97,6 +99,7 @@ const applyDetailData = (data) => {
enforcementBases: data.legalBasis || [],
startTime: data.createTime || '',
deadline: data.deadline || '',
taskTypeId: data.taskTypeId || '',
};
taskItemList.value = (data.taskItemList || []).map(item => ({
...item,

44
zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/views/enforcement/nos/nosEvaluateList.vue

@ -14,24 +14,24 @@
<div class="evaluate-card" v-for="item in list" :key="item.id" @click="toDetail(item)">
<!-- 执法时间 -->
<div class="card-time">
执法时间:{{ item.enforcementTime }}
办结时间:{{ item.endTime }}
</div>
<!-- 标题 -->
<div class="card-title">{{ item.title || item.checkItemText || '执法检查' }}</div>
<div class="card-title">{{ item.title || '执法检查' }}</div>
<!-- 内容 -->
<div class="card-content">
<div class="info-row">
<span class="label">执法单位</span>
<span class="value">{{ item.lawEnforcement || item.bureauDeptName }}</span>
<span class="value">{{ item.lawEnforcementAgency || '--' }}</span>
</div>
<div class="info-row">
<span class="label">执法人员:</span>
<span class="label">执法人员</span>
<div>
<div v-for="(enforcer, index) in item" :key="index"
<div v-for="(enforcer, index) in item.lawEnforcer" :key="index"
class="enforcer-item">
{{ enforcer }}
{{ enforcer.lawEnforcerName }} {{ enforcer.lawEnforcerIdCard || enforcer.lawEnforcerPhone }}
</div>
</div>
</div>
@ -43,9 +43,9 @@
<!-- 底部状态 -->
<div class="card-footer">
<span class="status">状态:<span :class="getStatusClass(item.hasEvaluate)">{{
getStatusText(item.hasEvaluate) }}</span></span>
<span class="evaluate-time">评价时间:{{ item.evaluateTime }}</span>
<span class="status">状态:<span :class="getStatusClass(item.commentStatus)">{{
getStatusText(item.commentStatus) }}</span></span>
<span class="evaluate-time">评价时间:{{ item.commentTime }}</span>
</div>
</div>
</van-list>
@ -55,11 +55,11 @@
</template>
<script setup name="enforcementEvaluateList">
import { ref, onMounted } from 'vue';
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { showToast } from 'vant';
import 'vant/es/toast/style';
import { queryEvaluateList } from '@/api/enforcement/index';
import { nosTaskHasCommentPageApi } from '@/api/nos/enfDemo';
const router = useRouter();
@ -96,12 +96,11 @@ const fetchList = () => {
const params = {
pageNum: pageNum.value,
pageSize: pageSize.value,
hasEvaluate: 1,
};
queryEvaluateList(params, (res) => {
nosTaskHasCommentPageApi(params, (res) => {
if (res.code === 200) {
const rows = res.rows || res.data?.rows || res.data?.list || res.data || [];
const total = res.total ?? res.data?.total ?? 0;
const rows = res.rows || [];
const total = res.total ?? 0;
if (refreshing.value) {
list.value = Array.isArray(rows) ? rows : [];
@ -148,8 +147,8 @@ const onRefresh = () => {
// ========== 跳转详情页面 ==========
const toDetail = (item) => {
router.push({
path: '/enforcement/enforcementEvaluateDetail',
query: { id: item.id, hasEvaluate: 1, from: 'evaluateList' }
path: '/enforcement/nos/detail',
query: { id: item.id, tab: item.taskStatus }
});
};
@ -158,10 +157,6 @@ const onClickLeft = () => {
router.back();
};
// ========== 组件挂载时加载数据 ==========
onMounted(() => {
fetchList();
});
</script>
<style lang="less" scoped>
@ -218,12 +213,13 @@ onMounted(() => {
font-size: 16px;
font-weight: bold;
color: #333;
margin-bottom: 15px;
line-height: 1.4;
border-top: 1px dashed #e5e5e5;
padding-top: 15px;
}
.card-content {
border-top: 1px dashed #e5e5e5;
// border-top: 1px dashed #e5e5e5;
padding-top: 15px;
}
@ -238,7 +234,7 @@ onMounted(() => {
}
.enforcer-item {
padding: 4px 0px;
padding: 0px 0px 6px 0px;
}
.value {

14
zdxt-web-client/zdxt-efcode-nos-enforcement-app/src/views/enforcement/nos/nosList.vue

@ -1,10 +1,5 @@
<template>
<div class="nos-list-page app_content">
<van-nav-bar fixed placeholder title="执法监督码">
<!-- <template #left>
<van-icon name="arrow-left" class="nav-icon" @click.stop="onBack" />
</template> -->
</van-nav-bar>
<div class="nos-list-body">
<van-tabs
@ -31,12 +26,17 @@ import FooterBar from '@/components/FooterBar.vue';
import NosListPanel from './components/NosListPanel.vue';
const router = useRouter();
// 判断是否是执法人员
const isLaw = $globalStore.useCommon.hasLaw
const TAB_LIST = [
const TAB_LIST = isLaw ? [
{ key: 1, title: '行政检查' },
{ key: 2, title: '材料备案' },
{ key: 3, title: '材料验证' },
{ key: 4, title: '待核实案件' },
{ key: 5, title: '巡查' },
{ key: 4, title: '待核实' },
] : [
{ key: 5, title: '巡查' },
];
const activeTab = ref(1);

2
zdxt-web-client/zdxt-efcode-nos-enforcement-app/vite-env/.env.enforcement-dev

@ -9,7 +9,7 @@ VITE_NOS_BASE_URL = '/nosapi'
# 仅 dev server 代理目标(生产由 nginx 转发,不读这两项)
VITE_PROXY_TARGET = 'http://139.186.148.21:8080'
VITE_NOS_PROXY_TARGET = 'http://192.168.1.13:28080'
VITE_NOS_PROXY_TARGET = 'http://192.168.1.12:28080'
# 附件/图片等静态资源前缀(与现场执法同源)
VITE_FILE_URL = '/api'

11
zdxt-web-client/zdxt-efcode-nos-enterprise-app/src/views/enterprise/nos/components/NosDetailTaskTab.vue

@ -35,11 +35,11 @@
<div class="section">
<div class="section-title">检查对象</div>
<div class="detail-row">
<span class="detail-label">执法单位</span>
<span class="detail-label">{{ detail.taskTypeId != 5 ? '执法单位' : '巡查单位' }}</span>
<span class="detail-value">{{ detail.enforcementUnit }}</span>
</div>
<div class="detail-row">
<span class="detail-label">执法人员</span>
<span class="detail-label">{{ detail.taskTypeId != 5 ? '执法人员' : '参与人员' }}</span>
<div class="detail-value">
<p v-for="(person, index) in detail.enforcementPerson" :key="index" class="detail-text">
{{ person }}
@ -49,7 +49,7 @@
</div>
<div class="section">
<div class="section-title">执法信息</div>
<div class="section-title">{{ detail.taskTypeId != 5 ? '执法信息' : '巡查信息' }}</div>
<div class="detail-row">
<span class="detail-label">企业名称</span>
<div class="detail-value">
@ -61,8 +61,8 @@
<span class="detail-label">类  别</span>
<span class="detail-value">{{ detail.category }}</span>
</div>
<div class="detail-row">
<span class="detail-label">执法事项</span>
<div class="detail-row" v-if="detail.taskTypeId == 1 || detail.taskTypeId == 5">
<span class="detail-label">{{ detail.taskTypeId == 1 ? '执法事项' : '巡查事项' }}</span>
<span class="detail-value">{{ detail.enforcementMatter }}</span>
</div>
<div v-if="requirementLabel" class="detail-row">
@ -101,6 +101,7 @@ const CATEGORY_REQUIREMENT_LABEL_MAP = {
行政检查: '检查要求',
材料备案: '备案文件',
材料验证: '验证文件',
巡查: '巡查要求',
};
const props = defineProps({

10
zdxt-web-client/zdxt-efcode-nos-enterprise-app/src/views/enterprise/nos/nosDetail.vue

@ -61,10 +61,11 @@ const router = useRouter();
const route = useRoute();
const TAB_TASK_TITLE_MAP = {
inspection: '行政检查任务',
filing: '材料备案任务',
verify: '材料验证任务',
pending: '待核实案件',
1: '行政检查任务',
2: '材料备案任务',
3: '材料验证任务',
4: '待核实案件',
5: '巡查任务',
};
const activeTab = ref('task');
@ -95,6 +96,7 @@ const applyDetailData = (data) => {
enforcementBases: data.legalBasis || [],
startTime: data.createTime || '',
deadline: data.deadline || '',
taskTypeId: data.taskTypeId || '',
};
taskItemList.value = (data.taskItemList || []).map((item) => {
const { fileList, ...rest } = item

1
zdxt-web-client/zdxt-efcode-nos-enterprise-app/src/views/enterprise/nos/nosList.vue

@ -36,6 +36,7 @@ const TAB_LIST = [
{ key: 1, title: '行政检查' },
{ key: 2, title: '材料备案' },
{ key: 3, title: '材料验证' },
{ key: 5, title: '巡查' },
];
const activeTab = ref(1);

2
zdxt-web-client/zdxt-efcode-nos-enterprise-app/vite-env/.env.enterprise-dev

@ -10,4 +10,4 @@ VITE_APP_ENV = 'dev'
VITE_NOS_BASE_URL = '/nosapi'
# 仅 dev server 代理目标(生产由 nginx 转发,不读这两项)
VITE_PROXY_TARGET = 'http://139.186.148.21:8080'
VITE_NOS_PROXY_TARGET = 'http://192.168.1.13:28080'
VITE_NOS_PROXY_TARGET = 'http://192.168.1.12:28080'

Loading…
Cancel
Save