Commit e6efdf695a642811a33b705277c3d6cc7c5059d6

Authored by 曾国涛
2 parents 26d5934a f098454e

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	nuxt.config.ts
components/CategoryList.vue
... ... @@ -11,7 +11,8 @@
11 11 </div>
12 12 <v-col class="flex pa-0" cols="12" sm="9">
13 13 <span
14   - :class="'tw-leading-[50px] tw-inline-flex tw-cursor-pointer px-4 mb-1 mr-1 tw-font-medium rounded hover:tw-text-[#fff] hover:tw-bg-[#1e88e5] ' +
  14 + :class="
  15 + 'tw-leading-[50px] tw-inline-flex tw-cursor-pointer px-4 mb-1 mr-1 tw-font-medium rounded hover:tw-text-[#fff] hover:tw-bg-[#1e88e5] ' +
15 16 (categoryStore.selectedCategory === item.categoryDisplayName &&
16 17 'tw-text-[#fff] tw-bg-[#1e88e5]')
17 18 "
... ... @@ -31,12 +32,14 @@
31 32 </div>
32 33 <v-col class="pa-0" cols="12" sm="9">
33 34 <span
34   - :class="'px-4 py-1 mb-1 mr-1 tw-font-medium rounded tw-inline-flex tw-cursor-pointer hover:tw-text-[#fff] hover:tw-bg-[#1e88e5] ' +
35   - (categoryStore.selectedSubCategory === item.id && 'tw-text-[#fff] tw-bg-[#1e88e5]')
  35 + :class="
  36 + 'px-4 py-1 mb-1 mr-1 tw-font-medium rounded tw-inline-flex tw-cursor-pointer hover:tw-text-[#fff] hover:tw-bg-[#1e88e5] ' +
  37 + (categoryStore.selectedSubCategory === item.id &&
  38 + 'tw-text-[#fff] tw-bg-[#1e88e5]')
36 39 "
37 40 v-for="(item, index) in subCategoryList"
38 41 :key="index"
39   - @click="handleSubCategoryClick(item.id)"
  42 + @click="handleSubCategoryClick(item)"
40 43 >
41 44 {{ item.name }}
42 45 </span>
... ... @@ -53,12 +56,14 @@
53 56 </div>
54 57 <v-col class="pa-0" cols="12" sm="9">
55 58 <span
56   - :class="'px-4 py-1 mb-1 mr-1 tw-font-medium rounded tw-inline-flex tw-cursor-pointer hover:tw-text-[#fff] hover:tw-bg-[#1e88e5] ' +
57   - (categoryStore.selectedFuncCategory === item.id && 'tw-text-[#fff] tw-bg-[#1e88e5]')
  59 + :class="
  60 + 'px-4 py-1 mb-1 mr-1 tw-font-medium rounded tw-inline-flex tw-cursor-pointer hover:tw-text-[#fff] hover:tw-bg-[#1e88e5] ' +
  61 + (categoryStore.selectedFuncCategory === item.id &&
  62 + 'tw-text-[#fff] tw-bg-[#1e88e5]')
58 63 "
59 64 v-for="(item, index) in funcCategoryList"
60 65 :key="index"
61   - @click="handleFuncCategoryClick(item.id)"
  66 + @click="handleFuncCategoryClick(item)"
