index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. <template>
  2. <div class="app-container" ref="appContainer">
  3. <PropTable :loading="loading" @selection-change="selectionChange" :columns="column" :data="list" @reset="reset"
  4. @onSubmit="onSubmit">
  5. <template v-slot:btn>
  6. <div style="display: flex; justify-content: flex-end">
  7. <el-button type="primary" @click="add"><el-icon>
  8. <plus />
  9. </el-icon>添加</el-button>
  10. <el-button type="danger" @click="batchDelete"><el-icon>
  11. <delete />
  12. </el-icon>删除</el-button>
  13. </div>
  14. </template>
  15. <template v-slot:loadType="scope">{{ getLoadTypeLabel(scope.row.loadType) }}</template>
  16. <template v-slot:operation="scope">
  17. <el-button type="primary" size="small" icon="Edit" @click="edit(scope.row)">
  18. 编辑
  19. </el-button>
  20. <el-button @click="del(scope.row)" type="danger" size="small" icon="Delete">
  21. 删除
  22. </el-button>
  23. </template>
  24. </PropTable>
  25. <el-dialog v-model="dialogVisible" :title='title' width="50%">
  26. <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="120px" class="demo-ruleForm"
  27. :size="formSize">
  28. <el-form-item label="ID" prop="id">
  29. <el-input v-model="ruleForm.id" />
  30. </el-form-item>
  31. <el-form-item label="资源地址" prop="assetsUrl">
  32. <el-input v-model="ruleForm.assetsUrl" />
  33. </el-form-item>
  34. <el-form-item label="资源版本" prop="assetsVer">
  35. <el-input v-model="ruleForm.assetsVer" />
  36. </el-form-item>
  37. <el-form-item label="资源强更版本" prop="forceAssetsVer">
  38. <el-input v-model="ruleForm.forceAssetsVer" />
  39. </el-form-item>
  40. <el-form-item label="安装包版本" prop="apkVer">
  41. <el-input v-model="ruleForm.apkVer" />
  42. </el-form-item>
  43. <el-form-item label="安装包子版本" prop="apkSubVer">
  44. <el-input v-model="ruleForm.apkSubVer" />
  45. </el-form-item>
  46. <el-form-item label="打包版本" prop="buildVer">
  47. <el-input v-model="ruleForm.buildVer" />
  48. </el-form-item>
  49. <el-form-item label="协议版本" prop="protocolVer">
  50. <el-input v-model="ruleForm.protocolVer" />
  51. </el-form-item>
  52. <el-form-item label="资源加载类型" prop="loadType">
  53. <el-radio-group v-model="ruleForm.loadType">
  54. <el-radio :label="0">远程加载</el-radio>
  55. <el-radio :label="1">本地加载</el-radio>
  56. </el-radio-group>
  57. </el-form-item>
  58. </el-form>
  59. <template #footer>
  60. <span class="dialog-footer">
  61. <el-button @click="dialogVisible = false">取消</el-button>
  62. <el-button type="primary" @click="handleClose(ruleFormRef)">确定</el-button>
  63. </span>
  64. </template>
  65. </el-dialog>
  66. </div>
  67. </template>
  68. <script lang="ts" setup name="comprehensive">
  69. import { ref, reactive, onMounted, nextTick, onBeforeMount } from 'vue'
  70. import { ElMessage, ElMessageBox } from 'element-plus'
  71. import type { FormInstance } from 'element-plus'
  72. import clientConfigApi from '@/api/clientConfig'
  73. import PropTable from '@/components/Table/PropTable/index.vue'
  74. const loading = ref(true)
  75. const appContainer = ref(null)
  76. // import { ref } from 'vue'
  77. import ExcelJS from 'exceljs'
  78. import { UploadFilled } from '@element-plus/icons-vue'
  79. import type { UploadProps, UploadInstance } from 'element-plus'
  80. // import { ElMessage } from 'element-plus'
  81. const tableData = ref([])
  82. const tableHeader = ref([])
  83. const upload = ref<UploadInstance>()
  84. const tableColumn = ["title","type","validTime","invalidTime","content"]
  85. const beforeUploadAction = (file, fileLi) => {
  86. return new Promise((resolve, reject) => {
  87. const reader = new FileReader()
  88. reader.onload = async (e) => {
  89. const data = e.target.result
  90. const workbook = new ExcelJS.Workbook()
  91. try {
  92. let res = await workbook.xlsx.load(data)
  93. const sheets =
  94. res._worksheets && res._worksheets.filter((item) => typeof item !== 'undefined')
  95. const table = []
  96. let headers = []
  97. sheets.forEach((sheet) => {
  98. sheet._rows.forEach((row, index) => {
  99. if (index === 0) {
  100. row.values.forEach((it, i) => {
  101. // console.log("string" + it + " " + i + "" + tableColumn[i])
  102. headers.push({label: it, value: tableColumn[i - 1]})
  103. })
  104. } else {
  105. let obj = {}
  106. let arr = []
  107. row.values.forEach((it) => {
  108. arr.push(it)
  109. })
  110. tableColumn.forEach((ite, i) => {
  111. if (arr[i] == undefined) {
  112. obj[ite] = null
  113. } else {
  114. obj[ite] = arr[i]
  115. }
  116. })
  117. table.push(obj)
  118. }
  119. // const tableRow = {
  120. // position: "",
  121. // val: "",
  122. // };
  123. // row._cells.forEach((cell) => {
  124. // tableRow.position = cell._address;
  125. // tableRow.val = cell._value.model.value || "";
  126. // });
  127. })
  128. })
  129. tableData.value = table
  130. tableHeader.value = headers
  131. console.log("table", table)
  132. console.log("headers", headers)
  133. } catch (e) {
  134. ElMessage.error('解析失败')
  135. }
  136. }
  137. reader.readAsArrayBuffer(file)
  138. })
  139. }
  140. const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => {
  141. tableData.value = null
  142. tableHeader.value = null
  143. }
  144. const data = ref([])
  145. let currPageNum = 1;
  146. const pageSize = 1000;
  147. onBeforeMount(() => {
  148. loadClientConfigInfo()
  149. })
  150. const loadClientConfigInfo = () => {
  151. let queryParams = reactive({
  152. pageNum: currPageNum,
  153. pageSize: pageSize
  154. })
  155. clientConfigApi.query(queryParams).then(res => {
  156. data.value = res.data.result;
  157. console.log(data)
  158. })
  159. }
  160. const column = [
  161. { type: 'selection', width: 60, fixed: 'left' },
  162. { name: 'id', label: 'ID', width: 80, inSearch: true, valueType: 'input' },
  163. { name: 'assetsUrl', label: '资源地址' },
  164. { name: 'assetsVer', label: '资源版本' },
  165. { name: 'forceAssetsVer', label: '强更资源版本' },
  166. { name: 'apkVer', label: '安装包版本' },
  167. { name: 'apkSubVer', label: '安装包子版本' },
  168. { name: 'buildVer', label: '打包版本' },
  169. { name: 'protocolVer', label: '协议版本' },
  170. { name: 'loadType', label: '资源加载类型', slot: true},
  171. { name: 'operation', slot: true, fixed: 'right', width: 200, label: '操作' },
  172. ]
  173. const getLoadTypeLabel = (val) => {
  174. if (val == 0) {
  175. return '远程加载'
  176. } else if (val == 1) {
  177. return '本地加载'
  178. }
  179. }
  180. const list = ref(data)
  181. const formSize = ref('default')
  182. const ruleFormRef = ref<FormInstance>()
  183. const ruleForm = reactive({
  184. id: null,
  185. assetsUrl: null,
  186. assetsVer: null,
  187. forceAssetsVer: null,
  188. apkVer: null,
  189. apkSubVer: null,
  190. buildVer: null,
  191. protocolVer: null,
  192. loadType:0
  193. })
  194. const rules = reactive({
  195. id: [
  196. {
  197. required: true,
  198. message: '请输入ID',
  199. trigger: 'change',
  200. },
  201. ],
  202. assetsUrl: [
  203. {
  204. required: true,
  205. message: '请输入资源地址',
  206. trigger: 'change',
  207. },
  208. ],
  209. assetsVer: [
  210. {
  211. required: true,
  212. message: '请输入资源版本号',
  213. trigger: 'change',
  214. },
  215. ]
  216. })
  217. const dialogVisible = ref(false)
  218. const importVisible = ref(false)
  219. const rowObj = ref({})
  220. const selectObj = ref([])
  221. const title = ref('详情')
  222. const add = () => {
  223. title.value = '新增'
  224. dialogVisible.value = true
  225. ruleForm.id = null
  226. ruleForm.assetsUrl = null
  227. ruleForm.assetsVer = null
  228. ruleForm.forceAssetsVer = null
  229. ruleForm.apkVer = null
  230. ruleForm.apkSubVer = null
  231. ruleForm.buildVer = null
  232. ruleForm.protocolVer = null
  233. ruleForm.loadType = 0
  234. }
  235. const handleConfirm = () => {
  236. // 验证table数据
  237. // ...
  238. let importParams = reactive({
  239. importValue: tableData.value
  240. })
  241. clientConfigApi.importBatch(importParams).then(res => {
  242. console.log('result', res)
  243. if (res.data.code = 200) {
  244. loadClientConfigInfo()
  245. importVisible.value = false
  246. return ElMessage.success(res.data.msg)
  247. } else {
  248. return ElMessage.error(res.data.msg)
  249. }
  250. })
  251. console.log('import submit!')
  252. }
  253. const handleClose = async (done: () => void) => {
  254. await ruleFormRef.value.validate((valid, fields) => {
  255. if (valid) {
  256. if (title.value == '新增') {
  257. clientConfigApi.add(ruleForm).then(res => {
  258. console.log('result', res)
  259. if (res.data.code = 200) {
  260. loadClientConfigInfo()
  261. dialogVisible.value = false
  262. return ElMessage.success(res.data.msg)
  263. } else {
  264. return ElMessage.error(res.data.msg)
  265. }
  266. })
  267. console.log('add submit!')
  268. } else {
  269. // let updateParams = reactive({
  270. // id: rowObj.value.id,
  271. // updateValue: ruleForm
  272. // })
  273. clientConfigApi.update(ruleForm).then(res => {
  274. if (res.data.code = 200) {
  275. loadClientConfigInfo()
  276. dialogVisible.value = false
  277. return ElMessage.success('修改成功')
  278. } else {
  279. return ElMessage.error('修改失败')
  280. }
  281. })
  282. console.log('update submit!')
  283. }
  284. console.log('submit!', ruleForm)
  285. } else {
  286. console.log('error submit!', fields)
  287. }
  288. })
  289. }
  290. const batchDelete = () => {
  291. if (!selectObj.value.length) {
  292. return ElMessage.error('未选中任何行')
  293. }
  294. ElMessageBox.confirm('你确定要删除选中项吗?', '温馨提示', {
  295. confirmButtonText: '确定',
  296. cancelButtonText: '取消',
  297. type: 'warning',
  298. draggable: true,
  299. })
  300. .then(() => {
  301. let selectClientConfigIds = reactive([])
  302. for (let value of selectObj.value) {
  303. selectClientConfigIds.push(value.id)
  304. }
  305. let deleteParams = reactive({
  306. deleteIds: selectClientConfigIds
  307. })
  308. clientConfigApi.deleteBatch(deleteParams).then(res => {
  309. loadClientConfigInfo()
  310. ElMessage.success('批量删除成功')
  311. })
  312. list.value = list.value.concat([])
  313. })
  314. .catch(() => { })
  315. }
  316. const selectionChange = (val) => {
  317. selectObj.value = val
  318. }
  319. const edit = (row) => {
  320. title.value = '编辑'
  321. rowObj.value = row
  322. dialogVisible.value = true
  323. ruleForm.id = row.id
  324. ruleForm.assetsUrl = row.assetsUrl
  325. ruleForm.assetsVer = row.assetsVer == null ? row.assetsVer : row.assetsVer.toString()
  326. ruleForm.forceAssetsVer = row.forceAssetsVer == null ? row.forceAssetsVer : row.forceAssetsVer.toString()
  327. ruleForm.apkVer = row.apkVer == null ? row.apkVer : row.apkVer.toString()
  328. ruleForm.apkSubVer = row.apkSubVer == null ? row.apkSubVer : row.apkSubVer.toString()
  329. ruleForm.buildVer = row.buildVer == null ? row.buildVer : row.buildVer.toString()
  330. ruleForm.protocolVer = row.protocolVer == null ? row.protocolVer : row.protocolVer.toString()
  331. ruleForm.loadType = row.loadType
  332. }
  333. const del = (row) => {
  334. console.log('row==', row)
  335. ElMessageBox.confirm('你确定要删除当前项吗?', '温馨提示', {
  336. confirmButtonText: '确定',
  337. cancelButtonText: '取消',
  338. type: 'warning',
  339. draggable: true,
  340. })
  341. .then(() => {
  342. let deleteParams = reactive({
  343. id: row.id
  344. })
  345. clientConfigApi.delete(deleteParams).then(res => {
  346. loadClientConfigInfo()
  347. ElMessage.success('删除成功')
  348. })
  349. loading.value = true
  350. setTimeout(() => {
  351. loading.value = false
  352. }, 500)
  353. })
  354. .catch(() => { })
  355. }
  356. const reset = () => {
  357. loadClientConfigInfo()
  358. loading.value = true
  359. setTimeout(() => {
  360. loading.value = false
  361. }, 500)
  362. ElMessage.success('重置成功')
  363. }
  364. const onSubmit = (val) => {
  365. if (val.id == null) {
  366. ElMessage.warning('请输入查询条件')
  367. return
  368. }
  369. let queryParams = reactive({
  370. pageNum: 1,
  371. pageSize: pageSize,
  372. condition: val
  373. })
  374. clientConfigApi.query(queryParams).then(res => {
  375. data.value = res.data.result;
  376. console.log(data.value)
  377. })
  378. loading.value = true
  379. setTimeout(() => {
  380. loading.value = false
  381. }, 500)
  382. }
  383. const getHeight = () => {
  384. }
  385. onMounted(() => {
  386. nextTick(() => {
  387. // let data = appContainer.value.
  388. })
  389. setTimeout(() => {
  390. loading.value = false
  391. }, 500)
  392. })
  393. </script>
  394. <style scoped>
  395. .edit-input {
  396. padding-right: 100px;
  397. }
  398. .app-container {
  399. flex: 1;
  400. display: flex;
  401. width: 100%;
  402. padding: 16px;
  403. box-sizing: border-box;
  404. }
  405. .cancel-btn {
  406. position: absolute;
  407. right: 15px;
  408. top: 10px;
  409. }
  410. .m-upload-excel {
  411. .el-upload {
  412. width: 100%;
  413. }
  414. .el-upload-dragger {
  415. width: 100%;
  416. }
  417. }
  418. </style>