diff --git a/core/mobile/src/common/style/uni.css b/core/mobile/src/common/style/uni.css
index a3a520e310..28d8ed4f82 100644
--- a/core/mobile/src/common/style/uni.css
+++ b/core/mobile/src/common/style/uni.css
@@ -17,6 +17,17 @@ uni-app {
.fix-left-window {
padding-left: var(--window-left);
}
+.uni-page-head-ft {
+ margin-left: 8px;
+ .uni-page-head-btn {
+ background: none;
+ border: 1px solid #BBBFC4;
+ border-radius: 4px;
+ .uni-btn-icon {
+ color: #bbbfc4 !important;
+ }
+ }
+}
.pc-hide {
display: none !important;
diff --git a/core/mobile/src/common/utils.js b/core/mobile/src/common/utils.js
index 2e6fa8b2f7..5b07132d56 100644
--- a/core/mobile/src/common/utils.js
+++ b/core/mobile/src/common/utils.js
@@ -156,3 +156,46 @@ export function getUrlParams(url){
}
return Params
}
+
+
+export function deepCopy(target) {
+ if (typeof target === 'object' && target !== null) {
+ const result = Array.isArray(target) ? [] : {}
+ for (const key in target) {
+ if (typeof target[key] === 'object') {
+ result[key] = deepCopy(target[key])
+ } else {
+ result[key] = target[key]
+ }
+ }
+
+ return result
+ }
+
+ return target
+}
+export function treeSort(tree, hisSortType, sortType) {
+ const result = deepCopy(tree)
+ sortCircle(result, hisSortType, sortType)
+ return result
+}
+
+export function sortCircle(tree, hisSortType, sortType) {
+ sortPer(tree, hisSortType, sortType)
+ tree.forEach(node => {
+ if (node.children && node.children.length > 0) {
+ sortCircle(node.children, hisSortType, sortType)
+ }
+ })
+ return tree
+}
+
+export function sortPer(subTree, hisSortType, sortType) {
+ if (sortType === 'name_desc') {
+ subTree.sort((a, b) => b.text.localeCompare(a.text, 'zh-Hans-CN', { sensitivity: 'accent' }))
+ } else if (sortType === 'name_asc') {
+ subTree.sort((a, b) => a.text.localeCompare(b.text, 'zh-Hans-CN', { sensitivity: 'accent' }))
+ } else if (sortType === 'time_asc') {
+ subTree.reverse()
+ }
+}
diff --git a/core/mobile/src/components/uni-popup-dialog/keypress.js b/core/mobile/src/components/uni-popup-dialog/keypress.js
new file mode 100644
index 0000000000..6ef26a2621
--- /dev/null
+++ b/core/mobile/src/components/uni-popup-dialog/keypress.js
@@ -0,0 +1,45 @@
+// #ifdef H5
+export default {
+ name: 'Keypress',
+ props: {
+ disable: {
+ type: Boolean,
+ default: false
+ }
+ },
+ mounted () {
+ const keyNames = {
+ esc: ['Esc', 'Escape'],
+ tab: 'Tab',
+ enter: 'Enter',
+ space: [' ', 'Spacebar'],
+ up: ['Up', 'ArrowUp'],
+ left: ['Left', 'ArrowLeft'],
+ right: ['Right', 'ArrowRight'],
+ down: ['Down', 'ArrowDown'],
+ delete: ['Backspace', 'Delete', 'Del']
+ }
+ const listener = ($event) => {
+ if (this.disable) {
+ return
+ }
+ const keyName = Object.keys(keyNames).find(key => {
+ const keyName = $event.key
+ const value = keyNames[key]
+ return value === keyName || (Array.isArray(value) && value.includes(keyName))
+ })
+ if (keyName) {
+ // 避免和其他按键事件冲突
+ setTimeout(() => {
+ this.$emit(keyName, {})
+ }, 0)
+ }
+ }
+ document.addEventListener('keyup', listener)
+ this.$once('hook:beforeDestroy', () => {
+ document.removeEventListener('keyup', listener)
+ })
+ },
+ render: () => {}
+}
+// #endif
diff --git a/core/mobile/src/components/uni-popup-dialog/uni-popup-dialog.vue b/core/mobile/src/components/uni-popup-dialog/uni-popup-dialog.vue
new file mode 100644
index 0000000000..08707d41b6
--- /dev/null
+++ b/core/mobile/src/components/uni-popup-dialog/uni-popup-dialog.vue
@@ -0,0 +1,316 @@
+
+
+
+
+
+
+
diff --git a/core/mobile/src/components/uni-popup-message/uni-popup-message.vue b/core/mobile/src/components/uni-popup-message/uni-popup-message.vue
new file mode 100644
index 0000000000..91370a8295
--- /dev/null
+++ b/core/mobile/src/components/uni-popup-message/uni-popup-message.vue
@@ -0,0 +1,143 @@
+
+
+
+
+
+
diff --git a/core/mobile/src/components/uni-popup-share/uni-popup-share.vue b/core/mobile/src/components/uni-popup-share/uni-popup-share.vue
new file mode 100644
index 0000000000..f7e667c4c9
--- /dev/null
+++ b/core/mobile/src/components/uni-popup-share/uni-popup-share.vue
@@ -0,0 +1,187 @@
+
+
+
+
+
+
diff --git a/core/mobile/src/components/uni-popup/i18n/en.json b/core/mobile/src/components/uni-popup/i18n/en.json
new file mode 100644
index 0000000000..7f1bd06a03
--- /dev/null
+++ b/core/mobile/src/components/uni-popup/i18n/en.json
@@ -0,0 +1,7 @@
+{
+ "uni-popup.cancel": "cancel",
+ "uni-popup.ok": "ok",
+ "uni-popup.placeholder": "pleace enter",
+ "uni-popup.title": "Hint",
+ "uni-popup.shareTitle": "Share to"
+}
diff --git a/core/mobile/src/components/uni-popup/i18n/index.js b/core/mobile/src/components/uni-popup/i18n/index.js
new file mode 100644
index 0000000000..de7509c87b
--- /dev/null
+++ b/core/mobile/src/components/uni-popup/i18n/index.js
@@ -0,0 +1,8 @@
+import en from './en.json'
+import zhHans from './zh-Hans.json'
+import zhHant from './zh-Hant.json'
+export default {
+ en,
+ 'zh-Hans': zhHans,
+ 'zh-Hant': zhHant
+}
diff --git a/core/mobile/src/components/uni-popup/i18n/zh-Hans.json b/core/mobile/src/components/uni-popup/i18n/zh-Hans.json
new file mode 100644
index 0000000000..5e3003cabc
--- /dev/null
+++ b/core/mobile/src/components/uni-popup/i18n/zh-Hans.json
@@ -0,0 +1,7 @@
+{
+ "uni-popup.cancel": "取消",
+ "uni-popup.ok": "确定",
+ "uni-popup.placeholder": "请输入",
+ "uni-popup.title": "提示",
+ "uni-popup.shareTitle": "分享到"
+}
diff --git a/core/mobile/src/components/uni-popup/i18n/zh-Hant.json b/core/mobile/src/components/uni-popup/i18n/zh-Hant.json
new file mode 100644
index 0000000000..13e39eba10
--- /dev/null
+++ b/core/mobile/src/components/uni-popup/i18n/zh-Hant.json
@@ -0,0 +1,7 @@
+{
+ "uni-popup.cancel": "取消",
+ "uni-popup.ok": "確定",
+ "uni-popup.placeholder": "請輸入",
+ "uni-popup.title": "提示",
+ "uni-popup.shareTitle": "分享到"
+}
diff --git a/core/mobile/src/components/uni-popup/keypress.js b/core/mobile/src/components/uni-popup/keypress.js
new file mode 100644
index 0000000000..62dda461bd
--- /dev/null
+++ b/core/mobile/src/components/uni-popup/keypress.js
@@ -0,0 +1,45 @@
+// #ifdef H5
+export default {
+ name: 'Keypress',
+ props: {
+ disable: {
+ type: Boolean,
+ default: false
+ }
+ },
+ mounted () {
+ const keyNames = {
+ esc: ['Esc', 'Escape'],
+ tab: 'Tab',
+ enter: 'Enter',
+ space: [' ', 'Spacebar'],
+ up: ['Up', 'ArrowUp'],
+ left: ['Left', 'ArrowLeft'],
+ right: ['Right', 'ArrowRight'],
+ down: ['Down', 'ArrowDown'],
+ delete: ['Backspace', 'Delete', 'Del']
+ }
+ const listener = ($event) => {
+ if (this.disable) {
+ return
+ }
+ const keyName = Object.keys(keyNames).find(key => {
+ const keyName = $event.key
+ const value = keyNames[key]
+ return value === keyName || (Array.isArray(value) && value.includes(keyName))
+ })
+ if (keyName) {
+ // 避免和其他按键事件冲突
+ setTimeout(() => {
+ this.$emit(keyName, {})
+ }, 0)
+ }
+ }
+ document.addEventListener('keyup', listener)
+ // this.$once('hook:beforeDestroy', () => {
+ // document.removeEventListener('keyup', listener)
+ // })
+ },
+ render: () => {}
+}
+// #endif
diff --git a/core/mobile/src/components/uni-popup/popup.js b/core/mobile/src/components/uni-popup/popup.js
new file mode 100644
index 0000000000..c4e5781dd6
--- /dev/null
+++ b/core/mobile/src/components/uni-popup/popup.js
@@ -0,0 +1,26 @@
+
+export default {
+ data() {
+ return {
+
+ }
+ },
+ created(){
+ this.popup = this.getParent()
+ },
+ methods:{
+ /**
+ * 获取父元素实例
+ */
+ getParent(name = 'uniPopup') {
+ let parent = this.$parent;
+ let parentName = parent.$options.name;
+ while (parentName !== name) {
+ parent = parent.$parent;
+ if (!parent) return false
+ parentName = parent.$options.name;
+ }
+ return parent;
+ },
+ }
+}
diff --git a/core/mobile/src/components/uni-popup/uni-popup.uvue b/core/mobile/src/components/uni-popup/uni-popup.uvue
new file mode 100644
index 0000000000..5eb8d5be62
--- /dev/null
+++ b/core/mobile/src/components/uni-popup/uni-popup.uvue
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/mobile/src/components/uni-popup/uni-popup.vue b/core/mobile/src/components/uni-popup/uni-popup.vue
new file mode 100644
index 0000000000..8349e99443
--- /dev/null
+++ b/core/mobile/src/components/uni-popup/uni-popup.vue
@@ -0,0 +1,503 @@
+
+
+
+
+
+
diff --git a/core/mobile/src/components/uni-transition/createAnimation.js b/core/mobile/src/components/uni-transition/createAnimation.js
new file mode 100644
index 0000000000..8f89b185c7
--- /dev/null
+++ b/core/mobile/src/components/uni-transition/createAnimation.js
@@ -0,0 +1,131 @@
+// const defaultOption = {
+// duration: 300,
+// timingFunction: 'linear',
+// delay: 0,
+// transformOrigin: '50% 50% 0'
+// }
+// #ifdef APP-NVUE
+const nvueAnimation = uni.requireNativePlugin('animation')
+// #endif
+class MPAnimation {
+ constructor(options, _this) {
+ this.options = options
+ // 在iOS10+QQ小程序平台下,传给原生的对象一定是个普通对象而不是Proxy对象,否则会报parameter should be Object instead of ProxyObject的错误
+ this.animation = uni.createAnimation({
+ ...options
+ })
+ this.currentStepAnimates = {}
+ this.next = 0
+ this.$ = _this
+
+ }
+
+ _nvuePushAnimates(type, args) {
+ let aniObj = this.currentStepAnimates[this.next]
+ let styles = {}
+ if (!aniObj) {
+ styles = {
+ styles: {},
+ config: {}
+ }
+ } else {
+ styles = aniObj
+ }
+ if (animateTypes1.includes(type)) {
+ if (!styles.styles.transform) {
+ styles.styles.transform = ''
+ }
+ let unit = ''
+ if(type === 'rotate'){
+ unit = 'deg'
+ }
+ styles.styles.transform += `${type}(${args+unit}) `
+ } else {
+ styles.styles[type] = `${args}`
+ }
+ this.currentStepAnimates[this.next] = styles
+ }
+ _animateRun(styles = {}, config = {}) {
+ let ref = this.$.$refs['ani'].ref
+ if (!ref) return
+ return new Promise((resolve, reject) => {
+ nvueAnimation.transition(ref, {
+ styles,
+ ...config
+ }, res => {
+ resolve()
+ })
+ })
+ }
+
+ _nvueNextAnimate(animates, step = 0, fn) {
+ let obj = animates[step]
+ if (obj) {
+ let {
+ styles,
+ config
+ } = obj
+ this._animateRun(styles, config).then(() => {
+ step += 1
+ this._nvueNextAnimate(animates, step, fn)
+ })
+ } else {
+ this.currentStepAnimates = {}
+ typeof fn === 'function' && fn()
+ this.isEnd = true
+ }
+ }
+
+ step(config = {}) {
+ // #ifndef APP-NVUE
+ this.animation.step(config)
+ // #endif
+ // #ifdef APP-NVUE
+ this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config)
+ this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin
+ this.next++
+ // #endif
+ return this
+ }
+
+ run(fn) {
+ // #ifndef APP-NVUE
+ this.$.animationData = this.animation.export()
+ this.$.timer = setTimeout(() => {
+ typeof fn === 'function' && fn()
+ }, this.$.durationTime)
+ // #endif
+ // #ifdef APP-NVUE
+ this.isEnd = false
+ let ref = this.$.$refs['ani'] && this.$.$refs['ani'].ref
+ if(!ref) return
+ this._nvueNextAnimate(this.currentStepAnimates, 0, fn)
+ this.next = 0
+ // #endif
+ }
+}
+
+
+const animateTypes1 = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d',
+ 'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY',
+ 'translateZ'
+]
+const animateTypes2 = ['opacity', 'backgroundColor']
+const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom']
+animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => {
+ MPAnimation.prototype[type] = function(...args) {
+ // #ifndef APP-NVUE
+ this.animation[type](...args)
+ // #endif
+ // #ifdef APP-NVUE
+ this._nvuePushAnimates(type, args)
+ // #endif
+ return this
+ }
+})
+
+export function createAnimation(option, _this) {
+ if(!_this) return
+ clearTimeout(_this.timer)
+ return new MPAnimation(option, _this)
+}
diff --git a/core/mobile/src/components/uni-transition/uni-transition.vue b/core/mobile/src/components/uni-transition/uni-transition.vue
new file mode 100644
index 0000000000..f3ddd1f321
--- /dev/null
+++ b/core/mobile/src/components/uni-transition/uni-transition.vue
@@ -0,0 +1,286 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/mobile/src/pages.json b/core/mobile/src/pages.json
index 11a720f61d..9a0a3542a8 100644
--- a/core/mobile/src/pages.json
+++ b/core/mobile/src/pages.json
@@ -41,7 +41,13 @@
"type": "transparent",
"titleColor": "#fff",
"backgroundColor": "#0faeff",
- "buttons": [],
+ "buttons": [
+ {
+ "fontSrc":"/static/custom/iconfont.ttf",
+ "text":"\ue61d",
+ "fontSize": "24px"
+ }
+ ],
"searchInput": {
"backgroundColor": "#fff",
"borderRadius": "6px",
diff --git a/core/mobile/src/pages/tabBar/dir/folder.vue b/core/mobile/src/pages/tabBar/dir/folder.vue
index c18e814a33..a20c00b888 100644
--- a/core/mobile/src/pages/tabBar/dir/folder.vue
+++ b/core/mobile/src/pages/tabBar/dir/folder.vue
@@ -28,6 +28,7 @@
@@ -104,4 +174,36 @@ swiper,
.de-main {
padding-top: 60rpx;
}
+.action-sheet-container {
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ box-shadow: 0 -1px 3px rgba(0, 0, 0, 0.1);
+}
+.action-sheet-content-container {
+ background-color: #FFFFFF;
+ bottom: 0;
+ left: 0;
+ right: 0;
+}
+.action-sheet-close-container {
+ background-color: #FFFFFF;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ margin-top: 1px;
+}
+
+.action-sheet-item {
+ padding: 10px;
+ text-align: center;
+ font-size: 18px;
+ color: #666666;
+}
+
+.action-sheet-item-selected {
+ color: #007AFF;
+ font-weight: bold;
+}
diff --git a/core/mobile/src/static/custom/iconfont.css b/core/mobile/src/static/custom/iconfont.css
new file mode 100644
index 0000000000..2311963255
--- /dev/null
+++ b/core/mobile/src/static/custom/iconfont.css
@@ -0,0 +1,19 @@
+@font-face {
+ font-family: "iconfont"; /* Project id 4566310 */
+ src: url('iconfont.woff2?t=1716966170729') format('woff2'),
+ url('iconfont.woff?t=1716966170729') format('woff'),
+ url('iconfont.ttf?t=1716966170729') format('truetype');
+}
+
+.iconfont {
+ font-family: "iconfont" !important;
+ font-size: 16px;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-paixu-jiangxu:before {
+ content: "\e61d";
+}
+
diff --git a/core/mobile/src/static/custom/iconfont.js b/core/mobile/src/static/custom/iconfont.js
new file mode 100644
index 0000000000..a9b11689cd
--- /dev/null
+++ b/core/mobile/src/static/custom/iconfont.js
@@ -0,0 +1 @@
+window._iconfont_svg_string_4566310='',function(n){var t=(t=document.getElementsByTagName("script"))[t.length-1],e=t.getAttribute("data-injectcss"),t=t.getAttribute("data-disable-injectsvg");if(!t){var i,o,a,d,c,s=function(t,e){e.parentNode.insertBefore(t,e)};if(e&&!n.__iconfont__svg__cssinject__){n.__iconfont__svg__cssinject__=!0;try{document.write("")}catch(t){console&&console.log(t)}}i=function(){var t,e=document.createElement("div");e.innerHTML=n._iconfont_svg_string_4566310,(e=e.getElementsByTagName("svg")[0])&&(e.setAttribute("aria-hidden","true"),e.style.position="absolute",e.style.width=0,e.style.height=0,e.style.overflow="hidden",e=e,(t=document.body).firstChild?s(e,t.firstChild):t.appendChild(e))},document.addEventListener?~["complete","loaded","interactive"].indexOf(document.readyState)?setTimeout(i,0):(o=function(){document.removeEventListener("DOMContentLoaded",o,!1),i()},document.addEventListener("DOMContentLoaded",o,!1)):document.attachEvent&&(a=i,d=n.document,c=!1,r(),d.onreadystatechange=function(){"complete"==d.readyState&&(d.onreadystatechange=null,l())})}function l(){c||(c=!0,a())}function r(){try{d.documentElement.doScroll("left")}catch(t){return void setTimeout(r,50)}l()}}(window);
\ No newline at end of file
diff --git a/core/mobile/src/static/custom/iconfont.json b/core/mobile/src/static/custom/iconfont.json
new file mode 100644
index 0000000000..d02fa9a745
--- /dev/null
+++ b/core/mobile/src/static/custom/iconfont.json
@@ -0,0 +1,16 @@
+{
+ "id": "4566310",
+ "name": "dataease-v1-mobile",
+ "font_family": "iconfont",
+ "css_prefix_text": "icon-",
+ "description": "",
+ "glyphs": [
+ {
+ "icon_id": "21571824",
+ "name": "排序-降序",
+ "font_class": "paixu-jiangxu",
+ "unicode": "e61d",
+ "unicode_decimal": 58909
+ }
+ ]
+}
diff --git a/core/mobile/src/static/custom/iconfont.ttf b/core/mobile/src/static/custom/iconfont.ttf
new file mode 100644
index 0000000000..7c61f8baa6
Binary files /dev/null and b/core/mobile/src/static/custom/iconfont.ttf differ
diff --git a/core/mobile/src/static/custom/iconfont.woff b/core/mobile/src/static/custom/iconfont.woff
new file mode 100644
index 0000000000..1383043856
Binary files /dev/null and b/core/mobile/src/static/custom/iconfont.woff differ
diff --git a/core/mobile/src/static/custom/iconfont.woff2 b/core/mobile/src/static/custom/iconfont.woff2
new file mode 100644
index 0000000000..4419a61620
Binary files /dev/null and b/core/mobile/src/static/custom/iconfont.woff2 differ
diff --git a/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/static/.gitkeep b/extensions/dataease-extensions-view/view-bubblemap/view-bubblemap-frontend/static/.gitkeep
deleted file mode 100644
index e69de29bb2..0000000000