62 67 >
63 68 {{ item.name }}
64 69 </span>
... ... @@ -69,34 +74,157 @@
69 74 </template>
70 75  
71 76 <script setup lang="ts">
72   -import { useCategoryStore } from '@/stores/category'
73   -import { useProductListStore } from '@/stores/product_list'
74   -import type { CategoryRootType } from '@/type'
75   -import { computed } from 'vue'
76   -import { useRouter, useRoute } from 'vue-router'
  77 +import { useCategoryStore } from "@/stores/category";
  78 +import { useProductListStore } from "@/stores/product_list";
  79 +import type { CategoryRootType } from "@/type";
  80 +import { computed } from "vue";
  81 +import { useRouter, useRoute } from "vue-router";
  82 +
  83 +const route = useRoute();
  84 +const router = useRouter();
  85 +
  86 +const categoryStore = useCategoryStore();
  87 +const productStore = useProductListStore();
  88 +watchEffect(async () => {
  89 + if (route.query.categories) {
  90 + // 1. 提取 query.category 的内容
  91 + productStore.updateKeyword("");
  92 + const categories = route.query.categories.split(",");
  93 + const mainCategory = categories[0].trim(); // 取第一个值
  94 + const subCategoryName = categories[1] ? categories[1].trim() : null; // 取第二个值(如果存在)
  95 +
  96 + // 2. 更新选中的主分类
  97 + categoryStore.updateCategory(mainCategory);
  98 +
  99 + // 3. 如果有子分类名称,查找其对应的 ID
  100 + if (subCategoryName) {
  101 + const subCategoryList = computed(() => {
  102 + if (categoryStore.selectedCategory) {
  103 + const tmp = categoryStore.list.filter(
  104 + (item) =>
  105 + item.categoryDisplayName === categoryStore.selectedCategory
  106 + );
  107 + return tmp?.[0]?.list || [];
  108 + }
  109 + return [];
  110 + });
  111 +
  112 + // 4. 查找对应的子分类 ID
  113 + const foundFuncCategory = subCategoryList.value.find(
  114 + (func) => func.name === subCategoryName
  115 + );
  116 +
  117 + if (foundFuncCategory) {
  118 + const funcCategoryId = foundFuncCategory.id;
  119 + // 你可以在这里使用找到的 funcCategoryId
  120 + categoryStore.updateSubCategory(funcCategoryId);
  121 + }
  122 + }
  123 + // 5. 判断 query 中是否存在 function,并查找对应的 ID
  124 + if (route.query.function) {
  125 + const functionName = route.query.function.trim();
  126 + const funcCategoryList = computed(() => {
  127 + if (categoryStore.selectedCategory) {
  128 + const tmp = categoryStore.list.filter(
  129 + (item) =>
  130 + item.categoryDisplayName === categoryStore.selectedCategory
  131 + );
  132 + return tmp?.[0]?.productFunctions || [];
  133 + }
  134 + return [];
  135 + });
  136 + const foundFuncCategory = funcCategoryList.value.find(
  137 + (func) => func.name === functionName
  138 + );
  139 +
  140 + if (foundFuncCategory) {
  141 + const funcCategoryId = foundFuncCategory.id;
  142 + // 你可以在这里使用找到的 funcCategoryId
  143 + categoryStore.updateFuncCategory(funcCategoryId);
  144 + }
  145 + // // 6. 查找对应的功能分类 ID
  146 + // const foundFuncCategory = funcCategories.find(
  147 + // (func) => func.name === functionName
  148 + // );
  149 +
  150 + // if (foundFuncCategory) {
  151 + // const funcCategoryId = foundFuncCategory.id;
  152 + // // 使用找到的 funcCategoryId
  153 + // categoryStore.updateFuncCategory(funcCategoryId);
  154 + // }
  155 + }
  156 + } else if (Object.keys(route.query).length === 0) {
  157 + // 检查是否有默认的分类
  158 + const defaultCategory = categoryStore.list[0]; // 假设第一个分类是默认的
77 159  
78   -const router = useRouter()
  160 + if (defaultCategory) {
  161 + const defaultCategoryName = defaultCategory.categoryDisplayName;
  162 + const defaultSubCategory = defaultCategory.list[0]; // 假设第一个子分类为默认子分类
  163 + const defaultFuncCategory = defaultCategory.productFunctions[0]; // 假设第一个功能分类为默认功能分类
79 164  
80   -const categoryStore = useCategoryStore()
81   -const productStore = useProductListStore()
  165 + // 更新 store 和 URL
  166 + categoryStore.updateCategory(defaultCategoryName);
  167 + productStore.updatePageNo(1);
82 168  
  169 + if (defaultSubCategory) {
  170 + categoryStore.updateSubCategory(defaultSubCategory.id);
  171 +
  172 + // 如果有之前的值则使用之前的值,拼接新的子分类名
  173 + const updatedCategory =
  174 + defaultCategoryName + "," + defaultSubCategory.name;
  175 +
  176 + // 拼接设备类型到 URL
  177 + router.push({
  178 + query: {
  179 + categories: defaultCategoryName + "," + defaultSubCategory.name,
  180 + },
  181 + });
  182 + }
  183 +
  184 + if (defaultFuncCategory) {
  185 + categoryStore.updateFuncCategory(defaultFuncCategory.id);
  186 + // 拼接功能类型到 URL
  187 + router.push({
  188 + query: {
  189 + categories: defaultCategoryName + "," + defaultSubCategory.name,
  190 + function: defaultFuncCategory.name,
  191 + },
  192 + });
  193 + }
  194 + }
  195 + }
  196 +});
