复制id功能

This commit is contained in:
2025-07-25 14:33:45 +08:00
parent 7573ef5d7c
commit 8fb59508b0
10 changed files with 163 additions and 153 deletions

View File

@@ -4,8 +4,9 @@ NODE_ENV=development
VITE_DEV=true VITE_DEV=true
# 请求路径 # 请求路径
# VITE_BASE_URL='http://192.168.1.174:48080' VITE_BASE_URL='http://192.168.1.174:48080'
VITE_BASE_URL='http://47.79.98.113:48080' # VITE_BASE_URL='http://47.79.98.113:48080'
# VITE_BASE_URL='https://backstageapi.yolozs.com'
# 文件上传类型server - 后端上传, client - 前端直连上传,仅支持 S3 服务 # 文件上传类型server - 后端上传, client - 前端直连上传,仅支持 S3 服务
VITE_UPLOAD_TYPE=server VITE_UPLOAD_TYPE=server

View File

@@ -4,7 +4,7 @@ NODE_ENV=production
VITE_DEV=false VITE_DEV=false
# 请求路径 # 请求路径
VITE_BASE_URL='http://47.79.98.113:48080' VITE_BASE_URL='https://backstageapi.yolozs.com'
# 文件上传类型server - 后端上传, client - 前端直连上传仅支持S3服务 # 文件上传类型server - 后端上传, client - 前端直连上传仅支持S3服务
VITE_UPLOAD_TYPE=server VITE_UPLOAD_TYPE=server

View File

