uniapp-商城-43-shop 后台管理 页面

后台管理较为简单,主要用于后台数据的管理,包含商品类别和商品信息,其实还可以扩展到管理用户等等

1、后台首页

包含 分类管理 商品管理 关于商家等几个栏目

主要代码:

html 复制代码
<template>
	<view class="manage">
		<!-- 商品管理后台 -->
	<!-- uni-section标题栏 组件来完成   https://zh.uniapp.dcloud.io/component/uniui/uni-section.html-->
		<uni-section title="分类管理" type="line"></uni-section>
		<!-- 使用列表组件  uni-list  uni-list-item 完成    https://zh.uniapp.dcloud.io/component/uniui/uni-list.html -->
		<uni-list>
			<uni-list-item title="管理分类" show-arrow to="/pages_manage/category/category"></uni-list-item>
		</uni-list>
		
		<uni-section title="商品管理" type="line"></uni-section>
		<uni-list>
			<uni-list-item title="商品列表" show-arrow to="/pages_manage/goods/list"></uni-list-item>
			<uni-list-item title="新增商品" show-arrow to="/pages_manage/goods/add"></uni-list-item>
		</uni-list>
		
		<uni-section title="关于商家" type="line"></uni-section>
		<uni-list>
			<uni-list-item title="商家信息" show-arrow to="/pages_manage/brand/brand"></uni-list-item>
		</uni-list>
		
	</view>
</template>

<script>
	export default {
		data() {
			return {
				
			};
		}
	}
</script>

<style lang="scss" scoped>
.manage{
	padding:30rpx;
}
</style>

2、分类管理

由于对商品的类别进行划分,可以添加、修改和删除

新增分类;对已有分类进行修改和删除

代码:

页面展示以及操作方法

html 复制代码
<template>
	<view class="category">
		<!-- 分类管理 -->
		<!-- 第二步 -->
		<!-- 这里的row add 中间有一个空格,下面样式就可以写成 .row.add -->
		<view class="row add" @click="clickAdd">
			<view class="left">
				<!-- https://uviewui.com/components/icon.html 使用的是uview的icon -->
				<u-icon name="plus" color="#576b95" size="22"></u-icon>
				<text class="text">新增分类</text>
			</view>
		</view>
		
		<!-- 第一步 -->
		<view class="row" v-for="(item,index) in categoryList" :key="item._id">
			<view class="left">
				<!-- 分类名称 -->
				<view class="name">{{item.name}}</view>
			</view>
			<view class="right">
				<!-- 编辑和删除图标 -->
				<!-- 使用的u-icon组件,自动生成一个class名字为 u-icon -->
				<u-icon name="edit-pen" size="26" color="#576b95" @click="updateData(item._id,item.name)"></u-icon>
				<u-icon name="trash" size="26" color="#EC544F" @click="deleteData(item._id)"></u-icon>
			</view>
		</view>
		
		<!-- 第三步 -->
		<!-- https://uniapp.dcloud.net.cn/component/uniui/uni-popup.html 使用这里弹出层 官方  使用的是输入框示例 -->
		<!-- 下载安装相应的组件  ref来获取方法进行相应的动作,uview 是通过show 来完成相应的动作 -->
		<!-- @confirm 这是一个回调函数,我们通过这就知道输入的到底是什么 -->
		<uni-popup ref="inputDialog">
			<uni-popup-dialog mode="input" 
			:value="iptValue"
			placeholder="请输入分类名称"
			title="分类名称" 
			@confirm="dialogConfirm"
				></uni-popup-dialog>
		</uni-popup>
		
		
	</view>
</template>

