@steedos/service-core-objects 3.0.9-beta.2 → 3.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (24) hide show
  1. package/main/default/applications/admin.app.yml +3 -2
  2. package/main/default/applications/desktop.app.yml +63 -0
  3. package/main/default/objectTranslations/apps.en/apps.en.objectTranslation.yml +0 -4
  4. package/main/default/objectTranslations/apps.zh-CN/apps.zh-CN.objectTranslation.yml +0 -4
  5. package/main/default/objects/apps/apps.object.yml +5 -9
  6. package/main/default/pages/app_launcher.page.amis.json +106 -0
  7. package/main/default/pages/app_launcher.page.yml +7 -0
  8. package/main/default/pages/app_store.page.amis.json +10 -0
  9. package/main/default/pages/app_store.page.yml +7 -0
  10. package/main/default/tabs/admin_bull_dashboard.tab.yml +1 -1
  11. package/main/default/tabs/admin_swagger.tab.yml +1 -1
  12. package/main/default/tabs/page_app_launcher.tab.yml +10 -0
  13. package/main/default/tabs/{admin_flow_roles.tab.yml → page_app_store.tab.yml} +7 -6
  14. package/package.json +3 -3
  15. package/main/default/objects/apps/buttons/amis_nav_schema_design.button.js +0 -31
  16. package/main/default/objects/apps/buttons/amis_nav_schema_design.button.yml +0 -4
  17. package/main/default/tabs/admin_categories.tab.yml +0 -21
  18. package/main/default/tabs/admin_flow_positions.tab.yml +0 -21
  19. package/main/default/tabs/admin_flows.tab.yml +0 -21
  20. package/main/default/tabs/admin_instance_number_rules.tab.yml +0 -23
  21. package/main/default/tabs/admin_instances_statistic.tab.yml +0 -24
  22. package/main/default/tabs/admin_roles.tab.yml +0 -21
  23. package/main/default/tabs/admin_space_user_signs.tab.yml +0 -25
  24. package/main/default/tabs/admin_webhooks.tab.yml +0 -21
@@ -1,8 +1,9 @@
1
1
  name: Setup
2
2
  code: admin
3
3
  description: 管理员设置公司、人员、权限等。
4
- icon: ion-ios-people-outline
5
4
  dark: true
5
+ color: gray
6
+ icon: settings
6
7
  icon_slds: settings
7
8
  is_creator: true
8
9
  showSidebar: true
@@ -18,7 +19,7 @@ tab_groups:
18
19
  - group_name: process_automation
19
20
  default_open: false
20
21
  - group_name: approval_workflow
21
- default_open: false
22
+ default_open: true
22
23
  - group_name: development
23
24
  default_open: false
24
25
  - group_name: advanced_settings
@@ -0,0 +1,63 @@
1
+ name: 工作台
2
+ code: desktop
3
+ color: red
4
+ dark: true
5
+ icon_slds: agent_home
6
+ is_creator: true
7
+ is_new_window: false
8
+ is_use_iframe: false
9
+ locked: false
10
+ mobile: true
11
+ oauth2_enabled: false
12
+ showSidebar: true
13
+ sort: 5
14
+ tab_groups:
15
+ - group_name: 协作
16
+ default_open: true
17
+ - group_name: 管理
18
+ default_open: true
19
+ - group_name: 开发
20
+ default_open: true
21
+ tab_items:
22
+ page_app_launcher:
23
+ group: ''
24
+ index: 1
25
+ core_announcements:
26
+ group: 协作
27
+ index: 2
28
+ core_tasks:
29
+ group: 协作
30
+ index: 3
31
+ core_events:
32
+ group: 协作
33
+ index: 4
34
+ admin_space_users:
35
+ group: 管理
36
+ index: 1
37
+ admin_organizations:
38
+ group: 管理
39
+ index: 2
40
+ admin_objects:
41
+ group: 开发
42
+ index: 5
43
+ admin_pages:
44
+ group: 开发
45
+ index: 6
46
+ admin_apps:
47
+ group: 开发
48
+ index: 7
49
+ page_app_store:
50
+ group: 开发
51
+ index: 8
52
+ tabs:
53
+ - page_app_launcher
54
+ - core_announcements
55
+ - core_tasks
56
+ - core_events
57
+ - admin_objects
58
+ - admin_apps
59
+ - admin_pages
60
+ - page_app_store
61
+ - admin_space_users
62
+ - admin_organizations
63
+ visible: true
@@ -50,10 +50,6 @@ fields:
50
50
  label: Visible On
51
51
  help:
52
52
  description:
53
- enable_nav_schema:
54
- label: Enable Custom Navigation
55
- help:
56
- description:
57
53
  sort:
58
54
  label: Sort Number
59
55
  help:
@@ -50,10 +50,6 @@ fields:
50
50
  label: 显示公式
51
51
  help: 根据公式判断是否显示应用
52
52
  description:
53
- enable_nav_schema:
54
- label: 启用自定义导航
55
- help:
56
- description:
57
53
  sort:
