Pārlūkot izejas kodu

新增用户管理界面,新增用户管理查询,删除功能

zhangxike 1 nedēļu atpakaļ
vecāks
revīzija
79e749445f

+ 4 - 4
api/login.uts

@@ -1,5 +1,5 @@
 import request from '@/utils/request'
-import { getToken, removeToken, getCurrentUserSync } from '@/utils/auth';
+import { getToken, removeToken, getCurrentUserNameSync } from '@/utils/auth';
 // #ifdef APP-ANDROID
 import {selectTableData, insertTableData} from '@/utils/sqlite'
 // #endif
@@ -76,7 +76,7 @@ export function register(data:RegForm):Promise<UTSJSONObject> {
   }) */
   // #ifdef APP-ANDROID
 	let condition = 'username,name,password,role,status,createtime,updatetime'
-	let date = "strftime('%Y-%m-%d %H:%M:%S', 'now')"
+	let date = "strftime('%Y-%m-%d %H:%M:%S', 'now', 'localtime')"
 	let dataStr = `'${data.username}','${data.name}','${data.password}','user',1, ${date}, ${date}`;  
 	console.log(dataStr)
 	const result = insertTableData('app_user', dataStr, condition);
@@ -107,8 +107,8 @@ export function getInfo():Promise<UTSJSONObject> {
   } as UTSJSONObject
       
 	// #ifdef APP-ANDROID
-	console.log('getCurrentUserSync', getCurrentUserSync())
-	const result = selectTableData('app_user', 'username', getCurrentUserSync(), null, null);
+	console.log('getCurrentUserNameSync', getCurrentUserNameSync())
+	const result = selectTableData('app_user', 'username', getCurrentUserNameSync(), null, null);
 	console.log(result);
 	return result;
   // #endif

+ 9 - 4
api/work.uts