<script>
	const db = uniCloud.database()
	export default {
		data() {
			return {
				// categoryList:[{_id:1,name:"水果"},{_id:2,name:"肉类"}],
				// 上面是模拟数据  实际写的是空 下面这样的  真实数据来之云存储,并给该变量赋值
				categoryList:[],
				iptValue:"",
				updateID:null
			};
		},
		onLoad() {
			this.getCateGory()
		},
		methods:{
			//获取数据库中的分类
			getCateGory(){
				db.collection("kt-mall-category").get().then(res=>{
					console.log(res);
					this.categoryList = res.result.data
				})
			},
			//添加分类
			clickAdd(){
				this.iptValue=""
				this.updateID=null;
				//https://uniapp.dcloud.net.cn/component/uniui/uni-popup.html  使用的是Popup Methods中open  
				// 这里的inputDialog 的属性是ref在uni-popup中
				// 所以这里使用的是 this.$refs.inputDialog.open();
				this.$refs.inputDialog.open();
			},
			//点击确认按钮
			async dialogConfirm(e){
				this.iptValue = e;
				if(this.updateID){
					await db.collection("kt-mall-category").doc(this.updateID).update({
						name:this.iptValue
					})		
				}else{
					await db.collection("kt-mall-category").add({
						name:this.iptValue
					})
				}		
				this.iptValue = "";
				//把输入或修改的值改为空,以免下一次在调用就还有上一次的值
				this.getCateGory();	
				
			},
			
			//修改一条分类
			updateData(id,name){
				this.iptValue=name;
				this.updateID=id;
				this.$refs.inputDialog.open();
			},
			
			//删除一条分类
			deleteData(id){
				uni.showModal({
					content:"是否删除该分类?",
					success:res=>{
						if(res.confirm){
							db.collection("kt-mall-category").doc(id).remove().then(res=>{
								this.getCateGory();
							})							
						}
					},
					fail:err=>{
						console.log(err);
					}
				})
			}
		}
	}
</script>

<style lang="scss">
.category{
	padding:30rpx;
	.row{
		@include flex-box();
		border-bottom: 1px solid $border-color-light;
		padding:26rpx 0;
		.left{
			font-size: 34rpx;
		}
		.right{
			@include flex-box();
			//使用的u-icon组件,自动生成一个class名字为 u-icon 
			.u-icon{
				margin-left:30rpx;
			}
		}
	}
	// 对应的class 就是 row add
	.row.add{
		.left{
			color:$brand-theme-color-aux;
			@include flex-box();
			.text{
				font-size: 36rpx;
				padding-left:10rpx;
			}
		}
	}
}
</style>

3、商品管理

包含商品列表和新增商品

添加商品代码:

html 复制代码
<template>
	<view class="goodsView">
		<!-- 添加商品 -->
		<uni-forms ref="goodsForm" :model="goodsFormData" :rules="goodsRules" :label-width="100" label-align="right">
			<uni-forms-item label="商品图片">
				<uni-file-picker
				v-model="goodsFormData.thumb"
				fileMediatype="image"
				mode="grid"
				></uni-file-picker>
			</uni-forms-item>
			
			<uni-forms-item label="商品名称" required name="name">
				<uni-easyinput v-model="goodsFormData.name" placeholder="请输入商品名称" trim="both"></uni-easyinput>
			</uni-forms-item>
			
			<uni-forms-item label="产品分类" required name="category_id">
				<uni-data-select
				collection="kt-mall-category"
				field="_id as value, name as text"
				v-model="goodsFormData.category_id"
				></uni-data-select>
			</uni-forms-item>
			
			<uni-forms-item label="商品价格" required name="price">
				<uni-easyinput type="number" v-model="goodsFormData.price" placeholder="请输入商品价格" trim="both"></uni-easyinput>
			</uni-forms-item>
			
			<uni-forms-item label="商品原价">
				<uni-easyinput type="number" v-model="goodsFormData.before_price" placeholder="请输入原价" trim="both"></uni-easyinput>
			</uni-forms-item>
			
			<uni-forms-item label="商品属性">
				<u-cell :title="skuTitle" isLink :border="false" @click="clickSelect"></u-cell>
				<view class="skuList">
					<view class="item" v-for="item in goodsFormData.sku_select" @click="clickSelect">
						<view class="left">{{item.skuName}}:</view>
						<view class="right">{{skuChildName(item.children)}}</view>
					</view>
				</view>
			</uni-forms-item>
			
			
			<uni-forms-item label="商品描述">
				<uni-easyinput type="textarea" placeholder="请输入详细的描述信息" v-model="goodsFormData.description"></uni-easyinput>
			</uni-forms-item>
			
			<view class="btnView">
				<button type="primary" @click="onSubmit">确认提交</button>
			</view>
			
		</uni-forms>
		
		
		<uni-popup ref="attrWrapPop" type="bottom">
			<view class="attrWrapper">
				<view class="head">
					<view class="title">商品属性</view>
					<view class="addAttr" @click="clickAddAttr()">+ 添加属性</view>
				</view>				
				
				<view class="body">
					<view class="item" v-for="(item,index) in skuArr">
						<view class="top">							
							<checkbox :checked="item.checked" @click="changeCheckbox(index)"></checkbox>
							<view class="font">{{item.skuName}}</view>
						</view>
						<view class="btnGroup" v-if="item.checked">
							<view class="btn" 
							:class="child.checked?'active':''"
							v-for="(child,cIdx) in item.children" 
							@click="clickChlidBtn(index,cIdx)">{{child.name}}</view>
							<view class="btn" @click="clickAddAttr(index)">
								<u-icon name="plus"></u-icon>
							</view>
						</view>
					</view>
				</view>
								
				<view class="foot">
					<button type="primary" @click="clickConfirmSelect">确认选择</button>
				</view>
			</view>
			
			<view class="safe-area-bottom"></view>
		</uni-popup>
		
		
		<uni-popup ref="addAttrPop">
			<uni-popup-dialog  mode="input" title="新增" placeholder="请输入新增的内容"
			@confirm="dialogConfirm"
			></uni-popup-dialog>
		</uni-popup>
	</view>
