diff --git a/base-manager-ui/admin/src/pages/basicset/appmarket/components/AppDetailsPage.vue b/base-manager-ui/admin/src/pages/basicset/appmarket/components/AppDetailsPage.vue
index ea2e87532d5cc6b81cbabe8098a0895bbd75ae87..a114cd2c04d5960715925e727053763d00303f45 100644
--- a/base-manager-ui/admin/src/pages/basicset/appmarket/components/AppDetailsPage.vue
+++ b/base-manager-ui/admin/src/pages/basicset/appmarket/components/AppDetailsPage.vue
@@ -96,6 +96,12 @@
               <span class="primary pointer" @click="handlePreview(text.id)"
                 >棰勮</span
               >
+              <span
+                class="delete pointer"
+                v-permission="[1]"
+                @click="handleDel(text.id)"
+                >鍒犻櫎</span
+              >
             </a-space>
           </template>
         </a-table>
@@ -118,6 +124,7 @@ import {
   usedVersion,
   previewVersion,
   getCategoryList,
+  deleteVersion,
 } from "@/services/market";
 import CheckSite from "../modal/CheckSite.vue";
 import { pageSizeOptions } from "@/config/pageConfig.js";
@@ -270,6 +277,33 @@ export default {
         window.open(routeUrl.href, "_blank");
       }
     },