@@ -358,6 +358,9 @@ export async function removeTableData(tableName : string, field : string, value
 	// #ifdef APP-ANDROID
 
 	try {
+		if (value == null || value == '') {
+			return { errMsg: '删除失败', data: [] as any[] } as UTSJSONObject;
+		}
 		// 调用sqlite的删除方法
 		const result = await deleteTableData(tableName, field, value);
 		console.log('删除数据成功:', result);
@@ -382,7 +385,7 @@ export async function removeInfoAndRecord(value : string) : Promise<UTSJSONObjec
 	try {
 		// 调用sqlite的删除方法
 		const result = await deleteTableData('app_media_record', 'pid', value);
-		addLog({ module: 'app_media_record', dataid: 1, content: '删除数据成功', status: 1, params: value, updatetime: "strftime('%Y-%m-%d %H:%M:%S', 'now')" })
+		addLog({ module: 'app_media_record', dataid: 1, content: '删除数据成功', status: 1, params: value, updatetime: "strftime('%Y-%m-%d %H:%M:%S', 'now', 'localtime')" })
 
 		const result2 = await deleteTableData('app_media_info', 'pdid', value);
 		addLog({ module: 'app_media_info', dataid: 1, content: '删除数据成功', status: 1, params: value })
@@ -408,10 +411,10 @@ export async function addLog(data ?: UTSJSONObject | null) : Promise<UTSJSONObje
 	let values = `'${data?.getString('module') ?? ''}',${data?.getNumber('dataid') ?? 0},'${data?.getString('content') ?? ''}',${data?.getNumber('status') ?? 0},'${params}'`;
 	if (dataid === 0) {
 		fields = fields + ",createuser,createtime"
-		values = values + `,'${data?.getString('createuser') ?? 0}',strftime('%Y-%m-%d %H:%M:%S', 'now')`
+		values = values + `,'${data?.getString('createuser') ?? 0}',strftime('%Y-%m-%d %H:%M:%S', 'now', 'localtime')`
 	} else {
 		fields = fields + ",updateuser,updatetime"
-		values = values + `,'${data?.getString('updateuser') ?? 0}',strftime('%Y-%m-%d %H:%M:%S', 'now')`
+		values = values + `,'${data?.getString('updateuser') ?? 0}',strftime('%Y-%m-%d %H:%M:%S', 'now', 'localtime')`
 	}
 
 	const result = await insertTableData(tableName, values, fields);
@@ -670,4 +673,6 @@ export async function selectPageSql(tableName : string, order : string, num : nu
 	// #ifdef H5
 	return offlineData(initData)
 	// #endif
-}
+}
+
+

+ 15 - 1
pages.json

@@ -76,7 +76,7 @@
         {
             "path" : "pages/mine/index",
             "style" : {
-                "navigationBarTitleText" : "我的"
+                "navigationBarTitleText" : "用户管理"
             }
         },
         {
@@ -177,6 +177,20 @@
 			{
 				"navigationBarTitleText" : "日志详情"
 			}
+		},
+		{
+			"path" : "pages/mine/person/PersonList",
+			"style" : 
+			{
+				"navigationBarTitleText" : "用户列表"
+			}
+		},
+		{
+			"path" : "pages/mine/person/PersonDetail",
+			"style" : 
+			{
+				"navigationBarTitleText" : "用户信息"
+			}
 		}
     ],
     "tabBar" : {

+ 27 - 15
pages/mine/index.uvue

@@ -13,6 +13,11 @@
 			</view>
 		</view>
 	</view>
+	<view>
+		<view class = "name-label">
+			您好:{{currentName}}
+		</view>
+	</view>
 	<!-- 宫格 -->
     <view class="grid-body">
 	  <view class="grid uni-row">
@@ -31,6 +36,8 @@
 
 <script lang="uts">
   import {state} from '@/store'; 	
+  import { getCurrentUserSync } from '@/utils/auth.uts'
+  
   type ImageItem={
   	 image:string
   }
@@ -43,29 +50,29 @@
   export default {
     data() { 
 	   let basic = [
-		     ,{colorClass: 'green', iconType: "wallet-filled", text: "用户信息",path:"/pages/mine/pwd/index" }
+		     ,{colorClass: 'green', iconType: "wallet-filled", text: "修改用户信息",path:"/pages/mine/pwd/index" }
 		] as Item[];
 		let isAdmin = state.roles.includes('admin') ? true : false;
-		let adminItem =  {colorClass: 'blue', iconType: "personadd-filled", text: "注册用户",path:"/pages/register" }as Item;
+		let adminItem =  [ {colorClass: 'blue', iconType: "personadd-filled", text: "注册用户",path:"/pages/register" },
+		{colorClass: 'blue', iconType: "staff-filled", text: "用户列表",path:"/pages/mine/person/PersonList" }] as Item [];
+		
 		let items = isAdmin ? basic.concat(adminItem) : basic;
 		
       return {
 		items: items as Item[],
-        current: 0 as number,
-        swiperDotIndex: 0 as number,
-        data: [{
-            image: '/static/images/banner/banner01.png'
-          },
-        ] as ImageItem[]
+		currentName: getCurrentUserSync(),
       }
     },
+	onBackPress() {
+		// 覆盖系统默认的返回行为,返回到指定页面
+		uni.reLaunch({
+		  url: `/pages/work/index`,
+		})
+		// 返回true表示拦截默认返回行为
+		return true
+	},
     methods: {
-      clickBannerItem(item:ImageItem) {
-        console.info(item)
-      },
-      changeSwiper(e:UniSwiperChangeEvent) {
-        this.current = e.detail.current
-      },
+     
       enterItem(e:Item) {
 		  if (e.path != null && e.path != "") {
 		  	uni.navigateTo({
@@ -82,7 +89,7 @@
   }
 </script>
 
-<style lang="scss">
+<style lang="scss" scope>
   /* #ifndef APP-NVUE */
   .my-page {
     display: flex;
@@ -219,4 +226,9 @@
     }
   }
   }
+  
+  .name-label {
+	  margin-right: 20rpx;
+	  margin-left: auto;
+  }
 </style>

+ 26 - 0
pages/mine/person/PersonDetail.uvue

@@ -0,0 +1,26 @@
+<template>
+	<!-- #ifdef APP -->
+	<scroll-view style="flex:1">
+	<!-- #endif -->
+		
+	<!-- #ifdef APP -->
+	</scroll-view>
+	<!-- #endif -->
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				
+			}
+		},
+		methods: {
+			
+		}
+	}
+</script>
+
+<style>
+
+</style>

+ 340 - 0
pages/mine/person/PersonList.uvue

@@ -0,0 +1,340 @@
+<template>
+	<view class="container">
+		<!-- 列表内容 -->
+		<!-- #ifdef APP -->
+		<list-view class="list" :bounces="false" :scroll-y="true" :custom-nested-scroll="true"
+			@scrolltolower="loadData(null)" associative-container="nested-scroll-view">
+			<list-item class="list-item" type="10">
+			<!-- #endif -->
+				<view class="download-card" v-for="(item, index) in users" :key="index">
+					<view @click="enterItem(item.id)">
+						<view class="info-row">
+							<text class="label">序号:</text>
+							<text class="value">{{ item.id }}</text>
+						</view>
+						<view class="info-row">
+							<text class="label">用户姓名:</text>
+							<text class="value">{{ item.name }}</text>
+						</view>
+						<view class="info-row">
+							<text class="label">用户登录账号:</text>
+							<text class="value">{{ item.username }}</text>
+						</view>
+						<view class="info-row">
+							<text class="label">用户类型:</text>
+							<text class="value">{{ item.role == 'user' ? '普通用户' : '管理员' }}</text>
+						</view>
+						<view class="info-row">
+							<text class="label">创建时间:</text>
+							<text
+								class="value">{{ item.createtime === null ? item.createtime : item.updatetime }}</text>
+						</view>
+					</view>
+
+					<view class="info-row">
+						<button class="btn btn-second" type='warn' v-if="item.role == 'user'" @click="del(item.id)">
+							删除
+						</button>
+					</view>
+				</view>
+			<!-- #ifdef APP -->
+			</list-item type="20">
+			<list-item class="loading">
+				<uni-loading :loading="loading" color="#999" :text="loadingText"></uni-loading>
+			</list-item>
+		</list-view>
+		<!-- #endif -->
+	</view>
+</template>
+
+<script setup>
+	import { ref, reactive } from 'vue'
+	import { selectPageSql, removeTableData } from '@/api/work';
+
+	const backPressOptions = reactive({
+		from: 'backbutton'
+	} as OnBackPressOptions)
+
+	onBackPress((options : OnBackPressOptions) : boolean | null => {
+		console.log('onBackPress', options)
+		// 使用reLaunch代替switchTab,避免多层跳转时的闪回问题
+		// reLaunch会关闭所有页面并打开到目标页面,适合需要完全重置导航栈的场景
+		uni.reLaunch({
+			url: `/pages/mine/index`,
+		})
+		// 返回true表示拦截默认返回行为
+		return true
+	})
+
+	type User = {
+		id : number,
+		name : string,
+		username : string,
+		role : string,
+		updatetime : string,
+		createtime : string
+	}
+
+	var initUser = [] as User[]
+	var users = ref<User[]>([]);
+	const loading = ref(false)
+	const isEnded = ref(false)
+	const loadingError = ref('')
+	const currentPage = ref(1)
+
+	const loadingText = computed(() : string => {
+		if (loading.value) {
+			return "加载中..."
+		} else if (isEnded.value) {
+			return "没有更多了"
+		} else if (loadingError.value.length > 0) {
+			return loadingError.value
+		} else {
+			return ""
+		}
+	})
+	// #ifdef APP-ANDROID
+
+	const loadData = (loadComplete : (() => void) | null) {
+		if (loading.value || isEnded.value) {
+			return
+		}
+		loading.value = true
+		let offset = currentPage.value === 1 ? 0 : (currentPage.value - 1) * 10
+		selectPageSql('app_user', 'createtime', offset).then((res : UTSJSONObject) => {
+			console.log(res)
+			let dataList = res?.['data'] as UTSJSONObject[] ?? Array<UTSJSONObject>()
+			if (dataList != null && dataList.length > 0) {
+				dataList.forEach(item => {
+					if (item != null) {
+						let log = JSON.parse<User>(item.toJSONString());
+						if (log != null) {
+							initUser.push(log)
+						}
+					}
+				});
+				currentPage.value++
+			} else {
+				isEnded.value = true
+			}
+			users.value = initUser
+			loading.value = false
+			if (loadComplete != null) {
+				loadComplete()
+			}
+		})
+
+	}
+
+
+	onMounted(() => {
+		loadData(null)
+	})
+
+	// #endif
+
+	const del = (id : number) => {
+		console.log("删除用户")
+		console.log(id)
+		uni.showModal({
+			title: '系统提示',
+			content: '确定要删除当前用户?',
+			cancelText: '取消',
+			confirmText: '确定',
+			success: function (res) {
+				if (res.confirm) {
+					removeTableData('app_user', 'id', id.toString()).then(res => {
+						if (res != null) {
+							let dataList = res?.['data'] as UTSJSONObject[] ?? Array<UTSJSONObject>();
+							if (dataList != null && dataList.length > 0) {
+								let data = dataList[0] as boolean ?? false
+								if (data != null && data == true) {
+									uni.showToast({
+										title: "删除成功!",
+									});
+								}
+							}
+
+						}
+					})
+					console.log(res)
+				} else {
+					// 用户取消覆盖
+					uni.hideLoading();
+				}
+			}
+		});
+
+	}
+
+	const enterItem = (id : number) => {
+		uni.navigateTo({
+			url: `/pages/work/download/DownloadDetail?id=${id}`
+		});
+	}
+
+	defineExpose({
+		loadData,
+		backPressOptions
+	})
+</script>
+
+<style scope>
+	.container {
+		padding: 24rpx;
+		background-color: #f0f4f8;
+		flex: 1;
+		display: flex;
+		flex-direction: column;
+		font-family: "PingFang SC", "Helvetica Neue", Helvetica, Arial, sans-serif;
+		/* #ifndef APP-ANDROID */
+		min-height: 100vh;
+		/* #endif */
+		height: 120rpx;
+	}
+
+	.search-bar {
+		background-color: #ffffff;
+		border-radius: 10rpx;
+		box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
+	}
+
+	/* 搜索输入框:占满容器剩余空间,放在按钮左侧 */
+	.search-input {
+		/* 清除默认输入框样式 */
+		border: none;
+		background: transparent;
+		width: 70%;
+		margin-left: 10rpx;
+	}
+
+	/* 扫描按钮:放在输入框右侧,距离最右10rpx */
+	.scan-btn {
+		justify-content: center;
+		align-items: center;
+		/* 新增:按钮内部图标垂直居中 */
+		/* 关键:右侧10rpx边距,实现"距离最右10rpx" */
+		margin-left: auto;
+		/* 自动推到flex容器最右侧 */
+		margin-right: 10rpx;
+		/* 与容器右边缘保持10rpx间距 */
+	}
+
+	.download-card {
+		background: #ffffff;
+		border-radius: 20rpx;
+		padding: 24rpx 32rpx;
+		box-shadow: 0 8rpx 15rpx rgba(0, 43, 92, 0.1);
+		display: flex;
+		flex-direction: column;
+		margin-bottom: 20rpx;
+		margin-top: 40rpx;
+		margin-left: 20rpx;
+		margin-right: 20rpx;
+	}
+
+	.download-card .view {
+		margin-bottom: 16rpx;
+	}
+
+	/* 信息行 */
+	.info-row {
+		display: flex;
+		flex-direction: row;
+		/* #ifdef H5 */
+		font-size: 28rpx;
+		color: #33475b;
+		/* #endif */
+		align-items: center;
+	}
+
+	.info-row>.label {
+		margin-left: 10rpx;
+	}
+
+	.info-row>.value {
+		margin-left: 10rpx;
+	}
+
+	.btn-panel {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-left: 5rpx;
+		margin-right: 5rpx;
+	}
+
+	.label {
+		font-weight: bold;
+		color: #102a43;
+		min-width: 100rpx;
+	}
+
+	.value {
+		flex: 1;
+		white-space: nowrap;
+		overflow: hidden;
+		text-overflow: ellipsis;
+	}
+
+	.btn {
+		align-self: flex-end;
+		background-color: #00aaff;
+		color: #fff;
+		border: none;
+		border-radius: 32rpx;
+		padding: 2rpx 30rpx;
+		font-size: 24rpx;
+		font-weight: bold;
+		/* #ifndef APP-ANDROID */
+		transition: background-color 0.3s ease;
+		/* #endif */
+		margin-top: 30rpx;
+	}
+
+	.process-value {
+		width: 120rpx;
+		min-width: 100rpx;
+		text-align: center;
+		border-radius: 10rpx;
+	}
+
+	.bg-green {
+		background-color: seagreen;
+	}
+
+	.bg-yellow {
+		background-color: yellow;
+	}
+
+	.bg-black {
+		background-color: #102a43;
+	}
+
+	.btn-first {
+		margin-left: 5rpx;
+	}
+
+	.btn-second {
+		margin-right: 5rpx;
+		margin-left: auto;
+		color: #fff;
+		background-color: red;
+	}
+
+	.loading {
+		padding: 30px;
+		align-items: center;
+	}
+
+	.list {
+		flex: 1;
+		background-color: #ffffff;
+	}
+
+	.list-item {
+		flex-direction: column;
+		margin-top: 10px;
+		padding: 10px;
+	}
+</style>

+ 14 - 4
pages/mine/pwd/index.uvue

@@ -28,7 +28,7 @@
 	import { updateUserPwd } from "@/api/system/user"
 	import { updateData, getList } from '@/api/work';
 	import { getCurrentUserSync, getCurrentUserNameSync } from '@/utils/auth.uts'
-	
+
 	type User = {
 		oldPassword : string | null,
 		newPassword : string | null,
@@ -48,7 +48,17 @@
 				} as User,
 			}
 		},
