Browse Source

优化用户管理配置

dev
LiLongLong 7 months ago
parent
commit
b1f0528a76
  1. 6
      components.d.ts
  2. 1
      src/pages/Index/Regular/Emergency.vue
  3. 3
      src/pages/Index/Regular/Running.vue
  4. 80
      src/pages/Index/Settings/Users.vue
  5. 88
      src/pages/Index/components/Setting/AddUserModal.vue
  6. 8
      src/pages/Index/components/Setting/DelWarn.vue
  7. 84
      src/pages/Index/components/Setting/EnterPinModal.vue
  8. 290
      src/pages/Index/components/Setting/UpdatePinModal.vue
  9. 1
      src/pages/Index/components/Setting/index.ts

6
components.d.ts

@ -8,14 +8,13 @@ export {}
declare module 'vue' {
export interface GlobalComponents {
ElButton: typeof import('element-plus/es')['ElButton']
ElCol: typeof import('element-plus/es')['ElCol']
ElDropdown: typeof import('element-plus/es')['ElDropdown']
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
ElFooter: typeof import('element-plus/es')['ElFooter']
ElHeader: typeof import('element-plus/es')['ElHeader']
ElIcon: typeof import('element-plus/es')['ElIcon']
ElPopover: typeof import('element-plus/es')['ElPopover']
ElRow: typeof import('element-plus/es')['ElRow']
ElTable: typeof import('element-plus/es')['ElTable']
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
ErrorModal: typeof import('./src/components/dialogs/ErrorModal.vue')['default']
@ -25,7 +24,4 @@ declare module 'vue' {
SimpleKeyboard: typeof import('./src/components/SimpleKeyboard.vue')['default']
StackInfoModal: typeof import('./src/components/dialogs/StackInfoModal.vue')['default']
}
export interface ComponentCustomProperties {
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
}
}

1
src/pages/Index/Regular/Emergency.vue

@ -391,7 +391,6 @@ const showKeyboard = (field: 'sampleBarcode' | 'userid') => {
//
const handleKeyboardInput = (value: string) => {
if (!currentInputField.value) return
console.log('value----', value)
//
currentInputValue.value = value
//

3
src/pages/Index/Regular/Running.vue

@ -31,7 +31,8 @@
光学模组
</span>
<div v-if="runningStore.optScanModuleState && runningStore.optScanModuleState!.state !== 'EMPTY'" class="scan-ji">
<div style="position: absolute;left:0px">
<!--是急诊位时-->>
<div style="position: absolute;left:0px" v-if="runningStore.optScanModuleState!.isEmergency">
<img
src="@/assets/ji.png"
alt=""

80
src/pages/Index/Settings/Users.vue

@ -1,7 +1,7 @@
<template>
<div class="user-management">
<div class="user-table" :key="refreshKey">
<el-table :data="tableData" header-cell-class-name="table-header" row-class-name="table-row">
<el-table :data="tableData" @selection-change="handleSelectionChange" header-cell-class-name="table-header" row-class-name="table-row">
<el-table-column type="selection" width="80" />
<el-table-column label="用户" property="account" min-width="200" />
<el-table-column label="权限" property="usrRole" min-width="200" />
@ -22,13 +22,17 @@
<DelMessage v-if="delMessageShowModal" v-model:visible="delMessageShowModal" icon="/src/assets/OK.svg"
message="已成功删除用户" :username="selectedUsers[0]?.account" @confirm="handleConfirmMsgDelete" />
<DelWarn v-if="updatePinModal" :visible="updatePinModal" icon="/src/assets/update-pin-icon.svg" title="PIN码更新"
<!-- <DelWarn v-if="updatePinModal" :visible="updatePinModal" icon="/src/assets/update-pin-icon.svg" title="PIN码更新"
:message="updatePinMessage" description="您正在更改PIN码,请谨慎操作" confirm-text="确认更新" cancel-text="取消更新"
@confirm="handleConfirmUpdatePin" @cancel="handleCancelUpdatePin" />
@confirm="handleConfirmUpdatePin" @cancel="handleCancelUpdatePin" /> -->
<EnterPinModal v-if="enterPinModal" :visible="enterPinModal" :loading="updatePinLoading" @confirm="updatePinConfirm"
@cancel="closeEnterPinModal" />
<UpdatePinModal v-if="updatePinModal" :visible="updatePinModal" :loading="updatePinLoading" @confirm="updatePwdConfirm"
@cancel="closePwdModal" />
<DelMessage v-if="updatePinMsgModal" :visible="updatePinMsgModal" icon="/src/assets/OK.svg" message="PIN码更新成功"
:username="selectedUsers[0].account" @confirm="handleConfirmMsg" />
@ -38,7 +42,7 @@
@confirm="handleConfirmInsert" @cancel="handleCancelInsert" @resetAlreadyExist="resetAlreadyExist" />
</template>
<template v-else-if="currentStep === 'pin'">
<template v-if="isPinModalVisible">
<EnterPinModal :visible="isPinModalVisible" :loading="registerLoading" @confirm="handlePinConfirm"
@cancel="closeModal" />
</template>
@ -50,7 +54,7 @@
<script setup lang="ts">
import type { User } from '../../../types/Index'
import { DelWarn, DelMessage, AddUserModal, EnterPinModal } from '../components'
import { DelWarn, DelMessage, AddUserModal, EnterPinModal, UpdatePinModal } from '../components'
import { ref, onMounted, computed } from 'vue'
import {
getUserList,
@ -85,6 +89,12 @@ const tempUser = ref({
id: 0,
password: '',
})
const updateUser = ref({
id: 0,
password: '',
oldpasswd: '',
})
const registerLoading = ref(false)
const updatePinLoading = ref(false)
const placeholder = ref('请输入用户名')
@ -95,7 +105,7 @@ const delMessageShowModal = ref(false)
const updatePinModal = ref(false)
const updatePinMsgModal = ref(false)
const insertUserShowModal = ref(false)
const isPinModalVisible = ref(true)
const isPinModalVisible = ref(false)
const confirmInsert = ref(false)
const isChecked = ref(false)
const enterPinModal = ref(false)
@ -133,6 +143,11 @@ const fetchUserList = async () => {
//
const addUser = async () => {
insertUserShowModal.value = true
currentStep.value = 'username'
}
const handleSelectionChange = (val) => {
selectedUsers.value = val
}
// ( PIN )
const modifyPin = async () => {
@ -141,7 +156,12 @@ const modifyPin = async () => {
isChecked.value = true
return
}
updatePinModal.value = true
if(selectedUsers.value.length !== 1){
return;
}
// updatePinModal.value = true
handleConfirmUpdatePin()
}
//
const deleteSelectedUsers = () => {
@ -211,10 +231,31 @@ const handleUpdatePin = async () => {
console.log('修改用户权限失败')
}
}
const handleUpdatePwd= async () => {
if (selectedUsers.value.length !== 1) {
console.log('请选择一个用户来修改PIN码')
return
}
const user = updateUser.value
const response = await changeUserPassword({
id: user.id,
password: user.password,
oldpasswd: user.oldpasswd,
})
if (response && response.success) {
} else {
console.log('修改用户权限失败')
}
}
//pin
const handleConfirmUpdatePin = () => {
updatePinModal.value = false
enterPinModal.value = true
updatePinModal.value = true
// enterPinModal.value = true
}
//pin
const updatePinConfirm = (val: string) => {
@ -223,9 +264,27 @@ const updatePinConfirm = (val: string) => {
tempUser.value.password = val
handleUpdatePin().then(() => {
updatePinLoading.value = false
updatePinModal.value = false
updatePinMsgModal.value = true
})
}
const updatePwdConfirm= (params:{password:string, oldpasswd: string}) => {
enterPinModal.value = false
updatePinLoading.value = true
updateUser.value.password = params.password
updateUser.value.oldpasswd = params.oldpasswd
handleUpdatePwd().then(() => {
updatePinLoading.value = false
updatePinModal.value = false
updatePinMsgModal.value = true
})
}
const closePwdModal = ()=> {
updatePinModal.value = false;
}
//
const closeEnterPinModal = () => {
enterPinModal.value = false
@ -248,6 +307,7 @@ const handleConfirmInsert = (val: string) => {
} else {
newUser.value.account = val //
currentStep.value = 'pin'
isPinModalVisible.value = true
}
}
const handleCancelInsert = () => {
@ -288,7 +348,7 @@ const updatePinMessage = computed(
() => `是否更新PIN码 <strong>${selectedUserAccount.value}</strong> 用户`,
)
const deleteUserMessage = computed(
() => `是否删除 <strong>${selectedUserAccount.value}</strong> 用户`,
() => `是否删除 <strong>${selectedUserAccount.value}</strong> 用户`,
)
</script>
<style scoped lang="less">

88
src/pages/Index/components/Setting/AddUserModal.vue

@ -12,6 +12,7 @@
<div class="modal-body">
<div class="input-container">
<input type="text" v-model="username" :placeholder="placeholder"
@focus="showKeyboard()"
:class="['username-input', { 'already-exist': alreadyExist }]" />
<img class="input-icon" :src="iconUrl" alt="" />
<div class="input-tips" v-if="alreadyExist">
@ -21,16 +22,23 @@
</div>
<!-- 操作按钮 -->
<div class="modal-footer">
<el-button type="danger" @click="cancel">取消添加</el-button>
<el-button @click="cancel">取消添加</el-button>
<el-button type="primary" @click="confirmAdd" :loading="isLoading">添加</el-button>
</div>
</div>
<!-- 键盘 -->
<transition name="slide-up">
<div class="keyboard" v-if="keyboardVisible">
<SimpleKeyboard :input="currentInputValue" @onChange="handleKeyboardInput" @onKeyPress="handleKeyPress" />
</div>
</transition>
</div>
</teleport>
</template>
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { ref, computed, watch, onUnmounted } from 'vue'
import activeIcon from '@/assets/register-user-active.svg'
import existIcon from '@/assets/register-user-exist.svg'
import devicateIcon from '@/assets/register-user-devicate.svg'
@ -43,6 +51,10 @@ const props = defineProps<{
tips?: string //
}>()
const username = ref('')
//
const keyboardVisible = ref(false)
const currentInputValue = ref('')
const currentInputField = ref<'sampleBarcode' | 'userid' | ''>('')
// `username`
watch(username, (newVal) => {
@ -61,6 +73,26 @@ const iconUrl = computed(() => {
}
})
//
const hideKeyboard = () => {
keyboardVisible.value = false
currentInputField.value = ''
currentInputValue.value = ''
}
//
const showKeyboard = () => {
//
// currentInputValue.value = ''
currentInputValue.value = username.value
keyboardVisible.value = true
}
//
onUnmounted(() => {
hideKeyboard()
})
//
const emit = defineEmits<{
(e: 'confirm', username: string): void
@ -84,6 +116,30 @@ const cancel = () => {
username.value = '' //
}
//
const handleKeyboardInput = (value: string) => {
//
currentInputValue.value = value
//
username.value = value
}
//
const handleKeyPress = (button: string) => {
if (button === '{enter}') {
hideKeyboard()
} else if (button === '{bksp}') {
// 退
const value = currentInputValue.value
if (value.length > 0) {
const newValue = value.slice(0, -1)
handleKeyboardInput(newValue)
}
}
}
//
const placeholder = props.placeholder || '用户名'
</script>
@ -211,8 +267,34 @@ const placeholder = props.placeholder || '用户名'
width: 400px;
height: 100px;
font-size: 32px;
border-radius: 50px;
border-radius: 30px;
}
}
}
.keyboard {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 300px;
background-color: #f5f7fa;
border-top-left-radius: 16px;
border-top-right-radius: 16px;
box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.1);
z-index: 1000;
}
//
.slide-up-enter-active,
.slide-up-leave-active {
transition: transform 0.3s ease;
}
.slide-up-enter-from,
.slide-up-leave-to {
transform: translateY(100%);
}
</style>

8
src/pages/Index/components/Setting/DelWarn.vue

@ -14,12 +14,12 @@
</div>
<!-- 操作按钮 -->
<div class="del-warn-footer">
<el-button @click="cancelDelete">{{
cancelText
}}</el-button>
<el-button type="danger" @click="confirmDelete">{{
confirmText
}}</el-button>
<el-button type="primary" @click="cancelDelete">{{
cancelText
}}</el-button>
</div>
</div>
</div>
@ -137,7 +137,7 @@ onMounted(async () => {
width: 200px;
height: 80px;
font-size: 32px;
border-radius: 50px;
border-radius: 30px;
}
}
</style>

84
src/pages/Index/components/Setting/EnterPinModal.vue

@ -8,7 +8,8 @@
</div>
<div class="modal-body">
<div class="input-container">
<input type="password" v-model="pin" placeholder="输入 PIN 码" class="pin-input" />
<input :type="isShowType?'text':'password'" v-model="pin" placeholder="输入PIN 码" @focus="showKeyboard()" class="pin-input" />
<el-icon class="pwd-view" @click="isShowType = !isShowType"><View /></el-icon>
</div>
</div>
<div class="modal-footer">
@ -16,6 +17,12 @@
<el-button type="primary" @click="confirmPin" :loading="loading">确认</el-button>
</div>
</div>
<!-- 键盘 -->
<transition name="slide-up">
<div class="keyboard" v-if="keyboardVisible">
<SimpleKeyboard :input="currentInputValue" @onChange="handleKeyboardInput" @onKeyPress="handleKeyPress" />
</div>
</transition>
</div>
</teleport>
</template>
@ -29,12 +36,57 @@ const emit = defineEmits<{
(e: 'cancel'): void
}>()
const inputType = ref('password')
const isShowType = ref(false)
const pin = ref('')
const confirmPin = () => {
emit('confirm', pin.value)
}
//
const keyboardVisible = ref(false)
const currentInputValue = ref('')
const currentInputField = ref<'sampleBarcode' | 'userid' | ''>('')
//
const hideKeyboard = () => {
keyboardVisible.value = false
currentInputField.value = ''
currentInputValue.value = ''
}
//
const showKeyboard = () => {
//
// currentInputValue.value = ''
currentInputValue.value = pin.value
keyboardVisible.value = true
}
//
const handleKeyboardInput = (value: string) => {
//
currentInputValue.value = value
//
pin.value = value
}
//
const handleKeyPress = (button: string) => {
if (button === '{enter}') {
hideKeyboard()
} else if (button === '{bksp}') {
// 退
const value = currentInputValue.value
if (value.length > 0) {
const newValue = value.slice(0, -1)
handleKeyboardInput(newValue)
}
}
}
const cancel = () => {
emit('cancel')
}
@ -138,4 +190,34 @@ const cancel = () => {
}
}
}
.keyboard {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 300px;
background-color: #f5f7fa;
border-top-left-radius: 16px;
border-top-right-radius: 16px;
box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.1);
z-index: 1000;
}
//
.slide-up-enter-active,
.slide-up-leave-active {
transition: transform 0.3s ease;
}
.slide-up-enter-from,
.slide-up-leave-to {
transform: translateY(100%);
}
.pwd-view{
font-size: 30px;
position: absolute;
margin-left: -40px;
margin-top: 16px;
}
</style>

290
src/pages/Index/components/Setting/UpdatePinModal.vue

@ -0,0 +1,290 @@
<template>
<teleport to="body">
<div v-if="visible" class="modal-overlay">
<div class="modal-container">
<div class="modal-header"></div>
<div class="modal-title">
<span class="title-text">请输入 PIN </span>
</div>
<div class="modal-body">
<div class="input-container">
<div>
<input :type="showoldpasswd?'text':'password'" v-model="oldpasswd" placeholder="输入旧PIN码" @focus="showKeyboard('oldpasswd')" class="pin-input" />
<el-icon class="pwd-view" @click="showoldpasswd = !showoldpasswd"><View /></el-icon>
</div>
<br/>
<div>
<input :type="showPassword?'text':'password'" v-model="password " placeholder="输入新PIN 码" @focus="showKeyboard('password')" class="pin-input" />
<el-icon class="pwd-view" @click="showPassword = !showPassword"><View /></el-icon>
</div>
<br/>
<div>
<input :type="showConfirmPassword?'text':'password'" v-model="confirmPassword " placeholder="输入确认新PIN 码" @focus="showKeyboard('confirmPassword')" class="pin-input" />
<el-icon class="pwd-view" @click="showConfirmPassword = !showConfirmPassword"><View /></el-icon>
</div>
</div>
</div>
<div class="modal-footer">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="confirmPin" :loading="loading">确认</el-button>
</div>
</div>
<InitWarn
v-if="showErrorModal"
:visible="showErrorModal"
title="错误提示"
message="两次输入的密码不一致"
icon="/src/assets/Warn.svg"
confirmText="确认"
@confirm="showErrorModal = false"
/>
<!-- 键盘 -->
<transition name="slide-up">
<div class="keyboard" v-if="keyboardVisible">
<SimpleKeyboard :input="currentInputValue" @onChange="handleKeyboardInput" @onKeyPress="handleKeyPress" />
</div>
</transition>
</div>
</teleport>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { InitWarn } from '../../components/Consumables'
import { ElMessage } from 'element-plus';
defineProps<{ visible: boolean; loading: boolean }>()
const emit = defineEmits<{
(e: 'confirm', pin: {oldpasswd:string, password:string}): void
(e: 'cancel'): void
}>()
const showErrorModal = ref(false)
const showoldpasswd = ref(false)
const showPassword = ref(false)
const showConfirmPassword = ref(false)
const oldpasswd = ref('')
const password = ref('')
const confirmPassword = ref('')
const confirmPin = () => {
if(!oldpasswd.value){
ElMessage.error('请输入旧密码');
return;
}
if(!password.value){
ElMessage.error('请输入新密码');
return;
}
if(!confirmPassword.value){
ElMessage.error('请确认新密码');
return;
}
if(password.value != confirmPassword.value){
// showErrorModal.value = true;
ElMessage.error('两次输入的密码不一致');
return;
}
const params = {
oldpasswd: oldpasswd.value,
password: password.value
}
emit('confirm', params)
}
//
const keyboardVisible = ref(false)
const currentInputValue = ref('')
const currentInputField = ref<'oldpasswd' | 'password' | 'confirmPassword' | ''>('')
//
const hideKeyboard = () => {
keyboardVisible.value = false
currentInputField.value = ''
currentInputValue.value = ''
}
//
const showKeyboard = (field:any) => {
//
// currentInputValue.value = ''
if(field == 'oldpasswd'){
currentInputValue.value = oldpasswd.value
}
if(field == 'password'){
currentInputValue.value = password.value
}
if(field == 'confirmPassword'){
currentInputValue.value = confirmPassword.value
}
currentInputField.value = field
keyboardVisible.value = true
}
//
const handleKeyboardInput = (value: string) => {
//
currentInputValue.value = value
//
if (currentInputField.value === 'oldpasswd') {
oldpasswd.value = value
} else if(currentInputField.value == 'password'){
password.value = value
}else if(currentInputField.value == 'confirmPassword'){
confirmPassword.value = value
}
}
//
const handleKeyPress = (button: string) => {
if (button === '{enter}') {
hideKeyboard()
} else if (button === '{bksp}') {
// 退
const value = currentInputValue.value
if (value.length > 0) {
const newValue = value.slice(0, -1)
handleKeyboardInput(newValue)
}
}
}
const cancel = () => {
emit('cancel')
}
</script>
<style scoped lang="less">
/* 样式与 AddUserModal 类似 */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal-container {
background-color: #fff;
border-radius: 10px;
width: 833px;
height: 633px;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.2);
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: center;
position: relative;
.modal-header {
background-color: #528dfe;
height: 8px;
position: absolute;
top: 0;
left: 0;
width: 100%;
}
.modal-title {
text-align: center;
margin-top: 15px;
font-size: 32px;
color: #528dfe;
font-weight: bold;
}
.modal-body {
display: flex;
justify-content: center;
padding: 20px;
.input-container {
position: relative;
width: 100%;
.pin-input {
box-sizing: border-box;
width: 100%;
font-size: 32px;
padding: 20px 80px;
color: #b0b0b0;
border: 1px solid #e0e0e0;
border-radius: 25px;
outline: none;
&:focus {
border-color: #528dfe;
color: #528dfe;
}
}
}
}
.modal-footer {
display: flex;
justify-content: space-around;
padding: 20px;
box-sizing: border-box;
button {
width: 200px;
height: 80px;
font-size: 32px;
border-radius: 30px;
}
}
}
.keyboard {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 300px;
background-color: #f5f7fa;
border-top-left-radius: 16px;
border-top-right-radius: 16px;
box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.1);
z-index: 1000;
}
//
.slide-up-enter-active,
.slide-up-leave-active {
transition: transform 0.3s ease;
}
.slide-up-enter-from,
.slide-up-leave-to {
transform: translateY(100%);
}
.pwd-view{
font-size: 30px;
position: absolute;
margin-left: -40px;
margin-top: 16px;
}
</style>

1
src/pages/Index/components/Setting/index.ts

@ -2,3 +2,4 @@ export { default as AddUserModal } from './AddUserModal.vue'
export { default as DelMessage } from './DelMessage.vue'
export { default as DelWarn } from './DelWarn.vue'
export { default as EnterPinModal } from './EnterPinModal.vue'
export { default as UpdatePinModal } from './UpdatePinModal.vue'
Loading…
Cancel
Save