|
|
@@ -9,26 +9,12 @@
|
|
|
<div class="employee-selector">
|
|
|
<div class="employee-selector__search">
|
|
|
<el-form :model="searchForm" inline>
|
|
|
- <el-form-item label="部门">
|
|
|
- <el-select v-model="searchForm.department_id" placeholder="选择部门" style="width: 120px">
|
|
|
- <el-option value="" label="全部" />
|
|
|
- <el-option
|
|
|
- v-for="dept in departments"
|
|
|
- :key="dept.value"
|
|
|
- :label="dept.label"
|
|
|
- :value="dept.value"
|
|
|
- />
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
<el-form-item label="姓名">
|
|
|
<el-input v-model="searchForm.name" placeholder="输入员工姓名" style="width: 120px" />
|
|
|
</el-form-item>
|
|
|
<el-form-item label="手机号">
|
|
|
<el-input v-model="searchForm.phone" placeholder="输入员工手机号" style="width: 120px" />
|
|
|
</el-form-item>
|
|
|
- <el-form-item label="邮箱">
|
|
|
- <el-input v-model="searchForm.email" placeholder="请输入邮箱" style="width: 120px" />
|
|
|
- </el-form-item>
|
|
|
</el-form>
|
|
|
<div class="employee-selector__actions">
|
|
|
<el-button type="default" @click="handleReset">重置</el-button>
|
|
|
@@ -39,7 +25,7 @@
|
|
|
<div class="employee-selector__tabs">
|
|
|
<el-tabs v-model="activeTab" @tab-change="handleTabChange">
|
|
|
<el-tab-pane label="全部" name="all" />
|
|
|
- <el-tab-pane label="已选 ({{ selectedEmployees.length }}人)" name="selected" />
|
|
|
+ <el-tab-pane label="已选 ({{ selectedIds.length }}人)" name="selected" />
|
|
|
</el-tabs>
|
|
|
</div>
|
|
|
|
|
|
@@ -47,16 +33,14 @@
|
|
|
<el-table
|
|
|
ref="tableRef"
|
|
|
:data="displayEmployees"
|
|
|
- :show-header="true"
|
|
|
+ row-key="id"
|
|
|
border
|
|
|
:max-height="300"
|
|
|
@selection-change="handleSelectionChange"
|
|
|
>
|
|
|
- <el-table-column type="selection" width="50" />
|
|
|
+ <el-table-column type="selection" width="50" :reserve-selection="true" />
|
|
|
<el-table-column label="员工姓名" prop="name" />
|
|
|
- <el-table-column label="员工部门" prop="department" />
|
|
|
- <el-table-column label="手机号" prop="phone" />
|
|
|
- <el-table-column label="邮箱" prop="email" />
|
|
|
+ <el-table-column label="手机号" prop="phone" width="140" />
|
|
|
</el-table>
|
|
|
</div>
|
|
|
|
|
|
@@ -67,6 +51,7 @@
|
|
|
:total="pagination.total"
|
|
|
:page-sizes="[10, 20, 50]"
|
|
|
layout="prev, pager, next, jumper, ->, total, sizes"
|
|
|
+ @current-change="fetchEmployees"
|
|
|
/>
|
|
|
</div>
|
|
|
|
|
|
@@ -79,26 +64,26 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
-import { ref, computed, watch, nextTick } from "vue";
|
|
|
+import { ref, computed, watch } from "vue";
|
|
|
+import EmployeeAPI from "@/api/module_payment/employee";
|
|
|
|
|
|
interface Employee {
|
|
|
id: string;
|
|
|
name: string;
|
|
|
- department: string;
|
|
|
phone: string;
|
|
|
- email: string;
|
|
|
}
|
|
|
|
|
|
interface Props {
|
|
|
visible: boolean;
|
|
|
selectedIds: string[];
|
|
|
+ enterpriseId: string;
|
|
|
}
|
|
|
|
|
|
const props = defineProps<Props>();
|
|
|
|
|
|
const emit = defineEmits<{
|
|
|
(e: "update:visible", value: boolean): void;
|
|
|
- (e: "confirm", employees: Employee[]): void;
|
|
|
+ (e: "confirm", ids: string[]): void;
|
|
|
}>();
|
|
|
|
|
|
const visibleProxy = computed({
|
|
|
@@ -106,77 +91,98 @@ const visibleProxy = computed({
|
|
|
set: (v: boolean) => emit("update:visible", v),
|
|
|
});
|
|
|
|
|
|
-const searchForm = ref({
|
|
|
- department_id: "",
|
|
|
- name: "",
|
|
|
- phone: "",
|
|
|
- email: "",
|
|
|
-});
|
|
|
-
|
|
|
+const searchForm = ref({ name: "", phone: "" });
|
|
|
const activeTab = ref("all");
|
|
|
+const pagination = ref({ page_no: 1, page_size: 10, total: 0 });
|
|
|
|
|
|
-const pagination = ref({
|
|
|
- page_no: 1,
|
|
|
- page_size: 10,
|
|
|
- total: 2,
|
|
|
-});
|
|
|
-
|
|
|
-const departments = ref([
|
|
|
- { value: "dept1", label: "研发部" },
|
|
|
- { value: "dept2", label: "产品部" },
|
|
|
- { value: "dept3", label: "运营部" },
|
|
|
-]);
|
|
|
-
|
|
|
-const allEmployees = ref<Employee[]>([
|
|
|
- { id: "emp1", name: "湖南钱程似锦技术服务有限公司", department: "湖南钱程似锦技术服务有限公司", phone: "-", email: "-" },
|
|
|
- { id: "emp2", name: "湖南钱程似锦技术服务有限公司", department: "湖南钱程似锦技术服务有限公司", phone: "-", email: "-" },
|
|
|
-]);
|
|
|
-
|
|
|
-const selectedEmployees = ref<Employee[]>([]);
|
|
|
+const allEmployees = ref<Employee[]>([]);
|
|
|
const tableRef = ref();
|
|
|
|
|
|
-function handleSelectionChange(val: Employee[]) {
|
|
|
- selectedEmployees.value = val;
|
|
|
-}
|
|
|
+// 追踪已选 ID 集合(跨页持久)
|
|
|
+const internalSelectedIds = ref<string[]>([]);
|
|
|
|
|
|
-watch(() => props.visible, (v) => {
|
|
|
- if (v) {
|
|
|
- nextTick(() => selectedEmployees.value = allEmployees.value.filter(emp => props.selectedIds.includes(emp.id)));
|
|
|
+watch(
|
|
|
+ () => props.visible,
|
|
|
+ (v) => {
|
|
|
+ if (v) {
|
|
|
+ internalSelectedIds.value = [...props.selectedIds];
|
|
|
+ fetchEmployees();
|
|
|
+ }
|
|
|
}
|
|
|
-});
|
|
|
+);
|
|
|
+
|
|
|
+async function fetchEmployees() {
|
|
|
+ try {
|
|
|
+ const params: Record<string, unknown> = {
|
|
|
+ page_no: pagination.value.page_no,
|
|
|
+ page_size: pagination.value.page_size,
|
|
|
+ enterprise_id: props.enterpriseId,
|
|
|
+ };
|
|
|
+ if (searchForm.value.name) params.employee_name = searchForm.value.name;
|
|
|
+ if (searchForm.value.phone) params.employee_mobile = searchForm.value.phone;
|
|
|
+
|
|
|
+ const res = await EmployeeAPI.listEmployee(params);
|
|
|
+ const data = res?.data?.data || res?.data;
|
|
|
+ const list = data?.items || data?.list || [];
|
|
|
+ allEmployees.value = (list).map((item: any) => ({
|
|
|
+ id: item.employee_id || item.id,
|
|
|
+ name: item.employee_name || "-",
|
|
|
+ phone: item.employee_mobile || "-",
|
|
|
+ }));
|
|
|
+ pagination.value.total = data?.total || 0;
|
|
|
+
|
|
|
+ // 重新勾选已选条目
|
|
|
+ nextTick(() => {
|
|
|
+ if (tableRef.value) {
|
|
|
+ allEmployees.value.forEach((row) => {
|
|
|
+ if (internalSelectedIds.value.includes(row.id)) {
|
|
|
+ tableRef.value.toggleRowSelection(row, true);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } catch (e) {
|
|
|
+ console.error("获取员工列表失败", e);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function handleSelectionChange(rows: Employee[]) {
|
|
|
+ // 只更新当前页的选中状态
|
|
|
+ const currentIds = rows.map((r) => r.id);
|
|
|
+ const otherIds = internalSelectedIds.value.filter(
|
|
|
+ (id) => !allEmployees.value.some((e) => e.id === id)
|
|
|
+ );
|
|
|
+ internalSelectedIds.value = [...new Set([...otherIds, ...currentIds])];
|
|
|
+}
|
|
|
|
|
|
const displayEmployees = computed(() => {
|
|
|
if (activeTab.value === "selected") {
|
|
|
- return selectedEmployees.value;
|
|
|
+ return allEmployees.value.filter((e) => internalSelectedIds.value.includes(e.id));
|
|
|
}
|
|
|
return allEmployees.value;
|
|
|
});
|
|
|
|
|
|
-
|
|
|
function handleClose() {
|
|
|
- selectedEmployees.value = [];
|
|
|
emit("update:visible", false);
|
|
|
}
|
|
|
|
|
|
function handleReset() {
|
|
|
- searchForm.value = {
|
|
|
- department_id: "",
|
|
|
- name: "",
|
|
|
- phone: "",
|
|
|
- email: "",
|
|
|
- };
|
|
|
+ searchForm.value = { name: "", phone: "" };
|
|
|
+ pagination.value.page_no = 1;
|
|
|
+ fetchEmployees();
|
|
|
}
|
|
|
|
|
|
function handleSearch() {
|
|
|
pagination.value.page_no = 1;
|
|
|
+ fetchEmployees();
|
|
|
}
|
|
|
|
|
|
function handleTabChange() {
|
|
|
- pagination.value.page_no = 1;
|
|
|
+ // 不重置
|
|
|
}
|
|
|
|
|
|
function handleConfirm() {
|
|
|
- emit("confirm", selectedEmployees.value);
|
|
|
+ emit("confirm", internalSelectedIds.value);
|
|
|
emit("update:visible", false);
|
|
|
}
|
|
|
</script>
|
|
|
@@ -188,33 +194,27 @@ function handleConfirm() {
|
|
|
gap: 16px;
|
|
|
height: 100%;
|
|
|
}
|
|
|
-
|
|
|
.employee-selector__search {
|
|
|
display: flex;
|
|
|
justify-content: space-between;
|
|
|
align-items: flex-start;
|
|
|
}
|
|
|
-
|
|
|
.employee-selector__actions {
|
|
|
display: flex;
|
|
|
gap: 8px;
|
|
|
}
|
|
|
-
|
|
|
.employee-selector__tabs {
|
|
|
background: #f5f7fa;
|
|
|
padding: 8px;
|
|
|
}
|
|
|
-
|
|
|
.employee-selector__table {
|
|
|
flex: 1;
|
|
|
overflow: hidden;
|
|
|
}
|
|
|
-
|
|
|
.employee-selector__pagination {
|
|
|
padding: 8px 0;
|
|
|
border-top: 1px solid #ebeef5;
|
|
|
}
|
|
|
-
|
|
|
.employee-selector__footer {
|
|
|
display: flex;
|
|
|
justify-content: flex-end;
|
|
|
@@ -222,4 +222,4 @@ function handleConfirm() {
|
|
|
padding-top: 16px;
|
|
|
border-top: 1px solid #ebeef5;
|
|
|
}
|
|
|
-</style>
|
|
|
+</style>
|