diff --git a/app/Http/Controllers/Api/FileController.php b/app/Http/Controllers/Api/FileController.php index 19bd5330e..bf0beb94d 100755 --- a/app/Http/Controllers/Api/FileController.php +++ b/app/Http/Controllers/Api/FileController.php @@ -106,6 +106,7 @@ class FileController extends AbstractController * * @apiParam {String} [link] 通过分享地址搜索(如:https://t.hitosea.com/single/file/ODcwOCwzOSxpa0JBS2lmVQ==) * @apiParam {String} [key] 关键词 + * @apiParam {Number} [take] 获取数量(默认:50,最大:100) * * @apiSuccess {Number} ret 返回状态码(1正确、0错误) * @apiSuccess {String} msg 返回信息(错误描述) @@ -118,7 +119,7 @@ class FileController extends AbstractController $link = trim(Request::input('link')); $key = trim(Request::input('key')); $id = 0; - $take = 50; + $take = Base::getPaginate(100, 50, 'take'); if (preg_match("/\/single\/file\/(.*?)$/i", $link, $match)) { $id = intval(FileLink::whereCode($match[1])->value('file_id')); $take = 1; diff --git a/package.json b/package.json index 989ca087c..73dc7c118 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "stylus-loader": "^7.1.0", "tinymce": "^5.10.3", "tui-calendar-hi": "^1.15.1-5", - "view-design-hi": "^4.7.0-65", + "view-design-hi": "^4.7.0-66", "vite": "^2.9.15", "vite-plugin-file-copy": "^1.0.0", "vite-plugin-require": "^1.1.10", diff --git a/resources/assets/js/components/SearchBox.vue b/resources/assets/js/components/SearchBox.vue index 8283abed2..60cbc15e5 100755 --- a/resources/assets/js/components/SearchBox.vue +++ b/resources/assets/js/components/SearchBox.vue @@ -14,12 +14,24 @@ - +
+
+
+ + {{$L(tag.name)}} + +
+
    -
  • {{typeLabel(type)}}
  • +
  • {{typeLabel(type)}}
  • @@ -92,6 +104,15 @@ export default { searchTimer: null, showModal: false, + + tags: [ + {type: 'task', name: '任务', icon: ''}, + {type: 'project', name: '项目', icon: ''}, + {type: 'message', name: '消息', icon: ''}, + {type: 'contact', name: '联系人', icon: ''}, + {type: 'file', name: '文件', icon: ''}, + ], + action: '', } }, @@ -104,26 +125,12 @@ export default { }, watch: { - searchKey: { - handler: function () { - if (!this.searchKey.trim()) { - return; - } - if (this.searchTimer) { - clearTimeout(this.searchTimer) - this.searchTimer = null; - this.loadIng--; - } - this.loadIng++; - this.searchTimer = setTimeout(() => { - if (this.searchKey.trim()) { - this.onSearch() - } - this.searchTimer = null; - this.loadIng--; - }, 500) - }, - immediate: true + searchKey() { + this.preSearch() + }, + + action() { + this.preSearch() }, showModal(v) { @@ -137,22 +144,22 @@ export default { 'keyboardType' ]), - list({searchKey, searchResults}) { - const items = searchResults.filter(item => item.key === searchKey) + list({searchKey, searchResults, action}) { + const items = searchResults.filter(item => item.key === searchKey && (!action || item.type === action)) const groups = {} items.forEach(item => { if (!groups[item.type]) { groups[item.type] = [] } - if (groups[item.type].length < 10) { + if (groups[item.type].length < 10 || action) { groups[item.type].push(item) } }) return groups }, - listLength({searchKey, searchResults}) { - const items = searchResults.filter(item => item.key === searchKey) + listLength({searchKey, searchResults, action}) { + const items = searchResults.filter(item => item.key === searchKey && (!action || item.type === action)) return items.length }, @@ -163,17 +170,9 @@ export default { methods: { typeLabel(type) { - switch (type) { - case 'task': - return this.$L('任务') - case 'project': - return this.$L('项目') - case 'message': - return this.$L('消息') - case 'contact': - return this.$L('联系人') - case 'file': - return this.$L('文件') + const tag = this.tags.find(item => item.type === type); + if (tag) { + return this.$L(tag.name); } return type; }, @@ -238,6 +237,15 @@ export default { } }, + onTag(type, e) { + this.action = this.action !== type ? type : ''; + $A.scrollToView(e.target, { + block: 'nearest', + inline: 'nearest', + behavior: 'smooth' + }) + }, + onShow() { this.showModal = true this.$nextTick(() => { @@ -258,15 +266,48 @@ export default { this.showModal = false }, - onSearch() { - this.searchTask(this.searchKey) - this.searchProject(this.searchKey) - this.searchMessage(this.searchKey) - this.searchContact(this.searchKey) - this.searchFile(this.searchKey) + onEnter() { + this.preSearch(); + $A.eeuiAppKeyboardHide(); }, - pushResults(items) { + preSearch() { + if (!this.searchKey.trim()) { + return; + } + if (this.searchTimer) { + clearTimeout(this.searchTimer) + this.searchTimer = null; + this.loadIng--; + } + this.loadIng++; + this.searchTimer = setTimeout(() => { + if (this.searchKey.trim()) { + this.onSearch() + } + this.searchTimer = null; + this.loadIng--; + }, 500) + }, + + onSearch() { + if (this.action) { + this.distSearch(this.action) + return; + } + this.tags.forEach(({type}) => this.distSearch(type)) + }, + + distSearch(type) { + const func = this[`search${type.charAt(0).toUpperCase()}${type.slice(1)}`] + if (typeof func === 'function') { + func(this.searchKey) + return true + } + return false + }, + + echoSearch(items) { items.forEach(item => { const index = this.searchResults.findIndex(({id, type}) => id === item.id && type === item.type) if (index > -1) { @@ -284,7 +325,7 @@ export default { data: { keys: {name: key}, archived: 'all', - pagesize: 10, + pagesize: this.action ? 50 : 10, }, }).then(({data}) => { const nowTime = $A.dayjs().unix() @@ -320,7 +361,7 @@ export default { rawData: item, }; }); - this.pushResults(items) + this.echoSearch(items) }).finally(_ => { this.loadIng--; }) @@ -335,7 +376,7 @@ export default { name: key }, archived: 'all', - pagesize: 10, + pagesize: this.action ? 50 : 10, }, }).then(({data}) => { const items = data.data.map(item => { @@ -366,7 +407,7 @@ export default { rawData: item, }; }) - this.pushResults(items) + this.echoSearch(items) }).finally(_ => { this.loadIng--; }) @@ -378,7 +419,7 @@ export default { url: 'dialog/msg/esearch', data: { key, - pagesize: 10, + pagesize: this.action ? 50 : 10, }, }).then(({data}) => { const items = data.data.map(item => { @@ -415,7 +456,7 @@ export default { rawData: item, }; }) - this.pushResults(items) + this.echoSearch(items) }).finally(_ => { this.loadIng--; }) @@ -427,7 +468,7 @@ export default { url: 'users/search', data: { keys: {key}, - pagesize: 10, + pagesize: this.action ? 50 : 10, }, }).then(({data}) => { const items = data.map(item => { @@ -445,7 +486,7 @@ export default { rawData: item, }; }) - this.pushResults(items) + this.echoSearch(items) }).finally(_ => { this.loadIng--; }) @@ -455,7 +496,10 @@ export default { this.loadIng++; this.$store.dispatch("call", { url: 'file/search', - data: {key}, + data: { + key, + take: this.action ? 50 : 10, + }, }).then(({data}) => { const items = data.map(item => { const tags = []; @@ -479,7 +523,7 @@ export default { rawData: item, }; }) - this.pushResults(items) + this.echoSearch(items) }).finally(_ => { this.loadIng--; }) diff --git a/resources/assets/sass/components/search-box.scss b/resources/assets/sass/components/search-box.scss index d72a6c1d8..1088fd74a 100755 --- a/resources/assets/sass/components/search-box.scss +++ b/resources/assets/sass/components/search-box.scss @@ -98,13 +98,52 @@ flex-direction: column; border-top: 1px solid #f0f0f0; + .search-tags { + flex-shrink: 0; + display: flex; + gap: 12px; + overflow-x: auto; + overflow-y: hidden; + scroll-behavior: smooth; + -webkit-overflow-scrolling: touch; + padding: 16px 20px 0; + + &::-webkit-scrollbar { + display: none; + } + + .tag-item { + flex-shrink: 0; + border: 1px solid #d5d5d5; + border-radius: 8px; + padding: 3px 12px; + line-height: 24px; + display: flex; + align-items: center; + justify-content: center; + gap: 8px; + cursor: pointer; + transition: all 0.2s ease; + + .tag-close { + font-size: 13px; + } + + &.action { + background-color: #8bcf70; + border-color: #8bcf70; + color: #fff; + } + } + } + .search-empty { - height: 248px; + height: 268px; display: flex; align-items: center; justify-content: center; flex-direction: column; - padding: 24px; + padding: 16px 24px 48px; > i { font-size: 44px; @@ -128,11 +167,11 @@ .search-list { overflow: auto; - max-height: calc(100vh - 255px); + max-height: calc(100vh - 305px); overscroll-behavior: contain; @media (max-height: 900px) { - max-height: calc(100vh - 125px); + max-height: calc(100vh - 175px); } > ul { @@ -151,7 +190,7 @@ } &.item-label { - padding: 8px 10px; + padding: 8px 12px; position: sticky; top: 0; z-index: 9; @@ -173,6 +212,7 @@ .file-icon { display: flex; + &:before { width: 100%; height: 100%; diff --git a/resources/assets/sass/dark.scss b/resources/assets/sass/dark.scss index 05520db82..f1f3206bd 100644 --- a/resources/assets/sass/dark.scss +++ b/resources/assets/sass/dark.scss @@ -635,6 +635,14 @@ body.dark-mode-reverse { .search-body { border-top-color: #e9e9e9; + .search-tags { + .tag-item { + &.action { + color: #000; + } + } + } + .search-list { ul { > li {