riku
2023-05-09 0959c095ad9715633d6ccdf10eb3b3d52f0bede1
2023.5.9前所有小改动版本记录
已修改21个文件
已删除3个文件
已添加12个文件
已重命名2个文件
1723 ■■■■ 文件已修改
src/App.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/fysp/problemApi.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/fysp/sceneApi.js 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/fysp/taskApi.js 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/fysp/userApi.js 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/fytz/noticeApi.js 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/fytz/userApi.js 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/index.js 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/problemApi.js 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/taskApi.js 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/userApi.js 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components.d.ts 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/ProblemCard.vue 75 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/SearchBar.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/core/Content.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/core/MenuItems.vue 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/core/SiderMenu.vue 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/composables/formConfirm.js 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/enum/scene.js 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/enum/user.js 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/index.js 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/baseinfo/fysp/scene/CompSceneBaseInfo.vue 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/baseinfo/fysp/scene/CompSceneConstructionInfo.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/baseinfo/fysp/scene/CompSceneDeviceInfo.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/baseinfo/fysp/scene/SceneEdit.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/baseinfo/fysp/scene/SceneInfo.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/baseinfo/fysp/user/CompUserInfo.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/check/ProCheck.vue 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/common/CompTransfer.vue 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/common/UserMatch.vue 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/fysp/night-construction/NightConstruction.vue 补丁 | 查看 | 原始文档 | blame | 历史
src/views/fytz/user/UserEdit.vue 181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/fytz/user/UserInfo.vue 295 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/fytz/user/components/CompUserInfo.vue 305 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/fytz/user/components/CompUserInfoAddDrawer.vue 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/notice/CompNoticeAdd.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/notice/CompNoticeAddDrawer.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/notice/NoticeManage.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/App.vue
@@ -4,7 +4,6 @@
      <el-aside class="el-aside"
        ><SiderMenu
          :collapse="isCollapsed"
          @collapsed-sider="collapsedSider"
          @nav-page="navPage"
        ></SiderMenu
      ></el-aside>
