gemercheung 9 місяців тому
батько
коміт
4368bc2796

+ 1 - 1
.env

@@ -1,5 +1,5 @@
 VITE_QJ_URL=https://test.4dkankan.com/panorama
 VITE_LASER_URL=https://uat-laser.4dkankan.com/4pc
-VITE_API=https://uat-sp.4dkankan.com/
+VITE_API=http://192.168.9.27/
 VITE_4DKK_URL=https://test.4dkankan.com
 

+ 1 - 1
.env.development

@@ -1,4 +1,4 @@
 VITE_QJ_URL=https://test.4dkankan.com/panorama
 VITE_LASER_URL=https://uat-laser.4dkankan.com/4pc
-VITE_API=https://uat-sp.4dkankan.com/api
+VITE_API=http://192.168.9.27/
 VITE_4DKK_URL=https://test.4dkankan.com

+ 2 - 2
.env.production

@@ -1,4 +1,4 @@
 VITE_QJ_URL=https://4dkankan.com/panorama
-VITE_LASER_URL=http://192.168.9.27/laser
+VITE_LASER_URL=/4pc
 VITE_API=http://192.168.9.27/
-VITE_4DKK_URL=http://192.168.9.27/swkk
+VITE_4DKK_URL=/swkk

+ 1 - 0
src/request/users.ts

@@ -23,6 +23,7 @@ export type UserType = {
     msgAuthCode?: string
     password?: string
     phoneNum?: string
+    type?: number
 }
 
 

+ 6 - 0
src/router.ts

@@ -112,6 +112,12 @@ const routes: RouteRecordRaw[] = [
         meta: { title: "用户管理", svgIcon: 'yhgl' },
         component: () => import("@/view/users.vue"),
       },
