Files
medical-mall/pages/mall/admin/marketing/newcomer/index.uvue
2026-02-06 12:06:33 +08:00

523 lines
11 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="card-container">
<view class="card-header">
<text class="card-header-title">鏂颁汉绀艰缃?/text>
</view>
<view class="form-content">
<!-- 璧犻€佷綑棰?-->
<view class="form-item">
<view class="label-col">
<text class="form-label">璧犻€佷綑棰?鍏?:</text>
</view>
<view class="input-col">
<input type="number" class="form-input" v-model="formData.balance" />
<text class="form-tip">鏂扮敤鎴峰鍔遍噾棰濓紝蹇呴』澶т簬绛変簬0锛?涓轰笉璧犻€?/text>
</view>
</view>
<!-- 璧犻€佺Н鍒?-->
<view class="form-item">
<view class="label-col">
<text class="form-label">璧犻€佺Н鍒?</text>
</view>
<view class="input-col">
<input type="number" class="form-input" v-model="formData.integral" />
<text class="form-tip">鏂扮敤鎴峰鍔辩Н鍒嗭紝蹇呴』澶т簬绛変簬0锛?涓轰笉璧犻€?/text>
</view>
</view>
<!-- 璧犻€佷紭鎯犲埜 -->
<view class="form-item row-center">
<view class="label-col">
<text class="form-label">璧犻€佷紭鎯犲埜:</text>
</view>
<view class="input-col row-layout">
<view class="coupon-display-area" v-if="formData.coupons.length > 0">
<view v-for="(coupon, index) in formData.coupons" :key="index" class="coupon-tag-group">
<view class="coupon-tag-main">
<text class="coupon-tag-name">{{ coupon.name }}</text>
<text class="coupon-tag-del" @click="removeCoupon(index)">脳</text>
</view>
<view class="explicit-edit-btn" @click="editCoupon(index)">
<text class="edit-btn-text">淇敼璁剧疆</text>
</view>
</view>
</view>
<button class="btn-select-action" @click="showCouponModal = true">閫夋嫨浼樻儬鍒?/button>
</view>
</view>
<!-- 纭鎸夐挳 -->
<view class="form-submit-bar">
<button class="btn-primary-confirm" @click="handleSubmit">纭</button>
</view>
</view>
</view>
<!-- 浼樻儬鍒搁€夋嫨涓庤鎯呴厤缃脊绐?-->
<view class="modal-mask" v-if="showCouponModal" @click="closeModal">
<view class="modal-box" @click.stop>
<view class="modal-head">
<text class="modal-head-title">{{ isEditing ? '閰嶇疆璧犻€佽鎯? : '閫夋嫨浼樻儬鍒? }}</text>
<text class="modal-head-close" @click="closeModal">脳</text>
</view>
<view class="modal-body">
<!-- 缂栬緫/璁剧疆妯″紡锛氬綋鐢ㄦ埛鐢变簬鐐瑰嚮鈥滀慨鏀硅缃€濇椂瑙﹀彂 -->
<view v-if="isEditing" class="setting-form">
<view class="setting-row">
<text class="setting-label">鏄剧ず鍚嶇О:</text>
<input class="setting-input" v-model="editingCoupon.name" placeholder="璇疯緭鍏ラ〉闈㈡樉绀虹殑鍚嶇О" />
</view>
<view class="setting-row">
<text class="setting-label">鍙戞斁鎻忚堪:</text>
<input class="setting-input" v-model="editingCoupon.desc" placeholder="璇疯緭鍏ュ彂鏀炬椂鐨勬弿杩? />
</view>
<view class="setting-tip">
<text class="tip-text">* 姝ゅ鐨勪慨鏀逛粎褰卞搷鈥滄柊浜虹ぜ鈥濇椿鍔ㄤ腑鐨勫睍绀猴紝涓嶅奖鍝嶄紭鎯犲埜鑷韩閰嶇疆</text>
</view>
</view>
<!-- 閫夋嫨妯″紡 -->
<view v-else class="selection-list">
<view v-for="(item, index) in couponOptions" :key="index"
class="selection-card" :class="{'selected-card': isSelected(item)}"
@click="toggleCoupon(item)">
<view class="card-left">
<text class="card-name">{{ item.name }}</text>
<text class="card-desc">{{ item.desc }}</text>
</view>
<view class="card-right">
<view class="check-circle" :class="{'checked-circle': isSelected(item)}">
<text class="check-mark" v-if="isSelected(item)">鉁?/text>
</view>
</view>
</view>
</view>
</view>
<view class="modal-foot">
<button class="foot-btn-cancel" @click="closeModal">鍙栨秷</button>
<button class="foot-btn-ok" @click="confirmModal">纭畾</button>
</view>
</view>
</view>
</view>
</template>
<script setup lang="uts">
import { ref, reactive } from 'vue'
interface Coupon {
id: number;
name: string;
desc: string;
}
const formData = reactive({
balance: '88888',
integral: '88888',
coupons: [] as Coupon[]
})
const showCouponModal = ref(false)
const isEditing = ref(false)
const editingIndex = ref(-1)
const editingCoupon = reactive<Coupon>({ id: 0, name: '', desc: '' })
const couponOptions = reactive<Coupon[]>([
{ id: 1, name: '婊?00鍑?0鍏冨埜', desc: '鍏ㄥ満閫氱敤' },
{ id: 2, name: '鏂颁汉5鍏冩棤闂ㄦ', desc: '浠呴檺鏂颁汉浣跨敤' },
{ id: 3, name: '婊?00鍑?0鍏冨埜', desc: '闄愮壒瀹氬晢鍝? }
])
function isSelected(item: Coupon): boolean {
return formData.coupons.some(c => c.id === item.id)
}
function toggleCoupon(item: Coupon) {
const index = formData.coupons.findIndex(c => c.id === item.id)
if (index > -1) {
formData.coupons.splice(index, 1)
} else {
formData.coupons.push({ ...item })
}
}
function removeCoupon(index: number) {
formData.coupons.splice(index, 1)
}
function editCoupon(index: number) {
editingIndex.value = index
const coupon = formData.coupons[index]
editingCoupon.id = coupon.id
editingCoupon.name = coupon.name
editingCoupon.desc = coupon.desc
isEditing.value = true
showCouponModal.value = true
}
function closeModal() {
showCouponModal.value = false
isEditing.value = false
}
function confirmModal() {
if (isEditing.value && editingIndex.value > -1) {
formData.coupons[editingIndex.value].name = editingCoupon.name
formData.coupons[editingIndex.value].desc = editingCoupon.desc
}
closeModal()
}
function handleSubmit() {
uni.showLoading({ title: '淇濆瓨涓?..' })
setTimeout(() => {
uni.hideLoading()
uni.showToast({
title: '璁剧疆宸茬敓鏁?,
icon: 'success'
})
}, 500)
}
</script>
<style scoped lang="scss">
.admin-main {
padding: 24px;
background-color: #f0f2f5;
min-height: 100vh;
}
.card-container {
border-radius: 2px;
}
.card-header {
padding: 16px 24px;
border-bottom: 1px solid #f0f0f0;
}
.card-header-title {
font-size: 16px;
font-weight: 500;
color: rgba(0, 0, 0, 0.85);
}
.form-content {
padding: 40px 60px;
}
.form-item {
display: flex;
flex-direction: row;
margin-bottom: 24px;
}
.row-center {
align-items: flex-start;
}
.label-col {
width: 140px;
padding-right: 12px;
text-align: right;
}
.form-label {
font-size: 14px;
color: #333;
line-height: 40px;
}
.input-col {
flex: 1;
}
.row-layout {
display: flex;
flex-direction: row;
align-items: center;
flex-wrap: wrap;
}
.form-input {
width: 320px;
height: 40px;
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 0 12px;
font-size: 14px;
transition: all 0.3s;
}
.form-input:focus {
border-color: #1890ff;
}
.form-tip {
display: block;
margin-top: 10px;
font-size: 14px;
color: #bfbfbf;
}
.coupon-display-area {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.coupon-tag-group {
display: flex;
flex-direction: row;
align-items: center;
margin-right: 16px;
margin-bottom: 8px;
}
.coupon-tag-main {
display: flex;
flex-direction: row;
align-items: center;
background-color: #f5f5f5;
border: 1px solid #d9d9d9;
padding: 0 10px;
height: 32px;
border-radius: 4px;
}
.coupon-tag-name {
font-size: 14px;
color: #555;
}
.coupon-tag-del {
margin-left: 8px;
font-size: 16px;
color: #999;
cursor: pointer;
}
.explicit-edit-btn {
margin-left: 8px;
cursor: pointer;
}
.edit-btn-text {
font-size: 13px;
color: #1890ff;
text-decoration: underline;
}
.btn-select-action {
height: 36px;
line-height: 36px;
padding: 0 16px;
font-size: 14px;
background-color: #fff;
border: 1px solid #d9d9d9;
border-radius: 4px;
color: #666;
margin-left: 0;
cursor: pointer;
}
.form-submit-bar {
margin-top: 32px;
padding-left: 140px;
}
.btn-primary-confirm {
width: 88px;
height: 38px;
line-height: 38px;
background-color: #1890ff;
color: #fff;
font-size: 14px;
border-radius: 4px;
margin-left: 0;
border: none;
cursor: pointer;
}
/* Modal */
.modal-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal-box {
width: 560px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 4px 20px rgba(0,0,0,0.15);
overflow: hidden;
}
.modal-head {
padding: 20px 24px;
border-bottom: 1px solid #f0f0f0;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.modal-head-title {
font-size: 18px;
font-weight: 500;
color: #222;
}
.modal-head-close {
font-size: 24px;
color: #aaa;
cursor: pointer;
}
.modal-body {
padding: 24px;
max-height: 450px;
overflow-y: auto;
}
.setting-form {
padding: 10px 0;
}
.setting-row {
margin-bottom: 24px;
}
.setting-label {
display: block;
margin-bottom: 10px;
font-size: 14px;
color: #333;
font-weight: 500;
}
.setting-input {
width: 100%;
height: 42px;
border: 1px solid #d9d9d9;
border-radius: 4px;
padding: 0 12px;
font-size: 14px;
}
.setting-tip {
margin-top: 16px;
}
.tip-text {
font-size: 12px;
color: #ff4d4f;
}
.selection-list {
display: flex;
flex-direction: column;
}
.selection-card {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 16px 20px;
border: 1px solid #f0f0f0;
margin-bottom: 14px;
border-radius: 6px;
transition: all 0.2s;
cursor: pointer;
}
.selection-card:hover {
border-color: #1890ff;
}
.selected-card {
border-color: #1890ff;
background-color: #f0faff;
}
.card-name {
font-size: 15px;
color: #333;
font-weight: 500;
}
.card-desc {
font-size: 13px;
color: #888;
margin-top: 6px;
}
.check-circle {
width: 20px;
height: 20px;
border: 1px solid #d9d9d9;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
}
.checked-circle {
background-color: #1890ff;
border-color: #1890ff;
}
.check-mark {
color: #fff;
font-size: 12px;
}
.modal-foot {
padding: 16px 24px;
border-top: 1px solid #f0f0f0;
display: flex;
flex-direction: row;
justify-content: flex-end;
}
.foot-btn-cancel, .foot-btn-ok {
height: 34px;
line-height: 34px;
padding: 0 20px;
margin-left: 12px;
font-size: 14px;
border-radius: 4px;
cursor: pointer;
}
.foot-btn-cancel {
background-color: #fff;
border: 1px solid #d9d9d9;
color: #666;
}
.foot-btn-ok {
background-color: #1890ff;
color: #fff;
border: none;
}
</style>