pathList.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. <template>
  2. <div class="container">
  3. <Breadcrumb :items="['路径数据', '路径列表']" />
  4. <a-card title="路径列表">
  5. <a-row>
  6. <a-col :flex="1">
  7. <a-form :model="queryData" :label-col-props="{ span: 6 }" :wrapper-col-props="{ span: 18 }"
  8. label-align="left">
  9. <a-row :gutter="16">
  10. <a-col :span="8">
  11. <a-form-item field="area" label="跑区">
  12. <a-select v-model="queryData.area" placeholder="请选择乐跑跑区" default-value="">
  13. <a-option value="">所有</a-option>
  14. <a-option v-for="(item, index) in areas" :key="index" :value="item">
  15. {{ item }}
  16. </a-option>
  17. </a-select>
  18. </a-form-item>
  19. </a-col>
  20. <a-col :span="8">
  21. <a-form-item field="path_id" label="路径ID">
  22. <a-input-number v-model="queryData.path_id" placeholder="请输入路径ID" :step="1"
  23. :precision="0" />
  24. </a-form-item>
  25. </a-col>
  26. <a-col :span="8">
  27. <a-form-item field="min_distance" label="最短距离">
  28. <a-input-number v-model="queryData.min_distance" placeholder="请输入最短距离" :step="0.01"
  29. :precision="2" />
  30. </a-form-item>
  31. </a-col>
  32. <a-col :span="8">
  33. <a-form-item field="max_distance" label="最长距离">
  34. <a-input-number v-model="queryData.max_distance" placeholder="请输入最长距离" :step="0.01"
  35. :precision="2" />
  36. </a-form-item>
  37. </a-col>
  38. <a-col :span="8">
  39. <a-form-item field="area" label="状态">
  40. <a-select v-model="queryData.state" :options="state" placeholder="请选择路径状态"
  41. :default-value="-1" />
  42. </a-form-item>
  43. </a-col>
  44. </a-row>
  45. </a-form>
  46. </a-col>
  47. <a-divider style="height: 84px" direction="vertical" />
  48. <a-col :flex="'86px'" style="text-align: right">
  49. <a-space direction="vertical" :size="18">
  50. <a-button type="primary" @click="search">
  51. <template #icon>
  52. <icon-search />
  53. </template>
  54. 搜索
  55. </a-button>
  56. <a-button @click="reset">
  57. <template #icon>
  58. <icon-refresh />
  59. </template>
  60. 重置
  61. </a-button>
  62. </a-space>
  63. </a-col>
  64. </a-row>
  65. <a-table :data="data" stripe hoverable column-resizable class="table" :loading="loading" :columns="columns"
  66. :pagination="{
  67. showPageSize: true,
  68. showJumper: true,
  69. showTotal: true,
  70. pageSize: pagination.pagesize,
  71. current: pagination.current,
  72. total: pagination.total
  73. }" @page-change="handlePageChange" @page-size-change="handlePageSizeChange">
  74. <template #distance="{ record }">
  75. {{ Number(record.distance).toFixed(2) }} Km
  76. </template>
  77. <template #time="{ record }">
  78. {{ formatSecondsToMinSec(record.time) }}
  79. </template>
  80. <template #state="{ record }">
  81. <a-tag color="blue" v-if="!record.state">待审核</a-tag>
  82. <a-tag color="green" v-else-if="record.state === 1">审核通过</a-tag>
  83. <a-tag color="red" v-else-if="record.state === 2">审核失败</a-tag>
  84. </template>
  85. <template #optional="{ record }">
  86. <a-button @click="$router.push(`/path/detail/${record.id}`)">查看详情</a-button>
  87. </template>
  88. </a-table>
  89. </a-card>
  90. </div>
  91. </template>
  92. <script setup>
  93. import { ref, reactive, onMounted } from 'vue'
  94. import { GetPathList } from '@/api/pathData'
  95. import { Notification } from '@arco-design/web-vue'
  96. const queryData = reactive({
  97. area: '',
  98. path_id: '',
  99. min_distance: 1.60,
  100. max_distance: 10.00,
  101. state: -1
  102. })
  103. const pagination = reactive({
  104. total: 0,
  105. current: 1, // 默认从第1页开始
  106. pagesize: 20
  107. })
  108. const loading = ref(false)
  109. const data = ref([])
  110. const state = [
  111. { label: '全部', value: -1 }, { label: '待审核', value: 0 }, { label: '审核通过', value: 1 }, { label: '审核失败', value: 2 }
  112. ]
  113. const areas = ["重庆工程学院南泉校区", "重庆工程学院双桥校区"]
  114. const columns = [{
  115. title: 'ID',
  116. dataIndex: 'id',
  117. }, {
  118. title: '跑区',
  119. dataIndex: 'run_zone_name',
  120. }, {
  121. title: '跑步距离(Km)',
  122. slotName: 'distance',
  123. }, {
  124. title: '用时',
  125. slotName: 'time'
  126. }, {
  127. title: '配速',
  128. dataIndex: 'speed',
  129. }, {
  130. title: '使用次数',
  131. dataIndex: 'count',
  132. }, {
  133. title: '状态',
  134. slotName: 'state'
  135. }, {
  136. title: '操作',
  137. slotName: 'optional'
  138. }]
  139. const search = () => {
  140. pagination.current = 1
  141. getPathList()
  142. }
  143. const reset = () => {
  144. pagination.current = 1
  145. queryData.area = ''
  146. queryData.state = -1
  147. queryData.path_id = ''
  148. queryData.min_distance = 1.60
  149. queryData.max_distance = 10.00
  150. getPathList()
  151. }
  152. const getPathList = async () => {
  153. try {
  154. loading.value = true
  155. const reqData = {
  156. ...queryData,
  157. pagesize: pagination.pagesize,
  158. current: pagination.current
  159. }
  160. const res = await GetPathList(reqData)
  161. if (!res || res.code !== 0)
  162. return Notification.error({
  163. title: '获取路径数据失败!',
  164. content: res?.msg ?? '请稍后再试'
  165. })
  166. data.value = res.data
  167. pagination.total = res.pagination.total
  168. } catch (error) {
  169. Notification.error({
  170. title: '获取路径数据失败!',
  171. content: error.message || '请稍后再试'
  172. })
  173. } finally {
  174. loading.value = false
  175. }
  176. }
  177. // 分页 - 页码变化
  178. const handlePageChange = (page) => {
  179. pagination.current = page
  180. getPathList()
  181. }
  182. // 分页 - 每页条数变化
  183. const handlePageSizeChange = (size) => {
  184. pagination.pagesize = size
  185. pagination.current = 1 // 页大小变化后回到第一页
  186. getPathList()
  187. }
  188. onMounted(() => {
  189. getPathList()
  190. })
  191. function formatSecondsToMinSec(totalSeconds) {
  192. const minutes = Math.floor(totalSeconds / 60);
  193. const seconds = totalSeconds % 60;
  194. return `${minutes}分${seconds.toString().padStart(2, '0')}秒`;
  195. }
  196. </script>
  197. <style scoped>
  198. .container {
  199. padding: 0 20px 20px 20px;
  200. }
  201. .table {
  202. margin-top: 15px;
  203. }
  204. </style>