Эх сурвалжийг харах

longwei-2025-07-31 02:49:22

genlitex 1 өдөр өмнө
parent
commit
201352e6f3

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
dist/assets/index-4owCqU6i.css


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 0
dist/assets/index-B1nFdOqT.css


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 4 - 0
dist/assets/index-BgbU1ENp.js


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 0 - 4
dist/assets/index-C_m0F2Qf.js


+ 2 - 2
dist/index.html

@@ -5,8 +5,8 @@
     <link rel="icon" type="image/svg+xml" href="/vite.svg" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>Vite + Vue</title>
-    <script type="module" crossorigin src="/ide/proxy/6002/assets/index-C_m0F2Qf.js"></script>
-    <link rel="stylesheet" crossorigin href="/ide/proxy/6002/assets/index-4owCqU6i.css">
+    <script type="module" crossorigin src="/ide/proxy/6009/assets/index-BgbU1ENp.js"></script>
+    <link rel="stylesheet" crossorigin href="/ide/proxy/6009/assets/index-B1nFdOqT.css">
   </head>
   <body>
     <div id="app"></div>

+ 6 - 0
src/router/index.js

@@ -1,5 +1,6 @@
 import { createRouter, createWebHashHistory } from 'vue-router'
 import HomeView from '../views/HomeView.vue'
+import ProductManagementView from '../views/ProductManagement.vue'
 import MinimalistView from '../assets/templates/ui-standard/MinimalistView.vue'
 import DarkModeView from '../assets/templates/ui-standard/DarkModeView.vue'
 import RetroView from '../assets/templates/ui-standard/RetroView.vue'
@@ -160,6 +161,11 @@ const routes = [
   {
     path: '/:pathMatch(.*)*',
     redirect: '/'
+  },
+  {
+    path: '/product-management',
+    name: 'product-management',
+    component: ProductManagementView
   }
 ]
 

+ 405 - 0
src/views/ProductManagement.vue

