浏览代码

Merge branch 'register' into dev

gemercheung 1 年之前
父节点
当前提交
ca558e1b34

+ 4 - 0
src/request/URL.ts

@@ -33,6 +33,8 @@ export const delOrganization = `/relics/org/del`;
 export const getOrganizationDetail = `/relics/org/info/:orgId`;
 export const alterOrganization = `/relics/org/update`;
 
+export const registerOrganization = `/relics/org/register`;
+
 // users
 export const addUser = `/relics/user/addUser`;
 export const changeUserStatus = `/relics/user/changeStatus`;
@@ -45,6 +47,8 @@ export const userScenepage = `/relics/user/page`;
 export const getMsgAuthCode = `/relics/user/getMsgAuthCode`;
 export const changePassword = `/relics/user/changePassword`;
 
+
+
 ///drawing
 
 export const addOrUpdateDrawing = `/relics/relics/drawing/saveOrUpdate`;

+ 13 - 2
src/request/organization.ts

@@ -1,9 +1,10 @@
-import { sendFetch, PageProps } from './index'
+import { sendFetch, PageProps, UserType } from './index'
 import { ResPage, ResResult } from './type'
 import { organizationTypeEnum } from '@/store/organization'
 import * as URL from "./URL";
 import { ElMessage } from "element-plus";
-import { throttle } from "@/util";
+import { throttle, encodePwd } from "@/util";
+
 const error = throttle((msg: string) => ElMessage.error(msg), 2000);
 const success = throttle((msg: string) => ElMessage.success(msg), 2000);
 
@@ -65,3 +66,13 @@ export const getOrgListFetchList = () =>
         method: "post",
         body: JSON.stringify({}),
     });
+
+
+export const registerOrganization = (params: any) => {
+    const password = encodePwd(params.password)
+    return sendFetch<ResResult>(URL.registerOrganization, {
+        method: "post",
+        body: JSON.stringify({ ...params, password, confirmPwd: password }),
+    });
+
+}

+ 3 - 5
src/request/users.ts

@@ -33,7 +33,7 @@ export const getUserpageFetch = (params: any) =>
     });
 
 
-export const addUserFetch = (params: any) =>
+export const addUserFetch = (params: Pick<UserType, 'orgId' | 'userName' | 'nickName' | 'password'>) =>
     sendFetch<ResPage<PageProps<UserType>>>(URL.addUser, {
         method: "post",
         body: JSON.stringify(params),
@@ -83,12 +83,8 @@ export const changePassword = async (params: ChangePasswordParam) => {
         }
     }
 
-
-
 }
 