src/api/fysp/problemApi.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,22 @@
import { $fysp } from '../index';
const id = 'IF3DgsgKxSWvTM3M';
const name = 'pcheck';
export default {
  /**
   * èŽ·å–å­ä»»åŠ¡ç»Ÿè®¡ä¿¡æ¯
   * @param {Number} action 0:问题通过;1:问题不通过;2:整改通过;3整改不通过
   */
  checkProblem({ pId, action, remark = '', userId = id, userName = name }) {
    return $fysp
      .post('problemlist/check', {
        pId: pId,
        action: action,
        remark: remark,
        userId: userId,
        userName: userName,
      })
      .then((res) => res.data);
  },
};
src/api/fysp/sceneApi.js
ÎļþÃû´Ó src/api/sceneApi.js ÐÞ¸Ä
@@ -1,4 +1,4 @@
import { $fysp } from './index';
import { $fysp } from '../index';
export default {
  /**
@@ -7,7 +7,7 @@
   */
  searchScene(area, page = 1, perPage = 20) {
    const params = `page=${page}&per_page=${perPage}`;
    return $fysp.post(`scense/find?${params}`, area);
    return $fysp.post(`scense/find?${params}`, area).then((res) => res.data);
  },
  /**
@@ -16,11 +16,13 @@
   * @returns åœºæ™¯è¯¦æƒ…
   */
  getSceneDetail(sId) {
    return $fysp.get(`scense/detail`, {
      params: {
        sceneId: sId,
      },
    });
    return $fysp
      .get(`scense/detail`, {
        params: {
          sceneId: sId,
        },
      })
      .then((res) => res.data);
  },
  /**
@@ -33,21 +35,27 @@
      subScene: subScene ? JSON.stringify(subScene) : null,
      sceneDevice: sceneDevice ? sceneDevice : null,
    };
    return $fysp.post(`scense/detail/update?${params}`, rb);
    return $fysp
      .post(`scense/detail/update?${params}`, rb)
      .then((res) => res.data);
  },
  /**
   * æ›´æ–°åœºæ™¯é¢å¤–信息
   */
  updateSubScene(typeId, subScene) {
    return this.updateSceneDetail(typeId, { subScene: subScene });
    return this.updateSceneDetail(typeId, { subScene: subScene }).then(
      (res) => res.data
    );
  },
  /**
   * æ›´æ–°åœºæ™¯è®¾å¤‡ä¿¡æ¯
   */
  updateSceneDevice(typeId, sceneDevice) {
    return this.updateSceneDetail(typeId, { sceneDevice: sceneDevice });
    return this.updateSceneDetail(typeId, { sceneDevice: sceneDevice }).then(
      (res) => res.data
    );
  },
  /**
@@ -55,7 +63,7 @@
   * @param {Object} scene
   */
  createScene(scene) {
    return $fysp.put('scense', scene);
    return $fysp.put('scense', scene).then((res) => res.data);
  },
  /**
@@ -63,6 +71,6 @@
   * @param {Object} scene
   */
  updateScene(scene) {
    return $fysp.post('scense', scene);
    return $fysp.post('scense', scene).then((res) => res.data);
  },
};
src/api/fysp/taskApi.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,37 @@
import { $fysp } from '../index';
export default {
  /**
   * èŽ·å–é¡¶å±‚ä»»åŠ¡
   */
  getTopTask() {
    return $fysp.get('task/alltask/0').then((res) => res.data);
  },
  /**
   * èŽ·å–å­ä»»åŠ¡ç»Ÿè®¡ä¿¡æ¯
   */
  getSubtaskSummary({ topTaskId = undefined, sceneTypeId = undefined }) {
    return $fysp
      .get('subtask/summary', {
        params: {
          topTaskId: topTaskId,
          sceneTypeId: sceneTypeId,
        },
      })
      .then((res) => res.data);
  },
  /**
   * èŽ·å–å­ä»»åŠ¡é—®é¢˜è¯¦æƒ…
   */
  getProBySubtask(id) {
    return $fysp
      .get('problemlist/subtask', {
        params: {
          stGuid: id,
        },
      })
      .then((res) => res.data);
  },
};
src/api/fysp/userApi.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,33 @@
import { $fysp } from '../index';
export default {
  /**
   * èŽ·å–ç”¨æˆ·è¯¦æƒ…
   */
  getUserById(id) {
    return $fysp.get(`userinfo/${id}`).then((res) => res.data);
  },
  /**
   * æ›´æ–°ç”¨æˆ·è¯¦æƒ…
   */
  updateUser(user) {
    return $fysp.post(`userinfo`, user).then((res) => res.data);
  },
  /**
   * èŽ·å–åœºæ™¯çš„ç”¨æˆ·è¯¦æƒ…
   */
  getUserByScene(sId) {
    return $fysp
      .get(`userinfo/scene/get?sceneId=${sId}`)
      .then((res) => res.data);
  },
  /**
   * è‡ªåŠ¨åˆ›å»ºè´¦æˆ·
   */
  autoCreateAccount(sId) {
    return $fysp.post(`userinfo/create?sceneId=${sId}`).then((res) => res.data);
  },
};
src/api/fytz/noticeApi.js
ÎļþÃû´Ó src/api/noticeApi.js ÐÞ¸Ä
@@ -1,6 +1,6 @@
import { $fytz } from './index';
import { $fytz } from '../index';
const id = 'IF3DgsgKxSWvTM3M';
const id = 'BbEfZ4izeR4TEZ2N';
const name = 'pcheck';
export default {
@@ -9,23 +9,27 @@
   */
  getNoticeHistory({ type, subtype = null, page = 1, perPage = 20 }) {
    const params = `userId=${id}&page=${page}&per_page=${perPage}`;
    return $fytz.post(`notifications/history?${params}`, {
      ecNoticetype: type,
      ecNoticesubtype: subtype,
    });
    return $fytz
      .post(`notifications/history?${params}`, {
        ecNoticetype: type,
        ecNoticesubtype: subtype,
      })
      .then((res) => res.data);
  },
  /**
   * èŽ·å–ç”¨æˆ·æœªè¯»é€šçŸ¥
   */
  getNotification() {
    return $fytz.get('notifications', {
      params: {
        userId: id,
        page: 1,
        per_page: 30,
      },
    });
    return $fytz
      .get('notifications', {
        params: {
          userId: id,
          page: 1,
          per_page: 30,
        },
      })
      .then((res) => res.data);
  },
  /**
@@ -60,8 +64,10 @@
      }
   */
  releaseNotice(notice) {
    notice.authorId = id
    notice.authorName = name
    return $fytz.post(`notifications/${id}/release2`, notice);
    notice.authorId = id;
    notice.authorName = name;
    return $fytz
      .post(`notifications/${id}/release2`, notice)
      .then((res) => res.data);
  },
};
src/api/fytz/userApi.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
import { $fytz } from '../index';
export default {
  /**
   * æœç´¢ç”¨æˆ·
   * @param {String} userId
   * @param {Number} page
   * @param {Number} per_page
   * @param {Object} data
   * @returns
   */
  fetchUser(userId, page = 1, per_page = 20, data) {
    const params = `page=${page}&per_page=${per_page}`;
    return $fytz.post(`userInfo/searchUser/${userId}?${params}`, data);
  },
  /**
   * èŽ·å–ç”¨æˆ·åŸºæœ¬ä¿¡æ¯
   * @param {String} userId
   * @returns
   */
  fetchUserBaseInfo(userId) {
    return $fytz
      .get(`userInfo/baseInfo?userId=${userId}`)
      .then((res) => res.data);
  },
  /**
   * æ›´æ–°ç”¨æˆ·è´¦æˆ·ä¿¡æ¯
   * @param {*} data
   * @returns
   */
  updateUserInfo(data) {
    return $fytz.post('userInfo', data).then((res) => res.data);
  },
  /**
   * æ–°å¢žç”¨æˆ·
   * @param {*} data
   * @returns
   */
  createUser(data) {
    return $fytz.put('userInfo', data).then((res) => res.data);
  }
};
src/api/index.js
@@ -4,8 +4,8 @@
const ip1 = 'http://47.100.191.150:9005/';
// const ip1 = 'http://192.168.1.12:8080/';
// const ip2 = 'http://47.100.191.150:9006/';
// const ip2 = 'http://192.168.1.14:8080/';
const ip2 = 'https://fyami.com.cn/'
// const ip2 = 'http://192.168.1.6:8080/';
const ip2 = 'https://fyami.com.cn/';
//飞羽监管
const $fysp = axios.create({
@@ -30,6 +30,9 @@
      // åœ¨å‘送请求之前做些什么
      console.log('==>请求开始');
      console.log(`${config.baseURL}${config.url}`);
      if (config.data) {
        console.log('==>请求数据', config.data);
      }
      return config;
    },
    function (error) {
@@ -52,7 +55,15 @@
      console.log(response);
      console.log('==>请求结束');
      if (response.status == 200) {
        return response.data
        if (response.data.success != undefined && response.data.success != null) {
          if (response.data.success == true) {
            return response;
          } else {
            return Promise.reject(response.data.message);
          }
        } else {
          return response;
        }
      } else {
        return Promise.reject(response);
      }
src/api/problemApi.js
ÎļþÒÑɾ³ý
src/api/taskApi.js
ÎļþÒÑɾ³ý
src/api/userApi.js
ÎļþÒÑɾ³ý
src/components.d.ts
@@ -45,16 +45,22 @@
    ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
    ElSelect: typeof import('element-plus/es')['ElSelect']
    ElSpace: typeof import('element-plus/es')['ElSpace']
    ElStep: typeof import('element-plus/es')['ElStep']
    ElSteps: typeof import('element-plus/es')['ElSteps']
    ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
    ElSwitch: typeof import('element-plus/es')['ElSwitch']
    ElTable: typeof import('element-plus/es')['ElTable']
    ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
    ElTabPane: typeof import('element-plus/es')['ElTabPane']
    ElTabs: typeof import('element-plus/es')['ElTabs']
    ElTag: typeof import('element-plus/es')['ElTag']
    ElTooltip: typeof import('element-plus/es')['ElTooltip']
    ElTransfer: typeof import('element-plus/es')['ElTransfer']
    ElTree: typeof import('element-plus/es')['ElTree']
    Footer: typeof import('./components/core/Footer.vue')['default']
    FormCol: typeof import('./components/layout/FormCol.vue')['default']
    Header: typeof import('./components/core/Header.vue')['default']
    MenuItems: typeof import('./components/core/MenuItems.vue')['default']
    ProblemCard: typeof import('./components/ProblemCard.vue')['default']
    RouterLink: typeof import('vue-router')['RouterLink']
    RouterView: typeof import('vue-router')['RouterView']
src/components/ProblemCard.vue
@@ -1,20 +1,24 @@
<template>
  <el-card class="layout" shadow="hover">
    <!-- <el-steps :active="active" finish-status="success" style="">
      <el-step title="Step 1" style=""/>
      <el-step title="Step 2" />
      <el-step title="Step 3" />
    </el-steps> -->
    <el-descriptions :column="3" size="small" >
    <el-steps :active="active" finish-status="success" style="" simple>
      <el-step v-for="(s, i) in getSteps" :key="i" :title="s" />
    </el-steps>
    <el-descriptions :column="3" size="small">
      <template #title>
        <span class="d-index">{{ index + 1 }}</span>
        <span class="d-title">{{ title }}</span>
      </template>
      <template #extra>
        <!-- <span class="d-extra">{{ status }}</span> -->
        <el-tag style="font-size: 16px;line-height: 16px;padding: 14px;" :type="status.type" effect="plain" size="large" round>{{
          status.name
        }}</el-tag>
        <el-tag
          style="font-size: 16px; line-height: 16px; padding: 14px"
          :type="status.type"
          effect="plain"
          size="large"
          round
          >{{ status.name }}</el-tag
        >
      </template>
      <el-descriptions-item
        label-class-name="descriptions-label-1"
@@ -86,8 +90,8 @@
      type: Object,
      default: () => {
        return {
          name: "",
          type: "",
          name: '',
          type: '',
        };
      },
    },
@@ -95,8 +99,8 @@
      type: Array,
      default: () => [
        {
          name: "",
          value: "",
          name: '',
          value: '',
        },
      ],
    },
@@ -104,7 +108,7 @@
      type: Array,
      default: () => [
        {
          title: "",
          title: '',
          path: [],
        },
      ],
