1369 lines
43 KiB
Vue
1369 lines
43 KiB
Vue
<template>
|
||
<div class="app-container">
|
||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||
|
||
|
||
|
||
<el-form-item label="姓名" prop="name">
|
||
<el-input
|
||
v-model="queryParams.name"
|
||
placeholder="请输入昵称"
|
||
clearable
|
||
@keyup.enter.native="handleQuery"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="电话" prop="phone">
|
||
<el-input
|
||
v-model="queryParams.phone"
|
||
placeholder="请输入电话"
|
||
clearable
|
||
@keyup.enter.native="handleQuery"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="工号" prop="jobNumber">
|
||
<el-input
|
||
v-model="queryParams.jobNumber"
|
||
placeholder="请输入工号"
|
||
clearable
|
||
@keyup.enter.native="handleQuery"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="状态" prop="status">
|
||
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable>
|
||
<el-option
|
||
v-for="dict in dict.type.users_status"
|
||
:key="dict.value"
|
||
:label="dict.label"
|
||
:value="dict.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item label="等级" prop="level">
|
||
<el-input
|
||
v-model="queryParams.level"
|
||
placeholder="请输入工号"
|
||
clearable
|
||
@keyup.enter.native="handleQuery"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="使用状态" prop="loginStatus">
|
||
<el-select v-model="queryParams.loginStatus" placeholder="请选择使用状态" clearable>
|
||
<el-option
|
||
v-for="dict in dict.type.users_login_status"
|
||
:key="dict.value"
|
||
:label="dict.label"
|
||
:value="dict.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
|
||
<el-form-item label="当前佣金" prop="priceRange" label-width="auto">
|
||
<el-input
|
||
v-model="queryParams.commissionMin"
|
||
placeholder="最低价"
|
||
style="width: 100px; margin-right: 10px;"
|
||
type="number"
|
||
min="0"
|
||
clearable
|
||
/>
|
||
<span style="margin: 0 5px;">-</span>
|
||
<el-input
|
||
v-model="queryParams.commissionMax"
|
||
placeholder="最高价"
|
||
style="width: 100px;"
|
||
type="number"
|
||
min="0"
|
||
clearable
|
||
/>
|
||
</el-form-item>
|
||
|
||
|
||
<el-form-item label="质保金" prop="priceRange" label-width="auto">
|
||
<el-input
|
||
v-model="queryParams.marginMin"
|
||
placeholder="最低价"
|
||
style="width: 100px; margin-right: 10px;"
|
||
type="number"
|
||
min="0"
|
||
clearable
|
||
/>
|
||
<span style="margin: 0 5px;">-</span>
|
||
<el-input
|
||
v-model="queryParams.marginMax"
|
||
placeholder="最高价"
|
||
style="width: 100px;"
|
||
type="number"
|
||
min="0"
|
||
clearable
|
||
/>
|
||
</el-form-item>
|
||
|
||
|
||
<el-form-item label="累计提现" prop="priceRange" label-width="auto">
|
||
<el-input
|
||
v-model="queryParams.totalCommMin"
|
||
placeholder="最低价"
|
||
style="width: 100px; margin-right: 10px;"
|
||
type="number"
|
||
min="0"
|
||
clearable
|
||
/>
|
||
<span style="margin: 0 5px;">-</span>
|
||
<el-input
|
||
v-model="queryParams.totalCommMax"
|
||
placeholder="最高价"
|
||
style="width: 100px;"
|
||
type="number"
|
||
min="0"
|
||
clearable
|
||
/>
|
||
</el-form-item>
|
||
|
||
|
||
|
||
<el-form-item>
|
||
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
||
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<el-row :gutter="10" class="mb8">
|
||
<el-col :span="1.5">
|
||
<el-button
|
||
type="primary"
|
||
plain
|
||
icon="el-icon-plus"
|
||
size="mini"
|
||
@click="handleAdd"
|
||
v-hasPermi="['system:users:add']"
|
||
>新增</el-button>
|
||
</el-col>
|
||
<el-col :span="1.5">
|
||
<el-button
|
||
type="success"
|
||
plain
|
||
icon="el-icon-edit"
|
||
size="mini"
|
||
:disabled="single"
|
||
@click="handleUpdate"
|
||
v-hasPermi="['system:users:edit']"
|
||
>修改</el-button>
|
||
</el-col>
|
||
<el-col :span="1.5">
|
||
<el-button
|
||
type="danger"
|
||
plain
|
||
icon="el-icon-delete"
|
||
size="mini"
|
||
:disabled="multiple"
|
||
@click="handleDelete"
|
||
v-hasPermi="['system:users:remove']"
|
||
>删除</el-button>
|
||
</el-col>
|
||
<el-col :span="1.5">
|
||
<el-button
|
||
type="warning"
|
||
plain
|
||
icon="el-icon-refresh"
|
||
size="mini"
|
||
@click="handleManualResumeWorkerStatus"
|
||
v-hasPermi="['system:users:edit']"
|
||
>恢复过期暂停</el-button>
|
||
</el-col>
|
||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||
</el-row>
|
||
|
||
<el-table v-loading="loading" :data="usersList" @selection-change="handleSelectionChange">
|
||
<el-table-column type="selection" width="55" align="center" />
|
||
<el-table-column label="ID" align="center" width="55" prop="id" />
|
||
<el-table-column label="工号" align="center" prop="jobNumber" />
|
||
<el-table-column label="姓名" align="center" prop="name" />
|
||
<el-table-column label="电话" align="center" prop="phone" />
|
||
<el-table-column label="openid" align="center" prop="openid" />
|
||
<el-table-column label="头像" align="center" prop="avatar" width="100">
|
||
<template slot-scope="scope">
|
||
<image-preview :src="scope.row.avatar" :width="50" :height="50"/>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="使用状态" align="center" prop="loginStatus">
|
||
<template slot-scope="scope">
|
||
<dict-tag :options="dict.type.users_login_status" :value="scope.row.loginStatus"/>
|
||
</template>
|
||
</el-table-column>
|
||
|
||
<el-table-column label="状态" width="85" align="center">
|
||
<template slot-scope="scope">
|
||
<el-switch
|
||
v-model="scope.row.status"
|
||
:active-value="1"
|
||
:inactive-value="0"
|
||
@change="handleStatusChange(scope.row)"
|
||
></el-switch>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="本月累计单量" align="center" prop="toa" />
|
||
<el-table-column label="签到时间" align="center" prop="createdAt" width="180">
|
||
<template slot-scope="scope">
|
||
<span>{{ parseTime(scope.row.workerTime, '{y}-{m}-{d}') }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="等级" align="center" prop="level" width="100">
|
||
<template slot-scope="scope">
|
||
<div class="level-container">
|
||
<el-select
|
||
v-model="scope.row.level"
|
||
@change="handleRowClick(scope.row)"
|
||
size="small"
|
||
class="level-select-custom"
|
||
:class="'level-' + scope.row.level"
|
||
placeholder="选择等级"
|
||
>
|
||
<el-option
|
||
v-for="item in levelList"
|
||
:key="item.id"
|
||
:label="item.title"
|
||
:value="item.id"
|
||
class="level-option-item"
|
||
>
|
||
<div class="level-option-wrapper">
|
||
<span class="level-text">{{ item.title }}</span>
|
||
<span class="level-number">{{ item.id }}</span>
|
||
</div>
|
||
</el-option>
|
||
</el-select>
|
||
</div>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="当前佣金" align="center" prop="commission" />
|
||
<el-table-column label="累计佣金" align="center" prop="totalComm">
|
||
<template slot-scope="scope">
|
||
<el-link
|
||
type="primary"
|
||
@click="showWorkerMoneyLog(scope.row)"
|
||
v-hasPermi="['system:workerMoneyLog:list']"
|
||
>{{ scope.row.totalComm }}</el-link>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="质保金" align="center" prop="margin">
|
||
<template slot-scope="scope">
|
||
<el-link
|
||
type="primary"
|
||
@click="showWorkerMarginLog(scope.row)"
|
||
v-hasPermi="['system:WorkerMarginLog:list']"
|
||
>{{ scope.row.margin }}</el-link>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="累计提现" align="center" prop="propose" />
|
||
<el-table-column label="接单状态" align="center" prop="isStop" width="100">
|
||
<template slot-scope="scope">
|
||
<el-tag v-if="scope.row.isStop === 1 && !scope.row.isExpired" type="danger">已暂停</el-tag>
|
||
<el-tag v-else-if="scope.row.isStop === 1 && scope.row.isExpired" type="warning">已过期</el-tag>
|
||
<el-tag v-else type="success">正常</el-tag>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="暂停时长" align="center" prop="prohibitTimeNum" width="80">
|
||
<template slot-scope="scope">
|
||
<span v-if="scope.row.isStop === 1 && scope.row.prohibitTimeNum">{{ scope.row.prohibitTimeNum }}小时</span>
|
||
<span v-else>-</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="暂停到期时间" align="center" prop="prohibitTime" width="150">
|
||
<template slot-scope="scope">
|
||
<span v-if="scope.row.isStop === 1 && scope.row.prohibitTime" :class="{'expired-time': scope.row.isExpired}">
|
||
{{ parseTime(scope.row.prohibitTime, '{y}-{m}-{d} {h}:{i}') }}
|
||
</span>
|
||
<span v-else>-</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="服务区域" align="center" prop="serviceCityIds" width="150">
|
||
<template slot-scope="scope">
|
||
<span v-if="scope.row.serviceCityIds">{{ formatServiceAreas(scope.row.serviceCityIds) }}</span>
|
||
<span v-else>-</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="技能" align="center" prop="skillIds" width="150">
|
||
<template slot-scope="scope">
|
||
<span v-if="scope.row.skillIds">{{ formatSkillNames(scope.row.skillIds) }}</span>
|
||
<span v-else>-</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||
<template slot-scope="scope">
|
||
<el-button
|
||
size="mini"
|
||
type="text"
|
||
icon="el-icon-edit"
|
||
@click="handleUpdate(scope.row)"
|
||
v-hasPermi="['system:users:edit']"
|
||
>修改</el-button>
|
||
<el-button
|
||
v-if="scope.row.isStop !== 1"
|
||
size="mini"
|
||
type="text"
|
||
icon="el-icon-video-pause"
|
||
@click="handlePauseOrder(scope.row)"
|
||
v-hasPermi="['system:users:edit']"
|
||
style="color: #E6A23C;"
|
||
>暂停接单</el-button>
|
||
<el-button
|
||
v-else-if="scope.row.isExpired"
|
||
size="mini"
|
||
type="text"
|
||
icon="el-icon-refresh"
|
||
@click="handleResumeOrder(scope.row)"
|
||
v-hasPermi="['system:users:edit']"
|
||
style="color: #E6A23C;"
|
||
>恢复过期</el-button>
|
||
<el-button
|
||
v-else
|
||
size="mini"
|
||
type="text"
|
||
icon="el-icon-video-play"
|
||
@click="handleResumeOrder(scope.row)"
|
||
v-hasPermi="['system:users:edit']"
|
||
style="color: #67C23A;"
|
||
>恢复接单</el-button>
|
||
<el-button
|
||
size="mini"
|
||
type="text"
|
||
icon="el-icon-delete"
|
||
@click="handleDelete(scope.row)"
|
||
v-hasPermi="['system:users:remove']"
|
||
>删除</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<pagination
|
||
v-show="total>0"
|
||
:total="total"
|
||
:page.sync="queryParams.pageNum"
|
||
:limit.sync="queryParams.pageSize"
|
||
@pagination="getList"
|
||
/>
|
||
|
||
<UserEditDialog
|
||
:visible.sync="editDialogVisible"
|
||
:user="editUser"
|
||
:mode="editMode"
|
||
@confirm="handleEditConfirm"
|
||
@cancel="editDialogVisible = false"
|
||
/>
|
||
|
||
<!-- 师傅佣金明细弹窗 -->
|
||
<el-dialog :title="'师傅佣金明细'" :visible.sync="workerMoneyLogDialogVisible" width="70%" top="5vh" append-to-body>
|
||
<worker-money-log-table
|
||
:worker-id="currentWorkerId"
|
||
@close="workerMoneyLogDialogVisible = false"
|
||
v-if="workerMoneyLogDialogVisible"
|
||
/>
|
||
</el-dialog>
|
||
|
||
<!-- 师傅质保金明细弹窗 -->
|
||
<el-dialog :title="'师傅质保金明细'" :visible.sync="workerMarginLogDialogVisible" width="70%" top="5vh" append-to-body>
|
||
<worker-margin-log-detail-table
|
||
:worker-id="currentWorkerId"
|
||
@close="workerMarginLogDialogVisible = false"
|
||
@margin-changed="handleMarginChanged"
|
||
v-if="workerMarginLogDialogVisible"
|
||
:key="'margin-log-' + currentWorkerId"
|
||
/>
|
||
</el-dialog>
|
||
|
||
<WorkerLevelSelectDialog
|
||
:visible.sync="workerLevelDialogVisible"
|
||
:user-id="workerLevelUserId"
|
||
:user-name="workerLevelUserName"
|
||
@level-selected="handleWorkerLevelSelected"
|
||
/>
|
||
|
||
<!-- 暂停接单弹窗 -->
|
||
<el-dialog title="暂停接单" :visible.sync="pauseOrderDialogVisible" width="500px" append-to-body>
|
||
<el-form ref="pauseOrderForm" :model="pauseOrderForm" :rules="pauseOrderRules" label-width="100px">
|
||
<el-form-item label="师傅姓名">
|
||
<el-input v-model="pauseOrderForm.name" disabled />
|
||
</el-form-item>
|
||
<el-form-item label="暂停时长" prop="prohibitTimeNum">
|
||
<div class="time-input">
|
||
<el-button icon="el-icon-minus" @click="decreasePauseTime" size="small"></el-button>
|
||
<el-input-number
|
||
v-model="pauseOrderForm.prohibitTimeNum"
|
||
:min="1"
|
||
:max="168"
|
||
:controls="false"
|
||
placeholder="1"
|
||
style="width: 100px; text-align: center;" />
|
||
<el-button icon="el-icon-plus" @click="increasePauseTime" size="small"></el-button>
|
||
<span style="margin-left: 10px;">小时</span>
|
||
</div>
|
||
<div style="margin-top: 5px; color: #909399; font-size: 12px;">
|
||
暂停时长范围:1-168小时(7天)
|
||
</div>
|
||
</el-form-item>
|
||
<el-form-item label="暂停原因" prop="reason">
|
||
<el-input
|
||
v-model="pauseOrderForm.reason"
|
||
type="textarea"
|
||
:rows="3"
|
||
placeholder="请输入暂停接单原因(可选)"
|
||
maxlength="200"
|
||
show-word-limit
|
||
/>
|
||
</el-form-item>
|
||
</el-form>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button @click="pauseOrderDialogVisible = false">取消</el-button>
|
||
<el-button type="primary" @click="confirmPauseOrder" :loading="pauseOrderLoading">确认暂停</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { listUsers, getUsers, delUsers, addUsers, updateUsers,getUserDataList,changetypeStatus,pauseOrder } from "@/api/system/users"
|
||
import { listWorkerLevel } from '@/api/system/WorkerLevel'
|
||
import { datalist, getDiyCity, manualResumeWorkerStatus } from "@/api/system/DiyCity"
|
||
import { getSiteSkillList } from "@/api/system/SiteSkill"
|
||
import UserEditDialog from './UserEditDialog.vue'
|
||
import WorkerMoneyLogTable from '@/views/system/workerMoneyLog/WorkerMoneyLogTable.vue'
|
||
import WorkerMarginLogDetailTable from '@/views/system/WorkerMarginLog/WorkerMarginLogTable.vue'
|
||
import WorkerLevelSelectDialog from '../workerLevelSelect/WorkerLevelSelectDialog.vue'
|
||
|
||
|
||
export default {
|
||
name: "Users",
|
||
dicts: ['users_status','users_login_status'],
|
||
components: { UserEditDialog, WorkerMoneyLogTable, WorkerMarginLogDetailTable, WorkerLevelSelectDialog },
|
||
data() {
|
||
return {
|
||
// 遮罩层
|
||
loading: true,
|
||
// 选中数组
|
||
ids: [],
|
||
// 非单个禁用
|
||
single: true,
|
||
// 非多个禁用
|
||
multiple: true,
|
||
// 显示搜索条件
|
||
showSearch: true,
|
||
// 总条数
|
||
total: 0,
|
||
|
||
levelList: [],
|
||
|
||
userDataList: [],
|
||
// 用户列表表格数据
|
||
usersList: [],
|
||
// 弹出层标题
|
||
title: "",
|
||
// 是否显示弹出层
|
||
open: false,
|
||
// 查询参数
|
||
queryParams: {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
totalCommMin: null,
|
||
totalCommMax: null,
|
||
marginMin: null,
|
||
marginMax: null,
|
||
commissionMin: null,
|
||
commissionMax: null,
|
||
jobNumber: null,
|
||
type: '2',
|
||
name: null,
|
||
phone: null,
|
||
status: null,
|
||
},
|
||
// 表单参数
|
||
form: {},
|
||
// 表单校验
|
||
rules: {
|
||
name: [
|
||
{ required: true, message: "昵称不能为空", trigger: "blur" }
|
||
],
|
||
phone: [
|
||
{ required: true, message: "电话不能为空", trigger: "blur" }
|
||
],
|
||
status: [
|
||
{ required: true, message: "1:启用 0:关闭不能为空", trigger: "change" }
|
||
],
|
||
},
|
||
editDialogVisible: false,
|
||
editUser: {},
|
||
editMode: 'add',
|
||
workerMoneyLogDialogVisible: false,
|
||
currentWorkerId: null,
|
||
workerMarginLogDialogVisible: false,
|
||
workerLevelDialogVisible: false,
|
||
workerLevelUserId: null,
|
||
workerLevelUserName: '',
|
||
// 地区数据缓存
|
||
areaDataCache: {},
|
||
// 技能数据缓存
|
||
skillDataCache: {},
|
||
// 暂停接单弹窗相关
|
||
pauseOrderDialogVisible: false,
|
||
pauseOrderForm: {
|
||
name: '',
|
||
prohibitTimeNum: 1,
|
||
reason: ''
|
||
},
|
||
pauseOrderRules: {
|
||
prohibitTimeNum: [
|
||
{ required: true, message: '请选择暂停时长', trigger: 'change' }
|
||
]
|
||
},
|
||
pauseOrderLoading: false
|
||
}
|
||
},
|
||
created() {
|
||
this.getList()
|
||
this.getlevelList();
|
||
this.initAreaDataCache();
|
||
this.initSkillDataCache();
|
||
|
||
// 添加调试信息
|
||
console.log('UsersWorker - 组件创建完成');
|
||
},
|
||
mounted() {
|
||
// 确保在组件挂载后重新获取数据,以便格式化方法能正常工作
|
||
this.$nextTick(() => {
|
||
// 立即初始化缓存,不需要等待
|
||
console.log('UsersWorker - 组件挂载,立即初始化缓存');
|
||
this.initAreaDataCache();
|
||
this.initSkillDataCache();
|
||
|
||
// 等待一定时间后重新获取列表,让缓存有时间初始化
|
||
setTimeout(() => {
|
||
console.log('UsersWorker - 缓存初始化时间结束,重新获取列表数据');
|
||
this.getList();
|
||
}, 2000);
|
||
});
|
||
},
|
||
methods: {
|
||
/** 查询用户列表列表 */
|
||
getList() {
|
||
this.loading = true
|
||
listUsers(this.queryParams).then(response => {
|
||
this.usersList = response.rows
|
||
this.total = response.total
|
||
this.loading = false
|
||
|
||
// 检查暂停状态是否过期
|
||
this.checkExpiredPauseStatus();
|
||
|
||
// 添加调试信息,查看实际的数据格式
|
||
console.log('UsersWorker - 获取到的用户列表:', this.usersList);
|
||
if (this.usersList.length > 0) {
|
||
console.log('第一个用户的服务地区数据:', this.usersList[0].serviceCityIds, '类型:', typeof this.usersList[0].serviceCityIds);
|
||
}
|
||
})
|
||
},
|
||
// 取消按钮
|
||
cancel() {
|
||
this.open = false
|
||
this.reset()
|
||
},
|
||
// 表单重置
|
||
reset() {
|
||
this.form = {
|
||
id: null,
|
||
name: null,
|
||
nickname: null,
|
||
phone: null,
|
||
password: null,
|
||
rememberToken: null,
|
||
openid: null,
|
||
avatar: null,
|
||
type: null,
|
||
workerTime: null,
|
||
integral: null,
|
||
totalIntegral: null,
|
||
status: null,
|
||
level: null,
|
||
commission: null,
|
||
totalComm: null,
|
||
margin: null,
|
||
jobNumber: null,
|
||
prohibitTime: null,
|
||
prohibitTimeNum: null,
|
||
toa: null,
|
||
serviceCityPid: null,
|
||
serviceCityIds: null,
|
||
skillIds: null,
|
||
propose: null,
|
||
loginStatus: null,
|
||
isStop: null,
|
||
middleAuth: null,
|
||
createdAt: null,
|
||
updatedAt: null
|
||
}
|
||
this.resetForm("form")
|
||
},
|
||
/** 搜索按钮操作 */
|
||
handleQuery() {
|
||
this.queryParams.pageNum = 1
|
||
this.getList()
|
||
},
|
||
|
||
getlevelList(){
|
||
listWorkerLevel().then(response => {
|
||
this.levelList = response.rows
|
||
})
|
||
},
|
||
|
||
/** 重置按钮操作 */
|
||
resetQuery() {
|
||
this.resetForm("queryForm")
|
||
this.handleQuery()
|
||
},
|
||
// 多选框选中数据
|
||
handleSelectionChange(selection) {
|
||
this.ids = selection.map(item => item.id)
|
||
this.single = selection.length!==1
|
||
this.multiple = !selection.length
|
||
},
|
||
handleRowClick(row) {
|
||
updateUsers(row).then(() => {
|
||
this.$message.success('等级修改成功')
|
||
}).catch(error => {
|
||
console.error('等级修改失败:', error);
|
||
this.$message.error('等级修改失败,请重试');
|
||
// 如果更新失败,刷新列表恢复原状态
|
||
this.getList()
|
||
})
|
||
},
|
||
|
||
/** 新增按钮操作 */
|
||
handleAdd() {
|
||
this.editUser = {
|
||
name: undefined,
|
||
phone: undefined,
|
||
avatar: undefined,
|
||
prohibitTime: undefined,
|
||
prohibitTimeNum: 0,
|
||
serviceCityPid: undefined,
|
||
serviceCityIds: undefined,
|
||
skillIds: undefined,
|
||
commission: undefined,
|
||
status: 1
|
||
};
|
||
this.editMode = 'add';
|
||
this.editDialogVisible = true;
|
||
},
|
||
/** 修改按钮操作 */
|
||
handleUpdate(row) {
|
||
const id = row.id || this.ids
|
||
getUsers(id).then(response => {
|
||
this.editUser = response.data;
|
||
this.editMode = 'edit';
|
||
this.editDialogVisible = true;
|
||
})
|
||
},
|
||
// 状态修改
|
||
handleStatusChange(row) {
|
||
let text = row.status === "0" ? "启用" : "停用"
|
||
this.$modal.confirm('确认要"' + text + '""' + row.name + '"状态吗?').then(function() {
|
||
return changetypeStatus(row.id, row.status)
|
||
}).then(() => {
|
||
this.$modal.msgSuccess(text + "成功")
|
||
}).catch(function() {
|
||
row.status = row.status === "0" ? "1" : "0"
|
||
})
|
||
},
|
||
/** 提交按钮 */
|
||
submitForm() {
|
||
this.$refs["form"].validate(valid => {
|
||
if (valid) {
|
||
if (this.form.id != null) {
|
||
updateUsers(this.form).then(response => {
|
||
this.$modal.msgSuccess("修改成功")
|
||
this.open = false
|
||
this.getList()
|
||
})
|
||
} else {
|
||
addUsers(this.form).then(response => {
|
||
this.$modal.msgSuccess("新增成功")
|
||
this.open = false
|
||
this.getList()
|
||
})
|
||
}
|
||
}
|
||
})
|
||
},
|
||
/** 删除按钮操作 */
|
||
handleDelete(row) {
|
||
const ids = row.id || this.ids
|
||
this.$modal.confirm('是否确认删除用户列表编号为"' + ids + '"的数据项?').then(function() {
|
||
return delUsers(ids)
|
||
}).then(() => {
|
||
this.getList()
|
||
this.$modal.msgSuccess("删除成功")
|
||
}).catch(() => {})
|
||
},
|
||
/** 导出按钮操作 */
|
||
handleExport() {
|
||
this.download('system/users/export', {
|
||
...this.queryParams
|
||
}, `users_${new Date().getTime()}.xlsx`)
|
||
},
|
||
handleEditConfirm(user) {
|
||
if (this.editMode === 'add') {
|
||
addUsers(user).then(response => {
|
||
this.$modal.msgSuccess("新增成功");
|
||
this.editDialogVisible = false;
|
||
this.getList();
|
||
});
|
||
} else {
|
||
updateUsers(user).then(response => {
|
||
this.$modal.msgSuccess("修改成功");
|
||
this.editDialogVisible = false;
|
||
this.getList();
|
||
});
|
||
}
|
||
},
|
||
showWorkerMoneyLog(row) {
|
||
console.log('点击查看师傅佣金明细,师傅信息:', row);
|
||
if (!row || !row.id) {
|
||
this.$message.error('师傅信息不完整,无法查看佣金明细');
|
||
return;
|
||
}
|
||
this.currentWorkerId = row.id;
|
||
this.workerMoneyLogDialogVisible = true;
|
||
console.log('设置currentWorkerId:', this.currentWorkerId);
|
||
},
|
||
showWorkerMarginLog(row) {
|
||
console.log('点击查看师傅质保金明细,师傅信息:', row);
|
||
if (!row || !row.id) {
|
||
this.$message.error('师傅信息不完整,无法查看质保金明细');
|
||
return;
|
||
}
|
||
this.currentWorkerId = row.id;
|
||
this.workerMarginLogDialogVisible = true;
|
||
},
|
||
showWorkerLevelDialog(row) {
|
||
this.workerLevelUserId = row.id;
|
||
this.workerLevelUserName = row.name;
|
||
this.workerLevelDialogVisible = true;
|
||
},
|
||
handleWorkerLevelSelected() {
|
||
this.workerLevelDialogVisible = false;
|
||
this.getList(); // 选中后刷新列表
|
||
},
|
||
// 处理质保金变动事件
|
||
handleMarginChanged() {
|
||
console.log('质保金发生变动,刷新师傅列表');
|
||
this.getList(); // 刷新师傅列表,更新质保金显示
|
||
},
|
||
// 格式化服务区域显示
|
||
formatServiceAreas(serviceCityIds) {
|
||
if (!serviceCityIds) return '-';
|
||
try {
|
||
console.log('格式化服务区域,原始数据:', serviceCityIds, '类型:', typeof serviceCityIds);
|
||
|
||
// 如果是字符串,先转换为数组
|
||
let areaIds = [];
|
||
if (typeof serviceCityIds === 'string') {
|
||
// 处理可能是JSON字符串的情况
|
||
if (serviceCityIds.startsWith('[') && serviceCityIds.endsWith(']')) {
|
||
try {
|
||
areaIds = JSON.parse(serviceCityIds);
|
||
} catch (e) {
|
||
console.warn('JSON解析失败,使用逗号分隔:', e);
|
||
areaIds = serviceCityIds.replace(/[\[\]]/g, '').split(',').map(id => id.trim()).filter(id => id);
|
||
}
|
||
} else {
|
||
areaIds = serviceCityIds.split(',').map(id => id.trim()).filter(id => id);
|
||
}
|
||
} else if (Array.isArray(serviceCityIds)) {
|
||
areaIds = serviceCityIds;
|
||
} else {
|
||
areaIds = [serviceCityIds];
|
||
}
|
||
|
||
// 转换为数字数组
|
||
areaIds = areaIds.map(id => parseInt(id)).filter(id => !isNaN(id) && id > 0);
|
||
console.log('解析后的地区ID数组:', areaIds);
|
||
console.log('地区数据缓存:', this.areaDataCache);
|
||
|
||
if (areaIds.length === 0) return '-';
|
||
|
||
// 从缓存中获取地区名称
|
||
const areaNames = areaIds.map(id => {
|
||
const cached = this.areaDataCache[id];
|
||
console.log(`地区ID ${id} 对应的缓存数据:`, cached);
|
||
if (cached) {
|
||
return cached.title;
|
||
} else {
|
||
// 如果缓存中没有,尝试实时获取
|
||
this.loadAreaById(id);
|
||
return `区域${id}`; // 临时显示
|
||
}
|
||
});
|
||
|
||
const result = areaNames.join(', ');
|
||
console.log('格式化结果:', result);
|
||
return result;
|
||
} catch (error) {
|
||
console.error('格式化服务区域失败:', error);
|
||
return serviceCityIds;
|
||
}
|
||
},
|
||
// 格式化技能名称显示
|
||
formatSkillNames(skillIds) {
|
||
if (!skillIds) return '-';
|
||
try {
|
||
console.log('格式化技能名称,原始数据:', skillIds, '类型:', typeof skillIds);
|
||
|
||
// 如果是字符串,先转换为数组
|
||
let skillIdArray = [];
|
||
if (typeof skillIds === 'string') {
|
||
// 处理可能是JSON字符串的情况
|
||
if (skillIds.startsWith('[') && skillIds.endsWith(']')) {
|
||
try {
|
||
skillIdArray = JSON.parse(skillIds);
|
||
} catch (e) {
|
||
skillIdArray = skillIds.split(',').map(id => id.trim()).filter(id => id);
|
||
}
|
||
} else {
|
||
skillIdArray = skillIds.split(',').map(id => id.trim()).filter(id => id);
|
||
}
|
||
} else if (Array.isArray(skillIds)) {
|
||
skillIdArray = skillIds;
|
||
}
|
||
|
||
console.log('解析后的技能ID数组:', skillIdArray);
|
||
console.log('技能数据缓存:', this.skillDataCache);
|
||
|
||
if (skillIdArray.length === 0) return '-';
|
||
|
||
// 从缓存中获取技能名称
|
||
const skillNames = skillIdArray.map(id => {
|
||
const cached = this.skillDataCache[id];
|
||
console.log(`技能ID ${id} 对应的缓存数据:`, cached);
|
||
return cached ? cached.title : id;
|
||
});
|
||
|
||
const result = skillNames.join(', ');
|
||
console.log('格式化结果:', result);
|
||
return result;
|
||
} catch (error) {
|
||
console.error('格式化技能名称失败:', error);
|
||
return skillIds;
|
||
}
|
||
},
|
||
// 初始化地区数据缓存
|
||
initAreaDataCache() {
|
||
console.log('开始初始化地区数据缓存');
|
||
|
||
// 先添加一些常见的地区ID到缓存,以防API获取失败
|
||
const commonAreas = [
|
||
// 陕西省下的地区
|
||
{ id: 2, title: "新城区" },
|
||
{ id: 5, title: "碑林区" },
|
||
{ id: 7, title: "莲湖区" },
|
||
{ id: 10, title: "灞桥区" },
|
||
{ id: 11, title: "未央区" },
|
||
{ id: 12, title: "雁塔区" },
|
||
{ id: 13, title: "阎良区" },
|
||
{ id: 14, title: "临潼区" },
|
||
{ id: 15, title: "长安区" },
|
||
{ id: 16, title: "高陵区" },
|
||
{ id: 17, title: "鄠邑区" },
|
||
// 安徽省下的地区
|
||
{ id: 53, title: "瑶海区" },
|
||
{ id: 54, title: "庐阳区" },
|
||
{ id: 55, title: "蜀山区" },
|
||
{ id: 56, title: "包河区" },
|
||
{ id: 57, title: "经开区" },
|
||
{ id: 58, title: "高新区" }
|
||
];
|
||
commonAreas.forEach(area => {
|
||
this.areaDataCache[area.id] = area;
|
||
console.log(`添加常见地区到缓存: ${area.id} -> ${area.title}`);
|
||
});
|
||
|
||
// 获取所有省份数据
|
||
const queryParams = {
|
||
parentId: 0 // 查询一级城市(省份)
|
||
}
|
||
datalist(queryParams).then(response => {
|
||
console.log('获取省份数据成功:', response);
|
||
if (response.code === 200 && response.data) {
|
||
// 先缓存省份数据
|
||
response.data.forEach(province => {
|
||
this.areaDataCache[province.id] = province;
|
||
console.log(`添加省份到缓存: ${province.id} -> ${province.title}`);
|
||
});
|
||
|
||
// 为每个省份获取下级地区数据
|
||
const loadPromises = response.data.map(province => {
|
||
const cityParams = {
|
||
parentId: province.id
|
||
}
|
||
return datalist(cityParams).then(cityResponse => {
|
||
console.log(`获取城市数据成功 (${province.id}):`, cityResponse);
|
||
if (cityResponse.code === 200 && cityResponse.data) {
|
||
cityResponse.data.forEach(city => {
|
||
this.areaDataCache[city.id] = city;
|
||
console.log(`添加城市到缓存: ${city.id} -> ${city.title}`);
|
||
});
|
||
}
|
||
return cityResponse;
|
||
}).catch((error) => {
|
||
console.error(`获取城市数据失败 (${province.id}):`, error);
|
||
return Promise.resolve();
|
||
});
|
||
});
|
||
|
||
// 等待所有城市数据加载完成
|
||
Promise.all(loadPromises).then(() => {
|
||
console.log('所有地区数据加载完成,最终缓存:', this.areaDataCache);
|
||
// 数据加载完成后,重新渲染列表以显示正确的地区名称
|
||
this.$forceUpdate();
|
||
});
|
||
}
|
||
}).catch((error) => {
|
||
console.error('获取省份数据失败:', error);
|
||
// 如果获取省份数据失败,使用默认数据
|
||
const defaultProvinces = [
|
||
{ id: 1, title: "陕西省" },
|
||
{ id: 27, title: "上海市" },
|
||
{ id: 44, title: "湖南省" },
|
||
{ id: 52, title: "安徽省" }
|
||
];
|
||
defaultProvinces.forEach(province => {
|
||
this.areaDataCache[province.id] = province;
|
||
console.log(`添加默认省份到缓存: ${province.id} -> ${province.title}`);
|
||
});
|
||
});
|
||
},
|
||
// 初始化技能数据缓存
|
||
initSkillDataCache() {
|
||
console.log('开始初始化技能数据缓存');
|
||
getSiteSkillList().then(response => {
|
||
console.log('获取技能数据成功:', response);
|
||
if (response.code === 200 && response.data) {
|
||
response.data.forEach(skill => {
|
||
this.skillDataCache[skill.id] = skill;
|
||
console.log(`添加技能到缓存: ${skill.id} -> ${skill.title}`);
|
||
});
|
||
}
|
||
}).catch((error) => {
|
||
console.error('获取技能数据失败:', error);
|
||
// 如果获取技能数据失败,使用默认数据
|
||
const defaultSkills = [
|
||
{ id: 1, title: '水电工' },
|
||
{ id: 2, title: '油工师傅' },
|
||
{ id: 3, title: '改造维修' },
|
||
{ id: 4, title: '工程施工' }
|
||
];
|
||
defaultSkills.forEach(skill => {
|
||
this.skillDataCache[skill.id] = skill;
|
||
console.log(`添加默认技能到缓存: ${skill.id} -> ${skill.title}`);
|
||
});
|
||
});
|
||
},
|
||
// 根据ID加载地区数据
|
||
loadAreaById(id) {
|
||
if (this.areaDataCache[id]) {
|
||
return; // 如果已缓存,则直接返回
|
||
}
|
||
|
||
// 使用getDiyCity API根据ID获取单个地区数据
|
||
getDiyCity(id).then(response => {
|
||
if (response.code === 200 && response.data) {
|
||
this.areaDataCache[id] = response.data;
|
||
console.log(`从API加载地区到缓存: ${id} -> ${response.data.title}`);
|
||
// 如果加载成功,重新渲染列表以显示正确的地区名称
|
||
this.$forceUpdate();
|
||
} else {
|
||
console.warn(`API加载地区失败,ID: ${id}, 响应:`, response);
|
||
}
|
||
}).catch((error) => {
|
||
console.error(`API加载地区失败,ID: ${id}:`, error);
|
||
});
|
||
},
|
||
|
||
// 暂停接单按钮操作
|
||
handlePauseOrder(row) {
|
||
console.log('点击暂停接单,师傅信息:', row);
|
||
if (!row || !row.id) {
|
||
this.$message.error('师傅信息不完整,无法暂停接单');
|
||
return;
|
||
}
|
||
|
||
// 重置表单数据
|
||
this.pauseOrderForm = {
|
||
id: row.id,
|
||
name: row.name,
|
||
prohibitTimeNum: 1,
|
||
reason: ''
|
||
};
|
||
|
||
// 清除表单验证
|
||
this.$nextTick(() => {
|
||
if (this.$refs.pauseOrderForm) {
|
||
this.$refs.pauseOrderForm.clearValidate();
|
||
}
|
||
});
|
||
|
||
this.pauseOrderDialogVisible = true;
|
||
},
|
||
|
||
// 减少暂停时间
|
||
decreasePauseTime() {
|
||
if (this.pauseOrderForm.prohibitTimeNum > 1) {
|
||
this.pauseOrderForm.prohibitTimeNum--;
|
||
}
|
||
},
|
||
|
||
// 增加暂停时间
|
||
increasePauseTime() {
|
||
if (this.pauseOrderForm.prohibitTimeNum < 168) {
|
||
this.pauseOrderForm.prohibitTimeNum++;
|
||
}
|
||
},
|
||
|
||
// 确认暂停接单
|
||
confirmPauseOrder() {
|
||
this.$refs.pauseOrderForm.validate(valid => {
|
||
if (valid) {
|
||
this.pauseOrderLoading = true;
|
||
|
||
const pauseData = {
|
||
id: this.pauseOrderForm.id,
|
||
prohibitTimeNum: this.pauseOrderForm.prohibitTimeNum
|
||
};
|
||
|
||
pauseOrder(pauseData).then(response => {
|
||
this.$modal.msgSuccess(`已成功暂停师傅"${this.pauseOrderForm.name}"接单${this.pauseOrderForm.prohibitTimeNum}小时`);
|
||
this.pauseOrderDialogVisible = false;
|
||
this.getList(); // 刷新列表
|
||
}).catch(error => {
|
||
console.error('暂停接单失败:', error);
|
||
this.$modal.msgError('暂停接单失败,请重试');
|
||
}).finally(() => {
|
||
this.pauseOrderLoading = false;
|
||
});
|
||
}
|
||
});
|
||
},
|
||
|
||
// 恢复接单按钮操作
|
||
handleResumeOrder(row) {
|
||
console.log('点击恢复接单,师傅信息:', row);
|
||
if (!row || !row.id) {
|
||
this.$message.error('师傅信息不完整,无法恢复接单');
|
||
return;
|
||
}
|
||
|
||
this.$modal.confirm(`确认要恢复师傅"${row.name}"的接单状态吗?`).then(() => {
|
||
this.resumeOrder(row.id, row.name);
|
||
}).catch(() => {
|
||
console.log('用户取消恢复接单操作');
|
||
});
|
||
},
|
||
|
||
// 恢复接单
|
||
resumeOrder(userId, userName) {
|
||
const resumeData = {
|
||
id: userId,
|
||
prohibitTimeNum: 0,
|
||
isStop: 0
|
||
};
|
||
|
||
updateUsers(resumeData).then(response => {
|
||
this.$modal.msgSuccess(`已成功恢复师傅"${userName}"的接单状态`);
|
||
this.getList(); // 刷新列表
|
||
}).catch(error => {
|
||
console.error('恢复接单失败:', error);
|
||
this.$modal.msgError('恢复接单失败,请重试');
|
||
});
|
||
},
|
||
// 检查并更新过期暂停状态
|
||
checkExpiredPauseStatus() {
|
||
const now = new Date();
|
||
let hasExpired = false;
|
||
|
||
this.usersList.forEach(user => {
|
||
if (user.isStop === 1 && user.prohibitTime) {
|
||
const prohibitTime = new Date(user.prohibitTime);
|
||
if (prohibitTime < now) {
|
||
// 如果暂停时间已过期,标记为已过期但不立即更新数据库
|
||
user.isExpired = true;
|
||
hasExpired = true;
|
||
console.log(`师傅"${user.name}"的暂停时间已过期`);
|
||
}
|
||
}
|
||
});
|
||
|
||
// 如果有过期的暂停状态,显示提示信息
|
||
if (hasExpired) {
|
||
this.$message.info('检测到部分师傅的暂停时间已过期,请手动恢复接单状态。');
|
||
}
|
||
},
|
||
// 更新用户状态
|
||
updateUserStatus(id, status) {
|
||
changetypeStatus(id, status).then(() => {
|
||
this.$message.success(`用户状态更新成功`);
|
||
this.getList(); // 刷新列表以显示最新的状态
|
||
}).catch(error => {
|
||
console.error('更新用户状态失败:', error);
|
||
this.$message.error('更新用户状态失败,请重试');
|
||
});
|
||
},
|
||
// 手动恢复师傅暂停状态
|
||
handleManualResumeWorkerStatus() {
|
||
this.$modal.confirm('确认要执行师傅暂停状态自动恢复任务吗?此操作将检查所有暂停的师傅,并自动恢复已过期的师傅接单状态。').then(() => {
|
||
this.executeManualResumeWorkerStatus();
|
||
}).catch(() => {
|
||
console.log('用户取消手动恢复过期暂停操作');
|
||
});
|
||
},
|
||
// 执行师傅暂停状态自动恢复
|
||
executeManualResumeWorkerStatus() {
|
||
// 显示加载状态
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: '正在执行师傅暂停状态恢复任务...',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
|
||
manualResumeWorkerStatus().then(response => {
|
||
loading.close();
|
||
if (response.code === 200) {
|
||
this.$message.success(response.msg || '师傅暂停状态自动恢复任务执行成功');
|
||
// 刷新列表以显示最新状态
|
||
this.getList();
|
||
} else {
|
||
this.$message.error(response.msg || '师傅暂停状态自动恢复任务执行失败');
|
||
}
|
||
}).catch(error => {
|
||
loading.close();
|
||
console.error('执行师傅暂停状态自动恢复失败:', error);
|
||
this.$message.error('执行师傅暂停状态自动恢复失败,请重试');
|
||
});
|
||
},
|
||
// 批量恢复过期暂停状态
|
||
resumeAllExpiredWorkers() {
|
||
const expiredUsers = this.usersList.filter(user => user.isStop === 1 && user.isExpired);
|
||
if (expiredUsers.length === 0) {
|
||
this.$message.info('没有过期暂停的师傅。');
|
||
return;
|
||
}
|
||
|
||
const userIds = expiredUsers.map(user => user.id);
|
||
const userNames = expiredUsers.map(user => user.name);
|
||
|
||
this.$modal.confirm(`确认要恢复以下${userIds.length}个师傅的接单状态吗?\n${userNames.join('、')}`).then(() => {
|
||
const resumePromises = userIds.map(id => {
|
||
const resumeData = {
|
||
id: id,
|
||
prohibitTimeNum: 0,
|
||
isStop: 0
|
||
};
|
||
return updateUsers(resumeData);
|
||
});
|
||
|
||
Promise.all(resumePromises).then(() => {
|
||
this.$message.success(`已成功恢复${userIds.length}个师傅的接单状态。`);
|
||
this.getList(); // 刷新列表
|
||
}).catch(error => {
|
||
console.error('批量恢复过期暂停失败:', error);
|
||
this.$message.error('批量恢复过期暂停失败,请重试');
|
||
});
|
||
}).catch(() => {
|
||
console.log('用户取消批量恢复过期暂停操作');
|
||
});
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.time-input {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.selected-tags {
|
||
margin-top: 8px;
|
||
max-width: 100%;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.selected-tags .el-tag {
|
||
margin: 2px;
|
||
max-width: 200px;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.time-input .el-button {
|
||
border-radius: 4px;
|
||
margin: 0 5px;
|
||
}
|
||
|
||
.time-input .el-input-number {
|
||
margin: 0 5px;
|
||
}
|
||
|
||
.expired-time {
|
||
color: #E6A23C;
|
||
font-weight: bold;
|
||
text-decoration: line-through;
|
||
}
|
||
|
||
/* 等级选择器样式 */
|
||
.level-container {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
.level-select-custom {
|
||
width: 80px !important;
|
||
font-weight: 600;
|
||
border-radius: 20px;
|
||
transition: all 0.3s ease;
|
||
border-width: 2px;
|
||
}
|
||
|
||
.level-select-custom:hover {
|
||
transform: translateY(-1px);
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||
}
|
||
|
||
.level-select-custom:focus-within {
|
||
transform: translateY(-1px);
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
|
||
}
|
||
|
||
/* 不同等级的颜色样式 */
|
||
.level-1 {
|
||
background-color: #f8f9fa;
|
||
border-color: #6c757d;
|
||
color: #495057;
|
||
}
|
||
|
||
.level-1:hover {
|
||
border-color: #5a6268;
|
||
background-color: #f1f3f4;
|
||
}
|
||
|
||
.level-2 {
|
||
background-color: #e8f5e8;
|
||
border-color: #28a745;
|
||
color: #155724;
|
||
}
|
||
|
||
.level-2:hover {
|
||
border-color: #1e7e34;
|
||
background-color: #d1ecf1;
|
||
}
|
||
|
||
.level-3 {
|
||
background-color: #e3f2fd;
|
||
border-color: #2196f3;
|
||
color: #0d47a1;
|
||
}
|
||
|
||
.level-3:hover {
|
||
border-color: #1976d2;
|
||
background-color: #bbdefb;
|
||
}
|
||
|
||
.level-4 {
|
||
background-color: #fff3e0;
|
||
border-color: #ff9800;
|
||
color: #e65100;
|
||
}
|
||
|
||
.level-4:hover {
|
||
border-color: #f57c00;
|
||
background-color: #ffe0b2;
|
||
}
|
||
|
||
.level-5 {
|
||
background-color: #ffebee;
|
||
border-color: #f44336;
|
||
color: #b71c1c;
|
||
}
|
||
|
||
.level-5:hover {
|
||
border-color: #d32f2f;
|
||
background-color: #ffcdd2;
|
||
}
|
||
|
||
/* 下拉选项样式 */
|
||
.level-option-item {
|
||
padding: 8px 16px !important;
|
||
border-radius: 6px;
|
||
margin: 2px 4px;
|
||
transition: all 0.2s ease;
|
||
}
|
||
|
||
.level-option-item:hover {
|
||
background-color: #f8f9fa !important;
|
||
transform: translateX(4px);
|
||
}
|
||
|
||
.level-option-wrapper {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
width: 100%;
|
||
}
|
||
|
||
.level-text {
|
||
font-weight: 500;
|
||
color: #333;
|
||
}
|
||
|
||
.level-number {
|
||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
color: white;
|
||
border-radius: 50%;
|
||
width: 20px;
|
||
height: 20px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 12px;
|
||
font-weight: bold;
|
||
margin-left: 8px;
|
||
}
|
||
|
||
/* 选择器下拉箭头样式优化 */
|
||
.level-select-custom .el-input__suffix {
|
||
right: 8px;
|
||
}
|
||
|
||
.level-select-custom .el-input__suffix .el-input__suffix-inner .el-select__caret {
|
||
color: inherit;
|
||
font-size: 14px;
|
||
transition: transform 0.3s ease;
|
||
}
|
||
|
||
.level-select-custom.is-focus .el-select__caret {
|
||
transform: rotateZ(180deg);
|
||
}
|
||
|
||
/* 响应式设计 */
|
||
@media (max-width: 768px) {
|
||
.level-select-custom {
|
||
width: 70px !important;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.level-number {
|
||
width: 16px;
|
||
height: 16px;
|
||
font-size: 10px;
|
||
}
|
||
}
|
||
</style>
|