83 197 const seo = {
84   - 'Energy materials':
85   - 'Energy materials,Not specified,Battery accessories,Lithium-ion batteries,Capacitors,Sodium-ion batteries,Lithium-sulfur batteries,Potassium/magnesium/aluminum/zinc batteries,Air/fuel/solar,Analytical electrodes,Complete battery accessories',
86   - 'Laboratory consumables':
87   - 'Laboratory consumables,Not specified,Glass materials,Plastic materials,Metal materials,Ceramic materials,Paper film materials,Chemical materials,Tetrafluoro materials,Safety protection,Office supplies,Tools,Others',
88   - 'Low-dimensional materials':
89   - ',Low-dimensional materialsNot specified,Zero-dimensional carbon materials,One-dimensional carbon materials,Two-dimensional carbon materials,Three-dimensional carbon materials,Inorganic nanomaterials,Organic nanomaterials,Metal nanomaterials,Others',
  198 + "Energy materials":
  199 + "Energy materials,Not specified,Battery accessories,Lithium-ion batteries,Capacitors,Sodium-ion batteries,Lithium-sulfur batteries,Potassium/magnesium/aluminum/zinc batteries,Air/fuel/solar,Analytical electrodes,Complete battery accessories",
  200 + "Laboratory consumables":
  201 + "Laboratory consumables,Not specified,Glass materials,Plastic materials,Metal materials,Ceramic materials,Paper film materials,Chemical materials,Tetrafluoro materials,Safety protection,Office supplies,Tools,Others",
  202 + "Low-dimensional materials":
  203 + ",Low-dimensional materialsNot specified,Zero-dimensional carbon materials,One-dimensional carbon materials,Two-dimensional carbon materials,Three-dimensional carbon materials,Inorganic nanomaterials,Organic nanomaterials,Metal nanomaterials,Others",
90 204 Equipment:
91   - 'Equipment,Not specified,Equipment,Accessories & fixtures,Fuel cell manufacturing and testing equipment'
92   -}
  205 + "Equipment,Not specified,Equipment,Accessories & fixtures,Fuel cell manufacturing and testing equipment",
  206 +};