58
54
  label: 排序
59
55
  help:
@@ -23,6 +23,7 @@ fields:
23
23
  required: true
24
24
  searchable: true
25
25
  filterable: true
26
+ defaultValue: 'app_${UUID(3)}'
26
27
  icon_slds:
27
28
  label: Icon
28
29
  type: select
@@ -66,7 +67,7 @@ fields:
66
67
  dark:
67
68
  label: Dark Mode
68
69
  type: boolean
69
- defaultValue: false
70
+ defaultValue: true
70
71
  description:
71
72
  label: Description
72
73
  type: textarea
@@ -104,11 +105,11 @@ fields:
104
105
  is_creator:
105
106
  type: boolean
106
107
  label: Show this app for Desktop
107
- # defaultValue: true
108
+ defaultValue: true
108
109
  mobile:
109
110
  type: boolean
110
111
  label: Show this app for Mobile
111
- # defaultValue: true
112
+ defaultValue: true
112
113
  icon:
113
114
  label: Icon
114
115
  type: text
@@ -116,7 +117,7 @@ fields:
116
117
  visible:
117
118
  label: Visible
118
119
  type: boolean
119
- # defaultValue: true
120
+ defaultValue: true
120
121
 
121
122
  showSidebar:
122
123
  label: 显示左侧导航
@@ -189,11 +190,6 @@ fields:
189
190
  # inlineHelpText: Visible On
190
191
  # type: textarea
191
192
  # group: other
192
- # enable_nav_schema:
193
- # label: 启用自定义导航
194
- # type: boolean
195
- # required: false
196
- # group: other
197
193
 
198
194
  oauth2_enabled:
199
195
  group: External Application
