index.vue 6.7 KB

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