Initial commit of akmon project
This commit is contained in:
303
pages/admins/user-management.uvue
Normal file
303
pages/admins/user-management.uvue
Normal file
@@ -0,0 +1,303 @@
|
||||
<template>
|
||||
<view class="user-management-page">
|
||||
<text class="page-title">{{ $t('user_mgmt.title') }}</text>
|
||||
<view class="search-bar">
|
||||
<input class="searchinput" type="text" v-model="searchQuery" placeholder="Search users..." />
|
||||
<button class="searchbutton" @click="searchUsers">{{ $t('common.search') }}</button>
|
||||
</view>
|
||||
<supadb
|
||||
ref="userdb"
|
||||
:collection="'ak_users'"
|
||||
:field="'*'"
|
||||
:filter="where"
|
||||
:orderby="'id.desc'"
|
||||
:page-size="pageSize"
|
||||
:page-current="pageCurrent"
|
||||
getcount="exact"
|
||||
loadtime="manual"
|
||||
v-slot:default="{ data, pagination, loading, current, total, error }"
|
||||
@load="onUserLoad"
|
||||
>
|
||||
<view v-if="loading">{{ $t('common.loading') }}</view>
|
||||
<view v-else-if="error">{{ error }}</view>
|
||||
<view v-else>
|
||||
<!-- Large Screen Layout (Table) -->
|
||||
<view class="table-view">
|
||||
<view class="table-header">
|
||||
<text>{{ $t('user.username') }}</text>
|
||||
<text>{{ $t('user.email') }}</text>
|
||||
<text>{{ $t('user.role') }}</text>
|
||||
<text>{{ $t('user.created_at') }}</text>
|
||||
<text>{{ $t('common.action') }}</text>
|
||||
</view>
|
||||
<view v-for="(user, idx) in (data as Array<UTSJSONObject>)" :key="user.get('id')" :class="['table-row', idx % 2 === 0 ? 'row-even' : 'row-odd']">
|
||||
<text>{{ user.get('username') }}</text>
|
||||
<text>{{ user.get('email') }}</text>
|
||||
<text>{{ user.get('role') }}</text>
|
||||
<text>{{ user.get('created_at') }}</text>
|
||||
<view class="action-buttons">
|
||||
<button @click="editUser(user)">{{ $t('common.edit') }}</button>
|
||||
<button @click="deleteUser(user)">{{ $t('common.delete') }}</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- Small Screen Layout (Cards) -->
|
||||
<view class="card-view">
|
||||
<view v-for="(user, idx) in (data as Array<UTSJSONObject>)" :key="user.get('id')" :class="['user-card', idx % 2 === 0 ? 'row-even' : 'row-odd']">
|
||||
<view class="card-row">
|
||||
<text class="card-label">{{ $t('user.username') }}:</text>
|
||||
<text class="card-value">{{ user.get('username') }}</text>
|
||||
</view>
|
||||
<view class="card-row">
|
||||
<text class="card-label">{{ $t('user.email') }}:</text>
|
||||
<text class="card-value">{{ user.get('email') }}</text>
|
||||
</view>
|
||||
<view class="card-row">
|
||||
<text class="card-label">{{ $t('user.role') }}:</text>
|
||||
<text class="card-value">{{ user.get('role') }}</text>
|
||||
</view>
|
||||
<view class="card-row">
|
||||
<text class="card-label">{{ $t('user.created_at') }}:</text>
|
||||
<text class="card-value">{{ user.get('created_at') }}</text>
|
||||
</view>
|
||||
<view class="card-actions">
|
||||
<button @click="editUser(user)">{{ $t('common.edit') }}</button>
|
||||
<button @click="deleteUser(user)">{{ $t('common.delete') }}</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="pagination">
|
||||
<button @click="prevPage(pagination!!)">{{ $t('common.prev') }}</button>
|
||||
<text>{{ current}}/{{ total }}</text>
|
||||
<button @click="nextPage(pagination!!)">{{ $t('common.next') }}</button>
|
||||
<button v-if="hasMoreData" @click="continueIteration()">{{ $t('common.continueToIterate') }}</button>
|
||||
</view>
|
||||
</view>
|
||||
</supadb>
|
||||
<!-- 编辑/新增弹窗等可后续补充 -->
|
||||
</view>
|
||||
</template>
|
||||
<script lang="uts">
|
||||
import supa from '@/components/supadb/aksupainstance.uts';
|
||||
|
||||
|
||||
export default {
|
||||
name: 'UserManagement',
|
||||
data() {
|
||||
return {
|
||||
supadb: null as SupadbComponentPublicInstance | null,
|
||||
where: {},
|
||||
pageSize: 10,
|
||||
pageCurrent: 1,
|
||||
searchQuery: '',
|
||||
screenWidth: uni.getSystemInfoSync().windowWidth,
|
||||
hasMoreData: false
|
||||
}
|
||||
},
|
||||
onReady() {
|
||||
this.supadb = this.$refs["userdb"] as SupadbComponentPublicInstance;
|
||||
// supa.from('system_dept').select(*).or('"name.like.%20%,email.like.%202%");
|
||||
this.supadb?.loadData?.({ clear: false })
|
||||
|
||||
},
|
||||
methods: {
|
||||
onUserLoad(data: any[]) {
|
||||
// 可处理数<E79086>?
|
||||
this.hasMoreData = data.length === this.pageSize;
|
||||
},
|
||||
async prevPage(pagination: any) {
|
||||
this.pageCurrent--;
|
||||
await nextTick();
|
||||
this.supadb?.loadData?.({ clear: false })
|
||||
},
|
||||
async nextPage(pagination: any) {
|
||||
this.pageCurrent++;
|
||||
await nextTick();
|
||||
this.supadb?.loadData?.({ clear: false })
|
||||
},
|
||||
editUser(user: UTSJSONObject) {
|
||||
// 编辑逻辑
|
||||
console.log(user)
|
||||
uni.navigateTo({
|
||||
url:'/pages/admins/users/detail?id='+ user.getString("id")
|
||||
})
|
||||
},
|
||||
deleteUser(user: any) {
|
||||
// 删除逻辑
|
||||
},
|
||||
async searchUsers() {
|
||||
// Implement search logic
|
||||
if (this.searchQuery!=null) {
|
||||
// this.where = {
|
||||
// text: this.searchQuery,
|
||||
// column: ['username', 'email', 'role']
|
||||
// };
|
||||
// this.where = { email: { ilike: '%'+this.searchQuery+'%' }} as UTSJSONObject
|
||||
this.where ={ or:"username.like.%"+this.searchQuery+"%,email.like.%"+this.searchQuery+"%"}
|
||||
} else {
|
||||
this.where = {};
|
||||
}
|
||||
console.log(this.where)
|
||||
this.pageCurrent = 1;
|
||||
await nextTick();
|
||||
this.supadb?.loadData?.({ clear: true });
|
||||
},
|
||||
async continueIteration() {
|
||||
this.pageCurrent++;
|
||||
await nextTick();
|
||||
this.supadb?.loadData?.({ clear: false })
|
||||
}
|
||||
},
|
||||
onResize(size) {
|
||||
// 这里处理页面尺寸变化
|
||||
this.screenWidth = size.size.windowWidth;
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.user-management-page {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
display: flex;
|
||||
margin-bottom: 16px;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
/* Table View (Large Screens) */
|
||||
.table-view {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.table-header, .table-row {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.table-header {
|
||||
font-weight: bold;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.table-header text, .table-row text {
|
||||
flex: 1;
|
||||
padding: 8px 4px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.table-row {
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 8px 0;
|
||||
}
|
||||
|
||||
.table-row:nth-child(even) {
|
||||
background-color: #f7f7fa;
|
||||
}
|
||||
.table-row:nth-child(odd) {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.action-buttons {
|
||||
display: flex;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
/* Card View (Small Screens) */
|
||||
.card-view {
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.user-card {
|
||||
border: 1px solid #eee;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.user-card:nth-child(even) {
|
||||
background-color: #f7f7fa;
|
||||
}
|
||||
.user-card:nth-child(odd) {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.card-row {
|
||||
display: flex;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.card-label {
|
||||
font-weight: bold;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.card-value {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.card-actions {
|
||||
display: flex;
|
||||
padding: 8px;
|
||||
margin-top: 12px;
|
||||
/* justify-content: flex-end; */
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 16px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* Responsive Design */
|
||||
@media screen and (max-width: 768px) {
|
||||
.table-view {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.card-view {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
flex-direction: row;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 769px) {
|
||||
.table-view {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.card-view {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.row-even { background-color: #f7f7fa; }
|
||||
.row-odd { background-color: #fff; }
|
||||
.searchbutton{
|
||||
width:200rpx;
|
||||
height:80rpx;
|
||||
}
|
||||
.searchinput{
|
||||
flex:1;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user