columns.tsx 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. import type {
  2. LoadingConfig,
  3. AdaptiveConfig,
  4. PaginationProps
  5. } from "@pureadmin/table";
  6. import { ref, reactive, watch } from "vue";
  7. import { delObjectProperty } from "@pureadmin/utils";
  8. import { clone, delay } from "@pureadmin/utils";
  9. import Attend from "@/model/attend.js";
  10. import AttendItem from "@/model/attendItem.js";
  11. export function useColumns(projects) {
  12. const loading = ref(true);
  13. const editMap = ref({});
  14. const dataList = ref([]);
  15. const dataFilter = ref([]);
  16. const options = ref([]);
  17. const confirmOptions = ref([
  18. { value: 0, label: '缺岗' },
  19. { value: 1, label: '到岗' }
  20. ]);
  21. const projectMap = reactive<Record<string | number, string>>({});
  22. const getProjectName = (projId) => {
  23. for (const p of projects.value) {
  24. if (Number(p.id) == Number(projId)) {
  25. return p.name;
  26. }
  27. }
  28. return ''
  29. }
  30. const getLocName = (projId, locId) => {
  31. for (const p of projects.value) {
  32. if (Number(p.id) == Number(projId)) {
  33. for (const loc of p.locations) {
  34. if (Number(loc.id) == Number(locId)) {
  35. return loc.name;
  36. }
  37. }
  38. }
  39. }
  40. return ''
  41. }
  42. // 监听 projectList 变化,动态更新映射(异步获取后会触发)
  43. watch(
  44. projects,
  45. (newList) => {
  46. // 清空旧映射
  47. Object.keys(projectMap).forEach(key => delete projectMap[key]);
  48. // 构建新映射
  49. newList.forEach(project => {
  50. projectMap[project.id] = project.name;
  51. });
  52. },
  53. { immediate: true } // 初始时执行一次(即使 projectList 初始为空)
  54. );
  55. const columns: TableColumnList = [
  56. {
  57. label: "时间",
  58. prop: "tm",
  59. cellRenderer: ({ row, index }) => (
  60. <p>{ new Date(row.tm).toLocaleString() }</p>
  61. )
  62. },
  63. {
  64. label: "项目名称",
  65. prop: "projId",
  66. // cellRenderer: ({ row, index }) => {
  67. // // 处理未加载/未匹配的情况
  68. // if (!Object.keys(projectMap).length) {
  69. // return <p>加载中...</p>; // 未加载完成时显示
  70. // }
  71. // const projectName = projectMap[row.projId] || `未知项目(${row.projId})`;
  72. // return <p>{ projectName }</p>;
  73. // }
  74. cellRenderer: ({ row, index }) => (
  75. <p>{ getProjectName(row.projId) }</p>
  76. )
  77. },
  78. {
  79. label: "区域名称",
  80. prop: "locId",
  81. cellRenderer: ({ row, index }) => (
  82. <p>{ getLocName(row.projId, row.locId) }</p>
  83. )
  84. },
  85. {
  86. label: "人员ID",
  87. prop: "id",
  88. cellRenderer: ({ row, index }) => (
  89. <p>{row.id}</p>
  90. )
  91. },
  92. {
  93. label: "人员名称",
  94. prop: "name",
  95. cellRenderer: ({ row, index }) => (
  96. <p>{row.name}</p>
  97. )
  98. },
  99. {
  100. label: "职位",
  101. prop: "job",
  102. cellRenderer: ({ row, index }) => (
  103. <p>{row.job}</p>
  104. )
  105. },
  106. {
  107. label: "电话",
  108. prop: "phone",
  109. cellRenderer: ({ row, index }) => (
  110. <p>{row.phone}</p>
  111. )
  112. },
  113. {
  114. label: "标签ID",
  115. prop: "tagId",
  116. cellRenderer: ({ row, index }) => (
  117. <p>{row.tagId}</p>
  118. )
  119. },
  120. {
  121. label: "在线",
  122. prop: "isOnline",
  123. cellRenderer: ({ row, index }) => (
  124. <el-tag type={row.rssi == 0 ? 'danger' : 'primary'}>
  125. {row.rssi == 0 ? '离线' : '在线'}
  126. </el-tag>
  127. )
  128. },
  129. {
  130. label: "到岗",
  131. prop: "confirm",
  132. cellRenderer: ({ row, index }) => (
  133. <>
  134. {editMap.value[index]?.editable ? (
  135. <el-select v-model={row.confirm} clearable placeholder="请选择爱好">
  136. {confirmOptions.value.map(item => {
  137. return (
  138. <el-option
  139. key={item.value}
  140. label={item.label}
  141. value={item.value}
  142. />
  143. );
  144. })}
  145. </el-select>
  146. ) : (
  147. <el-tag type={row.confirm == 0 ? 'danger' : 'primary'}>
  148. {row.confirm == 0 ? '缺岗' : '到岗'}
  149. </el-tag>
  150. )}
  151. </>
  152. )
  153. },
  154. {
  155. label: "操作",
  156. fixed: "right",
  157. slot: "operation"
  158. },
  159. ];
  160. /** 分页配置 */
  161. const pagination = reactive<PaginationProps>({
  162. pageSize: 20,
  163. currentPage: 1,
  164. pageSizes: [20, 40, 60],
  165. total: 0,
  166. align: "right",
  167. background: true,
  168. size: "default"
  169. });
  170. /** 加载动画配置 */
  171. const loadingConfig = reactive<LoadingConfig>({
  172. text: "正在加载第一页...",
  173. viewBox: "-10, -10, 50, 50",
  174. spinner: `
  175. <path class="path" d="
  176. M 30 15
  177. L 28 17
  178. M 25.61 25.61
  179. A 15 15, 0, 0, 1, 15 30
  180. A 15 15, 0, 1, 1, 27.99 7.5
  181. L 15 15
  182. " style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"/>
  183. `
  184. // svg: "",
  185. // background: rgba()
  186. });
  187. /** 撑满内容区自适应高度相关配置 */
  188. const adaptiveConfig: AdaptiveConfig = {
  189. /** 表格距离页面底部的偏移量,默认值为 `96` */
  190. offsetBottom: 110
  191. /** 是否固定表头,默认值为 `true`(如果不想固定表头,fixHeader设置为false并且表格要设置table-layout="auto") */
  192. // fixHeader: true
  193. /** 页面 `resize` 时的防抖时间,默认值为 `60` ms */
  194. // timeout: 60
  195. /** 表头的 `z-index`,默认值为 `100` */
  196. // zIndex: 100
  197. };
  198. function onSizeChange(val) {
  199. console.log("onSizeChange", val);
  200. }
  201. function onCurrentChange(val) {
  202. loadingConfig.text = `正在加载第${val}页...`;
  203. loading.value = true;
  204. delay(600).then(() => {
  205. loading.value = false;
  206. });
  207. }
  208. function onEdit(row, index) {
  209. editMap.value[index] = Object.assign({ ...row, editable: true });
  210. }
  211. function onSave(index) {
  212. editMap.value[index].editable = false;
  213. }
  214. function onCancel(index) {
  215. editMap.value[index].editable = false;
  216. dataFilter.value[index] = delObjectProperty(editMap.value[index], "editable");
  217. }
  218. function onDel(row) {
  219. let index = dataFilter.value.indexOf(row);
  220. if (index !== -1) dataFilter.value.splice(index, 1);
  221. index = dataList.value.indexOf(row);
  222. if (index !== -1) dataList.value.splice(index, 1);
  223. if (row.parent) {
  224. const attend = row.parent;
  225. index = attend.items.indexOf(row);
  226. if (index !== -1) attend.items.splice(index, 1);
  227. } else {
  228. console.log('no parent', row)
  229. }
  230. }
  231. return {
  232. loading,
  233. editMap,
  234. columns,
  235. dataList,
  236. dataFilter,
  237. options,
  238. pagination,
  239. loadingConfig,
  240. adaptiveConfig,
  241. getProjectName,
  242. getLocName,
  243. onDel,
  244. onEdit,
  245. onSave,
  246. onCancel,
  247. onSizeChange,
  248. onCurrentChange
  249. };
  250. }