+      {
+        path: "platform-users",
+        name: "platform-users",
+        meta: { title: "平台用户", svgIcon: 'yhgl' },
+        component: () => import("@/view/platform-users/users.vue"),
+      },
     ],
   },
   {

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

@@ -16,7 +16,7 @@
         </span>
       </span>
       <div class="right-panel" v-if="user && !['pano', 'map'].includes(name)">
-        <a
+        <!-- <a
           target="_blank"
           class="helper"
           href="https://showdoc.4dage.com/web/#/179?page_id=1007"
@@ -25,7 +25,7 @@
             <QuestionFilled />
           </el-icon>
           帮助
-        </a>
+        </a> -->
         <el-dropdown placement="bottom-start" class="avatar" v-if="user">
           <span class="avatar-left-label">
             <el-avatar class="avatar" :src="user.head || avatarDefault" />
@@ -135,6 +135,7 @@ const showBack = computed(() => {
   &.relics,
   &.device,
   &.organization,
+  &.platform-users,
   &.users {
     .content {
       .view {

+ 6 - 4
src/view/layout/slide/index.vue

@@ -30,19 +30,21 @@ const isSuper = computed(
 );
 const normal_name = [
   "scene",
-  "relics",
-  "device",
+  // "relics",
+  // "device",
   "organization",
   "users",
   "no-persession",
+  "platform-users",
 ];
 const super_names = [
   "scene",
-  "relics",
-  "device",
+  // "relics",
+  // "device",
   "organization",
   "users",
   "no-persession",
+  "platform-users",
 ];
 console.log("isSuper", isSuper.value);
 

+ 18 - 0
src/view/platform-users/quisk.ts

@@ -0,0 +1,18 @@
+import { quiskMountFactory } from "@/helper/mount";
+
+import UsersAdd from "./users-add.vue";
+import UsersEdit from "./users-edit.vue";
+import UsersPasswordEdit from "./users-password-edit.vue";
+
+export const usersAdd = quiskMountFactory(UsersAdd, {
+  title: "创建用户",
+  width: 520,
+});
+export const usersEdit = quiskMountFactory(UsersEdit, {
+  title: "编辑用户",
+  width: 520,
+});
+export const usersPasswordEdit = quiskMountFactory(UsersPasswordEdit, {
+  title: "修改密码",
+  width: 520,
+});

+ 163 - 0
src/view/platform-users/users-add.vue

@@ -0,0 +1,163 @@
+<template>
+  <el-form label-width="100px" :model="data" :rules="rules" ref="baseFormRef">
+    <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
+        :check-strictly="true"
+        :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>
+
+    <el-form-item label="姓名" prop="nickName" required>
+      <el-input
+        v-model="data.nickName"
+        style="width: 300px"
+        :maxlength="15"
+        placeholder="请输入"
+      />
+    </el-form-item>
+    <el-form-item label="账号" prop="userName" required>
+      <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"
+        :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 { ElMessage } from "element-plus";
+import type { OrganizationType } from "@/request/organization";
+import { getOrgListFetchList, UserType } from "@/request";
+
+import { ref, reactive, unref, onMounted, watch } from "vue";
+import { View, Hide } from "@element-plus/icons-vue";
+// import { user } from '@/store/user'
+
+const addPassFlag = ref(true); //图标显示标识
+
+const baseFormRef = ref<FormInstance>();
+
+type SelectType = {
+  orgName: string;
+  orgId: number;
+  children: SelectType[];
+};
+
+const allOrgs = ref<SelectType[]>([]);
+
+const rules = reactive<FormRules>({
+  orgId: [{ required: true, message: "请选择单位名称", trigger: "select" }],
+  nickName: [{ 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" },
+  ],
+});
+
+const props = defineProps<{
+  submit: (data: OrganizationType) => Promise<any>;
+}>();
+const data = ref<Partial<OrganizationType> & Partial<UserType>>({
+  nickName: "",
+  orgId: undefined,
+  password: "",
+  status: 0,
+  // userId: 0,
+  userName: "",
+  type: 1,
+});
+watch(
+  data,
+  (newValue) => {
+    // data.value.userName = newValue.userName.replace(/[^A-Za-z0-9]/g, '');
+    data.value.userName = newValue.userName.replace(/[^0-9]/g, "");
+  },
+  {
+    immediate: true,
+    deep: true,
+  }
+);
+onMounted(async () => {
+  const data = await getOrgListFetchList();
+
+  // 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'] }
+  //   return i
+  // });
+});
+
+const handleNodeClick = (node: SelectType) => {
+  data.value.orgId = node.orgId;
+  console.log("handleNodeClick", node.orgId, data.value);
+};
+
+defineExpose<QuiskExpose>({
+  async submit() {
+    if (unref(baseFormRef)) {
+      const res = await unref(baseFormRef)?.validate();
+      if (res) {
+        await props.submit(data.value as any as OrganizationType);
+        ElMessage.success("新增成功!");
+      }
+    } else {
+      throw "";
+    }
+  },
+});
+</script>

+ 108 - 0
src/view/platform-users/users-edit.vue

@@ -0,0 +1,108 @@
+<template>
+
+  <el-form label-width="100px" :model="data" :rules="rules" ref="baseFormRef">
+    <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   :check-strictly="true" :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>
+      <el-input v-model="data.nickName" style="width: 300px" :maxlength="15" placeholder="请输入" />
+    </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 { ElMessage } from "element-plus";
+import type { OrganizationType } from '@/request/organization'
+import {
+  // getOrgListFetch,
+  getOrgListFetchList,
+  UserType
+} from "@/request";
+
+import { ref, reactive, unref, onMounted, watchEffect } from "vue";
+
+
+const baseFormRef = ref<FormInstance>();
+
+type SelectType = {
+  orgName: string,
+  orgId: number
+  children: SelectType[]
+}
+
+const allOrgs = ref<SelectType[]>([]);
+
+const rules = reactive<FormRules>({
+  orgId: [
+    { required: true, message: "请选择单位名称", trigger: "select" },
+  ],
+  nickName: [
+    { required: true, message: "请输入姓名", trigger: "blur" },
+    // { required: true, pattern: /^1[3456789]\d{9}$/, message: "请输入正确手机号", trigger: "blur" },
+  ],
+},)
+
+const props = defineProps<{
+  user: UserType,
+  submit: (data: UserType) => Promise<any>;
+}>();
+const data = ref<Partial<OrganizationType> & Partial<UserType>>({
+  nickName: "",
+  orgId: undefined,
+  password: "",
+  status: 0,
+  // userId: 0,
+  userName: "",
+  type:1
+});
+
+onMounted(async () => {
+
+  const data = await getOrgListFetchList()
+  console.log('list', data)
+  allOrgs.value = data as any as SelectType[]
+
+})
+
+// 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 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)) {
+      const res = await unref(baseFormRef)?.validate();
+      if (res) {
+        await props.submit(data.value as any as UserType);
+        ElMessage.success('编辑成功!');
+      }
+    } else {
+      throw "";
+    }
+  },
+});
+</script>

+ 194 - 0
src/view/platform-users/users-password-edit.vue

@@ -0,0 +1,194 @@
+<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 :loading="checkCodeBtn.loading" :disabled="checkCodeBtn.disabled" type="danger"
+        style="margin-left: 10px" @click="getCheckCode"> {{ checkCodeBtn.text }}</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="40"
+        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 {
+  getMsgAuthCode,
+  UserType,
+  ChangePasswordParam
+} from "@/request";
+
+import { ref, reactive, unref, onMounted, watchEffect } from "vue";
+import { onUnmounted } from "vue";
+const addPassFlag = ref(false)//图标显示标识
+import { globalPasswordRex } from "@/util/regex";
+const baseFormRef = ref<FormInstance>();
+
+const props = defineProps<{
+  user: UserType,
+  submit: (data: ChangePasswordParam) => 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 equalToPassword = (_, value: any, callback: any) => {
+  if (data.value.password !== value) {
+    callback(new Error("两次输入的密码不一致"));
+  } else {
+    callback();
+  }
+};
+
+const rules = reactive<FormRules>({
+
+
+  userName: [
+    { required: true, message: "请输入账号", trigger: "blur" },
+  ],
+  msgAuthCode: [
+    { required: true, message: "请输入验证码", trigger: "change" },
+  ],
+
+  password: [
+    { required: true, pattern: globalPasswordRex, message: "请输入8-16位数字、字母大小写组合", trigger: "blur" },
+    { required: true, min: 8, message: '密码太短!', trigger: "blur" },
+  ],
+  confirmPwd: [
+    { required: true, pattern: globalPasswordRex, message: "请输入8-16位数字、字母大小写组合", trigger: "blur" },
+    { required: true, min: 8, message: '密码太短!', trigger: "blur" },
+    { required: true, validator: equalToPassword, trigger: "blur" }
+  ]
+},)
+
+
+let checkCodeBtn = reactive<any>({
+  text: '获取验证码',
+  loading: false,
+  disabled: false,
+  duration: 60,
+  timer: null
+})
+
+onMounted(async () => {
+})
+onUnmounted(() => {
+  // 清除掉定时器
+  checkCodeBtn.timer && clearInterval(checkCodeBtn.timer)
+})
+
+
+
+watchEffect(() => {
+  if (props.user) {
+    data.value = { ...props.user }
+    console.log('data', data)
+  }
+})
+const getCheckCode = async () => {
+  // 倒计时期间按钮不能单击
+  const phoneNum = data.value.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 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>

+ 221 - 0
src/view/platform-users/users.vue

@@ -0,0 +1,221 @@
+<template>
+  <div class="relics-layout">
+    <div class="relics-header">
+      <div class="search">
+        <el-form label-width="100px" inline>
+          <el-form-item label="用户账号">
+            <el-input
+              v-model="pageProps.userName"
+              clearable
+              style="width: 250px"
+              placeholder="请输入"
+            />
+          </el-form-item>
+          <el-form-item label="所属单位">
+            <el-input
+              v-model="pageProps.orgName"
+              clearable
+              style="width: 250px"
+              placeholder="请输入"
+            />
+          </el-form-item>
+
+          <el-form-item>
+            <el-button type="primary" @click="refresh">查询</el-button>
+            <el-button
+              type="primary"
+              plain
+              @click="pageProps = { ...initProps }"
+            >
+              重置
+            </el-button>
+            <el-button type="primary" @click="addHandler"> 创建用户 </el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </div>
+
+    <div class="relics-content">
+      <el-table :data="relicsArray" border>
+        <el-table-column label="姓名" prop="nickName"></el-table-column>
+        <el-table-column label="账号" prop="userName"></el-table-column>
+        <!-- <el-table-column label="账号" prop="userName" v-slot:default="{ row }: { row: Device }">
+          {{ DeviceTypeDesc[row.cameraType] }}
+        </el-table-column> -->
+
+        <el-table-column label="所属单位" prop="orgName"> </el-table-column>
+        <el-table-column label="角色" prop="roleNames"> </el-table-column>
+        <el-table-column label="创建人" prop="createBy"> </el-table-column>
+        <el-table-column
+          label="创建时间"
+          prop="createTime"
+          v-slot:default="{ row }"
+        >
+          {{ row.createTime && row.createTime.substr(0, 16) }}
+        </el-table-column>
+        <el-table-column
+          align="center"
+          label="状态"
+          prop="status"
+          v-slot:default="{ row }"
+        >
+          <el-switch
+            inline-prompt
+            width="60"
+            v-model="row.status"
+            :before-change="() => beforeChangeStatus(row)"
+            :active-value="1"
+            :inactive-value="0"
+            active-text="启用"
+            inactive-text="禁用"
+            style="--el-switch-on-color: #13ce66"
+          />
+        </el-table-column>
+        <el-table-column label="操作" width="100px" fixed="right">
+          <template #default="{ row }">
+            <el-button
+              link
+              type="primary"
+              @click="editHandler(row)"
+              size="small"
+            >
+              编辑
+            </el-button>
+            <el-button
+              link
+              type="danger"
+              @click="delHandler(row)"
+              size="small"
+              v-if="!isMe(row.userId)"
+            >
+              删除
+            </el-button>
+          </template>
+        </el-table-column>
+      </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"
+      />
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { onActivated, ref, watch, computed } from "vue";
+import {
+  getUserpageFetch,
+  addUserFetch,
+  delUserFetch,
+  updateUserStatusFetch,
+  editUserFetch,
+  PageProps,
+  UserType,
+} from "@/request";
+import { usersAdd, usersEdit } from "./quisk";
+import { openLoading, closeLoading } from "@/helper/loading";
+import { ElMessageBox } from "element-plus";
+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,
+  pageSize: 10,
+  userName: "",
+  orgName: "",
+};
+
+const pageProps = ref({ ...initProps });
+const total = ref<number>(0);
+const relicsArray = ref<UserType[]>([]);
+
+const refresh = debounce(async () => {
+  const data = await getUserpageFetch({ ...pageProps.value, type: 1 });
+  total.value = data.total;
+  relicsArray.value = data.records;
+});
+const addHandler = async () => {
+  await usersAdd({ submit: addUserFetch });
+  await refresh();
+};
+const editHandler = async (row: UserType) => {
+  await usersEdit({ user: row, submit: editUserFetch });
+  await refresh();
+};
+const delHandler = async (row: UserType) => {
+  const ok = await ElMessageBox.confirm("确定要删除吗", {
+    type: "warning",
+  });
+  if (ok) {
+    await delUserFetch({
+      userId: row.userId,
+    });
+    await refresh();
+  }
+};
+
+const beforeChangeStatus = (row: UserType): Promise<boolean> => {
+  openLoading();
+  return new Promise(async (resolve, reject) => {
+    try {
+      const anti = !row.status;
+      console.log("anti", anti);
+      await updateUserStatusFetch({
+        userId: row.userId,
+        status: Number(anti),
+      });
+      resolve(true);
+    } catch (error) {
+      reject(false);
+    }
+
+    closeLoading();
+  });
+};
+watch(pageProps, refresh, { deep: true, immediate: true });
+onActivated(refresh);
+</script>
+
+<style scoped lang="scss">
+.relics-layout {
+  height: 100%;
+  overflow-y: auto;
+  padding: 30px;
+}
+
+.pag-layout {
+  margin-top: 20px;
+  display: flex;
+  justify-content: center;
+}
+
+.relics-header {
+  display: flex;
+  align-items: center;
+  margin-bottom: 20px;
+
+  .search {
+    flex: 1;
+  }
+
+  .relics-oper {
+    flex: 0 0 100px;
+    text-align: right;
+  }
+}
+</style>

+ 2 - 1
src/view/users-add.vue

@@ -92,7 +92,8 @@ const data = ref<Partial<OrganizationType> & Partial<UserType>>({
   password: "",
   status: 0,
   // userId: 0,
-  userName: ""
+  userName: "",
+  type: 0,
 });
 watch(data, (newValue) => {
   // data.value.userName = newValue.userName.replace(/[^A-Za-z0-9]/g, '');

+ 40 - 32
src/view/users-edit.vue

@@ -1,19 +1,31 @@
 <template>
-
   <el-form label-width="100px" :model="data" :rules="rules" ref="baseFormRef">
     <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   :check-strictly="true" :props="{
+      <el-tree-select
+        :check-strictly="true"
+        :props="{
         value: 'orgId',
         label: (data: any) => data.orgName,
-      }" style="width: 300px" v-model="data.orgId" :data="allOrgs" node-key="orgId" @node-click="handleNodeClick" clearable>
-
+      }"
+        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>
-      <el-input v-model="data.nickName" style="width: 300px" :maxlength="15" placeholder="请输入" />
+      <el-input
+        v-model="data.nickName"
+        style="width: 300px"
+        :maxlength="15"
+        placeholder="请输入"
+      />
     </el-form-item>
   </el-form>
 </template>
@@ -22,38 +34,35 @@
 import { QuiskExpose } from "@/helper/mount";
 import { ElMessage, type FormInstance, type FormRules } from "element-plus";
 // import { ElMessage } from "element-plus";
-import type { OrganizationType } from '@/request/organization'
+import type { OrganizationType } from "@/request/organization";
 import {
   // getOrgListFetch,
   getOrgListFetchList,
-  UserType
+  UserType,
 } from "@/request";
 
 import { ref, reactive, unref, onMounted, watchEffect } from "vue";
 
-
 const baseFormRef = ref<FormInstance>();
 
 type SelectType = {
-  orgName: string,
-  orgId: number
-  children: SelectType[]
-}
+  orgName: string;
+  orgId: number;
+  children: SelectType[];
+};
 
 const allOrgs = ref<SelectType[]>([]);
 
 const rules = reactive<FormRules>({
-  orgId: [
-    { required: true, message: "请选择单位名称", trigger: "select" },
-  ],
+  orgId: [{ required: true, message: "请选择单位名称", trigger: "select" }],
   nickName: [
     { required: true, message: "请输入姓名", trigger: "blur" },
     // { required: true, pattern: /^1[3456789]\d{9}$/, message: "请输入正确手机号", trigger: "blur" },
   ],
-},)
+});
 
 const props = defineProps<{
-  user: UserType,
+  user: UserType;
   submit: (data: UserType) => Promise<any>;
 }>();
 const data = ref<Partial<OrganizationType> & Partial<UserType>>({
@@ -62,16 +71,15 @@ const data = ref<Partial<OrganizationType> & Partial<UserType>>({
   password: "",
   status: 0,
   // userId: 0,
-  userName: ""
+  userName: "",
+  type: 0,
 });
 
 onMounted(async () => {
-
-  const data = await getOrgListFetchList()
-  console.log('list', data)
-  allOrgs.value = data as any as SelectType[]
-
-})
+  const data = await getOrgListFetchList();
+  console.log("list", data);
+  allOrgs.value = data as any as SelectType[];
+});
 
 // const setParentId = () => {
 //   if (user.value) {
@@ -81,15 +89,15 @@ onMounted(async () => {
 // }
 watchEffect(() => {
   if (props.user) {
-    data.value = { ...props.user }
+    data.value = { ...props.user };
   }
-})
+});
 
 const handleNodeClick = (node: SelectType) => {
-  data.value.orgId = node.orgId
-  data.value.orgName = node.orgName
-  console.log('handleNodeClick', node.orgId, node.orgName)
-}
+  data.value.orgId = node.orgId;
+  data.value.orgName = node.orgName;
+  console.log("handleNodeClick", node.orgId, node.orgName);
+};
 
 defineExpose<QuiskExpose>({
   async submit() {
@@ -97,11 +105,11 @@ defineExpose<QuiskExpose>({
       const res = await unref(baseFormRef)?.validate();
       if (res) {
         await props.submit(data.value as any as UserType);
-        ElMessage.success('编辑成功!');
+        ElMessage.success("编辑成功!");
       }
     } else {
       throw "";
     }
   },
 });
-</script>
+</script>

+ 1 - 1
src/view/users.vue

@@ -94,7 +94,7 @@ const total = ref<number>(0);
 const relicsArray = ref<UserType[]>([]);
 
 const refresh = debounce(async () => {
-  const data = await getUserpageFetch(pageProps.value);
+  const data = await getUserpageFetch({ ...pageProps.value, type: 0 });
 
   total.value = data.total;
   relicsArray.value = data.records;