<template> <div class="app-container"> <el-form :inline="true" ref="form" :model="form" size="mini"> <el-form-item label="应用名称" prop="uuid"> <el-select v-model="form.uuid" filterable placeholder="请输入标题"> <el-option v-for="(item, index) in selectList" :key="index" :label="item.app_name" :value="item.uuid" ></el-option> </el-select> </el-form-item> <el-form-item label="应用分类"> <el-select v-model="form.category" filterable placeholder="请选择分类"> <el-option v-for="(item, index) in categoryList" :key="index" :label="item" :value="item" ></el-option> </el-select> </el-form-item> <el-form-item ><el-button type="primary" @click="onSubmit" >查询</el-button ></el-form-item > <el-form-item ><el-button type="warning" @click="onAdd" >添加应用</el-button ></el-form-item > </el-form> <el-table :data="list" v-loading="isLoading" element-loading-text="Loading" size="mini" border stripe fit highlight-current-row > <el-table-column prop="app_name" label="应用名称" width="180" ></el-table-column> <el-table-column prop="app_version" label="应用版本号" width="150" ></el-table-column> <el-table-column prop="category" label="应用类别" width="120" ></el-table-column> <el-table-column prop="epk_size" label="应用大小" width="120" ></el-table-column> <el-table-column prop="app_desc" label="应用描述" width="200" ></el-table-column> <el-table-column prop="create_at" label="创建时间" width="150" ></el-table-column> <el-table-column prop="create_by.username" label="创建者" width="150" ></el-table-column> <el-table-column prop="update_at" label="更新时间" width="150" :show-overflow-tooltip="true" ></el-table-column> <el-table-column prop="update_by.username" label="更新者" width="150" ></el-table-column> <el-table-column label="操作" align="center" min-width="260" fixed="right" > <template slot-scope="scope"> <el-button size="mini" type="success" @click="handleRebuild(scope.$index, scope.row)" >重新打包</el-button > <el-button size="mini" type="primary" @click="handleBuild(scope.$index, scope.row)" >下载应用</el-button > <el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)" >删除</el-button > </template> </el-table-column> </el-table> <div class="page-wrapper"> <el-pagination @current-change="handleCurrentChange" :current-page.sync="form.pagenum" background small :page-size="form.pagesize" :pager-count="5" layout="pager, prev, next, total" :total="total" ></el-pagination> </div> <el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="45%"> <el-form :model="post" status-icon ref="post" size="medium" label-width="100px" > <el-form-item label="应用排序" prop="sort"> <el-input type="number" v-model.number="post.sort" autocomplete="off" ></el-input> </el-form-item> <el-form-item label="应用名称" prop="app_name"> <el-input type="text" v-model="post.app_name" autocomplete="off" ></el-input> </el-form-item> <el-form-item label="应用版本号" prop="app_version"> <el-input type="text" v-model="post.app_version" autocomplete="off" ></el-input> </el-form-item> <el-form-item label="应用类别" prop="category"> <el-input type="text" v-model="post.category" autocomplete="off" ></el-input> </el-form-item> <el-form-item label="应用描述" prop="app_desc"> <el-input type="text" v-model="post.app_desc" autocomplete="off" ></el-input> </el-form-item> <el-form-item label="应用Logo" prop="app_icon"> <el-upload class="avatar-uploader" ref="logo" name="logo" accept="image/*" action="null" :auto-upload="false" :http-request="handleUploadLogo" :on-remove="handleLogoRemove" :on-change="handleLogoChange" :before-upload="beforeLogoUpload" > <img v-if="imageUrl" :src="imageUrl" class="avatar" /> <i v-else class="el-icon-plus avatar-uploader-icon"></i> </el-upload> </el-form-item> <el-form-item label="应用文件" prop="app_files"> <el-upload drag multiple ref="upload" name="binfiles" action="null" :auto-upload="false" :http-request="handleUploadFile" :on-remove="handleUploadRemove" > <i class="el-icon-upload"></i> <div class="el-upload__text"> 将文件拖到此处,或<em>点击上传</em> </div> <div class="el-upload__tip" slot="tip"> <el-button size="small" type="text" @click="clear" >清空上传</el-button > </div> </el-upload> </el-form-item> </el-form> <div slot="footer" class="dialog-footer"> <el-button type="primary" size="medium" plain @click="submitForm('post')" >提交</el-button > <el-button type="success" size="medium" plain @click="onReset('form')" >重置</el-button > <el-button size="medium" @click="dialogVisible = false">关闭</el-button> </div> </el-dialog> </div> </template> <script> import { getAppsList, deleteApp, addApp, rebuildApp, updateApp, getBuildApp, } from "@/api/app-store"; import { mapTrim, download } from "@/utils/index"; export default { name: "AppIndex", data() { return { imageUrl: "", total: 0, list: [], selectList: [], categoryList: [], isLoading: false, form: { uuid: null, name: null, category: null, pagesize: 15, pagenum: 1, }, currentIndex: 0, currentValue: null, dialogTitle: "", dialogVisible: false, post: { sort: 0, app_name: "evue_launcher", app_version: "1.0", app_icon: null, category: "tools", app_desc: "启动器", app_files: [], logo: null, fileList: [], }, }; }, computed: { window: () => window, }, methods: { clear() { this.imageUrl = null; this.post.app_icon = null; this.post.app_files = []; this.$refs.upload.clearFiles(); this.$refs.logo.clearFiles(); }, fetchData(params) { this.isLoading = true; getAppsList(params) .then((res) => { this.total = res.count; this.list = res.data.map((item) => { if (item.app_build_log && item.app_build_log.app_info) item.epk_size = (item.app_build_log.app_info.buff_length / 1024).toFixed(2) + "KB"; else item.epk_size = ""; return item; }); }) .catch((err) => { console.log(err.message); }) .finally(() => { this.isLoading = false; }); }, fetchCategory() { getAppsList({ scope_type: "distinct" }).then(res => { this.categoryList = res.data }).catch(err => { console.log(err.message) }) }, handleSizeChange(e) { this.form.pagesize = e; this.fetchData(mapTrim(this.form)); }, handleCurrentChange(e) { this.form.pagenum = e; this.fetchData(mapTrim(this.form)); }, handleRebuild(index, row) { rebuildApp({ uuid: row.uuid }) .then((res) => { this.$message.success(res.message); }) .catch((err) => { this.$message.error(err.message); }); }, handleBuild(index, row) { getBuildApp(row.uuid) .then((res) => { download(`${res.data.app_name}.epk`, res.data.app_path); this.$message.success(res.message); }) .catch((err) => { this.$message.error(err.message); }); }, handleEdit(index, row) { this.post = Object.assign(row); this.imageUrl = null; this.currentIndex = index; this.currentValue = row; this.dialogTitle = "编辑"; this.dialogVisible = true; }, handleDelete(index, row) { this.$alert( "您确定要删除么?删除操作将不可恢复。如需取消操作,请点击右上角关闭按钮。", "删除提醒", { confirmButtonText: "确定", callback: (action) => { if (action == "confirm") deleteApp(row.uuid) .then((res) => { console.log(res); this.total -= 1; this.$delete(this.list, index); this.$message({ type: "success", message: `成功删除第${index}行`, }); }) .catch((err) => { this.$message.error(err.message); }); }, } ); }, handleUploadLogo(file) { this.post.logo = file; }, handleUploadFile(file) { this.post.fileList.push(file); }, handleUploadRemove(file, fileList) { console.log(file, fileList); for (let i = 0; i < this.post.app_files.length; i++) { if (this.post.app_files[i].uuid == file.response.data.uuid) { this.post.app_files.splice(i, 1); break; } } // this.post.app_files = fileList; }, handleLogoChange(file) { this.imageUrl = URL.createObjectURL(file.raw); }, beforeLogoUpload(file) { const isLt2M = file.size / 1024 / 1024 < 2; if (!isLt2M) { this.$message.error("上传头像图片大小不能超过 2MB!"); } return isLt2M; }, handleLogoRemove(file) { console.log(file); this.imageUrl = null; this.post.logo = file.file; }, fetchSelectData() { getAppsList({ scope_type: "list" }) .then((res) => { if (res.code == 200) this.selectList = res.data; }) .catch((err) => { console.log(err.message); }); }, submitForm(formName) { this.$refs[formName].validate((valid) => { let result = true; if (valid) { if (this.dialogTitle === "添加") { this.$refs.upload.submit(); // 调用这个upload组件该方法才会执行http-request回调 this.$refs.logo.submit(); let formData = new FormData(); this.post.fileList.forEach(item => { formData.append("fileList", item.file) }); formData.append("logo", this.post.logo.file) Object.keys(this.post).forEach(k => { if (this.post[k] && typeof this.post[k] !== "object") { formData.append(k, this.post[k]) } }); addApp(formData).then((res) => { this.$message({ type: "success", message: `添加成功:${res.message}`, }); this.fetchData(mapTrim(this.form)); }) .catch((err) => { this.$message.error(err.message); }); } else if (this.dialogTitle === "编辑") { updateApp(this.currentValue.uuid, this.post) .then((res) => { // this.$set(this.list, this.currentIndex, Object.assign(this.currentValue, tmp)) this.$message({ type: "success", message: `更新成功:${res.message}`, }); this.fetchData(mapTrim(this.form)); }) .catch((err) => { this.$message.error(err.message); }); } } else { result = false; } this.dialogVisible = false; return result; }); }, onAdd() { setTimeout(() => { this.clear(); }, 100); this.post.sort = this.form.pagesize * (this.form.pagenum - 1) + this.list.length + 1; this.dialogTitle = "添加"; this.dialogVisible = true; }, onSubmit() { this.form.pagenum = 1; this.form.pagesize = 15; this.fetchData(mapTrim(this.form)); }, onReset(formName) { this.$refs[formName].resetFields(); this.form.pagesize = 15; this.form.pagenum = 1; this.fetchData(mapTrim(this.form)); }, }, mounted() {}, created() { this.fetchData(mapTrim(this.form)); this.fetchSelectData(); this.fetchCategory(); }, }; </script> <style lang="scss" scoped> .app-container { & > div.page-wrapper { margin: 10px 0px; } } .avatar-uploader .el-upload { border: 1px dashed #d9d9d9; border-radius: 6px; cursor: pointer; position: relative; overflow: hidden; } .avatar-uploader .el-upload:hover { border-color: #409eff; } .avatar-uploader-icon { font-size: 28px; color: #8c939d; width: 178px; height: 178px; line-height: 178px; text-align: center; } .avatar { width: 178px; height: 178px; display: block; } </style>