app.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. <template>
  2. <basic-container>
  3. <avue-crud :option="option"
  4. :table-loading="loading"
  5. :data="data"
  6. ref="crud"
  7. v-model="form"
  8. :page.sync="page"
  9. :permission="permissionList"
  10. :before-open="beforeOpen"
  11. @row-del="rowDel"
  12. @row-update="rowUpdate"
  13. @row-save="rowSave"
  14. @selection-change="selectionChange"
  15. @current-change="currentChange"
  16. @size-change="sizeChange"
  17. @refresh-change="refreshChange"
  18. @on-load="onLoad">
  19. <template slot-scope="scope" slot="menu">
  20. <el-button type="text" size="small" icon="el-icon-upload2" @click.stop="handleAdd(scope.row,scope.index)">升级
  21. </el-button>
  22. </template>
  23. </avue-crud>
  24. <!-- 升级 -->
  25. <el-dialog class="app-upload-dialog" title="App升级" :visible.sync="dialogUpload" append-to-body center>
  26. <avue-crud :option="option1"
  27. :table-loading="loadingDeail"
  28. :data="dataDetail"
  29. ref="crud"
  30. v-model="form"
  31. :page.sync="pageDetail"
  32. :permission="permissionList"
  33. :before-open="beforeOpen"
  34. @row-del="rowDelDetail"
  35. @row-update="rowUpdateDetail"
  36. @row-save="rowSaveDetail"
  37. @current-change="currentChangeDetail"
  38. @size-change="sizeChange"
  39. @refresh-change="refreshChangeDetail"
  40. @on-load="onLoadDetail">
  41. <div slot-scope="{}" slot="fileUrlForm" style="display: inline-block;width: 100%;">
  42. <el-input v-model="form.fileUrl">
  43. <el-upload slot="append" action="/api/blade-resource/oss/endpoint/put-file3" accept=".apk,.wgt" :disabled="isLoading"
  44. :on-remove="handleRemove" :limit="1" :headers='headers' :show-file-list="false"
  45. :on-exceed="handleExceed" :on-success="handleSuccess" :on-progress="handleProgress" :on-error="handleError"
  46. >
  47. <el-button size="small" type="primary" :loading="isLoading" style="display: inline-block">上传</el-button>
  48. </el-upload>
  49. </el-input>
  50. </div>
  51. </avue-crud>
  52. </el-dialog>
  53. </basic-container>
  54. </template>
  55. <script>
  56. import {
  57. getList,
  58. remove,
  59. update,
  60. add,
  61. getDetailList,
  62. updateDetail,
  63. addDetail,
  64. removeDetail
  65. } from "@/api/system/app";
  66. import {getDetail as packageDetail} from "@/api/system/tenantpackage";
  67. import {mapGetters} from "vuex";
  68. import {getMenuTree} from "@/api/system/menu";
  69. import {validatenull} from "@/util/validate";
  70. import website from '@/config/website';
  71. import {Base64} from 'js-base64';
  72. import {getToken} from '@/util/auth';
  73. export default {
  74. data() {
  75. return {
  76. form: {},
  77. selectionList: [],
  78. query: {},
  79. loading: true,
  80. box: false,
  81. datasourceBox: false,
  82. packageBox: false,
  83. packageSettingBox: false,
  84. page: {
  85. pageSize: 10,
  86. currentPage: 1,
  87. total: 0
  88. },
  89. pageDetail: {
  90. pageSize: 10,
  91. currentPage: 1,
  92. total: 0
  93. },
  94. option: {
  95. height: 'auto',
  96. calcHeight: 30,
  97. tip: false,
  98. searchShow: false,
  99. searchMenuSpan: 6,
  100. border: true,
  101. index: true,
  102. selection: false,
  103. viewBtn: false,
  104. dialogWidth: 600,
  105. dialogClickModal: false,
  106. column: [
  107. {
  108. label: "应用平台",
  109. prop: "platform",
  110. span: 24,
  111. rules: [{
  112. required: true,
  113. message: "请输入应用平台",
  114. trigger: "blur"
  115. }]
  116. },
  117. {
  118. label: "应用名称",
  119. prop: "name",
  120. span: 24,
  121. rules: [{
  122. required: true,
  123. message: "请输入应用名称",
  124. trigger: "blur"
  125. }]
  126. },
  127. {
  128. label: "当前版本",
  129. prop: "currentVersion",
  130. span: 24,
  131. rules: [{
  132. required: true,
  133. message: "请输入当前版本号",
  134. trigger: "blur"
  135. }]
  136. },
  137. {
  138. label: "应用说明",
  139. prop: "appExplain",
  140. span: 24,
  141. minRows: 2,
  142. type: "textarea",
  143. hide: true,
  144. },
  145. {
  146. label: "更新时间",
  147. prop: "updateTime",
  148. span: 24,
  149. type: "time",
  150. display: false
  151. },
  152. ]
  153. },
  154. data: [],
  155. dataDetail: [],
  156. loadingDeail: false,
  157. settingForm: {},
  158. dialogUpload: false,
  159. isLoading: false,
  160. option1: {
  161. height: '100%',
  162. calcHeight: 30,
  163. tip: false,
  164. searchShow: true,
  165. searchMenuSpan: 6,
  166. border: true,
  167. index: true,
  168. selection: true,
  169. viewBtn: true,
  170. dialogWidth: 600,
  171. dialogClickModal: false,
  172. column: [
  173. {
  174. label: "当前版本",
  175. prop: "versionNumber",
  176. span: 24,
  177. rules: [{
  178. required: true,
  179. message: "请输入当前版本号",
  180. trigger: "blur"
  181. }]
  182. },
  183. {
  184. label: "软件类型",
  185. prop: "softwareType",
  186. type: "radio",
  187. span: 24,
  188. search: true,
  189. dicData: [
  190. {
  191. label: "安卓",
  192. value: 1
  193. },
  194. {
  195. label: "ios",
  196. value: 2
  197. }
  198. ],
  199. value: 1,
  200. rules: [
  201. {
  202. required: true,
  203. message: "请选择软件类型",
  204. trigger: "blur"
  205. }
  206. ],
  207. },
  208. {
  209. label: "文件类型",
  210. prop: "fileType",
  211. type: "radio",
  212. span: 24,
  213. search: true,
  214. dicData: [
  215. {
  216. label: "完整安装包",
  217. value: 0
  218. },
  219. {
  220. label: "wgt热更新包",
  221. value: 1
  222. }
  223. ],
  224. value: 1,
  225. rules: [
  226. {
  227. required: true,
  228. message: "请选择资源类型",
  229. trigger: "blur"
  230. }
  231. ],
  232. },
  233. {
  234. label: "更新内容",
  235. prop: "updateContent",
  236. span: 24,
  237. minRows: 3,
  238. type: "textarea",
  239. hide: true,
  240. rules: [{
  241. required: true,
  242. message: "请填写更新内容",
  243. trigger: "blur"
  244. }]
  245. },
  246. {
  247. label: "文件地址",
  248. prop: "fileUrl",
  249. span: 24,
  250. hide: true,
  251. rules: [{
  252. required: false,
  253. message: "请上传文件",
  254. trigger: "blur"
  255. }]
  256. },
  257. {
  258. label: "强制更新",
  259. prop: "constraintUpdate",
  260. type: "radio",
  261. span: 24,
  262. search: true,
  263. dicData: [
  264. {
  265. label: "是",
  266. value: 1
  267. },
  268. {
  269. label: "否",
  270. value: 0
  271. }
  272. ],
  273. value: 1,
  274. rules: [
  275. {
  276. required: true,
  277. message: "请选择是否强制更新",
  278. trigger: "blur"
  279. }
  280. ],
  281. },
  282. {
  283. label: "更新时间",
  284. prop: "updateDate",
  285. span: 24,
  286. type: "time",
  287. display: false
  288. },
  289. ]
  290. },
  291. versionId: '',
  292. headers: {},
  293. };
  294. },
  295. watch: {
  296. 'packageForm.packageId'() {
  297. if (!validatenull(this.packageForm.packageId)) {
  298. packageDetail(this.packageForm.packageId).then(res => {
  299. this.packageForm.menuId = res.data.data.menuId;
  300. this.initData();
  301. });
  302. }
  303. }
  304. },
  305. computed: {
  306. ...mapGetters(["userInfo", "permission"]),
  307. permissionList() {
  308. return {
  309. addBtn: this.vaildData(this.permission.tenant_add, false),
  310. delBtn: this.vaildData(this.permission.tenant_delete, false),
  311. editBtn: this.vaildData(this.permission.tenant_edit, false)
  312. };
  313. },
  314. ids() {
  315. let ids = [];
  316. this.selectionList.forEach(ele => {
  317. ids.push(ele.id);
  318. });
  319. return ids.join(",");
  320. },
  321. tenantId() {
  322. return this.selectionList[0].tenantId;
  323. }
  324. },
  325. methods: {
  326. setHeaders() {
  327. this.headers['Authorization'] = `Basic ${Base64.encode(`${website.clientId}:${website.clientSecret}`)}`;
  328. this.headers[website.tokenHeader] = 'bearer ' + getToken()
  329. },
  330. initData() {
  331. getMenuTree().then(res => {
  332. const column = this.findObject(this.packageOption.column, "menuId");
  333. column.dicData = res.data.data;
  334. });
  335. },
  336. rowSave(row, done, loading) {
  337. add(row).then(() => {
  338. this.onLoad(this.page);
  339. this.$message({
  340. type: "success",
  341. message: "操作成功!"
  342. });
  343. done();
  344. }, error => {
  345. window.console.log(error);
  346. loading();
  347. });
  348. },
  349. rowSaveDetail(row, done, loading) {
  350. row.versionId = this.versionId
  351. addDetail(row).then(() => {
  352. this.onLoadDetail(this.pageDetail);
  353. this.$message({
  354. type: "success",
  355. message: "操作成功!"
  356. });
  357. done();
  358. }, error => {
  359. window.console.log(error);
  360. loading();
  361. });
  362. },
  363. rowUpdate(row, index, done, loading) {
  364. update(row).then(() => {
  365. this.onLoad(this.page);
  366. this.$message({
  367. type: "success",
  368. message: "操作成功!"
  369. });
  370. done();
  371. }, error => {
  372. window.console.log(error);
  373. loading();
  374. });
  375. },
  376. rowUpdateDetail(row, index, done, loading) {
  377. updateDetail(row).then(() => {
  378. this.onLoadDetail(this.pageDetail);
  379. this.$message({
  380. type: "success",
  381. message: "操作成功!"
  382. });
  383. done();
  384. }, error => {
  385. window.console.log(error);
  386. loading();
  387. });
  388. },
  389. rowDel(row) {
  390. this.$confirm("确定将选择数据删除?", {
  391. confirmButtonText: "确定",
  392. cancelButtonText: "取消",
  393. type: "warning"
  394. })
  395. .then(() => {
  396. return remove(row.id);
  397. })
  398. .then(() => {
  399. this.onLoad(this.page);
  400. this.$message({
  401. type: "success",
  402. message: "操作成功!"
  403. });
  404. });
  405. },
  406. rowDelDetail(row) {
  407. this.$confirm("确定将选择数据删除?", {
  408. confirmButtonText: "确定",
  409. cancelButtonText: "取消",
  410. type: "warning"
  411. })
  412. .then(() => {
  413. return removeDetail(row.id);
  414. })
  415. .then(() => {
  416. this.onLoadDetail(this.page);
  417. this.$message({
  418. type: "success",
  419. message: "操作成功!"
  420. });
  421. });
  422. },
  423. beforeOpen(done, type) {
  424. if (["view"].includes(type)) {
  425. getDetail(this.form.id).then(res => {
  426. const data = res.data.data;
  427. if (!(data.accountNumber > 0)) {
  428. data.accountNumber = "不限制";
  429. }
  430. if (!data.expireTime) {
  431. data.expireTime = "不限制";
  432. }
  433. this.form = data;
  434. });
  435. }
  436. done();
  437. },
  438. searchReset() {
  439. this.query = {};
  440. this.onLoad(this.page);
  441. },
  442. searchChange(params, done) {
  443. this.query = params;
  444. this.page.currentPage = 1;
  445. this.onLoad(this.page, params);
  446. done();
  447. },
  448. selectionChange(list) {
  449. this.selectionList = list;
  450. },
  451. selectionClear() {
  452. this.selectionList = [];
  453. this.$refs.crud.toggleSelection();
  454. },
  455. handleDelete() {
  456. if (this.selectionList.length === 0) {
  457. this.$message.warning("请选择至少一条数据");
  458. return;
  459. }
  460. this.$confirm("确定将选择数据删除?", {
  461. confirmButtonText: "确定",
  462. cancelButtonText: "取消",
  463. type: "warning"
  464. })
  465. .then(() => {
  466. return remove(this.ids);
  467. })
  468. .then(() => {
  469. this.onLoad(this.page);
  470. this.$message({
  471. type: "success",
  472. message: "操作成功!"
  473. });
  474. this.$refs.crud.toggleSelection();
  475. });
  476. },
  477. handlePackage() {
  478. if (this.selectionList.length === 0) {
  479. this.$message.warning("请选择至少一条数据");
  480. return;
  481. }
  482. if (this.selectionList.length !== 1) {
  483. this.$message.warning("只能选择一条数据");
  484. return;
  485. }
  486. if (this.selectionList.length === 1) {
  487. packageInfo(this.selectionList[0].id).then(res => {
  488. const data = res.data.data;
  489. this.packageForm.packageId = data.id;
  490. this.packageForm.menuId = data.menuId;
  491. });
  492. } else {
  493. this.packageForm.menuId = '';
  494. }
  495. this.packageBox = true;
  496. //更新字典远程数据
  497. setTimeout(() => {
  498. const form = this.$refs.formPackage;
  499. form.updateDic('packageId');
  500. }, 10);
  501. },
  502. handlePackageSetting() {
  503. this.packageSettingBox = true;
  504. },
  505. handleSubmit(form, done, loading) {
  506. setting(this.ids, form).then(() => {
  507. this.onLoad(this.page);
  508. this.$message({
  509. type: "success",
  510. message: "配置成功!"
  511. });
  512. done();
  513. this.box = false;
  514. }, error => {
  515. window.console.log(error);
  516. loading();
  517. });
  518. },
  519. currentChange(currentPage) {
  520. this.page.currentPage = currentPage;
  521. },
  522. currentChangeDetail(currentPage) {
  523. this.pageDetail.currentPage = currentPage;
  524. },
  525. sizeChange(pageSize) {
  526. this.page.pageSize = pageSize;
  527. },
  528. refreshChange() {
  529. this.onLoad(this.page, this.query);
  530. },
  531. refreshChangeDetail() {
  532. this.onLoadDetail(this.pageDetail);
  533. },
  534. onLoad(page, params = {}) {
  535. this.loading = true;
  536. getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
  537. const data = res.data.data;
  538. this.page.total = data.total;
  539. this.data = data.records;
  540. this.loading = false;
  541. this.selectionClear();
  542. });
  543. },
  544. handleAdd(row, index) {
  545. this.dialogUpload = true;
  546. this.versionId = row.id
  547. this.onLoadDetail(this.pageDetail)
  548. this.setHeaders()
  549. },
  550. onLoadDetail(page) {
  551. this.loadingDeail = true;
  552. getDetailList(page.currentPage, page.pageSize, this.versionId).then(res => {
  553. const data = res.data.data;
  554. this.pageDetail.total = data.total;
  555. this.dataDetail = data.records;
  556. this.loadingDeail = false;
  557. });
  558. },
  559. handleRemove(file) {
  560. this.form.fileUrl = '';
  561. this.form.fileSize = '';
  562. },
  563. handleExceed() {
  564. this.$message.warning(`当前限制选择 1 个文件,请先移除后,再次上传`);
  565. },
  566. handleSuccess(res) {
  567. this.$message({
  568. type: "success",
  569. message: "上传成功!"
  570. });
  571. this.form.fileUrl = res.data.link;
  572. this.form.fileSize = res.data.fileSize
  573. this.isLoading = false
  574. },
  575. handleError() {
  576. this.isLoading = false
  577. this.$message({
  578. type: "error",
  579. message: "上传失败!"
  580. });
  581. },
  582. handleProgress() {
  583. this.isLoading = true
  584. },
  585. },
  586. created() {
  587. this.setHeaders()
  588. },
  589. };
  590. </script>
  591. <style lang="scss">
  592. .el-dialog__wrapper.app-upload-dialog .el-dialog {
  593. width: 80%;
  594. }
  595. </style>