linqilong před 3 týdny
rodič
revize
0e9ae49dac

+ 15 - 2
src/api/inspect.js

@@ -40,7 +40,7 @@ export function getObjectList(groupId) {
     return request({
         url: '/tac/insp/year/batch/obj/getObjList',
         method: 'POST',
-        data: {"limit":-1,"pageNum":1,"pageSize":200,"groupId":groupId,"inspType":"","mainType":false,"ojbNm":"","persId":userid,"prjType":"","type":""}
+        data: { "limit": -1, "pageNum": 1, "pageSize": 200, "groupId": groupId, "inspType": "", "mainType": false, "ojbNm": "", "persId": userid, "prjType": "", "type": "" }
     })
 }
 
@@ -53,6 +53,19 @@ export function getTacQuestionList(rgstrId) {
     return request({
         url: '/tac/pblm/info/page',
         method: 'POST',
-        data: {"listType":"","pageNum":1,"pageSize":200,"realPageNum":0,"rgstrId":rgstrId}
+        data: { "listType": "", "pageNum": 1, "pageSize": 200, "realPageNum": 0, "rgstrId": rgstrId }
     })
 }
+
+
+
+/**
+ * 稽察 - 获取问题详情
+ * @param {问题ID} id
+ */
+export function getTacQuestionById(id) {
+    return request({
+        url: `/tac/pblm/info/${id}`,
+        method: 'GET',
+    })
+}

+ 2 - 2
src/api/login.js

@@ -50,7 +50,7 @@ export function loginWithMessage(phone, code, message) {
  */
 export function logout() {
     return request({
-        url: '/bis/insp/logout',
-        method: 'POST',
+        url: '/bis/insp/logOut',
+        method: 'GET',
     })
 }

+ 17 - 3
src/api/questions.js

@@ -4,7 +4,7 @@ import { useUserStore } from "@/stores/user";
 const userStore = useUserStore()
 
 /**
- * 获取问题清单
+ * 稽查 - 获取问题清单
  */
 export function getTacQuestionList() {
     const userid = userStore.userId
@@ -14,11 +14,25 @@ export function getTacQuestionList() {
         data: {"count":"false",
             "orderBy":"INTM",
             "pageNum":1,
-            "pageSize":20,
+            "pageSize":200,
             "pblmQlttvCd":0,
             "persId":userid,
             "sn":0,
             "year":0
         }
     })
-}
+}
+
+
+/**
+ * 稽查 - 获取违法事项列表
+ * {"class1Name":"","pageNum":2,"pageSize":20,"pblmType":"1"}
+ */
+export function getIllegalActList(data) {
+    data.realPageNum = 0
+    return request({
+        url: '/tac/obj/pblmstb/page',
+        method: 'POST',
+        data: data
+    })
+}

+ 58 - 0
src/components/GwSelect02.vue

@@ -0,0 +1,58 @@
+<template>
+    <div class="filter-item">
+            <van-field   v-model="name"    is-link  readonly  :label="props.label"    :placeholder="`选择${props.label}`"      @click="showPicker = true"  />
+        <van-popup v-model:show="showPicker" round position="bottom">
+            <van-picker :columns="props.columns" @cancel="showPicker = false" @confirm="onConfirm" />
+        </van-popup>
+    </div>
+</template>
+<script setup>
+import { ref, defineProps, defineEmits, watch } from "vue";
+
+const emits = defineEmits(['update:value']);
+
+const props = defineProps({
+    label: {
+        type: String,
+        default: '',
+    },
+    columns: {
+        type: Array,
+        default: () => [],
+    },
+    value: {
+        type: null,
+    }
+})
+
+const name = ref('')
+const showPicker = ref(false);
+const onConfirm = ({ selectedOptions }) => {
+    showPicker.value = false;
+    emits('update:value', selectedOptions[0].value);
+};
+
+function getTypeName(code) {
+    if (!code) return '';
+    return props.columns.find(item => item.value === code)?.text;
+}
+
+watch(() => props.value, (newValue) => {
+    name.value = getTypeName(newValue);
+}, { immediate: true })
+</script>
+<style lang="scss" scoped>
+@import '@/assets/styles/filter.scss';
+
+.content-wrapper {
+    padding-top: 8px;
+    height: 100%;
+    overflow: auto;
+
+    .ducha-group-wrapper {
+        height: calc(100% - 35px);
+        overflow: auto;
+    }
+
+}
+</style>

+ 11 - 3
src/components/card01.vue

@@ -1,18 +1,22 @@
 <template>
     <div class="card-01-wrapper">
         <div class="card-01-header">