</template>

<script>
	const skuCloudObj = uniCloud.importObject("kt-mall-sku",{
		"customUI":true
	});
	
	const goodsCloudObj = uniCloud.importObject("kt-mall-goods",{
		"customUI":true
	})
	
	export default {
		data() {
			return {
				goodsFormData:{
					thumb:[],
					name:"",
					category_id:null,
					price:null,
					before_price:null,
					description:"",
					sku_select:[]
				},
				addAttrType:"parent",  //parent代表父,child代表子
				
				goodsRules:{
					name:{
						rules:[{
							required:true,
							errorMessage:"请输入产品名称"
						}]
					},
					price:{
						rules:[{
							required:true,
							errorMessage:"请输入产品价格"
						}]
					},
					category_id:{
						rules:[{
							required:true,
							errorMessage:"请输入产品分类"
						}]
					}
				},
				
				skuArr:[]
			};
		},
		
		onLoad(){
			
		},
		
		computed:{
			skuTitle(){
				if(this.goodsFormData.sku_select.length){
					let arr = this.goodsFormData.sku_select.map(item=>{
						return item.skuName
					})
					return arr.join("/")
				}else{
					return "点击添加属性"
				}
			}
		},
		
		
		methods:{
			//属性返回子元素的名称
			skuChildName(arr){
				let nsArr =  arr.map(item=>{
					return item.name
				})
				return nsArr.join("/")
			},		
			
			
			//点击确认选择
			clickConfirmSelect(){
				let arr = this.skuArr.filter(item=>{
					let state =  item.children.some(child=>child.checked)
					return item.checked && state
				}).map(item=>{
					let children =  item.children.filter(child=>{
						return child.checked
					})
					return {
						...item,
						children
					}
				})
				this.goodsFormData.sku_select = arr
				this.$refs.attrWrapPop.close();			
				
			},
			//获取sku列表
			async getSkuData(){
				let res = await skuCloudObj.get();
				this.skuArr = res.data
				console.log(res);
			},
			
			
			//点击添加属性
			clickAddAttr(index=null){
				if(index==null){
					this.addAttrType="parent"
					this.attrIndex=null
				}else{
					this.addAttrType="child"
					this.attrIndex=index
				}
				this.$refs.addAttrPop.open();
			},			
			//添加属性弹窗的确认按钮
			async dialogConfirm(e){
				if(!e) return;	
				if(this.addAttrType=="parent"){
					let obj={
						skuName:e,
						checked:true,
						children:[]
					}
					let res = await skuCloudObj.add(obj)
					obj._id = res.id;					
					this.skuArr.push(obj)					
					
				}else if(this.addAttrType=="child"){					
					let obj={
						name:e,
						checked:true
					}
					let id = this.skuArr[this.attrIndex]._id;
					let res = await  skuCloudObj.updateChild(id,obj)					
					this.skuArr[this.attrIndex].children.push(obj)
				}
				
			},
			
			//点击属性的复选框
			changeCheckbox(index){
				this.skuArr[index].checked  = !this.skuArr[index].checked 
			},
			
			//点击属性值的子元素
			clickChlidBtn(index,cIdx){
				this.skuArr[index].children[cIdx].checked =  !this.skuArr[index].children[cIdx].checked
			},
			
			
			//点击选择属性
			clickSelect(){
				this.$refs.attrWrapPop.open();
				if(this.skuArr.length) return;
				this.getSkuData();
				
			},
			
			//点击提交表单
			onSubmit(){
				this.$refs.goodsForm.validate().then(res=>{
					this.toDataBase();
					
				}).catch(err=>{
					console.log(err);
				})
			},
			//上传到云数据库
			async toDataBase(){
				this.goodsFormData.thumb = this.goodsFormData.thumb.map(item=>{
					return {
						url:item.url,
						name:item.name,
						extname:item.extname
					}
				})
				
				let res = await goodsCloudObj.add(this.goodsFormData)
				uni.showToast({
					title:"新增商品成功"
				})
				setTimeout(()=>{
					uni.navigateBack()
				},1500)				
				
			}
			
			
		}
	}
