浏览代码

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

bill 1 年之前
父节点
当前提交
21b7f5f62b

二进制
src/assets/avatar.png


+ 5 - 14
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="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>
@@ -32,6 +22,7 @@ const props = withDefaults(
     title: string;
     name?: string;
     placeholder: string;
+    isAllowEmpty?: boolean;
     updateValue: (value: string) => void;
   }>(),
   {
@@ -48,7 +39,7 @@ watchEffect(() => {
 });
 
 const submit = async () => {
-  if (ivalue.value.length === 0) {
+  if (ivalue.value.length === 0 && !props.isAllowEmpty) {
     return ElMessage.error(`${props.name || "点位"}名称不能为空!`);
   }
   await props.updateValue(ivalue.value);

+ 1 - 0
src/request/type.ts

@@ -23,6 +23,7 @@ export type UserInfo = {
   roles: UserInfoRoles[];
   orgId: string;
   orgName?: string;
+  userId?: number;
 };
 
 export type Relics = {

+ 11 - 1
src/router.ts

@@ -1,5 +1,5 @@
 import { RouteRecordRaw, createRouter, createWebHashHistory } from "vue-router";
-import { UserStatus, logintAuth, userStatus } from "./store/user";
+import { UserStatus, logintAuth, userStatus, isSuper } from "./store/user";
 import { watch, watchEffect } from "vue";
 
 export const COORD_NAME = "map-coord";
@@ -144,6 +144,7 @@ const routes: RouteRecordRaw[] = [
       },
     ],
   },
+  { path: '/:pathMatch(.*)*', component: import("@/view/layout/nav.vue") },
 ];
 
 export const findRoute = (
@@ -207,6 +208,15 @@ router.beforeEach((to, _, next) => {
     }
     return;
   }
+  // organization
+  if (to.name === "organization") {
+    console.log('isSuper-organization', isSuper.value)
+    if (!isSuper.value) {
+      router.replace({ name: "scene" });
+      return
+    }    
+  }
+
   if (to.name === "map") {
     router.replace({ name: COORD_NAME, params: to.params });
   } else if (to.name === "query-map") {

+ 3 - 3
src/store/organization.ts

@@ -7,9 +7,9 @@ export enum organizationTypeEnum {
 }
 
 export const OrganizationTypeDesc: { [key in organizationTypeEnum]: string } = {
-  [organizationTypeEnum.Province]: "省",
-  [organizationTypeEnum.City]: "市",
-  [organizationTypeEnum.Country]: "县",
+  [organizationTypeEnum.Province]: "省(自治区、直辖市)",
+  [organizationTypeEnum.City]: "市(地区、州、盟)",
+  [organizationTypeEnum.Country]: "县(区、市、旗)",
   [organizationTypeEnum.Supplier]: "服务商",
 
 };

+ 3 - 1
src/store/user.ts

@@ -2,7 +2,7 @@ import { LoginProps, loginFetch, userInfoFetch } from "@/request";
 import { errorHook, gHeaders } from "@/request/state";
 import { UserInfo } from "@/request/type";
 import { encodePwd } from "@/util";
-import { ref } from "vue";
+import { ref, computed } from "vue";
 
 export const user = ref<UserInfo>();
 export enum UserStatus {
@@ -12,6 +12,8 @@ export enum UserStatus {
 }
 export const userStatus = ref<UserStatus>(UserStatus.UNKNOWN);
 
+export const isSuper = computed(() => user.value ? user.value.roles.filter(item => item.roleKey === "super_admin").length > 0 : false)
+
 export const login = async (props: LoginProps) => {
   const data = await loginFetch({
     ...props,

+ 2 - 4
src/view/layout/nav.vue

@@ -6,11 +6,10 @@
         <span v-if="!name">不可移动文物管理平台</span>
       </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" />
+          <el-avatar :src="user.head || avatarDefault" />
         </span>
         <template #dropdown>
           <el-dropdown-menu>
@@ -41,6 +40,7 @@ import { user, logout } from "@/store/user";
 import { errorHook } from "@/request/state";
 import lySlide from "./slide/index.vue";
 import { usersPasswordEdit } from "@/view/quisk";
+import avatarDefault from "@/assets/avatar.png";
 import {
   UserType,
   changePassword,
@@ -137,8 +137,6 @@ const showBack = computed(() => {
       display: none;
     }
 
-
-
     * {
       pointer-events: all;
     }

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

@@ -136,6 +136,7 @@
     @update:visible="inputPoint = null"
     :value="inputPoint?.name || ''"
     :update-value="updatePointName"
+    is-allow-empty
     title="测点说明"
     placeholder="请填写测点说明"
   />

+ 39 - 13
src/view/organization-add.vue

@@ -10,7 +10,7 @@
   "userName": "" -->
   <el-form label-width="100px" :model="data" :rules="rules" ref="baseFormRef">
     <el-form-item label="单位名称" prop="orgName" required>
-      <el-input v-model="data.orgName" style="width: 300px" :maxlength="500" placeholder="请输入" />
+      <el-input v-model="data.orgName" style="width: 300px" :maxlength="50" placeholder="请输入" />
     </el-form-item>
     <el-form-item label="类型" prop="type" required>
       <!-- <el-input v-model="data.type" style="width: 300px" :maxlength="500" placeholder="请输入" /> -->
@@ -18,11 +18,19 @@
         <el-option :value="Number(key)" :label="type" v-for="(type, key) in OrganizationTypeDesc" />
       </el-select>
     </el-form-item>
+
+    <el-form-item label="上级单位" prop="parentId">
+      <el-tree-select :props="{
+        value: 'orgId',
+        label: (data: any) => data.orgName,
+      }" style="width: 300px" v-model="data.parentId" :data="allOrgs" node-key="orgId" clearable>
+      </el-tree-select>
+    </el-form-item>
     <el-form-item label="联系人" prop="contact" required>
-      <el-input v-model="data.contact" style="width: 300px" :maxlength="500" placeholder="请输入" />
+      <el-input v-model="data.contact" style="width: 300px" :maxlength="50" placeholder="请输入" />
     </el-form-item>
     <el-form-item label="账号" prop="userName" required>
-      <el-input v-model="data.userName" style="width: 300px" :maxlength="11"  placeholder="请输入手机号" />
+      <el-input v-model="data.userName" style="width: 300px" :maxlength="11" placeholder="请输入手机号" />
     </el-form-item>
     <el-form-item label="密码" prop="password" required>
       <el-input autocomplete="off" readonly onfocus="this.removeAttribute('readonly');" v-model="data.password"
@@ -51,13 +59,24 @@ import type { FormInstance, FormRules } from "element-plus";
 import type { OrganizationType } from '@/request/organization'
 import { OrganizationTypeDesc } from '@/store/organization'
 
-import { ref, reactive, unref, watch } from "vue";
+import { ref, reactive, unref, watch, onMounted } from "vue";
 import { View, Hide } from '@element-plus/icons-vue';
-import { user } from '@/store/user'
+// import { user } from '@/store/user'
+import {
+  getOrgListFetchList,
+
+} from "@/request";
 
 const addPassFlag = ref(true)//图标显示标识
 
+type SelectType = {
+  orgName: string,
+  orgId: number
+  children: SelectType[]
+}
+
 const baseFormRef = ref<FormInstance>();
+const allOrgs = ref<SelectType[]>([]);
 
 const rules = reactive<FormRules>({
   orgName: [
@@ -87,18 +106,24 @@ const data = ref<OrganizationType & {}>({
   orderNum: 0,
   orgId: 0,
   orgName: "",
-  parentId: 0,
+  parentId: null,
   password: "",
   type: null,
   userName: ""
 });
 
-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)
-  }
-}
+// const setParentId = () => {
+//   if (user.value) {
+//     const isSuper = user.value.roles.filter(item => item.roleKey === "super_admin").length > 0;
+//     data.value.parentId = isSuper ? 0 : Number(data.value.parentId)
+//   }
+// }
+
+onMounted(async () => {
+  const data = await getOrgListFetchList()
+  // console.log('allOrgs', data);
+  allOrgs.value = data as any as SelectType[]
+})
 watch(data, (newValue) => {
   data.value.userName = newValue.userName.replace(/[^0-9]/g, '');
 }, {
@@ -110,9 +135,10 @@ defineExpose<QuiskExpose>({
   async submit() {
 
     if (unref(baseFormRef)) {
-      setParentId();
+      // setParentId();
       const res = await unref(baseFormRef)?.validate();
       if (res) {
+        console.log('data', data.value)
         await props.submit(data.value as any as OrganizationType);
       }
     } else {

+ 1 - 1
src/view/organization-edit.vue

@@ -2,7 +2,7 @@
 
   <el-form label-width="100px" :model="data" :rules="rules" ref="baseFormRef">
     <el-form-item label="单位名称" prop="orgName" required>
-      <el-input v-model="data.orgName" style="width: 300px" :maxlength="500" placeholder="请输入" />
+      <el-input v-model="data.orgName" style="width: 300px" :maxlength="50" placeholder="请输入" />
     </el-form-item>
     <el-form-item label="类型" prop="type" required>
       <!-- <el-input v-model="data.type" style="width: 300px" :maxlength="500" placeholder="请输入" /> -->

+ 15 - 57
src/view/scene.vue

@@ -4,50 +4,23 @@
       <div class="search">
         <el-form label-width="100px" inline>
           <el-form-item label="场景标题:">
-            <el-input
-              clearable
-              v-model="pageProps.sceneName"
-              style="width: 250px"
-              placeholder="请输入"
-            />
+            <el-input clearable v-model="pageProps.sceneName" style="width: 250px" placeholder="请输入" />
           </el-form-item>
           <el-form-item label="场景码:">
-            <el-input
-              clearable
-              v-model="pageProps.sceneCode"
-              style="width: 250px"
-              placeholder="请输入"
-            />
+            <el-input clearable v-model="pageProps.sceneCode" style="width: 250px" placeholder="请输入" />
           </el-form-item>
           <template v-if="!simple">
             <el-form-item label="SN码:">
-              <el-input
-                clearable
-                v-model="pageProps.snCode"
-                style="width: 250px"
-                placeholder="请输入"
-              />
+              <el-input clearable v-model="pageProps.snCode" style="width: 250px" placeholder="请输入" />
             </el-form-item>
             <el-form-item label="设备类型:">
               <el-select style="width: 250px" v-model="pageProps.cameraType" clearable>
-                <el-option
-                  :value="Number(key)"
-                  :label="type"
-                  v-for="(type, key) in DeviceTypeDesc"
-                />
+                <el-option :value="Number(key)" :label="type" v-for="(type, key) in DeviceTypeDesc" />
               </el-select>
             </el-form-item>
             <el-form-item label="拍摄时间:">
-              <el-date-picker
-                clearable
-                type="daterange"
-                v-model="pageProps.shootTime"
-                start-placeholder="请选择"
-                end-placeholder="请选择"
-                range-separator="-"
-                placeholder="请选择"
-                style="width: 250px"
-              />
+              <el-date-picker clearable type="daterange" v-model="pageProps.shootTime" start-placeholder="请选择"
+                end-placeholder="请选择" range-separator="-" placeholder="请选择" style="width: 250px" />
             </el-form-item>
             <!-- <el-form-item label="绑定账号:">
               <el-input
@@ -69,13 +42,8 @@
     </div>
 
     <div class="relics-content">
-      <el-table
-        :data="sceneArray"
-        border
-        row-key="'sceneCode'"
-        @selection-change="handleTableSelect"
-        :ref="(d) => {tableProps && ((tableProps as any).tableRef.value = d)}"
-      >
+      <el-table :data="sceneArray" border row-key="'sceneCode'" @selection-change="handleTableSelect"
+        :ref="(d) => { tableProps && ((tableProps as any).tableRef.value = d) }">
         <slot name="table"></slot>
         <el-table-column label="场景标题" v-slot:default="{ row }">
           <a class="link" @click="gotoScene(row, false)">
@@ -108,7 +76,8 @@
           <TexToolTip :text="row.shootCount || '-'" />
         </el-table-column>
         <el-table-column label="拍摄位置" v-slot:default="{ row }">
-          <TexToolTip :text="row.gpsInfo" />
+          <TexToolTip v-if="row.gpsInfo" :text="row.gpsInfo" />
+          <span v-else>-</span>
         </el-table-column>
 
         <el-table-column label="状态" v-slot:default="{ row }">
@@ -123,13 +92,8 @@
             <el-button link type="primary" size="small" @click="gotoScene(row, true)">
               编辑
             </el-button>
-            <el-button
-              link
-              type="danger"
-              @click="delHandler(row.sceneId)"
-              size="small"
-              v-if="row.calcStatus !== SceneStatus.RUN"
-            >
+            <el-button link type="danger" @click="delHandler(row.sceneId)" size="small"
+              v-if="row.calcStatus !== SceneStatus.RUN">
               删除
             </el-button>
           </template>
@@ -137,15 +101,9 @@
       </el-table>
     </div>
     <div class="pag-layout">
-      <el-pagination
-        background
-        layout="total, prev, pager, next, sizes, jumper"
-        v-model:page-size="pageProps.pageSize"
-        :page-sizes="[10, 20, 50, 100]"
-        :total="total"
-        @current-change="(data: number) => pageProps.pageNum = data"
-        :current-page="pageProps.pageNum"
-      />
+      <el-pagination background layout="total, prev, pager, next, sizes, jumper" v-model:page-size="pageProps.pageSize"
+        :page-sizes="[10, 20, 50, 100]" :total="total" @current-change="(data: number) => pageProps.pageNum = data"
+        :current-page="pageProps.pageNum" />
     </div>
   </div>
 </template>

+ 21 - 19
src/view/users-edit.vue

@@ -4,9 +4,12 @@
     <el-form-item label="单位名称" prop="orgId" required>
       <!-- <el-autocomplete style="width: 300px" v-model="data.orgName" :fetch-suggestions="querySearch" clearable
         class="inline-input w-50" placeholder="请输入" @select="handleSelect" /> -->
-      <el-select style="width: 300px" v-model="data.orgId" clearable @change="handleSelect">
-        <el-option :value="Number(id)" :label="value" v-for="{ value, id } in allOrgs" />
-      </el-select>
+      <el-tree-select :props="{
+        value: 'orgId',
+        label: (data: any) => data.orgName,
+      }" style="width: 300px" v-model="data.orgId" :data="allOrgs" node-key="orgId" @node-click="handleNodeClick" clearable>
+
+      </el-tree-select>
     </el-form-item>
 
     <el-form-item label="姓名" prop="nickName" required>
@@ -21,7 +24,8 @@ import { ElMessage, type FormInstance, type FormRules } from "element-plus";
 // import { ElMessage } from "element-plus";
 import type { OrganizationType } from '@/request/organization'
 import {
-  getOrgListFetch,
+  // getOrgListFetch,
+  getOrgListFetchList,
   UserType
 } from "@/request";
 
@@ -31,7 +35,9 @@ import { ref, reactive, unref, onMounted, watchEffect } from "vue";
 const baseFormRef = ref<FormInstance>();
 
 type SelectType = {
-  value: string, id: number
+  orgName: string,
+  orgId: number
+  children: SelectType[]
 }
 
 const allOrgs = ref<SelectType[]>([]);
@@ -60,15 +66,10 @@ const data = ref<Partial<OrganizationType> & Partial<UserType>>({
 });
 
 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 data = await getOrgListFetchList()
+  console.log('list', data)
+  allOrgs.value = data as any as SelectType[]
 
 })
 
@@ -83,12 +84,13 @@ watchEffect(() => {
     data.value = { ...props.user }
   }
 })
-const handleSelect = (orgId: number) => {
-  const item = Array.from(allOrgs.value).find(i => i.id === orgId)
-  if (item) {
-    data.value.orgName = item.value
-  }
+
+const handleNodeClick = (node: SelectType) => {
+  data.value.orgId = node.orgId
+  data.value.orgName = node.orgName
+  console.log('handleNodeClick', node.orgId, node.orgName)
 }
+
 defineExpose<QuiskExpose>({
   async submit() {
     if (unref(baseFormRef)) {

+ 4 - 1
src/view/users.vue

@@ -45,7 +45,7 @@
             <el-button link type="primary" @click="editHandler(row)" size="small">
               编辑
             </el-button>
-            <el-button link type="danger" @click="delHandler(row)" size="small" v-if="isSuper">
+            <el-button link type="danger" @click="delHandler(row)" size="small" v-if="isSuper && !isMe(row.userId)">
               删除
             </el-button>
           </template>
@@ -78,6 +78,9 @@ import { debounce } from "@/util";
 import { user } from "@/store/user";
 
 const isSuper = computed(() => user.value.roles.filter(item => item.roleKey === "super_admin").length > 0)
+const isMe = computed(() => (id: any) => {
+  return id === user.value.userId
+})
 console.log('isSuper', isSuper)
 const initProps: PageProps<Partial<Pick<UserType, "userName" | "orgName">>> = {
   pageNum: 1,