-            <van-icon style="margin-right: 5px;" :name="props.icon" color="#1989fa" size="1.3rem" />
+            <van-icon v-if="props.icon && isString(props.icon)" style="margin-right: 5px;" :name="props.icon" color="#1989fa" size="1.3rem" />
+            <van-tag  v-else-if="props.icon && props.icon.type === 'tag'"  style="margin-right: 5px;height: 1rem;white-space: nowrap;" :color="props.icon.color" text-color="#fff">{{ props.icon.value }}</van-tag>
             <span>{{ props.title }}</span>
         </div>
-        <div v-if="props.description" class="card-01-description" v-html="props.description"></div>
+        <div v-if="props.description" class="card-01-description">
+            <van-text-ellipsis v-if="props.ellipsisDescription" :content="props.description" />
+            <span v-else v-html="props.description"></span>
+        </div>
     </div>
 </template>
 <script setup>
 import { defineProps } from 'vue';
+import { isString } from '@/utils/validate';
 
 const props = defineProps({
     icon: {
-        type: String,
         default: ''
     },
     title: {
@@ -22,6 +26,10 @@ const props = defineProps({
     description: {
         type: String,
         default: ''
+    },
+    ellipsisDescription: {
+        type: Boolean,
+        default: false
     }
 })
 

+ 1 - 1
src/main.js

@@ -17,6 +17,6 @@ app.use(router);
 app.use(VueCookies);
 app.use(Vant);
 // Lazyload 指令需要单独进行注册
-app.use(Vant.Lazyload);
+// app.use(Vant.Lazyload);
 
 app.mount('#app');

+ 1 - 0
src/stores/user.js

@@ -95,6 +95,7 @@ export const useUserStore = defineStore('user', () => {
   function LogOut() {
     return new Promise((resolve, reject) => {
       logout().then(() => {
+        localStorage.clear()
         token.value = ""
         removeToken();
         resolve();

+ 34 - 0
src/utils/convert.js

@@ -0,0 +1,34 @@
+/**
+ * 严重程度转换
+ * @param {严重程度} pblmPasi 
+ * @returns 
+ */
+export function pblmPasiConvert(pblmPasi) {
+    if (pblmPasi === '1') {
+        return { type: 'tag', value: "严重", color: '#E6A23C' };
+    } else if (pblmPasi === '2') {
+        return { type: 'tag', value: "较重", color: '#F56C6C' };
+    } else if (pblmPasi === '3') {
+        return { type: 'tag', value: "特别严重", color: '#640b0b' };
+    }
+    return { type: 'tag', value: "一般", color: '#409EFF' };
+}
+
+export function listTypeConvert(listType) {
+    switch (listType) {
+        case '1':
+            return '前期与设计专业';
+        case '2':
+            return '建设管理专业';
+        case '3':
+            return '计划下达与执行专业';
+        case '4':
+            return '资金使用与管理专业';
+        case '5':
+            return '工程质量专业';
+        case '6':
+            return '工程安全专业';
+    }
+
+    return '';
+}

+ 9 - 5
src/utils/request.js

@@ -1,4 +1,5 @@
 import axios from "axios";
+import router from '@/router';
 import { getToken } from "@/utils/auth";
 import { getErrorMessage } from "@/utils/errorCode";
 import { validURL } from "@/utils/validate";
@@ -69,12 +70,15 @@ service.interceptors.response.use(
         const code = res.data.code || 200;
         // 查询错误信息
         const msg = res.data.msg || getErrorMessage(code);
-        if (code === 401) {
+
+        if (code == 10005 || code == 10006 || code == 9999) {
+            const userStore = useUserStore()
+            userStore.LogOut().then(() => {
+                router.replace({ path: '/login' })
+                location.reload() // 为了重新实例化vue-router对象 避免bug
+            })
+        } else if (code === 401) {
             return Promise.reject("无效的会话,或者会话已过期,请重新登录。");
-        } else if (code === 500) {
-            return Promise.reject(msg)
-        } else if (code === 601) {
-            return Promise.reject('error')
         } else if (code !== 0 && code !== 200) {
             return Promise.reject(msg);
         } else {

+ 10 - 11
src/views/Inspect/Object/Problem/index.vue

@@ -1,13 +1,13 @@
 <template>
-  <div style="height: 100%;">
-    <card01 :title="object.ojbNm + ''" icon="label" :description="renderData(object, objectConfig.description2)" />
+  <div style="height: 100%;padding: 10px 0;">
+    <card01 style="margin-top: 0;" :title="object.ojbNm + ''" icon="label" :description="renderData(object, objectConfig.description2)" />
     <van-collapse class="pblm-list-wrapper" v-model="activeNames">
       <van-collapse-item v-for="item in list" :key="item.id" :name="item.id">
         <template #title>
           <div>{{ item.name }}&nbsp;&nbsp;<van-tag v-if="item.pblmList && item.pblmList.length > 0" round type="primary">{{item.pblmList.length}}</van-tag></div>
         </template>
         <card01 v-for="pblm in item.pblmList" :key="pblm.pblmId" :title="pblm.pblmNm" icon="question"
-        @click="jumpPage(`/problem/${item.pblmId}`)" />
+        @click="jumpPage(`/problem/${pblm.id}`)" />
       </van-collapse-item>
     </van-collapse>
   </div>
@@ -50,19 +50,18 @@ onMounted(() => {
 })
 </script>
 <style lang="scss" scoped>
-.inspect-object-wrapper {
-  width: 100%;
-  height: 100%;
-  overflow: auto;
-}
+
 </style>
 <style lang="scss">
 .pblm-list-wrapper{
   padding: 0 10px;
+  height: calc(100% - 120px);
+  overflow: auto;
+  
   .van-collapse-item__content{
-  padding: 0;
-  background-color: transparent;
-}
+    padding: 0;
+    background-color: transparent;
+  }
 }
 
 </style>

+ 133 - 1
src/views/Problem/detail/index.vue

@@ -1,5 +1,137 @@
 <template>
-    
+    <div class="pblm-detail-wrapper">
+        <van-form @submit="onSubmit">
+            <card01 style="margin-top: 0;" :title="pblm.name + ''" icon="label"
+                :description="`工程地址:${pblm.location}<br/>问题类型:${listTypeConvert(pblm.listType)}`" />
+            <div class="pblm-detail-label">
+                <span>违规事项</span>
+                <van-button size="mini" type="primary" @click="changeTacObjPblmstb()">选择违规事项</van-button>
+            </div>
+            <van-cell-group inset>
+                <van-field v-model="tacObjPblmstb.pblmTypeDesc" label="问题类型" placeholder="问题类型" label-align="top"
+                    rows="1" autosize type="textarea" readonly />
+                <van-field v-model="tacObjPblmstb.pblmsDesc" label="违规事项" placeholder="违规事项" label-align="top" rows="2"
+                    autosize type="textarea" readonly />
+                <van-field v-model="tacObjPblmstb.relativeLaw" label="法规条款" placeholder="法规条款" label-align="top"
+                    rows="2" autosize type="textarea" readonly />
+                <van-field v-model="tacObjPblmstb.lawContent" label="法规内容" placeholder="法规内容" label-align="top" rows="2"
+                    autosize type="textarea" readonly />
+                <van-field v-model="pblm.note" label="备注" placeholder="备注" label-align="top" rows="2" autosize
+                    type="textarea" />
+            </van-cell-group>
+            <div class="pblm-detail-label">问题描述</div>
+            <van-cell-group inset>
+                <van-field v-model="pblm.pblmNm" label="发现问题" placeholder="发现问题" label-align="top" rows="2" autosize
+                    type="textarea" />
+                <van-field v-model="pblm.pblmDesc" label="问题阐述" placeholder="问题阐述" label-align="top" rows="2" autosize
+                    type="textarea" />
+                <van-field v-model="pblm.pblmReason" label="主要原因分析" placeholder="主要原因分析" label-align="top" rows="2"
+                    autosize type="textarea" />
+                <van-field v-model="pblm.pblmSggtn" label="整改意见及建议" placeholder="整改意见及建议" label-align="top" rows="2"
+                    autosize type="textarea" />
+                <van-field v-model="pblm.spclRvwOptn" label="稽查组长复核意见" placeholder="稽查组长复核意见" label-align="top" rows="2"
+                    autosize type="textarea" />
+                <GwSelect02 label="问题严重性" :columns="cateObjList" v-model:value="pblm.pblmPasi"></GwSelect02>
+                <van-field name="radio" label="是否典型问题">
+                    <template #input>
+                        <van-radio-group v-model="pblm.ifCasePblm" direction="horizontal">
+                            <van-radio name="1">是</van-radio>
+                            <van-radio name="0">否</van-radio>
+                        </van-radio-group>
+                    </template>
+                </van-field>
+                <van-field name="stepper" label="排序序号">
+                    <template #input>
+                        <van-stepper v-model="pblm.sn" />
+                    </template>
+                </van-field>
+                <van-field name="uploader" label="文件上传">
+                    <template #input>
+                        <van-uploader v-model="gwComFileList" />
+                    </template>
+                </van-field>
+            </van-cell-group>
+            <div class="pblm-detail-label">责任主体</div>
+            <van-cell-group inset>
+                <div class="pblmSubjectList" v-for="item in pblm.pblmSubjectList" :key="item.id">
+                    <GwSelect02 label="单位性质" :columns="objSubjectColumns" v-model:value="item.subId"></GwSelect02>
+                    <van-field v-model="item.unitNm" label="单位名称" placeholder="单位名称" />
+                </div>
+                <van-button round plain hairline block>
+                    <van-icon style="margin-right: 5px;" name="plus" color="#000" size="1rem" />
+                    添加单位
+                </van-button>
+            </van-cell-group>
+            <div style="margin: 16px;">
+                <van-button round block type="primary" native-type="submit">
+                    提交
+                </van-button>
+            </div>
+        </van-form>
+
+        <van-popup v-model:show="tacObjPblmstbShow" position="left" :style="{ width: '80%', height: '100%' }">
+
+        </van-popup>
+    </div>
 </template>
 <script setup>
+import { onMounted, ref, computed, watch } from "vue";
+import { useRoute } from "vue-router";
+import card01 from '@/components/card01.vue';
+import GwSelect02 from '@/components/GwSelect02.vue';
+import { getTacQuestionById } from "@/api/inspect";
+import { listTypeConvert } from "@/utils/convert"
+
+const route = useRoute();
+const pblm = ref({});
+const tacObjPblmstb = computed(() => pblm.value.tacObjPblmstb || {});
+const cateObjList = computed(() => tacObjPblmstb.value?.cateObjList?.map(i => { return { text: i.desc, value: i.cate } }) || []);
+const objSubjectList = computed(() => pblm.value.tacObjPblmstb.objSubjectList || []);
+const objSubjectColumns = computed(() => objSubjectList.value?.map(i => { return { text: i.subName, value: i.id } }) || []);
+const gwComFileList = computed(() => pblm.value.gwComFileList?.map(i => process.env.VUE_APP_BASE_API + i.filePath) || []);
+
+const tacObjPblmstbShow = ref(false);
+
+function getQuestionData() {
+    getTacQuestionById(route.params.id).then(res => {
+        pblm.value = res.data
+    })
+}
+
+/**
+ * 选择违规事项
+ */
+function changeTacObjPblmstb() {
+    console.log('changeTacObjPblmstb')
+}
+
+
+function onSubmit() {
+    console.log(e)
+}
+
+onMounted(() => {
+    getQuestionData();
+})
 </script>
+<style lang="scss" scoped>
+.pblm-detail-wrapper {
+    height: 100%;
+    padding: 10px 0;
+    overflow: auto;
+
+    .pblm-detail-label {
+        padding: 10px 16px;
+        color: #606266;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+    }
+
+}
+</style>
+<style lang="scss">
+.van-cell-group--inset {
+    margin: 0 10px;
+}
+</style>

+ 7 - 11
src/views/Problem/listquestions.vue

@@ -2,9 +2,9 @@
     <div style="height: 100%;">
         <van-pull-refresh class="inspect-object-question-wrapper" v-model="loading" @refresh="getData()">
             <!-- 使用 v-for 指令遍历 list 数组 -->
-            <card01 v-for="item in list" :key="item.id" :title="item.pblmNm + ''" icon="notes"
-                    :description="renderData(item, item.pblmDesc)"
-                    @click="jumpPage(`/problem/${item.id}`)" />
+            <card01 v-for="item in list" :key="item.id" :title="item.pblmNm + ''" :icon="pblmPasiConvert(item.pblmPasi)"
+                :description="renderData(item, item.pblmDesc)" :ellipsisDescription="true"
+                @click="jumpPage(`/problem/${item.id}`)" />
         </van-pull-refresh>
     </div>
 </template>
@@ -15,16 +15,12 @@ import { jumpPage } from "@/utils/page";
 import { getTacQuestionList } from "@/api/questions";
 import { onMounted, ref } from "vue";
 import card01 from '@/components/card01.vue';
+import { pblmPasiConvert } from "@/utils/convert";
 
 // 使用 ref 定义响应式变量 list 和 loading
 const list = ref([]);
 const loading = ref(false);
 
-// 定义 objectConfig 变量
-const objectConfig = ref({
-    description: '这里是默认描述信息' // 你可以根据实际情况修改默认描述内容
-});
-
 // 定义 getData 函数,用于获取数据
 function getData() {
     // 设置 loading 为 true,表示正在加载数据
@@ -47,8 +43,8 @@ onMounted(() => {
 
 <style lang="scss" scoped>
 .inspect-object-wrapper {
-  width: 100%;
-  height: 100%;
-  overflow: auto;
+    width: 100%;
+    height: 100%;
+    overflow: auto;
 }
 </style>

+ 8 - 0
vue.config.js

@@ -40,4 +40,12 @@ module.exports = defineConfig({
             }
         }
     },
+    chainWebpack: config => {
+        config.plugin('define').tap(definitions => {
+            Object.assign(definitions[0], {
+                __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: 'false'
+            });
+            return definitions;
+        });
+    }
 })