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,7 +11,8 @@
11 </div> 11 </div>
12 <v-col class="flex pa-0" cols="12" sm="9"> 12 <v-col class="flex pa-0" cols="12" sm="9">
13 <span 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 (categoryStore.selectedCategory === item.categoryDisplayName && 16 (categoryStore.selectedCategory === item.categoryDisplayName &&
16 'tw-text-[#fff] tw-bg-[#1e88e5]') 17 'tw-text-[#fff] tw-bg-[#1e88e5]')
17 " 18 "
@@ -31,12 +32,14 @@ @@ -31,12 +32,14 @@
31 </div> 32 </div>
32 <v-col class="pa-0" cols="12" sm="9"> 33 <v-col class="pa-0" cols="12" sm="9">
33 <span 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 v-for="(item, index) in subCategoryList" 40 v-for="(item, index) in subCategoryList"
38 :key="index" 41 :key="index"
39 - @click="handleSubCategoryClick(item.id)" 42 + @click="handleSubCategoryClick(item)"
40 > 43 >
41 {{ item.name }} 44 {{ item.name }}
42 </span> 45 </span>
@@ -53,12 +56,14 @@ @@ -53,12 +56,14 @@
53 </div> 56 </div>
54 <v-col class="pa-0" cols="12" sm="9"> 57 <v-col class="pa-0" cols="12" sm="9">
55 <span 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 v-for="(item, index) in funcCategoryList" 64 v-for="(item, index) in funcCategoryList"
60 :key="index" 65 :key="index"
61 - @click="handleFuncCategoryClick(item.id)" 66 + @click="handleFuncCategoryClick(item)"
62 > 67 >
63 {{ item.name }} 68 {{ item.name }}
64 </span> 69 </span>
@@ -69,34 +74,157 @@ @@ -69,34 +74,157 @@
69 </template> 74 </template>
70 75
71 <script setup lang="ts"> 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 const seo = { 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 Equipment: 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 const handleCategoryClick = (item: CategoryRootType) => { 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 // const doc = document as any 229 // const doc = document as any
102 // const head = doc.getElementsByTagName('head') 230 // const head = doc.getElementsByTagName('head')
@@ -106,35 +234,60 @@ const handleCategoryClick = (item: CategoryRootType) =&gt; { @@ -106,35 +234,60 @@ const handleCategoryClick = (item: CategoryRootType) =&gt; {
106 // .querySelector('meta[name="keywords"]') 234 // .querySelector('meta[name="keywords"]')
107 // .setAttribute('content', seo[item.categoryDisplayName as keyof typeof seo]) 235 // .setAttribute('content', seo[item.categoryDisplayName as keyof typeof seo])
108 // head[0].appendChild(meta) 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 const subCategoryList = computed(() => { 274 const subCategoryList = computed(() => {
122 if (categoryStore.selectedCategory) { 275 if (categoryStore.selectedCategory) {
123 const tmp = categoryStore.list.filter( 276 const tmp = categoryStore.list.filter(
124 (item) => item.categoryDisplayName === categoryStore.selectedCategory 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 const funcCategoryList = computed(() => { 284 const funcCategoryList = computed(() => {
132 if (categoryStore.selectedCategory) { 285 if (categoryStore.selectedCategory) {
133 const tmp = categoryStore.list.filter( 286 const tmp = categoryStore.list.filter(
134 (item) => item.categoryDisplayName === categoryStore.selectedCategory 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 </script> 293 </script>
components/Header.vue
@@ -5,30 +5,61 @@ @@ -5,30 +5,61 @@
5 <router-link to="/"><v-img src="/logo.jpg" alt="canrud" /></router-link> 5 <router-link to="/"><v-img src="/logo.jpg" alt="canrud" /></router-link>
6 </v-col> 6 </v-col>
7 <v-col cols="6" md="8" class="px-0"> 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 </v-text-field> 18 </v-text-field>
11 </v-col> 19 </v-col>
12 <v-col cols="4" md="2" class="px-0"> 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 </v-btn> 23 </v-btn>
15 </v-col> 24 </v-col>
16 </v-row> 25 </v-row>
17 </v-container> 26 </v-container>
18 <div class="tabs"> 27 <div class="tabs">
19 <div class="tw-max-w-[1200px] tw-mx-auto"> 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 </v-tab> 44 </v-tab>
24 <v-tab :value="2" to="/products"> 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 </v-tab> 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 </v-tab> 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 </v-tab> 63 </v-tab>
33 <v-tab> 64 <v-tab>
34 <span class="text-grey-lighten-3 tw-font-bold"> 65 <span class="text-grey-lighten-3 tw-font-bold">
@@ -42,71 +73,71 @@ @@ -42,71 +73,71 @@
42 </template> 73 </template>
43 74
44 <script setup lang="ts"> 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 const handleKeyDown = (e: any) => { 95 const handleKeyDown = (e: any) => {
65 if (e.keyCode == 13) { 96 if (e.keyCode == 13) {
66 - handleClick() 97 + handleClick();
67 } 98 }
68 -} 99 +};
69 100
70 const handleClick = () => { 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 const handleTabClick = () => { 110 const handleTabClick = () => {
80 - categoryStore.updateDisplay(true)  
81 - productStore.updateKeyword('')  
82 -} 111 + categoryStore.updateDisplay(true);
  112 + productStore.updateKeyword("");
  113 +};
83 114
84 watchEffect(() => { 115 watchEffect(() => {
85 - input.value = productStore.keyword  
86 -}) 116 + input.value = productStore.keyword;
  117 +});
87 118
88 onMounted(() => { 119 onMounted(() => {
89 // 获取url的参数 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 if (index !== -1) { 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 params.forEach((item) => { 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 // 获取dialog的状态 130 // 获取dialog的状态
100 if (obj.flag) { 131 if (obj.flag) {
101 - dialog.updateDialog(true) 132 + dialog.updateDialog(true);
102 } 133 }
103 134
104 if (obj.keyword) { 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 </script> 141 </script>
111 142
112 <style lang="scss" scoped> 143 <style lang="scss" scoped>
deploy/prod2.sh
1 #!/bin/bash 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 TARGET_PATH="/root/web/canrud-outside-nuxt-front" 5 TARGET_PATH="/root/web/canrud-outside-nuxt-front"
6 DOCKERFILE_PATH="/root/web/canrud-outside-nuxt-front/canrud-nuxt-front" 6 DOCKERFILE_PATH="/root/web/canrud-outside-nuxt-front/canrud-nuxt-front"
7 IMAGE_NAME="canrud-outside-front" 7 IMAGE_NAME="canrud-outside-front"