93 207  
94 208 const handleCategoryClick = (item: CategoryRootType) => {
95   - categoryStore.updateCategory(item.categoryDisplayName)
96   - categoryStore.updateSubCategory(item.list[0].id)
97   - productStore.updatePageNo(1)
  209 + categoryStore.updateCategory(item.categoryDisplayName);
  210 + categoryStore.updateSubCategory(item.list[0].id);
  211 + productStore.updatePageNo(1);
  212 + const defaultSubCategory = item.list[0]; // 假设第一个子分类为默认子分类
98 213  
99   - router.push({ query: { category: item.categoryDisplayName } })
  214 + if (item.categoryDisplayName === "Energy materials") {
  215 + router.push({
  216 + query: {
  217 + categories: item.categoryDisplayName + "," + defaultSubCategory.name,
  218 + function: item.productFunctions[0].name,
  219 + },
  220 + });
  221 + } else {
  222 + router.push({
  223 + query: {
  224 + categories: item.categoryDisplayName + "," + defaultSubCategory.name,
  225 + },
  226 + });
  227 + }
100 228  
101 229 // const doc = document as any
102 230 // const head = doc.getElementsByTagName('head')
... ... @@ -106,35 +234,60 @@ const handleCategoryClick = (item: CategoryRootType) =&gt; {
106 234 // .querySelector('meta[name="keywords"]')
107 235 // .setAttribute('content', seo[item.categoryDisplayName as keyof typeof seo])
108 236 // head[0].appendChild(meta)
109   -}
  237 +};
  238 +
  239 +const handleSubCategoryClick = (value: CategoryRootType) => {
  240 + categoryStore.updateSubCategory(value.id);
  241 + productStore.updatePageNo(1);
  242 +
  243 + // 获取当前的查询参数
  244 + const currentQuery = router.currentRoute.value.query;
  245 + const currentCategory = currentQuery.categories || "";
  246 +
  247 + // 如果有之前的值则使用之前的值,拼接新的子分类名
  248 + const updatedCategory = currentCategory.split(",")[0] + "," + value.name;
  249 +
  250 + // 更新路由,保持 handleCategoryClick 的值不变
  251 + // router.push({ query: { category: updatedCategory } });
  252 + // 更新路由,保持 function 参数不变
  253 + router.push({
  254 + query: { categories: updatedCategory, function: currentQuery.function },
  255 + });
  256 +};
  257 +
  258 +const handleFuncCategoryClick = (value: CategoryRootType) => {
  259 + categoryStore.updateFuncCategory(value.id);
  260 + productStore.updatePageNo(1);
  261 + // 获取当前的查询参数
  262 + const currentQuery = router.currentRoute.value.query;
110 263  
111   -const handleSubCategoryClick = (value: string) => {
112   - categoryStore.updateSubCategory(value)
113   - productStore.updatePageNo(1)
114   -}
  264 + // 将 value.name 作为新的查询参数加入到现有的 query 中
  265 + const updatedQuery = {
  266 + ...currentQuery, // 保持当前的查询参数
  267 + function: value.name, // 将 value.name 添加为新的查询参数 funcCategory
  268 + };
115 269  
116   -const handleFuncCategoryClick = (value: string) => {
117   - categoryStore.updateFuncCategory(value)
118   - productStore.updatePageNo(1)
119   -}
  270 + // 更新路由
  271 + router.push({ query: updatedQuery });
  272 +};
120 273  
121 274 const subCategoryList = computed(() => {
122 275 if (categoryStore.selectedCategory) {
123 276 const tmp = categoryStore.list.filter(
124 277 (item) => item.categoryDisplayName === categoryStore.selectedCategory
125   - )
126   - return tmp?.[0]?.list || []
  278 + );
  279 + return tmp?.[0]?.list || [];
127 280 }
128   - return []
129   -})
  281 + return [];
  282 +});
130 283  
131 284 const funcCategoryList = computed(() => {
132 285 if (categoryStore.selectedCategory) {
133 286 const tmp = categoryStore.list.filter(
134 287 (item) => item.categoryDisplayName === categoryStore.selectedCategory
135   - )
136   - return tmp?.[0]?.productFunctions || []
  288 + );
  289 + return tmp?.[0]?.productFunctions || [];
137 290 }
138   - return []
139   -})
  291 + return [];
  292 +});
