Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
R
rrpgLink_FrontEnd
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kesaubeeire
rrpgLink_FrontEnd
Commits
c9770aed
Commit
c9770aed
authored
Oct 23, 2023
by
KesaubeEire
Browse files
Options
Browse Files
Download
Plain Diff
edit & Merge commit '
0e55277f
'
parents
ab4fe607
0e55277f
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
205 additions
and
71 deletions
+205
-71
.gitignore
.gitignore
+5
-1
README.md
README.md
+12
-5
src/Content.svelte
src/Content.svelte
+161
-64
src/utils/index.js
src/utils/index.js
+24
-0
vite.config.js
vite.config.js
+3
-1
No files found.
.gitignore
View file @
c9770aed
...
...
@@ -15,8 +15,12 @@ dist-ssr
# 自定义文件夹
# -- 后端示例文件
backEndExample
#生成&推送脚本
# 自定义文件
# 生成 & 推送脚本
build-prod.bat
# 开发服务器代理配置
devServer.config.js
# Editor directories and files
.vscode/*
...
...
README.md
View file @
c9770aed
...
...
@@ -19,15 +19,21 @@ Svelte + daysiUI
## 开发
```
JavaScript
// 在 dev 模式下开发要在根目录(vite.config.js 同级目录)中
// 新建 devServer.config.js
// 改进下面的代码并复制粘贴到这个文件里
// 这个文件子在 .gitignore 中被忽略
// 可以在这里复制名称再新建文件, 不要忘记这步, 非常关键
// 单独提出来的目的是不让开发受这个代理服务器路径变更的影响
export const proxy = "http://192.168.31.103:25702";
```
```
bash
# 安装
npm
install
# 在 dev 模式下开发要在 vite.config.js 中
# 把 server -> proxy -> /api/ 中的 target
# 改为你能在本地浏览器访问到的 rrpg.duels.link 的网址
# 毕竟我是开了 NGINX 转发开发的, 比较迂回
# 这是 dev 模式开发
npm run dev:dev
...
...
@@ -58,6 +64,7 @@ npm run build:prod
-
[ ] 定时更新
-
[ ] 卡片展示
-
[x] 请求 php
-
[x] 瀑布流
-
[x] 展示基础卡片
-
[x] 图片
-
[x] 点击 Cover 预览所有图片
...
...
src/Content.svelte
View file @
c9770aed
...
...
@@ -3,6 +3,33 @@
import { SvelteToast, toast } from '@zerodevx/svelte-toast';
import { _category, _detailWindow, _env, _tagTrans, _detailPics } from './stores';
import { fade } from 'svelte/transition';
import { debounceImmediate } from './utils';
/**开发模式下 console.log debug 函数
* @param str
*/
function debugMessage() {
if (process.env.APP_ENV === 'dev') console.log(...str);
}
// -----------------------------
// page & 搜索相关
/**NextPage 指示瀑布流下次应请求的页码数*/
let nextPage = 1;
/**NextPage 指示瀑布流下次应请求的limit数*/
let globalPageLimit = 20;
/**瀑布流是否请求中, 为 true 时不能重复请求*/
let isSearching = false;
/**若isEnd(已经没有新的结果了)则暂停瀑布流请求*/
let isEnd = false;
/**上次搜索完整参数*/
let lastSearchURL;
/**上次搜索类型*/
let lastSearchType = '';
/**上次搜索请求头封装对象*/
let lastSearchParam = null;
// -----------------------------
// 各种请求封装头 & 请求函数
...
...
@@ -20,9 +47,11 @@
};
/**请求封装头 -> 获取所有资料*/
const getContentsRequest = {
url: `${$_env}/query.php?action=get`,
params: { method: 'GET' }
const getContentsRequest = () => {
return {
url: `${$_env}/query.php?action=get&limit=${globalPageLimit}&page=${nextPage}`,
params: { method: 'GET' }
};
};
/**请求封装头 -> 搜索对应 Tag (函数形式)
...
...
@@ -31,7 +60,7 @@
*/
const searchTagRequest = tag => {
return {
url: `${$_env}/query.php?action=get&tag=${encodeURIComponent(tag)}`,
url: `${$_env}/query.php?action=get&
limit=${globalPageLimit}&page=${nextPage}&
tag=${encodeURIComponent(tag)}`,
params: { method: 'GET' }
};
};
...
...
@@ -42,7 +71,7 @@
*/
const searchCategoryRequest = category => {
return {
url: `${$_env}/query.php?action=get&category=${category}`,
url: `${$_env}/query.php?action=get&
limit=${globalPageLimit}&page=${nextPage}&
category=${category}`,
params: { method: 'GET' }
};
};
...
...
@@ -53,12 +82,11 @@
*/
const searchTextRequest = text => {
return {
url: `${$_env}/query.php?action=get&search=${encodeURIComponent(text)}`,
url: `${$_env}/query.php?action=get&
limit=${globalPageLimit}&page=${nextPage}&
search=${encodeURIComponent(text)}`,
params: { method: 'GET' }
};
};
let lastSearchURL;
/**创建请求 fetch 函数
* @param {object} param0 参数对象
* @param {function} callback 回调函数
...
...
@@ -76,7 +104,9 @@
if (params.headers) msg.headers = params.headers;
if (lastSearchURL == url) {
toast.push('搜索参数重复捏~');
isSearching = false;
if (!isEnd) toast.push('搜索参数重复捏~');
if (process.env.APP_ENV === 'dev') console.log(lastSearchURL, url);
return;
}
lastSearchURL = url;
...
...
@@ -85,10 +115,6 @@
.then(response => response.json())
.then(data => {
// console.log(data);
if (!data.length) {
toast.push('没有搜索到东西捏~');
return;
}
// 处理数据
callback(data);
...
...
@@ -97,6 +123,9 @@
// 处理错误
console.error('网络请求错误:', error);
toast.push('网络请求错误');
})
.finally(() => {
isSearching = false;
});
}
...
...
@@ -106,7 +135,7 @@
/**渲染数据列表*/
let List = [];
/**
渲染 & 更新视图
/**
更新视图 -> 替换元素
* @param data JSON数据
*/
function showList(data) {
...
...
@@ -116,47 +145,94 @@
// <!-- FIXME: 暂时以这种略微丑陋的方式做切换动画, 可能这就是唯一方案了 -->
setTimeout(() => {
List = [...data];
window.scrollTo(0, 0);
}, 400);
}
/**
根据 TAG 搜索游戏
* @param
{string} tag TAG
/**
更新视图 -> 增加元素 -> 瀑布流
* @param
data JSON数据
*/
export function searchTag(tag) {
if (process.env.APP_ENV === 'dev') console.log(tag, encodeURIComponent(tag));
createFetch(searchTagRequest(tag), data => {
function appendList(data) {
List = [...List, ...data];
}
/**瀑布流: 延续参数继续搜索下一页*/
function continueLastSearch() {
performSearch(lastSearchType, lastSearchParam, globalPageLimit, nextPage);
}
/**执行搜索主函数
* @param searchType
* @param searchParam
* @param limit
* @param page
*/
function performSearch(searchType, searchParam, limit = 20, page = 1) {
// 瀑布流请求中不能重复请求
if (isSearching) {
return;
}
isSearching = true;
globalPageLimit = limit;
nextPage = page;
lastSearchType = searchType;
lastSearchParam = searchParam;
let requestType;
switch (searchType) {
case 'category':
requestType = searchCategoryRequest;
break;
case 'tag':
requestType = searchTagRequest;
break;
case 'title':
requestType = searchTextRequest;
break;
default:
requestType = getContentsRequest;
break;
}
if (process.env.APP_ENV === 'dev') console.log(requestType(searchParam));
createFetch(requestType(searchParam), data => {
if (process.env.APP_ENV === 'dev') console.log(data);
showList(data);
page == 1 ? showList(data) : appendList(data);
if (data.length < globalPageLimit) {
console.log(data.length);
isEnd = true;
toast.push('没有更多数据了捏~');
return;
}
nextPage++;
// console.log(nextPage);
});
}
/**根据 TAG 搜索游戏
* @param {string} tag TAG
*/
export function searchTag(tag, limit = globalPageLimit, page = 1) {
console.log(tag);
performSearch('tag', tag, limit, page);
}
/**根据 category 搜索游戏
* @param {string} category category
*/
export function searchCategory(category) {
if (process.env.APP_ENV === 'dev') console.log(category);
createFetch(searchCategoryRequest(category), data => {
if (process.env.APP_ENV === 'dev') console.log(data);
showList(data);
});
export function searchCategory(category, limit = globalPageLimit, page = 1) {
performSearch('category', category, limit, page);
}
/**@var {string} 上次搜索内容*/
let lastSearch;
/**根据 title 搜索游戏
* @param {string} title 名称
*/
export function searchTitle(title) {
if (title === lastSearch) {
toast.push('搜索名称重复捏~');
return;
}
lastSearch = title;
if (process.env.APP_ENV === 'dev') console.log('执行搜索:\t', title);
createFetch(searchTextRequest(title), data => {
if (process.env.APP_ENV === 'dev') console.log(data);
showList(data);
});
export function searchTitle(title, limit = globalPageLimit, page = 1) {
performSearch('title', title, limit, page);
}
window.searchTitle = searchTitle;
...
...
@@ -164,11 +240,8 @@
* 默认搜索 -> 暂时是全部搜索
* TODO: 全局内容 30分钟 一次缓存在 localstorage 里
*/
export function searchDefault() {
createFetch(getContentsRequest, data => {
if (process.env.APP_ENV === 'dev') console.log(data);
showList(data);
});
export function searchDefault(limit = globalPageLimit, page = 1) {
performSearch('', '', limit, page);
}
/**获取封面图
...
...
@@ -186,17 +259,6 @@
return $_env + '/' + folder.substring(2);
}
// -----------------------------
/**关闭详情*/
function key_closePanels(event) {
if (event.key === 'Escape') {
console.log(event);
// $_iframe_switch = 0;
// $_show_configPanel = false;
$_detailWindow = false;
}
}
// -----------------------------
// NOTE: 初始化执行 -> 考虑用 onMount
// 初始化请求 -> 拉取所有分类
...
...
@@ -205,6 +267,12 @@
createFetch(getLanguageCategory, data => {
if (process.env.APP_ENV === 'dev') console.log(data);
$_category = data;
if (!data.length) {
toast.push('分类拉取失败了捏~');
} else {
toast.push('分类拉取成功~');
}
});
}
...
...
@@ -214,26 +282,50 @@
createFetch(getTranslatedTag, data => {
if (process.env.APP_ENV === 'dev') console.log(data);
$_tagTrans = data;
if (!data.length) {
toast.push('标签拉取失败了捏~');
} else {
toast.push('标签拉取成功~');
}
});
}
/**对加载下一页进行防抖*/
let debouncedContinue = debounceImmediate(continueLastSearch, 1000);
//拉动到页面底部则更新数据
window.addEventListener('scroll', () => {
let scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
let clientHeight = document.documentElement.clientHeight || document.body.clientHeight;
let scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
if (clientHeight > 0 && scrollTop > 0 && scrollTop + clientHeight > scrollHeight - 10.0) {
// 加载下一页: page + 1 重复上次搜
// continueLastSearch();
debouncedContinue();
}
});
// 初始化请求 -> 拉取全部条目
searchDefault();
</script>
<!-- ----------------------------------------------- DOM ----------------------------------------------- -->
<!-- NOTE: svelte 绑定 window -> 关闭详情面板 -->
<svelte:window on:keydown|capture={key_closePanels} />
<!-- Open the modal using ID.showModal() method -->
<!-- <button class="btn" onclick="globalModal.showModal()">open modal</button> -->
{#if $_detailWindow}
<dialog id="globalModal" class="modal">
<div class="globalModal max-[1024px]:w-[98vw] max-[1024px]:max-w-[98vw]" transition:fade={{ delay: 200, duration: 1000 }}>
<dialog id="globalModal" class="modal focus:outline-none">
{#if $_detailWindow}
<div class="globalModal max-[1024px]:w-[98vw] max-[1024px]:max-w-[98vw]" transition:fade={{ delay: 0, duration: 500 }}>
<!-- NOTE: 按钮退出详情 -->
<form method="dialog">
<button class="btn btn-sm round-box btn-ghost absolute right-2 top-2">✕</button>
<button
on:click={() => {
$_detailWindow = false;
}}
class="btn btn-sm round-box btn-ghost absolute right-2 top-2">✕</button
>
</form>
<!-- NOTE: Transition -->
{#if $_detailPics.length}
...
...
@@ -259,11 +351,16 @@
</div>
{/if}
</div>
<!-- NOTE: 边框退出详情 -->
<form method="dialog" class="modal-backdrop">
<button>close</button>
<button
on:click={() => {
$_detailWindow = false;
}}
/>
</form>
</dialog>
{/if}
{/if}
</dialog>
{#if List.length}
<div class="cardContainer flex flex-wrap justify-evenly gap-4 my-3" transition:fade={{ delay: 0, duration: 300 }}>
...
...
src/utils/index.js
View file @
c9770aed
/** 防抖函数 -> 立即执行
* @param {function} func 操作函数
* @param {number} delay 延迟
* @returns
*/
export
function
debounceImmediate
(
func
,
delay
)
{
let
timeout
;
return
function
()
{
const
immediate
=
!
timeout
;
if
(
timeout
)
{
clearTimeout
(
timeout
);
}
timeout
=
setTimeout
(()
=>
{
// func.apply(this, arguments);
timeout
=
null
;
},
delay
);
if
(
immediate
)
{
func
.
apply
(
this
,
arguments
);
}
};
}
\ No newline at end of file
vite.config.js
View file @
c9770aed
import
{
defineConfig
}
from
'
vite
'
;
import
{
svelte
}
from
'
@sveltejs/vite-plugin-svelte
'
;
import
{
proxy
}
from
'
./devServer.config
'
import
SetEnvByCommandArg
,
{
getCommandArgv
}
from
'
vite-plugin-env-command
'
;
...
...
@@ -16,7 +17,8 @@ export default defineConfig({
server
:
{
proxy
:
{
"
/api/
"
:
{
target
:
"
http://192.168.31.103:25702
"
,
// NOTE: 在 ./devServer.config.js 文件把 proxy 后的 ip 改为你的浏览器内能访问到 rrpg.duels.link 的链接
target
:
proxy
,
changeOrigin
:
true
,
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
api/
,
""
),
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment