index.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. <template>
  2. <div class="communityPage">
  3. <div class="searchBar">
  4. <a-form layout="inline" @keydown.enter="searchHandler">
  5. <a-form-item label="小区名称">
  6. <a-input
  7. v-model:value.trim="searchState.tenantName"
  8. placeholder="小区名称"
  9. :maxlength="300"
  10. show-count
  11. allow-clear
  12. @change="clearHandler"
  13. />
  14. </a-form-item>
  15. <a-form-item>
  16. <a-space>
  17. <a-button type="primary" @click="searchHandler"> 搜索 </a-button>
  18. <a-button @click="resetHandler"> 重置 </a-button>
  19. </a-space>
  20. </a-form-item>
  21. </a-form>
  22. </div>
  23. <div class="tableCard">
  24. <div class="tableCard-header">
  25. <div class="tableCard-header-title">小区列表</div>
  26. <div class="tableCard-header-extra">
  27. <a-space>
  28. <a-button type="primary" @click="addCommunityHandler">添加小区</a-button>
  29. </a-space>
  30. </div>
  31. </div>
  32. <a-table
  33. :columns="columns"
  34. :data-source="listData"
  35. :loading="loading"
  36. :pagination="false"
  37. :scroll="{ x: 'max-content' }"
  38. >
  39. <template #bodyCell="{ column, record }">
  40. <template v-if="column.key === 'location'">
  41. <div>{{ record.location }}</div>
  42. <div>{{ record.address }}</div>
  43. </template>
  44. <template v-if="column.key === 'time'">
  45. <div>{{ record.createTime }}</div>
  46. <div>{{ record.updateTime }}</div>
  47. </template>
  48. <template v-if="column.key === 'action'">
  49. <!-- <a-button type="link" @click="viewHandler(record.tenantId, record.tenantName)"
  50. >设备树</a-button
  51. > -->
  52. <a-button type="link" :disabled="record.sort !== 1" @click="viewDevicelHandler(record)"
  53. >查看设备</a-button
  54. >
  55. <a-button type="link" :disabled="record.sort !== 1" @click="editlHandler(record)"
  56. >编辑小区</a-button
  57. >
  58. <a-button type="link" :disabled="record.sort !== 1" @click="adminlHandler(record)"
  59. >小区管理员</a-button
  60. >
  61. </template>
  62. </template>
  63. </a-table>
  64. <base-pagination
  65. v-if="listTotal > 0"
  66. v-model:current="current"
  67. v-model:pageSize="pageSize"
  68. :total="listTotal"
  69. @change="paginationChange"
  70. @showSizeChange="paginationSizeChange"
  71. ></base-pagination>
  72. </div>
  73. <add-community-modal
  74. v-model:open="addCommunityOpen"
  75. :title="addCommunityTitle"
  76. :type="addCommunityType"
  77. :data="addCommunityData"
  78. @success="searchHandler"
  79. ></add-community-modal>
  80. </div>
  81. </template>
  82. <script setup lang="ts">
  83. import { ref, onActivated } from 'vue'
  84. import * as tenantAPI from '@/api/tenant'
  85. import type { TenantItem } from '@/api/tenant/types'
  86. import { columns } from './const'
  87. import { useSearch } from '@/hooks/useSearch'
  88. import addCommunityModal from '../components/add/index.vue'
  89. import { useRouter } from 'vue-router'
  90. const router = useRouter()
  91. defineOptions({
  92. name: 'CommunityIndex',
  93. })
  94. interface SearchData {
  95. tenantName: string // 租户名称、小区名称
  96. }
  97. // 默认搜索条件
  98. const defaultSearch: SearchData = {
  99. tenantName: '',
  100. }
  101. const [searchState, resetHandler] = useSearch(defaultSearch, { afterReset: () => searchHandler() })
  102. const listData = ref<TenantItem[]>()
  103. const listTotal = ref<number>(0)
  104. const current = ref<number>(1)
  105. const pageSize = ref<number>(10)
  106. // 分页变化
  107. const paginationChange = (current: number, pageSize: number) => {
  108. console.log('change', current, pageSize)
  109. fetchList()
  110. }
  111. // 分页大小变化
  112. const paginationSizeChange = (current: number, pageSize: number) => {
  113. console.log('showSizeChange', current, pageSize)
  114. }
  115. const loading = ref(false)
  116. // 获取租户/小区列表
  117. const fetchList = async () => {
  118. try {
  119. loading.value = true
  120. const res = await tenantAPI.queryTenant({
  121. pageNo: current.value,
  122. pageSize: pageSize.value,
  123. tenantName: searchState.tenantName,
  124. })
  125. console.log('✅获取到数据', res)
  126. const { rows, total } = res.data
  127. listData.value = rows
  128. try {
  129. listData.value = rows.map((item) => {
  130. return {
  131. ...item,
  132. location: [item.province, item.city, item.district]
  133. .map((i) => {
  134. return i?.split(',')[1] || ''
  135. })
  136. .join(' '),
  137. }
  138. })
  139. } catch (error) {
  140. console.log('❌', error)
  141. }
  142. listTotal.value = Number(total)
  143. loading.value = false
  144. } catch (err) {
  145. console.log('❌ 获取数据失败', err)
  146. loading.value = false
  147. }
  148. }
  149. onActivated(() => {
  150. fetchList()
  151. })
  152. // 搜索
  153. const searchHandler = async () => {
  154. console.log('searchState', searchState)
  155. current.value = 1
  156. pageSize.value = 10
  157. await fetchList()
  158. }
  159. // 搜索条件变化时清空搜索结果
  160. const clearHandler = (e: InputEvent) => {
  161. const target = e.target as HTMLInputElement
  162. console.log('clearHandler', e, target, target?.value)
  163. if (!target?.value) {
  164. fetchList()
  165. }
  166. }
  167. const addCommunityOpen = ref(false)
  168. const addCommunityTitle = ref('')
  169. const addCommunityType = ref<'tenant' | 'admin'>('tenant')
  170. const addCommunityData = ref<Partial<TenantItem | object>>({})
  171. // 添加小区
  172. const addCommunityHandler = () => {
  173. console.log('添加小区')
  174. addCommunityTitle.value = '添加小区'
  175. addCommunityType.value = 'tenant'
  176. addCommunityOpen.value = true
  177. addCommunityData.value = {}
  178. }
  179. // 维护管理员
  180. const adminlHandler = (item: TenantItem) => {
  181. console.log('小区管理员', item)
  182. addCommunityTitle.value = `${item.tenantName} 管理员`
  183. addCommunityType.value = 'admin'
  184. addCommunityData.value = {
  185. tenantId: item.tenantId,
  186. }
  187. addCommunityOpen.value = true
  188. }
  189. // 查看设备
  190. const viewDevicelHandler = (item: TenantItem) => {
  191. console.log('查看设备', item)
  192. router.push({
  193. name: 'deviceList',
  194. query: {
  195. tenantId: item.tenantId,
  196. },
  197. })
  198. }
  199. // 查看详情
  200. // const viewHandler = (tenantId: string, name: string) => {
  201. // console.log('查看')
  202. // router.push({
  203. // name: 'communityDetail',
  204. // query: {
  205. // tenantId,
  206. // name,
  207. // },
  208. // })
  209. // }
  210. // 编辑小区
  211. const editlHandler = (item: TenantItem) => {
  212. console.log('编辑', item)
  213. addCommunityTitle.value = '编辑小区'
  214. addCommunityType.value = 'tenant'
  215. addCommunityData.value = {
  216. tenantId: item.tenantId,
  217. tenantName: item.tenantName,
  218. tenantType: item.tenantType,
  219. pcdStrs: [item.province, item.city, item.district],
  220. address: item.address,
  221. remark: item.remark,
  222. }
  223. addCommunityOpen.value = true
  224. }
  225. </script>
  226. <style scoped lang="less">
  227. .communityPage {
  228. .searchBar {
  229. padding: 20px;
  230. background-color: #fff;
  231. margin-bottom: 20px;
  232. display: flex;
  233. justify-content: space-between;
  234. .ant-form {
  235. flex-grow: 1;
  236. }
  237. :deep(.ant-form-inline .ant-form-item) {
  238. margin-bottom: 16px !important;
  239. }
  240. }
  241. .tableCard {
  242. background-color: #fff;
  243. &-header {
  244. display: flex;
  245. justify-content: space-between;
  246. padding: 20px;
  247. &-title {
  248. font-size: 18px;
  249. font-weight: 600;
  250. }
  251. }
  252. }
  253. }
  254. </style>