Files
medical-mall/pages/mall/admin/product/specifications/index.uvue
2026-02-25 11:39:54 +08:00

447 lines
8.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="admin-main">
<!-- 头部搜索 -->
<view class="search-card">
<view class="search-row">
<view class="search-item">
<text class="search-label">规格搜索:</text>
<input class="search-input" placeholder="请输入规格名称" />
</view>
<button class="btn-query">查询</button>
</view>
</view>
<!-- 数据表格区域 -->
<view class="table-card">
<view class="table-toolbar">
<button class="btn-add" @click="showModal = true">添加商品规格</button>
<button class="btn-batch-del">批量删除</button>
</view>
<view class="table-header">
<view class="th-cell flex-1 row-center">
<view class="checkbox-mock"></view>
</view>
<text class="th-cell flex-1">ID</text>
<text class="th-cell flex-3">规格名称</text>
<text class="th-cell flex-4">商品规格</text>
<text class="th-cell flex-4">商品属性</text>
<text class="th-cell flex-2 text-center">操作</text>
</view>
<view class="table-body">
<view v-if="list.length === 0" class="empty-box">
<text class="empty-text">暂无数据</text>
</view>
<view v-for="(item, index) in list" :key="index" class="table-row">
<view class="td-cell flex-1 row-center">
<view class="checkbox-mock" :class="item.selected ? 'checked' : ''" @click="item.selected = !item.selected">
<text v-if="item.selected" class="check-mark">✓</text>
</view>
</view>
<text class="td-cell flex-1 color-9">{{ item.id }}</text>
<text class="td-cell flex-3">{{ item.name }}</text>
<text class="td-cell flex-4">{{ item.specs }}</text>
<text class="td-cell flex-4">{{ item.attrs }}</text>
<view class="td-cell flex-2 row-center">
<text class="btn-link">编辑</text>
<view class="divider"></view>
<text class="btn-link delete" @click="deleteItem(index)">删除</text>
</view>
</view>
</view>
</view>
<!-- 添加规格弹窗 -->
<view class="modal-mask" v-if="showModal" @click="showModal = false">
<view class="modal-content" @click.stop>
<view class="modal-header">
<text class="modal-title">添加商品规格</text>
<text class="modal-close" @click="showModal = false">×</text>
</view>
<view class="modal-body">
<view class="modal-form">
<view class="form-item">
<view class="form-label-box"><text class="form-label">规格名称:</text></view>
<view class="form-input-box">
<input class="modal-input" v-model="form.name" placeholder="请输入规格名称" />
</view>
</view>
<view class="form-item">
<view class="form-label-box"><text class="form-label">商品规格:</text></view>
<view class="form-input-box">
<input class="modal-input" v-model="form.specs" placeholder="请输入商品规格" />
</view>
</view>
<view class="form-item">
<view class="form-label-box"><text class="form-label">商品属性:</text></view>
<view class="form-input-box">
<input class="modal-input" v-model="form.attrs" placeholder="请输入商品属性" />
</view>
</view>
</view>
</view>
<view class="modal-footer">
<button class="btn-modal-cancel" @click="showModal = false">取消</button>
<button class="btn-modal-submit" @click="saveAttr">确定</button>
</view>
</view>
</view>
</view>
</template>
<script setup lang="uts">
import { ref, reactive } from 'vue'
interface AttrItem {
id: number;
name: string;
specs: string;
attrs: string;
selected: boolean;
}
const list = reactive<AttrItem[]>([
{ id: 104, name: '颜色', specs: '红色,蓝色,黑色,白色', attrs: '颜色属性', selected: false },
{ id: 105, name: '尺寸', specs: 'S,M,L,XL,XXL', attrs: '服装尺寸', selected: false },
{ id: 106, name: '材质', specs: '纯棉,涤纶,真丝', attrs: '面料材质', selected: false },
{ id: 107, name: '内存', specs: '8G,16G,32G', attrs: '硬件参数', selected: false },
{ id: 108, name: '存储', specs: '128G,256G,512G', attrs: '容量', selected: false }
])
const showModal = ref(false)
const form = reactive({
name: '',
specs: '',
attrs: ''
})
function saveAttr() {
if (!form.name) {
uni.showToast({ title: '请输入规格名称', icon: 'none' })
return
}
list.push({
id: Math.floor(Math.random() * 1000),
name: form.name,
specs: form.specs,
attrs: form.attrs,
selected: false
})
showModal.value = false
form.name = ''
form.specs = ''
form.attrs = ''
uni.showToast({ title: '添加成功', icon: 'success' })
}
function deleteItem(index: number) {
uni.showModal({
title: '提示',
content: '确定删除该规格吗?',
success: (res) => {
if (res.confirm) {
list.splice(index, 1)
}
}
})
}
</script>
<style scoped lang="scss">
.admin-main {
/* 使用 Layout 的背景和内边距 */
padding: 0;
background-color: transparent;
min-height: auto;
}
/* 搜索卡片 */
.search-card {
background-color: #fff;
padding: var(--admin-card-padding);
border-radius: 4px;
margin-bottom: var(--admin-section-gap);
}
.search-row {
display: flex;
flex-direction: row;
align-items: center;
}
.search-item {
display: flex;
flex-direction: row;
align-items: center;
margin-right: 20px;
}
.search-label {
font-size: 14px;
color: #333;
margin-right: 12px;
}
.search-input {
width: 250px;
height: 32px;
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 0 12px;
font-size: 13px;
}
.btn-query {
width: 64px;
height: 32px;
line-height: 32px;
background-color: #1890ff;
color: #fff;
font-size: 14px;
border-radius: 4px;
border: none;
margin-left: 0;
}
/* 表格区域 */
.table-card {
background-color: #fff;
padding: var(--admin-card-padding);
border-radius: 4px;
}
.table-toolbar {
display: flex;
flex-direction: row;
margin-bottom: 20px;
}
.btn-add {
height: 32px;
line-height: 32px;
padding: 0 15px;
background-color: #1890ff;
color: #fff;
font-size: 14px;
border-radius: 4px;
margin-left: 0;
margin-right: 12px;
border: none;
}
.btn-batch-del {
height: 32px;
line-height: 32px;
padding: 0 15px;
background-color: #fff;
color: #606266;
border: 1px solid #dcdfe6;
font-size: 14px;
border-radius: 4px;
margin-left: 0;
}
.table-header {
display: flex;
flex-direction: row;
background-color: #f8f9fa;
border-bottom: 1px solid #f0f0f0;
height: 48px;
align-items: center;
}
.th-cell {
padding: 0 16px;
font-size: 14px;
font-weight: bold;
color: #333;
}
.table-row {
display: flex;
flex-direction: row;
border-bottom: 1px solid #f0f0f0;
min-height: 54px;
align-items: center;
}
.empty-box {
padding: 60px 0;
text-align: center;
}
.empty-text {
color: #999;
font-size: 14px;
}
.td-cell {
padding: 0 16px;
}
.color-9 {
color: #999;
}
.checkbox-mock {
width: 16px;
height: 16px;
border: 1px solid #dcdfe6;
border-radius: 2px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.checkbox-mock.checked {
background-color: #1890ff;
border-color: #1890ff;
}
.check-mark {
color: #fff;
font-size: 12px;
}
.btn-link {
font-size: 14px;
color: #1890ff;
cursor: pointer;
}
.btn-link.delete {
color: #ff4d4f;
}
.divider {
width: 1px;
height: 14px;
background-color: #f0f0f0;
margin: 0 12px;
}
.text-center {
text-align: center;
}
.row-center {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
/* Modal styles */
.modal-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0,0,0,0.5);
z-index: 1000;
display: flex;
justify-content: center;
align-items: center;
}
.modal-content {
width: 500px;
background-color: #fff;
border-radius: 4px;
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
.modal-header {
padding: 16px 24px;
border-bottom: 1px solid #f0f0f0;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.modal-title {
font-size: 16px;
font-weight: 500;
}
.modal-close {
font-size: 24px;
color: #999;
cursor: pointer;
}
.modal-body {
padding: 24px;
}
.form-item {
display: flex;
flex-direction: row;
margin-bottom: 20px;
align-items: center;
}
.form-label-box {
width: 80px;
text-align: right;
margin-right: 16px;
}
.form-label {
font-size: 14px;
color: #606266;
}
.form-input-box {
flex: 1;
}
.modal-input {
width: 100%;
height: 36px;
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 0 12px;
font-size: 14px;
}
.modal-footer {
padding: 12px 24px;
border-top: 1px solid #f0f0f0;
display: flex;
flex-direction: row;
justify-content: flex-end;
}
.btn-modal-cancel, .btn-modal-submit {
height: 32px;
line-height: 32px;
padding: 0 20px;
font-size: 14px;
border-radius: 4px;
margin-left: 12px;
}
.btn-modal-cancel {
background-color: #fff;
border: 1px solid #dcdfe6;
color: #606266;
}
.btn-modal-submit {
background-color: #1890ff;
color: #fff;
border: none;
}
.flex-1 { flex: 1; }
.flex-2 { flex: 2; }
.flex-3 { flex: 3; }
.flex-4 { flex: 4; }
</style>