@@ -0,0 +1,106 @@
1
+ {
2
+ "type": "page",
3
+ "title": "Welcome to Steedos",
4
+ "body": [
5
+ {
6
+ "type": "liquid",
7
+ "template": "<style>\n /* --- 基础设置 --- */\n .steedos-ios-launcher {\n font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;\n -webkit-touch-callout: none;\n -webkit-user-select: none;\n user-select: none;\n }\n\n .no-scrollbar::-webkit-scrollbar {\n display: none;\n }\n\n .no-scrollbar {\n -ms-overflow-style: none;\n scrollbar-width: none;\n }\n\n /* --- 动画定义 --- */\n @keyframes blob-bounce {\n 0% {\n transform: translate(0, 0) scale(1);\n }\n\n 33% {\n transform: translate(30px, -50px) scale(1.1);\n }\n\n 66% {\n transform: translate(-20px, 20px) scale(0.9);\n }\n\n 100% {\n transform: translate(0, 0) scale(1);\n }\n }\n\n .animate-blob {\n animation: blob-bounce 10s infinite ease-in-out;\n }\n\n @keyframes fade-in-up {\n from {\n opacity: 0;\n transform: translateY(20px);\n }\n\n to {\n opacity: 1;\n transform: translateY(0);\n }\n }\n\n .animate-fade-in-up {\n animation: fade-in-up 0.5s cubic-bezier(0.2, 0.8, 0.2, 1) forwards;\n }\n\n /* --- 交互样式 --- */\n .app-icon-container {\n transition: transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.2s;\n will-change: transform;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .app-item:not(.static-item):hover .app-icon-container {\n transform: scale(1.05);\n box-shadow: 0 15px 30px -5px rgba(0, 0, 0, 0.1);\n z-index: 10;\n }\n\n .app-item.static-item:hover .app-icon-container {\n transform: scale(1.05);\n background-color: rgba(255, 255, 255, 0.8);\n }\n\n .sortable-drag .app-icon-container {\n transform: scale(1.15) !important;\n box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.35);\n filter: brightness(1.02);\n cursor: grabbing;\n }\n\n .sortable-ghost {\n opacity: 0;\n }\n\n /* 加载状态 */\n .loading-skeleton {\n animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;\n background-color: rgba(255, 255, 255, 0.5);\n border-radius: 1.6rem;\n }\n\n @keyframes pulse {\n\n 0%,\n 100% {\n opacity: 1;\n }\n\n 50% {\n opacity: .5;\n }\n }\n</style>\n\n<div id=\"launcher-container\"\n class=\"steedos-ios-launcher relative w-full h-screen bg-[#F5F7FA] text-slate-800 overflow-hidden\">\n\n <div\n class=\"absolute top-0 left-0 w-[500px] h-[500px] bg-blue-300/30 rounded-full mix-blend-multiply filter blur-[80px] opacity-70 animate-blob pointer-events-none\">\n </div>\n <div class=\"absolute top-0 right-0 w-[500px] h-[500px] bg-purple-300/30 rounded-full mix-blend-multiply filter blur-[80px] opacity-70 animate-blob pointer-events-none\"\n style=\"animation-delay: 2s\"></div>\n <div class=\"absolute -bottom-32 left-20 w-[500px] h-[500px] bg-pink-300/30 rounded-full mix-blend-multiply filter blur-[80px] opacity-70 animate-blob pointer-events-none\"\n style=\"animation-delay: 4s\"></div>\n\n <div class=\"relative z-10 w-full h-full flex flex-col items-center pt-32 pb-10 px-6 overflow-y-auto no-scrollbar\"\n id=\"main-scroll-area\">\n <div id=\"vibrant-grid\"\n class=\"grid grid-cols-3 sm:grid-cols-4 md:grid-cols-5 lg:grid-cols-6 gap-x-6 gap-y-10 w-full max-w-6xl px-2 pb-20 animate-fade-in-up\"\n style=\"animation-delay: 0.1s;\">\n </div>\n </div>\n</div>\n\n<script>\n // ==========================================\n // ✅ 在这里编写您的业务逻辑\n // ==========================================\n \n // 1. 点击“应用市场”按钮时触发\n window.handleAppStoreClick = function() {\n // --- 请在此处编写代码 ---\n console.log(\"点击了应用市场\");\n window.location.href = \"/app/admin/page/app_store\"; \n };\n\n // 2. 点击列表末尾“添加应用”图标时触发\n window.handleAddAppClick = function() {\n // --- 请在此处编写代码 ---\n console.log(\"点击了添加应用\");\n data._scoped.doAction([{\n actionType: 'click',\n componentId: 'buttonAddApp',\n }])\n };\n\n\n // ==========================================\n // 下方为系统核心代码 (一般无需修改)\n // ==========================================\n \n var STORE_KEY = 'steedos_launcher_order';\n var COLOR_MAP = {\n 'red': 'from-red-400 to-rose-600 shadow-red-500/20',\n 'orange': 'from-orange-400 to-red-500 shadow-orange-500/20',\n 'yellow': 'from-amber-400 to-orange-500 shadow-amber-500/20',\n 'green': 'from-green-400 to-emerald-600 shadow-green-500/20',\n 'teal': 'from-teal-400 to-teal-600 shadow-teal-500/20',\n 'cyan': 'from-cyan-400 to-blue-500 shadow-cyan-500/20',\n 'sky': 'from-sky-400 to-blue-500 shadow-sky-500/20',\n 'blue': 'from-blue-400 to-indigo-600 shadow-blue-500/20',\n 'purple': 'from-violet-400 to-purple-600 shadow-violet-500/20',\n 'pink': 'from-pink-400 to-rose-600 shadow-pink-500/20',\n 'gray': 'from-slate-500 to-slate-700 shadow-slate-500/20',\n 'default':'from-sky-400 to-blue-500 shadow-sky-500/20' \n };\n\n function saveAppOrder(orderArray) {\n var cleanOrder = orderArray.filter(function(id) { return id !== 'add'; });\n localStorage.setItem(STORE_KEY, JSON.stringify(cleanOrder));\n }\n\n function createAppHtml(app) {\n var colorKey = app.color;\n if (!colorKey) colorKey = 'sky';\n if (app.id === 'admin' && !app.color) colorKey = 'gray';\n var bgClass = COLOR_MAP[colorKey] || COLOR_MAP['sky'];\n\n var iconName = app.icon || 'account'; \n var iconPath = '/assets/icons/standard-sprite/svg/symbols.svg#' + iconName;\n\n // 使用转义的模板字符串\n return `\n <div class=\"app-item group flex flex-col items-center select-none\" \n data-id=\"\\${app.id}\" \n onclick=\"window.location.href='\\${app.path}'\">\n <div class=\"app-icon-container relative w-20 h-20 md:w-24 md:h-24 rounded-[1.6rem] bg-gradient-to-br \\${bgClass} text-white\">\n <div class=\"absolute top-0 left-0 right-0 h-1/2 bg-gradient-to-b from-white/20 to-transparent rounded-t-[1.6rem] pointer-events-none\"></div>\n <svg class=\"w-11 h-11 md:w-14 md:h-14 drop-shadow-sm\" aria-hidden=\"true\" fill=\"currentColor\">\n <use xlink:href=\"\\${iconPath}\"></use>\n </svg>\n </div>\n <span class=\"mt-3 text-xs md:text-sm font-semibold text-slate-600 group-hover:text-slate-900 transition-colors text-center line-clamp-1\">\\${app.name}</span>\n </div>\n `;\n }\n\n // ✅ 2. 生成添加按钮 (已绑定 handleAddAppClick)\n function createAddBtnHtml() {\n return `\n <div class=\"app-item group flex flex-col items-center select-none static-item\" data-id=\"add\" onclick=\"handleAddAppClick()\">\n <div class=\"app-icon-container relative w-20 h-20 md:w-24 md:h-24 rounded-[1.6rem] border-2 border-dashed border-slate-300 bg-white/50 backdrop-blur-sm text-slate-400\">\n <svg class=\"w-11 h-11 md:w-14 md:h-14\" aria-hidden=\"true\" fill=\"currentColor\">\n <use xlink:href=\"/assets/icons/utility-sprite/svg/symbols.svg#add\"></use>\n </svg>\n </div>\n <span class=\"mt-3 text-xs md:text-sm font-semibold text-slate-500\">添加应用</span>\n </div>\n `;\n }\n\n (async function initLauncher() {\n var gridElement = document.getElementById('vibrant-grid');\n var skeletonHtml = '';\n for(var i=0; i<6; i++) { skeletonHtml += `<div class=\"w-20 h-20 md:w-24 md:h-24 loading-skeleton mx-auto\"></div>`; }\n gridElement.innerHTML = skeletonHtml;\n\n try {\n var response = await fetch('/service/api/apps/menus?mobile=false');\n if (!response.ok) throw new Error('Failed to fetch apps');\n var appsData = await response.json();\n\n var savedOrderStr = localStorage.getItem(STORE_KEY);\n var finalApps = [];\n \n if (savedOrderStr) {\n var savedOrderIds = JSON.parse(savedOrderStr);\n savedOrderIds.forEach(function(id) {\n var app = appsData.find(function(a) { return a.id === id; });\n if (app) finalApps.push(app);\n });\n appsData.forEach(function(app) {\n if (savedOrderIds.indexOf(app.id) === -1) finalApps.push(app);\n });\n } else {\n finalApps = appsData;\n }\n\n var htmlContent = finalApps.map(function(app) { return createAppHtml(app); }).join('');\n htmlContent += createAddBtnHtml(); \n gridElement.innerHTML = htmlContent;\n\n if (typeof Sortable !== 'undefined') {\n new Sortable(gridElement, {\n animation: 350,\n easing: \"cubic-bezier(0.2, 0.8, 0.2, 1)\",\n delay: 0,\n delayOnTouchOnly: true,\n ghostClass: 'sortable-ghost',\n dragClass: 'sortable-drag',\n filter: \".static-item\", \n onMove: function (evt) { return evt.related.className.indexOf('static-item') === -1; },\n onEnd: function (evt) {\n var newOrder = [];\n var currentItems = gridElement.querySelectorAll('.app-item');\n currentItems.forEach(function(item) {\n var id = item.getAttribute('data-id');\n if (id && id !== 'add') newOrder.push(id);\n });\n saveAppOrder(newOrder);\n }\n });\n }\n } catch (error) {\n console.error(\"Launcher Error:\", error);\n gridElement.innerHTML = `<div class=\"col-span-full text-center text-slate-400\">加载失败<br><span class=\"text-xs opacity-70\">\\${error.message}</span></div>`;\n }\n })();\n</script>",
8
+ "id": "u:04103f69c7d4"
9
+ },
10
+ {
11
+ "type": "button",
12
+ "label": "按钮",
13
+ "onEvent": {
14
+ "click": {
15
+ "actions": [
16
+ {
17
+ "ignoreError": false,
18
+ "actionType": "dialog",
19
+ "dialog": {
20
+ "type": "dialog",
21
+ "title": "新建应用",
22
+ "body": [
23
+ {
24
+ "type": "steedos-object-form",
25
+ "label": "对象表单",
26
+ "objectApiName": "apps",
27
+ "recordId": "${recordId}",
28
+ "mode": "edit",
29
+ "enableInitApi": false,
30
+ "className": "",
31
+ "id": "u:b81c61018eeb",
32
+ "fields": [
33
+ "name",
34
+ "code",
35
+ "color",
36
+ "icon_slds",
37
+ "dark"
38
+ ],
39
+ "enableTabs": false,
40
+ "tabsMode": "",
41
+ "onSubmitSuccess": "document.location.reload();"
42
+ }
43
+ ],
44
+ "id": "u:6afe7f1c03a3",
45
+ "actions": [
46
+ {
47
+ "type": "button",
48
+ "actionType": "cancel",
49
+ "label": "取消",
50
+ "id": "u:7c749cf8acad"
51
+ },
52
+ {
53
+ "type": "button",
54
+ "actionType": "confirm",
55
+ "label": "确定",
56
+ "primary": true,
57
+ "id": "u:6ba48c5527ec"
58
+ }
59
+ ],
60
+ "showCloseButton": true,
61
+ "closeOnOutside": false,
62
+ "closeOnEsc": false,
63
+ "showErrorMsg": true,
64
+ "showLoading": true,
65
+ "draggable": false,
66
+ "actionType": "dialog",
67
+ "size": "md"
68
+ }
69
+ }
70
+ ]
71
+ }
72
+ },
73
+ "id": "buttonAddApp",
74
+ "editorState": "default",
75
+ "visible": true,
76
+ "hidden": false,
77
+ "wrapperCustomStyle": {},
78
+ "className": "hidden"
79
+ }
80
+ ],
81
+ "regions": [
82
+ "body"
83
+ ],
84
+ "data": {
85
+ "initialValues": {},
86
+ "appId": "builder",
87
+ "title": ""
88
+ },
89
+ "id": "u:d3e47da07a71",
90
+ "asideResizor": false,
91
+ "editorState": "default",
92
+ "pullRefresh": {
93
+ "disabled": true
94
+ },
95
+ "themeCss": {
96
+ "bodyControlClassName": {
97
+ "padding-and-margin:default": {
98
+ "paddingTop": "0",
99
+ "paddingRight": "0",
100
+ "paddingBottom": "0",
101
+ "paddingLeft": "0"
102
+ }
103
+ }
104
+ },
105
+ "definitions": {}
106
+ }
@@ -0,0 +1,7 @@
1
+ name: app_launcher
2
+ is_active: true
3
+ label: 应用
4
+ pageAssignments: []
5
+ render_engine: amis
6
+ type: app
7
+ widgets: []
@@ -0,0 +1,10 @@
1
+ {
2
+ "type": "page",
3
+ "body": [
4
+ {
5
+ "type": "liquid",
6
+ "id": "u:b10e5475cbfd",
7
+ "template": "\n<div class=\"max-w-7xl mx-auto p-4 sm:p-8\">\n \n \n <div class=\"flex items-center justify-between gap-4 mb-8 h-16\">\n <div class=\"shrink-0\">\n <h1 class=\"text-2xl font-bold text-slate-900 tracking-tight leading-none\">应用市场</h1>\n </div>\n <div class=\"flex items-center justify-end gap-3 flex-1 min-w-0\">\n <div class=\"relative group w-full max-w-xs\">\n <input type=\"text\" id=\"search-input\" class=\"block w-full pl-9 pr-3 py-2 bg-white border border-slate-200 rounded-lg text-sm placeholder-slate-400 focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500 transition-all shadow-sm\" placeholder=\"搜索应用...\">\n </div>\n </div>\n </div>\n\n \n <div class=\"relative overflow-hidden rounded-2xl bg-gradient-to-r from-blue-600 to-indigo-600 shadow-xl shadow-blue-900/10 mb-8\">\n <div class=\"absolute top-0 right-0 -mr-16 -mt-16 w-64 h-64 rounded-full bg-white opacity-10 blur-3xl\"></div>\n <div class=\"relative z-10 px-6 py-8 flex flex-col md:flex-row items-center justify-between gap-4\">\n <div>\n <h2 class=\"text-xl md:text-2xl font-bold text-white mb-1\">Steedos 3.0 现已上线</h2>\n <p class=\"text-blue-100 text-sm opacity-90\">采用先进的 元数据驱动 架构,帮助企业以传统开发 1/10 的成本,快速构建安全、可扩展的数字化核心应用。</p>\n </div>\n <a class=\"shrink-0 bg-white text-blue-600 hover:bg-blue-50 font-semibold py-2 px-5 rounded-lg text-sm shadow-sm transition-colors\" href=\"https://docs.steedos.com\" target=\"_blank\">查看详情</a>\n </div>\n </div>\n\n \n <div id=\"app-grid\" class=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6 min-h-[300px]\">\n \n <div class=\"col-span-full flex flex-col items-center justify-center py-20 text-slate-400\">\n <svg class=\"animate-spin h-8 w-8 text-blue-500 mb-4\" xmlns=\"http://www.w3.org/2000/svg\" fill=\"none\" viewBox=\"0 0 24 24\">\n <circle class=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" stroke-width=\"4\"></circle>\n <path class=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z\"></path>\n </svg>\n <span>正在加载应用数据...</span>\n </div>\n </div>\n</div>\n\n<script>\n(function() {\n // === 1. 配置 ===\n // 修改点:使用新的 Rest API 获取已安装列表,设置 top=5000 确保获取全部\n const API_INSTALLED = '/api/v6/data/steedos_packages?skip=0&top=5000';\n const API_MARKET = '/api/cloud/appstore/packages'; \n const API_INSTALL = '/api/nodes/package/add';\n \n let globalMarketApps = [];\n let globalInstalledNames = [];\n\n // === 2. 核心:等待 DOM 就绪 ===\n function checkReady() {\n const grid = document.getElementById('app-grid');\n const searchInput = document.getElementById('search-input');\n \n if (grid && searchInput) {\n init();\n \n searchInput.addEventListener('input', (e) => {\n const term = e.target.value.toLowerCase();\n const filtered = globalMarketApps.filter(app => \n (app.name && app.name.toLowerCase().includes(term)) || \n (app.label && app.label.toLowerCase().includes(term))\n );\n render(filtered, globalInstalledNames);\n });\n } else {\n setTimeout(checkReady, 100);\n }\n }\n\n // === 3. 初始化数据 ===\n async function init() {\n try {\n const [installedRes, marketRes] = await Promise.all([\n fetchInstalled(),\n fetchMarket()\n ]);\n\n globalInstalledNames = installedRes;\n globalMarketApps = marketRes;\n\n render(globalMarketApps, globalInstalledNames);\n\n } catch (error) {\n console.error('Init Error:', error);\n const grid = document.getElementById('app-grid');\n if(grid) {\n grid.innerHTML = `<div class=\"col-span-full text-center py-10 text-red-500\">数据加载失败: ${error.message}</div>`;\n }\n }\n }\n\n // === 4. API 请求 ===\n \n // 修改点:fetchInstalled 改为 GET 请求并适配新数据结构\n async function fetchInstalled() {\n try {\n const res = await fetch(API_INSTALLED, {\n method: 'GET', // 默认为 GET,显式写出方便理解\n headers: { 'Content-Type': 'application/json' }\n });\n if (!res.ok) return [];\n const json = await res.json();\n // 新接口结构是 { data: [...] }\n const list = json.data || [];\n // 提取 name 字段用于比对\n return list.map(item => item.name);\n } catch(e) {\n console.warn('Failed to fetch installed packages', e);\n return [];\n }\n }\n\n async function fetchMarket() {\n const res = await fetch(API_MARKET);\n if (!res.ok) throw new Error(`API Error: ${res.status}`);\n const json = await res.json();\n return Array.isArray(json) ? json : (json.data || json.rows || []);\n }\n\n // === 5. 渲染 HTML ===\n function render(apps, installedNames) {\n const grid = document.getElementById('app-grid');\n if (!grid) return;\n\n if (!apps || apps.length === 0) {\n grid.innerHTML = '<div class=\"col-span-full text-center text-slate-400 py-20\">暂无应用数据</div>';\n return;\n }\n\n const html = apps.map(app => {\n const isInstalled = installedNames.includes(app.package_name);\n const iconSlds = app.icon_slds || 'user';\n const displayName = app.name; \n const description = app.description || '暂无描述信息';\n const vender = app.vender;\n const version = app.version;\n \n let btnHtml = '';\n if (isInstalled) {\n btnHtml = `\n <button class=\"w-full rounded-lg bg-slate-100 text-slate-400 font-semibold py-2 px-4 cursor-not-allowed\" disabled>\n 已安装\n </button>`;\n } else {\n btnHtml = `\n <button \n onclick=\"window.installApp('\\${app.package_name}', this)\" \n class=\"w-full bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 px-4 rounded-lg shadow-lg shadow-blue-500/30 transition-all active:scale-95 flex items-center justify-center gap-2\">\n 立即安装\n </button>`;\n }\n\n return `\n <div class=\"group relative bg-white rounded-xl border border-slate-200 p-5 flex flex-col h-[260px] shadow-sm hover:shadow-xl hover:shadow-slate-200/50 hover:-translate-y-1 transition-all duration-300 overflow-hidden\">\n <div class=\"flex items-start justify-between mb-4\">\n <div class=\"w-14 h-14 rounded-xl flex items-center justify-center slds-icon_container slds-icon-standard-\\${iconSlds}\">\n <svg class=\"w-8 h-8 slds-icon\" aria-hidden=\"true\">\n <use xlink:href=\"/assets/icons/standard-sprite/svg/symbols.svg#\\${iconSlds}\"></use>\n </svg>\n </div>\n \\${app.featured ? '<span class=\"px-2 py-1 rounded text-[10px] font-bold bg-slate-100 text-slate-500 uppercase tracking-wider\">推荐</span>' : ''}\n </div>\n\n <h3 class=\"text-lg font-bold text-slate-800 mb-2 transition-colors truncate\" title=\"\\${displayName}\">\n \\${displayName}\n </h3>\n \n <p class=\"text-sm text-slate-500 leading-relaxed line-clamp-3\">\\${description}</p>\n\n <div class=\"mt-auto pt-2 flex justify-between items-center border-t border-slate-50\">\n <p class=\"text-xs text-slate-400 mt-2\">v\\${version}</p>\n <p class=\"text-xs text-slate-400 mt-2\">\\${vender}</p>\n </div>\n\n <div class=\"absolute inset-x-0 bottom-0 pt-10 pb-5 px-5 bg-gradient-to-t from-white via-white/95 to-transparent translate-y-full group-hover:translate-y-0 transition-transform duration-300 ease-out flex items-end\">\n \\${btnHtml}\n </div>\n </div>\n `;\n }).join('');\n\n grid.innerHTML = html;\n }\n\n // === 6. 挂载点击事件 ===\n window.installApp = async function(packageName, btnElement) {\n const originalText = btnElement.innerText;\n btnElement.innerText = '安装中...';\n btnElement.disabled = true;\n btnElement.classList.add('opacity-75', 'cursor-wait');\n\n try {\n const registry = 'https://registry.npmmirror.com';\n const response = await fetch(API_INSTALL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n package: packageName\n })\n });\n\n if (!response.ok) throw new Error('Network error');\n await response.json();\n\n // 成功\n btnElement.innerText = '已安装';\n btnElement.className = 'w-full rounded-lg bg-slate-100 text-slate-400 font-semibold py-2 px-4 cursor-not-allowed';\n globalInstalledNames.push(packageName);\n\n } catch (error) {\n console.error('Install Failed:', error);\n alert('安装失败,请重试');\n btnElement.innerText = originalText;\n btnElement.disabled = false;\n btnElement.classList.remove('opacity-75', 'cursor-wait');\n }\n };\n\n checkReady();\n})();\n</script>"
8
+ }
9
+ ]
10
+ }
@@ -0,0 +1,7 @@
1
+ name: app_store
2
+ is_active: true
3
+ label: App Store
4
+ pageAssignments: []
5
+ render_engine: amis
6
+ type: app
7
+ widgets: []
@@ -1,7 +1,7 @@
1
1
  name: admin_bull_dashboard
