人员所属部门下拉对齐旧项目:主账提供 /departments 短名全量,后台可搜可选。
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+35
-2
@@ -22,8 +22,10 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -147,9 +149,40 @@ public class InquiryStaffRoleController extends JeecgController<InquiryStaffRole
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 企微部门下拉选项。浏览器禁止直连企微,只打本接口。
|
* 员工「所属部门」下拉(对齐旧项目 admin-rel26)。
|
||||||
|
* <p>
|
||||||
|
* 旧前端:{@code GET /inquiry/staffRole/departments} → {@code string[]},
|
||||||
|
* 再 {@code options: names.map(n => ({label:n,value:n}))},showSearch 可滚动全量。
|
||||||
|
* 本接口同源:企微 {@code department/list} 短名全量;根公司(id=1)不进下拉。
|
||||||
|
* 浏览器禁止直连企微。
|
||||||
*/
|
*/
|
||||||
@ApiOperation("企微部门列表")
|
@ApiOperation("员工部门名列表(对齐旧项目 /departments)")
|
||||||
|
@RequiresPermissions("inquiry:staff:list")
|
||||||
|
@GetMapping("/departments")
|
||||||
|
public Result<List<String>> departments() {
|
||||||
|
List<WeComDepartment> all = weComAddressBookClient.listDepartments();
|
||||||
|
List<String> names = new ArrayList<>();
|
||||||
|
LinkedHashSet<String> seen = new LinkedHashSet<>();
|
||||||
|
for (WeComDepartment d : all) {
|
||||||
|
if (d == null || StringUtils.isBlank(d.getName())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// 企微根部门(id=1 / parentid=0)是公司全称,员工下拉不展示
|
||||||
|
if (d.getId() == 1 || d.getParentId() <= 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
String name = d.getName().trim();
|
||||||
|
if (seen.add(name)) {
|
||||||
|
names.add(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Result.OK(names);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 企微部门结构列表(含 id/path,供排查)。员工下拉请用 {@link #departments()}。
|
||||||
|
*/
|
||||||
|
@ApiOperation("企微部门结构列表")
|
||||||
@RequiresPermissions("inquiry:staff:list")
|
@RequiresPermissions("inquiry:staff:list")
|
||||||
@GetMapping("/wecomDepartments")
|
@GetMapping("/wecomDepartments")
|
||||||
public Result<List<WeComDepartment>> wecomDepartments() {
|
public Result<List<WeComDepartment>> wecomDepartments() {
|
||||||
|
|||||||
+4
-3
@@ -127,8 +127,9 @@ public class WeComAddressBookClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 拉取企微部门树(扁平列表,带 path 便于下拉展示)。
|
* 拉取企微 {@code department/list} 全量扁平列表(短名 + path)。
|
||||||
* <p>
|
* <p>
|
||||||
|
* 员工下拉与旧项目同源:整份通讯录,不截层级。顺序保持企微返回序。
|
||||||
* 副作用:出站 HTTP;失败抛 IllegalStateException。
|
* 副作用:出站 HTTP;失败抛 IllegalStateException。
|
||||||
*/
|
*/
|
||||||
public List<WeComDepartment> listDepartments() {
|
public List<WeComDepartment> listDepartments() {
|
||||||
@@ -163,8 +164,8 @@ public class WeComAddressBookClient {
|
|||||||
String path = buildDepartmentPath(id, byId);
|
String path = buildDepartmentPath(id, byId);
|
||||||
result.add(new WeComDepartment(id, name, parentId, path));
|
result.add(new WeComDepartment(id, name, parentId, path));
|
||||||
}
|
}
|
||||||
// 按路径排序,下拉更易扫
|
// 保持企微 department/list 原序(LinkedHashMap 插入序 = 接口返回序),
|
||||||
result.sort((a, b) -> StringUtils.defaultString(a.getPath()).compareTo(StringUtils.defaultString(b.getPath())));
|
// 不要按 path 重排,也不要截层级;员工下拉与旧项目一样用这份全量短名。
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { message, Modal } from "ant-design-vue";
|
|||||||
import {
|
import {
|
||||||
disableStaff,
|
disableStaff,
|
||||||
getStaffCounts,
|
getStaffCounts,
|
||||||
|
getStaffDepartments,
|
||||||
getStaffList,
|
getStaffList,
|
||||||
getWecomDepartments,
|
getWecomDepartments,
|
||||||
saveStaff as saveStaffApi,
|
saveStaff as saveStaffApi,
|
||||||
@@ -19,7 +20,8 @@ import AdminModal from "/@/views/inquiry/components/AdminModal.vue";
|
|||||||
|
|
||||||
type StaffRole = "sales" | "air" | "sea" | "land";
|
type StaffRole = "sales" | "air" | "sea" | "land";
|
||||||
|
|
||||||
type WecomDeptOption = { id: number; name: string; path: string; parentId: number; depth: number };
|
/** 部门下拉:value 存短名,label 带层级缩进 */
|
||||||
|
type DeptOption = { id: number; name: string; label: string; depth: number };
|
||||||
|
|
||||||
type StaffRow = {
|
type StaffRow = {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -59,9 +61,11 @@ const filters = reactive({
|
|||||||
const modalOpen = ref(false);
|
const modalOpen = ref(false);
|
||||||
const editing = ref<StaffRow | null>(null);
|
const editing = ref<StaffRow | null>(null);
|
||||||
const syncing = ref(false);
|
const syncing = ref(false);
|
||||||
const wecomDepts = ref<WecomDeptOption[]>([]);
|
/** 部门树扁平列表:一级不缩进,子级前加空格 */
|
||||||
const wecomDeptsLoading = ref(false);
|
const deptOptions = ref<DeptOption[]>([]);
|
||||||
const wecomDeptsLoaded = ref(false);
|
const deptLoading = ref(false);
|
||||||
|
const deptLoaded = ref(false);
|
||||||
|
const deptOpen = ref(false);
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
name: "",
|
name: "",
|
||||||
wecomId: "",
|
wecomId: "",
|
||||||
@@ -75,6 +79,12 @@ const form = reactive({
|
|||||||
|
|
||||||
const filtered = computed(() => rows.value);
|
const filtered = computed(() => rows.value);
|
||||||
|
|
||||||
|
const filteredDeptOptions = computed(() => {
|
||||||
|
const q = (form.dept || "").trim().toLowerCase();
|
||||||
|
if (!q) return deptOptions.value;
|
||||||
|
return deptOptions.value.filter((d) => d.name.toLowerCase().includes(q));
|
||||||
|
});
|
||||||
|
|
||||||
function colorFor(name: string) {
|
function colorFor(name: string) {
|
||||||
let h = 0;
|
let h = 0;
|
||||||
for (let i = 0; i < name.length; i++) h = (h + name.charCodeAt(i) * (i + 1)) % AVATAR_COLORS.length;
|
for (let i = 0; i < name.length; i++) h = (h + name.charCodeAt(i) * (i + 1)) % AVATAR_COLORS.length;
|
||||||
@@ -148,64 +158,79 @@ watch(
|
|||||||
|
|
||||||
onMounted(() => loadList());
|
onMounted(() => loadList());
|
||||||
|
|
||||||
|
/** 企微根部门公司全称,下拉不展示 */
|
||||||
|
const ROOT_DEPT_NAME = "深圳市友通达供应链管理有限公司";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 打开弹窗时拉企微部门;失败不挡手工保存,仅提示。
|
* 按 parentId 排成树再前序展开。
|
||||||
* 下拉对齐旧项目业务层:只展示「分公司」「旧组织」下的直接子部门
|
* 展示:部门1 / 「 」子部门1 / 「 」子部门2 / 部门2(根公司不出现)。
|
||||||
*(事业二部/元昇/武汉友通达/通多邦…),不要公司根下的一级中心。
|
* 保存仍用短名 name。
|
||||||
*/
|
*/
|
||||||
async function ensureWecomDepartments() {
|
function buildDeptTreeOptions(raw: any[]): DeptOption[] {
|
||||||
if (wecomDeptsLoaded.value || wecomDeptsLoading.value) {
|
const nodes = (raw as any[])
|
||||||
|
.map((d) => ({
|
||||||
|
id: Number(d?.id),
|
||||||
|
name: String(d?.name || "").trim(),
|
||||||
|
parentId: Number(d?.parentId ?? d?.parentid ?? 0),
|
||||||
|
}))
|
||||||
|
.filter((d) => d.name && Number.isFinite(d.id) && d.id > 0)
|
||||||
|
.filter((d) => d.id !== 1 && d.parentId > 0 && d.name !== ROOT_DEPT_NAME);
|
||||||
|
|
||||||
|
const idSet = new Set(nodes.map((n) => n.id));
|
||||||
|
const children = new Map<number, typeof nodes>();
|
||||||
|
for (const n of nodes) {
|
||||||
|
const pid = idSet.has(n.parentId) ? n.parentId : 0;
|
||||||
|
const list = children.get(pid) || [];
|
||||||
|
list.push(n);
|
||||||
|
children.set(pid, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
const out: DeptOption[] = [];
|
||||||
|
const walk = (pid: number, depth: number) => {
|
||||||
|
for (const n of children.get(pid) || []) {
|
||||||
|
out.push({
|
||||||
|
id: n.id,
|
||||||
|
name: n.name,
|
||||||
|
label: "\u00A0".repeat(depth) + n.name,
|
||||||
|
depth,
|
||||||
|
});
|
||||||
|
walk(n.id, depth + 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
walk(0, 0);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打开弹窗拉企微部门树;失败不挡手工保存。
|
||||||
|
* 优先 wecomDepartments(有 parentId 才能缩进);否则退回 departments 扁平短名。
|
||||||
|
*/
|
||||||
|
async function ensureDeptOptions() {
|
||||||
|
if (deptLoaded.value || deptLoading.value) {
|
||||||
ensureCurrentDeptOption();
|
ensureCurrentDeptOption();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
wecomDeptsLoading.value = true;
|
deptLoading.value = true;
|
||||||
try {
|
try {
|
||||||
const res: any = await getWecomDepartments();
|
try {
|
||||||
const list = Array.isArray(res) ? res : res?.result || [];
|
const res: any = await getWecomDepartments();
|
||||||
const all: WecomDeptOption[] = (list as any[])
|
const list = Array.isArray(res) ? res : res?.result || [];
|
||||||
.map((d) => {
|
deptOptions.value = buildDeptTreeOptions(list);
|
||||||
const path = String(d.path || d.name || "");
|
} catch {
|
||||||
const name = String(d.name || path);
|
const res: any = await getStaffDepartments();
|
||||||
const parentId = Number(d.parentId ?? d.parentid ?? 0);
|
const list = Array.isArray(res) ? res : res?.result || [];
|
||||||
const depth = path ? path.split(" / ").length - 1 : 0;
|
deptOptions.value = (list as any[])
|
||||||
return {
|
.map((x, i) => {
|
||||||
id: Number(d.id),
|
const name = String(x || "").trim();
|
||||||
name,
|
return { id: -(i + 1), name, label: name, depth: 0 };
|
||||||
path,
|
})
|
||||||
parentId,
|
.filter((d) => d.name && d.name !== ROOT_DEPT_NAME);
|
||||||
depth: depth < 0 ? 0 : depth,
|
|
||||||
};
|
|
||||||
})
|
|
||||||
.filter((d) => d.name && d.id);
|
|
||||||
|
|
||||||
// 旧项目下拉对应层:分公司 + 旧组织 的子节点
|
|
||||||
const businessParentNames = new Set(["分公司", "旧组织"]);
|
|
||||||
const businessParentIds = new Set(
|
|
||||||
all.filter((d) => businessParentNames.has(d.name)).map((d) => d.id),
|
|
||||||
);
|
|
||||||
let picked = all.filter((d) => businessParentIds.has(d.parentId));
|
|
||||||
|
|
||||||
// 兜底:若企微改名导致找不到父节点,仍回退到根下一级,避免空下拉
|
|
||||||
if (!picked.length) {
|
|
||||||
const rootIds = new Set(
|
|
||||||
all.filter((d) => d.parentId === 0 || d.depth === 0).map((d) => d.id),
|
|
||||||
);
|
|
||||||
if (!rootIds.size) {
|
|
||||||
const minDepth = Math.min(...all.map((d) => d.depth));
|
|
||||||
all.filter((d) => d.depth === minDepth).forEach((d) => rootIds.add(d.id));
|
|
||||||
}
|
|
||||||
picked = all.filter((d) => rootIds.has(d.parentId));
|
|
||||||
}
|
}
|
||||||
|
deptLoaded.value = true;
|
||||||
wecomDepts.value = picked
|
|
||||||
.slice()
|
|
||||||
.sort((a, b) => a.name.localeCompare(b.name, "zh-CN"))
|
|
||||||
.map((d) => ({ ...d, depth: 0 }));
|
|
||||||
wecomDeptsLoaded.value = true;
|
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
message.warning(e?.message || "企微部门列表加载失败,可稍后重试");
|
message.warning(e?.message || "部门列表加载失败,可稍后重试");
|
||||||
} finally {
|
} finally {
|
||||||
wecomDeptsLoading.value = false;
|
deptLoading.value = false;
|
||||||
ensureCurrentDeptOption();
|
ensureCurrentDeptOption();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -213,17 +238,40 @@ async function ensureWecomDepartments() {
|
|||||||
function ensureCurrentDeptOption() {
|
function ensureCurrentDeptOption() {
|
||||||
const cur = (form.dept || "").trim();
|
const cur = (form.dept || "").trim();
|
||||||
if (!cur) return;
|
if (!cur) return;
|
||||||
const hit = wecomDepts.value.some((d) => d.name === cur || d.path === cur);
|
if (!deptOptions.value.some((d) => d.name === cur)) {
|
||||||
if (!hit) {
|
deptOptions.value = [{ id: -1, name: cur, label: cur, depth: 0 }, ...deptOptions.value];
|
||||||
wecomDepts.value = [{ id: -1, name: cur, path: cur, parentId: 0, depth: 0 }, ...wecomDepts.value];
|
|
||||||
} else {
|
|
||||||
const byPath = wecomDepts.value.find((d) => d.path === cur);
|
|
||||||
if (byPath && form.dept !== byPath.name) {
|
|
||||||
form.dept = byPath.name;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let deptBlurTimer: ReturnType<typeof setTimeout> | null = null;
|
||||||
|
|
||||||
|
function pickDept(d: DeptOption) {
|
||||||
|
form.dept = d.name;
|
||||||
|
deptOpen.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDeptFocus() {
|
||||||
|
if (deptBlurTimer) {
|
||||||
|
clearTimeout(deptBlurTimer);
|
||||||
|
deptBlurTimer = null;
|
||||||
|
}
|
||||||
|
deptOpen.value = true;
|
||||||
|
ensureDeptOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDeptBlur() {
|
||||||
|
deptBlurTimer = setTimeout(() => {
|
||||||
|
deptOpen.value = false;
|
||||||
|
}, 180);
|
||||||
|
}
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => modalOpen.value,
|
||||||
|
(open) => {
|
||||||
|
if (!open) deptOpen.value = false;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
function openCreate() {
|
function openCreate() {
|
||||||
editing.value = null;
|
editing.value = null;
|
||||||
Object.assign(form, {
|
Object.assign(form, {
|
||||||
@@ -237,9 +285,8 @@ function openCreate() {
|
|||||||
status: "active",
|
status: "active",
|
||||||
});
|
});
|
||||||
modalOpen.value = true;
|
modalOpen.value = true;
|
||||||
// 每次打开重新拉一级部门,避免会话里还留着旧的「整棵树」缓存
|
deptLoaded.value = false;
|
||||||
wecomDeptsLoaded.value = false;
|
ensureDeptOptions();
|
||||||
ensureWecomDepartments();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function openEdit(row: StaffRow) {
|
function openEdit(row: StaffRow) {
|
||||||
@@ -255,8 +302,8 @@ function openEdit(row: StaffRow) {
|
|||||||
status: row.status,
|
status: row.status,
|
||||||
});
|
});
|
||||||
modalOpen.value = true;
|
modalOpen.value = true;
|
||||||
wecomDeptsLoaded.value = false;
|
deptLoaded.value = false;
|
||||||
ensureWecomDepartments();
|
ensureDeptOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveStaff() {
|
async function saveStaff() {
|
||||||
@@ -483,10 +530,32 @@ function routeTags(routes: string) {
|
|||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label class="lbl">所属部门</label>
|
<label class="lbl">所属部门</label>
|
||||||
<select v-model="form.dept" class="field" :disabled="wecomDeptsLoading">
|
<div class="dept-combo">
|
||||||
<option value="">{{ wecomDeptsLoading ? "加载企微部门…" : "请选择部门" }}</option>
|
<input
|
||||||
<option v-for="d in wecomDepts" :key="d.id + '-' + d.name" :value="d.name">{{ d.name }}</option>
|
v-model="form.dept"
|
||||||
</select>
|
class="field"
|
||||||
|
type="text"
|
||||||
|
autocomplete="off"
|
||||||
|
:disabled="deptLoading"
|
||||||
|
:placeholder="deptLoading ? '加载部门…' : '请选择或输入部门'"
|
||||||
|
@focus="onDeptFocus"
|
||||||
|
@input="deptOpen = true"
|
||||||
|
@blur="onDeptBlur"
|
||||||
|
/>
|
||||||
|
<span class="dept-combo-arrow" aria-hidden="true">▾</span>
|
||||||
|
<ul v-show="deptOpen" class="dept-combo-list">
|
||||||
|
<li v-if="!filteredDeptOptions.length" class="is-empty">无匹配部门</li>
|
||||||
|
<li
|
||||||
|
v-for="d in filteredDeptOptions"
|
||||||
|
:key="d.id"
|
||||||
|
:class="{ 'is-active': d.name === form.dept }"
|
||||||
|
:style="{ paddingLeft: 10 + d.depth * 12 + 'px' }"
|
||||||
|
@mousedown.prevent="pickDept(d)"
|
||||||
|
>
|
||||||
|
{{ d.name }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<label class="lbl">岗位 <span class="req">*</span></label>
|
<label class="lbl">岗位 <span class="req">*</span></label>
|
||||||
@@ -553,4 +622,61 @@ function routeTags(routes: string) {
|
|||||||
accent-color: #155eef;
|
accent-color: #155eef;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dept-combo {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-combo .field {
|
||||||
|
padding-right: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-combo-arrow {
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
pointer-events: none;
|
||||||
|
color: #64748b;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-combo-list {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: calc(100% + 4px);
|
||||||
|
z-index: 30;
|
||||||
|
max-height: 220px;
|
||||||
|
overflow: auto;
|
||||||
|
margin: 0;
|
||||||
|
padding: 4px 0;
|
||||||
|
list-style: none;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #cbd5e1;
|
||||||
|
border-radius: 7px;
|
||||||
|
box-shadow: 0 8px 20px rgba(15, 23, 42, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-combo-list li {
|
||||||
|
padding: 6px 10px;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #172033;
|
||||||
|
cursor: pointer;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-combo-list li:hover,
|
||||||
|
.dept-combo-list li.is-active {
|
||||||
|
background: #eff6ff;
|
||||||
|
color: #155eef;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dept-combo-list li.is-empty {
|
||||||
|
color: #94a3b8;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* 员工岗位 API:对接主账 /inquiry/staffRole。
|
* 员工岗位 API:对接主账 /inquiry/staffRole。
|
||||||
* 与 Jeecg /sys/user 分离——本页管企微岗位绑定;同步走主账 /syncWecom,浏览器不直连企微。
|
* 与 Jeecg /sys/user 分离——本页管企微岗位绑定;同步走主账 /syncWecom,浏览器不直连企微。
|
||||||
|
* 部门下拉对齐旧项目:GET /inquiry/staffRole/departments → string[]。
|
||||||
*/
|
*/
|
||||||
import { defHttp } from '/@/utils/http/axios';
|
import { defHttp } from '/@/utils/http/axios';
|
||||||
|
|
||||||
@@ -12,6 +13,8 @@ enum Api {
|
|||||||
disable = '/inquiry/staffRole/disable',
|
disable = '/inquiry/staffRole/disable',
|
||||||
queryById = '/inquiry/staffRole/queryById',
|
queryById = '/inquiry/staffRole/queryById',
|
||||||
syncWecom = '/inquiry/staffRole/syncWecom',
|
syncWecom = '/inquiry/staffRole/syncWecom',
|
||||||
|
/** 旧项目同名接口:部门短名全量 */
|
||||||
|
departments = '/inquiry/staffRole/departments',
|
||||||
wecomDepartments = '/inquiry/staffRole/wecomDepartments',
|
wecomDepartments = '/inquiry/staffRole/wecomDepartments',
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,5 +26,10 @@ export const disableStaff = (id: string) => defHttp.post({ url: Api.disable, par
|
|||||||
export const getStaffById = (id: string) => defHttp.get({ url: Api.queryById, params: { id } });
|
export const getStaffById = (id: string) => defHttp.get({ url: Api.queryById, params: { id } });
|
||||||
/** 主账拉企微通讯录 upsert;返回 { fetched, created, updated, skipped, message } */
|
/** 主账拉企微通讯录 upsert;返回 { fetched, created, updated, skipped, message } */
|
||||||
export const syncWecomStaff = () => defHttp.post({ url: Api.syncWecom });
|
export const syncWecomStaff = () => defHttp.post({ url: Api.syncWecom });
|
||||||
/** 企微部门下拉(主账转发,禁止浏览器直连企微) */
|
/**
|
||||||
|
* 部门下拉(对齐旧项目):返回 string[] 短名全量,可搜索可滚动。
|
||||||
|
* 失败时勿挡手工填部门。
|
||||||
|
*/
|
||||||
|
export const getStaffDepartments = () => defHttp.get({ url: Api.departments });
|
||||||
|
/** @deprecated 结构列表;员工下拉请用 getStaffDepartments */
|
||||||
export const getWecomDepartments = () => defHttp.get({ url: Api.wecomDepartments });
|
export const getWecomDepartments = () => defHttp.get({ url: Api.wecomDepartments });
|
||||||
|
|||||||
Reference in New Issue
Block a user