1081 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			HTML
		
	
	
	
			
		
		
	
	
			1081 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			HTML
		
	
	
	
<!DOCTYPE html>
 | 
						|
<html lang="zh-CN">
 | 
						|
<head>
 | 
						|
    <meta charset="UTF-8">
 | 
						|
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
						|
    <title>积分商城 - 商品管理</title>
 | 
						|
    <style>
 | 
						|
        * {
 | 
						|
            margin: 0;
 | 
						|
            padding: 0;
 | 
						|
            box-sizing: border-box;
 | 
						|
        }
 | 
						|
 | 
						|
        body {
 | 
						|
            font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
 | 
						|
            background-color: #f5f5f5;
 | 
						|
            color: #333;
 | 
						|
            line-height: 1.6;
 | 
						|
        }
 | 
						|
 | 
						|
        .container {
 | 
						|
            max-width: 100%;
 | 
						|
            margin: 0 auto;
 | 
						|
            padding: 16px;
 | 
						|
        }
 | 
						|
 | 
						|
        .header {
 | 
						|
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
 | 
						|
            color: white;
 | 
						|
            padding: 20px 16px;
 | 
						|
            margin: -16px -16px 20px -16px;
 | 
						|
        }
 | 
						|
 | 
						|
        .header h1 {
 | 
						|
            font-size: 18px;
 | 
						|
            font-weight: 600;
 | 
						|
            text-align: center;
 | 
						|
        }
 | 
						|
 | 
						|
        .search-section {
 | 
						|
            background: white;
 | 
						|
            border-radius: 12px;
 | 
						|
            padding: 20px;
 | 
						|
            margin-bottom: 20px;
 | 
						|
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
 | 
						|
        }
 | 
						|
 | 
						|
        .search-grid {
 | 
						|
            display: grid;
 | 
						|
            gap: 15px;
 | 
						|
            margin-bottom: 20px;
 | 
						|
        }
 | 
						|
 | 
						|
        .input-group {
 | 
						|
            display: flex;
 | 
						|
            flex-direction: column;
 | 
						|
            gap: 8px;
 | 
						|
        }
 | 
						|
 | 
						|
        .input-group label {
 | 
						|
            font-size: 14px;
 | 
						|
            font-weight: 500;
 | 
						|
            color: #666;
 | 
						|
        }
 | 
						|
 | 
						|
        .input-group input {
 | 
						|
            padding: 12px 16px;
 | 
						|
            border: 1px solid #ddd;
 | 
						|
            border-radius: 8px;
 | 
						|
            font-size: 16px;
 | 
						|
            transition: all 0.3s ease;
 | 
						|
        }
 | 
						|
 | 
						|
        .input-group input:focus {
 | 
						|
            outline: none;
 | 
						|
            border-color: #667eea;
 | 
						|
            box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
 | 
						|
        }
 | 
						|
 | 
						|
        .search-btn {
 | 
						|
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
 | 
						|
            color: white;
 | 
						|
            border: none;
 | 
						|
            padding: 12px 24px;
 | 
						|
            border-radius: 8px;
 | 
						|
            font-size: 16px;
 | 
						|
            font-weight: 500;
 | 
						|
            cursor: pointer;
 | 
						|
            transition: all 0.3s ease;
 | 
						|
            width: 100%;
 | 
						|
        }
 | 
						|
 | 
						|
        .search-btn:hover {
 | 
						|
            transform: translateY(-2px);
 | 
						|
            box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
 | 
						|
        }
 | 
						|
 | 
						|
        .search-btn:active {
 | 
						|
            transform: translateY(0);
 | 
						|
        }
 | 
						|
 | 
						|
        .products-section {
 | 
						|
            background: white;
 | 
						|
            border-radius: 12px;
 | 
						|
            overflow: hidden;
 | 
						|
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
 | 
						|
            margin-bottom: 20px;
 | 
						|
        }
 | 
						|
 | 
						|
        .products-header {
 | 
						|
            background: #f8f9fa;
 | 
						|
            padding: 16px;
 | 
						|
            border-bottom: 1px solid #eee;
 | 
						|
        }
 | 
						|
 | 
						|
        .products-header h2 {
 | 
						|
            font-size: 16px;
 | 
						|
            font-weight: 600;
 | 
						|
            color: #333;
 | 
						|
        }
 | 
						|
 | 
						|
        .product-list {
 | 
						|
            padding: 0;
 | 
						|
        }
 | 
						|
 | 
						|
        .product-card {
 | 
						|
            padding: 16px;
 | 
						|
            border-bottom: 1px solid #f0f0f0;
 | 
						|
            transition: background-color 0.2s ease;
 | 
						|
        }
 | 
						|
 | 
						|
        .product-card:last-child {
 | 
						|
            border-bottom: none;
 | 
						|
        }
 | 
						|
 | 
						|
        .product-card:hover {
 | 
						|
            background-color: #f8f9fa;
 | 
						|
        }
 | 
						|
 | 
						|
        .product-info {
 | 
						|
            margin-bottom: 12px;
 | 
						|
        }
 | 
						|
 | 
						|
        .product-name {
 | 
						|
            font-size: 16px;
 | 
						|
            font-weight: 600;
 | 
						|
            color: #333;
 | 
						|
            margin-bottom: 8px;
 | 
						|
        }
 | 
						|
 | 
						|
        .product-details {
 | 
						|
            display: grid;
 | 
						|
            grid-template-columns: 1fr 1fr;
 | 
						|
            gap: 8px;
 | 
						|
            margin-bottom: 12px;
 | 
						|
        }
 | 
						|
 | 
						|
        .product-detail {
 | 
						|
            display: flex;
 | 
						|
            align-items: center;
 | 
						|
            gap: 4px;
 | 
						|
        }
 | 
						|
 | 
						|
        .detail-label {
 | 
						|
            font-size: 12px;
 | 
						|
            color: #666;
 | 
						|
            min-width: 40px;
 | 
						|
        }
 | 
						|
 | 
						|
        .detail-value {
 | 
						|
            font-size: 14px;
 | 
						|
            color: #333;
 | 
						|
            font-weight: 500;
 | 
						|
        }
 | 
						|
 | 
						|
        .product-price {
 | 
						|
            font-size: 18px;
 | 
						|
            font-weight: 700;
 | 
						|
            color: #e74c3c;
 | 
						|
            margin-bottom: 12px;
 | 
						|
        }
 | 
						|
 | 
						|
        .add-btn {
 | 
						|
            background: linear-gradient(135deg, #27ae60 0%, #2ecc71 100%);
 | 
						|
            color: white;
 | 
						|
            border: none;
 | 
						|
            padding: 10px 16px;
 | 
						|
            border-radius: 6px;
 | 
						|
            font-size: 14px;
 | 
						|
            font-weight: 500;
 | 
						|
            cursor: pointer;
 | 
						|
            transition: all 0.3s ease;
 | 
						|
            width: 100%;
 | 
						|
        }
 | 
						|
 | 
						|
        .add-btn:hover {
 | 
						|
            transform: translateY(-1px);
 | 
						|
            box-shadow: 0 3px 8px rgba(46, 204, 113, 0.3);
 | 
						|
        }
 | 
						|
 | 
						|
        .add-btn:active {
 | 
						|
            transform: translateY(0);
 | 
						|
        }
 | 
						|
 | 
						|
        .add-btn:disabled {
 | 
						|
            background: #95a5a6;
 | 
						|
            cursor: not-allowed;
 | 
						|
            transform: none;
 | 
						|
        }
 | 
						|
 | 
						|
        .add-btn.discount {
 | 
						|
            background: linear-gradient(135deg, #e67e22 0%, #f39c12 100%);
 | 
						|
        }
 | 
						|
 | 
						|
        .add-btn.discount:hover {
 | 
						|
            transform: translateY(-1px);
 | 
						|
            box-shadow: 0 3px 8px rgba(230, 126, 34, 0.3);
 | 
						|
        }
 | 
						|
 | 
						|
        .add-btn.discount:disabled {
 | 
						|
            background: #95a5a6;
 | 
						|
            cursor: not-allowed;
 | 
						|
            transform: none;
 | 
						|
        }
 | 
						|
 | 
						|
        .add-btn.discount:disabled:hover {
 | 
						|
            transform: none;
 | 
						|
            box-shadow: none;
 | 
						|
        }
 | 
						|
 | 
						|
        .pagination {
 | 
						|
            display: flex;
 | 
						|
            justify-content: center;
 | 
						|
            align-items: center;
 | 
						|
            gap: 8px;
 | 
						|
            background: white;
 | 
						|
            padding: 20px;
 | 
						|
            border-radius: 12px;
 | 
						|
            box-shadow: 0 2px 8px rgba(0,0,0,0.1);
 | 
						|
        }
 | 
						|
 | 
						|
        .pagination button {
 | 
						|
            padding: 8px 12px;
 | 
						|
            border: 1px solid #ddd;
 | 
						|
            background: white;
 | 
						|
            border-radius: 6px;
 | 
						|
            cursor: pointer;
 | 
						|
            font-size: 14px;
 | 
						|
            color: #666;
 | 
						|
            transition: all 0.2s ease;
 | 
						|
            min-width: 40px;
 | 
						|
        }
 | 
						|
 | 
						|
        .pagination button:hover {
 | 
						|
            background: #f8f9fa;
 | 
						|
            border-color: #667eea;
 | 
						|
        }
 | 
						|
 | 
						|
        .pagination button.active {
 | 
						|
            background: #667eea;
 | 
						|
            color: white;
 | 
						|
            border-color: #667eea;
 | 
						|
        }
 | 
						|
 | 
						|
        .pagination button:disabled {
 | 
						|
            opacity: 0.5;
 | 
						|
            cursor: not-allowed;
 | 
						|
        }
 | 
						|
 | 
						|
        .empty-state {
 | 
						|
            text-align: center;
 | 
						|
            padding: 40px 20px;
 | 
						|
            color: #999;
 | 
						|
        }
 | 
						|
 | 
						|
        .empty-state i {
 | 
						|
            font-size: 48px;
 | 
						|
            margin-bottom: 16px;
 | 
						|
            display: block;
 | 
						|
        }
 | 
						|
 | 
						|
        @media (min-width: 768px) {
 | 
						|
            .container {
 | 
						|
                max-width: 768px;
 | 
						|
                padding: 20px;
 | 
						|
            }
 | 
						|
 | 
						|
            .search-grid {
 | 
						|
                grid-template-columns: 1fr 1fr;
 | 
						|
            }
 | 
						|
 | 
						|
            .product-details {
 | 
						|
                grid-template-columns: 1fr 1fr 1fr 1fr;
 | 
						|
            }
 | 
						|
 | 
						|
            .add-btn {
 | 
						|
                width: auto;
 | 
						|
                min-width: 120px;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        .loading {
 | 
						|
            text-align: center;
 | 
						|
            padding: 20px;
 | 
						|
            color: #666;
 | 
						|
        }
 | 
						|
 | 
						|
        .toast {
 | 
						|
            position: fixed;
 | 
						|
            top: 20px;
 | 
						|
            left: 50%;
 | 
						|
            transform: translateX(-50%);
 | 
						|
            background: #333;
 | 
						|
            color: white;
 | 
						|
            padding: 12px 20px;
 | 
						|
            border-radius: 8px;
 | 
						|
            font-size: 14px;
 | 
						|
            z-index: 1000;
 | 
						|
            opacity: 0;
 | 
						|
            transition: opacity 0.3s ease;
 | 
						|
        }
 | 
						|
 | 
						|
        .toast.show {
 | 
						|
            opacity: 1;
 | 
						|
        }
 | 
						|
 | 
						|
        .toast.success {
 | 
						|
            background: #27ae60;
 | 
						|
        }
 | 
						|
 | 
						|
        .toast.error {
 | 
						|
            background: #e74c3c;
 | 
						|
        }
 | 
						|
 | 
						|
        .points-status {
 | 
						|
            display: inline-block;
 | 
						|
            padding: 4px 8px;
 | 
						|
            border-radius: 12px;
 | 
						|
            font-size: 12px;
 | 
						|
            font-weight: 500;
 | 
						|
            margin-left: 8px;
 | 
						|
        }
 | 
						|
 | 
						|
        .points-status.active {
 | 
						|
            background: #e8f5e8;
 | 
						|
            color: #27ae60;
 | 
						|
            border: 1px solid #27ae60;
 | 
						|
        }
 | 
						|
 | 
						|
        .points-status.discount {
 | 
						|
            background: #fff3cd;
 | 
						|
            color: #e67e22;
 | 
						|
            border: 1px solid #e67e22;
 | 
						|
        }
 | 
						|
 | 
						|
        .points-status.inactive {
 | 
						|
            background: #f8f8f8;
 | 
						|
            color: #666;
 | 
						|
            border: 1px solid #ddd;
 | 
						|
        }
 | 
						|
 | 
						|
        .modal-overlay {
 | 
						|
            position: fixed;
 | 
						|
            top: 0;
 | 
						|
            left: 0;
 | 
						|
            right: 0;
 | 
						|
            bottom: 0;
 | 
						|
            background: rgba(0, 0, 0, 0.5);
 | 
						|
            z-index: 1000;
 | 
						|
            display: none;
 | 
						|
            align-items: center;
 | 
						|
            justify-content: center;
 | 
						|
            backdrop-filter: blur(4px);
 | 
						|
        }
 | 
						|
 | 
						|
        .modal-overlay.show {
 | 
						|
            display: flex;
 | 
						|
        }
 | 
						|
 | 
						|
        .modal-content {
 | 
						|
            background: white;
 | 
						|
            border-radius: 16px;
 | 
						|
            max-width: 400px;
 | 
						|
            width: 90%;
 | 
						|
            max-height: 80vh;
 | 
						|
            overflow-y: auto;
 | 
						|
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
 | 
						|
            animation: modalSlideIn 0.3s ease-out;
 | 
						|
        }
 | 
						|
 | 
						|
        @keyframes modalSlideIn {
 | 
						|
            from {
 | 
						|
                transform: scale(0.8) translateY(-20px);
 | 
						|
                opacity: 0;
 | 
						|
            }
 | 
						|
            to {
 | 
						|
                transform: scale(1) translateY(0);
 | 
						|
                opacity: 1;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        .modal-header {
 | 
						|
            padding: 20px 24px;
 | 
						|
            border-bottom: 1px solid #eee;
 | 
						|
            position: relative;
 | 
						|
        }
 | 
						|
 | 
						|
        .modal-title {
 | 
						|
            font-size: 18px;
 | 
						|
            font-weight: 600;
 | 
						|
            color: #333;
 | 
						|
            margin: 0;
 | 
						|
        }
 | 
						|
 | 
						|
        .modal-close {
 | 
						|
            position: absolute;
 | 
						|
            top: 20px;
 | 
						|
            right: 24px;
 | 
						|
            background: none;
 | 
						|
            border: none;
 | 
						|
            font-size: 24px;
 | 
						|
            color: #999;
 | 
						|
            cursor: pointer;
 | 
						|
            line-height: 1;
 | 
						|
            transition: color 0.2s ease;
 | 
						|
        }
 | 
						|
 | 
						|
        .modal-close:hover {
 | 
						|
            color: #666;
 | 
						|
        }
 | 
						|
 | 
						|
        .modal-body {
 | 
						|
            padding: 24px;
 | 
						|
        }
 | 
						|
 | 
						|
        .exchange-info {
 | 
						|
            margin-bottom: 24px;
 | 
						|
        }
 | 
						|
 | 
						|
        .info-item {
 | 
						|
            display: flex;
 | 
						|
            justify-content: space-between;
 | 
						|
            align-items: center;
 | 
						|
            padding: 12px 0;
 | 
						|
            border-bottom: 1px solid #f5f5f5;
 | 
						|
        }
 | 
						|
 | 
						|
        .info-item:last-child {
 | 
						|
            border-bottom: none;
 | 
						|
        }
 | 
						|
 | 
						|
        .info-label {
 | 
						|
            font-size: 14px;
 | 
						|
            color: #666;
 | 
						|
            font-weight: 500;
 | 
						|
        }
 | 
						|
 | 
						|
        .info-value {
 | 
						|
            font-size: 16px;
 | 
						|
            color: #333;
 | 
						|
            font-weight: 600;
 | 
						|
        }
 | 
						|
 | 
						|
        .info-value.highlight {
 | 
						|
            color: #e74c3c;
 | 
						|
        }
 | 
						|
 | 
						|
        .modal-footer {
 | 
						|
            padding: 16px 24px;
 | 
						|
            border-top: 1px solid #eee;
 | 
						|
            display: flex;
 | 
						|
            gap: 12px;
 | 
						|
        }
 | 
						|
 | 
						|
        .modal-btn {
 | 
						|
            flex: 1;
 | 
						|
            padding: 12px 16px;
 | 
						|
            border: none;
 | 
						|
            border-radius: 8px;
 | 
						|
            font-size: 16px;
 | 
						|
            font-weight: 500;
 | 
						|
            cursor: pointer;
 | 
						|
            transition: all 0.3s ease;
 | 
						|
        }
 | 
						|
 | 
						|
        .modal-btn.cancel {
 | 
						|
            background: #f8f9fa;
 | 
						|
            color: #666;
 | 
						|
            border: 1px solid #ddd;
 | 
						|
        }
 | 
						|
 | 
						|
        .modal-btn.cancel:hover {
 | 
						|
            background: #e9ecef;
 | 
						|
            border-color: #adb5bd;
 | 
						|
        }
 | 
						|
 | 
						|
        .modal-btn.confirm {
 | 
						|
            background: linear-gradient(135deg, #27ae60 0%, #2ecc71 100%);
 | 
						|
            color: white;
 | 
						|
        }
 | 
						|
 | 
						|
        .modal-btn.confirm:hover {
 | 
						|
            transform: translateY(-1px);
 | 
						|
            box-shadow: 0 4px 12px rgba(39, 174, 96, 0.3);
 | 
						|
        }
 | 
						|
 | 
						|
        .info-input {
 | 
						|
            flex: 1;
 | 
						|
            padding: 8px 12px;
 | 
						|
            border: 1px solid #ddd;
 | 
						|
            border-radius: 6px;
 | 
						|
            font-size: 14px;
 | 
						|
            font-weight: 600;
 | 
						|
            color: #333;
 | 
						|
            transition: all 0.3s ease;
 | 
						|
            min-width: 120px;
 | 
						|
            text-align: right;
 | 
						|
        }
 | 
						|
 | 
						|
        .info-input:focus {
 | 
						|
            outline: none;
 | 
						|
            border-color: #667eea;
 | 
						|
            box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.1);
 | 
						|
        }
 | 
						|
 | 
						|
        .info-input.highlight {
 | 
						|
            color: #e74c3c;
 | 
						|
            border-color: #e74c3c;
 | 
						|
        }
 | 
						|
 | 
						|
        .info-input.highlight:focus {
 | 
						|
            border-color: #e74c3c;
 | 
						|
            box-shadow: 0 0 0 2px rgba(231, 76, 60, 0.1);
 | 
						|
        }
 | 
						|
 | 
						|
        .info-input::placeholder {
 | 
						|
            color: #999;
 | 
						|
            font-weight: normal;
 | 
						|
        }
 | 
						|
 | 
						|
        .info-input.error {
 | 
						|
            border-color: #e74c3c;
 | 
						|
            background-color: #ffeaea;
 | 
						|
        }
 | 
						|
 | 
						|
        .input-error-message {
 | 
						|
            color: #e74c3c;
 | 
						|
            font-size: 12px;
 | 
						|
            margin-top: 4px;
 | 
						|
            display: none;
 | 
						|
        }
 | 
						|
    </style>
 | 
						|
</head>
 | 
						|
<body>
 | 
						|
    <div class="container">
 | 
						|
        <div class="header">
 | 
						|
            <h1>积分商城 - 商品管理</h1>
 | 
						|
        </div>
 | 
						|
 | 
						|
        <div class="search-section">
 | 
						|
            <div class="search-grid">
 | 
						|
                <div class="input-group">
 | 
						|
                    <label for="shopName">店铺</label>
 | 
						|
                    <input type="text" id="shopName" placeholder="请输入店铺名称">
 | 
						|
                </div>
 | 
						|
                <div class="input-group">
 | 
						|
                    <label for="productName">商品名称</label>
 | 
						|
                    <input type="text" id="productName" placeholder="请输入商品名称">
 | 
						|
                </div>
 | 
						|
                <div class="input-group">
 | 
						|
                    <label for="productId">商品ID</label>
 | 
						|
                    <input type="text" id="productId" placeholder="请输入商品ID">
 | 
						|
                </div>
 | 
						|
            </div>
 | 
						|
            <button class="search-btn" onclick="searchProducts()">查询</button>
 | 
						|
        </div>
 | 
						|
 | 
						|
        <div class="products-section">
 | 
						|
            <div class="products-header">
 | 
						|
                <h2>商品列表</h2>
 | 
						|
            </div>
 | 
						|
            <div class="product-list" id="productList">
 | 
						|
                <div class="product-card">
 | 
						|
                    <div class="product-info">
 | 
						|
                        <div class="product-name">猪肉</div>
 | 
						|
                        <div class="product-details">
 | 
						|
                            <div class="product-detail">
 | 
						|
                                <span class="detail-label">ID:</span>
 | 
						|
                                <span class="detail-value">1212</span>
 | 
						|
                            </div>
 | 
						|
                            <div class="product-detail">
 | 
						|
                                <span class="detail-label">店铺:</span>
 | 
						|
                                <span class="detail-value">猪肉铺</span>
 | 
						|
                            </div>
 | 
						|
                            <div class="product-detail">
 | 
						|
                                <span class="detail-label">规格:</span>
 | 
						|
                                <span class="detail-value">大份</span>
 | 
						|
                            </div>
 | 
						|
                        </div>
 | 
						|
                        <div class="product-price">¥2</div>
 | 
						|
                    </div>
 | 
						|
                    <button class="add-btn" onclick="addToPointsMall('1212', '猪肉', 'exchange')" style="margin-bottom: 8px;">添加为积分换购商品</button>
 | 
						|
                    <button class="add-btn discount" onclick="addToPointsMall('1212', '猪肉', 'discount')">添加为积分优惠购商品</button>
 | 
						|
                </div>
 | 
						|
 | 
						|
                <div class="product-card">
 | 
						|
                    <div class="product-info">
 | 
						|
                        <div class="product-name">牛肉</div>
 | 
						|
                        <div class="product-details">
 | 
						|
                            <div class="product-detail">
 | 
						|
                                <span class="detail-label">ID:</span>
 | 
						|
                                <span class="detail-value">1213</span>
 | 
						|
                            </div>
 | 
						|
                            <div class="product-detail">
 | 
						|
                                <span class="detail-label">店铺:</span>
 | 
						|
                                <span class="detail-value">牛肉铺</span>
 | 
						|
                            </div>
 | 
						|
                            <div class="product-detail">
 | 
						|
                                <span class="detail-label">规格:</span>
 | 
						|
                                <span class="detail-value">小份</span>
 | 
						|
                            </div>
 | 
						|
                        </div>
 | 
						|
                        <div class="product-price">¥5</div>
 | 
						|
                    </div>
 | 
						|
                    <button class="add-btn" onclick="addToPointsMall('1213', '牛肉', 'exchange')" style="margin-bottom: 8px;">添加为积分换购商品</button>
 | 
						|
                    <button class="add-btn discount" onclick="addToPointsMall('1213', '牛肉', 'discount')">添加为积分优惠购商品</button>
 | 
						|
                </div>
 | 
						|
 | 
						|
                <div class="product-card">
 | 
						|
                    <div class="product-info">
 | 
						|
                        <div class="product-name">鸡肉</div>
 | 
						|
                        <div class="product-details">
 | 
						|
                            <div class="product-detail">
 | 
						|
                                <span class="detail-label">ID:</span>
 | 
						|
                                <span class="detail-value">1214</span>
 | 
						|
                            </div>
 | 
						|
                            <div class="product-detail">
 | 
						|
                                <span class="detail-label">店铺:</span>
 | 
						|
                                <span class="detail-value">鸡肉铺</span>
 | 
						|
                            </div>
 | 
						|
                            <div class="product-detail">
 | 
						|
                                <span class="detail-label">规格:</span>
 | 
						|
                                <span class="detail-value">无</span>
 | 
						|
                            </div>
 | 
						|
                        </div>
 | 
						|
                        <div class="product-price">¥3</div>
 | 
						|
                    </div>
 | 
						|
                    <button class="add-btn" onclick="addToPointsMall('1214', '鸡肉', 'exchange')" style="margin-bottom: 8px;">添加为积分换购商品</button>
 | 
						|
                    <button class="add-btn discount" onclick="addToPointsMall('1214', '鸡肉', 'discount')">添加为积分优惠购商品</button>
 | 
						|
                </div>
 | 
						|
            </div>
 | 
						|
        </div>
 | 
						|
 | 
						|
        <div class="pagination">
 | 
						|
            <button onclick="changePage('prev')" id="prevBtn">Previous</button>
 | 
						|
            <button class="active" onclick="changePage(1)">1</button>
 | 
						|
            <button onclick="changePage(2)">2</button>
 | 
						|
            <button onclick="changePage(3)">3</button>
 | 
						|
            <button onclick="changePage('next')" id="nextBtn">Next</button>
 | 
						|
        </div>
 | 
						|
    </div>
 | 
						|
 | 
						|
    <div class="toast" id="toast"></div>
 | 
						|
 | 
						|
    <!-- 积分兑换确认弹窗 -->
 | 
						|
    <div class="modal-overlay" id="exchangeModal">
 | 
						|
        <div class="modal-content">
 | 
						|
            <div class="modal-header">
 | 
						|
                <h3 class="modal-title" id="modalTitle">添加积分商品确认</h3>
 | 
						|
                <button class="modal-close" onclick="closeExchangeModal()">×</button>
 | 
						|
            </div>
 | 
						|
            <div class="modal-body">
 | 
						|
                <div class="exchange-info">
 | 
						|
                    <div class="info-item">
 | 
						|
                        <span class="info-label">商品ID</span>
 | 
						|
                        <span class="info-value" id="modalProductId">-</span>
 | 
						|
                    </div>
 | 
						|
                    <div class="info-item">
 | 
						|
                        <span class="info-label">商品名称</span>
 | 
						|
                        <span class="info-value" id="modalProductName">-</span>
 | 
						|
                    </div>
 | 
						|
                    <div class="info-item">
 | 
						|
                        <span class="info-label">归属摊位</span>
 | 
						|
                        <span class="info-value" id="modalProductShop">-</span>
 | 
						|
                    </div>
 | 
						|
                    <div class="info-item">
 | 
						|
                        <span class="info-label">规格名称</span>
 | 
						|
                        <span class="info-value" id="modalProductSpec">-</span>
 | 
						|
                    </div>
 | 
						|
                    <div class="info-item">
 | 
						|
                        <span class="info-label">SKU-ID</span>
 | 
						|
                        <span class="info-value" id="modalProductSkuId">-</span>
 | 
						|
                    </div>
 | 
						|
                    <div class="info-item">
 | 
						|
                        <span class="info-label">商品原价</span>
 | 
						|
                        <span class="info-value" id="modalProductPrice">-</span>
 | 
						|
                    </div>
 | 
						|
                    <div class="info-item" id="pointsRequiredRow">
 | 
						|
                        <span class="info-label">兑换所需积分</span>
 | 
						|
                        <input type="number" class="info-input highlight" id="modalPointsRequired" min="1" placeholder="请输入积分">
 | 
						|
                    </div>
 | 
						|
                    <div class="info-item" id="discountPointsRow" style="display: none;">
 | 
						|
                        <span class="info-label">优惠购所需积分</span>
 | 
						|
                        <input type="number" class="info-input highlight" id="modalDiscountPoints" min="1" placeholder="请输入优惠购所需积分">
 | 
						|
                    </div>
 | 
						|
                    <div class="info-item" id="discountPriceRow" style="display: none;">
 | 
						|
                        <span class="info-label">优惠购商品价格</span>
 | 
						|
                        <input type="number" class="info-input" id="modalDiscountPrice" min="0" step="0.01" placeholder="请输入优惠购价格">
 | 
						|
                    </div>
 | 
						|
                    <div class="info-item">
 | 
						|
                        <span class="info-label">最大可兑换数量</span>
 | 
						|
                        <input type="number" class="info-input" id="modalMaxExchange" min="1" placeholder="请输入数量">
 | 
						|
                    </div>
 | 
						|
                    <div class="info-item" id="exchangeNoticeRow" style="display: none;">
 | 
						|
                        <span class="info-label" style="color: #999; font-size: 12px; font-weight: normal;">说明</span>
 | 
						|
                        <span class="info-value" style="color: #999; font-size: 12px; font-weight: normal;">固定支付0.01,商业支付要求</span>
 | 
						|
                    </div>
 | 
						|
                </div>
 | 
						|
            </div>
 | 
						|
            <div class="modal-footer">
 | 
						|
                <button class="modal-btn cancel" onclick="closeExchangeModal()">取消</button>
 | 
						|
                <button class="modal-btn confirm" onclick="confirmAddToPointsMall()" id="confirmBtn">确认添加</button>
 | 
						|
            </div>
 | 
						|
        </div>
 | 
						|
    </div>
 | 
						|
 | 
						|
    <script>
 | 
						|
        let currentPage = 1;
 | 
						|
        const totalPages = 3;
 | 
						|
 | 
						|
        // 模拟商品数据
 | 
						|
        const allProducts = [
 | 
						|
            {id: '1212', name: '猪肉', shop: '猪肉铺', spec: '大份', price: 2, stock: 150, skuId: 'SKU1212001', exchangeType: 'none', pointsRequired: 200, maxExchangeCount: 50, discountPoints: 50},
 | 
						|
            {id: '1213', name: '牛肉', shop: '牛肉铺', spec: '小份', price: 5, stock: 80, skuId: 'SKU1213002', exchangeType: 'exchange', pointsRequired: 500, maxExchangeCount: 30, discountPoints: 100},
 | 
						|
            {id: '1214', name: '鸡肉', shop: '鸡肉铺', spec: '无', price: 3, stock: 200, skuId: 'SKU1214003', exchangeType: 'none', pointsRequired: 300, maxExchangeCount: 80, discountPoints: 80},
 | 
						|
            {id: '1215', name: '鱼肉', shop: '鱼肉铺', spec: '中份', price: 8, stock: 60, skuId: 'SKU1215004', exchangeType: 'discount', pointsRequired: 800, maxExchangeCount: 25, discountPoints: 200},
 | 
						|
            {id: '1216', name: '虾', shop: '海鲜铺', spec: '特大', price: 12, stock: 45, skuId: 'SKU1216005', exchangeType: 'none', pointsRequired: 1200, maxExchangeCount: 20, discountPoints: 300},
 | 
						|
            {id: '1217', name: '蟹', shop: '海鲜铺', spec: '精选', price: 25, stock: 30, skuId: 'SKU1217006', exchangeType: 'none', pointsRequired: 2500, maxExchangeCount: 15, discountPoints: 500},
 | 
						|
        ];
 | 
						|
 | 
						|
        let filteredProducts = [...allProducts];
 | 
						|
        let currentEditingProduct = null;
 | 
						|
        let currentExchangeType = null;
 | 
						|
 | 
						|
        function showToast(message, type = 'success') {
 | 
						|
            const toast = document.getElementById('toast');
 | 
						|
            toast.textContent = message;
 | 
						|
            toast.className = `toast ${type} show`;
 | 
						|
            
 | 
						|
            setTimeout(() => {
 | 
						|
                toast.classList.remove('show');
 | 
						|
            }, 3000);
 | 
						|
        }
 | 
						|
 | 
						|
        function searchProducts() {
 | 
						|
            const shopName = document.getElementById('shopName').value.trim().toLowerCase();
 | 
						|
            const productName = document.getElementById('productName').value.trim().toLowerCase();
 | 
						|
            const productId = document.getElementById('productId').value.trim();
 | 
						|
 | 
						|
            filteredProducts = allProducts.filter(product => {
 | 
						|
                const matchShop = !shopName || product.shop.toLowerCase().includes(shopName);
 | 
						|
                const matchName = !productName || product.name.toLowerCase().includes(productName);
 | 
						|
                const matchId = !productId || product.id.includes(productId);
 | 
						|
                
 | 
						|
                return matchShop && matchName && matchId;
 | 
						|
            });
 | 
						|
 | 
						|
            currentPage = 1;
 | 
						|
            renderProducts();
 | 
						|
            updatePagination();
 | 
						|
 | 
						|
            if (filteredProducts.length === 0) {
 | 
						|
                showToast('未找到匹配的商品', 'error');
 | 
						|
            } else {
 | 
						|
                showToast(`找到 ${filteredProducts.length} 个商品`);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        function renderProducts() {
 | 
						|
            const productList = document.getElementById('productList');
 | 
						|
            const startIndex = (currentPage - 1) * 3;
 | 
						|
            const endIndex = startIndex + 3;
 | 
						|
            const pageProducts = filteredProducts.slice(startIndex, endIndex);
 | 
						|
 | 
						|
            if (pageProducts.length === 0) {
 | 
						|
                productList.innerHTML = `
 | 
						|
                    <div class="empty-state">
 | 
						|
                        <i>📦</i>
 | 
						|
                        <div>暂无商品数据</div>
 | 
						|
                    </div>
 | 
						|
                `;
 | 
						|
                return;
 | 
						|
            }
 | 
						|
 | 
						|
            productList.innerHTML = pageProducts.map(product => {
 | 
						|
                return `
 | 
						|
                <div class="product-card">
 | 
						|
                    <div class="product-info">
 | 
						|
                        <div class="product-name">${product.name}</div>
 | 
						|
                        <div class="product-details">
 | 
						|
                            <div class="product-detail">
 | 
						|
                                <span class="detail-label">ID:</span>
 | 
						|
                                <span class="detail-value">${product.id}</span>
 | 
						|
                            </div>
 | 
						|
                            <div class="product-detail">
 | 
						|
                                <span class="detail-label">店铺:</span>
 | 
						|
                                <span class="detail-value">${product.shop}</span>
 | 
						|
                            </div>
 | 
						|
                            <div class="product-detail">
 | 
						|
                                <span class="detail-label">规格:</span>
 | 
						|
                                <span class="detail-value">${product.spec}</span>
 | 
						|
                            </div>
 | 
						|
                        </div>
 | 
						|
                        <div class="product-price">¥${product.price}</div>
 | 
						|
                    </div>
 | 
						|
                    <button class="add-btn" onclick="addToPointsMall('${product.id}', '${product.name}', 'exchange')" style="margin-bottom: 8px;">添加为积分换购商品</button>
 | 
						|
                    <button class="add-btn discount" onclick="addToPointsMall('${product.id}', '${product.name}', 'discount')">添加为积分优惠购商品</button>
 | 
						|
                </div>`;
 | 
						|
            }).join('');
 | 
						|
        }
 | 
						|
 | 
						|
        function addToPointsMall(productId, productName, exchangeType) {
 | 
						|
            const product = allProducts.find(p => p.id === productId);
 | 
						|
            if (!product) return;
 | 
						|
 | 
						|
            currentEditingProduct = product;
 | 
						|
            currentExchangeType = exchangeType;
 | 
						|
            showExchangeModal(product, exchangeType);
 | 
						|
        }
 | 
						|
 | 
						|
        function showExchangeModal(product, exchangeType) {
 | 
						|
            // 更新弹窗标题
 | 
						|
            const modalTitle = document.getElementById('modalTitle');
 | 
						|
            const pointsRequiredRow = document.getElementById('pointsRequiredRow');
 | 
						|
            const discountPointsRow = document.getElementById('discountPointsRow');
 | 
						|
            const discountPriceRow = document.getElementById('discountPriceRow');
 | 
						|
            const exchangeNoticeRow = document.getElementById('exchangeNoticeRow');
 | 
						|
            
 | 
						|
            if (exchangeType === 'exchange') {
 | 
						|
                modalTitle.textContent = '添加积分换购商品确认';
 | 
						|
                pointsRequiredRow.style.display = 'flex';
 | 
						|
                discountPointsRow.style.display = 'none';
 | 
						|
                discountPriceRow.style.display = 'none';
 | 
						|
                exchangeNoticeRow.style.display = 'flex';
 | 
						|
            } else if (exchangeType === 'discount') {
 | 
						|
                modalTitle.textContent = '添加积分优惠购商品确认';
 | 
						|
                pointsRequiredRow.style.display = 'none';
 | 
						|
                discountPointsRow.style.display = 'flex';
 | 
						|
                discountPriceRow.style.display = 'flex';
 | 
						|
                exchangeNoticeRow.style.display = 'none';
 | 
						|
            }
 | 
						|
            
 | 
						|
            document.getElementById('modalProductId').textContent = product.id;
 | 
						|
            document.getElementById('modalProductName').textContent = product.name;
 | 
						|
            document.getElementById('modalProductShop').textContent = product.shop;
 | 
						|
            document.getElementById('modalProductSpec').textContent = product.spec;
 | 
						|
            document.getElementById('modalProductSkuId').textContent = product.skuId || product.id;
 | 
						|
            document.getElementById('modalProductPrice').textContent = `¥${product.price}`;
 | 
						|
            
 | 
						|
            if (exchangeType === 'exchange') {
 | 
						|
                document.getElementById('modalPointsRequired').value = product.pointsRequired;
 | 
						|
            } else if (exchangeType === 'discount') {
 | 
						|
                document.getElementById('modalDiscountPoints').value = product.discountPoints;
 | 
						|
                document.getElementById('modalDiscountPrice').value = product.discountPrice || product.price;
 | 
						|
            }
 | 
						|
            
 | 
						|
            document.getElementById('modalMaxExchange').value = product.maxExchangeCount;
 | 
						|
            
 | 
						|
            // 清除之前的错误状态
 | 
						|
            clearInputErrors();
 | 
						|
            
 | 
						|
            document.getElementById('exchangeModal').classList.add('show');
 | 
						|
            document.body.style.overflow = 'hidden'; // 防止背景滚动
 | 
						|
        }
 | 
						|
 | 
						|
        function closeExchangeModal() {
 | 
						|
            document.getElementById('exchangeModal').classList.remove('show');
 | 
						|
            document.body.style.overflow = 'auto';
 | 
						|
            currentEditingProduct = null;
 | 
						|
            currentExchangeType = null;
 | 
						|
        }
 | 
						|
 | 
						|
        function validateInputs() {
 | 
						|
            const pointsInput = document.getElementById('modalPointsRequired');
 | 
						|
            const discountPointsInput = document.getElementById('modalDiscountPoints');
 | 
						|
            const discountPriceInput = document.getElementById('modalDiscountPrice');
 | 
						|
            const maxExchangeInput = document.getElementById('modalMaxExchange');
 | 
						|
            
 | 
						|
            let isValid = true;
 | 
						|
            
 | 
						|
            // 验证积分输入(根据类型)
 | 
						|
            if (currentExchangeType === 'exchange') {
 | 
						|
                const pointsValue = parseInt(pointsInput.value);
 | 
						|
                if (!pointsValue || pointsValue < 1) {
 | 
						|
                    pointsInput.classList.add('error');
 | 
						|
                    showToast('兑换所需积分必须大于0', 'error');
 | 
						|
                    isValid = false;
 | 
						|
                } else {
 | 
						|
                    pointsInput.classList.remove('error');
 | 
						|
                }
 | 
						|
            } else if (currentExchangeType === 'discount') {
 | 
						|
                const discountValue = parseInt(discountPointsInput.value);
 | 
						|
                if (!discountValue || discountValue < 1) {
 | 
						|
                    discountPointsInput.classList.add('error');
 | 
						|
                    showToast('优惠购所需积分必须大于0', 'error');
 | 
						|
                    isValid = false;
 | 
						|
                } else {
 | 
						|
                    discountPointsInput.classList.remove('error');
 | 
						|
                }
 | 
						|
                
 | 
						|
                const discountPriceValue = parseFloat(discountPriceInput.value);
 | 
						|
                if (isNaN(discountPriceValue) || discountPriceValue < 0) {
 | 
						|
                    discountPriceInput.classList.add('error');
 | 
						|
                    showToast('优惠购商品价格必须大于等于0', 'error');
 | 
						|
                    isValid = false;
 | 
						|
                } else {
 | 
						|
                    discountPriceInput.classList.remove('error');
 | 
						|
                }
 | 
						|
            }
 | 
						|
            
 | 
						|
            // 验证数量输入
 | 
						|
            const maxExchangeValue = parseInt(maxExchangeInput.value);
 | 
						|
            if (!maxExchangeValue || maxExchangeValue < 1) {
 | 
						|
                maxExchangeInput.classList.add('error');
 | 
						|
                showToast('最大可兑换数量必须大于0', 'error');
 | 
						|
                isValid = false;
 | 
						|
            } else if (maxExchangeValue > currentEditingProduct.stock) {
 | 
						|
                maxExchangeInput.classList.add('error');
 | 
						|
                showToast('最大可兑换数量不能超过库存数量', 'error');
 | 
						|
                isValid = false;
 | 
						|
            } else {
 | 
						|
                maxExchangeInput.classList.remove('error');
 | 
						|
            }
 | 
						|
            
 | 
						|
            return isValid;
 | 
						|
        }
 | 
						|
        
 | 
						|
        function clearInputErrors() {
 | 
						|
            document.getElementById('modalPointsRequired').classList.remove('error');
 | 
						|
            document.getElementById('modalDiscountPoints').classList.remove('error');
 | 
						|
            document.getElementById('modalDiscountPrice').classList.remove('error');
 | 
						|
            document.getElementById('modalMaxExchange').classList.remove('error');
 | 
						|
        }
 | 
						|
 | 
						|
        function confirmAddToPointsMall() {
 | 
						|
            if (!currentEditingProduct || !currentExchangeType) return;
 | 
						|
            
 | 
						|
            // 验证输入
 | 
						|
            if (!validateInputs()) {
 | 
						|
                return;
 | 
						|
            }
 | 
						|
 | 
						|
            const confirmBtn = document.getElementById('confirmBtn');
 | 
						|
            const maxExchangeCount = parseInt(document.getElementById('modalMaxExchange').value);
 | 
						|
            
 | 
						|
            let pointsValue = 0;
 | 
						|
            let discountPriceValue = 0;
 | 
						|
            let successMessage = '';
 | 
						|
            
 | 
						|
            if (currentExchangeType === 'exchange') {
 | 
						|
                pointsValue = parseInt(document.getElementById('modalPointsRequired').value);
 | 
						|
                successMessage = `${currentEditingProduct.name} 已成功添加到积分换购商城!需要${pointsValue}积分,最多可兑换${maxExchangeCount}件`;
 | 
						|
            } else if (currentExchangeType === 'discount') {
 | 
						|
                pointsValue = parseInt(document.getElementById('modalDiscountPoints').value);
 | 
						|
                discountPriceValue = parseFloat(document.getElementById('modalDiscountPrice').value);
 | 
						|
                successMessage = `${currentEditingProduct.name} 已成功添加到积分优惠购商城!需要${pointsValue}积分,优惠购价格¥${discountPriceValue},最多可购买${maxExchangeCount}件`;
 | 
						|
            }
 | 
						|
            
 | 
						|
            confirmBtn.disabled = true;
 | 
						|
            confirmBtn.textContent = '添加中...';
 | 
						|
 | 
						|
            setTimeout(() => {
 | 
						|
                // 更新数据状态
 | 
						|
                currentEditingProduct.exchangeType = currentExchangeType;
 | 
						|
                currentEditingProduct.maxExchangeCount = maxExchangeCount;
 | 
						|
                
 | 
						|
                if (currentExchangeType === 'exchange') {
 | 
						|
                    currentEditingProduct.pointsRequired = pointsValue;
 | 
						|
                } else if (currentExchangeType === 'discount') {
 | 
						|
                    currentEditingProduct.discountPoints = pointsValue;
 | 
						|
                    currentEditingProduct.discountPrice = discountPriceValue;
 | 
						|
                }
 | 
						|
                
 | 
						|
                // 重新渲染当前页面
 | 
						|
                renderProducts();
 | 
						|
                
 | 
						|
                // 关闭弹窗
 | 
						|
                closeExchangeModal();
 | 
						|
                
 | 
						|
                // 恢复按钮状态
 | 
						|
                confirmBtn.disabled = false;
 | 
						|
                confirmBtn.textContent = '确认添加';
 | 
						|
                
 | 
						|
                showToast(successMessage);
 | 
						|
            }, 1000);
 | 
						|
        }
 | 
						|
 | 
						|
        function changePage(page) {
 | 
						|
            if (page === 'prev' && currentPage > 1) {
 | 
						|
                currentPage--;
 | 
						|
            } else if (page === 'next' && currentPage < Math.ceil(filteredProducts.length / 3)) {
 | 
						|
                currentPage++;
 | 
						|
            } else if (typeof page === 'number') {
 | 
						|
                currentPage = page;
 | 
						|
            }
 | 
						|
 | 
						|
            renderProducts();
 | 
						|
            updatePagination();
 | 
						|
        }
 | 
						|
 | 
						|
        function updatePagination() {
 | 
						|
            const maxPages = Math.ceil(filteredProducts.length / 3);
 | 
						|
            const prevBtn = document.getElementById('prevBtn');
 | 
						|
            const nextBtn = document.getElementById('nextBtn');
 | 
						|
 | 
						|
            prevBtn.disabled = currentPage === 1;
 | 
						|
            nextBtn.disabled = currentPage === maxPages || maxPages === 0;
 | 
						|
 | 
						|
            // 更新页码按钮
 | 
						|
            const pageButtons = document.querySelectorAll('.pagination button:not(#prevBtn):not(#nextBtn)');
 | 
						|
            pageButtons.forEach((btn, index) => {
 | 
						|
                const pageNum = index + 1;
 | 
						|
                btn.style.display = pageNum <= maxPages ? 'block' : 'none';
 | 
						|
                btn.classList.toggle('active', pageNum === currentPage);
 | 
						|
            });
 | 
						|
        }
 | 
						|
 | 
						|
        // 初始化页面
 | 
						|
        document.addEventListener('DOMContentLoaded', function() {
 | 
						|
            renderProducts();
 | 
						|
            updatePagination();
 | 
						|
 | 
						|
            // 添加输入框回车搜索功能
 | 
						|
            document.addEventListener('keypress', function(e) {
 | 
						|
                if (e.key === 'Enter') {
 | 
						|
                    searchProducts();
 | 
						|
                }
 | 
						|
            });
 | 
						|
 | 
						|
            // 点击弹窗背景关闭弹窗
 | 
						|
            document.getElementById('exchangeModal').addEventListener('click', function(e) {
 | 
						|
                if (e.target === this) {
 | 
						|
                    closeExchangeModal();
 | 
						|
                }
 | 
						|
            });
 | 
						|
 | 
						|
            // ESC键关闭弹窗
 | 
						|
            document.addEventListener('keydown', function(e) {
 | 
						|
                if (e.key === 'Escape') {
 | 
						|
                    closeExchangeModal();
 | 
						|
                }
 | 
						|
            });
 | 
						|
 | 
						|
            // 输入框实时验证
 | 
						|
            document.getElementById('modalPointsRequired').addEventListener('input', function() {
 | 
						|
                if (this.classList.contains('error')) {
 | 
						|
                    this.classList.remove('error');
 | 
						|
                }
 | 
						|
            });
 | 
						|
            
 | 
						|
            document.getElementById('modalDiscountPoints').addEventListener('input', function() {
 | 
						|
                if (this.classList.contains('error')) {
 | 
						|
                    this.classList.remove('error');
 | 
						|
                }
 | 
						|
            });
 | 
						|
            
 | 
						|
            document.getElementById('modalDiscountPrice').addEventListener('input', function() {
 | 
						|
                if (this.classList.contains('error')) {
 | 
						|
                    this.classList.remove('error');
 | 
						|
                }
 | 
						|
            });
 | 
						|
            
 | 
						|
            document.getElementById('modalMaxExchange').addEventListener('input', function() {
 | 
						|
                if (this.classList.contains('error')) {
 | 
						|
                    this.classList.remove('error');
 | 
						|
                }
 | 
						|
            });
 | 
						|
        });
 | 
						|
    </script>
 | 
						|
</body>
 | 
						|
</html> |