Pārlūkot izejas kodu

fix: Merge branch 'dev' of http://192.168.0.115:3000/bill/4pc into dev

bill 1 gadu atpakaļ
vecāks
revīzija
58d9cfda0e

+ 2 - 1
.env

@@ -1,2 +1,3 @@
 VITE_QJ_URL=https://test.4dkankan.com/panorama
-VITE_API=https://uat-sp.4dkankan.com/
+VITE_API=https://uat-sp.4dkankan.com/
+

+ 1 - 1
.env.development

@@ -1,2 +1,2 @@
 VITE_QJ_URL=https://test.4dkankan.com/panorama
-VITE_API=https://uat-sp.4dkankan.com/
+VITE_API=https://uat-sp.4dkankan.com/

+ 1 - 0
package.json

@@ -22,6 +22,7 @@
     "pinia": "^2.1.7",
     "proj4": "^2.11.0",
     "qrcode": "^1.5.3",
+    "vite-svg-loader": "^5.1.0",
     "vue": "^3.4.21",
     "vue-router": "^4.3.0",
     "xlsx": "^0.18.5"

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 427 - 284
pnpm-lock.yaml


+ 8 - 0
src/assets/frame.svg

@@ -0,0 +1,8 @@
+<svg fill="currentColor" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
+	<g id="frame">
+		<g id="Union">
+			<path d="M3.5 1C2.11929 1 1 2.11929 1 3.5V5C1 5.27614 1.22386 5.5 1.5 5.5C1.77614 5.5 2 5.27614 2 5V3.5C2 2.67157 2.67157 2 3.5 2H12.5C13.3284 2 14 2.67157 14 3.5V12.5C14 13.3284 13.3284 14 12.5 14H3.5C2.67157 14 2 13.3284 2 12.5V11C2 10.7239 1.77614 10.5 1.5 10.5C1.22386 10.5 1 10.7239 1 11V12.5C1 13.8807 2.11929 15 3.5 15H12.5C13.8807 15 15 13.8807 15 12.5V3.5C15 2.11929 13.8807 1 12.5 1H3.5Z"  />
+			<path d="M7.14645 4.14645C7.34171 3.95118 7.65829 3.95118 7.85355 4.14645L10.8536 7.14645C11.0488 7.34171 11.0488 7.65829 10.8536 7.85355L7.85355 10.8536C7.65829 11.0488 7.34171 11.0488 7.14645 10.8536C6.95118 10.6583 6.95118 10.3417 7.14645 10.1464L9.29289 8H1.5C1.22386 8 1 7.77614 1 7.5C1 7.22386 1.22386 7 1.5 7H9.29289L7.14645 4.85355C6.95118 4.65829 6.95118 4.34171 7.14645 4.14645Z" />
+		</g>
+	</g>
+</svg>

+ 5 - 0
src/assets/location.svg

@@ -0,0 +1,5 @@
+<svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+	<g id="location">
+		<path id="Subtract" fill-rule="evenodd" clip-rule="evenodd" d="M12 23C12 23 21 17.0417 21 10.1667C21 5.10406 16.9706 1 12 1C7.02945 1 3 5.10406 3 10.1667C3 17.0417 12 23 12 23ZM12 14.7499C14.4852 14.7499 16.5 12.6979 16.5 10.1666C16.5 7.63528 14.4852 5.58325 12 5.58325C9.51467 5.58325 7.49995 7.63528 7.49995 10.1666C7.49995 12.6979 9.51467 14.7499 12 14.7499Z" />
+	</g>
+</svg>

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 5 - 0
src/assets/panorama.svg


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 5 - 0
src/assets/pic_pen.svg


+ 11 - 0
src/assets/state_gps.svg

