|
@@ -1,29 +1,9 @@
|
|
|
<template>
|
|
<template>
|
|
|
<div class="personnel-config-container">
|
|
<div class="personnel-config-container">
|
|
|
- <!-- 操作按钮区域 -->
|
|
|
|
|
- <div class="action-section">
|
|
|
|
|
- <el-button v-if="!hasTitle" type="primary" @click="handleCreateTitle"> 创建标题 </el-button>
|
|
|
|
|
- <el-button type="primary" @click="openCreateDialog"> 创建人员 </el-button>
|
|
|
|
|
- </div>
|
|
|
|
|
-
|
|
|
|
|
- <!-- 表格区域 -->
|
|
|
|
|
|
|
+ <!-- 表格区域:工具栏在表格上方左侧 -->
|
|
|
<div class="table-box button-table">
|
|
<div class="table-box button-table">
|
|
|
- <div class="table-header-title">
|
|
|
|
|
- <span class="table-title">演出人员</span>
|
|
|
|
|
- <el-dropdown v-if="hasTitle" trigger="click" @command="handleTitleCommand">
|
|
|
|
|
- <el-icon class="table-icon">
|
|
|
|
|
- <ArrowDown />
|
|
|
|
|
- </el-icon>
|
|
|
|
|
- <template #dropdown>
|
|
|
|
|
- <el-dropdown-menu>
|
|
|
|
|
- <el-dropdown-item command="edit"> 编辑标题 </el-dropdown-item>
|
|
|
|
|
- <el-dropdown-item command="delete"> 删除标题 </el-dropdown-item>
|
|
|
|
|
- </el-dropdown-menu>
|
|
|
|
|
- </template>
|
|
|
|
|
- </el-dropdown>
|
|
|
|
|
- <el-icon v-else class="table-icon">
|
|
|
|
|
- <ArrowDown />
|
|
|
|
|
- </el-icon>
|
|
|
|
|
|
|
+ <div class="personnel-table-toolbar">
|
|
|
|
|
+ <el-button type="primary"> 人员 </el-button>
|
|
|
</div>
|
|
</div>
|
|
|
<ProTable
|
|
<ProTable
|
|
|
ref="proTable"
|
|
ref="proTable"
|
|
@@ -32,6 +12,11 @@
|
|
|
:init-param="initParam"
|
|
:init-param="initParam"
|
|
|
:data-callback="dataCallback"
|
|
:data-callback="dataCallback"
|
|
|
>
|
|
>
|
|
|
|
|
+ <template #tableHeader>
|
|
|
|
|
+ <div class="personnel-table-header-actions">
|
|
|
|
|
+ <el-button type="primary" @click="openCreateDialog"> 新增人员 </el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </template>
|
|
|
<template #empty>
|
|
<template #empty>
|
|
|
<div class="personnel-config-empty">暂无数据</div>
|
|
<div class="personnel-config-empty">暂无数据</div>
|
|
|
</template>
|
|
</template>
|
|
@@ -44,7 +29,7 @@
|
|
|
<!-- 已驳回(status === 2):显示编辑、删除、查看详情 -->
|
|
<!-- 已驳回(status === 2):显示编辑、删除、查看详情 -->
|
|
|
<template v-else-if="scope.row.status === 2 || scope.row.status === '2'">
|
|
<template v-else-if="scope.row.status === 2 || scope.row.status === '2'">
|
|
|
<el-button type="primary" link @click="editPersonnel(scope.row, 0)"> 编辑 </el-button>
|
|
<el-button type="primary" link @click="editPersonnel(scope.row, 0)"> 编辑 </el-button>
|
|
|
- <el-button type="primary" link @click="deletePersonnelHandler(scope.row.id!, 0)"> 删除 </el-button>
|
|
|
|
|
|
|
+ <el-button type="danger" link @click="deletePersonnelHandler(scope.row.id!, 0)"> 删除 </el-button>
|
|
|
<el-button type="primary" link @click="handleViewDetail(scope.row)"> 查看详情 </el-button>
|
|
<el-button type="primary" link @click="handleViewDetail(scope.row)"> 查看详情 </el-button>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
@@ -76,7 +61,7 @@
|
|
|
取消置顶
|
|
取消置顶
|
|
|
</el-button>
|
|
</el-button>
|
|
|
<el-button v-else type="primary" link @click="handlePin(scope.row)"> 置顶 </el-button>
|
|
<el-button v-else type="primary" link @click="handlePin(scope.row)"> 置顶 </el-button>
|
|
|
- <el-button type="primary" link @click="deletePersonnelHandler(scope.row.id!, 0)"> 删除 </el-button>
|
|
|
|
|
|
|
+ <el-button type="danger" link @click="deletePersonnelHandler(scope.row.id!, 0)"> 删除 </el-button>
|
|
|
<el-button type="primary" link @click="handleViewDetail(scope.row)"> 查看详情 </el-button>
|
|
<el-button type="primary" link @click="handleViewDetail(scope.row)"> 查看详情 </el-button>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
@@ -180,18 +165,30 @@
|
|
|
<div class="detail-item">
|
|
<div class="detail-item">
|
|
|
<div class="detail-label">在线状态:</div>
|
|
<div class="detail-label">在线状态:</div>
|
|
|
<div class="detail-value">
|
|
<div class="detail-value">
|
|
|
- <span v-if="personnelDetail.onlineStatus === 0 || personnelDetail.onlineStatus === '0'">上线</span>
|
|
|
|
|
- <span v-else-if="personnelDetail.onlineStatus === 1 || personnelDetail.onlineStatus === '1'">下线</span>
|
|
|
|
|
- <span v-else>—</span>
|
|
|
|
|
|
|
+ <span v-if="personnelDetail.onlineStatus === 1 || personnelDetail.onlineStatus === '1'" class="personnel-cell-dash"
|
|
|
|
|
+ >—</span
|
|
|
|
|
+ >
|
|
|
|
|
+ <span
|
|
|
|
|
+ v-else-if="personnelDetail.onlineStatus === 0 || personnelDetail.onlineStatus === '0'"
|
|
|
|
|
+ class="personnel-cell-online-up"
|
|
|
|
|
+ >在线</span
|
|
|
|
|
+ >
|
|
|
|
|
+ <span v-else class="personnel-cell-dash">—</span>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="detail-item">
|
|
<div class="detail-item">
|
|
|
<div class="detail-label">审核状态:</div>
|
|
<div class="detail-label">审核状态:</div>
|
|
|
<div class="detail-value">
|
|
<div class="detail-value">
|
|
|
- <el-tag v-if="personnelDetail.status === 1 || personnelDetail.status === '1'" type="success"> 已通过 </el-tag>
|
|
|
|
|
- <el-tag v-else-if="personnelDetail.status === 2 || personnelDetail.status === '2'" type="danger"> 已驳回 </el-tag>
|
|
|
|
|
- <el-tag v-else-if="personnelDetail.status === 0 || personnelDetail.status === '0'" type="info"> 待审核 </el-tag>
|
|
|
|
|
- <span v-else>—</span>
|
|
|
|
|
|
|
+ <span v-if="personnelDetail.status === 1 || personnelDetail.status === '1'" class="personnel-cell-pass"
|
|
|
|
|
+ >已通过</span
|
|
|
|
|
+ >
|
|
|
|
|
+ <span v-else-if="personnelDetail.status === 2 || personnelDetail.status === '2'" class="personnel-cell-reject"
|
|
|
|
|
+ >已驳回</span
|
|
|
|
|
+ >
|
|
|
|
|
+ <span v-else-if="personnelDetail.status === 0 || personnelDetail.status === '0'" class="personnel-cell-pending"
|
|
|
|
|
+ >待审核</span
|
|
|
|
|
+ >
|
|
|
|
|
+ <span v-else class="personnel-cell-dash">—</span>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
<div v-if="personnelDetail.status === 2 || personnelDetail.status === '2'" class="detail-item">
|
|
<div v-if="personnelDetail.status === 2 || personnelDetail.status === '2'" class="detail-item">
|
|
@@ -330,7 +327,7 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
-import { ref, reactive, computed, onMounted, watch, nextTick } from "vue";
|
|
|
|
|
|
|
+import { ref, reactive, computed, onMounted, watch, nextTick, h } from "vue";
|
|
|
import { ElMessage, ElMessageBox } from "element-plus";
|
|
import { ElMessage, ElMessageBox } from "element-plus";
|
|
|
import type { FormInstance, FormRules } from "element-plus";
|
|
import type { FormInstance, FormRules } from "element-plus";
|
|
|
import { Picture, Plus, Delete, ArrowDown, VideoPlay } from "@element-plus/icons-vue";
|
|
import { Picture, Plus, Delete, ArrowDown, VideoPlay } from "@element-plus/icons-vue";
|
|
@@ -411,10 +408,10 @@ const titleRules = reactive<FormRules>({
|
|
|
// 标题弹窗标题
|
|
// 标题弹窗标题
|
|
|
const titleDialogTitle = computed(() => (titleEditId.value !== null ? "修改标题" : "创建标题"));
|
|
const titleDialogTitle = computed(() => (titleEditId.value !== null ? "修改标题" : "创建标题"));
|
|
|
|
|
|
|
|
-// 在线状态枚举 - 0: 上线, 1: 下线
|
|
|
|
|
|
|
+// 在线状态枚举 - 0: 在线, 1: 离线(列表展示为「—」)
|
|
|
const onlineStatusEnum = [
|
|
const onlineStatusEnum = [
|
|
|
- { label: "上线", value: 0 },
|
|
|
|
|
- { label: "下线", value: 1 }
|
|
|
|
|
|
|
+ { label: "在线", value: 0 },
|
|
|
|
|
+ { label: "离线", value: 1 }
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
// 审核状态枚举
|
|
// 审核状态枚举
|
|
@@ -441,6 +438,29 @@ const formatTime = (time: string | null | undefined) => {
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+/** ProTable「职位」筛选项:GET alienStore/storeStaffTitle/query?storeId= */
|
|
|
|
|
+async function fetchPositionSearchEnum() {
|
|
|
|
|
+ const storeId = localGet("geeker-user")?.userInfo?.storeId || localGet("createdId");
|
|
|
|
|
+ if (!storeId) return { data: [] as { label: string; value: string }[] };
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res: any = await queryStaffTitle({ storeId });
|
|
|
|
|
+ const inner = res?.data;
|
|
|
|
|
+ const raw = Array.isArray(inner) ? inner : (inner?.records ?? inner?.list ?? []);
|
|
|
|
|
+ const arr = Array.isArray(raw) ? raw : [];
|
|
|
|
|
+ const seen = new Set<string>();
|
|
|
|
|
+ const list: { label: string; value: string }[] = [];
|
|
|
|
|
+ for (const item of arr) {
|
|
|
|
|
+ const title = String(item.titleName ?? item.name ?? item.positionName ?? "").trim();
|
|
|
|
|
+ if (!title || seen.has(title)) continue;
|
|
|
|
|
+ seen.add(title);
|
|
|
|
|
+ list.push({ label: title, value: title });
|
|
|
|
|
+ }
|
|
|
|
|
+ return { data: list };
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ return { data: [] };
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
// 表格配置项
|
|
// 表格配置项
|
|
|
const columns = reactive<ColumnProps<any>[]>([
|
|
const columns = reactive<ColumnProps<any>[]>([
|
|
|
{
|
|
{
|
|
@@ -465,9 +485,11 @@ const columns = reactive<ColumnProps<any>[]>([
|
|
|
prop: "position",
|
|
prop: "position",
|
|
|
label: "职位",
|
|
label: "职位",
|
|
|
minWidth: 100,
|
|
minWidth: 100,
|
|
|
|
|
+ fieldNames: { label: "label", value: "value" },
|
|
|
|
|
+ enum: fetchPositionSearchEnum,
|
|
|
search: {
|
|
search: {
|
|
|
- el: "input",
|
|
|
|
|
- props: { placeholder: "请输入" },
|
|
|
|
|
|
|
+ el: "select",
|
|
|
|
|
+ props: { placeholder: "请选择", filterable: true, clearable: true },
|
|
|
order: 2
|
|
order: 2
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
@@ -494,9 +516,13 @@ const columns = reactive<ColumnProps<any>[]>([
|
|
|
order: 3
|
|
order: 3
|
|
|
},
|
|
},
|
|
|
render: (scope: any) => {
|
|
render: (scope: any) => {
|
|
|
- if (scope.row.onlineStatus === 0 || scope.row.onlineStatus === "0") return "上线";
|
|
|
|
|
- if (scope.row.onlineStatus === 1 || scope.row.onlineStatus === "1") return "下线";
|
|
|
|
|
- return "—";
|
|
|
|
|
|
|
+ if (scope.row.onlineStatus === 1 || scope.row.onlineStatus === "1") {
|
|
|
|
|
+ return h("span", { class: "personnel-cell-dash" }, "—");
|
|
|
|
|
+ }
|
|
|
|
|
+ if (scope.row.onlineStatus === 0 || scope.row.onlineStatus === "0") {
|
|
|
|
|
+ return h("span", { class: "personnel-cell-online-up" }, "在线");
|
|
|
|
|
+ }
|
|
|
|
|
+ return h("span", { class: "personnel-cell-dash" }, "—");
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
{
|
|
{
|
|
@@ -505,17 +531,22 @@ const columns = reactive<ColumnProps<any>[]>([
|
|
|
width: 120,
|
|
width: 120,
|
|
|
enum: approvalStatusEnum,
|
|
enum: approvalStatusEnum,
|
|
|
fieldNames: { label: "label", value: "value" },
|
|
fieldNames: { label: "label", value: "value" },
|
|
|
- tag: true,
|
|
|
|
|
search: {
|
|
search: {
|
|
|
el: "select",
|
|
el: "select",
|
|
|
props: { placeholder: "请选择" },
|
|
props: { placeholder: "请选择" },
|
|
|
order: 4
|
|
order: 4
|
|
|
},
|
|
},
|
|
|
render: (scope: any) => {
|
|
render: (scope: any) => {
|
|
|
- if (scope.row.approvalStatus === 1 || scope.row.approvalStatus === "1") return "已通过";
|
|
|
|
|
- if (scope.row.approvalStatus === 2 || scope.row.approvalStatus === "2") return "已驳回";
|
|
|
|
|
- if (scope.row.approvalStatus === 0 || scope.row.approvalStatus === "0") return "待审核";
|
|
|
|
|
- return "—";
|
|
|
|
|
|
|
+ if (scope.row.approvalStatus === 1 || scope.row.approvalStatus === "1") {
|
|
|
|
|
+ return h("span", { class: "personnel-cell-pass" }, "已通过");
|
|
|
|
|
+ }
|
|
|
|
|
+ if (scope.row.approvalStatus === 2 || scope.row.approvalStatus === "2") {
|
|
|
|
|
+ return h("span", { class: "personnel-cell-reject" }, "已驳回");
|
|
|
|
|
+ }
|
|
|
|
|
+ if (scope.row.approvalStatus === 0 || scope.row.approvalStatus === "0") {
|
|
|
|
|
+ return h("span", { class: "personnel-cell-pending" }, "待审核");
|
|
|
|
|
+ }
|
|
|
|
|
+ return h("span", { class: "personnel-cell-dash" }, "—");
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
{
|
|
{
|
|
@@ -1226,8 +1257,13 @@ const handleTitleSubmit = async () => {
|
|
|
params.id = titleEditId.value;
|
|
params.id = titleEditId.value;
|
|
|
res = await updateTitle(params);
|
|
res = await updateTitle(params);
|
|
|
} else {
|
|
} else {
|
|
|
- // 创建标题
|
|
|
|
|
- res = await createTitle(params);
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ res = await createTitle(params, { hideBusinessErrorMessage: true });
|
|
|
|
|
+ } catch {
|
|
|
|
|
+ ElMessage.error("此名称已存在");
|
|
|
|
|
+ titleSubmitLoading.value = false;
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (res && (res.code === 200 || res.code === "200")) {
|
|
if (res && (res.code === 200 || res.code === "200")) {
|
|
@@ -2300,31 +2336,40 @@ onMounted(async () => {
|
|
|
min-height: 100%;
|
|
min-height: 100%;
|
|
|
padding: 20px;
|
|
padding: 20px;
|
|
|
background-color: white;
|
|
background-color: white;
|
|
|
- .action-section {
|
|
|
|
|
|
|
+ .personnel-table-toolbar {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
|
|
+ flex-wrap: wrap;
|
|
|
gap: 12px;
|
|
gap: 12px;
|
|
|
|
|
+ align-items: center;
|
|
|
margin-bottom: 16px;
|
|
margin-bottom: 16px;
|
|
|
|
|
+ .title-dropdown-trigger {
|
|
|
|
|
+ display: inline-flex;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /* 列表:在线状态 / 审核状态 文字颜色 */
|
|
|
|
|
+ :deep(.personnel-cell-online-up) {
|
|
|
|
|
+ color: var(--el-color-success);
|
|
|
|
|
+ }
|
|
|
|
|
+ :deep(.personnel-cell-dash) {
|
|
|
|
|
+ color: var(--el-text-color-secondary);
|
|
|
|
|
+ }
|
|
|
|
|
+ :deep(.personnel-cell-pass) {
|
|
|
|
|
+ color: var(--el-color-success);
|
|
|
|
|
+ }
|
|
|
|
|
+ :deep(.personnel-cell-reject) {
|
|
|
|
|
+ color: var(--el-color-danger);
|
|
|
|
|
+ }
|
|
|
|
|
+ :deep(.personnel-cell-pending) {
|
|
|
|
|
+ color: var(--el-color-warning);
|
|
|
}
|
|
}
|
|
|
.table-box {
|
|
.table-box {
|
|
|
- .table-header-title {
|
|
|
|
|
|
|
+ :deep(.personnel-table-header-actions) {
|
|
|
display: flex;
|
|
display: flex;
|
|
|
align-items: center;
|
|
align-items: center;
|
|
|
- margin-bottom: 16px;
|
|
|
|
|
- font-size: 16px;
|
|
|
|
|
- font-weight: 500;
|
|
|
|
|
- color: var(--el-text-color-primary);
|
|
|
|
|
- .table-title {
|
|
|
|
|
- margin-right: 8px;
|
|
|
|
|
- }
|
|
|
|
|
- .table-icon {
|
|
|
|
|
- font-size: 16px;
|
|
|
|
|
- color: var(--el-text-color-regular);
|
|
|
|
|
- cursor: pointer;
|
|
|
|
|
- transition: transform 0.3s;
|
|
|
|
|
- &:hover {
|
|
|
|
|
- color: var(--el-color-primary);
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ padding: 12px 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* 列表为空时去掉空状态残留图形/背景,仅显示「暂无数据」文字 */
|
|
/* 列表为空时去掉空状态残留图形/背景,仅显示「暂无数据」文字 */
|