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

348 lines
9.7 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="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>