</script>

<style lang="scss" scoped>
.goodsView{
	padding:30rpx;
	.skuList{
		.item{
			padding:30rpx;
			background: $page-bg-color;
			margin:15rpx 0;
			@include flex-box-set(start);
		}
	}
}


.attrWrapper{
	padding:30rpx;
	background: #fff;
	border-radius: 20rpx 20rpx 0 0;
	.head{
		@include flex-box();
		font-size: 34rpx;
		margin-bottom:30rpx;
		.title{
			font-weight: bold;
		}
		.addAttr{
			color:$brand-theme-color-aux;
		}
	}
	.body{
		.item{
			border-top:1px solid $border-color-light;
			&:last-child{
				border-bottom:1px solid $border-color-light;
			}
			.top{
				padding:30rpx 0;
				@include flex-box-set(start);
				.font{
					padding-left: 10rpx;
					font-weight: bold;
				}
			}
			.btnGroup{
				padding:10rpx 0 30rpx;
				@include flex-box-set(start);
				flex-wrap: wrap;
				.btn{
					padding:0rpx 25rpx;
					height: 60rpx;
					border:1rpx solid $border-color-light;
					margin-right: 20rpx;
					border-radius: 10rpx;					
					color:$text-font-color-2;
					margin-bottom:20rpx;
					@include flex-box-set();
					&.active{
						border-color: $brand-theme-color;
						color:$brand-theme-color;
						background: rgba(236,87,79,0.1);
					}
				}
			}
		}
	}
	
	.foot{
		padding:50rpx 200rpx;
	}
}
</style>

4、关于商家

商家信息展示和修改

代码:

html 复制代码
<template>
	<view class="brand">
		<!-- 商户信息 -->
		<uni-forms ref="brandRef" :model="brandFormData" :rules="brandRules" :label-width="100" label-align="right">
			<uni-forms-item label="品牌招牌">
				<uni-file-picker 
					v-model="brandFormData.thumb" 
					fileMediatype="image" 
					mode="grid"
					:limit="1"
				/>
			</uni-forms-item>
			
			
			<uni-forms-item label="品牌名称" name="name" required>
				<uni-easyinput type="text" v-model="brandFormData.name" placeholder="请输入品牌名称" />
			</uni-forms-item>

			<uni-forms-item label="商户电话" name="mobile" required>
				<uni-easyinput type="text" v-model="brandFormData.mobile" placeholder="请输入商户电话" />
			</uni-forms-item>

			<uni-forms-item label="商户地址" name="address">
				<uni-easyinput v-model="brandFormData.address" placeholder="请输入商户地址" />
			</uni-forms-item>

			<uni-forms-item label="商家介绍" name="about">
				<uni-easyinput v-model="brandFormData.about" placeholder="请输入商家介绍" type="textarea" />
			</uni-forms-item>


			<button type="primary" @click="onSubmit">提交信息</button>
		</uni-forms>
	</view>
