From afa0ffca1673eb61c27496b9988fa8559678bd94 Mon Sep 17 00:00:00 2001
From: chenyc <501753378@qq.com>
Date: 星期二, 23 九月 2025 16:55:15 +0800
Subject: [PATCH] gx用户管理
---
src/assets/logo.png | 0
src/layout/navBars/topBar/user.vue | 2
package-lock.json | 64 +++
src/views/userAdmin/component/addUser.vue | 202 +++++++++++
src/views/userAdmin/index.vue | 179 +++++++++
src/api/register/index.ts | 62 +++
src/i18n/lang/zh-cn.ts | 1
src/router/route.ts | 42 ++
src/views/registerSuu/index.vue | 26 +
package.json | 1
src/views/register/index.vue | 272 +++++++++++++++
.env.production | 2
src/layout/upgrade/index.vue | 1
src/router/index.ts | 3
src/views/personal/index.vue | 2
src/views/userAdmin/component/editUser.vue | 164 +++++++++
16 files changed, 1,018 insertions(+), 5 deletions(-)
diff --git a/.env.production b/.env.production
index 270412d..b58c100 100644
--- a/.env.production
+++ b/.env.production
@@ -2,4 +2,4 @@
ENV = production
# 线上环境接口地址
-VITE_API_URL = 'https://hemobs.icoldchain.cn/'
\ No newline at end of file
+VITE_API_URL = 'https://backend.ihemodialysis.com/'
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 2bd7a23..9adb600 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -36,6 +36,7 @@
"screenfull": "^6.0.2",
"sortablejs": "^1.15.2",
"splitpanes": "^3.1.5",
+ "vant": "^4.9.21",
"vue": "^3.4.21",
"vue-clipboard3": "^2.0.0",
"vue-demi": "^0.14.7",
@@ -1372,6 +1373,21 @@
},
"peerDependencies": {
"@uppy/core": "^2.3.3"
+ }
+ },
+ "node_modules/@vant/popperjs": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/@vant/popperjs/-/popperjs-1.3.0.tgz",
+ "integrity": "sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw==",
+ "license": "MIT"
+ },
+ "node_modules/@vant/use": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmmirror.com/@vant/use/-/use-1.6.0.tgz",
+ "integrity": "sha512-PHHxeAASgiOpSmMjceweIrv2AxDZIkWXyaczksMoWvKV2YAYEhoizRuk/xFnKF+emUIi46TsQ+rvlm/t2BBCfA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "vue": "^3.0.0"
}
},
"node_modules/@vitejs/plugin-vue": {
@@ -4297,6 +4313,26 @@
"base64-arraybuffer": "^1.0.2"
}
},
+ "node_modules/vant": {
+ "version": "4.9.21",
+ "resolved": "https://registry.npmmirror.com/vant/-/vant-4.9.21.tgz",
+ "integrity": "sha512-hXUoZMrLLjykimFRLDlGNd+K2iYSRh9YwLMKnsVdVZ+9inUKxpqnjhOqlZwocbnYkvJlS+febf9u9aJpDol4Pw==",
+ "license": "MIT",
+ "dependencies": {
+ "@vant/popperjs": "^1.3.0",
+ "@vant/use": "^1.6.0",
+ "@vue/shared": "^3.5.17"
+ },
+ "peerDependencies": {
+ "vue": "^3.0.0"
+ }
+ },
+ "node_modules/vant/node_modules/@vue/shared": {
+ "version": "3.5.21",
+ "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.21.tgz",
+ "integrity": "sha512-+2k1EQpnYuVuu3N7atWyG3/xoFWIVJZq4Mz8XNOdScFI0etES75fbny/oU4lKWk/577P1zmg0ioYvpGEDZ3DLw==",
+ "license": "MIT"
+ },
"node_modules/vite": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.1.6.tgz",
@@ -5449,6 +5485,17 @@
"@uppy/utils": "^4.1.2",
"nanoid": "^3.1.25"
}
+ },
+ "@vant/popperjs": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/@vant/popperjs/-/popperjs-1.3.0.tgz",
+ "integrity": "sha512-hB+czUG+aHtjhaEmCJDuXOep0YTZjdlRR+4MSmIFnkCQIxJaXLQdSsR90XWvAI2yvKUI7TCGqR8pQg2RtvkMHw=="
+ },
+ "@vant/use": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmmirror.com/@vant/use/-/use-1.6.0.tgz",
+ "integrity": "sha512-PHHxeAASgiOpSmMjceweIrv2AxDZIkWXyaczksMoWvKV2YAYEhoizRuk/xFnKF+emUIi46TsQ+rvlm/t2BBCfA==",
+ "requires": {}
},
"@vitejs/plugin-vue": {
"version": "5.0.4",
@@ -7611,6 +7658,23 @@
"base64-arraybuffer": "^1.0.2"
}
},
+ "vant": {
+ "version": "4.9.21",
+ "resolved": "https://registry.npmmirror.com/vant/-/vant-4.9.21.tgz",
+ "integrity": "sha512-hXUoZMrLLjykimFRLDlGNd+K2iYSRh9YwLMKnsVdVZ+9inUKxpqnjhOqlZwocbnYkvJlS+febf9u9aJpDol4Pw==",
+ "requires": {
+ "@vant/popperjs": "^1.3.0",
+ "@vant/use": "^1.6.0",
+ "@vue/shared": "^3.5.17"
+ },
+ "dependencies": {
+ "@vue/shared": {
+ "version": "3.5.21",
+ "resolved": "https://registry.npmmirror.com/@vue/shared/-/shared-3.5.21.tgz",
+ "integrity": "sha512-+2k1EQpnYuVuu3N7atWyG3/xoFWIVJZq4Mz8XNOdScFI0etES75fbny/oU4lKWk/577P1zmg0ioYvpGEDZ3DLw=="
+ }
+ }
+ },
"vite": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/vite/-/vite-5.1.6.tgz",
diff --git a/package.json b/package.json
index 16135ba..0ec6829 100644
--- a/package.json
+++ b/package.json
@@ -38,6 +38,7 @@
"screenfull": "^6.0.2",
"sortablejs": "^1.15.2",
"splitpanes": "^3.1.5",
+ "vant": "^4.9.21",
"vue": "^3.4.21",
"vue-clipboard3": "^2.0.0",
"vue-demi": "^0.14.7",
diff --git a/src/api/register/index.ts b/src/api/register/index.ts
new file mode 100644
index 0000000..178abcf
--- /dev/null
+++ b/src/api/register/index.ts
@@ -0,0 +1,62 @@
+import request from "/@/utils/request";
+export function sendValidateCode(params: any) {
+ return request({
+ url: '/user/info/sendValidateCodeForRegister',
+ method: 'post',
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded'
+ },
+ data:params,
+ });
+}
+export function registerForNutrition(params: any) {
+ return request({
+ url: '/user/info/registerForNutrition',
+ method: 'post',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ data: params,
+ });
+}
+export function listForNutrition(params: any) {
+ return request({
+ url: '/user/info/listForNutrition',
+ method: 'post',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ data: params,
+ });
+}
+export function Add(params: string) {
+ return request({
+ url: '/user/info/add',
+ method: 'post',
+ data: params,
+ });
+}
+export function update(params: string) {
+ return request({
+ url: '/user/info/update',
+ method: 'post',
+ data: params,
+ });
+}
+export function deleteId(params: string) {
+ return request({
+ url: '/user/info/delete',
+ method: 'post',
+ headers: {
+ 'Content-Type': 'application/x-www-form-urlencoded'
+ },
+ data: params,
+ });
+}
+export function getClientList(params: object) {
+ return request({
+ url: '/client/info/list',
+ method: 'post',
+ params,
+ });
+}
\ No newline at end of file
diff --git a/src/assets/logo.png b/src/assets/logo.png
new file mode 100644
index 0000000..7e585df
--- /dev/null
+++ b/src/assets/logo.png
Binary files differ
diff --git a/src/i18n/lang/zh-cn.ts b/src/i18n/lang/zh-cn.ts
index 8ce86df..434bb94 100644
--- a/src/i18n/lang/zh-cn.ts
+++ b/src/i18n/lang/zh-cn.ts
@@ -72,6 +72,7 @@
visualizingLinkDemo2: '数据可视化演示2',
personal: '个人中心',
tongji:'患者健康服务统计',
+ userAdmin:'用户管理',
xueqingdanbai:'质控-血清蛋白控制率',
tools: '工具类集合',
layoutLinkView: '外链',
diff --git a/src/layout/navBars/topBar/user.vue b/src/layout/navBars/topBar/user.vue
index fa73b14..9d15a75 100644
--- a/src/layout/navBars/topBar/user.vue
+++ b/src/layout/navBars/topBar/user.vue
@@ -92,7 +92,7 @@
<!-- <el-dropdown-item command="wareHouse">{{ $t('message.user.dropdown6') }}</el-dropdown-item> -->
<el-dropdown-item command="/personal">{{ $t('message.user.dropdown2') }}</el-dropdown-item>
<el-dropdown-item command="/tongji">患者健康服务统计</el-dropdown-item>
- <!-- <el-dropdown-item command="/401">{{ $t('message.user.dropdown4') }}</el-dropdown-item> -->
+ <el-dropdown-item command="/userAdmin">用户管理</el-dropdown-item>
<el-dropdown-item divided command="logOut">{{ $t('message.user.dropdown5') }}</el-dropdown-item>
</el-dropdown-menu>
</template>
diff --git a/src/layout/upgrade/index.vue b/src/layout/upgrade/index.vue
index c94eb9c..ac198ab 100644
--- a/src/layout/upgrade/index.vue
+++ b/src/layout/upgrade/index.vue
@@ -92,6 +92,7 @@
}
.el-dialog__header {
display: none !important;
+ background: red;
}
.upgrade-title {
text-align: center;
diff --git a/src/router/index.ts b/src/router/index.ts
index e33cef8..ad85cdc 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -92,13 +92,14 @@
// 路由加载前
router.beforeEach(async (to, from, next) => {
+ console.log('to', to);
NProgress.configure({ showSpinner: false });
if (to.meta.title) NProgress.start();
const token = Session.get('token');
if (to.path === '/login' && !token) {
next();
NProgress.done();
- }else if (to.path === '/tiaochabiao1' && !token) {
+ }else if ((to.path === '/register'||to.path==='/registerSuu') && !token) {
next();
NProgress.done();
}
diff --git a/src/router/route.ts b/src/router/route.ts
index d4258de..d9f0b2e 100644
--- a/src/router/route.ts
+++ b/src/router/route.ts
@@ -1135,6 +1135,21 @@
},
},
{
+ path: '/userAdmin',
+ name: 'userAdmin',
+ component: () => import('/@/views/userAdmin/index.vue'),
+ meta: {
+ title: 'message.router.userAdmin',
+ isLink: '',
+ isHide: false,
+ isKeepAlive: true,
+ isAffix: false,
+ isIframe: false,
+ roles: ['admin', 'common'],
+ icon: 'iconfont icon-gerenzhongxin',
+ },
+ },
+ {
path: '/zhikong/xueqingdanbai',
name: 'xueqingdanbai',
component: () => import('/@/views/zhikong/xueqingdanbai.vue'),
@@ -1346,7 +1361,15 @@
},
],
- }
+ },
+ {
+ path: '/register',
+ name: 'register',
+ component: () => import('/@/views/register/index.vue'),
+ meta: {
+ title: '注册',
+ },
+ },
];
/**
@@ -1380,6 +1403,22 @@
title: '调查表',
},
},
+ {
+ path: '/register',
+ name: 'register',
+ component: () => import('/@/views/register/index.vue'),
+ meta: {
+ title: '注册',
+ },
+ },
+ {
+ path: '/registerSuu',
+ name: 'registerSuu',
+ component: () => import('/@/views/registerSuu/index.vue'),
+ meta: {
+ title: '注册成功',
+ },
+ },
];
/**
@@ -1397,6 +1436,7 @@
title: '登录',
},
},
+
/**
* 提示:写在这里的为全屏界面,不建议写在这里
* 请写在 `dynamicRoutes` 路由数组中
diff --git a/src/views/personal/index.vue b/src/views/personal/index.vue
index 69980dc..e4db217 100644
--- a/src/views/personal/index.vue
+++ b/src/views/personal/index.vue
@@ -12,7 +12,7 @@
</div>
<div class="personal-user-right">
<el-row>
- <el-col :span="24" class="personal-title mb18">{{ currentTime }},admin,生活变的再糟糕,也不妨碍我变得更好! </el-col>
+ <!-- <el-col :span="24" class="personal-title mb18">{{ currentTime }},admin,生活变的再糟糕,也不妨碍我变得更好! </el-col> -->
<el-col :span="24">
<el-row>
<el-col :xs="24" :sm="8" class="personal-item mb6">
diff --git a/src/views/register/index.vue b/src/views/register/index.vue
new file mode 100644
index 0000000..cab0e0d
--- /dev/null
+++ b/src/views/register/index.vue
@@ -0,0 +1,272 @@
+<template>
+ <div class="register-form">
+ <!-- Logo -->
+ <el-image :src="logo" :width="100" :height="100" />
+ <h1>用户注册</h1>
+ <p class="desc">创建您的账户,开始使用我们的服务</p>
+
+ <!-- 表单 -->
+ <el-form
+ :model="formData"
+ :rules="formRules"
+ ref="formRef"
+ @submit.prevent="onSubmit"
+ label-width="auto"
+ class="form-container"
+ >
+ <!-- 用户名 -->
+ <el-form-item label="用户姓名*" prop="username">
+ <el-input
+ v-model="formData.username"
+ placeholder="请输入您的姓名"
+ />
+ </el-form-item>
+
+ <!-- 手机号 -->
+ <el-form-item label="手机号*" prop="phone">
+ <el-input
+ v-model="formData.phone"
+ placeholder="请输入您的手机号"
+ />
+ </el-form-item>
+
+ <!-- 验证码 -->
+ <el-form-item label="手机验证码*" prop="code">
+ <el-input
+ v-model="formData.code"
+ placeholder="请输入验证码"
+ class="code-input"
+ >
+ <template #append>
+ <el-button
+ type="primary"
+ @click="sendCode"
+ :disabled="isSendingCode"
+ >
+ {{ sendButtonText }}
+ </el-button>
+ </template>
+ </el-input>
+ </el-form-item>
+
+ <!-- 邮箱 -->
+ <el-form-item label="邮箱地址*" prop="email">
+ <el-input
+ v-model="formData.email"
+ type="email"
+ placeholder="请输入您的邮箱地址"
+ />
+ </el-form-item>
+
+ <!-- 密码 -->
+ <el-form-item label="密码*" prop="password">
+ <el-input
+ v-model="formData.password"
+ type="password"
+ placeholder="请输入您的密码"
+ />
+ </el-form-item>
+
+ <!-- 确认密码 -->
+ <el-form-item label="确认密码*" prop="confirmPassword">
+ <el-input
+ v-model="formData.confirmPassword"
+ type="password"
+ placeholder="请确认您的密码"
+ />
+ </el-form-item>
+
+ <!-- 提交按钮 -->
+ <div class="submit-btn">
+ <el-button
+ round
+ type="primary"
+ native-type="submit"
+ :loading="submitLoading"
+ style="width: 100%"
+ >
+ 立即注册
+ </el-button>
+ </div>
+ </el-form>
+
+ </div>
+</template>
+
+<script setup>
+import { ref, reactive } from 'vue';
+import { useRouter } from 'vue-router';
+import { ElMessage, ElLoading } from 'element-plus';
+import logo from '/@/assets/logo.png';
+
+// API 导入(保持不变)
+import { sendValidateCode, registerForNutrition } from "/@/api/register";
+
+const router = useRouter();
+
+// 表单数据
+const formData = reactive({
+ username: '',
+ phone: '',
+ code: '',
+ email: '',
+ password: '',
+ confirmPassword: ''
+});
+
+// 表单引用(用于校验)
+const formRef = ref(null);
+
+// 提交加载状态
+const submitLoading = ref(false);
+
+// 验证码发送状态
+const isSendingCode = ref(false);
+const sendButtonText = ref('发送验证码');
+let countdownTimer = null;
+const countdown = ref(60);
+
+// 手机号格式校验
+const isValidPhone = (phone) => /^1[3456789]\d{9}$/.test(phone);
+
+// 发送验证码
+const sendCode = () => {
+ if (!formData.phone) {
+ ElMessage.error('请先填写手机号');
+ return;
+ }
+
+ if (!isValidPhone(formData.phone)) {
+ ElMessage.error('请输入正确的手机号码');
+ return;
+ }
+
+ // 模拟请求发送验证码
+ console.log('发送验证码至:', formData.phone);
+ sendValidateCode('mobileNo=' + formData.phone)
+ .then(() => {
+ ElMessage.success('验证码已发送');
+ // 启动倒计时
+ isSendingCode.value = true;
+ countdown.value = 60;
+ sendButtonText.value = `${countdown.value}秒后重发`;
+
+ countdownTimer = setInterval(() => {
+ countdown.value--;
+ sendButtonText.value = `${countdown.value}秒后重发`;
+ if (countdown.value <= 0) {
+ clearInterval(countdownTimer);
+ isSendingCode.value = false;
+ sendButtonText.value = '重新发送';
+ }
+ }, 1000);
+ })
+ .catch(() => {
+ ElMessage.error('验证码发送失败');
+ });
+};
+
+// 自定义密码确认校验
+const validatePass = (rule, value, callback) => {
+ if (value !== formData.password) {
+ callback(new Error('两次输入密码不一致'));
+ } else {
+ callback();
+ }
+};
+
+// 表单规则
+const formRules = {
+ username: [
+ { required: true, message: '请填写用户名', trigger: 'blur' }
+ ],
+ phone: [
+ { required: true, message: '请填写手机号', trigger: 'blur' },
+ { pattern: /^1[3456789]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }
+ ],
+ code: [
+ { required: true, message: '请填写验证码', trigger: 'blur' }
+ ],
+ email: [
+ { pattern: /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/, message: '请输入正确的邮箱格式', trigger: 'blur' }
+ ],
+ password: [
+ { required: true, message: '请填写密码', trigger: 'blur' },
+ { min: 6, message: '密码长度不能少于6位', trigger: 'blur' }
+ ],
+ confirmPassword: [
+ { required: true, message: '请确认密码', trigger: 'blur' },
+ { validator: validatePass, trigger: 'blur' }
+ ]
+};
+
+// 表单提交
+const onSubmit = () => {
+ formRef.value.validate(async (valid) => {
+ if (!valid) return;
+
+ const submitData = {
+ 手机验证码: formData.code,
+ 用户姓名: formData.username,
+ 手机号: formData.phone,
+ 密码: formData.confirmPassword,
+ Email: formData.email
+ };
+
+ console.log('提交数据:', submitData);
+
+ const loading = ElLoading.service({
+ lock: true,
+ text: '注册中...',
+ background: 'rgba(0, 0, 0, 0.7)'
+ });
+
+ try {
+ const res = await registerForNutrition(submitData);
+ if (res.code === 400) {
+ ElMessage.error(res.message);
+ } else if (res.code === 200) {
+ ElMessage.success('注册成功!');
+ router.push('/registerSuu');
+ }
+ } catch (err) {
+ ElMessage.error('注册失败,请稍后重试');
+ } finally {
+ loading.close();
+ }
+ });
+};
+</script>
+
+<style scoped>
+.register-form {
+ text-align: center;
+ max-width: 400px;
+ margin: 0 auto;
+ padding: 20px;
+ padding-top: 40px;
+}
+
+h1 {
+ font-size: 20px;
+ margin-bottom: 10px;
+}
+
+.desc {
+ color: #666;
+ font-size: 14px;
+ margin-bottom: 20px;
+}
+
+.form-container {
+ margin-top: 20px;
+}
+
+.code-input :deep(.el-input-group__append) {
+ padding: 0;
+}
+
+.submit-btn {
+ margin: 24px 0;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/registerSuu/index.vue b/src/views/registerSuu/index.vue
new file mode 100644
index 0000000..7f05019
--- /dev/null
+++ b/src/views/registerSuu/index.vue
@@ -0,0 +1,26 @@
+<template>
+ <div class="success-container" style="text-align: center;margin-top: 100px;">
+ <el-image :src="logo" :width="100" :height="100" style="margin-bottom: 30px;" />
+ <van-icon name="checked" class="success-icon" />
+ <h2>注册成功!</h2>
+ <p>您的账户已成功创建,欢迎加入我们!</p>
+ <p>待审核通过后才可以登录系统!</p>
+ <!-- <van-button type="primary" block @click="goToLogin">前往登录</van-button> -->
+ </div>
+</template>
+<script setup>
+ import logo from '/@/assets/logo.png';
+</script>
+<style scoped>
+
+ .success-icon {
+ font-size: 60px;
+ color: #4caf50;
+ margin-bottom: 20px;
+ }
+p {
+ height: 40px;
+ line-height: 40px;
+ font-size: 14px;
+}
+ </style>
\ No newline at end of file
diff --git a/src/views/userAdmin/component/addUser.vue b/src/views/userAdmin/component/addUser.vue
new file mode 100644
index 0000000..d96ad0d
--- /dev/null
+++ b/src/views/userAdmin/component/addUser.vue
@@ -0,0 +1,202 @@
+<template>
+ <div class="system-add-user-container">
+ <div v-if="isShowDialog">
+ <el-dialog title="新增用户" v-model="isShowDialog" width="769px">
+ <el-form :model="ruleForm" :rules="rules" ref="adduserForm" size="small" label-width="90px">
+ <el-row :gutter="35">
+
+ <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+ <el-form-item label="用户代号" prop="userNo">
+ <el-input v-model="ruleForm.userNo" placeholder="请输入用户代号" clearable></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+ <el-form-item label="用户姓名" prop="userName">
+ <el-input v-model="ruleForm.userName" placeholder="请输入用户姓名" clearable></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+ <el-form-item label="手机号" prop="userMobile">
+ <el-input v-model="ruleForm.userMobile" placeholder="请输入手机号" clearable></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+ <el-form-item label="邮箱">
+ <el-input v-model="ruleForm.userEmail" placeholder="请输入" clearable></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+ <el-form-item label="his编号">
+ <el-input v-model="ruleForm.hisCode" placeholder="请输入his编号" clearable></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+ <el-form-item label="性别">
+ <el-select clearable v-model="ruleForm.userGender" placeholder="请选择" class="w100">
+ <el-option label="男" :value="0"></el-option>
+ <el-option label="女" :value="1"></el-option>
+ </el-select>
+ </el-form-item>
+ </el-col>
+ <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+ <el-form-item label="账户过期">
+ <el-date-picker v-model="ruleForm.updateTime" type="date" placeholder="请选择" class="w100"> </el-date-picker>
+ </el-form-item>
+ </el-col>
+ <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+ <el-form-item label="用户状态">
+ <el-switch v-model="ruleForm.isValid" inline-prompt :active-value="1" :inactive-value="0" active-text="启" inactive-text="禁"></el-switch>
+ </el-form-item>
+ </el-col>
+ <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+ <el-form-item label="排序">
+ <!-- <el-input-number v-model="ruleForm.userSortOrder" /> -->
+ <el-input v-model.number="ruleForm.userSortOrder" type="number" oninput="value=value.replace(/[^\d]/g,'')" placeholder="请输入"></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
+ <el-form-item label="角色分配">
+ <el-checkbox-group v-model="checkedRoles" >
+ <el-checkbox v-for="(role,index) in roleData" :disabled='role.roleName==="admin"' :key="index" :label="role.roleText">{{role.roleText}}</el-checkbox>
+ </el-checkbox-group>
+ </el-form-item>
+ </el-col>
+ <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
+ <el-form-item label="用户描述">
+ <el-input v-model="ruleForm.remark" type="textarea" placeholder="请输入用户描述" maxlength="150"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="onCancel" :loading="loading" size="small">取 消</el-button>
+ <el-button type="primary" :loading="loading" @click="onSubmit" size="small">新 增</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </div>
+ </div>
+</template>
+
+<script lang="ts">
+import { reactive, toRefs, onMounted,getCurrentInstance} from 'vue';
+import {Add } from '/@/api/user/index'
+import { useStore } from '/@/store/index';
+import {list as getroleList} from '/@/api/role/index'
+export default {
+ name: 'systemAddUser',
+ setup(props,context) {
+ const { proxy } = getCurrentInstance() as any;
+ const store = useStore();
+ const state = reactive({
+ isShowDialog: false,
+ ruleForm: {
+ id:0,
+ userName: '', // 账户名称
+ userNo: '', // 用户昵称
+ roleSign: '', // 关联角色
+ userMobile: '', // 手机号
+ userEmail: '', // 邮箱
+ userGender: 0, // 性别
+ userTitle:'',//职称(编号)
+ overdueTime: '', // 账户过期
+ isValid: 1, // 用户状态
+ remark: '', // 用户描述
+ userSortOrder:0,
+ hisCode:'',
+ roles:[]
+ },
+ rules: {
+ userName: { required: true, message: '请输入用户姓名', trigger: 'blur' },
+ userNo: { required: true, message: '请输入用户代号', trigger: 'blur' },
+ userEmail: { required: true, message: '请输入用户邮箱', trigger: 'blur' },
+ userMobile: [
+ { required: true, message: '请输入用户手机号码', trigger: 'blur' },
+ { pattern: /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/, message: '请输入有效的手机号', trigger: 'blur' }
+ ],
+ },
+ checkedRoles:[],
+ roleData:[], // 部门数据
+ loading: false,
+ });
+ // 打开弹窗
+ const openDialog = () => {
+ state.ruleForm={
+ id:0,
+ userName: '', // 账户名称
+ userNo: '', // 用户昵称
+ roleSign: '', // 关联角色
+ userMobile: '', // 手机号
+ userEmail: '', // 邮箱
+ userGender: 0, // 性别
+ userTitle:'',//职称(编号)
+ overdueTime: '', // 账户过期
+ isValid: 1, // 用户状态
+ remark: '', // 用户描述
+ userSortOrder:999,
+ roles:[]
+ }
+ state.isShowDialog = true;
+ };
+ // 关闭弹窗
+ const closeDialog = () => {
+ state.isShowDialog = false;
+ };
+ // 取消
+ const onCancel = () => {
+ closeDialog();
+ };
+ // 新增
+ const onSubmit = () => {
+ console.log('3434')
+ console.log(state.checkedRoles)
+ proxy.$refs['adduserForm'].validate(async (valid) => {
+ if(valid){
+ state.loading = true;
+ const roles: never[]=[]
+ if(state.checkedRoles.length>0){
+ state.roleData.forEach(r=>{
+ if(state.checkedRoles.findIndex(e=>e===r.roleText)>-1){
+ roles.push({role_code:r.code})
+ }
+ })
+ }
+ state.ruleForm.userVsRoleList=roles
+ state.ruleForm.clientCode=store.state.userInfos.userInfos.client.code
+ Add(state.ruleForm).then(()=>{
+ closeDialog();
+ context.emit("update:Search");//调用父级方法参数
+ }).finally(() => {
+ state.loading = false;
+ })
+ }
+ })
+ };
+ // 初始化部门数据
+ const initTableData = () => {
+ var ps= new Object ({
+ page: 0,
+ size: 0,
+ wherecondition: '',
+ ordercondition: 'create_time desc'
+ })
+ getroleList(ps).then(re=>{
+ state.roleData=re.data.list
+ console.log(state.roleData)
+ })
+ };
+ // 页面加载时
+ onMounted(() => {
+ initTableData();
+ });
+ return {
+ openDialog,
+ closeDialog,
+ onCancel,
+ onSubmit,
+ ...toRefs(state),
+ };
+ },
+};
+</script>
diff --git a/src/views/userAdmin/component/editUser.vue b/src/views/userAdmin/component/editUser.vue
new file mode 100644
index 0000000..76db1c2
--- /dev/null
+++ b/src/views/userAdmin/component/editUser.vue
@@ -0,0 +1,164 @@
+<template>
+ <div class="upgrade-dialog">
+ <el-dialog title="修改用户" v-model="isShowDialog" width="1069px" center>
+ <el-form :model="ruleForm" :rules="rules" ref="edituserForm" label-width="90px">
+ <el-row :gutter="35">
+ <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+ <el-form-item label="用户代号" prop="userNo">
+ <el-input v-model="ruleForm.userNo" placeholder="请输入用户代号" clearable></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+ <el-form-item label="用户姓名" prop="userName">
+ <el-input v-model="ruleForm.userName" placeholder="请输入用户姓名" clearable></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+ <el-form-item label="手机号" prop="userMobile">
+ <el-input v-model="ruleForm.userMobile" placeholder="请输入手机号" clearable></el-input>
+ </el-form-item>
+ </el-col>
+ <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
+ <el-form-item label="用户状态">
+ <el-switch v-model="ruleForm.isValid" inline-prompt :inactive-value="0" :active-value="1" active-text="启" inactive-text="禁"></el-switch>
+ </el-form-item>
+ </el-col>
+ <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
+ <el-form-item label="所属医院">
+ <div style="border: 1px solid #EBEDF0;padding: 5px; ">
+ <el-checkbox-group v-model="ruleForm.clientCodes">
+ <el-checkbox v-for="(client,index) in clientData" :label="client.clientName" :value="client.code" :key="index" />
+ </el-checkbox-group>
+ </div>
+ </el-form-item>
+ </el-col>
+ <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24" class="mb20">
+ <el-form-item label="用户描述">
+ <el-input v-model="ruleForm.remark" type="textarea" placeholder="请输入用户描述" maxlength="150"></el-input>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="onCancel" :loading="loading" >取 消</el-button>
+ <el-button type="primary" :loading="loading" @click="onSubmit" >修 改</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script lang="ts">
+import { reactive, toRefs, onMounted,getCurrentInstance } from 'vue';
+import {update,getClientList} from '/@/api/register'
+export default {
+ name: 'systemEditUser',
+ setup(props,context) {
+ const { proxy } = getCurrentInstance() as any;
+ const state = reactive({
+ isShowDialog: false,
+ ruleForm: {
+ userName: '', // 账户名称
+ userNo: '', // 用户昵称
+ roleSign: '', // 关联角色
+ userMobile: '', // 手机号
+ userEmail: '', // 邮箱
+ userGender: 0, // 性别
+ userTitle:'',//职称(编号)
+ overdueTime: '', // 账户过期
+ isValid: 0, // 用户状态
+ clientCodes:'',
+ remark: '', // 用户描述
+
+ },
+
+ clientData: [], // 部门数据
+ rules: {
+ userName: { required: true, message: '请输入用户姓名', trigger: 'blur' },
+ userNo: { required: true, message: '请输入用户代号', trigger: 'blur' },
+ userMobile: [
+ { required: true, message: '请输入用户手机号码', trigger: 'blur' },
+ { pattern: /^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/, message: '请输入有效的手机号', trigger: 'blur' }
+ ],
+ },
+ loading: false,
+ });
+ // 打开弹窗
+ const openDialog = (row: any) => {
+ state.ruleForm =row
+ state.isShowDialog = true;
+ };
+ // 关闭弹窗
+ const closeDialog = () => {
+ state.isShowDialog = false;
+ };
+ // 取消
+ const onCancel = () => {
+ closeDialog();
+ };
+ // 新增
+ const onSubmit = () => {
+ proxy.$refs['edituserForm'].validate(async (valid) => {
+ if(valid){
+ state.loading = true;
+ update(state.ruleForm).then(()=>{
+ closeDialog();
+ context.emit("update:Search");//调用父级方法参数
+ }).finally(() => {
+ state.loading = false;
+ })
+ }
+ })
+ };
+ // 初始化部门数据
+ const initTableData = () => {
+ const pas={
+ page: 0,
+ size: 0,
+ wherecondition: '',
+ ordercondition: 'create_time desc'
+ }
+ getClientList(pas).then((res)=>{
+ state.clientData=res.data.list
+ console.log(res.data.list,'部门数据')
+ })
+
+ };
+ // 页面加载时
+ onMounted(() => {
+ initTableData();
+ });
+ return {
+ openDialog,
+ closeDialog,
+ onCancel,
+ onSubmit,
+ ...toRefs(state),
+ };
+ },
+};
+</script>
+<style scoped lang="scss">
+.upgrade-dialog {
+ :deep(.el-dialog) {
+ padding:0;
+ padding-bottom: 20px;
+ .el-dialog__body {
+ padding: 5 !important;
+ }
+ .el-dialog__header {
+ background: #409EFF;
+ height: 50px;
+ line-height: 50px;
+ margin-bottom: 30px;
+ .span{
+ color: white;
+ }
+
+ }
+
+ }
+}
+</style>
+
diff --git a/src/views/userAdmin/index.vue b/src/views/userAdmin/index.vue
new file mode 100644
index 0000000..6d1db38
--- /dev/null
+++ b/src/views/userAdmin/index.vue
@@ -0,0 +1,179 @@
+<template>
+ <div class="user-management">
+ <!-- 搜索和操作区域 -->
+ <el-form :inline="true" class="demo-form-inline" style="background-color: white;padding-top: 20px; padding-left: 10px;">
+ <el-form-item label="">
+ <el-input v-model="search.userNameOrMobile" placeholder="请输入用户名/手机号"></el-input>
+ </el-form-item>
+ <el-form-item label="用户状态">
+ <el-select v-model="search.isValid" placeholder="请选择用户状态" style="width: 100px;">
+ <el-option label="全部" value=""></el-option>
+ <el-option label="启用" :value="1"></el-option>
+ <el-option label="禁用" :value="0"></el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary" @click="onSearch"> <el-icon><Search /></el-icon>查询</el-button>
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary" @click="onAddUser"><el-icon><Plus /></el-icon>新增用户</el-button>
+ </el-form-item>
+ </el-form>
+
+ <!-- 用户列表 -->
+ <el-table :data="tableData" style="width: 100%;background-color: white; min-height: 700px;">
+ <el-table-column prop="userName" label="用户姓名"></el-table-column>
+ <el-table-column prop="userNo" label="登录名"></el-table-column>
+ <el-table-column prop="userMobile" label="手机号"></el-table-column>
+ <el-table-column prop="createTime" label="注册时间"></el-table-column>
+ <el-table-column label="用户状态">
+ <template #default="scope">
+ <el-tag :type="scope.row.isValid === 1 ? 'success' : 'danger'">{{ scope.row.isValid === 1 ? '启用' : '禁用' }}</el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column label="所属医院">
+ <template #default="scope">
+ <el-tag v-for="hospital in scope.row.clientInfos" :key="hospital" size="small" style="margin-right: 5px;">{{ hospital.clientName }}</el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column label="操作">
+ <template #default="scope">
+ <el-button @click="onEdit(scope.$index, scope.row)"><el-icon><Edit /></el-icon></el-button>
+
+ <el-button @click="onDelete(scope.$index, scope.row)" style="color: red;"><el-icon><Delete /></el-icon></el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <!-- 分页 -->
+ <el-pagination style="margin-top: 20px;"
+ background
+ layout="prev, pager, next"
+ :total="total"
+ @current-change="handleCurrentChange"
+ ></el-pagination>
+ <EditUser ref="editUserRef" @update:Search="onSearch" />
+ </div>
+ </template>
+
+ <script>
+ import { onMounted, ref } from 'vue';
+ import { ElLoading, ElMessageBox } from 'element-plus';
+ import {listForNutrition,deleteId} from '/@/api/register'
+ import EditUser from './component/editUser.vue';
+ export default {
+ components: { EditUser },
+ setup() {
+ const search = ref({
+ userNameOrMobile: '',
+ isValid: '',
+ page:1,
+ size:10
+ });
+ const editUserRef=ref()
+ const tableData = ref([]);
+
+ const total = ref(1);
+
+ const onSearch = () => {
+ // 实现搜索逻辑
+ getDatas()
+ };
+
+ const onAddUser = () => {
+ // 实现新增用户逻辑
+ editUserRef.value.openDialog({
+ id:0,
+ userName:'',
+ userNo:'',
+ userMobile:'',
+ userGender:'',
+ isValid:1,
+ clientCodes:[],
+ remark:''
+ })
+ };
+
+ const onEdit = (index, row) => {
+ const pasm={
+ id:row.id,
+ userName:row.userName,
+ userNo:row.userNo,
+ userMobile:row.userMobile,
+ userGender:row.userGender,
+ isValid:row.isValid,
+ clientCodes:row.clientInfos.map(item=>item.code),
+ remark:row.remark
+ }
+ console.log(pasm)
+ // 实现编辑逻辑
+ editUserRef.value.openDialog(pasm)
+
+ };
+
+ const onDelete = (index, row) => {
+ // 实现删除逻辑
+ console.log(row)
+ ElMessageBox.confirm(`确定删除${row.userName}?`, '提示', {
+ confirmButtonText: '确定',
+ cancelButtonText: '取消',
+ type: 'warning',
+ }).then(() => {
+ deleteId({id:row.id}).then(res=>{
+ getDatas()
+ })
+ }).catch(() => {
+ // 用户取消删除
+ });
+ };
+
+ const handleCurrentChange = (currentPage) => {
+ search.value.page = currentPage;
+ getDatas()
+ // 实现分页逻辑
+ };
+ onMounted(async()=>{
+ getDatas()
+
+ })
+ const getDatas=()=>{
+ const loading = ElLoading.service({
+ lock: true,
+ text: 'Loading',
+ background: 'rgba(0, 0, 0, 0.7)',
+ })
+ listForNutrition(search.value).then(res=>{
+ tableData.value=res.data.list
+ total.value=res.data.total
+ console.log(res)
+
+ }).finally(()=>{
+ loading.close()
+ })
+ }
+ return {
+ search,
+ tableData,
+ total,
+ onSearch,
+ editUserRef,
+ onAddUser,
+ onEdit,
+ onDelete,
+ handleCurrentChange
+ };
+ }
+ };
+ </script>
+
+ <style scoped>
+ body {
+ background-color: #8c3e3e;
+ }
+ .user-management {
+ padding: 50px;
+ }
+ .demo-form-inline {
+ margin-bottom: 20px;
+ }
+ </style>
\ No newline at end of file
--
Gitblit v1.8.0