index.vue 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. <script setup lang="ts">
  2. import { FiveIotProjectDailyReportApi } from '@/api/pms/fiveconstructiondailyreport'
  3. import { useUserStore } from '@/store/modules/user'
  4. import { rangeShortcuts } from '@/utils/formatTime'
  5. import { useDebounceFn } from '@vueuse/core'
  6. import dayjs from 'dayjs'
  7. import ConstructionDailyReportDrawer from './components/ConstructionDailyReportDrawer.vue'
  8. import ConstructionDailyReportTable from './components/ConstructionDailyReportTable.vue'
  9. import type {
  10. ConstructionDailyReportQuery,
  11. ConstructionDailyReportRow
  12. } from './components/report-config'
  13. defineOptions({ name: 'ConstructionDailyReport' })
  14. const userStore = useUserStore()
  15. const deptId = userStore.getUser.deptId
  16. const route = useRoute()
  17. const parseQueryNumber = (value: unknown) => {
  18. if (Array.isArray(value)) {
  19. return parseQueryNumber(value[0])
  20. }
  21. if (value === undefined || value === null || value === '') {
  22. return undefined
  23. }
  24. const parsedValue = Number(value)
  25. return Number.isNaN(parsedValue) ? undefined : parsedValue
  26. }
  27. const resolveCreateTimeFromRoute = () => {
  28. const createTime = route.query.createTime
  29. if (Array.isArray(createTime)) {
  30. const values = createTime.filter((item): item is string => typeof item === 'string')
  31. return values.length === 2 ? values : undefined
  32. }
  33. if (typeof createTime === 'string') {
  34. const values = createTime.split(',').filter(Boolean)
  35. return values.length === 2 ? values : undefined
  36. }
  37. return undefined
  38. }
  39. const getDefaultCreateTime = (): string[] => {
  40. const yesterday = dayjs().subtract(1, 'day')
  41. return [
  42. yesterday.startOf('day').format('YYYY-MM-DD HH:mm:ss'),
  43. yesterday.endOf('day').format('YYYY-MM-DD HH:mm:ss')
  44. ]
  45. }
  46. const createDefaultQuery = (): ConstructionDailyReportQuery => ({
  47. pageNo: 1,
  48. pageSize: 10,
  49. deptId: parseQueryNumber(route.query.deptId) ?? deptId,
  50. projectDeptId: parseQueryNumber(route.query.projectDeptId),
  51. teamId: parseQueryNumber(route.query.teamId),
  52. createTime: resolveCreateTimeFromRoute() ?? getDefaultCreateTime()
  53. })
  54. const query = ref<ConstructionDailyReportQuery>(createDefaultQuery())
  55. const list = ref<ConstructionDailyReportRow[]>([])
  56. const total = ref(0)
  57. const loading = ref(false)
  58. const visible = ref(false)
  59. const formRef = ref<InstanceType<typeof ConstructionDailyReportDrawer>>()
  60. function syncQueryFromRoute() {
  61. const nextQuery = createDefaultQuery()
  62. query.value = {
  63. ...query.value,
  64. deptId: nextQuery.deptId,
  65. projectDeptId: nextQuery.projectDeptId,
  66. teamId: nextQuery.teamId,
  67. createTime: nextQuery.createTime
  68. }
  69. }
  70. const loadList = useDebounceFn(async () => {
  71. loading.value = true
  72. try {
  73. const data = await FiveIotProjectDailyReportApi.getIotProjectDailyReportPage(query.value as any)
  74. list.value = data.list ?? []
  75. total.value = data.total ?? 0
  76. } finally {
  77. loading.value = false
  78. }
  79. }, 200)
  80. function handleQuery(setPage = true) {
  81. if (setPage) {
  82. query.value.pageNo = 1
  83. }
  84. loadList()
  85. }
  86. function resetQuery() {
  87. query.value = createDefaultQuery()
  88. handleQuery()
  89. }
  90. function handleSizeChange(value: number) {
  91. query.value.pageSize = value
  92. handleQuery()
  93. }
  94. function handleCurrentChange(value: number) {
  95. query.value.pageNo = value
  96. loadList()
  97. }
  98. function handleOpenForm(id: number, type: 'edit' | 'readonly') {
  99. formRef.value?.handleOpenForm(id, type)
  100. }
  101. watch(
  102. [
  103. () => query.value.deptId,
  104. () => query.value.projectDeptId,
  105. () => query.value.teamId,
  106. () => query.value.projectName,
  107. () => query.value.wellName,
  108. () => query.value.createTime
  109. ],
  110. () => handleQuery(),
  111. { immediate: true }
  112. )
  113. watch(
  114. () => [route.query.deptId, route.query.projectDeptId, route.query.teamId, route.query.createTime],
  115. () => {
  116. syncQueryFromRoute()
  117. }
  118. )
  119. onMounted(() => {
  120. if (route.query.id) {
  121. handleOpenForm(Number(route.query.id), 'edit')
  122. }
  123. })
  124. </script>
  125. <template>
  126. <div
  127. class="grid grid-cols-[auto_1fr] grid-rows-[62px_1fr] gap-4 h-[calc(100vh-20px-var(--top-tool-height)-var(--tags-view-height)-var(--app-footer-height))]">
  128. <DeptTreeSelect
  129. v-model="query.deptId"
  130. :top-id="388"
  131. :deptId="deptId"
  132. :show-title="false"
  133. class="row-span-2" />
  134. <el-form
  135. size="default"
  136. class="bg-white dark:bg-[#1d1e1f] rounded-lg shadow px-8 gap-8 flex items-center justify-between">
  137. <div class="flex items-center gap-8">
  138. <el-form-item label="项目">
  139. <el-input
  140. v-model="query.projectName"
  141. placeholder="请输入项目名称"
  142. clearable
  143. @keyup.enter="handleQuery()"
  144. class="!w-240px" />
  145. </el-form-item>
  146. <el-form-item label="生产任务">
  147. <el-input
  148. v-model="query.wellName"
  149. placeholder="请输入生产任务"
  150. clearable
  151. @keyup.enter="handleQuery()"
  152. class="!w-240px" />
  153. </el-form-item>
  154. <el-form-item label="创建时间">
  155. <el-date-picker
  156. v-model="query.createTime"
  157. value-format="YYYY-MM-DD HH:mm:ss"
  158. type="daterange"
  159. start-placeholder="开始日期"
  160. end-placeholder="结束日期"
  161. :shortcuts="rangeShortcuts"
  162. :default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
  163. class="!w-260px" />
  164. </el-form-item>
  165. </div>
  166. <el-form-item>
  167. <el-button type="primary" @click="handleQuery()">
  168. <Icon icon="ep:search" class="mr-5px" /> 搜索
  169. </el-button>
  170. <el-button @click="resetQuery"> <Icon icon="ep:refresh" class="mr-5px" /> 重置 </el-button>
  171. </el-form-item>
  172. </el-form>
  173. <ConstructionDailyReportTable
  174. :list="list"
  175. :loading="loading"
  176. :total="total"
  177. :page-no="query.pageNo"
  178. :page-size="query.pageSize"
  179. @size-change="handleSizeChange"
  180. @current-change="handleCurrentChange">
  181. <template #action="{ row }">
  182. <el-button
  183. link
  184. type="primary"
  185. @click="handleOpenForm(row.id!, 'edit')"
  186. v-hasPermi="['pms:iot-five-daily-report:update']">
  187. 填报
  188. </el-button>
  189. <el-button
  190. link
  191. type="success"
  192. @click="handleOpenForm(row.id!, 'readonly')"
  193. v-hasPermi="['pms:iot-five-daily-report:query']">
  194. 查看
  195. </el-button>
  196. </template>
  197. </ConstructionDailyReportTable>
  198. </div>
  199. <ConstructionDailyReportDrawer ref="formRef" v-model:visible="visible" :load-list="loadList" />
  200. </template>
  201. <style scoped>
  202. :deep(.el-form-item) {
  203. margin-bottom: 0;
  204. }
  205. </style>