</template>

<script>
	const brandCloudObj = uniCloud.importObject("kt-mall-brand")
	export default {
		data() {
			return {
				brandFormData: {
					thumb:[],
					name: "", //品牌名称
					mobile: "",
					address:"",
					about:""
				},
				brandRules: {
					name: {
						rules: [{
							required: true,
							errorMessage: "请输入正确的品牌名称"
						}, {
							minLength: 3,
							maxLength: 20,
							errorMessage: '长度在{minLength}到{maxLength}的字符'
						}]
					},
					mobile: {
						rules: [{
							required: true,
							errorMessage: "请输入正确的品牌电话"
						}, {
							validateFunction: function(rule, value, data, callback) {
								let res = /^1[3-9]\d{9}$/.test(value);
								if (!res) {
									callback("手机格式不正确")
								}
								return;
							}
						}]
					}
					
				}
			};
		},
		
		onLoad(){
			this.getBrand();
		},
		
		methods: {
			//获取数据库中的品牌信息
			getBrand(){
				brandCloudObj.get().then(res=>{
					console.log(res);
					this.brandFormData = res.data[0]
				})
			},
			
			
			//点击提交按钮
			onSubmit() {								
				this.$refs.brandRef.validate().then(res => {
					let arr =  this.brandFormData.thumb.map(item=>{
						return {
							extname:item.extname,
							url:item.url,
							name:item.name,
							size:item.size
						}
					})
					this.brandFormData.thumb = arr;
					this.addAndUpdate();
				}).catch(err => {
					console.log(err);
				})
			},
			//新增或者修改品牌啊信息
			addAndUpdate(){
				if(this.brandFormData._id){
					brandCloudObj.update(this.brandFormData).then(res=>{
						uni.showToast({
							title:"修改成功",
							mask:true
						})
						setTimeout(()=>{
							uni.navigateBack();
						},1500)
						
					})
				}else{
					//新增
					brandCloudObj.add(this.brandFormData).then(res=>{
						uni.showToast({
							title:"新增成功"
						})
						setTimeout(()=>{
							uni.navigateBack();
						},1500)
					})
				}
				
				
				
			}
		}
	}
</script>

<style lang="scss" scoped>
	.brand {
		padding: 30rpx;

	}
</style>
相关推荐
小妖6669 小时前
uni-app 引入vconsole web端正常,安卓端报错 Cannot read property ‘sendBeacon‘ of undefined
android·前端·uni-app
源码宝11 小时前
ERP进销存系统源码,SaaS模式多租户ERP管理系统,SpringBoot、Vue、UniAPP技术框架
vue.js·spring boot·uni-app·源代码管理·erp·erp系统·进销存
牧杉-惊蛰11 小时前
uniapp 震动功能实现
uni-app
yrldjsbk19 小时前
uniapp开发09-设置一个tabbar底部导航栏且配置icon图标
前端·uni-app
假客套1 天前
2025 后端自学UNIAPP【项目实战:旅游项目】1、创建项目框架
uni-app·旅游
济南壹软网络科技-专注源码开发数十年!1 天前
盲盒源码_盲盒系统_盲盒定制开发 盲盒搭建前端教程
开发语言·前端·uni-app·php
象骑士Hack1 天前
Uni-app小程序 hello world示例
小程序·uni-app
爱笑的眼睛112 天前
uniapp 云开发全集 云数据库
javascript·数据库·oracle·uni-app
青茶3602 天前
uniapp开发微信小程序时如何进行分包(新手图文)
微信小程序·小程序·uni-app