@@ -68,7 +68,7 @@
"editor.defaultFormatter": "esbenp.prettier-vscode" "editor.defaultFormatter": "esbenp.prettier-vscode"
}, },
"[html]": { "[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode" "editor.defaultFormatter": "vscode.html-language-features"
}, },
"[css]": { "[css]": {
"editor.defaultFormatter": "esbenp.prettier-vscode" "editor.defaultFormatter": "esbenp.prettier-vscode"

View File

@@ -103,7 +103,8 @@ const open = async (type: string, id?: number, index?: number) => {
formData.value = await EmployeeHostsApi.getEmployeeHosts(id) formData.value = await EmployeeHostsApi.getEmployeeHosts(id)
getStrDictOptions(DICT_TYPE.OPERATION_STATE).forEach(item => { getStrDictOptions(DICT_TYPE.OPERATION_STATE).forEach(item => {
if (item.value == formData.value.operationStatus) { if (item.value == formData.value.operationStatus) {
formData.value.operationStatus = item.label console.log("item", item)
formData.value.operationStatus = item.value
} }
}) })

View File

@@ -115,6 +115,12 @@
{{ scope.row.hostsId }}</div> {{ scope.row.hostsId }}</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" prop="hostsId" width="75">
<template #default="scope">
<el-link type="primary" @click="handleCopy(scope.row.hostsId)">复制</el-link>
</template>
</el-table-column>
<el-table-column :label="$t('employee.hostsLevel')" align="center" prop="hostsLevel" /> <el-table-column :label="$t('employee.hostsLevel')" align="center" prop="hostsLevel" />
<el-table-column :label="$t('employee.invitationType')" align="center" prop="invitationType"> <el-table-column :label="$t('employee.invitationType')" align="center" prop="invitationType">
<template #default="scope"> <template #default="scope">
@@ -151,9 +157,12 @@
<!-- 移动端使用卡片列表 --> <!-- 移动端使用卡片列表 -->
<div v-else v-infinite-scroll="loadList"> <div v-else v-infinite-scroll="loadList">
<div v-for="(item, index) in list" :key="index" class="mobile-card"> <div v-for="(item, index) in list" :key="index" class="mobile-card">
<div class="card-row" @click="openHtml(item, item.hostsId)" style="color:green;"> <div class="card-row" style="color:green;">
<b>{{ $t('employee.hostsId') }}</b><span style=" text-decoration: underline;">{{ item.hostsId }}</span> <b>{{ $t('employee.hostsId') }}</b><span @click="openHtml(item, item.hostsId)"
style=" text-decoration: underline;margin-right: 50px;">{{ item.hostsId }}</span>
<el-link @click="handleCopy(item.hostsId)" type="primary">复制id</el-link>
</div> </div>
<!-- <div class="card-row"><b>{{ $t('employee.userId') }}</b>{{ item.userId }}</div> --> <!-- <div class="card-row"><b>{{ $t('employee.userId') }}</b>{{ item.userId }}</div> -->
<div class="card-row"><b>{{ $t('employee.hostsLevel') }}</b>{{ item.hostsLevel }}</div> <div class="card-row"><b>{{ $t('employee.hostsLevel') }}</b>{{ item.hostsLevel }}</div>
<div class="card-row"><b>{{ $t('employee.hostsCoins') }}</b>{{ item.hostsCoins }}</div> <div class="card-row"><b>{{ $t('employee.hostsCoins') }}</b>{{ item.hostsCoins }}</div>
@@ -426,6 +435,29 @@ function AllocationFun() {
console.log(selectHostList.value) console.log(selectHostList.value)
} }
function handleCopy(text) {
// fallback 兼容方案
const textarea = document.createElement('textarea')
textarea.value = text
textarea.style.position = 'fixed' // 避免跳动
textarea.style.opacity = '0'
document.body.appendChild(textarea)
textarea.select()
try {
const result = document.execCommand('copy')
if (result) {
ElMessage.success('✅复制成功 ')
} else {
ElMessage.error('❌复制失败')
}
} catch (err) {
ElMessage.error('❌复制异常')
console.error(err)
} finally {
document.body.removeChild(textarea)
}
}
const isMobile = ref(window.innerWidth <= 768) const isMobile = ref(window.innerWidth <= 768)
onMounted(() => { onMounted(() => {

View File

@@ -324,7 +324,8 @@ function AllocationFun() {
selectBigList.value.forEach(element => { selectBigList.value.forEach(element => {
data.push({ data.push({
id: element.id, id: element.id,
userId: allocationUser.value userId: allocationUser.value,
operationStatus: 0
}) })
}) })

View File

@@ -103,7 +103,9 @@ const open = async (type: string, id?: number, index?: number) => {
formData.value = await EmployeeHostsApi.getEmployeeHosts(id) formData.value = await EmployeeHostsApi.getEmployeeHosts(id)
getStrDictOptions(DICT_TYPE.OPERATION_STATE).forEach(item => { getStrDictOptions(DICT_TYPE.OPERATION_STATE).forEach(item => {
if (item.value == formData.value.operationStatus) { if (item.value == formData.value.operationStatus) {
formData.value.operationStatus = item.label console.log("item", item)
formData.value.operationStatus = item.value
} }
}) })

View File

@@ -114,6 +114,12 @@
{{ scope.row.hostsId }}</div> {{ scope.row.hostsId }}</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column align="center" prop="hostsId" width="75">
<template #default="scope">
<el-link type="primary" @click="handleCopy(scope.row.hostsId)">复制</el-link>
</template>
</el-table-column>
<el-table-column :label="$t('employee.hostsLevel')" align="center" prop="hostsLevel" /> <el-table-column :label="$t('employee.hostsLevel')" align="center" prop="hostsLevel" />
<el-table-column :label="$t('employee.invitationType')" align="center" prop="invitationType"> <el-table-column :label="$t('employee.invitationType')" align="center" prop="invitationType">
<template #default="scope"> <template #default="scope">
@@ -150,9 +156,12 @@
<!-- 移动端使用卡片列表 --> <!-- 移动端使用卡片列表 -->
<div v-else v-infinite-scroll="loadList"> <div v-else v-infinite-scroll="loadList">
<div v-for="(item, index) in list" :key="index" class="mobile-card"> <div v-for="(item, index) in list" :key="index" class="mobile-card">
<div class="card-row" @click="openHtml(item, item.hostsId)" style="color:green;"> <div class="card-row" style="color:green;">
<b>{{ $t('employee.hostsId') }}</b><span style=" text-decoration: underline;">{{ item.hostsId }}</span> <b>{{ $t('employee.hostsId') }}</b><span @click="openHtml(item, item.hostsId)"
style=" text-decoration: underline;margin-right: 50px;">{{ item.hostsId }}</span>
<el-link @click="handleCopy(item.hostsId)" type="primary">复制id</el-link>
</div> </div>
<!-- <div class="card-row"><b>{{ $t('employee.userId') }}</b>{{ item.userId }}</div> --> <!-- <div class="card-row"><b>{{ $t('employee.userId') }}</b>{{ item.userId }}</div> -->
<div class="card-row"><b>{{ $t('employee.hostsLevel') }}</b>{{ item.hostsLevel }}</div> <div class="card-row"><b>{{ $t('employee.hostsLevel') }}</b>{{ item.hostsLevel }}</div>
<div class="card-row"><b>uid</b>{{ item.uid }}</div> <div class="card-row"><b>uid</b>{{ item.uid }}</div>
@@ -416,7 +425,8 @@ function AllocationFun() {
selectHostList.value.forEach(element => { selectHostList.value.forEach(element => {
data.push({ data.push({
id: element.id, id: element.id,
userId: allocationUser.value userId: allocationUser.value,
operationStatus: 0
}) })
}) })
@@ -429,6 +439,30 @@ function AllocationFun() {
dialogAllocation.value = false dialogAllocation.value = false
} }
function handleCopy(text) {
// fallback 兼容方案
const textarea = document.createElement('textarea')
textarea.value = text
textarea.style.position = 'fixed' // 避免跳动
textarea.style.opacity = '0'
document.body.appendChild(textarea)
textarea.select()
try {
const result = document.execCommand('copy')
if (result) {
ElMessage.success('✅复制成功 ')
} else {
ElMessage.error('❌复制失败')
}
} catch (err) {
ElMessage.error('❌复制异常')
console.error(err)
} finally {
document.body.removeChild(textarea)
}
}
const isMobile = ref(window.innerWidth <= 768) const isMobile = ref(window.innerWidth <= 768)
onMounted(() => { onMounted(() => {

View File

@@ -113,12 +113,12 @@
:label="dict.label" :value="dict.value" /> :label="dict.label" :value="dict.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item :label="t('newHosts.allocationUser')" prop="allocationUser"> <!-- <el-form-item :label="t('newHosts.allocationUser')" prop="allocationUser">
<el-select v-model="queryParams.userId" :placeholder="t('newHosts.placeAllocationUser')" clearable <el-select v-model="queryParams.userId" :placeholder="t('newHosts.placeAllocationUser')" clearable
class="!w-240px"> class="!w-240px">
<el-option v-for="(user, index) in allocationUserList" :key="index" :label="user.label" :value="user.value" /> <el-option v-for="(user, index) in allocationUserList" :key="index" :label="user.label" :value="user.value" />
</el-select> </el-select>
</el-form-item> </el-form-item> -->
<el-form-item> <el-form-item>
<el-button @click="handleQuery"> <el-button @click="handleQuery">
<Icon icon="ep:search" class="mr-5px" /> {{ t('newHosts.search') }} <Icon icon="ep:search" class="mr-5px" /> {{ t('newHosts.search') }}
@@ -149,6 +149,12 @@
<el-table v-loading="loading" :data="list" :stripe="true" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="list" :stripe="true" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" /> <el-table-column type="selection" width="55" />
<el-table-column :label="t('newHosts.hostsId')" align="center" prop="hostsId" /> <el-table-column :label="t('newHosts.hostsId')" align="center" prop="hostsId" />
<el-table-column align="center" prop="hostsId" width="75">
<template #default="scope">
<el-link type="primary" @click="handleCopy(scope.row.hostsId)">复制</el-link>
</template>
</el-table-column>
<el-table-column :label="t('newHosts.hostsLevel')" sortable align="center" prop="hostsLevel" /> <el-table-column :label="t('newHosts.hostsLevel')" sortable align="center" prop="hostsLevel" />
<el-table-column :label="t('newHosts.invitationType')" align="center" prop="invitationType"> <el-table-column :label="t('newHosts.invitationType')" align="center" prop="invitationType">
<template #default="scope"> <template #default="scope">
@@ -402,7 +408,28 @@ function AllocationFun() {
getList() getList()
}) })
} }
function handleCopy(text) {
// fallback 兼容方案
const textarea = document.createElement('textarea')
textarea.value = text
textarea.style.position = 'fixed' // 避免跳动
textarea.style.opacity = '0'
document.body.appendChild(textarea)
textarea.select()
try {
const result = document.execCommand('copy')
if (result) {
ElMessage.success('✅复制成功 ')
} else {
ElMessage.error('❌复制失败')
}
} catch (err) {
ElMessage.error('❌复制异常')
console.error(err)
} finally {
document.body.removeChild(textarea)
}
}
/** 初始化 **/ /** 初始化 **/
onMounted(() => { onMounted(() => {

View File

@@ -13,91 +13,44 @@
<el-col :span="20" :xs="24"> <el-col :span="20" :xs="24">
<!-- 搜索 --> <!-- 搜索 -->
<ContentWrap> <ContentWrap>
<el-form <el-form class="-mb-15px" :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="68px"
>
<el-form-item label="用户名称" prop="username"> <el-form-item label="用户名称" prop="username">
<el-input <el-input v-model="queryParams.username" placeholder="请输入用户名称" clearable @keyup.enter="handleQuery"
v-model="queryParams.username" class="!w-240px" />
placeholder="请输入用户名称"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item> </el-form-item>
<el-form-item label="手机号码" prop="mobile"> <el-form-item label="手机号码" prop="mobile">
<el-input <el-input v-model="queryParams.mobile" placeholder="请输入手机号码" clearable @keyup.enter="handleQuery"
v-model="queryParams.mobile" class="!w-240px" />
placeholder="请输入手机号码"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item> </el-form-item>
<el-form-item label="状态" prop="status"> <el-form-item label="状态" prop="status">
<el-select <el-select v-model="queryParams.status" placeholder="请选择用户状态" clearable class="!w-240px">
v-model="queryParams.status" <el-option v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)" :key="dict.value"
placeholder="请选择用户状态" :label="dict.label" :value="dict.value" />
clearable
class="!w-240px"
>
<el-option
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="创建时间" prop="createTime"> <el-form-item label="创建时间" prop="createTime">
<el-date-picker <el-date-picker v-model="queryParams.createTime" value-format="YYYY-MM-DD HH:mm:ss" type="datetimerange"
v-model="queryParams.createTime" start-placeholder="开始日期" end-placeholder="结束日期" class="!w-240px" />
value-format="YYYY-MM-DD HH:mm:ss"
type="datetimerange"
start-placeholder="开始日期"
end-placeholder="结束日期"
class="!w-240px"
/>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" />搜索</el-button> <el-button @click="handleQuery">
<el-button @click="resetQuery"><Icon icon="ep:refresh" />重置</el-button> <Icon icon="ep:search" />搜索
<el-button </el-button>
type="primary" <el-button @click="resetQuery">
plain <Icon icon="ep:refresh" />重置
@click="openForm('create')" </el-button>
v-hasPermi="['system:user:create']" <el-button type="primary" plain @click="openForm('create')" v-hasPermi="['system:user:create']">
>
<Icon icon="ep:plus" /> 新增 <Icon icon="ep:plus" /> 新增
</el-button> </el-button>
<el-button <el-button type="warning" plain @click="handleImport" v-hasPermi="['system:user:import']">
type="warning"
plain
@click="handleImport"
v-hasPermi="['system:user:import']"
>
<Icon icon="ep:upload" /> 导入 <Icon icon="ep:upload" /> 导入
</el-button> </el-button>
<el-button <el-button type="success" plain @click="handleExport" :loading="exportLoading"
type="success" v-hasPermi="['system:user:export']">
plain
@click="handleExport"
:loading="exportLoading"
v-hasPermi="['system:user:export']"
>
<Icon icon="ep:download" />导出 <Icon icon="ep:download" />导出
</el-button> </el-button>
<el-button <el-button type="danger" plain :disabled="checkedIds.length === 0" @click="handleDeleteBatch"
type="danger" v-hasPermi="['system:user:delete']">
plain
:disabled="checkedIds.length === 0"
@click="handleDeleteBatch"
v-hasPermi="['system:user:delete']"
>
<Icon icon="ep:delete" />批量删除 <Icon icon="ep:delete" />批量删除
</el-button> </el-button>
</el-form-item> </el-form-item>
@@ -107,82 +60,43 @@
<el-table v-loading="loading" :data="list" @selection-change="handleRowCheckboxChange"> <el-table v-loading="loading" :data="list" @selection-change="handleRowCheckboxChange">
<el-table-column type="selection" width="55" /> <el-table-column type="selection" width="55" />
<el-table-column label="用户编号" align="center" key="id" prop="id" /> <el-table-column label="用户编号" align="center" key="id" prop="id" />
<el-table-column <el-table-column label="用户名称" align="center" prop="username" :show-overflow-tooltip="true" />
label="用户称" <el-table-column label="用户称" align="center" prop="nickname" :show-overflow-tooltip="true" />
align="center" <el-table-column label="部门" align="center" key="deptName" prop="deptName" :show-overflow-tooltip="true" />
prop="username"
:show-overflow-tooltip="true"
/>
<el-table-column
label="用户昵称"
align="center"
prop="nickname"
:show-overflow-tooltip="true"
/>
<el-table-column
label="部门"
align="center"
key="deptName"
prop="deptName"
:show-overflow-tooltip="true"
/>
<el-table-column label="手机号码" align="center" prop="mobile" width="120" /> <el-table-column label="手机号码" align="center" prop="mobile" width="120" />
<el-table-column label="状态" key="status"> <el-table-column label="状态" key="status">
<template #default="scope"> <template #default="scope">
<el-switch <el-switch v-model="scope.row.status" :active-value="0" :inactive-value="1"
v-model="scope.row.status" @change="handleStatusChange(scope.row)" :disabled="!checkPermi(['system:user:update'])" />
:active-value="0"
:inactive-value="1"
@change="handleStatusChange(scope.row)"
:disabled="!checkPermi(['system:user:update'])"
/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column label="创建时间" align="center" prop="createTime" :formatter="dateFormatter" width="180" />
label="创建时间"
align="center"
prop="createTime"
:formatter="dateFormatter"
width="180"
/>
<el-table-column label="操作" align="center" width="160"> <el-table-column label="操作" align="center" width="160">
<template #default="scope"> <template #default="scope">
<div class="flex items-center justify-center"> <div class="flex items-center justify-center">
<el-button <el-button type="primary" link @click="openForm('update', scope.row.id)"
type="primary" v-hasPermi="['system:user:update']">
link
@click="openForm('update', scope.row.id)"
v-hasPermi="['system:user:update']"
>
<Icon icon="ep:edit" />修改 <Icon icon="ep:edit" />修改
</el-button> </el-button>
<el-dropdown <el-dropdown @command="(command) => handleCommand(command, scope.row)" v-hasPermi="[
@command="(command) => handleCommand(command, scope.row)"
v-hasPermi="[
'system:user:delete', 'system:user:delete',
'system:user:update-password', 'system:user:update-password',
'system:permission:assign-user-role' 'system:permission:assign-user-role'
]" ]">
> <el-button type="primary" link>
<el-button type="primary" link><Icon icon="ep:d-arrow-right" /> 更多</el-button> <Icon icon="ep:d-arrow-right" /> 更多
</el-button>
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item <el-dropdown-item command="handleDelete"
command="handleDelete" v-if="checkPermi(['system:user:delete']) && wsCache.get('user').user.id != scope.row.id">
v-if="checkPermi(['system:user:delete'])"
>
<Icon icon="ep:delete" />删除 <Icon icon="ep:delete" />删除
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item <el-dropdown-item command="handleResetPwd" v-if="checkPermi(['system:user:update-password'])">
command="handleResetPwd"
v-if="checkPermi(['system:user:update-password'])"
>
<Icon icon="ep:key" />重置密码 <Icon icon="ep:key" />重置密码
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item <el-dropdown-item command="handleRole"
command="handleRole" v-if="checkPermi(['system:permission:assign-user-role']) && wsCache.get('user').user.id != scope.row.id">
v-if="checkPermi(['system:permission:assign-user-role'])"
>
<Icon icon="ep:circle-check" />分配角色 <Icon icon="ep:circle-check" />分配角色
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
@@ -192,12 +106,8 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<Pagination <Pagination :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize"
:total="total" @pagination="getList" />
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap> </ContentWrap>
</el-col> </el-col>
</el-row> </el-row>
@@ -220,7 +130,9 @@ import UserForm from './UserForm.vue'
import UserImportForm from './UserImportForm.vue' import UserImportForm from './UserImportForm.vue'
import UserAssignRoleForm from './UserAssignRoleForm.vue' import UserAssignRoleForm from './UserAssignRoleForm.vue'
import DeptTree from './DeptTree.vue' import DeptTree from './DeptTree.vue'
import { useCache } from '@/hooks/web/useCache'
const { wsCache } = useCache()
defineOptions({ name: 'SystemUser' }) defineOptions({ name: 'SystemUser' })
const message = useMessage() // 消息弹窗 const message = useMessage() // 消息弹窗
@@ -347,7 +259,7 @@ const handleDelete = async (id: number) => {
message.success(t('common.delSuccess')) message.success(t('common.delSuccess'))
// 刷新列表 // 刷新列表
await getList() await getList()
} catch {} } catch { }
} }
/** 批量删除按钮操作 */ /** 批量删除按钮操作 */
@@ -365,7 +277,7 @@ const handleDeleteBatch = async () => {
message.success(t('common.delSuccess')) message.success(t('common.delSuccess'))
// 刷新列表 // 刷新列表
await getList() await getList()
} catch {} } catch { }
} }
/** 重置密码 */ /** 重置密码 */
@@ -380,7 +292,7 @@ const handleResetPwd = async (row: UserApi.UserVO) => {
// 发起重置 // 发起重置
await UserApi.resetUserPassword(row.id, password) await UserApi.resetUserPassword(row.id, password)
message.success('修改成功,新密码是:' + password) message.success('修改成功,新密码是:' + password)
} catch {} } catch { }
} }
/** 分配角色 */ /** 分配角色 */