فهرست منبع

feat(1.8.0): update

gemercheung 1 سال پیش
والد
کامیت
2905c3ce49
8فایلهای تغییر یافته به همراه255 افزوده شده و 16 حذف شده
  1. 2 0
      src/request/URL.ts
  2. 7 2
      src/request/index.ts
  3. 4 2
      src/request/organization.ts
  4. 9 0
      src/request/type.ts
  5. 17 1
      src/request/users.ts
  6. 33 10
      src/view/layout/nav.vue
  7. 9 1
      src/view/quisk.ts
  8. 174 0
      src/view/users-password-edit.vue

+ 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
+    });
+
+

+ 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;
   }
 }

+ 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,
+});
+
+

+ 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>