140 293 </script>
... ...
components/Header.vue
... ... @@ -5,30 +5,61 @@
5 5 <router-link to="/"><v-img src="/logo.jpg" alt="canrud" /></router-link>
6 6 </v-col>
7 7 <v-col cols="6" md="8" class="px-0">
8   - <v-text-field name="keyword" label="Search keyword" hide-details="auto" variant="solo"
9   - append-inner-icon="mdi-magnify" @click:appendInner="handleClick" @keydown="handleKeyDown" v-model="input">
  8 + <v-text-field
  9 + name="keyword"
  10 + label="Search keyword"
  11 + hide-details="auto"
  12 + variant="solo"
  13 + append-inner-icon="mdi-magnify"
  14 + @click:appendInner="handleClick"
  15 + @keydown="handleKeyDown"
  16 + v-model="input"
  17 + >
10 18 </v-text-field>
11 19 </v-col>
12 20 <v-col cols="4" md="2" class="px-0">
13   - <v-btn variant="text" href="/contact" color="blue-darken-2 mt-4">Concat Us
  21 + <v-btn variant="text" href="/contact" color="blue-darken-2 mt-4"
  22 + >Concat Us
14 23 </v-btn>
15 24 </v-col>
16 25 </v-row>
17 26 </v-container>
18 27 <div class="tabs">
19 28 <div class="tw-max-w-[1200px] tw-mx-auto">
20   - <v-tabs mobile-breakpoint="580" v-model="tab" bg-color="blue-darken-1" slider-color="grey-lighten-3"
21   - tab-slider-size="6px" selected-class="active" :grow="screenWidth > 600 ? false : true">
22   - <v-tab :value="1" to="/"><span @click="handleTabClick" class="text-grey-lighten-3 tw-font-bold">Home</span>
  29 + <v-tabs
  30 + mobile-breakpoint="580"
  31 + v-model="tab"
  32 + bg-color="blue-darken-1"
  33 + slider-color="grey-lighten-3"
  34 + tab-slider-size="6px"
  35 + selected-class="active"
  36 + :grow="screenWidth > 600 ? false : true"
  37 + >
  38 + <v-tab :value="1" to="/"
  39 + ><span
  40 + @click="handleTabClick"
  41 + class="text-grey-lighten-3 tw-font-bold"
  42 + >Home</span
  43 + >
23 44 </v-tab>
24 45 <v-tab :value="2" to="/products">
25   - <span @click="handleTabClick" class="text-grey-lighten-3 tw-font-bold">Products</span>
  46 + <span @click="handleTabClick" class="text-grey-lighten-3 tw-font-bold"
  47 + >Products</span
  48 + >
26 49 </v-tab>
27   - <v-tab :value="3" to="/about"><span @click="handleTabClick"
28   - class="text-grey-lighten-3 tw-font-bold">About</span>
  50 + <v-tab :value="3" to="/about"
  51 + ><span
  52 + @click="handleTabClick"
  53 + class="text-grey-lighten-3 tw-font-bold"
  54 + >About</span
  55 + >
29 56 </v-tab>
30   - <v-tab :value="4" to="/contact"><span @click="handleTabClick"
31   - class="text-grey-lighten-3 tw-font-bold">Contact</span>
  57 + <v-tab :value="4" to="/contact"
  58 + ><span
  59 + @click="handleTabClick"
  60 + class="text-grey-lighten-3 tw-font-bold"
  61 + >Contact</span
  62 + >
32 63 </v-tab>
33 64 <v-tab>
34 65 <span class="text-grey-lighten-3 tw-font-bold">
... ... @@ -42,71 +73,71 @@
42 73 </template>
43 74  
44 75 <script setup lang="ts">
45   -import { ref, watchEffect } from 'vue'
46   -import ContactDialog from '@/components/ContactDialog.vue'
47   -import { useProductListStore } from '@/stores/product_list'
48   -import { useRouter } from 'vue-router'
49   -import { useDialogStore } from '@/stores/dialog'
50   -import { useCategoryStore } from '@/stores/category'
51   -import { useDisplay } from 'vuetify'
  76 +import { ref, watchEffect } from "vue";
  77 +import ContactDialog from "@/components/ContactDialog.vue";
  78 +import { useProductListStore } from "@/stores/product_list";
  79 +import { useRouter } from "vue-router";
  80 +import { useDialogStore } from "@/stores/dialog";
  81 +import { useCategoryStore } from "@/stores/category";
  82 +import { useDisplay } from "vuetify";