@@ -0,0 +1,405 @@
+<template>
+  <div class="min-h-screen bg-dopamine-50 dark:bg-dopamine-900">
+    <!-- 顶部导航栏 -->
+    <nav class="bg-white dark:bg-gray-800 shadow">
+      <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
+        <div class="flex justify-between h-16">
+          <div class="flex">
+            <div class="flex-shrink-0 flex items-center">
+              <h1 class="text-xl font-bold text-gray-900 dark:text-white">商品管理</h1>
+            </div>
+          </div>
+          <div class="flex items-center">
+            <button 
+              @click="showAddProductModal = true"
+              class="ml-4 inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-dopamine-600 hover:bg-dopamine-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-dopamine-500"
+            >
+              <PlusIcon class="h-4 w-4 mr-2" />
+              新增
+            </button>
+            <button 
+              @click="showSearchModal = true"
+              class="ml-4 inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-dopamine-600 hover:bg-dopamine-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-dopamine-500"
+            >
+              <SearchIcon class="h-4 w-4 mr-2" />
+              查询
+            </button>
+          </div>
+        </div>
+      </div>
+    </nav>
+
+    <!-- 主要内容区域 -->
+    <main class="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
+      <!-- 搜索与筛选区域 -->
+      <div class="mb-6 bg-white dark:bg-gray-800 shadow rounded-lg p-4">
+        <div class="grid grid-cols-1 md:grid-cols-4 gap-4">
+          <div class="relative">
+            <input
+              v-model="searchQuery"
+              type="text"
+              class="w-full pl-10 pr-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-dopamine-500 dark:bg-gray-700 dark:text-white"
+              placeholder="搜索商品名称"
+            />
+            <div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
+              <SearchIcon class="h-5 w-5 text-gray-400" />
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- 商品列表 -->
+      <div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden">
+        <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
+          <thead class="bg-gray-50 dark:bg-gray-700">
+            <tr>
+              <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
+                商品ID
+              </th>
+              <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
+                商品名称
+              </th>
+              <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
+                价格
+              </th>
+              <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
+                库存
+              </th>
+              <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
+                供应商信息
+              </th>
+              <th scope="col" class="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-300 uppercase tracking-wider">
+                操作
+              </th>
+            </tr>
+          </thead>
+          <tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
+            <tr v-for="product in filteredProducts" :key="product.id">
+              <td class="px-6 py-4 whitespace-nowrap">
+                <div class="text-sm text-gray-900 dark:text-white">{{ product.id }}</div>
+              </td>
+              <td class="px-6 py-4 whitespace-nowrap">
+                <div class="text-sm text-gray-900 dark:text-white">{{ product.name }}</div>
+              </td>
+              <td class="px-6 py-4 whitespace-nowrap">
+                <div class="text-sm text-gray-900 dark:text-white">¥{{ product.price }}</div>
+              </td>
+              <td class="px-6 py-4 whitespace-nowrap">
+                <div class="text-sm text-gray-900 dark:text-white">{{ product.stock }}</div>
+              </td>
+              <td class="px-6 py-4 whitespace-nowrap">
+                <div class="text-sm text-gray-900 dark:text-white">{{ product.supplier }}</div>
+              </td>
+              <td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
+                <button 
+                  @click="editProduct(product)"
+                  class="text-dopamine-600 hover:text-dopamine-900 dark:text-dopamine-400 dark:hover:text-dopamine-300 mr-4"
+                >
+                  编辑
+                </button>
+                <button 
+                  @click="deleteProduct(product)"
+                  class="text-red-600 hover:text-red-900 dark:text-red-400 dark:hover:text-red-300"
+                >
+                  删除
+                </button>
+              </td>
+            </tr>
+          </tbody>
+        </table>
+      </div>
+
+      <!-- 分页 -->
+      <div class="mt-4 flex justify-between items-center">
+        <div class="text-sm text-gray-700 dark:text-gray-300">
+          显示 {{ (currentPage - 1) * pageSize + 1 }} 到 {{ Math.min(currentPage * pageSize, totalProducts) }} 条,共 {{ totalProducts }} 条
+        </div>
+        <div class="flex space-x-2">
+          <button 
+            @click="prevPage"
+            :disabled="currentPage === 1"
+            class="px-3 py-1 border border-gray-300 dark:border-gray-600 rounded-md text-sm font-medium text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700"
+          >
+            上一页
+          </button>
+          <button 
+            @click="nextPage"
+            :disabled="currentPage * pageSize >= totalProducts"
+            class="px-3 py-1 border border-gray-300 dark:border-gray-600 rounded-md text-sm font-medium text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-700"
+          >
+            下一页
+          </button>
+        </div>
+      </div>
+    </main>
+
+    <!-- 添加/编辑商品弹窗 -->
+    <div v-if="showAddProductModal || showEditProductModal" class="fixed inset-0 z-50 overflow-y-auto">
+      <div class="flex items-center justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:block sm:p-0">
+        <div class="fixed inset-0 transition-opacity" aria-hidden="true">
+          <div class="absolute inset-0 bg-gray-500 dark:bg-gray-900 opacity-75"></div>
+        </div>
+        <span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
+        <div class="inline-block align-bottom bg-white dark:bg-gray-800 rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-2xl sm:w-full">
+          <div class="bg-white dark:bg-gray-800 px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
+            <div class="sm:flex sm:items-start">
+              <div class="mt-3 text-center sm:mt-0 sm:text-left w-full">
+                <div class="flex justify-between items-center mb-4">
+                  <h3 class="text-lg leading-6 font-medium text-gray-900 dark:text-white">
+                    {{ isEditing ? '编辑商品' : '新增商品' }}
+                  </h3>
+                  <button @click="closeModal" class="text-gray-400 hover:text-gray-500 dark:hover:text-gray-300">
+                    <XIcon class="h-6 w-6" />
+                  </button>
+                </div>
+                <form @submit.prevent="saveProduct" class="space-y-4">
+                  <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
+                    <div>
+                      <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">商品名称</label>
+                      <input
+                        v-model="productForm.name"
+                        type="text"
+                        required
+                        class="mt-1 block w-full border border-gray-300 dark:border-gray-600 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-dopamine-500 focus:border-dopamine-500 dark:bg-gray-700 dark:text-white"
+                      />
+                    </div>
+                    <div>
+                      <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">商品价格</label>
+                      <input
+                        v-model.number="productForm.price"
+                        type="number"
+                        min="0"
+                        step="0.01"
+                        required
+                        class="mt-1 block w-full border border-gray-300 dark:border-gray-600 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-dopamine-500 focus:border-dopamine-500 dark:bg-gray-700 dark:text-white"
+                      />
+                    </div>
+                    <div>
+                      <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">商品库存</label>
+                      <input
+                        v-model.number="productForm.stock"
+                        type="number"
+                        min="0"
+                        required
+                        class="mt-1 block w-full border border-gray-300 dark:border-gray-600 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-dopamine-500 focus:border-dopamine-500 dark:bg-gray-700 dark:text-white"
+                      />
+                    </div>
+                    <div>
+                      <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">供应商信息</label>
+                      <input
+                        v-model="productForm.supplier"
+                        type="text"
+                        required
+                        class="mt-1 block w-full border border-gray-300 dark:border-gray-600 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-dopamine-500 focus:border-dopamine-500 dark:bg-gray-700 dark:text-white"
+                      />
+                    </div>
+                  </div>
+                  <div class="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
+                    <button
+                      type="submit"
+                      class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-dopamine-600 text-base font-medium text-white hover:bg-dopamine-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-dopamine-500 sm:ml-3 sm:w-auto sm:text-sm"
+                    >
+                      保存
+                    </button>
+                    <button
+                      type="button"
+                      @click="closeModal"
+                      class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 dark:border-gray-600 shadow-sm px-4 py-2 bg-white dark:bg-gray-700 text-base font-medium text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-dopamine-500 sm:mt-0 sm:w-auto sm:text-sm"
+                    >
+                      取消
+                    </button>
+                  </div>
+                </form>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 查询弹窗 -->
+    <div v-if="showSearchModal" class="fixed inset-0 z-50 overflow-y-auto">
+      <div class="flex items-center justify-center min-h-screen px-4 pt-4 pb-20 text-center sm:block sm:p-0">
+        <div class="fixed inset-0 transition-opacity" aria-hidden="true">
+          <div class="absolute inset-0 bg-gray-500 dark:bg-gray-900 opacity-75"></div>
+        </div>
+        <span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
+        <div class="inline-block align-bottom bg-white dark:bg-gray-800 rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-2xl sm:w-full">
+          <div class="bg-white dark:bg-gray-800 px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
+            <div class="sm:flex sm:items-start">
+              <div class="mt-3 text-center sm:mt-0 sm:text-left w-full">
+                <div class="flex justify-between items-center mb-4">
+                  <h3 class="text-lg leading-6 font-medium text-gray-900 dark:text-white">
+                    查询商品
+                  </h3>
+                  <button @click="showSearchModal = false" class="text-gray-400 hover:text-gray-500 dark:hover:text-gray-300">
+                    <XIcon class="h-6 w-6" />
+                  </button>
+                </div>
+                <form @submit.prevent="performSearch" class="space-y-4">
+                  <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
+                    <div>
+                      <label class="block text-sm font-medium text-gray-700 dark:text-gray-300">商品名称</label>
+                      <input
+                        v-model="searchQuery"
+                        type="text"
+                        class="mt-1 block w-full border border-gray-300 dark:border-gray-600 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-dopamine-500 focus:border-dopamine-500 dark:bg-gray-700 dark:text-white"
+                      />
+                    </div>
+                  </div>
+                  <div class="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
+                    <button
+                      type="submit"
+                      class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-dopamine-600 text-base font-medium text-white hover:bg-dopamine-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-dopamine-500 sm:ml-3 sm:w-auto sm:text-sm"
+                    >
+                      查询
+                    </button>
+                    <button
+                      type="button"
+                      @click="showSearchModal = false"
+                      class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 dark:border-gray-600 shadow-sm px-4 py-2 bg-white dark:bg-gray-700 text-base font-medium text-gray-700 dark:text-gray-300 hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-dopamine-500 sm:mt-0 sm:w-auto sm:text-sm"
+                    >
+                      取消
+                    </button>
+                  </div>
+                </form>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref, computed } from 'vue'
+import { 
+  SearchIcon, 
+  PlusIcon,
+  XIcon
+} from 'lucide-vue-next'
+
+// 商品表单相关状态
+const showAddProductModal = ref(false)
+const showEditProductModal = ref(false)
+const isEditing = ref(false)
+const productForm = ref({
+  id: '',
+  name: '',
+  price: 0,
+  stock: 0,
+  supplier: ''
+})
+
+// 商品列表相关状态
+const products = ref([
+  { id: '1', name: '商品A', price: 100, stock: 50, supplier: '供应商A' },
+  { id: '2', name: '商品B', price: 200, stock: 30, supplier: '供应商B' },
+  { id: '3', name: '商品C', price: 150, stock: 20, supplier: '供应商C' },
+  { id: '4', name: '商品D', price: 250, stock: 10, supplier: '供应商D' },
+  { id: '5', name: '商品E', price: 300, stock: 40, supplier: '供应商E' },
+  { id: '6', name: '商品F', price: 120, stock: 60, supplier: '供应商F' },
+  { id: '7', name: '商品G', price: 180, stock: 25, supplier: '供应商G' },
+  { id: '8', name: '商品H', price: 220, stock: 15, supplier: '供应商H' },
+  { id: '9', name: '商品I', price: 280, stock: 35, supplier: '供应商I' },
+  { id: '10', name: '商品J', price: 190, stock: 45, supplier: '供应商J' }
+])
+const searchQuery = ref('')
+const currentPage = ref(1)
+const pageSize = ref(10)
+const totalProducts = ref(products.value.length)
+
+// 计算筛选后的商品列表
+const filteredProducts = computed(() => {
+  return products.value
+    .filter(product => product.name.toLowerCase().includes(searchQuery.value.toLowerCase()))
+    .slice((currentPage.value - 1) * pageSize.value, currentPage.value * pageSize.value)
+})
+
+// 处理新增商品按钮点击
+const addProduct = () => {
+  isEditing.value = false
+  productForm.value = {
+    id: '',
+    name: '',
+    price: 0,
+    stock: 0,
+    supplier: ''
+  }
+  showAddProductModal.value = true
+}
+
+// 处理编辑商品按钮点击
+const editProduct = (product) => {
+  isEditing.value = true
+  productForm.value = { ...product }
+  showEditProductModal.value = true
+}
+
+// 处理保存商品
+const saveProduct = () => {
+  if (isEditing.value) {
+    // 更新商品
+    const index = products.value.findIndex(p => p.id === productForm.value.id)
+    if (index !== -1) {
+      products.value[index] = { ...productForm.value }
+    }
+  } else {
+    // 添加新商品
+    productForm.value.id = String(products.value.length + 1)
+    products.value.push({ ...productForm.value })
+    totalProducts.value++
+  }
+  closeModal()
+}
+
+// 处理删除商品
+const deleteProduct = (product) => {
+  const index = products.value.findIndex(p => p.id === product.id)
+  if (index !== -1) {
+    products.value.splice(index, 1)
+    totalProducts.value--
+  }
+}
+
+// 处理查询提交
+const performSearch = () => {
+  currentPage.value = 1
+  showSearchModal.value = false
+}
+
+// 处理分页
+const prevPage = () => {
+  if (currentPage.value > 1) {
+    currentPage.value--
+  }
+}
+
+const nextPage = () => {
+  if (currentPage.value * pageSize.value < totalProducts.value) {
+    currentPage.value++
+  }
+}
+
+// 关闭模态框
+const closeModal = () => {
+  showAddProductModal.value = false
+  showEditProductModal.value = false
+}
+</script>
+
+<style scoped>
+:root {
+  --dopamine-50: #fff5f5;
+  --dopamine-100: #fed7d7;
+  --dopamine-200: #feb2b2;
+  --dopamine-300: #fc8181;
+  --dopamine-400: #f56565;
+  --dopamine-500: #e53e3e;
+  --dopamine-600: #c53030;
+  --dopamine-700: #9b2c2c;
+  --dopamine-800: #822727;
+  --dopamine-900: #63171b;
+}
+</style>

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно