personList.vue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <template>
  2. <view class="page_person_list">
  3. <CommonHeader :title="headerTitle" @back="goBack"></CommonHeader>
  4. <SearchBar v-model="searchWord" @search="handleSearch" :isFixed="true" :top="114" :border="false"></SearchBar>
  5. <scroll-view scroll-y class="person_list">
  6. <view v-for="(person, index) in filteredList" :key="person.userId || person.id" class="person_item">
  7. <view class="person_info">
  8. <text class="person_name">{{ person.thirdName || person.name }}</text>
  9. <text class="person_code">({{ person.thirdCode || person.userAccount || '' }})</text>
  10. </view>
  11. <view class="person_action" @click="openDeleteModal(index)">
  12. <text class="delete_text">删除</text>
  13. </view>
  14. </view>
  15. <view v-if="filteredList.length === 0" class="empty_state">
  16. <text class="empty_text">暂无人员</text>
  17. </view>
  18. </scroll-view>
  19. <ConfirmModal
  20. :visible="showDeleteModal"
  21. title="提示"
  22. :content="`确定要删除【${deletePersonName}】吗?`"
  23. cancelText="取消"
  24. confirmText="确定"
  25. @cancel="closeDeleteModal"
  26. @confirm="confirmDelete"
  27. ></ConfirmModal>
  28. </view>
  29. </template>
  30. <script setup>
  31. import { ref, computed, onMounted } from 'vue';
  32. import CommonHeader from '@/components/common-header.vue';
  33. import SearchBar from '@/components/search-bar.vue';
  34. import ConfirmModal from '@/components/confirm-modal.vue';
  35. const searchWord = ref('');
  36. const personList = ref([]);
  37. const objectTypeLabel = ref('');
  38. const showDeleteModal = ref(false);
  39. const deleteIndex = ref(-1);
  40. const deletePersonName = ref('');
  41. const filteredList = computed(() => {
  42. console.log(personList.value)
  43. if (!searchWord.value) return personList.value;
  44. const keyword = searchWord.value.toLowerCase();
  45. return personList.value.filter(person => {
  46. const name = (person.thirdName || person.name || '').toLowerCase();
  47. const code = (person.thirdCode || person.userAccount || '').toLowerCase();
  48. return name.includes(keyword) || code.includes(keyword);
  49. });
  50. });
  51. const headerTitle = computed(() => {
  52. return `${objectTypeLabel.value || ''} 已选${personList.value.length}人`;
  53. });
  54. const handleSearch = (keyword) => {
  55. searchWord.value = keyword;
  56. };
  57. const openDeleteModal = (index) => {
  58. const person = personList.value[index];
  59. deletePersonName.value = person.thirdName || person.name || '';
  60. deleteIndex.value = index;
  61. showDeleteModal.value = true;
  62. };
  63. const closeDeleteModal = () => {
  64. showDeleteModal.value = false;
  65. deleteIndex.value = -1;
  66. deletePersonName.value = '';
  67. };
  68. const confirmDelete = () => {
  69. if (deleteIndex.value >= 0) {
  70. personList.value.splice(deleteIndex.value, 1);
  71. }
  72. closeDeleteModal();
  73. };
  74. const goBack = () => {
  75. uni.setStorageSync('personListResult', JSON.stringify({
  76. users: personList.value
  77. }));
  78. uni.navigateBack();
  79. };
  80. onMounted(() => {
  81. const data = uni.getStorageSync('personListData');
  82. if (data) {
  83. try {
  84. const parsed = JSON.parse(data);
  85. const users = parsed.users || [];
  86. const seen = new Set();
  87. personList.value = users.filter(user => {
  88. const userId = user.userId || user.id;
  89. if (!userId || seen.has(userId)) return false;
  90. seen.add(userId);
  91. return true;
  92. });
  93. objectTypeLabel.value = parsed.tab || '';
  94. } catch (e) {
  95. console.error('解析人员列表数据失败:', e);
  96. }
  97. }
  98. });
  99. </script>
  100. <style lang="scss">
  101. .page_person_list {
  102. display: flex;
  103. flex-direction: column;
  104. min-height: 100vh;
  105. }
  106. .person_list {
  107. flex: 1;
  108. padding: 222rpx 24rpx 24rpx 24rpx;
  109. box-sizing: border-box;
  110. }
  111. .person_item {
  112. display: flex;
  113. align-items: center;
  114. justify-content: space-between;
  115. height: 86rpx;
  116. border-bottom: 2rpx solid #F3F3F3;
  117. .person_info {
  118. display: flex;
  119. align-items: center;
  120. .person_name {
  121. font-size: 28rpx;
  122. color: #666;
  123. }
  124. .person_code {
  125. font-size: 28rpx;
  126. color: #666;
  127. margin-left: 16rpx;
  128. }
  129. }
  130. .person_action {
  131. .delete_text {
  132. font-size: 28rpx;
  133. color: #F56C6C;
  134. }
  135. }
  136. }
  137. .empty_state {
  138. display: flex;
  139. flex-direction: column;
  140. align-items: center;
  141. padding: 100rpx 0;
  142. .empty_text {
  143. font-size: 28rpx;
  144. color: #999999;
  145. }
  146. }
  147. </style>