2
2
  desktop: true
3
3
  icon: dashboard
4
- is_new_window: false
4
+ is_new_window: true
5
5
  is_use_iframe: true
6
6
  label: Bull Dashboard
7
7
  mobile: true
@@ -1,7 +1,7 @@
1
1
  name: admin_swagger
2
2
  desktop: true
3
3
  icon: data_model
4
- is_new_window: false
4
+ is_new_window: true
5
5
  is_use_iframe: true
6
6
  label: OpenAPI
7
7
  mobile: true
@@ -0,0 +1,10 @@
1
+ name: page_app_launcher
2
+ desktop: true
3
+ icon: agent_home
4
+ is_new_window: false
5
+ is_use_iframe: false
6
+ label: 应用
7
+ mobile: true
8
+ page: app_launcher
9
+ permissions: []
10
+ type: page
@@ -1,8 +1,9 @@
1
- name: admin_flow_roles
1
+ name: page_app_store
2
2
  desktop: true
3
- icon: messaging_user
3
+ icon: product_consumed
4
4
  is_new_window: false
5
- label: 审批岗位
5
+ is_use_iframe: false
6
+ label: App Store
6
7
  mobile: true
7
8
  permissions:
8
9
  - permission: 'on'
@@ -13,9 +14,9 @@ permissions:
13
14
  permission_set: customer