-
-
 export const getMsgAuthCode = (areaNum: string,
     phoneNum: string) =>
     sendFetch<ResResult>(URL.getMsgAuthCode, {
@@ -103,3 +99,5 @@ export const getMsgAuthCode = (areaNum: string,
 
 
 
+
+

+ 111 - 69
src/view/login.vue

@@ -1,8 +1,5 @@
 <template>
-  <div
-    class="system-layer"
-    :style="{ backgroundImage: `url('/image/Frame 208@2x.png')` }"
-  >
+  <div class="system-layer" :style="{ backgroundImage: `url('/image/Frame 208@2x.png')` }">
     <div class="l-content">
       <div class="login-layer">
         <div class="content">
@@ -30,72 +27,63 @@
               <img class="code" src="/image/pic_camera@2x.png" />
             </div>
           </div>
-          <el-form class="panel login" :model="form" @submit.stop>
-            <h2>欢迎登录</h2>
-            <el-form-item class="panel-form-item">
-              <p class="err-info">{{ verification.phone }}</p>
-              <el-input
-                :maxlength="11"
-                v-model.trim="form.phone"
-                placeholder="手机号"
-                @keydown.enter="submitClick"
-              ></el-input>
-            </el-form-item>
-            <el-form-item class="panel-form-item">
-              <p class="err-info">{{ verification.psw }}</p>
-              <el-input
-                v-model="form.psw"
-                :maxlength="16"
-                placeholder="密码"
-                :type="flag ? 'text' : 'password'"
-                @keydown.enter="submitClick"
-              >
-                <template v-slot:suffix>
-                  <el-icon :size="20" @click="flag = !flag" class="icon-style">
-                    <View v-if="flag" />
-                    <Hide v-else />
-                  </el-icon>
-                </template>
-              </el-input>
-            </el-form-item>
-
-            <el-form-item class="panel-form-item" style="user-select: none">
-              <DragVerify
-                ref="verify"
-                :class="{ passing: isPassing2 }"
-                :isPassing="isPassing2"
-                @passcallback="isPassing2 = true"
-                handlerIcon="el-icon-d-arrow-right"
-                background="#D9D9D9"
-                textColor="#333333"
-                successIcon="el-icon-circle-check"
-                :text="isPassing2 ? '已通过验证' : '登录需要拖拽验证'"
-                successText="验证通过"
-                :width="400"
-              >
-                <template v-slot:handlerIcon>
-                  <el-icon
-                    :size="20"
-                    style="
+          <!-- login right panel -->
+          <template v-if="currentStatus(0)">
+            <el-form class="panel login" :model="form" @submit.stop>
+              <h2>欢迎登录</h2>
+              <el-form-item class="panel-form-item">
+                <p class="err-info">{{ verification.phone }}</p>
+                <el-input :maxlength="11" v-model.trim="form.phone" placeholder="手机号"
+                  @keydown.enter="submitClick"></el-input>
+              </el-form-item>
+              <el-form-item class="panel-form-item">
+                <p class="err-info">{{ verification.psw }}</p>
+                <el-input v-model="form.psw" :maxlength="16" placeholder="密码" :type="flag ? 'text' : 'password'"
+                  @keydown.enter="submitClick">
+                  <template v-slot:suffix>
+                    <el-icon :size="20" @click="flag = !flag" class="icon-style">
+                      <View v-if="flag" />
+                      <Hide v-else />
+                    </el-icon>
+                  </template>
+                </el-input>
+              </el-form-item>
+
+              <el-form-item class="panel-form-item" style="user-select: none">
+                <DragVerify ref="verify" :class="{ passing: isPassing2 }" :isPassing="isPassing2"
+                  @passcallback="isPassing2 = true" handlerIcon="el-icon-d-arrow-right" background="#D9D9D9"
+                  textColor="#333333" successIcon="el-icon-circle-check" :text="isPassing2 ? '已通过验证' : '登录需要拖拽验证'"
+                  successText="验证通过" :width="400">
+                  <template v-slot:handlerIcon>
+                    <el-icon :size="20" style="
                       width: 20px;
                       display: inline-block;
                       line-height: 20px;
                       margin-top: 8px;
-                    "
-                  >
-                    <DArrowRight v-if="!isPassing2" />
-                    <SuccessFilled v-else />
-                  </el-icon>
-                </template>
-              </DragVerify>
-            </el-form-item>
-
-            <el-form-item class="panel-form-item">
-              <el-button type="primary" class="fill submit" @click="submitClick"
-                >登录</el-button
-              >
-            </el-form-item>
-          </el-form>
+                    ">
+                      <DArrowRight v-if="!isPassing2" />
+                      <SuccessFilled v-else />
+                    </el-icon>
+                  </template>
+                </DragVerify>
+              </el-form-item>
+
+              <el-form-item class="panel-form-item">
+                <el-button type="primary" class="fill submit" @click="submitClick">登录</el-button>
+              </el-form-item>
+
+              <div class="register">
+                <span @click="handleForgetPassword"> 忘记密码</span> |
+                <span @click="handleRegister"> 单位注册</span>
+              </div>
+            </el-form>
+          </template>
+          <template v-if="currentStatus(1)">
+            <register @done="goTologin"></register>
+          </template>
+          <template v-if="currentStatus(2)">
+            <reset @done="goTologin"></reset>
+          </template>
         </div>
       </div>
     </div>
@@ -103,14 +91,15 @@
 </template>
 
 <script lang="ts" setup>
-import { reactive, watch, ref } from "vue";
+import { reactive, watch, ref, computed } from "vue";
 import { View, Hide, DArrowRight, SuccessFilled } from "@element-plus/icons-vue";
 import { login } from "@/store/user";
 import { ElMessage } from "element-plus";
 import { router } from "@/router";
 import qrCode from "qrcode";
 import DragVerify from "@/components/drag-verify.vue";
-
+import register from '@/view/register/register.vue'
+import reset from '@/view/register/reset.vue'
 const PHONE = {
   REG: /^1(3|4|5|6|7|8|9)\d{9}$/,
   // REG: /^((13[0-9]|14[01456879]|15[0-3,5-9]|16[2567]|17[0-8]|18[0-9]|19[0-3,5-9])\d{8})|(8){11}$/,
@@ -120,6 +109,9 @@ const PHONE = {
 const flag = ref(false);
 const verify = ref<any>();
 const isPassing2 = ref(false);
+
+const registerStatus = ref(0);
+const currentStatus = computed(() => (status: number) => status === registerStatus.value)
 // 表单
 const form = reactive({
   phone: import.meta.env.DEV ? "13800000001" : "",
@@ -187,6 +179,21 @@ const submitClick = async () => {
   verify.value.reset();
   isPassing2.value = false;
 };
+
+// 忘记密码
+const handleForgetPassword = () => {
+  registerStatus.value = 2
+}
+// 注册
+const handleRegister = () => {
+  registerStatus.value = 1
+}
+// 业务回到login
+const goTologin = () => {
+  registerStatus.value = 0
+}
+
+
 </script>
 
 <style lang="scss" scoped>
@@ -194,6 +201,7 @@ const submitClick = async () => {
   width: 100%;
   height: 100%;
 }
+
 .content {
   display: flex;
   justify-content: center;
@@ -204,6 +212,7 @@ const submitClick = async () => {
   height: 100vh;
   padding: 0 50px 0 50px;
 }
+
 .info {
   color: #000;
   flex: none;
@@ -218,10 +227,12 @@ const submitClick = async () => {
 
   .top {
     margin-top: 50px;
+
     img {
       width: 142px;
     }
   }
+
   .bottom {
     height: 470px;
     display: flex;
@@ -257,13 +268,16 @@ const submitClick = async () => {
           background-size: 100% 100%;
         }
       }
+
       .e-code {
         width: 128px;
         margin-top: 13px;
         position: relative;
-        > img {
+
+        >img {
           width: 100%;
         }
+
         .e-logo {
           position: absolute;
           top: 50%;
@@ -274,6 +288,7 @@ const submitClick = async () => {
           padding: 7px;
           border-radius: 4px;
           text-align: center;
+
           img {
             height: 100%;
             width: 100%;
@@ -281,6 +296,7 @@ const submitClick = async () => {
           }
         }
       }
+
       p:last-child {
         font-weight: 400;
         font-size: 14px;
@@ -291,15 +307,18 @@ const submitClick = async () => {
 
   .center {
     text-align: center;
+
     h1 {
       color: #781c0b;
       font-size: 48px;
       line-height: 3.7rem;
       margin-bottom: 0.7rem;
     }
+
     p {
       width: 100%;
       margin-top: 40px;
+
       img {
         width: 320px;
       }
@@ -312,14 +331,17 @@ const submitClick = async () => {
   pointer-events: none;
   height: 153px;
   min-width: 1200px;
+
   img {
     position: absolute;
     right: 0;
   }
 }
+
 .fill {
   width: 100%;
 }
+
 .login {
   width: 400px;
   // padding: 40px 40px 30px;
@@ -344,6 +366,7 @@ const submitClick = async () => {
   .panel-form-item {
     padding-left: 0;
     padding-right: 0;
+
     .icon-style {
       margin-right: 14px;
       font-size: 20px;
@@ -379,6 +402,7 @@ const submitClick = async () => {
   background: no-repeat left bottom;
   background-size: auto 100%;
 }
+
 .l-content {
   display: flex;
   width: 100%;
@@ -386,6 +410,17 @@ const submitClick = async () => {
   justify-content: center;
   align-items: flex-start;
 }
+
+.register {
+  display: flex;
+  flex-direction: row;
+  flex: 1;
+  justify-content: center;
+
+  span {
+    padding: 0 10px;
+  }
+}
 </style>
 
 <style>
@@ -406,10 +441,12 @@ const submitClick = async () => {
 .login .code-form-item .el-input__inner {
   flex: 1;
 }
+
 .login .code-form-item .el-input-group__append,
 .login .code-form-item .el-input__inner {
   border-radius: 4px;
 }
+
 input[type="password"]::-ms-reveal {
   display: none;
 }
@@ -488,6 +525,7 @@ input[type="password"]::-ms-reveal {
 .panel-form-item .el-form-item__label {
   line-height: 50px;
 }
+
 .e-code img {
   width: 100%;
 }
@@ -503,4 +541,8 @@ input[type="password"]::-ms-reveal {
 .drag_verify {
   border: 1px solid #dcdfe6;
 }
+
+.register span {
+  cursor: pointer;
+}
 </style>

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

@@ -62,13 +62,12 @@ const data = ref<OrganizationType & {}>({
 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.org) {
-    data.value = { ...props.org}
+    data.value = { ...props.org }
   }
 
 })

+ 275 - 0
src/view/register/register.vue

@@ -0,0 +1,275 @@
+<template>
+    <div class="register">
+        <el-form class="panel" :model="form" :rules="rules" ref="baseFormRef">
+            <h2>单位注册</h2>
+            <span class="desc">
+                此功能仅用于注册单位及单位管理员,
+                单位内其它用户可由单位管理员登录后创建。
+            </span>
+            <el-form-item class="panel-form-item" label="单位名称">
+                <el-input :maxlength="11" v-model.trim="form.orgName" placeholder="请输入"></el-input>
+            </el-form-item>
+
+            <el-form-item class="panel-form-item" label="类型" prop="type">
+                <el-select v-model="form.type">
+                    <el-option class="register-select-option" :value="Number(key)" :label="type"
+                        v-for="(type, key) in OrganizationTypeDesc" />
+                </el-select>
+            </el-form-item>
+            <el-form-item class="panel-form-item" label="姓名">
+                <el-input :maxlength="200" v-model.trim="form.contact" placeholder="请选择"></el-input>
+            </el-form-item>
+
+
+            <el-form-item class="panel-form-item" prop="userName" label="账号" required>
+                <el-input :maxlength="11" v-model.trim="form.userName" placeholder="请输入手机号码">
+                </el-input>
+            </el-form-item>
+
+            <el-form-item class="panel-form-item msgcode" prop="msgAuthCode" label="验证码" required>
+                <el-input :maxlength="8" v-model.trim="form.msgAuthCode" placeholder="输入验证码">
+                </el-input>
+                <el-button class="getMsgAuthCode" :loading="checkCodeBtn.loading" :disabled="checkCodeBtn.disabled"
+                    style="margin-left: 10px" @click="getCheckCode"> {{ checkCodeBtn.text }}</el-button>
+            </el-form-item>
+
+            <!-- <el-form-item class="panel-form-item" label="密码" prop="password" required>
+                <el-input v-model.trim="form.password" placeholder="请输入8-16位数字、字母大小写组合">
+                </el-input>
+            </el-form-item> -->
+            <el-form-item class="panel-form-item" label="密码" prop="password" required>
+                <el-input autocomplete="off" readonly onfocus="this.removeAttribute('readonly');"
+                    v-model="form.password" :type="addPassFlag ? 'text' : 'password'" :maxlength="20"
+                    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 class="panel-form-item" label="密码确认" prop="confirmPwd" required>
+                <el-input autocomplete="off" readonly onfocus="this.removeAttribute('readonly');"
+                    v-model="form.confirmPwd" :type="addPassFlag1 ? 'text' : 'password'" :maxlength="20"
+                    placeholder="输入再次输入密码">
+                    <template #suffix>
+                        <span @click="addPassFlag1 = !addPassFlag1" style="cursor: pointer;">
+                            <el-icon v-if="addPassFlag1">
+                                <View />
+                            </el-icon>
+                            <el-icon v-else>
+                                <Hide />
+                            </el-icon>
+                        </span>
+                    </template>
+                </el-input>
+
+            </el-form-item>
+
+            <el-form-item class="panel-form-item">
+                <el-button type="primary" class="fill submit" @click="submitClick">注册</el-button>
+            </el-form-item>
+
+
+        </el-form>
+    </div>
+</template>
+<script lang="ts" setup>
+import { reactive, ref, unref } from 'vue'
+import { ElMessage, type FormInstance, type FormRules } from "element-plus";
+import { OrganizationTypeDesc } from '@/store/organization';
+import { View, Hide } from '@element-plus/icons-vue';
+import { registerOrganization } from '@/request/organization';
+// import { encodePwd } from "@/util";
+import {
+    getMsgAuthCode,
+} from "@/request";
+
+const emit = defineEmits(['done'])
+const baseFormRef = ref<FormInstance>();
+const addPassFlag = ref(false) //图标显示标识
+const addPassFlag1 = ref(false) //图标显示标识
+
+let checkCodeBtn = reactive<any>({
+    text: '获取验证码',
+    loading: false,
+    disabled: false,
+    duration: 60,
+    timer: null
+})
+
+
+
+const equalToPassword = (_, value: any, callback: any) => {
+    if (form.password !== value) {
+        callback(new Error("两次输入的密码不一致"));
+    } else {
+        callback();
+    }
+};
+
+
+const rules = reactive<FormRules>({
+    orgName: [
+        { required: true, message: "请选择单位名称", trigger: "select" },
+    ],
+    msgAuthCode: [
+        { required: true, message: "请输入验证码", trigger: "change" },
+    ],
+    contact: [
+        { required: true, message: "请输入姓名", trigger: "blur" },
+    ],
+    userName: [
+        { required: true, message: "请输入手机号码", trigger: "blur" },
+        { required: true, pattern: /^1[3456789]\d{9}$/, message: "请输入手机号码", trigger: "blur" },
+    ],
+    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" },
+        { required: true, validator: equalToPassword, trigger: "blur" }
+    ],
+},)
+
+
+const form = reactive({
+    orgName: "",
+    type: "",
+    userName: "",
+    password: "",
+    contact: "",
+    confirmPwd: "",
+    msgAuthCode: "",
+});
+
+const getCheckCode = async () => {
+    // 倒计时期间按钮不能单击
+    await unref(baseFormRef)?.validateField('userName');
+
+    const phoneNum = form.userName
+    console.log('getMsgCode', phoneNum)
+    const res = await getMsgAuthCode('+86', phoneNum)
+    if (res.success) {
+        ElMessage.success(res.data);
+    }
+    if (checkCodeBtn.duration == 60) {
+        checkCodeBtn.disabled = true
+    }
+    // 清除掉定时器
+    checkCodeBtn.timer && clearInterval(checkCodeBtn.timer)
+    // 开启定时器
+    checkCodeBtn.timer = setInterval(() => {
+        const tmp = checkCodeBtn.duration--
+        checkCodeBtn.text = `${tmp}秒`
+        if (tmp <= 0) {
+            // 清除掉定时器
+            clearInterval(checkCodeBtn.timer)
+            checkCodeBtn.duration = 60
+            checkCodeBtn.text = '重新获取'
+            // 设置按钮可以单击
+            checkCodeBtn.disabled = false
+        }
+        console.info(checkCodeBtn.duration)
+    }, 1000)
+}
+
+const submitClick = async () => {
+    if (unref(baseFormRef)) {
+        const res = await unref(baseFormRef)?.validate();
+        if (res) {
+            const result = await registerOrganization(form)
+            console.log('result', result)
+            emit('done')
+            // ElMessage.success('新增成功!');
+        }
+    } else {
+        throw "";
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.register {
+    padding: 10px 0;
+
+    .panel {
+        width: 430px;
+    }
+
+    .panel-form-item {
+        padding-left: 0;
+        padding-right: 0;
+    }
+
+    h2 {
+        padding-left: 0;
+        margin-bottom: 0;
+    }
+
+    .desc {
+        color: #93795D;
+        display: block;
+        margin-bottom: 20px;
+    }
+
+    :deep(.panel-form-item .el-form-item__label) {
+        line-height: 40px;
+        font-size: 16px;
+        min-width: 90px;
+    }
+
+    :deep(.el-form-item__error) {
+        font-size: 14px;
+    }
+
+    :deep(.el-select) {
+        width: 100%;
+        height: 42px;
+        line-height: 42px;
+
+        .el-select__wrapper {
+            height: 100%;
+            font-size: 1.14rem;
+        }
+    }
+
+    .msgcode {
+        position: relative;
+    }
+
+    .getMsgAuthCode {
+        border: 1px solid #93795D;
+        background: rgba(147, 121, 93, 0.05);
+        font-size: 14px;
+        position: absolute;
+        right: 5px;
+        top: 5px;
+        height: 32px;
+        line-height: 32px;
+    }
+
+    .fill {
+        width: 100%;
+    }
+
+
+}
+</style>
+<style>
+.register-select-option {
+    font-size: 1.14rem;
+    min-height: 50px;
+    line-height: 50px;
+    /* padding: 5px 0; */
+}
+</style>

+ 257 - 0
src/view/register/reset.vue

@@ -0,0 +1,257 @@
+<template>
+    <div class="register">
+        <el-form class="panel" :model="form" :rules="rules" ref="baseFormRef">
+            <h2>重置密码</h2>
+            <el-form-item class="panel-form-item" prop="userName" label="账号" required>
+                <el-input :maxlength="11" v-model.trim="form.userName" placeholder="请输入手机号码">
+                </el-input>
+            </el-form-item>
+
+            <el-form-item class="panel-form-item msgcode" prop="msgAuthCode" label="验证码" required>
+                <el-input :maxlength="8" v-model.trim="form.msgAuthCode" placeholder="输入验证码">
+                </el-input>
+                <el-button class="getMsgAuthCode" :loading="checkCodeBtn.loading" :disabled="checkCodeBtn.disabled"
+                    style="margin-left: 10px" @click="getCheckCode"> {{ checkCodeBtn.text }}</el-button>
+            </el-form-item>
+
+            <el-form-item class="panel-form-item" label="密码" prop="password" required>
+                <el-input autocomplete="off" readonly onfocus="this.removeAttribute('readonly');"
+                    v-model="form.password" :type="addPassFlag ? 'text' : 'password'" :maxlength="20"
+                    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 class="panel-form-item" label="密码确认" prop="confirmPwd" required>
+                <el-input autocomplete="off" readonly onfocus="this.removeAttribute('readonly');"
+                    v-model="form.confirmPwd" :type="addPassFlag1 ? 'text' : 'password'" :maxlength="20"
+                    placeholder="输入再次输入密码">
+                    <template #suffix>
+                        <span @click="addPassFlag1 = !addPassFlag1" style="cursor: pointer;">
+                            <el-icon v-if="addPassFlag1">
+                                <View />
+                            </el-icon>
+                            <el-icon v-else>
+                                <Hide />
+                            </el-icon>
+                        </span>
+                    </template>
+                </el-input>
+
+            </el-form-item>
+
+            <el-form-item class="panel-form-item">
+                <el-button type="primary" class="fill submit" @click="submitClick">确定</el-button>
+            </el-form-item>
+
+        </el-form>
+    </div>
+</template>
+<script lang="ts" setup>
+import { reactive, ref, unref } from 'vue'
+import {
+    changePassword,
+} from "@/request";
+import { ElMessage, type FormInstance, type FormRules } from "element-plus";
+// import { OrganizationTypeDesc } from '@/store/organization';
+import { View, Hide } from '@element-plus/icons-vue';
+// import { registerOrganization } from '@/request/organization';
+// import { encodePwd } from "@/util";
+
+import {
+    getMsgAuthCode,
+} from "@/request";
+
+const emit =defineEmits(['done'])
+
+const baseFormRef = ref<FormInstance>();
+const addPassFlag = ref(false) //图标显示标识
+const addPassFlag1 = ref(false) //图标显示标识
+
+let checkCodeBtn = reactive<any>({
+    text: '获取验证码',
+    loading: false,
+    disabled: false,
+    duration: 60,
+    timer: null
+})
+
+const equalToPassword = (_, value: any, callback: any) => {
+    if (form.password !== value) {
+        callback(new Error("两次输入的密码不一致"));
+    } else {
+        callback();
+    }
+};
+const rules = reactive<FormRules>({
+    orgName: [
+        { required: true, message: "请选择单位名称", trigger: "select" },
+    ],
+    msgAuthCode: [
+        { required: true, message: "请输入验证码", trigger: "change" },
+    ],
+    contact: [
+        { required: true, message: "请输入姓名", trigger: "blur" },
+    ],
+    userName: [
+        { required: true, message: "请输入手机号码", trigger: "blur" },
+        { required: true, pattern: /^1[3456789]\d{9}$/, message: "请输入手机号码", trigger: "blur" },
+    ],
+    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" },
+        { required: true, validator: equalToPassword, trigger: "blur" }
+    ],
+},)
+
+
+const form = reactive({
+    orgName: "",
+    type: "",
+    userName: "",
+    // userName: "",
+    password: "",
+    contact: "",
+    confirmPwd: "",
+    msgAuthCode: "",
+});
+
+const getCheckCode = async () => {
+    // 倒计时期间按钮不能单击
+    await unref(baseFormRef)?.validateField('userName');
+
+    const phoneNum = form.userName
+    console.log('getMsgCode', phoneNum)
+    const res = await getMsgAuthCode('+86', phoneNum)
+    if (res.success) {
+        ElMessage.success(res.data);
+    }
+    if (checkCodeBtn.duration == 60) {
+        checkCodeBtn.disabled = true
+    }
+    // 清除掉定时器
+    checkCodeBtn.timer && clearInterval(checkCodeBtn.timer)
+    // 开启定时器
+    checkCodeBtn.timer = setInterval(() => {
+        const tmp = checkCodeBtn.duration--
+        checkCodeBtn.text = `${tmp}秒`
+        if (tmp <= 0) {
+            // 清除掉定时器
+            clearInterval(checkCodeBtn.timer)
+            checkCodeBtn.duration = 60
+            checkCodeBtn.text = '重新获取'
+            // 设置按钮可以单击
+            checkCodeBtn.disabled = false
+        }
+        console.info(checkCodeBtn.duration)
+    }, 1000)
+}
+
+const submitClick = async () => {
+    if (unref(baseFormRef)) {
+        const res = await unref(baseFormRef)?.validate();
+        if (res) {
+            console.log('form', form)
+            const result = await changePassword({
+                ...form,
+                phoneNum: form.userName
+            });
+            console.log('result', result)
+            ElMessage.success('重置密码成功!');
+            emit('done')
+        }
+    } else {
+        throw "";
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.register {
+    padding: 10px 0;
+
+    .panel {
+        width: 430px;
+    }
+
+    .panel-form-item {
+        padding-left: 0;
+        padding-right: 0;
+    }
+
+    h2 {
+        padding-left: 0;
+        margin-bottom: 0;
+    }
+
+    .desc {
+        color: #93795D;
+        display: block;
+        margin-bottom: 20px;
+    }
+
+    :deep(.panel-form-item .el-form-item__label) {
+        line-height: 40px;
+        font-size: 16px;
+        min-width: 90px;
+    }
+
+    :deep(.el-form-item__error) {
+        font-size: 14px;
+    }
+
+    :deep(.el-select) {
+        width: 100%;
+        height: 42px;
+        line-height: 42px;
+
+        .el-select__wrapper {
+            height: 100%;
+            font-size: 1.14rem;
+        }
+    }
+
+    .msgcode {
+        position: relative;
+    }
+
+    .getMsgAuthCode {
+        border: 1px solid #93795D;
+        background: rgba(147, 121, 93, 0.05);
+        font-size: 14px;
+        position: absolute;
+        right: 5px;
+        top: 5px;
+        height: 32px;
+        line-height: 32px;
+    }
+
+    .fill {
+        width: 100%;
+    }
+
+
+}
+</style>
+<style>
+.register-select-option {
+    font-size: 1.14rem;
+    min-height: 50px;
+    line-height: 50px;
+    /* padding: 5px 0; */
+}
+</style>

+ 7 - 4
src/view/users-add.vue

@@ -4,8 +4,11 @@
     <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-tree-select style="width: 300px" v-model="data.orgId" :data="allOrgs" node-key="orgName"
-        @node-click="handleNodeClick" clearable>
+      <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-option :value="Number(id)" :label="value" v-for="{ value, id } in allOrgs" /> -->
       </el-tree-select>
     </el-form-item>
@@ -101,7 +104,7 @@ watch(data, (newValue) => {
 onMounted(async () => {
   const data = await getOrgListFetchList()
 
-  console.log('allOrgs', data);
+  // console.log('allOrgs', data);
   allOrgs.value = data as any as SelectType[]
   // allOrgs.value = Array.from(data.records).map((item: OrganizationType) => {
   //   const i: SelectType = { value: item['orgName'], id: item['orgId'] }
@@ -112,7 +115,7 @@ onMounted(async () => {
 
 const handleNodeClick = (node: SelectType) => {
   data.value.orgId = node.orgId
-  // console.log('handleNodeClick', node)
+  console.log('handleNodeClick', node.orgId, data.value)
 }
 
 

+ 1 - 2
src/view/users-password-edit.vue

@@ -28,7 +28,7 @@
     </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"
+        :type="addPassFlag ? 'text' : 'password'" style="width: 300px" :maxlength="40"
         placeholder="请输入8-16位数字、字母大小写组合">
         <template #suffix>
           <span @click="addPassFlag = !addPassFlag" style="cursor: pointer;">
@@ -114,7 +114,6 @@ const rules = reactive<FormRules>({
     { required: true, pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[\s\S]{8,16}$/, message: "请输入8-16位数字、字母大小写组合", trigger: "blur" },
     { required: true, min: 8, message: '密码太短!', trigger: "blur" },
     { required: true, validator: equalToPassword, trigger: "blur" }
-
   ]
 },)