@@ -0,0 +1,11 @@
+<svg  viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+	<g id="state_gps">
+		<g id="Union">
+			<path d="M4.11091 2.61088C4.30617 2.41562 4.30617 2.09903 4.11091 1.90377C3.91565 1.70851 3.59907 1.70851 3.40381 1.90377C0.865398 4.44218 0.865398 8.55775 3.40381 11.0962C3.59907 11.2914 3.91565 11.2914 4.11091 11.0962C4.30617 10.9009 4.30617 10.5843 4.11091 10.3891C1.96303 8.24117 1.96303 4.75876 4.11091 2.61088Z"  />
+			<path d="M12.5962 11.0962C15.1346 8.55775 15.1346 4.44218 12.5962 1.90377C12.4009 1.70851 12.0843 1.70851 11.8891 1.90377C11.6938 2.09903 11.6938 2.41562 11.8891 2.61088C14.037 4.75876 14.037 8.24117 11.8891 10.3891C11.6938 10.5843 11.6938 10.9009 11.8891 11.0962C12.0843 11.2914 12.4009 11.2914 12.5962 11.0962Z"  />
+			<path d="M5.52513 3.31796C5.72039 3.51322 5.72039 3.8298 5.52513 4.02506C4.15829 5.3919 4.15829 7.60797 5.52513 8.97481C5.72039 9.17007 5.72039 9.48665 5.52513 9.68192C5.32986 9.87718 5.01328 9.87718 4.81802 9.68192C3.06066 7.92456 3.06066 5.07531 4.81802 3.31796C5.01328 3.12269 5.32986 3.12269 5.52513 3.31796Z" />
+			<path d="M11.182 3.31796C12.9393 5.07531 12.9393 7.92456 11.182 9.68192C10.9867 9.87718 10.6701 9.87718 10.4749 9.68192C10.2796 9.48665 10.2796 9.17007 10.4749 8.97481C11.8417 7.60797 11.8417 5.3919 10.4749 4.02506C10.2796 3.8298 10.2796 3.51322 10.4749 3.31796C10.6701 3.12269 10.9867 3.12269 11.182 3.31796Z"  />
+			<path d="M8 4.49994C9.10457 4.49994 10 5.39537 10 6.49994C10 7.58489 9.1361 8.46806 8.05866 8.4991L11.3091 14.9999H4.69104L7.94146 8.4991C6.86396 8.46813 6 7.58493 6 6.49994C6 5.39537 6.89543 4.49994 8 4.49994ZM8 5.49994C7.44772 5.49994 7 5.94765 7 6.49994C7 7.05222 7.44772 7.49994 8 7.49994C8.55228 7.49994 9 7.05222 9 6.49994C9 5.94765 8.55228 5.49994 8 5.49994ZM7.99978 10.6166L6.30878 13.9996H9.69078L7.99978 10.6166Z"/>
+		</g>
+	</g>
+</svg>

+ 5 - 0
src/assets/vector.svg

@@ -0,0 +1,5 @@
+<svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
+	<g id="vector">
+		<path id="Union" fill-rule="evenodd" clip-rule="evenodd" d="M2 22V2H22V22H2ZM17.1226 4.85714H14.0203L4.85714 14.0203V17.1226L17.1226 4.85714ZM4.85714 4.85714H9.97971L4.85714 9.97971V4.85714ZM14.0203 19.1429H19.1429V14.0203L14.0203 19.1429ZM9.97971 19.1429H6.87747L19.1429 6.87747V9.97971L9.97971 19.1429Z" />
+	</g>
+</svg>

+ 10 - 15
src/components/single-input.vue

@@ -1,17 +1,7 @@
 <template>
-  <el-dialog
-    :model-value="visible"
-    @update:model-value="(val) => emit('update:visible', val)"
-    :title="title"
-    width="500"
-  >
-    <el-input
-      v-model.trim="ivalue"
-      :maxlength="100"
-      show-word-limit
-      type="textarea"
-      placeholder="请输入"
-    />
+  <el-dialog :model-value="visible" @update:model-value="(val) => emit('update:visible', val)" :title="title"
+    width="500">
+    <el-input v-model.trim="ivalue" :maxlength="100" show-word-limit type="textarea" :placeholder="placeholder" />
     <template #footer>
       <div class="dialog-footer">
         <el-button @click="emit('update:visible', false)">取消</el-button>
@@ -25,12 +15,17 @@
 import { ElMessage } from "element-plus";
 import { ref, watchEffect } from "vue";
 
-const props = defineProps<{
+
+
+const props = withDefaults(defineProps<{
   visible: boolean;
   value: string;
   title: string;
+  placeholder: string;
   updateValue: (value: string) => void;
-}>();
+}>(), {
+  placeholder: '请输入',
+})
 const emit = defineEmits<{
   (e: "update:visible", visible: boolean): void;
 }>();

+ 2 - 0
src/request/URL.ts

@@ -40,6 +40,7 @@ export const getUserSceneInfo = `/relics/user/getUserInfo`;
 export const getUserInfoById = `/relics/user/info/:id`;
 export const userScenepage = `/relics/user/page`;
 
+export const getMsgAuthCode = `/relics/user/getMsgAuthCode`;
 
 ///drawing
 
@@ -49,5 +50,6 @@ export const getDrawingDetail = `/relics/relics/drawing/info/:drawingId`;
 export const getDrawingInfoByRelicsId = `/relics/relics/drawing/infoByRelicsId/:drawingId`;
 export const updateDrawing = `/relics/relics/drawing/update`;
 
+
 //token
 export const getFdTokenByNum = `/relics/scene/getFdTokenByNum?num=`;

+ 7 - 2
src/request/index.ts

