index.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <template>
  2. <div class="container">
  3. <div v-show="!dataManagementAddState.show && !dataManagementViewState.show" class="search-bar">
  4. <div class="mb-[10px]">
  5. <el-form ref="queryFormRef" :model="queryParams" :inline="true">
  6. <el-form-item label="选择数据:" prop="planType" label-width="auto">
  7. <div class="flex" style="align-items: center; justify-content: flex-start">
  8. <el-select v-model="queryParams.dataType" placeholder="选择数据" @change="onDataTypeChange">
  9. <el-option v-for="item in type" :key="item.id" :label="item.layer_name" :value="item.id" />
  10. </el-select>
  11. <div class="info">
  12. <span>数据更新:{{ dataUpdateTime }}</span>
  13. <span class="spacer">数源单位:{{ dataSourceUnit }}</span>
  14. </div>
  15. </div>
  16. </el-form-item>
  17. </el-form>
  18. </div>
  19. <el-form-item>
  20. <el-button type="primary" icon="Plus" @click="handleAdd">录入</el-button>
  21. <el-button plain icon="Upload" @click="openImportDialog">批量导入</el-button>
  22. </el-form-item>
  23. </div>
  24. <el-table v-loading="loading" :data="tableData" :max-height="tableHeight">
  25. <el-table-column
  26. v-for="(item, index) in tableHeader"
  27. :key="index"
  28. :prop="item.column_name"
  29. :label="item.column_comment"
  30. :min-width="item.column_comment.length * 25 > 100 ? item.column_comment.length * 25 : 100"
  31. align="center"
  32. />
  33. <el-table-column label="操作" align="center" width="150px" fixed="right">
  34. <template #default="scope">
  35. <el-text v-hasPermi="['system:menu:View']" class="common-btn-text-primary" @click="handleView(scope.row)">查看</el-text>
  36. <el-text v-hasPermi="['system:menu:edit']" class="common-btn-text-primary" @click="handleUpdate(scope.row)">修改</el-text>
  37. <el-text v-hasPermi="['system:menu:remove']" class="common-btn-text-danger" @click="removeItem(scope.row)">删除</el-text>
  38. </template>
  39. </el-table-column>
  40. </el-table>
  41. <pagination v-show="total > 0" v-model:page="queryParams.page" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
  42. <AddDataManagement
  43. v-if="dataManagementAddState.show"
  44. :data-type="queryParams.dataType"
  45. :detail-data="dataManagementAddState.data"
  46. @on-cancel="handleCancel"
  47. @on-confirm="onConfirm"
  48. />
  49. <ViewDataManagement
  50. v-if="dataManagementViewState.show"
  51. :data-type="queryParams.dataType"
  52. :detail-data="dataManagementViewState.data"
  53. @on-cancel="handleCancel"
  54. />
  55. <DataImport
  56. v-model="showImportDialog"
  57. :url="importUrl"
  58. :data-type="queryParams.dataType"
  59. :file-name="fileName + '模板.xlsx'"
  60. :steps-text="fileName"
  61. @success="getList"
  62. />
  63. </div>
  64. </template>
  65. <script lang="ts" setup>
  66. import ViewDataManagement from './ViewDataManagement.vue';
  67. import AddDataManagement from './AddDataManagement.vue';
  68. import DataImport from './DataImport.vue';
  69. import { deleteDataManagerInfo, getDataManagerDataList, getDataManagerInfo, getDataManagerList } from '@/api/dataManagement/dataManagement';
  70. import { parseTime } from '@/utils/ruoyi';
  71. import { deepClone } from '@/utils';
  72. const { proxy } = getCurrentInstance() as ComponentInternalInstance;
  73. const queryParams = reactive({
  74. dataType: '',
  75. page: 1,
  76. pageSize: 10
  77. });
  78. const baseUrl = import.meta.env.VITE_APP_BASE_API;
  79. let loading = ref(false);
  80. const total = ref(0); // 总条目数
  81. const type = ref([]);
  82. const tableHeight = ref(document.documentElement.scrollHeight - 295 + 'px');
  83. const tableHeader = ref([]);
  84. // 表格数据
  85. const tableData = ref([]);
  86. const dataUpdateTime = ref('');
  87. const dataSourceUnit = ref('');
  88. let showImportDialog = ref(false);
  89. let importUrl = ref('');
  90. let fileName = ref('');
  91. let dataManagementViewState = reactive({
  92. show: false,
  93. data: {}
  94. });
  95. let dataManagementAddState = reactive({
  96. show: false,
  97. data: {}
  98. });
  99. // 打开新增
  100. const handleAdd = () => {
  101. dataManagementAddState.data = {};
  102. dataManagementAddState.show = true;
  103. };
  104. // 打开详情
  105. const handleView = (row: any) => {
  106. dataManagementViewState.data = row;
  107. dataManagementViewState.show = true;
  108. };
  109. // 打开修改
  110. const handleUpdate = (row: any) => {
  111. dataManagementAddState.data = deepClone(row);
  112. dataManagementAddState.show = true;
  113. };
  114. // 关闭
  115. const handleCancel = () => {
  116. dataManagementViewState.show = false;
  117. dataManagementAddState.show = false;
  118. };
  119. const onConfirm = () => {
  120. handleCancel();
  121. // queryParams.page = 1;
  122. getList();
  123. };
  124. // 删除
  125. const removeItem = (item) => {
  126. proxy?.$modal.confirm('是否确认删除选择的数据项?').then(() => {
  127. deleteDataManagerInfo(queryParams.dataType, item.id).then(() => {
  128. proxy?.$modal.msgSuccess('删除成功');
  129. getList();
  130. });
  131. });
  132. };
  133. // 数据选择变化
  134. const onDataTypeChange = () => {
  135. const index = type.value.findIndex((row) => row.id === queryParams.dataType);
  136. if (index !== -1) {
  137. importUrl.value = '/api/dataManager/generate_import_template/' + queryParams.dataType;
  138. fileName.value = type.value[index].layer_name;
  139. dataUpdateTime.value = parseTime(type.value[index].data_update_time);
  140. dataSourceUnit.value = type.value[index].data_resouce;
  141. }
  142. queryParams.page = 1;
  143. getList();
  144. };
  145. const parseTableTime = () => {
  146. if (tableHeader.value.length == 0 || tableData.value.length == 0) return;
  147. tableHeader.value.forEach((row) => {
  148. let pattern = '';
  149. if (row.data_type === 'datetime') {
  150. pattern = '{y}-{m}-{d} {h}:{i}:{s}';
  151. } else if (row.data_type === 'date') {
  152. pattern = '{y}-{m}-{d}';
  153. }
  154. if (pattern) {
  155. tableData.value.forEach((item) => {
  156. if (item[row.column_name]) {
  157. item[row.column_name] = parseTime(item[row.column_name], pattern);
  158. }
  159. });
  160. }
  161. });
  162. };
  163. // 获取表格数据
  164. const getList = async () => {
  165. loading.value = true;
  166. tableHeader.value = [];
  167. getDataManagerInfo(queryParams.dataType).then((res) => {
  168. tableHeader.value = res.data.columns;
  169. parseTableTime();
  170. });
  171. getDataManagerDataList(queryParams.dataType, { page: queryParams.page, pageSize: queryParams.pageSize })
  172. .then((res) => {
  173. tableData.value = res.data;
  174. total.value = res.total;
  175. parseTableTime();
  176. })
  177. .finally(() => {
  178. loading.value = false;
  179. });
  180. };
  181. // 加载数据
  182. const loadData = () => {
  183. getDataManagerList().then((res) => {
  184. type.value = res.data;
  185. queryParams.dataType = type.value[0].id;
  186. importUrl.value = '/api/dataManager/generate_import_template/' + queryParams.dataType;
  187. fileName.value = type.value[0].layer_name;
  188. dataUpdateTime.value = parseTime(type.value[0].data_update_time);
  189. dataSourceUnit.value = type.value[0].data_resouce;
  190. getList();
  191. });
  192. };
  193. // 打开批量导入弹窗
  194. const openImportDialog = () => {
  195. showImportDialog.value = true;
  196. };
  197. onMounted(() => {
  198. loadData();
  199. });
  200. </script>
  201. <style scoped>
  202. .container {
  203. max-width: 2200px;
  204. margin: 0 auto;
  205. padding: 20px;
  206. display: flex;
  207. flex-direction: column;
  208. }
  209. .search-bar {
  210. margin-bottom: 20px;
  211. }
  212. .info {
  213. display: flex;
  214. align-items: center;
  215. margin-left: 20px;
  216. }
  217. .spacer {
  218. margin-left: 15px;
  219. }
  220. </style>