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

zhengjianadmin-2025-07-01 01:16:30

genlitex 1 сар өмнө
parent
commit
fe5f2cbd93

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


Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 4 - 0
dist/assets/index-DsCNy6sI.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/6005/assets/index-D2hL6n7W.js"></script>
-    <link rel="stylesheet" crossorigin href="/ide/proxy/6005/assets/index-4owCqU6i.css">
+    <script type="module" crossorigin src="/ide/proxy/6007/assets/index-DsCNy6sI.js"></script>
+    <link rel="stylesheet" crossorigin href="/ide/proxy/6007/assets/index-4owCqU6i.css">
   </head>
   <body>
     <div id="app"></div>

+ 6 - 0
src/router/index.js

@@ -25,6 +25,7 @@ import ElementUIView from '../assets/templates/ui-standard/ElementUIView.vue'
 import FlatView from '../assets/templates/ui-standard/FlatView.vue'
 import NordicView from '../assets/templates/ui-standard/NordicView.vue'
 import FuturisticView from '../assets/templates/ui-standard/FuturisticView.vue'
+import RawMaterialCategoryView from '../views/RawMaterialCategoryView.vue'
 
 const routes = [
   {
@@ -157,6 +158,11 @@ const routes = [
     name: 'Futuristic',
     component: FuturisticView
   },
+  {
+    path: '/raw-material-category',
+    name: 'RawMaterialCategory',
+    component: RawMaterialCategoryView
+  },
   {
     path: '/:pathMatch(.*)*',
     redirect: '/'

+ 515 - 0
src/views/RawMaterialCategoryView.vue

@@ -0,0 +1,515 @@
+<template>
+  <div class="p-6">
+    <!-- 头部操作区 -->
+    <div class="bg-white rounded-lg shadow p-6 mb-6">
+      <div class="flex justify-between items-center">
+        <h2 class="text-2xl font-bold text-gray-800">原料品类管理</h2>
+        <div class="flex space-x-4">
+          <button 
+            @click="showAddDialog = true"
+            class="flex items-center px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
+          >
+            <PlusIcon class="w-5 h-5 mr-2" />
+            新增
+          </button>
+          <button 
+            @click="handleExport"
+            class="flex items-center px-4 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors"
+          >
+            <DownloadIcon class="w-5 h-5 mr-2" />
+            导出
+          </button>
+          <div class="relative">
+            <input 
+              type="file" 
+              class="hidden" 
+              ref="fileInput"
+              @change="handleFileChange"
+            />
+            <button 
+              @click="$refs.fileInput.click()"
+              class="flex items-center px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition-colors"
+            >
+              <UploadIcon class="w-5 h-5 mr-2" />
+              导入
+            </button>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 筛选区 -->
+    <div class="bg-white rounded-lg shadow p-6 mb-6">
+      <div class="flex flex-wrap gap-4">
+        <div class="relative flex-1 min-w-[200px]">
+          <SearchIcon class="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
+          <input 
+            v-model="searchQuery.materialCode"
+            type="text"
+            placeholder="物料编码"
+            class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
+            @input="handleSearch"
+          />
+        </div>
+        <div class="relative flex-1 min-w-[200px]">
+          <SearchIcon class="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
+          <input 
+            v-model="searchQuery.materialGroup"
+            type="text"
+            placeholder="物料组"
+            class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
+            @input="handleSearch"
+          />
+        </div>
+        <div class="relative flex-1 min-w-[200px]">
+          <SearchIcon class="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
+          <input 
+            v-model="searchQuery.categoryOne"
+            type="text"
+            placeholder="类别一"
+            class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
+            @input="handleSearch"
+          />
+        </div>
+        <div class="relative flex-1 min-w-[200px]">
+          <SearchIcon class="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
+          <input 
+            v-model="searchQuery.categoryTwo"
+            type="text"
+            placeholder="类别二"
+            class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
+            @input="handleSearch"
+          />
+        </div>
+        <div class="relative flex-1 min-w-[200px]">
+          <SearchIcon class="absolute left-3 top-1/2 transform -translate-y-1/2 w-5 h-5 text-gray-400" />
+          <input 
+            v-model="searchQuery.rawMaterialCategory"
+            type="text"
+            placeholder="原料大类"
+            class="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
+            @input="handleSearch"
+          />
+        </div>
+        <div class="flex items-center space-x-2">
+          <button 
+            @click="resetFilters"
+            class="px-4 py-2 bg-gray-600 text-white rounded-lg hover:bg-gray-700"
+          >
+            重置
+          </button>
+          <button 
+            @click="handleSearch"
+            class="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700"
+          >
+            查询
+          </button>
+        </div>
+      </div>
+    </div>
+
+    <!-- 原料品类列表 -->
+    <div class="bg-white rounded-lg shadow overflow-hidden">
+      <div class="overflow-x-auto">
+        <table class="min-w-full divide-y divide-gray-200">
+          <thead class="bg-gray-50">
+            <tr>
+              <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
+                <input 
+                  type="checkbox" 
+                  v-model="selectAll"
+                  class="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
+                />
+              </th>
+              <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
+                序号
+              </th>
+              <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
+                物料编码
+              </th>
+              <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
+                物料组
+              </th>
+              <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
+                类别一
+              </th>
+              <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
+                类别二
+              </th>
+              <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
+                原料大类
+              </th>
+              <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
+                操作
+              </th>
+            </tr>
+          </thead>
+          <tbody class="bg-white divide-y divide-gray-200">
+            <tr v-for="(rawMaterial, index) in filteredRawMaterials" :key="rawMaterial.id" class="hover:bg-gray-50">
+              <td class="px-6 py-4 whitespace-nowrap">
+                <input 
+                  type="checkbox" 
+                  v-model="selectedItems"
+                  :value="rawMaterial.id"
+                  class="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
+                />
+              </td>
+              <td class="px-6 py-4 whitespace-nowrap">{{ index + 1 }}</td>
+              <td class="px-6 py-4 whitespace-nowrap">{{ rawMaterial.materialCode }}</td>
+              <td class="px-6 py-4 whitespace-nowrap">{{ rawMaterial.materialGroup }}</td>
+              <td class="px-6 py-4 whitespace-nowrap">{{ rawMaterial.categoryOne }}</td>
+              <td class="px-6 py-4 whitespace-nowrap">{{ rawMaterial.categoryTwo }}</td>
+              <td class="px-6 py-4 whitespace-nowrap">{{ rawMaterial.rawMaterialCategory }}</td>
+              <td class="px-6 py-4 whitespace-nowrap">
+                <div class="flex space-x-2">
+                  <button 
+                    @click="handleEdit(rawMaterial)"
+                    class="px-3 py-1 text-sm text-green-600 hover:text-green-800"
+                  >
+                    修改
+                  </button>
+                  <button 
+                    @click="handleDelete(rawMaterial)"
+                    class="px-3 py-1 text-sm text-red-600 hover:text-red-800"
+                  >
+                    删除
+                  </button>
+                </div>
+              </td>
+            </tr>
+          </tbody>
+        </table>
+      </div>
+
+      <!-- 批量操作 -->
+      <div v-if="selectedItems.length > 0" class="px-6 py-4 bg-gray-50 border-t border-gray-200">
+        <div class="flex items-center justify-between">
+          <span class="text-sm text-gray-600">已选择 {{ selectedItems.length }} 项</span>
+          <div class="flex space-x-4">
+            <button 
+              @click="handleBatchEdit"
+              class="flex items-center px-4 py-2 text-sm text-blue-600 hover:text-blue-800"
+            >
+              <EditIcon class="w-4 h-4 mr-1" />
+              批量修改
+            </button>
+            <button 
+              @click="handleBatchDelete"
+              class="flex items-center px-4 py-2 text-sm text-red-600 hover:text-red-800"
+            >
+              <TrashIcon class="w-4 h-4 mr-1" />
+              批量删除
+            </button>
+          </div>
+        </div>
+      </div>
+
+      <!-- 分页 -->
+      <div class="px-6 py-4 bg-gray-50 border-t border-gray-200">
+        <div class="flex items-center justify-between">
+          <div class="flex items-center">
+            <span class="text-sm text-gray-700 mr-4">每页显示</span>
+            <select 
+              v-model="pageSize"
+              class="px-2 py-1 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
+              @change="handleSizeChange"
+            >
+              <option v-for="size in [10, 20, 50, 100]" :key="size" :value="size">
+                {{ size }}
+              </option>
+            </select>
+          </div>
+          <div class="flex items-center space-x-2">
+            <button 
+              @click="currentPage--"
+              :disabled="currentPage === 1"
+              class="px-3 py-1 border border-gray-300 rounded-md disabled:opacity-50"
+            >
+              <ChevronLeftIcon class="w-4 h-4" />
+            </button>
+            <span class="text-sm text-gray-700">
+              第 {{ currentPage }} 页 / 共 {{ totalPages }} 页
+            </span>
+            <button 
+              @click="currentPage++"
+              :disabled="currentPage === totalPages"
+              class="px-3 py-1 border border-gray-300 rounded-md disabled:opacity-50"
+            >
+              <ChevronRightIcon class="w-4 h-4" />
+            </button>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 新增/编辑原料品类对话框 -->
+    <div v-if="showAddDialog" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center">
+      <div class="bg-white rounded-lg shadow-xl w-1/2 max-w-2xl">
+        <div class="flex justify-between items-center p-6 border-b">
+          <h3 class="text-lg font-semibold">{{ isEdit ? '编辑原料品类' : '新增原料品类' }}</h3>
+          <button @click="showAddDialog = false" class="text-gray-400 hover:text-gray-500">
+            <XIcon class="w-5 h-5" />
+          </button>
+        </div>
+        <form @submit.prevent="handleSubmit" class="p-6">
+          <div class="grid grid-cols-2 gap-6">
+            <div>
+              <label class="block text-sm font-medium text-gray-700 mb-1">物料编码</label>
+              <input 
+                v-model="addForm.materialCode"
+                type="text"
+                class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
+                required
+              />
+            </div>
+            <div>
+              <label class="block text-sm font-medium text-gray-700 mb-1">物料组</label>
+              <input 
+                v-model="addForm.materialGroup"
+                type="text"
+                class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
+                required
+              />
+            </div>
+            <div>
+              <label class="block text-sm font-medium text-gray-700 mb-1">类别一</label>
+              <input 
+                v-model="addForm.categoryOne"
+                type="text"
+                class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
+                required
+              />
+            </div>
+            <div>
+              <label class="block text-sm font-medium text-gray-700 mb-1">类别二</label>
+              <input 
+                v-model="addForm.categoryTwo"
+                type="text"
+                class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
+                required
+              />
+            </div>
+            <div>
+              <label class="block text-sm font-medium text-gray-700 mb-1">原料大类</label>
+              <input 
+                v-model="addForm.rawMaterialCategory"
+                type="text"
+                class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
+                required
+              />
+            </div>
+          </div>
+          <div class="mt-6 flex justify-end space-x-4">
+            <button 
+              type="button"
+              @click="showAddDialog = false"
+              class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50"
+            >
+              取消
+            </button>
+            <button 
+              type="submit"
+              class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700"
+            >
+              确定
+            </button>
+          </div>
+        </form>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref, computed, onMounted, onUnmounted, watch, nextTick } from 'vue'
+import { useRouter } from 'vue-router'
+import { 
+  PlusIcon, 
+  DownloadIcon, 
+  UploadIcon, 
+  SearchIcon, 
+  ChevronUpIcon,
+  ChevronDownIcon,
+  EditIcon,
+  TrashIcon,
+  ChevronLeftIcon,
+  ChevronRightIcon,
+  XIcon,
+} from 'lucide-vue-next'
+
+const router = useRouter()
+
+// Mock 数据
+const mockData = {
+  rawMaterials: {
+    list: [
+      {
+        id: 1,
+        materialCode: 'RM001',
+        materialGroup: 'MG001',
+        categoryOne: 'C1',
+        categoryTwo: 'C2',
+        rawMaterialCategory: 'RMC1'
+      },
+      {
+        id: 2,
+        materialCode: 'RM002',
+        materialGroup: 'MG002',
+        categoryOne: 'C1',
+        categoryTwo: 'C2',
+        rawMaterialCategory: 'RMC2'
+      }
+    ],
+    total: 2
+  }
+}
+
+// 状态管理
+const loading = ref(false)
+const searchQuery = ref({
+  materialCode: '',
+  materialGroup: '',
+  categoryOne: '',
+  categoryTwo: '',
+  rawMaterialCategory: ''
+})
+const currentPage = ref(1)
+const pageSize = ref(10)
+const total = ref(0)
+const selectedItems = ref([])
+const showAddDialog = ref(false)
+const isEdit = ref(false)
+const sortKey = ref('')
+const sortOrder = ref('asc')
+
+// 计算属性
+const filteredRawMaterials = computed(() => {
+  return mockData.rawMaterials.list.filter(rawMaterial => {
+    return (
+      (!searchQuery.value.materialCode || rawMaterial.materialCode.includes(searchQuery.value.materialCode)) &&
+      (!searchQuery.value.materialGroup || rawMaterial.materialGroup.includes(searchQuery.value.materialGroup)) &&
+      (!searchQuery.value.categoryOne || rawMaterial.categoryOne.includes(searchQuery.value.categoryOne)) &&
+      (!searchQuery.value.categoryTwo || rawMaterial.categoryTwo.includes(searchQuery.value.categoryTwo)) &&
+      (!searchQuery.value.rawMaterialCategory || rawMaterial.rawMaterialCategory.includes(searchQuery.value.rawMaterialCategory))
+    )
+  })
+})
+
+const totalPages = computed(() => {
+  return Math.ceil(total.value / pageSize.value)
+})
+
+const selectAll = computed({
+  get: () => selectedItems.value.length === filteredRawMaterials.value.length,
+  set: (value) => {
+    selectedItems.value = value ? filteredRawMaterials.value.map(r => r.id) : []
+  }
+})
+
+// 方法
+const handleSearch = () => {
+  currentPage.value = 1
+  fetchRawMaterials()
+}
+
+const resetFilters = () => {
+  searchQuery.value = {
+    materialCode: '',
+    materialGroup: '',
+    categoryOne: '',
+    categoryTwo: '',
+    rawMaterialCategory: ''
+  }
+  handleSearch()
+}
+
+const handleSort = (prop) => {
+  if (sortKey.value === prop) {
+    sortOrder.value = sortOrder.value === 'asc' ? 'desc' : 'asc'
+  } else {
+    sortKey.value = prop
+    sortOrder.value = 'asc'
+  }
+  const sortedRawMaterials = [...filteredRawMaterials.value]
+  sortedRawMaterials.sort((a, b) => {
+    const aValue = a[prop]
+    const bValue = b[prop]
+    if (sortOrder.value === 'asc') {
+      return aValue > bValue ? 1 : -1
+    } else {
+      return aValue < bValue ? 1 : -1
+    }
+  })
+  filteredRawMaterials.value = sortedRawMaterials
+}
+
+const handleSizeChange = () => {
+  currentPage.value = 1
+  fetchRawMaterials()
+}
+
+const handleFileChange = (event) => {
+  const file = event.target.files[0]
+  if (file) {
+    // 处理文件上传
+  }
+}
+
+const handleExport = () => {
+  // 实现导出逻辑
+}
+
+const handleBatchEdit = () => {
+  // 实现批量编辑逻辑
+}
+
+const handleBatchDelete = () => {
+  // 实现批量删除逻辑
+}
+
+const handleEdit = (rawMaterial) => {
+  isEdit.value = true
+  addForm.value = { ...rawMaterial }
+  showAddDialog.value = true
+}
+
+const handleDelete = (rawMaterial) => {
+  // 实现删除逻辑
+}
+
+const handleSubmit = () => {
+  // 实现表单提交逻辑
+}
+
+// 数据获取
+const fetchRawMaterials = async () => {
+  try {
+    loading.value = true
+    // 模拟网络延迟
+    await new Promise(resolve => setTimeout(resolve, 500))
+    total.value = mockData.rawMaterials.total
+  } catch (error) {
+    console.error('获取数据失败:', error)
+  } finally {
+    loading.value = false
+  }
+}
+
+// 生命周期钩子
+onMounted(() => {
+  fetchRawMaterials()
+})
+
+onUnmounted(() => {
+  // 清理工作
+})
+
+// 表单数据
+const addForm = ref({
+  materialCode: '',
+  materialGroup: '',
+  categoryOne: '',
+  categoryTwo: '',
+  rawMaterialCategory: ''
+})
+</script>

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