@@ -113,23 +117,52 @@
      type: Array,
      default: () => [
        {
          name: "primary",
          color: "primary",
          name: 'primary',
          color: 'primary',
        },
      ],
    },
    // active: {
    //   type: Number,
    //   default: 3,
    // },
  },
  emits: ['buttonClick'],
  data() {
    return {
      active: 1
    }
      active: 3,
      steps: [
        {
          bef: '问题待审核',
          aft: '问题已审核',
        },
        {
          bef: '问题待整改',
          aft: '问题已整改',
        },
        {
          bef: '整改待审核',
          aft: '整改已审核',
        },
      ],
    };
  },
  computed: {
    getSteps() {
      return this.steps.map((v, i) => {
        if (i >= this.active) {
          return v.bef;
        } else {
          return v.aft;
        }
      });
    },
  },
  methods: {
    onButtonClick(i) {
      this.$emit('buttonClick', this.index, i)
    }
  }
      this.$emit('buttonClick', this.index, i);
    },
  },
};
</script>
<style scoped>
src/components/SearchBar.vue
@@ -37,7 +37,7 @@
</template>
<script>
import taskApi from '@/api/taskApi';
import taskApi from '@/api/fysp/taskApi';
import { enumScene_2NA } from "@/enum/scene";
export default {
src/components/core/Content.vue
@@ -1,10 +1,14 @@
<template>
  <router-view v-slot="{ Component, route }">
    <!-- <transition :name="route.meta.transition || 'fade'"> -->
      <keep-alive>
        <component v-if="route.meta.keepAlive" :is="Component" />
      </keep-alive>
      <component v-if="!route.meta.keepAlive" :is="Component" />
    <keep-alive>
      <component
        v-if="route.meta.keepAlive"
        :is="Component"
        :key="route.name"
      />
    </keep-alive>
    <component v-if="!route.meta.keepAlive" :is="Component" :key="route.name" />
    <!-- </transition> -->
  </router-view>
</template>
src/components/core/MenuItems.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,61 @@
<template>
  <template v-for="(item, i) in routes" :key="`${i}`">
    <el-sub-menu v-if="item.children" :index="`${i}`">
      <template #title>
        <el-icon>
          <component :is="item.icon"></component>
        </el-icon>
        <span>{{ item.name }}</span>
      </template>
      <template v-for="(child, i2) in item.children" :key="`${i}-${i2}`">
        <el-menu-item-group v-if="child.group" :title="child.name">
          <el-menu-item
            v-for="(child2, i3) in child.children"
            :key="`${i}-${i2}-${i3}`"
            :index="child2.path"
            @click="navPage(item, child, child2)"
          >
            <el-icon v-if="child2.icon">
              <component :is="child2.icon"></component>
            </el-icon>
            <template #title>{{ child2.name }}</template>
          </el-menu-item>
        </el-menu-item-group>
        <el-menu-item v-else :index="child.path" @click="navPage(item, child)">
          <el-icon v-if="child.icon">
            <component :is="child.icon"></component>
          </el-icon>
          <template #title>{{ child.name }}</template>
        </el-menu-item>
      </template>
    </el-sub-menu>
    <el-menu-item v-else :index="item.path" @click="navPage(item)">
      <el-icon>
        <component :is="item.icon"></component>
      </el-icon>
      <template #title>{{ item.name }}</template>
    </el-menu-item>
  </template>
</template>
<script>
export default {
  name: 'CoreMenuItem',
  props: {
    routes: {
      type: Array,
    },
  },
  emits: ['navPage'],
  methods: {
    navPage(...item) {
      // const titles = item.map((value) => {
      //   return value.name;
      // });
      this.$emit('navPage', ...item);
    },
  },
};
</script>
src/components/core/SiderMenu.vue
@@ -17,95 +17,11 @@
      </el-space>
    </el-row>
    <el-scrollbar :height="menuHeight" v-if="!collapse">
      <template v-for="(item, i) in routes" :key="`${i}`">
        <el-sub-menu v-if="item.children" :index="`${i}`">
          <template #title>
            <el-icon>
              <component :is="item.icon"></component>
            </el-icon>
            <span>{{ item.name }}</span>
          </template>
          <template v-for="(child, i2) in item.children" :key="`${i}-${i2}`">
            <el-menu-item-group v-if="child.group" :title="child.name">
              <el-menu-item
                v-for="(child2, i3) in child.children"
                :key="`${i}-${i2}-${i3}`"
                :index="child2.path"
                @click="navPage(item, child, child2)"
              >
                <el-icon v-if="child2.icon">
                  <component :is="child2.icon"></component>
                </el-icon>
                <template #title>{{ child2.name }}</template>
              </el-menu-item>
            </el-menu-item-group>
            <el-menu-item
              v-else
              :index="child.path"
              @click="navPage(item, child)"
            >
              <el-icon v-if="child.icon">
                <component :is="child.icon"></component>
              </el-icon>
              <template #title>{{ child.name }}</template>
            </el-menu-item>
          </template>
        </el-sub-menu>
        <el-menu-item v-else :index="item.path" @click="navPage(item)">
          <el-icon>
            <component :is="item.icon"></component>
          </el-icon>
          <template #title>{{ item.name }}</template>
        </el-menu-item>
      </template>
      <MenuItems :routes="routes" @navPage="navPage"> </MenuItems>
    </el-scrollbar>
    <template v-else>
      <template v-for="(item, i) in routes" :key="`${i}`">
        <el-sub-menu v-if="item.children" :index="`${i}`">
          <template #title>
            <el-icon>
              <component :is="item.icon"></component>
            </el-icon>
            <span>{{ item.name }}</span>
          </template>
          <template v-for="(child, i2) in item.children" :key="`${i}-${i2}`">
            <el-menu-item-group v-if="child.group" :title="child.name">
              <el-menu-item
                v-for="(child2, i3) in child.children"
                :key="`${i}-${i2}-${i3}`"
                :index="child2.path"
                @click="navPage(item, child, child2)"
              >
                <el-icon v-if="child2.icon">
                  <component :is="child2.icon"></component>
                </el-icon>
                <template #title>{{ child2.name }}</template>
              </el-menu-item>
            </el-menu-item-group>
            <el-menu-item
              v-else
              :index="child.path"
              @click="navPage(item, child)"
            >
              <el-icon v-if="child.icon">
                <component :is="child.icon"></component>
              </el-icon>
              <template #title>{{ child.name }}</template>
            </el-menu-item>
          </template>
        </el-sub-menu>
        <el-menu-item v-else :index="item.path" @click="navPage(item)">
          <el-icon>
            <component :is="item.icon"></component>
          </el-icon>
          <template #title>{{ item.name }}</template>
        </el-menu-item>
      </template>
      <MenuItems :routes="routes" @navPage="navPage"> </MenuItems>
    </template>
    <el-row ref="subTitleRef" class="sub-title" justify="center">
@@ -126,7 +42,6 @@
  emits: ['navPage'],
  data() {
    return {
      isCollapsed: this.collapse,
      menuHeight: '600px',
      title: '生态环境线上监管',
      subTitle: '©上海飞羽环保科技有限公司',
@@ -244,10 +159,14 @@
          icon: 'Search',
          name: '排污抽运',
        },
        {
          path: '/common/userMatch',
          icon: 'Connection',
          name: '账户匹配',
        },
      ],
    };
  },
  watch: {},
  computed: {
    homePage() {
      return this.routes[0].children
@@ -258,10 +177,6 @@
  methods: {
    handleOpen() {},
    handleClose() {},
    collapsedSider() {
      this.isCollapsed = !this.isCollapsed;
      this.$emit('collapsedSider', this.isCollapsed);
    },
    navPage(...item) {
      const titles = item.map((value) => {
        return value.name;
src/composables/formConfirm.js
@@ -4,10 +4,14 @@
import { useMessageBoxTip, useMessageBox } from './messageBox';
export function useFormConfirm({
  defaultForm = undefined,
  submit = {
    do: () => {},
  },
  cancel = {
    do: () => {},
  },
  reset = {
    do: () => {},
  },
}) {
@@ -17,7 +21,7 @@
  if (!cancel.msg) cancel.msg = '是否放弃已编辑的内容?';
  //表单内容
  const formObj = ref({});
  const formObj = ref(defaultForm ? defaultForm : {});
  let formObjClone = useCloned(formObj, { manual: true });
  //表单组件引用
  const formRef = ref(null);
@@ -59,7 +63,7 @@
  );
  // é‡ç½®è¡¨å•
  const reset = function () {
  const _reset = function () {
    edit.value = false;
    isReset = true;
    formObj.value = useCloned(formObjClone.cloned, {
@@ -116,19 +120,24 @@
  };
  // é‡ç½®è¡¨å•
  const onReset = function () {
  const onReset = function (tips) {
    if (edit.value) {
      // å¼¹å‡ºç¡®è®¤æ¡†
      useMessageBox({
        confirmMsg: '是否重置表单内容?',
        confirmTitle: '重置表单',
        onConfirm: () => {
          reset();
          return cancel.do();
        },
      });
      if (tips) {
        // å¼¹å‡ºç¡®è®¤æ¡†
        useMessageBox({
          confirmMsg: '是否重置表单内容?',
          confirmTitle: '重置表单',
          onConfirm: () => {
            _reset();
            return reset.do();
          },
        });
      } else {
        _reset();
        reset.do();
      }
    } else {
      cancel.do();
      reset.do();
    }
  };
src/enum/scene.js
@@ -1,7 +1,7 @@
// åœºæ™¯ç±»åž‹æžšä¸¾
// é£žç¾½çŽ¯å¢ƒç³»ç»Ÿ
function enumScene_1 () {
function enumScene_1() {
  return [
    {
      label: '全部',
@@ -42,9 +42,16 @@
  l.shift();
  return l;
}
function getSceneName_1(value) {
  enumScene_1().find((v) => {
    if (v.value == value) {
      return v;
    }
  });
}
// é£žç¾½ç›‘管系统
function enumScene_2 () {
function enumScene_2() {
  return [
    {
      label: '全部',
@@ -91,7 +98,13 @@
function enumScene_2NA() {
  const l = enumScene_2();
  l.shift();
  return l
  return l;
}
export { enumScene_1, enumScene_1NA, enumScene_2, enumScene_2NA };
export {
  enumScene_1,
  enumScene_1NA,
  getSceneName_1,
  enumScene_2,
  enumScene_2NA,
};
src/enum/user.js
@@ -11,15 +11,15 @@
      value: '0',
    },
    {
      label: '内部用户',
      label: '内部人员',
      value: '1',
    },
    {
      label: '政府用户',
      label: '政府部门',
      value: '2',
    },
    {
      label: '企业用户',
      label: '企业',
      value: '3',
    },
  ];
src/router/index.js
@@ -77,7 +77,7 @@
    component: () => import('@/views/notice/NoticeManage.vue'),
  },
  // é£žç¾½ç›‘管
  /**********************************飞羽监管***********************************************/
  {
    //账户管理
    name: 'fyspUser',
@@ -108,12 +108,28 @@
    meta: { transition: 'slide-left' },
  },
  // é£žç¾½çŽ¯å¢ƒ
  /**********************************飞羽环境***********************************************/
  {
    //账户管理
    name: 'fytzUser',
    path: '/fytz/userInfo',
    component: () => import('@/views/baseinfo/fytz/user/UserInfo.vue'),
    component: () => import('@/views/fytz/user/UserInfo.vue'),
    meta: { keepAlive: true },
  },
  {
    //账户编辑
    name: 'fytzUserEdit',
    path: '/fytz/userEdit/:userId',
    component: () => import('@/views/fytz/user/UserEdit.vue'),
    meta: { transition: 'slide-left' },
  },
  /**********************************通用模块***********************************************/
  {
    //账户匹配
    name: 'userMatch',
    path: '/common/userMatch',
    component: () => import('@/views/common/UserMatch.vue'),
  },
];
src/views/baseinfo/fysp/scene/CompSceneBaseInfo.vue
@@ -72,7 +72,9 @@
    <el-form-item label="联系电话" prop="contactst">
      <el-input type="tel" v-model="formObj.contactst" placeholder="联系电话">
        <template #prepend>
          <el-icon><Iphone /></el-icon>
          <el-icon>
            <Iphone />
          </el-icon>
        </template>
      </el-input>
    </el-form-item>
@@ -83,12 +85,7 @@
      }}</span>
    </el-form-item>
    <el-form-item label="编号" prop="index">
      <el-input-number
        readonly
        v-model="formObj.index"
        :step="1"
        :min="0"
      />
      <el-input-number readonly v-model="formObj.index" :step="1" :min="0" />
    </el-form-item>
    <el-form-item>
@@ -108,7 +105,7 @@
import { defineProps, defineEmits, reactive, ref, watch } from 'vue';
import { enumScene_2NA } from '@/enum/scene';
import { enumLocationNA } from '@/enum/location';
import sceneApi from '@/api/sceneApi';
import sceneApi from '@/api/fysp/sceneApi';
import { useFormConfirm } from '@/composables/formConfirm';
const props = defineProps({
src/views/baseinfo/fysp/scene/CompSceneConstructionInfo.vue
@@ -167,7 +167,7 @@
import { defineProps, defineEmits, reactive, ref, watch } from 'vue';
import { useDateFormat } from '@vueuse/core';
import { enumStatusNA, enumStageNA } from '@/enum/construction';
import sceneApi from '@/api/sceneApi';
import sceneApi from '@/api/fysp/sceneApi';
import { useFormConfirm } from '@/composables/formConfirm';
const props = defineProps({
src/views/baseinfo/fysp/scene/CompSceneDeviceInfo.vue
@@ -77,7 +77,7 @@
import { defineProps, defineEmits, reactive, ref, watch } from 'vue';
import { useFormConfirm } from '@/composables/formConfirm';
import { enumOnlineStatusNA } from '@/enum/onlineStatus';
import sceneApi from '@/api/sceneApi';
import sceneApi from '@/api/fysp/sceneApi';
const props = defineProps({
  //场景基本信息
@@ -134,9 +134,9 @@
  () => props.formInfo,
  (nValue) => {
    if (nValue) {
      formObj.value = nValue;
      formObj.value = nValue;
    }
  },
  }
);
</script>
src/views/baseinfo/fysp/scene/SceneEdit.vue
@@ -40,8 +40,8 @@
</template>
<script>
import sceneApi from '@/api/sceneApi';
import userApi from '@/api/userApi';
import sceneApi from '@/api/fysp/sceneApi';
import userApi from '@/api/fysp/userApi';
// import FormCol from '../../../../components/layout/FormCol.vue';
import CompSceneBaseInfo from './CompSceneBaseInfo.vue';
import CompSceneConstructionInfo from './CompSceneConstructionInfo.vue';
src/views/baseinfo/fysp/scene/SceneInfo.vue
@@ -109,7 +109,7 @@
import { enumScene_2 } from '@/enum/scene';
import { enumLocation } from '@/enum/location';
import { enumOnlineStatus } from '@/enum/onlineStatus';
import sceneApi from '@/api/sceneApi';
import sceneApi from '@/api/fysp/sceneApi';
import { useLoadingStore } from '@/stores/loadingStore';
import { mapStores } from 'pinia';
import { useMessageBoxTip } from '@/composables/messageBox';
src/views/baseinfo/fysp/user/CompUserInfo.vue
@@ -78,7 +78,7 @@
import { defineProps, defineEmits, reactive, ref, watch } from 'vue';
import { enumUserNA } from '@/enum/user';
import { useFormConfirm } from '@/composables/formConfirm';
import userApi from '@/api/userApi';
import userApi from '@/api/fysp/userApi';
const props = defineProps({
  //基本信息
src/views/check/ProCheck.vue
@@ -21,7 +21,11 @@
      </SearchBar>
    </template>
    <template #aside>
      <SideList :items="subtasks" :loading="sideLoading" @item-click="chooseSubtask"></SideList>
      <SideList
        :items="subtasks"
        :loading="sideLoading"
        @item-click="chooseSubtask"
      ></SideList>
    </template>
    <template #main>
      <ToolBar
@@ -30,7 +34,11 @@
        :buttons="buttons"
        :loading="mainLoading"
      ></ToolBar>
      <el-scrollbar v-if="proPicsCard.length > 0" class="el-scrollbar" v-loading="mainLoading">
      <el-scrollbar
        v-if="proPicsCard.length > 0"
        class="el-scrollbar"
        v-loading="mainLoading"
      >
        <ProblemCard
          v-for="(p, i) in proPicsCard"
          :key="i"
@@ -38,14 +46,14 @@
          @button-click="onProButtonClick"
        ></ProblemCard>
      </el-scrollbar>
      <el-empty v-else description="暂无记录" v-loading="mainLoading"/>
      <el-empty v-else description="暂无记录" v-loading="mainLoading" />
    </template>
  </BaseContentLayout>
</template>
<script>
import taskApi from '@/api/taskApi';
import problemApi from '@/api/problemApi';
import taskApi from '@/api/fysp/taskApi';
import problemApi from '@/api/fysp/problemApi';
import ProCheckProxy from './ProCheckProxy';
import { ElMessageBox, ElNotification, ElMessage } from 'element-plus';
@@ -183,10 +191,10 @@
  methods: {
    //查询子任务统计信息
    onSubmit(formSearch) {
      this.sideLoading = true
      this.mainLoading = true
      this.curProList = []
      this.curSubtask = {}
      this.sideLoading = true;
      this.mainLoading = true;
      this.curProList = [];
      this.curSubtask = {};
      taskApi.getSubtaskSummary(formSearch).then((res) => {
        const list = [];
        res.forEach((s) => {
@@ -200,8 +208,8 @@
        });
        this.subtasks = list;
        if (list.length == 0) {
          this.sideLoading = false
          this.mainLoading = false
          this.sideLoading = false;
          this.mainLoading = false;
        }
      });
    },
@@ -221,15 +229,18 @@
    },
    //点击左侧菜单任务事件
    chooseSubtask(s) {
      this.sideLoading = false
      this.mainLoading = true
      this.curSubtask = s;
      this.sideLoading = false;
      this.mainLoading = true;
      // const controller = new AbortController();
      taskApi.getProBySubtask(s.data.stGuid).then((res) => {
        this.curProList = res;
      }).finally(() => {
        this.mainLoading = false
      });
      taskApi
        .getProBySubtask(s.data.stGuid)
        .then((res) => {
          this.curProList = res;
          this.curSubtask = s;
        })
        .finally(() => {
          this.mainLoading = false;
        });
    },
    // é—®é¢˜å¡ç‰‡å†…部按钮点击事件
@@ -270,7 +281,7 @@
                title: '审核成功',
                message: `该问题已${doneMsg}`,
                type: 'success',
                offset: 170
                offset: 170,
              });
            })
            .catch(() => {
src/views/common/CompTransfer.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,114 @@
<template>
  <el-row justify="center" class="t-title">{{ title }}</el-row>
  <el-row justify="center">
    <el-transfer
      class="t-transfer"
      v-model="rightData"
      filterable
      :titles="titles"
      :button-texts="buttonTexts"
      :format="{
        noChecked: '${total}',
        hasChecked: '${checked}/${total}',
      }"
      :data="leftData"
      target-order="push"
      @change="handleChange"
    >
      <template #default="{ option }">
        <div class="t-transfer-item">
          <span>{{ option.label }}</span>
          <div>
            <el-icon><ArrowUp /></el-icon>
            <el-icon><ArrowDown /></el-icon>
          </div>
        </div>
      </template>
      <!-- <template #left-footer>
        <el-button class="transfer-footer" size="small">Operation</el-button>
      </template>
      <template #right-footer>
        <el-button class="transfer-footer" size="small">Operation</el-button>
      </template> -->
    </el-transfer>
  </el-row>
</template>
<script>
export default {
  props: {
    title: {
      type: String,
      default: '标题',
    },
    titleJustify: {
      type: String,
      default: 'start',
    },
    leftValue: {
      type: Array,
    },
    rightValue: {
      type: Array,
    },
  },
  data() {
    return {
      leftData: [],
      rightData: [],
    };
  },
  watch: {
    leftValue(nV) {
      this.leftData = nV;
    },
    rightValue(nV) {
      this.rightData = nV;
    },
  },
  computed: {
    titles() {
      return this.titleJustify == 'left'
        ? ['场景列表', '已选择']
        : ['已选择', '场景列表'];
    },
    buttonTexts() {
      return this.titleJustify == 'left' ? ['移除', '添加'] : ['添加', '移除'];
    },
  },
  methods: {
    handleChange(value, direction, movedKeys) {
      console.log(value, direction, movedKeys);
    },
  },
  created() {
    const data = [];
    for (let i = 1; i <= 15; i++) {
      data.push({
        key: i,
        label: `Option ${i}`,
        disabled: i % 4 === 0,
      });
    }
    this.leftData = data;
  },
};
</script>
<style>
.t-title {
  font-size: 20px;
  margin-bottom: 10px;
}
.t-transfer {
  /* background-color: aliceblue; */
  --el-transfer-panel-width: 300px;
  --el-transfer-panel-body-height: 600px;
}
.t-transfer-item {
  background-color: aliceblue;
  display: flex;
  justify-content: space-between;
}
</style>
src/views/common/UserMatch.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,19 @@
<template>
  <el-row :gutter="0">
    <el-col :span="12"
      ><CompTransfer title="飞羽监管" title-justify="left"></CompTransfer
    ></el-col>
    <el-col :span="12"
      ><CompTransfer title="飞羽环境" title-justify="right"></CompTransfer
    ></el-col>
  </el-row>
</template>
<script>
import CompTransfer from './CompTransfer.vue';
export default {
  components: {
    CompTransfer,
  },
};
</script>
src/views/fysp/night-construction/NightConstruction.vue
src/views/fytz/user/UserEdit.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,181 @@
<template>
  <el-page-header @back="onBack">
    <template #content>
      <span> è´¦æˆ·ä¿¡æ¯ç¼–辑 </span>
    </template>
  </el-page-header>
  <el-divider />
  <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
    <el-tab-pane label="基本信息" name="first">
      <div class="sub-title">用户信息</div>
      <FormCol>
        <CompUserInfo :form-info="formUser" />
      </FormCol>
      <el-divider />
      <div class="sub-title">用户信息表</div>
      <FormCol>
        <!-- <CompUserInfos :form-info="formUserInfos" /> -->
      </FormCol>
      <el-divider />
      <div class="sub-title">企业信息</div>
      <FormCol>
        <!-- <CompPanyInfo :form-info="formVehicleBaseInfo" /> -->
      </FormCol>
      <!-- <template v-if="formAnyInfo.typeid == 1">
        <div class="sub-title">油烟净化装置</div>
        <FormCol>
          <CompFumePurifyDevice :form-info="formFumePurifyDevice" />
        </FormCol>
      </template>
      <template v-if="formAnyInfo.typeid == 1">
        <div class="sub-title">餐饮基础信息表</div>
        <FormCol>
          <CompRestaurantBaseInfo :form-info="formRestaurantBaseInfo" />
        </FormCol>
      </template>
      <template v-if="formAnyInfo.typeid == 7">
        <div class="sub-title">汽修基础信息表</div>
        <FormCol>
          <CompVehicleBaseInfo :form-info="formVehicleBaseInfo" />
        </FormCol>
      </template> -->
    </el-tab-pane>
    <el-tab-pane label="设备管理" name="second">
      <el-row>
        <el-col :span="18">
          <div class="sub-title">监测设备信息</div>
          <!-- <CompDeviceInfo :form-info="formDevice" /> -->
        </el-col>
        <el-col :span="6">
          <el-row justify="end" align="middle" style="height: 80px">
            <el-button type="success" @click="drawer = true"
              >新增设备</el-button
            >
          </el-row>
        </el-col>
      </el-row>
    </el-tab-pane>
    <el-tab-pane label="危废排污" name="third">
      <div class="sub-title">危废排污清单</div>
      <FormCol>
        <!-- <CompHazardousWasteFile :form-info="formHazardousWasteFile" /> -->
      </FormCol>
      <div class="sub-title">危废排污记录</div>
      <FormCol>
        <!-- <CompHazardousWasteRecord :form-info="formHazardousWasteRecord" /> -->
      </FormCol>
    </el-tab-pane>
    <el-tab-pane label="行政处罚" name="fourth">
      <div class="sub-title">行政处罚表</div>
      <FormCol>
        <!-- <CompPunishment :form-info="formProblem" /> -->
      </FormCol>
    </el-tab-pane>
    <el-tab-pane label="信访投诉" name="fifth">
      <div class="sub-title">信访投诉</div>
      <FormCol>
        <!-- <CompLaint :form-info="formLaint" /> -->
      </FormCol>
    </el-tab-pane>
    <el-tab-pane label="巡查问题表" name="sixth">
      <div class="sub-title">巡查问题表</div>
      <FormCol>
        <!-- <CompProblem :form-info="formProblem" /> -->
      </FormCol>
    </el-tab-pane>
  </el-tabs>
  <!-- <ComBaseInformation v-model="drawer"></ComBaseInformation> -->
</template>
<script>
import userApi from '@/api/fytz/userApi';
// import ComBaseInformation from '@/views/baseinfo/fytz/scene/ComBaseInformation.vue';
import CompUserInfo from './components/CompUserInfo.vue';
// import CompLaint from '@/views/baseinfo/fytz/scene/CompLaint.vue';
// import CompDeviceInfo from "@/views/baseinfo/fytz/scene/CompDeviceInfo.vue";
// import CompPanyInfo from '@/views/baseinfo/fytz/scene/CompPanyInfo.vue';
// import CompFumePurifyDevice from '@/views/baseinfo/fytz/scene/CompFumePurifyDevice.vue';
// import CompHazardousWasteFile from '@/views/baseinfo/fytz/scene/CompHazardousWasteFile.vue';
// import CompHazardousWasteRecord from '@/views/baseinfo/fytz/scene/CompHazardousWasteRecord.vue';
// import CompProblem from '@/views/baseinfo/fytz/scene/CompProblem.vue';
// import CompPunishment from '@/views/baseinfo/fytz/scene/CompPunishment.vue';
// import CompRestaurantBaseInfo from '@/views/baseinfo/fytz/scene/CompRestaurantBaseInfo.vue';
// import CompVehicleBaseInfo from '@/views/baseinfo/fytz/scene/CompVehicleBaseInfo.vue';
// import CompUserInfos from '@/views/baseinfo/fytz/scene/CompUserInfos.vue';
export default {
  components: {
    // ComBaseInformation,
    // CompLaint,
    CompUserInfo,
    // CompDeviceInfo,
    // CompPanyInfo,
    // CompFumePurifyDevice,
    // CompHazardousWasteFile,
    // CompHazardousWasteRecord,
    // CompProblem,
    // CompPunishment,
    // CompRestaurantBaseInfo,
    // CompVehicleBaseInfo,
    // CompUserInfos,
  },
  data() {
    return {
      drawer: false,
      formUser: {},
      // formSubScene: {},
      formLaint: {},
      // formDevice: {},
      formPanyInfo: {},
      formFumePurifyDevice: {},
      formHazardousWasteFile: {},
      formHazardousWasteRecord: {},
      formProblem: {},
      formPunishment: {},
      formRestaurantBaseInfo: {},
      formVehicleBaseInfo: {},
      formUserInfos: {},
      activeName: 'first',
      scroll: '',
    };
  },
  beforeRouteEnter(to, from, next) {
    userApi.fetchUserBaseInfo(to.params.userId).then((res) => {
      next((vm) => {
        if (res.userInfo) {
          vm.formUser = res.userInfo;
        } else {
          vm.formUser = {
            guid: to.params.userId,
          };
        }
      });
    });
  },
  methods: {
    handleClick(tab) {
      console.log('tab', tab);
    },
    // å›žé€€é¡µé¢
    onBack() {
      this.$router.back();
    },
  },
};
</script>
<style scoped>
.sub-title {
  font-size: var(--el--font--size--large);
  margin-bottom: 30px;
  margin-top: 30px;
  margin-left: 20px;
}
</style>
src/views/fytz/user/UserInfo.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,295 @@
<template>
  <el-row ref="searchRef">
    <el-col>
      <el-form :inline="true" :model="formSearch">
        <el-form-item label="省/市/区/镇" prop="_locations">
          <el-cascader
            v-model="formSearch._locations"
            :options="locations"
            placeholder="省/市/区/镇"
            :props="props"
            style="width: 280px"
          />
        </el-form-item>
        <el-form-item label="场景名称" prop="searchText">
          <el-input
            clearable
            v-model="formSearch.searchText"
            placeholder="输入搜索场景名称"
          />
        </el-form-item>
        <el-form-item label="用户类型" prop="scensetypeid">
          <el-select
            v-model="formSearch.scensetypeid"
            placeholder="用户类型"
            style="width: 75px"
          >
            <el-option
              v-for="s in sceneTypes"
              :key="s.value"
              :label="s.label"
              :value="s.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="上线状态" prop="online">
          <el-select
            v-model="formSearch.online"
            placeholder="全部"
            style="width: 75px"
          >
            <el-option
              v-for="s in onlineStatus"
              :key="s.value"
              :label="s.label"
              :value="s.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button icon="Search" type="primary" @click="onSearch"
            >查询</el-button
          >
        </el-form-item>
      </el-form>
    </el-col>
  </el-row>
  <el-table
    :data="tableData"
    v-loading="loading"
    table-layout="fixed"
    :row-class-name="tableRowClassName"
    :height="tableHeight"
  >
    <el-table-column prop="realname" label="公司" align="center">
      <template #default="scope">
        <el-tooltip
          effect="dark"
          :content="scope.row.realname"
          placement="top-start"
          :show-after="500"
        >
          {{ scope.row.realname }}
        </el-tooltip>
      </template>
    </el-table-column>
    <el-table-column prop="telephone" label="电话" align="center" />
    <el-table-column
      prop="extension1"
      label="区县"
      width="120"
      align="center"
    />
    <el-table-column prop="usertype" label="类型"  align="center" />
    <el-table-column prop="departmentname" label="名称">
      <template #default="scope">
        <el-tooltip
          effect="dark"
          :content="scope.row.departmentname"
          placement="top-start"
          :show-after="500"
        >
          {{ scope.row.departmentname }}
        </el-tooltip>
      </template>
    </el-table-column>
    <el-table-column fixed="right" label="操作" width="140">
      <template #header>
        <el-button icon="DocumentAdd" type="success" @click="drawer = true"
          >新增用户</el-button
        >
      </template>
      <template #default="scope">
        <el-button
          :loading="scope.row.loading1"
          type="default"
          size="small"
          @click="editRow(scope)"
          >编辑</el-button
        >
        <el-button
          :loading="scope.row.loading2"
          :type="scope.row.extension1 != '0' ? 'danger' : 'primary'"
          size="small"
          @click="itemActive(scope)"
          >{{ scope.row.extension1 != '0' ? '下线' : '上线' }}</el-button
        >
      </template>
    </el-table-column>
  </el-table>
  <el-pagination
    ref="paginationRef"
    class="el-pagination"
    v-model:current-page="currentPage"
    v-model:page-size="pageSize"
    :page-sizes="[10, 20, 50, 100]"
    :background="true"
    layout="total, sizes, prev, pager, next, jumper"
    :total="total"
  />
  <CompUserInfoAddDrawer v-model:drawer="drawer"></CompUserInfoAddDrawer>
</template>
<script>
import { enumScene_1 } from '@/enum/scene';
import { enumLocation } from '@/enum/location';
import { enumOnlineStatus } from '@/enum/onlineStatus';
import userApi from '@/api/fytz/userApi';
import { useLoadingStore } from '@/stores/loadingStore';
import { mapStores } from 'pinia';
import { useMessageBoxTip } from '@/composables/messageBox';
import CompUserInfoAddDrawer from './components/CompUserInfoAddDrawer.vue';
export default {
  components: {
    CompUserInfoAddDrawer,
  },
  data() {
    return {
      locations: enumLocation(),
      sceneTypes: enumScene_1(),
      onlineStatus: enumOnlineStatus(),
      formSearch: {
        _locations: [],
        searchText: '',
        scensetypeid: '',
        online: '',
      },
      props: {
        checkStrictly: true,
      },
      tableData: [],
      tableHeight: '500',
      loading: false,
      currentPage: 1,
      pageSize: 20,
      total: 0,
      drawer: false,
    };
  },
  watch: {
    currentPage(nValue, oValue) {
      if (nValue != oValue) {
        this.onSearch();
      }
    },
    pageSize(nValue, oValue) {
      if (nValue != oValue) {
        this.onSearch();
      }
    },
  },
  computed: {
    ...mapStores(useLoadingStore),
  },
  methods: {
    onSearch() {
      this.loading = true;
      const f = this.formSearch;
      const area = {};
      // è¡Œæ”¿åŒºåˆ’
      f._locations.length > 0
        ? ([area.provinceCode, area.provinceName] = f._locations[0])
        : ([area.provinceCode, area.provinceName] = [null, null]);
      if (area.provinceCode == '0')
        [area.provinceCode, area.provinceName] = [null, null];
      f._locations.length > 1
        ? (area.citycode = f._locations[1][0])
        : (area.citycode = null);
      f._locations.length > 2
        ? ([area.districtCode, area.districtName] = f._locations[2])
        : ([area.districtCode, area.districtName] = [null, null]);
      f._locations.length > 3
        ? (area.towncode = f._locations[3][0])
        : (area.towncode = null);
      // åœºæ™¯ç±»åž‹
      area.scensetypeid = f.scensetypeid;
      if (area.scensetypeid == '0') area.scensetypeid = null;
      // ä¸Šä¸‹çº¿çŠ¶æ€
      area.online = f.online;
      // å…³é”®å­—
      area.searchText = f.searchText;
      userApi
        .fetchUser('00EQQVnE9QFvbkQr', this.currentPage, this.pageSize, area)
        .then((res) => {
          if (res) {
            this.tableData = res.data;
            this.currentPage = res.headers.currentPage;
            console.log(res.headers);
            this.total = parseInt(res.headers.totalPage) * this.pageSize;
          }
        })
        .finally(() => {
          this.loading = false;
        });
    },
    calcTableHeight() {
      const h1 = this.$refs.searchRef.$el.offsetHeight;
      const h2 = this.$refs.paginationRef.$el.offsetHeight;
      // return `calc(100vh - ${h1}px - ${h2}px - var(--el-main-padding) * 2 - var(--el-header-height))`;
      return `calc(100vh - ${h1}px - ${h2}px - 60px - var(--el-main-padding) * 2)`;
    },
    editRow(scope) {
      scope.row.loading1 = true;
      this.loadingStore.loadingStatus.push(() => (scope.row.loading1 = false));
      this.$router.push(`userEdit/${scope.row.guid}`);
    },
    itemActive(scope) {
      const rb = {};
      rb.guid = scope.row.guid;
      rb.extension1 = scope.row.extension1 != '0' ? '0' : '1';
      const msg = scope.row.extension1 != '0' ? '下线' : '上线';
      useMessageBoxTip({
        confirmMsg: `确认${msg}该场景?`,
        confirmTitle: msg,
        onConfirm: () => {
          scope.row.loading2 = true;
          userApi
            .updateScene(rb)
            .then((res) => {
              if (res == 1) {
                scope.row.extension1 = rb.extension1;
              }
            })
            .finally(() => {
              scope.row.loading2 = false;
            });
        },
      });
    },
    tableRowClassName({ row }) {
      return row.extension1 != '0' ? 'online-row' : 'offline-row';
    },
  },
  mounted() {
    this.formSearch.scensetypeid = this.sceneTypes[0].value;
    this.formSearch._locations = [this.locations[0].value];
    this.formSearch.online = this.onlineStatus[0].value;
    this.tableHeight = this.calcTableHeight();
    this.onSearch();
  },
};
</script>
<style>
.el-table .offline-row {
  background-color: var(--el-disabled-bg-color);
  color: var(--el-disabled-text-color);
}
.el-table .cell {
  white-space: nowrap;
  color: var(--el-disabled-text-color);
}
.el-pagination {
  background-color: var(--el-color-white);
  padding-top: 20px;
  border-top: 1px solid rgba(0, 0, 0, 0.096);
  /* margin-top: 2px; */
}
</style>
src/views/fytz/user/components/CompUserInfo.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,305 @@
<template>
  <el-form
    :inline="false"
    :model="formObj"
    ref="formRef"
    :rules="rules"
    label-position="right"
    label-width="150px"
  >
    <!-- <el-form-item label="id" prop="GUID">
      <el-input clearable v-model="formObj.GUID" placeholder="id" />
    </el-form-item> -->
    <!-- <el-form-item label="头像url" prop="HeadIconUrl">
      <el-input clearable v-model="formObj.HeadIconUrl" placeholder="头像url" />
    </el-form-item> -->
    <el-form-item label="账户名" prop="acountname">
      <el-input clearable v-model="formObj.acountname" placeholder="账户名" />
    </el-form-item>
    <el-form-item label="用户昵称" prop="realname">
      <el-input clearable v-model="formObj.realname" placeholder="用户昵称" />
    </el-form-item>
    <el-form-item label="密码" prop="password">
      <el-input
        clearable
        type="password"
        v-model="formObj.password"
        placeholder="默认密码123456"
      />
    </el-form-item>
    <!-- <el-form-item label="用户类型id" prop="UserTypeID">
      <el-input
        clearable
        v-model="formObj.UserTypeID"
        placeholder="用户类型id"
      />
    </el-form-item> -->
    <el-form-item label="用户类型" prop="_usertype">
      <el-select v-model="formObj._usertype" placeholder="用户类型">
        <el-option
          v-for="s in userTypes"
          :key="s.value"
          :label="s.label"
          :value="s"
        />
      </el-select>
    </el-form-item>
    <el-form-item label="所属企业" prop="departmentname">
      <el-input
        clearable
        v-model="formObj.departmentname"
        placeholder="所属企业"
        disabled
      />
    </el-form-item>
    <el-form-item label="是否可用" prop="isenable">
      <el-switch v-model="formObj.isenable" />
      <span style="margin-left: 16px">{{
        formObj.isenable ? '可用' : '不可用'
      }}</span>
    </el-form-item>
    <el-form-item label="工号" prop="workno">
      <el-input clearable v-model="formObj.workno" placeholder="工号" />
    </el-form-item>
    <el-form-item label="手机" prop="telephone">
      <el-input
        clearable
        type="tel"
        v-model="formObj.telephone"
        placeholder="手机"
      />
    </el-form-item>
    <!-- <el-form-item label="微信id" prop="WechatID">
      <el-input clearable v-model="formObj.WechatID" placeholder="微信id" />
    </el-form-item> -->
    <el-form-item label="省/市/区/镇" prop="_locations">
      <el-cascader
        v-model="formObj._locations"
        :options="locations"
        placeholder="省/市/区/镇"
        :props="locationsProps"
        style="width: 280px"
        :disabled="!create"
      />
    </el-form-item>
    <el-form-item label="场景类型" prop="_scenetype">
      <el-select
        v-model="formObj._scenetype"
        placeholder="场景类型"
      >
        <el-option
          v-for="s in sceneTypes"
          :key="s.value"
          :label="s.label"
          :value="s"
        />
      </el-select>
    </el-form-item>
    <el-form-item>
      <el-button
        :disabled="!edit"
        type="primary"
        @click="onSubmit"
        :loading="loading"
        >提交</el-button
      >
      <el-button :disabled="!edit" @click="onReset">重置</el-button>
    </el-form-item>
  </el-form>
</template>
<script setup>
import { defineProps, defineEmits, reactive, ref, watch } from 'vue';
import { useFormConfirm } from '@/composables/formConfirm';
import { enumUserNA } from '@/enum/user';
import { enumScene_1NA, getSceneName_1 } from '@/enum/scene';
import { enumLocationNA } from '@/enum/location';
import userApi from '@/api/fytz/userApi';
const props = defineProps({
  //基本信息
  formInfo: Object,
  isEdit: Boolean,
  create: {
    type: Boolean,
    default: false,
  },
  active: {
    type: Boolean,
    default: false,
  },
});
const emit = defineEmits(['onSubmit', 'onCancel', 'update:isEdit']);
const { formObj, formRef, edit, onSubmit, onReset } = useFormConfirm({
  defaultForm: {
    isenable: true,
  },
  submit: {
    do: submit,
  },
  cancel: {
    do: cancel,
  },
});
const userTypes = reactive(enumUserNA());
const sceneTypes = reactive(enumScene_1NA());
const locations = enumLocationNA();
const locationsProps = reactive({
  checkStrictly: true,
});
const loading = ref(false);
const rules = reactive({
  acountname: [
    {
      required: true,
      message: '账户名不能为空',
      trigger: 'blur',
    },
  ],
  realname: [
    {
      required: true,
      message: '用户昵称不能为空',
      trigger: 'blur',
    },
  ],
  password: [
    {
      required: props.create,
      message: '密码不能为空',
      trigger: 'blur',
    },
  ],
  _usertype: [
    {
      required: true,
      message: '用户类型不能为空',
      trigger: 'change',
    },
  ],
  _locations: [
    {
      required: props.create,
      message: '省/市/区/镇不能为空',
      trigger: 'change',
    },
  ],
  _scenetype: [
    {
      required: true,
      message: '场景类型不能为空',
      trigger: 'change',
    },
  ],
});
// ç”¨æˆ·åŸºæœ¬ä¿¡æ¯æ ¼å¼åŒ–
function parseUserInfo(s) {
  s._usertype = {
    label: s.usertype,
    value: s.usertypeid + '',
  };
  s._scenetype = {
    label: getSceneName_1(s.extension2),
    value: s.extension2,
  };
  s._locations = [];
  // if (s.provincecode && s.provincecode.length > 0)
  //   s._locations.push([s.provincecode, s.provincename]);
  // if (s.citycode && s.citycode.length > 0)
  //   s._locations.push([s.citycode, s.cityname]);
  // if (s.districtcode && s.districtcode.length > 0)
  //   s._locations.push([s.districtcode, s.districtname]);
  // if (s.towncode && s.towncode.length > 0)
  //   s._locations.push([s.towncode, s.townname]);
  return s;
}
function createUser() {
  loading.value = true;
  return userApi
    .createUser(formObj.value)
    .then(() => {
      emit('onSubmit', formObj);
    })
    .finally(() => {
      loading.value = false;
    });
}
function updateUser() {
  loading.value = true;
  return userApi
    .updateUserInfo(formObj.value)
    .then(() => {
      emit('onSubmit', formObj);
    })
    .finally(() => {
      loading.value = false;
    });
}
function submit() {
  // è¡Œæ”¿åŒºåˆ’信息填充
  const a = formObj.value._locations;
  if (a[0]) {
    formObj.value.provincecode = a[0][0];
    formObj.value.provincename = a[0][1];
  }
  if (a[1]) {
    formObj.value.citycode = a[1][0];
    formObj.value.cityname = a[1][1];
  }
  if (a[2]) {
    formObj.value.districtcode = a[2][0];
    formObj.value.extension1 = a[2][1];
  }
  if (a[3]) {
    formObj.value.towncode = a[3][0];
    formObj.value.townname = a[3][1];
  }
  // ç”¨æˆ·ç±»åž‹ä¿¡æ¯å¡«å……
  const b = formObj.value._usertype;
  formObj.value.usertypeid = b.value;
  formObj.value.usertype = b.label;
  // åœºæ™¯ç±»åž‹ä¿¡æ¯å¡«å……
  const c = formObj.value._scenetype;
  formObj.value.extension2 = c.value;
  return props.create ? createUser() : updateUser();
}
function cancel() {
  emit('onCancel');
}
watch(
  () => props.formInfo,
  (nValue) => {
    formObj.value = parseUserInfo(nValue);
  }
);
watch(
  () => props.active,
  (nValue) => {
    if (!nValue) {
      onReset();
    }
  }
);
watch(edit, (nValue) => {
  emit('update:isEdit', nValue);
});
</script>
src/views/fytz/user/components/CompUserInfoAddDrawer.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,67 @@
<template>
  <el-drawer
    v-model="drawer_"
    title="新增用户"
    direction="rtl"
    :before-close="onDrawerClose"
  >
    <CompUserInfo
      :create="true"
      :active="drawer"
      v-model:is-edit="drawerEdit"
      @on-submit="onDrawerSubmit"
      @on-cancel="onDrawerCancel"
    ></CompUserInfo>
  </el-drawer>
</template>
<script>
import CompUserInfo from './CompUserInfo.vue';
import { useMessageBox } from '@/composables/messageBox';
export default {
  components: { CompUserInfo },
  props: ['drawer'],
  emits: ['update:drawer'],
  data() {
    return {
      drawer_: this.drawer,
      drawerEdit: false,
    };
  },
  watch: {
    drawer(nValue) {
      this.drawer_ = nValue;
    },
    drawer_(nValue) {
      this.$emit('update:drawer', nValue);
    },
  },
  methods: {
    onDrawerSubmit() {
      // å…³é—­å¼¹å‡ºæ¡†
      this.drawer_ = false;
    },
    onDrawerClose(done) {
      if (this.drawerEdit) {
        // å¼¹å‡ºç¡®è®¤æ¡†
        useMessageBox({
          confirmMsg: '是否放弃已编辑的内容?',
          confirmTitle: '取消',
          onConfirm: () => {
            done();
          },
        });
      } else {
        // ç›´æŽ¥å…³é—­
        done();
      }
    },
    onDrawerCancel() {
      this.onDrawerClose(() => {
        this.drawer_ = false;
      });
    },
  },
};
</script>
src/views/notice/CompNoticeAdd.vue
@@ -92,7 +92,7 @@
        //通知内容
        content: '',
        //通知图片
        picUrl: '',
        picUrl: null,
        //通知链接
        bodyUrl: '',
        //是否需要签收
@@ -102,7 +102,7 @@
        //接受用户区县
        district: '0',
        //接受用户id
        receiverId: '',
        receiverId: null,
      },
      rules: {
        title: [
src/views/notice/CompNoticeAddDrawer.vue
@@ -16,7 +16,7 @@
</template>
<script>
import noticeApi from '@/api/noticeApi';
import noticeApi from '@/api/fytz/noticeApi';
import CompNoticeAdd from './CompNoticeAdd.vue';
import { useMessageBoxTip, useMessageBox } from '@/composables/messageBox';
src/views/notice/NoticeManage.vue
@@ -138,7 +138,7 @@
</template>
<script>
import noticeApi from '@/api/noticeApi';
import noticeApi from '@/api/fytz/noticeApi';
import { useDateFormat } from '@vueuse/core';
import { enumScene_1 } from '@/enum/scene';
import { enumDistrict } from '@/enum/district';