52 83  
53   -const { width: screenWidth } = useDisplay()
  84 +const { width: screenWidth } = useDisplay();
54 85  
55   -const productStore = useProductListStore()
56   -const categoryStore = useCategoryStore()
  86 +const productStore = useProductListStore();
  87 +const categoryStore = useCategoryStore();
57 88  
58   -const input = ref()
  89 +const input = ref();
59 90  
60   -const router = useRouter()
  91 +const router = useRouter();
61 92  
62   -const dialog = useDialogStore()
  93 +const dialog = useDialogStore();
63 94  
64 95 const handleKeyDown = (e: any) => {
65 96 if (e.keyCode == 13) {
66   - handleClick()
  97 + handleClick();
67 98 }
68   -}
  99 +};
69 100  
70 101 const handleClick = () => {
71   - categoryStore.updateDisplay(!input.value)
72   - productStore.updateKeyword(input.value)
73   - productStore.updatePageNo(1)
74   - router.push({ path: '/products', query: { keyword: input.value } })
75   -}
  102 + categoryStore.updateDisplay(!input.value);
  103 + productStore.updateKeyword(input.value);
  104 + productStore.updatePageNo(1);
  105 + router.push({ path: "/products", query: { keyword: input.value } });
  106 +};
76 107  
77   -const tab = ref(1)
  108 +const tab = ref(1);
78 109  
79 110 const handleTabClick = () => {
80   - categoryStore.updateDisplay(true)
81   - productStore.updateKeyword('')
82   -}
  111 + categoryStore.updateDisplay(true);
  112 + productStore.updateKeyword("");
  113 +};
83 114  
84 115 watchEffect(() => {
85   - input.value = productStore.keyword
86   -})
  116 + input.value = productStore.keyword;
  117 +});
87 118  
88 119 onMounted(() => {
89 120 // 获取url的参数
90   - const url = window.location.href
91   - const index = url.indexOf('?')
  121 + const url = window.location.href;
  122 + const index = url.indexOf("?");
92 123 if (index !== -1) {
93   - const params = url.slice(index + 1).split('&')
94   - const obj: any = {}
  124 + const params = url.slice(index + 1).split("&");
  125 + const obj: any = {};
95 126 params.forEach((item) => {
96   - const arr = item.split('=')
97   - obj[arr[0]] = arr[1]
98   - })
  127 + const arr = item.split("=");
  128 + obj[arr[0]] = arr[1];
  129 + });
99 130 // 获取dialog的状态
100 131 if (obj.flag) {
101   - dialog.updateDialog(true)
  132 + dialog.updateDialog(true);
102 133 }
103 134  
104 135 if (obj.keyword) {
105   - productStore.updateKeyword(obj.keyword)
106   - categoryStore.updateDisplay(false)
  136 + productStore.updateKeyword(obj.keyword);
  137 + categoryStore.updateDisplay(false);
107 138 }
108 139 }
109   -})
  140 +});
110 141 </script>
111 142  
112 143 <style lang="scss" scoped>
... ...
deploy/prod2.sh
1 1 #!/bin/bash
2 2 # 变量定义
3   -LAST_TAG="1.0.11"
4   -TAG="1.0.12"
  3 +LAST_TAG="1.0.14"
  4 +TAG="1.0.15"
5 5 TARGET_PATH="/root/web/canrud-outside-nuxt-front"
6 6 DOCKERFILE_PATH="/root/web/canrud-outside-nuxt-front/canrud-nuxt-front"
7 7 IMAGE_NAME="canrud-outside-front"
... ...