+
+    // 鍒犻櫎
+    handleDel(id) {
+      let _this = this;
+      _this.$confirm({
+        title: "绯荤粺鎻愮ず",
+        content: "鍒犻櫎涓嶅彲鎭㈠锛岀‘瀹氳鍒犻櫎鍚楋紵",
+        okText: "纭畾",
+        okType: "danger",
+        cancelText: "鍙栨秷",
+        centered: true,
+        icon: "exclamation-circle",
+        maskClosable: true,
+        async onOk() {
+          let res = await deleteVersion({ id });
+          let { code, msg } = res.data;
+          if (code === 1) {
+            _this.$message.success(msg);
+            _this.getVersions();
+          }
+        },
+        onCancel() {
+          console.log("Cancel");
+        },
+      });
+    },
+
     // 缈婚〉
     handleChange(cur) {
       this.current = cur;
@@ -353,4 +387,4 @@ export default {
 /deep/.ant-form-item {
   align-items: flex-start;
 }
-</style>
\ No newline at end of file
+</style>
diff --git a/base-manager-ui/admin/src/pages/basicset/appmarket/components/MoveApp.vue b/base-manager-ui/admin/src/pages/basicset/appmarket/components/MoveApp.vue
index d335a397679ff47ac0fbe1fca0128de3186ef3a7..d8d735b7734399ff1b03faf70ed7c6efff8144df 100644
--- a/base-manager-ui/admin/src/pages/basicset/appmarket/components/MoveApp.vue
+++ b/base-manager-ui/admin/src/pages/basicset/appmarket/components/MoveApp.vue
@@ -4,6 +4,12 @@
       <a-space>
         <a-button type="primary" @click="handleAdd"> 鏂板搴旂敤 </a-button>
         <a-button type="primary" @click="handleClone"> 鍏嬮殕 </a-button>
+        <a-button type="primary" @click="handleTheme">
+          鎵归噺鍏宠仈搴旂敤涓婚
+        </a-button>
+        <a-button v-permission="[1]" type="danger" @click="handleDelAll">
+          鎵归噺鍒犻櫎
+        </a-button>
       </a-space>
       <a-input-search
         style="width: 300px"
@@ -67,7 +73,7 @@
         </template>
         <!-- 鐗堟湰 -->
         <template slot="version" slot-scope="text">
-          {{ text.version ? "v" + text.version : "--" }}
+          {{ text.version || text.version == 0 ? "v" + text.version : "--" }}
         </template>
         <!-- 绫诲瀷 -->
         <template slot="appType" slot-scope="text">
@@ -91,7 +97,7 @@
             >
             <span
               class="delete pointer"
-              :class="{ unDelete: text.distribute }"
+              :class="{ unDelete: userInfo.id != 1 && text.distribute }"
               @click="handleDel(text.distribute, text.id)"
               >鍒犻櫎</span
             >
@@ -114,22 +120,30 @@
       :appList="selectedRowKeys"
       :siteVisible.sync="siteVisible"
     ></CheckSite>
+    <!-- 鎵归噺淇敼搴旂敤涓婚 -->
+    <ChangeThem
+      :themVisible.sync="themVisible"
+      :themList="categoryList"
+      :appList="selectedAppList"
+      @edit="cloneSuccess"
+    ></ChangeThem>
   </div>
 </template>
 
 <script>
 import YSwitch from "../../../../components/yswitch/YSwitch.vue";
-import { pageSizeOptions } from "@/config/pageConfig.js";
 import AddApp from "../modal/AddApp.vue";
 import CheckSite from "../modal/CheckSite.vue";
+import ChangeThem from "../modal/ChangeThem.vue";
 import {
   getAppList,
   deleteApp,
   saveApp,
   getCategoryList,
 } from "@/services/market";
-import { mapMutations } from "vuex";
 import local from "@/utils/local";
+import { mapMutations, mapGetters } from "vuex";
+import { pageSizeOptions } from "@/config/pageConfig.js";
 const columns = [
   {
     title: "搴忓彿",
@@ -184,6 +198,7 @@ export default {
     YSwitch,
     AddApp,
     CheckSite,
+    ChangeThem,
   },
   data() {
     return {
@@ -198,32 +213,21 @@ export default {
       size: 10,
       total: 0,
       pageSizeOptions,
-      selectedRowKeys: [], // 琛ㄦ牸鍕鹃€夋暟鎹�
+      selectedRowKeys: [], // 琛ㄦ牸鍕鹃€塱d鍒楄〃
+      selectedAppList: [], // 琛ㄦ牸鍕鹃€変俊鎭垪琛�
       AddVisible: false,
       title: "鏂板搴旂敤",
       siteVisible: false,
+      themVisible: false,
       dict: {}, // 瀛楀吀
       categoryList: [], // 搴旂敤鍒嗙被鍒楄〃
     };
   },
-  // 杩涘叆璺敱鍓�
-  // beforeRouteEnter(to, from, text) {
-  //   if (from.path === "/appmarket/appdetails") {
-  //     to.meta.isBack = true;
-  //   } else {
-  //     to.meta.isBack = false;
-  //   }
-  //   text();
-  // },
-  // // 璇︽儏椤佃繑鍥炰笉鍒锋柊鏁版嵁
-  // activated() {
-  //   if (!this.$route.meta.isBack) {
-  //     Object.assign(this.$data, this.$options.data());
-  //     this.getAppList();
-  //   } else {
-  //     this.$route.meta.isBack = false;
-  //   }
-  // },
+
+  computed: {
+    ...mapGetters("site", ["userInfo"]),
+  },
+
   created() {
     this.getCategoryList();
     this.getAppList();
@@ -232,7 +236,6 @@ export default {
     ...mapMutations("site", ["SET_appDict"]),
     // 鑾峰彇鍒嗙被鍒楄〃
     async getCategoryList() {
-      this.loading = true;
       let res = await getCategoryList({
         page: 1,
         size: -1,
@@ -243,6 +246,7 @@ export default {
         this.categoryList = data;
       }
     },
+
     // 鑾峰彇搴旂敤鍒楄〃
     async getAppList() {
       this.loading = true;
@@ -297,8 +301,17 @@ export default {
       this.getAppList();
     },
     // 鍕鹃€夎〃鏍�
-    onSelectChange(keys) {
+    onSelectChange(keys, rows) {
       this.selectedRowKeys = keys;
+      this.selectedAppList = [...this.selectedAppList, ...rows];
+      let map = new Map();
+      this.selectedAppList = this.selectedAppList
+        .filter((v) => {
+          return !map.has(v.id) && map.set(v.id, 1);
+        })
+        .filter((v) => {
+          return this.selectedRowKeys.some((item) => item == v.id);
+        });
     },
     // 缂栬緫
     handleEdit(row) {
@@ -306,6 +319,16 @@ export default {
       this.$refs.AddApp.onEdit(row);
       this.AddVisible = true;
     },
+
+    // 鎵归噺淇敼搴旂敤涓婚
+    handleTheme() {
+      if (!this.selectedRowKeys.length) {
+        this.$message.warning("璇峰厛鍕鹃€夊簲鐢�");
+        return;
+      }
+      this.themVisible = true;
+    },
+
     // 鏌ョ湅
     handleCheck(id) {
       this.$router.push({
@@ -317,7 +340,7 @@ export default {
     },
     // 鍒犻櫎
     handleDel(distribute, id) {
-      if (distribute) {
+      if (this.userInfo.id != 1 && distribute) {
         this.$confirm({
           title: "鎷掔粷鍒犻櫎",
           content: "璇ュ簲鐢ㄦ鍦ㄤ娇鐢ㄤ腑銆�",
@@ -359,6 +382,17 @@ export default {
         },
       });
     },
+
+    // 鎵归噺鍒犻櫎
+    handleDelAll() {
+      if (!this.selectedRowKeys.length) {
+        this.$message.warning("璇峰厛鍕鹃€夊簲鐢�");
+        return;
+      }
+      let ids = this.selectedRowKeys.join(",");
+      this.handleDel(0, ids);
+    },
+
     // 鍏嬮殕鎴愬姛
     cloneSuccess() {
       this.selectedRowKeys = [];
diff --git a/base-manager-ui/admin/src/pages/basicset/appmarket/components/TerminalApp.vue b/base-manager-ui/admin/src/pages/basicset/appmarket/components/TerminalApp.vue
index 5808693d935e2bcdee9b46a24e4e5748d819ab26..c4b12d99f5a1ef5e4d743d13c52311030c5f0620 100644
--- a/base-manager-ui/admin/src/pages/basicset/appmarket/components/TerminalApp.vue
+++ b/base-manager-ui/admin/src/pages/basicset/appmarket/components/TerminalApp.vue
@@ -4,6 +4,12 @@
       <a-space>
         <a-button type="primary" @click="handleAdd"> 鏂板搴旂敤 </a-button>
         <a-button type="primary" @click="handleClone"> 鍏嬮殕 </a-button>
+        <a-button type="primary" @click="handleTheme">
+          鎵归噺鍏宠仈搴旂敤涓婚
+        </a-button>
+        <a-button v-permission="[1]" type="danger" @click="handleDelAll">
+          鎵归噺鍒犻櫎
+        </a-button>
       </a-space>
       <a-input-search
         style="width: 300px"
@@ -67,7 +73,7 @@
         </template>
         <!-- 鐗堟湰 -->
         <template slot="version" slot-scope="text">
-          {{ text.version ? "v" + text.version : "--" }}
+          {{ text.version || text.version == 0 ? "v" + text.version : "--" }}
         </template>
         <!-- 绫诲瀷 -->
         <template slot="appType" slot-scope="text">
@@ -91,7 +97,7 @@
             >
             <span
               class="delete pointer"
-              :class="{ unDelete: text.distribute }"
+              :class="{ unDelete: userInfo.id != 1 && text.distribute }"
               @click="handleDel(text.distribute, text.id)"
               >鍒犻櫎</span
             >
@@ -114,6 +120,13 @@
       :appList="selectedRowKeys"
       :siteVisible.sync="siteVisible"
     ></CheckSite>
+    <!-- 鎵归噺淇敼搴旂敤涓婚 -->
+    <ChangeThem
+      :themVisible.sync="themVisible"
+      :themList="categoryList"
+      :appList="selectedAppList"
+      @edit="cloneSuccess"
+    ></ChangeThem>
   </div>
 </template>
 
@@ -121,6 +134,7 @@
 import YSwitch from "../../../../components/yswitch/YSwitch.vue";
 import AddApp from "../modal/AddApp.vue";
 import CheckSite from "../modal/CheckSite.vue";
+import ChangeThem from "../modal/ChangeThem.vue";
 import {
   getAppList,
   deleteApp,
@@ -128,7 +142,7 @@ import {
   getCategoryList,
 } from "@/services/market";
 import local from "@/utils/local";
-import { mapMutations } from "vuex";
+import { mapMutations, mapGetters } from "vuex";
 import { pageSizeOptions } from "@/config/pageConfig.js";
 const columns = [
   {
@@ -184,6 +198,7 @@ export default {
     YSwitch,
     AddApp,
     CheckSite,
+    ChangeThem,
   },
   data() {
     return {
@@ -198,15 +213,21 @@ export default {
       size: 10,
       total: 0,
       pageSizeOptions,
-      selectedRowKeys: [], // 琛ㄦ牸鍕鹃€夋暟鎹�
+      selectedRowKeys: [], // 琛ㄦ牸鍕鹃€塱d鍒楄〃
+      selectedAppList: [], // 琛ㄦ牸鍕鹃€変俊鎭垪琛�
       AddVisible: false,
       title: "鏂板搴旂敤",
       siteVisible: false,
+      themVisible: false,
       dict: {}, // 瀛楀吀
       categoryList: [], // 搴旂敤鍒嗙被鍒楄〃
     };
   },
 
+  computed: {
+    ...mapGetters("site", ["userInfo"]),
+  },
+
   created() {
     this.getCategoryList();
     this.getAppList();
@@ -280,8 +301,17 @@ export default {
       this.getAppList();
     },
     // 鍕鹃€夎〃鏍�
-    onSelectChange(keys) {
+    onSelectChange(keys, rows) {
       this.selectedRowKeys = keys;
+      this.selectedAppList = [...this.selectedAppList, ...rows];
+      let map = new Map();
+      this.selectedAppList = this.selectedAppList
+        .filter((v) => {
+          return !map.has(v.id) && map.set(v.id, 1);
+        })
+        .filter((v) => {
+          return this.selectedRowKeys.some((item) => item == v.id);
+        });
     },
     // 缂栬緫
     handleEdit(row) {
@@ -289,6 +319,16 @@ export default {
       this.$refs.AddApp.onEdit(row);
       this.AddVisible = true;
     },
+
+    // 鎵归噺淇敼搴旂敤涓婚
+    handleTheme() {
+      if (!this.selectedRowKeys.length) {
+        this.$message.warning("璇峰厛鍕鹃€夊簲鐢�");
+        return;
+      }
+      this.themVisible = true;
+    },
+
     // 鏌ョ湅
     handleCheck(id) {
       this.$router.push({
@@ -301,7 +341,7 @@ export default {
     },
     // 鍒犻櫎
     handleDel(distribute, id) {
-      if (distribute) {
+      if (this.userInfo.id != 1 && distribute) {
         this.$confirm({
           title: "鎷掔粷鍒犻櫎",
           content: "璇ュ簲鐢ㄦ鍦ㄤ娇鐢ㄤ腑銆�",
@@ -343,6 +383,17 @@ export default {
         },
       });
     },
+
+    // 鎵归噺鍒犻櫎
+    handleDelAll() {
+      if (!this.selectedRowKeys.length) {
+        this.$message.warning("璇峰厛鍕鹃€夊簲鐢�");
+        return;
+      }
+      let ids = this.selectedRowKeys.join(",");
+      this.handleDel(0, ids);
+    },
+
     // 鍏嬮殕鎴愬姛
     cloneSuccess() {
       this.selectedRowKeys = [];
diff --git a/base-manager-ui/admin/src/pages/basicset/appmarket/modal/ChangeThem.vue b/base-manager-ui/admin/src/pages/basicset/appmarket/modal/ChangeThem.vue
new file mode 100644
index 0000000000000000000000000000000000000000..5543b7858bc7d2a7213a75dc449ff11c19f08f9a
--- /dev/null
+++ b/base-manager-ui/admin/src/pages/basicset/appmarket/modal/ChangeThem.vue
@@ -0,0 +1,106 @@
+<template>
+  <div>
+    <a-modal v-model="Visible" title="璇烽€夋嫨涓婚">
+      <a-form-model
+        ref="form"
+        :model="form"
+        :rules="rules"
+        :label-col="{ span: 4 }"
+        :wrapper-col="{ span: 20 }"
+      >
+        <a-form-model-item label="搴旂敤" prop="appThemeName">
+          <a-select placeholder="璇烽€夋嫨涓婚" v-model="form.appThemeName">
+            <a-select-option
+              v-for="v in themList"
+              :key="v.id"
+              :value="'' + v.id"
+            >
+              {{ v.categoryName }}
+            </a-select-option>
+          </a-select>
+        </a-form-model-item>
+      </a-form-model>
+      <div slot="footer">
+        <a-space size="middle">
+          <a-button @click="handleCancel">鍙栨秷</a-button>
+          <a-button type="primary" @click="handleOk">纭畾</a-button>
+        </a-space>
+      </div>
+    </a-modal>
+  </div>
+</template>
+
+<script>
+import { batchSave } from "@/services/market";
+export default {
+  props: {
+    themVisible: {
+      type: Boolean,
+      required: true,
+      default: false,
+    },
+    themList: {
+      type: Array,
+      required: true,
+      default: () => [],
+    },
+    appList: {
+      type: Array,
+      required: true,
+      default: () => [],
+    },
+  },
+  data() {
+    return {
+      form: {
+        appThemeName: undefined,
+      },
+      rules: {
+        appThemeName: [
+          { required: true, message: "璇烽€夋嫨涓婚", trigger: "change" },
+        ],
+      },
+    };
+  },
+  computed: {
+    Visible: {
+      get() {
+        return this.themVisible;
+      },
+      set(val) {
+        this.$emit("update:themVisible", val);
+      },
+    },
+  },
+  methods: {
+    // 淇濆瓨
+    handleOk() {
+      this.$refs.form.validate(async (valid) => {
+        if (valid) {
+          let arr = this.appList.map((v) => {
+            return {
+              ...v,
+              appThemeName: this.form.appThemeName,
+            };
+          });
+          let res = await batchSave(arr);
+          let { code, msg } = res.data;
+          if (code == 1) {
+            this.$message.success(msg);
+            this.$emit("edit");
+            this.handleCancel();
+          }
+        }
+      });
+    },
+
+    // 鍙栨秷
+    handleCancel() {
+      this.$refs.form.resetFields();
+      this.Visible = false;
+    },
+  },
+};
+</script>
+
+<style lang="less" scoped></style>
diff --git a/base-manager-ui/admin/src/services/basicsetApi.js b/base-manager-ui/admin/src/services/basicsetApi.js
index 2dfcad0e9cdf88755fd5c8da09086d5b5c128da6..18144bc0eee1501bd4f4562c9948d0cccad8afda 100644
--- a/base-manager-ui/admin/src/services/basicsetApi.js
+++ b/base-manager-ui/admin/src/services/basicsetApi.js
@@ -285,6 +285,7 @@ module.exports = {
     list: `${BASE_URL}/base/app/list`,
     info: `${BASE_URL}/base/app/info`,
     save: `${BASE_URL}/base/app/save`,
+    batchSave: `${BASE_URL}/base/app/batchSave`,
     delete: `${BASE_URL}/base/app/delete`,
     distribute: `${BASE_URL}/base/app/appDistribute`,
     clone: `${BASE_URL}/base/app/cloneAppsBySites`,
diff --git a/base-manager-ui/admin/src/services/market.js b/base-manager-ui/admin/src/services/market.js
index ae75f06ccb0d73c4cfa2be0894594e770250679d..62e89aff66ce8eb70848520db52712fb1e4ded2a 100644
--- a/base-manager-ui/admin/src/services/market.js
+++ b/base-manager-ui/admin/src/services/market.js
@@ -27,6 +27,10 @@ export async function getAppInfo(data) {
 export async function saveApp(data) {
   return request(App.save, METHOD.POST, data);
 }
+// 鏂板锛屼慨鏀瑰簲鐢紙鎵归噺锛�
+export async function batchSave(data) {
+  return request(App.batchSave, METHOD.POST, data);
+}
 // 鍒犻櫎搴旂敤
 export async function deleteApp(data) {
   return request(App.delete, METHOD.GET, data);