Merge pull request 'feature/login-screen' (#5) from feature/login-screen into master
Reviewed-on: #5
This commit is contained in:
commit
0ceda90d0f
Binary file not shown.
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
@ -1,7 +1,7 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { logoutUser } from '../utils/jwt'; // logoutUser会处理清除存储和重定向
|
import { logoutUser } from '../utils/jwt'; // logoutUser会处理清除存储和重定向
|
||||||
|
|
||||||
const API_BASE_URL = 'https://zybdatasupport.online';
|
const API_BASE_URL = 'https://api.zybdatasupport.online';
|
||||||
|
|
||||||
const axiosInstance = axios.create({
|
const axiosInstance = axios.create({
|
||||||
baseURL: API_BASE_URL,
|
baseURL: API_BASE_URL,
|
||||||
|
BIN
src/assets/logo.png
Normal file
BIN
src/assets/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 12 KiB |
@ -209,6 +209,12 @@ const showCompetitionMenu = computed(() => showCompetition.value)
|
|||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
</main>
|
</main>
|
||||||
<footer class="footer">
|
<footer class="footer">
|
||||||
|
<div class="footer-top">
|
||||||
|
<div class="footer-brand">
|
||||||
|
<img src="../assets/logo.png" class="footer-logo">
|
||||||
|
<span class="footer-title">红色警戒3数据分析中心</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="footer-bottom">
|
<div class="footer-bottom">
|
||||||
<p>Byz解忧杂货铺</p>
|
<p>Byz解忧杂货铺</p>
|
||||||
<p class="beian">
|
<p class="beian">
|
||||||
@ -682,4 +688,39 @@ const showCompetitionMenu = computed(() => showCompetition.value)
|
|||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.footer-top {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-brand {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
background: none;
|
||||||
|
padding: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-logo {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: none;
|
||||||
|
object-fit: contain;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-title {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #fff;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -18,6 +18,7 @@
|
|||||||
<th>请求内容</th>
|
<th>请求内容</th>
|
||||||
<th>悬赏金额</th>
|
<th>悬赏金额</th>
|
||||||
<th>需求创建时间</th>
|
<th>需求创建时间</th>
|
||||||
|
<th>回复数量</th>
|
||||||
<th>回复</th>
|
<th>回复</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
@ -38,6 +39,11 @@
|
|||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td class="date">{{ formatDate(demand.date) }}</td>
|
<td class="date">{{ formatDate(demand.date) }}</td>
|
||||||
|
<td class="reply-count">
|
||||||
|
<span :class="['tag', getReplyCount(demand) > 0 ? 'has-replies' : 'no-reward']">
|
||||||
|
{{ getReplyCount(demand) }}
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn-common btn-gradient btn-reply" @click.stop="showReply(demand)">回复</button>
|
<button class="btn-common btn-gradient btn-reply" @click.stop="showReply(demand)">回复</button>
|
||||||
</td>
|
</td>
|
||||||
@ -321,6 +327,18 @@ const filteredDemands = computed(() => {
|
|||||||
return demands.value.filter(demand => !demand.content?.startsWith('&DEL'))
|
return demands.value.filter(demand => !demand.content?.startsWith('&DEL'))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const getReplyCount = (demand) => {
|
||||||
|
// 优先用 replies 字段
|
||||||
|
if (demand.replies && Array.isArray(demand.replies)) {
|
||||||
|
return demand.replies.length;
|
||||||
|
}
|
||||||
|
// 兼容旧的 sendcontent 字段
|
||||||
|
if (demand.sendcontent && typeof demand.sendcontent === 'string' && demand.sendcontent.trim() !== '') {
|
||||||
|
return demand.sendcontent.split('|').filter(reply => reply.trim() !== '').length;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// 格式化日期
|
// 格式化日期
|
||||||
const formatDate = (dateString) => {
|
const formatDate = (dateString) => {
|
||||||
if (!dateString || dateString === 'Test_date') return '日期未提供'
|
if (!dateString || dateString === 'Test_date') return '日期未提供'
|
||||||
@ -718,7 +736,14 @@ const onRefresh = () => {
|
|||||||
border: 1px solid #d9d9d9;
|
border: 1px solid #d9d9d9;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.has-replies {
|
||||||
|
background: #e3f0ff;
|
||||||
|
color: #1d4ed8;
|
||||||
|
border: 1px solid #b6d2ff;
|
||||||
|
}
|
||||||
|
|
||||||
.maps-table td.reward,
|
.maps-table td.reward,
|
||||||
|
.maps-table td.reply-count,
|
||||||
.maps-table tr {
|
.maps-table tr {
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
filter: none !important;
|
filter: none !important;
|
||||||
@ -810,7 +835,8 @@ const onRefresh = () => {
|
|||||||
padding: 12px 8px;
|
padding: 12px 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.maps-table td.reward {
|
.maps-table td.reward,
|
||||||
|
.maps-table td.reply-count {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="filters-row">
|
<div class="filters-row">
|
||||||
<div class="filters">
|
<div class="filters">
|
||||||
<div class="search-box">
|
<div class="search-box sticky-search-box">
|
||||||
<span class="search-label">搜索:</span>
|
<span class="search-label">搜索:</span>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@ -332,6 +332,29 @@ const scrollToTop = () => {
|
|||||||
window.scrollTo({ top: 0, behavior: 'smooth' })
|
window.scrollTo({ top: 0, behavior: 'smooth' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let searchBoxEl = null
|
||||||
|
const tabBarHeight = 56 // 按实际tab栏高度调整
|
||||||
|
|
||||||
|
const stickyStyles = {
|
||||||
|
position: 'fixed',
|
||||||
|
top: tabBarHeight + 'px',
|
||||||
|
left: '50%',
|
||||||
|
transform: 'translateX(-50%)',
|
||||||
|
zIndex: 2001,
|
||||||
|
width: '92vw',
|
||||||
|
maxWidth: '98vw',
|
||||||
|
boxShadow: '0 2px 12px rgba(37,99,235,0.13)'
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleStickySearchBox() {
|
||||||
|
if (!searchBoxEl) return
|
||||||
|
if (window.innerWidth <= 700 && window.scrollY > tabBarHeight) {
|
||||||
|
Object.entries(stickyStyles).forEach(([k, v]) => (searchBoxEl.style[k] = v))
|
||||||
|
} else {
|
||||||
|
Object.keys(stickyStyles).forEach(k => (searchBoxEl.style[k] = ''))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 恢复保存的状态
|
// 恢复保存的状态
|
||||||
const savedState = sessionStorage.getItem('maps_state')
|
const savedState = sessionStorage.getItem('maps_state')
|
||||||
@ -360,9 +383,13 @@ onMounted(() => {
|
|||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
isMobile.value = window.innerWidth <= 700
|
isMobile.value = window.innerWidth <= 700
|
||||||
})
|
})
|
||||||
|
searchBoxEl = document.querySelector('.sticky-search-box')
|
||||||
|
window.addEventListener('scroll', handleStickySearchBox)
|
||||||
|
window.addEventListener('resize', handleStickySearchBox)
|
||||||
})
|
})
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
window.removeEventListener('scroll', handleScroll)
|
window.removeEventListener('scroll', handleScroll)
|
||||||
|
window.removeEventListener('resize', handleStickySearchBox)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -590,13 +617,26 @@ onUnmounted(() => {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.search-box {
|
.search-box {
|
||||||
width: 100%;
|
/* 移除 position: fixed 相关样式,交由JS控制 */
|
||||||
margin-bottom: 0;
|
/* position: fixed; */
|
||||||
|
/* top: 0; */
|
||||||
|
/* left: 50%; */
|
||||||
|
/* transform: translateX(-50%); */
|
||||||
|
/* z-index: 2001; */
|
||||||
|
/* width: 92vw; */
|
||||||
|
/* max-width: 98vw; */
|
||||||
|
/* box-shadow: 0 2px 12px rgba(37,99,235,0.13); */
|
||||||
}
|
}
|
||||||
.search-input {
|
.search-input {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
padding-top: 70px;
|
||||||
}
|
}
|
||||||
.filter-select {
|
.filter-select {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -74,7 +74,7 @@
|
|||||||
error: null,
|
error: null,
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
itemsPerPage: 100,
|
itemsPerPage: 100,
|
||||||
apiBaseUrl: 'https://zybdatasupport.online',
|
apiBaseUrl: 'https://api.zybdatasupport.online',
|
||||||
categoryList: [],
|
categoryList: [],
|
||||||
selectedCategory: '全部',
|
selectedCategory: '全部',
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user