-
+		onBackPress() {
+			// 覆盖系统默认的返回行为,返回到指定页面
+			uni.navigateTo({
+				url: `/pages/mine/index`,
+				// 修改动画方向为从左到右退回
+				animationType: 'slide-in-left', // 使用从左到右滑出的动画效果
+				animationDuration: 300 // 动画持续时间,单位ms
+			})
+			// 返回true表示拦截默认返回行为
+			return true
+		},
 		methods: {
 			inputFocus(tag : string) {
 				this.$data[tag] = "my-focus"
@@ -127,10 +137,10 @@
 									title: "更新成功!",
 								});
 								setTimeout(() => {
-								
+
 								}, 1500)
 								uni.reLaunch({
-								  url: '/pages/mine/index'
+									url: '/pages/mine/index'
 								});
 							} else {
 								uni.showToast({

+ 14 - 21
pages/register.uvue

@@ -67,6 +67,17 @@ import { getCodeImg, register, RegForm} from '@/api/login'
     created() {
       //this.getCode()
     },
+	onBackPress() {
+		// 覆盖系统默认的返回行为,返回到指定页面
+		uni.navigateTo({
+			url: `/pages/mine/index`,
+			// 修改动画方向为从左到右退回
+			animationType: 'slide-in-left', // 使用从左到右滑出的动画效果
+			animationDuration: 300 // 动画持续时间,单位ms
+		})
+		// 返回true表示拦截默认返回行为
+		return true
+	},
     methods: {
       // 用户登录
      handleUserLogin() {
@@ -112,12 +123,6 @@ import { getCodeImg, register, RegForm} from '@/api/login'
             icon: 'error'
           });
         }
-		/*else if (this.registerForm.code == "" && this.captchaEnabled) {
-          uni.showToast({
-            title: '请输入验证码',
-            icon: 'error'
-          });
-        } */
 		else {
           uni.showLoading({
             title: '注册中,请耐心等待...'
@@ -134,23 +139,11 @@ import { getCodeImg, register, RegForm} from '@/api/login'
           	content: "恭喜你,您的账号 " + this.registerForm.username + " 注册成功!",
           	success: function (res:UniShowModalResult) {
           		if (res.confirm) {
-					uni.redirectTo({ url: `/pages/login` });
+					uni.redirectTo({ url: `/pages/mine/index` });
           		}
           	}
           })
         }).catch(() => {
-          if (this.captchaEnabled) {
-            this.getCode()
-          }
-        })
-      },
-      // 注册成功后,处理函数
-      registerSuccess() {
-        // 设置用户信息
-        GetInfo().then(() => {
-         uni.reLaunch({
-           url: '/pages/index'
-         });
         })
       }
     }
@@ -188,12 +181,12 @@ import { getCodeImg, register, RegForm} from '@/api/login'
      /* #ifdef APP-NVUE */
      text-align: center;
      /* #endif */
-      margin: 20px auto;
+      margin: 20rpx auto;
       margin-top: 15%;
       width: 80%;
 
       .input-item {
-        margin: 20px auto;
+        margin: 20rpx auto;
         background-color: #f5f6f7;
         height: 45px;
         border-radius: 20px;

BIN
static/db/QT800.db


+ 1 - 1
utils/storage.uts

@@ -4,7 +4,7 @@ import {constant} from './constant'
 let storageKey = 'storage_data'
 
 // 存储节点变量名
-let storageNodeKeys = [constant.avatar, constant.name, constant.roles, constant.permissions]
+let storageNodeKeys = [constant.avatar, constant.name, constant.roles, constant.permissions, constant.username]
 
 const storage = {
   set: function(key:string, value:any):void {