@@ -22,7 +22,7 @@ import {
 
 const error = throttle((msg: string) => ElMessage.error(msg), 2000);
 
-type Other = { params?: Param; paths?: Param };
+type Other = { params?: Param; paths?: Param, useResult?: boolean };
 export const sendFetch = <T>(
   url: string,
   init: RequestInit,
@@ -69,7 +69,12 @@ export const sendFetch = <T>(
         });
         throw data.message;
       } else {
-        return data.data;
+        if (other && other.useResult) {
+          return data
+        } else {
+          return data.data;
+        }
+
       }
     });
 };

+ 4 - 2
src/request/organization.ts

@@ -9,12 +9,14 @@ export type OrganizationType = {
     ancestors: string
     contact: string
     orderNum: number
-    orgId: number 
+    orgId: number
     parentId: number
     orgName: string
     password: string
     type: organizationTypeEnum | null
     userName: string
+    confirmPwd?: string,
+    msgAuthCode?: string
 
 }
 
@@ -28,7 +30,7 @@ export const alterOrgFetch = (params: Partial<OrganizationType>) =>
         method: "post",
         body: JSON.stringify(params),
     });
-export const delOrgFetch = (params:Partial<OrganizationType>) =>
+export const delOrgFetch = (params: Partial<OrganizationType>) =>
     sendFetch<PageProps<OrganizationType>>(URL.delOrganization, {
         method: "post",
         body: JSON.stringify(params),

+ 9 - 0
src/request/type.ts

@@ -24,6 +24,7 @@ export type UserInfo = {
   userName: string;
   roles: UserInfoRoles[]
   orgId: string
+  orgName?: string
 };
 
 export type Relics = {
@@ -45,6 +46,14 @@ export type ResPage<T> = {
   records: T[];
 };
 
+export type ResResult<T> = {
+  code: number
+  data: any
+  message: any
+  success: boolean
+  timestamp: string
+
+};
 export type ScenePoint = {
   tbStatus: number;
   createTime: string;

+ 17 - 1
src/request/users.ts

@@ -1,5 +1,5 @@
 import { sendFetch, PageProps } from './index'
-import { ResPage } from './type'
+import { ResPage, ResResult } from './type'
 import * as URL from "./URL";
 
 export type UserType = {
@@ -17,6 +17,9 @@ export type UserType = {
     userId: number
     userName: string
     roleNames: string
+    confirmPwd?: string
+    msgAuthCode?: string
+    password?: string
 }
 
 
@@ -49,3 +52,16 @@ export const updateUserStatusFetch = (params: Pick<UserType, 'userId' | 'status'
         method: "post",
         body: JSON.stringify(params),
     });
+export const getMsgAuthCode = (areaNum: string,
+    phoneNum: string) =>
+    sendFetch<ResResult<{}>>(URL.getMsgAuthCode, {
+        method: "post",
+        body: JSON.stringify({
+            areaNum,
+            phoneNum
+        }),
+    }, {
+        useResult: true
+    });
+
+

+ 16 - 12
src/style.scss

@@ -2,7 +2,7 @@ html,
 body,
 #app {
   margin: 0;
-  width : 100vw;
+  width: 100vw;
   height: 100vh;
 }
 
@@ -15,30 +15,30 @@ body,
 }
 
 .disable {
-  opacity       : 0.7;
+  opacity: 0.7;
   pointer-events: none;
 }
 
 .relics-layout {
-  height        : 100%;
-  display       : flex;
+  height: 100%;
+  display: flex;
   flex-direction: column;
-  overflow      : hidden !important;
+  overflow: hidden !important;
 
   .relics-header {
     flex: none;
   }
 
   .relics-content {
-    flex    : 1;
+    flex: 1;
     position: relative;
 
     .el-table {
       position: absolute;
-      left    : 0;
-      top     : 0;
-      width   : 100%;
-      height  : 100%;
+      left: 0;
+      top: 0;
+      width: 100%;
+      height: 100%;
     }
   }
 
@@ -48,6 +48,10 @@ body,
 }
 
 .link {
-  color : var(--el-color-primary);
+  color: var(--el-color-primary);
   cursor: pointer;
-}
+}
+:root {
+  --font14: 14px;
+  --font16: 16px;
+}

+ 33 - 10
src/view/layout/nav.vue

@@ -2,21 +2,19 @@
   <div class="main-layout">
     <div class="header" :class="{ [name]: true }">
       <span class="title-span">
-        <el-button
-          :icon="Back"
-          circle
-          type="primary"
-          @click="router.back()"
-          v-if="showBack"
-        />
+        <el-button :icon="Back" circle type="primary" @click="router.back()" v-if="showBack" />
         <span v-if="!name">不可移动文物管理平台</span>
       </span>
-      <el-dropdown class="avatar" v-if="user">
-        <span>
+      <el-dropdown placement="bottom-end" class="avatar" v-if="user">
+
+        <span class="avatar-left-label">
+          <span class="org"> {{ user.orgName }}</span>
+          <span class="name"> {{ user.nickName }}</span>
           <el-avatar :src="user.head" />
         </span>
         <template #dropdown>
           <el-dropdown-menu>
+            <el-dropdown-item @click="passwordHandler">修改密码</el-dropdown-item>
             <el-dropdown-item @click="logoutHandler">退出登录</el-dropdown-item>
           </el-dropdown-menu>
         </template>
@@ -42,13 +40,21 @@ import { computed } from "vue";
 import { user, logout } from "@/store/user";
 import { errorHook } from "@/request/state";
 import lySlide from "./slide/index.vue";
+import { usersPasswordEdit } from "@/view/quisk";
+import {
+  editUserFetch,
 
+} from "@/request";
 const name = computed(() => router.currentRoute.value.meta?.navClass as string);
 const routeName = computed(() => router.currentRoute.value.name as string);
 const logoutHandler = () => {
   logout();
   router.replace({ name: "login" });
 };
+const passwordHandler = async () => {
+  console.log('passwordHandler', user)
+  await usersPasswordEdit({ user: user.value, submit: editUserFetch });
+};
 errorHook.push((code) => {
   if (code === 4008) {
     router.replace({ name: "login" });
@@ -71,16 +77,29 @@ const showBack = computed(() => {
   flex-direction: column;
   height: 100%;
 }
+
 .header {
   display: flex;
   align-items: center;
   justify-content: space-between;
   padding: 4px 10px;
 
+  .avatar-left-label {
+    display: inline-flex;
+    align-items: center;
+    outline: none;
+
+    .name,
+    .org {
+      padding-right: 10px;
+    }
+  }
+
   &:not(.pano, .map) {
     border-bottom: 1px solid var(--border-color);
     flex: 0 0 auto;
   }
+
   &.pano,
   &.map {
     pointer-events: none;
@@ -91,6 +110,9 @@ const showBack = computed(() => {
     .avatar {
       display: none;
     }
+
+
+
     * {
       pointer-events: all;
     }
@@ -137,7 +159,8 @@ const showBack = computed(() => {
 .title-span {
   display: flex;
   align-items: center;
-  > span {
+
+  >span {
     margin-left: 10px;
   }
 }

+ 11 - 3
src/view/layout/slide/index.vue

@@ -2,17 +2,25 @@
   <div class="slide">
     <el-menu :default-active="(router.currentRoute.value.name as string)"
       @select="(name: string) => router.push({ name })">
-      <sub-menu v-for="route in routes" :meta="route.meta" :name="(route.name as string)" :key="route.name" />
+      <sub-menu v-for="route in routes" :meta="route.meta" v-show="!route.meta.hidden" :name="(route.name as string)"
+        :key="route.name" />
     </el-menu>
   </div>
 </template>
 
 <script setup lang="ts">
+import { computed } from "vue";
 import subMenu from "./submenu.vue";
+import { user } from "@/store/user";
+
 import { router, findRoute } from "@/router";
 //@TODO
-const names = ["scene", "relics", "device", "organization", "users"];
-const routes = names.map((name) => findRoute(name)!);
+const isSuper = computed(() => user.value.roles.filter(item => item.roleKey === "super_admin").length > 0)
+const normal_name = ["scene", "relics", "device", "users"];
+const super_names = ["scene", "relics", "device", "organization", "users"];
+console.log('isSuper', isSuper.value)
+
+const routes = isSuper.value ? super_names.map((name) => findRoute(name)!) : normal_name.map((name) => findRoute(name)!);
 </script>
 
 <style lang="scss" scoped>

+ 17 - 20
src/view/map/map-board.vue

@@ -3,7 +3,7 @@
     <Teleport to=".header" v-if="isMounted">
       <div class="custom_bar">
         <div class="back_container">
-          <el-button :icon="Back" circle type="default" @click="router.back()" />
+          <el-button :icon="Back" circle type="primary" @click="router.back()" />
         </div>
         <div class="nav_container">
           <div
@@ -12,7 +12,7 @@
             @click="handleTabs(0)"
           >
             <el-icon size="20">
-              <LocationInformation />
+              <locationIcon />
             </el-icon>
             <span>坐标</span>
           </div>
@@ -22,7 +22,7 @@
             @click="handleTabs(1)"
           >
             <el-icon size="20">
-              <Grid />
+              <vectorIcon />
             </el-icon>
             <span>矢量图</span>
           </div>
@@ -71,18 +71,8 @@
         v-if="isCurrentTab(1) && !isEditDrawingMode"
         @click="handleBoardDraw"
       >
-        <el-icon size="30">
-          <svg
-            xmlns="http://www.w3.org/2000/svg"
-            width="1em"
-            height="1em"
-            viewBox="0 0 24 24"
-          >
-            <path
-              fill="currentColor"
-              d="M2 4.621a.5.5 0 0 1 .854-.353l6.01 6.01c.126.126.17.31.15.487a2 2 0 1 0 1.751-1.751a.586.586 0 0 1-.487-.15l-6.01-6.01A.5.5 0 0 1 4.62 2H11a9 9 0 0 1 8.468 12.054l2.24 2.239a1 1 0 0 1 0 1.414l-4 4a1 1 0 0 1-1.415 0l-2.239-2.239A9 9 0 0 1 2 11z"
-            />
-          </svg>
+        <el-icon size="36">
+          <picpenIcon />
         </el-icon>
       </div>
     </Teleport>
@@ -99,6 +89,9 @@ import { onMounted, ref, watchEffect, watch, onUnmounted, computed } from "vue";
 import { createBoard, PolygonsPointAttrib } from "drawing-board";
 import MapRightPoly from "./map-right-poly.vue";
 import { Back } from "@element-plus/icons-vue";
+import vectorIcon from "@/assets/vector.svg";
+import picpenIcon from "@/assets/pic_pen.svg";
+import locationIcon from "@/assets/location.svg";
 import {
   addOrUpdateDrawingFetch,
   getDrawingDetailFetch,
@@ -106,7 +99,8 @@ import {
   DrawingDataType,
   PolyDataType,
 } from "@/request/drawing.ts";
-import { Grid, LocationInformation } from "@element-plus/icons-vue";
+// import { relicsPolyginsFetch } from "@/request";
+// import { Grid, LocationInformation } from "@element-plus/icons-vue";
 
 import { mapManageInit, flyUserCenter, tileOptions, tileType } from "./map-flow";
 
@@ -179,7 +173,7 @@ const flyScene = (scene: Scene) => {
 
 const flyScenePoint = (point: ScenePoint) => {
   flyPos(point.pos);
-  board.polygon.activePointId.value = point.id.toString();
+  board.polygon.status.activePointId = point.id.toString();
 };
 
 watch(
@@ -418,7 +412,7 @@ const handlePolysEdit = (item: PolyDataType) => {
 
 .right-control {
   flex: none;
-  width: 300px;
+  width: 320px;
   padding: 15px;
 
   border-left: 1px solid var(--border-color);
@@ -534,13 +528,16 @@ const handlePolysEdit = (item: PolyDataType) => {
       cursor: pointer;
       user-select: none;
       width: 100%;
-
       span {
         line-height: 26px;
-        font-size: 13px;
+        font-size: var(--font14);
       }
 
       &.active {
+        .icon {
+          color: #409eff;
+        }
+
         color: #409eff;
         background-color: #ecf5ff;
         position: relative;

+ 12 - 8
src/view/map/map-right-poly.vue

@@ -2,7 +2,7 @@
   <div class="right-layout">
     <div class="right-content">
       <div class="tree-layout">
-        <p>全部数据</p>
+        <p class="sub-title">全部数据</p>
         <div class="poly-list">
           <template v-if="data.polygons.length > 0" v-for="item in data.polygons">
             <div class="poly-list-item">
@@ -28,13 +28,8 @@
         </div>
       </div>
     </div>
-    <SingleInput
-      :visible="isShowPolyEditName"
-      @update:visible="isShowPolyEditName = false"
-      :value="currentPoly.name"
-      :update-value="updatePolyName"
-      title="修改边界名称"
-    />
+    <SingleInput :visible="isShowPolyEditName" @update:visible="isShowPolyEditName = false" :value="currentPoly.name"
+      :update-value="updatePolyName" title="修改边界名称" />
   </div>
 </template>
 
@@ -142,12 +137,19 @@ const handleDownload = async (item: any) => {
     color: #303133;
     font-size: 14px;
   }
+
+  .sub-title {
+    font-size: 14px;
+    font-weight: bolder;
+    margin-bottom: 30px;
+  }
 }
 
 .right-layout {
   display: flex;
   height: 100%;
   flex-direction: column;
+  font-size: 16px;
 
   .right-content {
     flex: 1;
@@ -178,8 +180,10 @@ const handleDownload = async (item: any) => {
 
     .icon {
       margin-left: 8px;
+      font-size: 16px;
       color: #409eff;
       cursor: pointer;
+
     }
   }
 

+ 57 - 20
src/view/map/map-right.vue

@@ -17,7 +17,7 @@
         </el-form-item>
       </el-form>
       <div class="tree-layout">
-        <p>全部数据</p>
+        <p class="sub-title">全部数据</p>
         <el-tree style="max-width: 600px" :data="treeNode" :props="{ disabled: 'run' }" node-key="id" ref="treeRef"
           :show-checkbox="router.currentRoute.value.name === 'map'" default-expand-all :expand-on-click-node="false">
           <template #default="{ node, data }">
@@ -28,6 +28,7 @@
                 <span :class="{ disable: data.disable }" class="title">
                   <el-icon>
                     <Grid />
+
                   </el-icon>
                   {{ data.raw.sceneName }}
 
@@ -38,7 +39,8 @@
                 <div class="title-box">
                   <span :class="{ disable: data.disable }" class="title">
                     <el-icon>
-                      <LocationInformation v-if="!data.disable" />
+
+                      <StateGpsIcon v-if="!data.disable" />
                       <DeleteLocation v-else />
                     </el-icon>
                     {{ node.label }}
@@ -46,7 +48,6 @@
                   </span>
                   <span :class="{ disable: data.disable }" class="name">
                     {{ data.raw.name }}
-
                   </span>
                 </div>
 
@@ -64,11 +65,23 @@
                   </el-icon>
                 </template>
                 <el-icon color="#409efc" style="margin-left: 8px">
-                  <Link v-if="!data.run" @click.stop="
-                    data.type === 'scene'
-                      ? gotoScene(data.raw)
-                      : emit('gotoPoint', data.raw)
-                    " />
+                  <!-- root -->
+                  <template v-if="data.raw.scenePos">
+                    <FrameIcon v-if="!data.run" @click.stop="
+                      data.type === 'scene'
+                        ? gotoScene(data.raw)
+                        : emit('gotoPoint', data.raw)
+                      " />
+                  </template>
+                  <template v-else>
+
+                    <PanoramaIcon v-if="!data.run" @click.stop="
+                      data.type === 'scene'
+                        ? gotoScene(data.raw)
+                        : emit('gotoPoint', data.raw)
+                      " />
+                  </template>
+
                 </el-icon>
               </span>
             </div>
@@ -81,10 +94,10 @@
       <el-button type="primary" :icon="Download" style="width: 100%" @click="handlerExport(2, relics?.name)">
         导出本体边界坐标
       </el-button>
-      <el-button type="primary" :icon="Download" style="width: 100%; margin-top: 20px; margin-left: 0"
+      <!-- <el-button type="primary" :icon="Download" style="width: 100%; margin-top: 20px; margin-left: 0"
         @click="exportFile(getSelectPoints(), 1, relics?.name)">
         导出绘制矢量数据
-      </el-button>
+      </el-button> -->
 
       <el-button type="primary" :icon="Download" style="width: 100%; margin-top: 20px; margin-left: 0"
         @click="exportImage(getSelectPoints(), relics?.name)">
@@ -94,7 +107,7 @@
   </div>
 
   <SingleInput :visible="!!inputPoint" @update:visible="inputPoint = null" :value="inputPoint?.name || ''"
-    :update-value="updatePointName" title="修改点位名称" />
+    :update-value="updatePointName" title="测点说明" placeholder="请填写测点说明"/>
 </template>
 
 <script setup lang="ts">
@@ -103,10 +116,10 @@ import {
   Delete,
   Grid,
   Download,
-  LocationInformation,
+  // LocationInformation,
   DeleteLocation,
   Edit,
-  Link,
+  // Link,
 } from "@element-plus/icons-vue";
 import { computed, ref, watchEffect } from "vue";
 import {
@@ -125,7 +138,10 @@ import { selectScenes } from "../quisk";
 import { addRelicsScenesFetch, delRelicsScenesFetch } from "@/request";
 import { exportFile, exportImage } from "./pc4Helper";
 import { SceneStatus } from "@/store/scene";
-
+import StateGpsIcon from '@/assets/state_gps.svg';
+import PanoramaIcon from '@/assets/panorama.svg';
+import FrameIcon from '@/assets/frame.svg';
+// import StateGpsIcon from '@/assets/state_gps.svg';
 const emit = defineEmits<{
   (e: "flyScene", data: Scene): void;
   (e: "flyPoint", data: ScenePoint): void;
@@ -217,20 +233,32 @@ const handlerExport = (type: number, name: string) => {
 
 
 <style lang="scss" scoped>
-:deep(.el-tree) {
+:deep(.el-tree-node__content) {
+  --el-tree-node-content-height: 26px;
+  line-height: 26px;
+  user-select: none;
+  margin-bottom: 8px;
+
+}
+
+:deep(.el-tree-node__children .el-tree-node__content) {
   --el-tree-node-content-height: 52px;
 
-  // .el-tree-node__content>label.el-checkbox {
-  //   // padding-top: 10px;
-  //   // align-items: flex-start;
-  // }
+  &>label.el-checkbox {
+    padding-top: 6px;
+    align-items: flex-start;
+  }
 }
 
+:deep(.el-tree .tree-item) {}
+
 .tree-item {
+
   display: flex;
   width: calc(100% - 50px);
   align-items: flex-start;
   justify-content: space-between;
+  font-size: var(--font14);
 
   .title {
     flex: 1;
@@ -239,6 +267,7 @@ const handlerExport = (type: number, name: string) => {
     align-items: center;
     text-overflow: ellipsis; //文本溢出显示省略号
     white-space: nowrap; //文本不会换行
+    line-height: 26px;
   }
 
   .title-box {
@@ -248,14 +277,17 @@ const handlerExport = (type: number, name: string) => {
     width: 100%;
     flex-wrap: nowrap;
 
+
     .name {
       padding-left: 15px;
-
+      color: #999;
     }
   }
 
   .oper {
     flex: none;
+    line-height: 26px;
+    vertical-align: middle;
   }
 }
 
@@ -266,7 +298,12 @@ const handlerExport = (type: number, name: string) => {
 .tree-layout {
   p {
     color: #303133;
+
+  }
+
+  .sub-title {
     font-size: 14px;
+    font-weight: bolder;
   }
 }
 

+ 1 - 1
src/view/map/map.vue

@@ -267,7 +267,7 @@ onUnmounted(() => mapManage.map.dispose());
 
 .right-control {
   flex: none;
-  width: 300px;
+  width: 320px;
   padding: 15px;
 
   border-left: 1px solid var(--border-color);

+ 2 - 1
src/view/pano/pano.vue

@@ -35,7 +35,8 @@
     @update:visible="update = false"
     :value="point.name || ''"
     :update-value="tex => updateScenePointName(point!, tex)"
-    title="修改点位名称"
+    title="测点说明"
+    placeholder="请填写测点说明"
   />
 </template>
 

+ 9 - 1
src/view/quisk.ts

@@ -6,6 +6,8 @@ import OrganizationAdd from "./organization-add.vue";
 import OrganizationEdit from "./organization-edit.vue";
 import UsersAdd from "./users-add.vue";
 import UsersEdit from "./users-edit.vue";
+import UsersPasswordEdit from "./users-password-edit.vue";
+console.log('RelicsEdit', RelicsEdit)
 
 export const relicsEdit = quiskMountFactory(RelicsEdit, {
   title: "创建文物",
@@ -38,4 +40,10 @@ export const usersAdd = quiskMountFactory(UsersAdd, {
 export const usersEdit = quiskMountFactory(UsersEdit, {
   title: "编辑用户",
   width: 520,
-});
+});
+export const usersPasswordEdit = quiskMountFactory(UsersPasswordEdit, {
+  title: "修改密码",
+  width: 520,
+});
+
+

+ 5 - 4
src/view/scene-select.vue

@@ -90,17 +90,18 @@ const tableProps = {
 
 let time: NodeJS.Timeout;
 const checkedTable = () => {
+  console.log('checkedTable', tableProps.tableRef.value)
   if (tableProps.tableRef.value) {
     tableProps.tableRef.value!.clearSelection();
     console.log("1");
     scenes.value.forEach((item) => {
       tableProps.tableRef.value!.toggleRowSelection(item, true);
     });
-    clearTimeout(time);
-    time = setTimeout(() => {
-      loaded.value = true;
-    }, 100);
   }
+  clearTimeout(time);
+  time = setTimeout(() => {
+    loaded.value = true;
+  }, 100);
 };
 
 watch(tableProps.tableRef, checkedTable);

+ 174 - 0
src/view/users-password-edit.vue

@@ -0,0 +1,174 @@
+<template>
+
+  <el-form label-width="100px" :model="data" :rules="rules" ref="baseFormRef">
+    <el-form-item label="手机号" prop="userName" required>
+      <el-input disabled v-model="data.userName" style="width: 300px" :maxlength="500" placeholder="请输入" />
+    </el-form-item>
+    <el-form-item label="验证码" prop="msgAuthCode" required>
+      <el-input v-model="data.msgAuthCode" style="width: 190px" :maxlength="500" placeholder="请输入" />
+      <el-button type="danger" style="margin-left: 10px" @click="getMsgCode">获取验证码</el-button>
+    </el-form-item>
+    <el-form-item label="密码" prop="password" required>
+      <el-input autocomplete="off" readonly onfocus="this.removeAttribute('readonly');" v-model="data.password"
+        :type="addPassFlag ? 'text' : 'password'" style="width: 300px" :maxlength="500"
+        placeholder="请输入8-16位数字、字母大小写组合">
+        <template #suffix>
+          <span @click="addPassFlag = !addPassFlag" style="cursor: pointer;">
+            <el-icon v-if="addPassFlag">
+              <View />
+            </el-icon>
+            <el-icon v-else>
+              <Hide />
+            </el-icon>
+          </span>
+        </template>
+      </el-input>
+
+    </el-form-item>
+    <el-form-item label="密码确认" prop="confirmPwd" required>
+      <el-input autocomplete="off" readonly onfocus="this.removeAttribute('readonly');" v-model="data.confirmPwd"
+        :type="addPassFlag ? 'text' : 'password'" style="width: 300px" :maxlength="500"
+        placeholder="请输入8-16位数字、字母大小写组合">
+        <template #suffix>
+          <span @click="addPassFlag = !addPassFlag" style="cursor: pointer;">
+            <el-icon v-if="addPassFlag">
+              <View />
+            </el-icon>
+            <el-icon v-else>
+              <Hide />
+            </el-icon>
+          </span>
+        </template>
+      </el-input>
+
+    </el-form-item>
+  </el-form>
+</template>
+
+<script setup lang="ts">
+import { QuiskExpose } from "@/helper/mount";
+import { ElMessage, type FormInstance, type FormRules } from "element-plus";
+import { View, Hide } from '@element-plus/icons-vue';
+import type { OrganizationType } from '@/request/organization'
+import {
+  getOrgListFetch,
+  getMsgAuthCode,
+  UserType
+} from "@/request";
+
+import { ref, reactive, unref, onMounted, watchEffect } from "vue";
+const addPassFlag = ref(false)//图标显示标识
+
+const baseFormRef = ref<FormInstance>();
+
+type SelectType = {
+  value: string, id: number
+}
+
+const allOrgs = ref<SelectType[]>([]);
+
+
+const rules = reactive<FormRules>({
+
+
+  userName: [
+    { required: true, message: "请输入账号", trigger: "blur" },
+  ],
+  msgAuthCode: [
+    { required: true, message: "请输入验证码", trigger: "change" },
+  ],
+
+  password: [
+    { required: true, pattern: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,16}$/, message: "请输入8-16位数字、字母大小写组合", trigger: "blur" },
+    { required: true, min: 8, message: '密码太短!', trigger: "blur" },
+  ],
+  confirmPwd: [
+    { required: true, pattern: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,16}$/, message: "请输入8-16位数字、字母大小写组合", trigger: "blur" },
+    { required: true, min: 8, message: '密码太短!', trigger: "blur" },
+  ]
+},)
+
+const props = defineProps<{
+  user: UserType,
+  submit: (data: UserType) => Promise<any>;
+}>();
+const data = ref<UserType>({
+  nickName: "",
+  orgId: undefined,
+  password: "",
+  msgAuthCode: "",
+  confirmPwd: "",
+  status: 0,
+  userName: "",
+  createBy: "",
+  createTime: "",
+  fdkkId: 0,
+  head: "",
+  orgName: "",
+  tbStatus: 0,
+  updateBy: "",
+  updateTime: "",
+  userId: 0,
+  roleNames: ""
+});
+const isDisableMsg = ref(false)
+
+onMounted(async () => {
+  const data = await getOrgListFetch({
+    pageNum: 1,
+    pageSize: 10000,
+  })
+  // console.log('allOrgs', data.records);
+  allOrgs.value = Array.from(data.records).map((item: OrganizationType) => {
+    const i: SelectType = { value: item['orgName'], id: item['orgId'] }
+    return i
+  });
+
+})
+
+// const setParentId = () => {
+//   if (user.value) {
+//     const isSuper = user.value.roles.filter(item => item.roleKey === "super_admin").length > 0;
+//     data.value.parentId = isSuper ? 0 : Number(user.value.orgId)
+//   }
+// }
+watchEffect(() => {
+  if (props.user) {
+    data.value = { ...props.user }
+  }
+})
+
+const getMsgCode = async () => {
+  const res = await getMsgAuthCode('+86', "13750087092")
+  console.log('res', res)
+  let timer = null
+  if (res.success) {
+    timer && clearTimeout(timer)
+    isDisableMsg.value = true
+    timer = setTimeout(() => {
+      isDisableMsg.value = false
+    }, 60 * 1000)
+  }
+
+}
+
+// const handleSelect = (orgId: number) => {
+//   const item = Array.from(allOrgs.value).find(i => i.id === orgId)
+//   if (item) {
+//     data.value.orgName = item.value
+//   }
+// }
+defineExpose<QuiskExpose>({
+  async submit() {
+    if (unref(baseFormRef)) {
+      const res = await unref(baseFormRef)?.validate();
+      if (res) {
+        await props.submit(data.value as any as UserType);
+        ElMessage.success('编辑成功!');
+      }
+    } else {
+      throw "";
+    }
+  },
+});
+</script>

+ 3 - 2
vite.config.ts

@@ -1,12 +1,13 @@
 import { defineConfig, loadEnv } from "vite";
 import { resolve } from "path";
 import vue from "@vitejs/plugin-vue";
+import svgLoader from "vite-svg-loader";
 
 // https://vitejs.dev/config/
 export default ({ mode }: any) =>
   defineConfig({
     base: "./",
-    plugins: [vue()],
+    plugins: [vue(), svgLoader()],
     resolve: {
       alias: [
         {
@@ -15,7 +16,7 @@ export default ({ mode }: any) =>
         },
         {
           find: "drawing-board",
-          replacement: resolve(__dirname, "./src/lib/board/4dmap.js"),
+          replacement: resolve(__dirname, "./src/submodule/src/board"),
         },
       ],
     },