348 lines
9.7 KiB
Plaintext
348 lines
9.7 KiB
Plaintext
<template>
|
||
<view class="product-edit-page">
|
||
<view class="page-header">
|
||
<view class="back-link" @click="goBack">
|
||
<text class="arrow">{"<"}</text>
|
||
<text class="back-txt">返回</text>
|
||
</view>
|
||
<text class="header-title">编辑商品</text>
|
||
</view>
|
||
|
||
<!-- 步骤层 -->
|
||
<view class="steps-card">
|
||
<view class="step-items">
|
||
<view v-for="(step, index) in steps" :key="index" class="step-item" :class="{ active: activeStep === index }">
|
||
<text class="step-txt">{{ step }}</text>
|
||
<view v-if="index < steps.length - 1" class="step-line"></view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 表单内容 -->
|
||
<view class="form-card">
|
||
<view class="form-item">
|
||
<view class="label"><text class="required">*</text><text>商品类型:</text></view>
|
||
<view class="input-wrap">
|
||
<view class="radio-group">
|
||
<view class="radio-item active">
|
||
<text class="radio-circle on"></text>
|
||
<view class="radio-txt">
|
||
<text class="main">普通商品</text>
|
||
<text class="sub">(物流发货)</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item">
|
||
<view class="label"><text class="required">*</text><text>商品名称:</text></view>
|
||
<view class="input-wrap">
|
||
<view class="input-box">
|
||
<input class="real-input" value="UR2024夏季新款女装复古纯欲氛围感一字肩短款T恤衫UWG440060" />
|
||
<text class="count">36/80</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item">
|
||
<view class="label"><text class="required">*</text><text>单位:</text></view>
|
||
<view class="input-wrap">
|
||
<view class="input-box small">
|
||
<input class="real-input" value="件" />
|
||
<text class="count">1/5</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item">
|
||
<view class="label"><text class="required">*</text><text>商品轮播图:</text></view>
|
||
<view class="input-wrap">
|
||
<view class="image-uploader">
|
||
<view v-for="(img, i) in carouselImages" :key="i" class="img-item">
|
||
<image :src="img" mode="aspectFill" />
|
||
<view class="img-close">×</view>
|
||
</view>
|
||
<view class="upload-btn">
|
||
<text class="icon">+</text>
|
||
</view>
|
||
</view>
|
||
<text class="tip">建议尺寸:800*800,可拖拽改变图片顺序,默认首张图为主图,最多上传10张</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item">
|
||
<view class="label"><text>添加视频:</text></view>
|
||
<view class="input-wrap">
|
||
<view class="upload-btn v-btn">
|
||
<text class="v-icon">📹</text>
|
||
</view>
|
||
<text class="tip">建议时长:9~30秒,视频宽高比16:9</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item">
|
||
<view class="label"><text class="required">*</text><text>商品分类:</text></view>
|
||
<view class="input-wrap">
|
||
<view class="tag-selector">
|
||
<view v-for="tag in categories" :key="tag" class="tag-item">
|
||
<text>{{ tag }}</text>
|
||
<text class="close">×</text>
|
||
</view>
|
||
<text class="add-link">新增分类</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item">
|
||
<view class="label"><text>商品标签:</text></view>
|
||
<view class="input-wrap">
|
||
<view class="mock-btn-select">选择标签</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="form-item">
|
||
<view class="label"><text>商品状态:</text></view>
|
||
<view class="input-wrap">
|
||
<view class="radio-group-simple">
|
||
<view class="radio-simple on">
|
||
<text class="dot"></text>
|
||
<text>上架</text>
|
||
</view>
|
||
<view class="radio-simple">
|
||
<text class="dot"></text>
|
||
<text>下架</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="footer-btns">
|
||
<button class="btn-next">下一步</button>
|
||
<button class="btn-save">保存</button>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="uts">
|
||
import { ref } from 'vue'
|
||
import { openRoute } from '@/layouts/admin/store/adminNavStore.uts'
|
||
|
||
const activeStep = ref(0)
|
||
const steps = ['基础信息', '规格库存', '商品详情', '物流设置', '会员价/佣金', '营销设置', '其他设置']
|
||
|
||
const carouselImages = ref([
|
||
'https://img1.baidu.com/it/u=254065646,3100346083&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
|
||
'https://img2.baidu.com/it/u=3025255470,3051061730&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500',
|
||
'https://img2.baidu.com/it/u=3775079632,546700868&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=500'
|
||
])
|
||
|
||
const categories = ref(['生活家居', '运动专区 / 361', '运动专区 / 特步', '运动专区 / 匹克'])
|
||
|
||
function goBack() {
|
||
openRoute('product_productList')
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.product-edit-page {
|
||
padding: 0;
|
||
background-color: transparent;
|
||
min-height: auto;
|
||
}
|
||
|
||
.page-header {
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
gap: 16px;
|
||
margin-bottom: 20px;
|
||
.back-link {
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
gap: 4px;
|
||
color: #666;
|
||
cursor: pointer;
|
||
.arrow { font-size: 14px; }
|
||
.back-txt { font-size: 14px; }
|
||
}
|
||
.header-title { font-size: 16px; font-weight: bold; color: #333; }
|
||
}
|
||
|
||
.steps-card {
|
||
background: #fff;
|
||
padding: 20px;
|
||
border-radius: 4px;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.step-items {
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
}
|
||
|
||
.step-item {
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
.step-txt {
|
||
font-size: 14px;
|
||
color: #999;
|
||
padding: 0 16px;
|
||
}
|
||
&.active .step-txt {
|
||
color: #1890ff;
|
||
font-weight: bold;
|
||
border-bottom: 2px solid #1890ff;
|
||
padding-bottom: 4px;
|
||
}
|
||
.step-line {
|
||
width: 20px;
|
||
height: 1px;
|
||
background: #e8e8e8;
|
||
}
|
||
}
|
||
|
||
.form-card {
|
||
background: #fff;
|
||
padding: 40px;
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.form-item {
|
||
display: flex;
|
||
flex-direction: row;
|
||
margin-bottom: 30px;
|
||
.label {
|
||
width: 120px;
|
||
text-align: right;
|
||
font-size: 14px;
|
||
color: #333;
|
||
padding-top: 8px;
|
||
margin-right: 20px;
|
||
.required { color: #f5222d; margin-right: 4px; }
|
||
}
|
||
.input-wrap { flex: 1; }
|
||
}
|
||
|
||
.radio-item {
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
gap: 8px;
|
||
border: 1px solid #1890ff;
|
||
border-radius: 4px;
|
||
padding: 10px 16px;
|
||
width: 160px;
|
||
position: relative;
|
||
.radio-circle {
|
||
width: 14px; height: 14px; border: 1px solid #d9d9d9; border-radius: 50%;
|
||
&.on { border-color: #1890ff; background: #1890ff; }
|
||
}
|
||
.radio-txt {
|
||
display: flex;
|
||
flex-direction: column;
|
||
.main { font-size: 14px; color: #333; }
|
||
.sub { font-size: 12px; color: #999; }
|
||
}
|
||
&::after {
|
||
content: '✓';
|
||
position: absolute;
|
||
right: 0; bottom: 0;
|
||
background: #1890ff; color: #fff; font-size: 10px; padding: 0 2px;
|
||
}
|
||
}
|
||
|
||
.input-box {
|
||
border: 1px solid #d9d9d9;
|
||
border-radius: 4px;
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: center;
|
||
padding: 0 12px;
|
||
width: 400px;
|
||
height: 36px;
|
||
&.small { width: 150px; }
|
||
.real-input { flex: 1; font-size: 14px; color: #333; }
|
||
.count { font-size: 12px; color: #bfbfbf; }
|
||
}
|
||
|
||
.image-uploader {
|
||
display: flex;
|
||
flex-direction: row;
|
||
flex-wrap: wrap;
|
||
gap: 12px;
|
||
margin-bottom: 8px;
|
||
.img-item {
|
||
width: 80px; height: 80px; position: relative;
|
||
image { width: 100%; height: 100%; border-radius: 4px; }
|
||
.img-close {
|
||
position: absolute; right: -6px; top: -6px; width: 16px; height: 16px;
|
||
background: rgba(0,0,0,0.5); color: #fff; border-radius: 50%;
|
||
display: flex; align-items: center; justify-content: center; font-size: 12px;
|
||
}
|
||
}
|
||
}
|
||
|
||
.upload-btn {
|
||
width: 80px; height: 80px; border: 1px dashed #d9d9d9; border-radius: 4px;
|
||
display: flex; align-items: center; justify-content: center;
|
||
.icon { font-size: 24px; color: #999; }
|
||
&.v-btn { width: 64px; height: 64px; margin-bottom: 8px; .v-icon { font-size: 24px; } }
|
||
}
|
||
|
||
.tip { font-size: 12px; color: #999; }
|
||
|
||
.tag-selector {
|
||
display: flex;
|
||
flex-direction: row;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
align-items: center;
|
||
.tag-item {
|
||
background: #f5f5f5; border: 1px solid #d9d9d9; padding: 2px 10px; border-radius: 4px;
|
||
display: flex; flex-direction: row; align-items: center; gap: 6px;
|
||
font-size: 14px; color: #666;
|
||
.close { color: #999; cursor: pointer; }
|
||
}
|
||
.add-link { font-size: 14px; color: #1890ff; cursor: pointer; }
|
||
}
|
||
|
||
.mock-btn-select {
|
||
border: 1px solid #d9d9d9; border-radius: 4px; padding: 6px 16px;
|
||
font-size: 14px; color: #666; display: inline-block;
|
||
}
|
||
|
||
.radio-group-simple {
|
||
display: flex;
|
||
flex-direction: row;
|
||
gap: 20px;
|
||
.radio-simple {
|
||
display: flex; flex-direction: row; align-items: center; gap: 6px; font-size: 14px; color: #666;
|
||
.dot { width: 14px; height: 14px; border: 1px solid #d9d9d9; border-radius: 50%; position: relative; }
|
||
&.on {
|
||
color: #1890ff;
|
||
.dot { border-color: #1890ff; }
|
||
.dot::after {
|
||
content: ''; position: absolute; left: 3px; top: 3px; width: 6px; height: 6px;
|
||
background: #1890ff; border-radius: 50%;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.footer-btns {
|
||
margin-top: 24px;
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: center;
|
||
gap: 16px;
|
||
padding-bottom: 40px;
|
||
.btn-next { background: #1890ff; color: #fff; border: none; padding: 0 24px; height: 40px; border-radius: 4px; }
|
||
.btn-save { background: #fff; color: #1890ff; border: 1px solid #1890ff; padding: 0 24px; height: 40px; border-radius: 4px; }
|
||
}
|
||
</style>
|