position.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. import Vue from "vue";
  2. import { get, postJ } from "@/utils/request";
  3. // 岗位状态:0-停用 / 1-启用 / 2-待撤销(与后端一致)
  4. export const POSITION_STATUS = {
  5. DISABLED: 0,
  6. ENABLED: 1,
  7. PENDING_REVOKE: 2,
  8. };
  9. export const POSITION_STATUS_LABEL = {
  10. 0: "停用",
  11. 1: "启用",
  12. 2: "待撤销",
  13. };
  14. /** 岗位基本信息 → 页面选项形状 */
  15. function positionOption(raw = {}) {
  16. return {
  17. id: String(raw.id != null ? raw.id : raw.positionId || ""),
  18. name: raw.positionName || raw.name || "",
  19. code: raw.positionCode || "",
  20. deptId: raw.deptId != null ? raw.deptId : "",
  21. deptName: raw.deptName || "",
  22. level: raw.positionLevel || "",
  23. levels: Array.isArray(raw.positionLevels) ? raw.positionLevels : [],
  24. sequence: raw.positionSequence || "",
  25. };
  26. }
  27. /** 只保留正整数主键,避免把空值当条件发给后端 */
  28. function positiveId(value) {
  29. const num = Number(value);
  30. return Number.isFinite(num) && num > 0 ? num : undefined;
  31. }
  32. /**
  33. * 岗位分页查询
  34. * POST /hr/position/page
  35. */
  36. export async function pagePosition(query = {}) {
  37. const body = {
  38. pageNum: Number(query.pageNum) || 1,
  39. size: Number(query.size) || 20,
  40. sortName: query.sortName || "createTime",
  41. orderBy: query.orderBy || "ascending",
  42. };
  43. if (query.deptId !== undefined && query.deptId !== null && query.deptId !== "") {
  44. body.deptId = String(query.deptId || 0);
  45. }
  46. if (
  47. query.organizationId !== undefined &&
  48. query.organizationId !== null &&
  49. query.organizationId !== ""
  50. ) {
  51. body.organizationId = String(query.organizationId) || 0;
  52. }
  53. if (query.keyword !== undefined && query.keyword !== null) {
  54. body.keyword = String(query.keyword);
  55. }
  56. if (query.positionSequence) body.positionSequence = String(query.positionSequence);
  57. if (query.positionLevel) body.positionLevel = String(query.positionLevel);
  58. if (query.status !== undefined && query.status !== null && query.status !== "") {
  59. body.status = Number(query.status);
  60. }
  61. const res = await postJ(Vue.prototype.apiUrl + "/hr/position/page", body);
  62. if (res.code == 0) {
  63. return (
  64. res.data || {
  65. count: 0,
  66. list: [],
  67. pageNum: body.pageNum,
  68. size: body.size,
  69. }
  70. );
  71. }
  72. throw new Error(res.msg || "岗位列表加载失败");
  73. }
  74. /**
  75. * 按部门加载可选岗位(启用状态)
  76. * @returns {{ list: Array, restricted: boolean }}
  77. */
  78. export async function loadSelectablePositions({ deptId, keyword = "" } = {}) {
  79. const deptKey = positiveId(deptId);
  80. if (!deptKey) return { list: [], restricted: false };
  81. const res = await postJ(Vue.prototype.apiUrl + "/hr/position/page", {
  82. pageNum: 1,
  83. size: 200,
  84. sortName: "createTime",
  85. orderBy: "ascending",
  86. deptId: String(deptKey),
  87. status: POSITION_STATUS.ENABLED,
  88. });
  89. const rows = (res.code == 0 && res.data && res.data.list) || [];
  90. const text = String(keyword || "").trim().toLowerCase();
  91. const list = rows
  92. .filter((item) => {
  93. if (!text) return true;
  94. return `${item.positionCode || ""}${item.positionName || ""}`
  95. .toLowerCase()
  96. .indexOf(text) !== -1;
  97. })
  98. .map(positionOption);
  99. return { list, restricted: false };
  100. }
  101. /** 岗位状态翻译 */
  102. export function translatePositionStatus(status) {
  103. if (status === undefined || status === null || status === "") return "";
  104. return POSITION_STATUS_LABEL[status] || String(status);
  105. }
  106. // ============ 部门岗位关联表(/fm/tmaindepartmentposition)级联查询 ============
  107. // 与 PC 端 kd-aiot-frontend-hr 的岗位调动表单共用同一套级联:
  108. // 部门 → 岗位序列 → 岗位 → 岗位性质(取首条) → 岗位层级
  109. function compactQuery(object = {}) {
  110. return Object.keys(object).reduce((result, key) => {
  111. const value = object[key];
  112. if (value !== "" && value !== null && value !== undefined) result[key] = value;
  113. return result;
  114. }, {});
  115. }
  116. function keepId(value) {
  117. if (value === undefined || value === null || value === "") return undefined;
  118. const text = String(value).trim();
  119. if (!/^-?\d+$/.test(text)) return value;
  120. if (!Number.isSafeInteger(Number(text))) return text;
  121. return Number(text);
  122. }
  123. async function cascadeGet(path, params, loding) {
  124. const res = await get(Vue.prototype.apiUrl + path, compactQuery(params), loding);
  125. if (res && Number(res.code) === 0) {
  126. const data = res.data;
  127. if (Array.isArray(data)) return data;
  128. if (data && Array.isArray(data.list)) return data.list;
  129. if (data && Array.isArray(data.records)) return data.records;
  130. return [];
  131. }
  132. throw new Error((res && res.message) || "查询失败");
  133. }
  134. /** 部门 → 岗位序列 */
  135. export async function getDeptPositionSequences(deptId, loding = true) {
  136. return cascadeGet(
  137. "/fm/tmaindepartmentposition/sequence/list",
  138. { deptId: keepId(deptId) },
  139. loding
  140. );
  141. }
  142. /** 部门 + 岗位序列 → 岗位 */
  143. export async function getDeptPositions({ deptId, positionSequenceId } = {}, loding = true) {
  144. return cascadeGet(
  145. "/fm/tmaindepartmentposition/position/list",
  146. { deptId: keepId(deptId), positionSequenceId: keepId(positionSequenceId) },
  147. loding
  148. );
  149. }
  150. /** 部门 + 岗位 + 岗位序列 → 岗位性质(数组,调用方取首条) */
  151. export async function getDeptPositionType(
  152. { deptId, positionId, positionSequenceId } = {},
  153. loding = true
  154. ) {
  155. return cascadeGet(
  156. "/fm/tmaindepartmentposition/positionType/list",
  157. {
  158. deptId: keepId(deptId),
  159. positionId: keepId(positionId),
  160. positionSequenceId: keepId(positionSequenceId),
  161. },
  162. loding
  163. );
  164. }
  165. /** 部门 + 岗位 + 岗位序列 + 岗位性质 → 岗位层级 */
  166. export async function getDeptPositionLevels(
  167. { deptId, positionId, positionSequenceId, positionType } = {},
  168. loding = true
  169. ) {
  170. return cascadeGet(
  171. "/fm/tmaindepartmentposition/positionLevel/list",
  172. {
  173. deptId: keepId(deptId),
  174. positionId: keepId(positionId),
  175. positionSequenceId: keepId(positionSequenceId),
  176. positionType,
  177. },
  178. loding
  179. );
  180. }