14
15
  - permission: 'off'
15
16
  permission_set: supplier
16
- - permission: 'off'
17
+ - permission: 'on'
17
18
  permission_set: organization_admin
18
19
  - permission: 'off'
19
20
  permission_set: workflow_admin
20
- type: object
21
- object: flow_roles
21
+ type: page
22
+ page: app_store
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steedos/service-core-objects",
3
- "version": "3.0.9-beta.2",
3
+ "version": "3.0.9",
4
4
  "main": "package.service.js",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -9,7 +9,7 @@
9
9
  "steedos"
10
10
  ],
11
11
  "dependencies": {
12
- "@steedos/service-package-loader": "3.0.9-beta.2",
12
+ "@steedos/service-package-loader": "3.0.9",
13
13
  "bcryptjs": "^3.0.3",
14
14
  "json2xls": "^0.1.2",
15
15
  "lodash": "^4.17.21"
@@ -17,5 +17,5 @@
17
17
  "description": "steedos package",
18
18
  "repository": {},
19
19
  "license": "MIT",
20
- "gitHead": "663d566c6486919ac0d7645e2f3003b2f38de732"
20
+ "gitHead": "9eb953c608479988327314b2a6974ea005f4d3e5"
21
21
  }
@@ -1,31 +0,0 @@
1
- /*
2
- * @Author: baozhoutao@steedos.com
3
- * @Date: 2023-04-11 14:05:42
4
- * @LastEditors: baozhoutao@steedos.com
5
- * @LastEditTime: 2023-10-09 15:44:47
6
- * @Description:
7
- */
8
- module.exports = {
9
- amis_nav_schema_design: function (object_name, record_id) {
10
- document.location = Steedos.absoluteUrl(`/api/amisAppNavSchemaDesign?id=${record_id}&object=${this.record.object_name}&assetUrls=${Builder.settings.assetUrls}&locale=${Builder.settings.locale}`);
11
- },
12
- amis_nav_schema_designVisible: function (object_name, record_id, record_permissions, data) {
13
- var perms = {};
14
- var record = data.record;
15
- if (!record) {
16
- return false;
17
- }
18
- if (!record.enable_nav_schema) {
19
- return false;
20
- }
21
- if (record_permissions) {
22
- perms = record_permissions;
23
- } else {
24
- record_permissions = Creator.getRecordPermissions(object_name, record, Meteor.userId());
25
- if (record_permissions) {
26
- perms = record_permissions;
27
- }
28
- }
29
- return perms["allowEdit"];
30
- }
31
- }
@@ -1,4 +0,0 @@
1
- name: amis_nav_schema_design
2
- is_enable: true
3
- label: 导航设计器
4
- 'on': record_only
@@ -1,21 +0,0 @@
1
- name: admin_categories
2
- desktop: true
3
- icon: hierarchy
4
- is_new_window: false
5
- label: 流程分类
6
- mobile: true
7
- permissions:
8
- - permission: 'on'
9
- permission_set: admin
10
- - permission: 'off'
11
- permission_set: user
12
- - permission: 'off'
13
- permission_set: customer
14
- - permission: 'off'
15
- permission_set: supplier
16
- - permission: 'off'
17
- permission_set: organization_admin
18
- - permission: 'off'
19
- permission_set: workflow_admin
20
- type: object
21
- object: categories
@@ -1,21 +0,0 @@
1
- name: admin_flow_positions
2
- desktop: true
3
- icon: person_account
4
- is_new_window: false
5
- label: 审批岗位成员
6
- mobile: true
7
- permissions:
8
- - permission: 'on'
9
- permission_set: admin
10
- - permission: 'off'
11
- permission_set: user
12
- - permission: 'off'
13
- permission_set: customer
14
- - permission: 'off'
15
- permission_set: supplier
16
- - permission: 'off'
17
- permission_set: organization_admin
18
- - permission: 'off'
19
- permission_set: workflow_admin
20
- type: object
21
- object: flow_positions
@@ -1,21 +0,0 @@
1
- name: admin_flows
2
- desktop: true
3
- icon: environment_hub
4
- is_new_window: false
5
- label: 流程
6
- mobile: true
7
- permissions:
8
- - permission: 'on'
9
- permission_set: admin
10
- - permission: 'off'
11
- permission_set: user
12
- - permission: 'off'
13
- permission_set: customer
14
- - permission: 'off'
15
- permission_set: supplier
16
- - permission: 'off'
17
- permission_set: organization_admin
18
- - permission: 'off'
19
- permission_set: workflow_admin
20
- type: object
21
- object: flows
@@ -1,23 +0,0 @@
1
- name: admin_instance_number_rules
2
- desktop: true
3
- icon: topic2
4
- is_new_window: false
5
- label: 流程编号
6
- mobile: true
7
- permissions:
8
- - permission: 'on'
9
- permission_set: admin
10
- - permission: 'off'
11
- permission_set: user
12
- - permission: 'off'
13
- permission_set: customer
14
- - permission: 'off'
15
- permission_set: supplier
16
- - permission: 'off'
17
- permission_set: organization_admin
18
- - permission: 'off'
19
- permission_set: workflow_admin
20
- type: object
21
- object: instance_number_rules
22
- license:
23
- - platform-enterprise
@@ -1,24 +0,0 @@
1
- name: admin_instances_statistic
2
- desktop: true
3
- icon: metrics
4
- is_new_window: false
5
- label: 效率统计
6
- mobile: true
7
- permissions:
8
- - permission: 'on'
9
- permission_set: admin
10
- - permission: 'off'
11
- permission_set: user
12
- - permission: 'off'
13
- permission_set: customer
14
- - permission: 'off'
15
- permission_set: supplier
16
- - permission: 'off'
17
- permission_set: organization_admin
18
- - permission: 'off'
19
- permission_set: workflow_admin
20
- type: object
21
- object: instances_statistic
22
- license:
23
- - platform-enterprise
24
-
@@ -1,21 +0,0 @@
1
- name: admin_roles
2
- desktop: true
3
- icon: job_family
4
- is_new_window: false
5
- label: 角色
6
- mobile: true
7
- permissions:
8
- - permission: 'on'
9
- permission_set: admin
10
- - permission: 'off'
11
- permission_set: user
12
- - permission: 'off'
13
- permission_set: customer
14
- - permission: 'off'
15
- permission_set: supplier
16
- - permission: 'off'
17
- permission_set: organization_admin
18
- - permission: 'off'
19
- permission_set: workflow_admin
20
- type: object
21
- object: roles
@@ -1,25 +0,0 @@
1
- name: admin_space_user_signs
2
- desktop: true
3
- icon: carousel
4
- is_new_window: false
5
- label: 图片签名
6
- mobile: true
7
- permissions:
8
- - permission: 'on'
9
- permission_set: admin
10
- - permission: 'off'
11
- permission_set: user
12
- - permission: 'off'
13
- permission_set: customer
14
- - permission: 'off'
15
- permission_set: supplier
16
- - permission: 'off'
17
- permission_set: organization_admin
18
- - permission: 'off'
19
- permission_set: workflow_admin
20
- type: object
21
- object: space_user_signs
22
- license:
23
- - platform-professional
24
- - platform-enterprise
25
-
@@ -1,21 +0,0 @@
1
- name: admin_webhooks
2
- desktop: true
3
- icon: sales_cadence
4
- is_new_window: false
5
- label: 流程触发器
6
- mobile: true
7
- permissions:
8
- - permission: 'on'
9
- permission_set: admin
10
- - permission: 'off'
11
- permission_set: user
12
- - permission: 'off'
13
- permission_set: customer
14
- - permission: 'off'
15
- permission_set: supplier
16
- - permission: 'off'
17
- permission_set: organization_admin
18
- - permission: 'off'
19
- permission_set: workflow_admin
20
- type: object
21
- object: webhooks