Browse Source

feat: save

gemercheung 6 months ago
parent
commit
6f32406064

+ 6 - 4
packages/backend/.env

@@ -1,11 +1,13 @@
 # 服务端口
 APP_PORT=8085
 # DB
-DB_HOST=120.24.144.164
-DB_PORT=3306
+# DB_HOST=120.24.144.164
+DB_HOST=localhost
+# DB_PORT=3306
+DB_PORT=3307
 DB_USER=root
-DB_PWD='4Dage@4Dage#@168'
-DB_DATABASE=4dkankan_motion
+DB_PWD='laser'
+DB_DATABASE=help_center
 DB_SYNC=true # 是否开启同步,生产环境请设置成 false
 
 # Redis

+ 1 - 1
packages/frontend/src/views/article/edit.vue

@@ -1,5 +1,5 @@
 <template>
-  <CommonPage show-footer>
+  <CommonPage back show-footer>
     <template #action>
       <NButton type="primary" @click="handleEdit">
         保存文章

+ 24 - 24
packages/frontend/src/views/menu/list.vue

@@ -19,77 +19,77 @@
         </n-input>
       </MeQueryItem>
       <MeQueryItem label="状态" :label-width="50">
-        <n-select
+        <n-select
           v-model:value="queryItems.enable" clearable :options="[
             { label: '启用', value: 1 },
             { label: '停用', value: 0 },
-          ]"
+          ]"
         />
       </MeQueryItem>
     </MeCrud>
 
     <MeModal ref="modalRef" width="520px">
       <n-form ref="modalFormRef" label-placement="left" label-align="left" :label-width="95" :model="modalForm">
-        <n-form-item
+        <n-form-item
           label="名称" path="title" :rule="{
             required: true,
             message: '请输入名称',
             trigger: ['input', 'blur'],
-          }"
+          }"
         >
           <n-input v-model:value="modalForm.title" />
         </n-form-item>
 
-        <n-form-item
+        <n-form-item
           label="描述" path="description" :rule="{
             required: false,
             message: '请输入描述',
             trigger: ['input', 'blur'],
-          }"
+          }"
         >
           <n-input v-model:value="modalForm.description" type="textarea" />
         </n-form-item>
         <n-form-item v-if="modalForm.level !== 0" label="封面" path="cover">
-          <n-upload
+          <n-upload
             :multiple="false" :default-upload="true" list-type="image-card" :custom-request="uploadCover"
-            :max="1" :default-file-list="previewFileList" @preview="handlePreview" @remove="handleCoverRemove"
+            :max="1" :default-file-list="previewFileList" @preview="handlePreview" @remove="handleCoverRemove"
           />
           <n-modal v-model:show="showModal" preset="card" style="width: 600px" title="">
             <img :src="previewImageUrl" style="width: 100%">
           </n-modal>
         </n-form-item>
-        <n-form-item
+        <n-form-item
           label="分类" path="categoryId" :rule="{
             required: modalForm.level === 0 ? false : true,
             type: 'number',
             trigger: ['change', 'blur'],
             message: '请输入分类',
-          }"
+          }"
         >
-          <n-tree-select
+          <n-tree-select
             v-model:value="modalForm.categoryId" :options="allCategory" label-field="title" key-field="id"
-            placeholder="根分类" clearable
+            placeholder="根分类" clearable
           />
         </n-form-item>
 
-        <n-form-item
+        <n-form-item
           v-if="modalForm.level === 0" label="样式类型" path="styleType" :rule="{
             required: true,
             type: 'number',
             message: '请输入样式类型',
             trigger: ['input', 'blur'],
-          }"
+          }"
         >
           <n-select v-model:value="modalForm.styleType" :options="styleEnum" clearable filterable tag />
         </n-form-item>
 
-        <n-form-item
+        <n-form-item
           label="文章链接" path="articleId" :rule="{
             required: false,
             type: 'number',
             trigger: ['change', 'blur'],
             message: '请输入文章链接',
-          }"
+          }"
         >
           <n-select v-model:value="modalForm.articleId" :options="allArticle" clearable filterable tag />
         </n-form-item>
@@ -98,13 +98,13 @@
           <n-input-number v-model:value="modalForm.grid" style="width:100%" />
         </n-form-item>
 
-        <n-form-item
+        <n-form-item
           label="排序" path="order" :rule="{
             type: 'number',
             required: true,
             message: '此为必填项',
             trigger: ['blur', 'change'],
-          }"
+          }"
         >
           <n-input-number v-model:value="modalForm.order" />
         </n-form-item>
@@ -112,22 +112,22 @@
         <n-tabs type="line" animated>
           <template v-for="(lang, index) in langs" :key="lang">
             <n-tab-pane :name="lang" :tab="langLabel[lang]" :index="index">
-              <n-form-item
-                label="文章名称" path="title" :rule="{
+              <n-form-item
+                label="名称" path="title" :rule="{
                   required: true,
-                  message: '请输入文章名称',
+                  message: '请输入名称',
                   trigger: ['input', 'blur'],
-                }"
+                }"
               >
                 <n-input v-model:value="modalForm.translations[index].title" />
               </n-form-item>
 
-              <n-form-item
+              <n-form-item
                 label="描述" path="description" :rule="{
                   required: false,
                   message: '请输入描述',
                   trigger: ['input', 'blur'],
-                }"
+                }"
               >
                 <n-input v-model:value="modalForm.translations[index].description" type="textarea" />
               </n-form-item>

+ 16 - 6
packages/web/src/components/footer.vue

@@ -13,15 +13,17 @@
           <div class="infos-list flex flex-row gap-col-[80px]">
             <div class="infos-item flex flex-col gap-row-[10px]">
               <n-h6 class="text-white">核心产品</n-h6>
-              <a target="_blank">四维深光</a>
-              <a target="_blank">四维深时</a>
-              <a target="_blank">四维看见</a>
-              <a target="_blank">四维看看</a>
+              <a target="_blank" href="https://4dkankan.com/#/Meta">四维深光</a>
+              <a target="_blank" href="https://4dkankan.com/#/Mega">四维深时</a>
+              <a target="_blank" href="https://4dkankan.com/#/Minion">四维看见</a>
+              <a target="_blank" href="https://4dkankan.com/#/KanKan">四维看看</a>
             </div>
             <div class="infos-item flex flex-col gap-row-[10px]">
               <n-h6 class="text-white">解决方案</n-h6>
-              <a target="_blank">智慧城市</a><a target="_blank">博物馆</a
-              ><a target="_blank">刑侦消防</a><a target="_blank">房产营销</a>
+              <a target="_blank">智慧城市</a>
+              <a target="_blank">博物馆</a>
+              <a target="_blank">刑侦消防</a>
+              <a target="_blank">房产营销</a>
             </div>
             <div class="infos-item flex flex-col gap-row-[10px]">
               <n-h6 class="text-white">服务支持</n-h6>
@@ -95,6 +97,14 @@ import { NH6 } from 'naive-ui'
 </script>
 
 <style scoped>
+a{
+  text-decoration: none;
+  color: white;
+}
+a:hover{
+  color:rgba(255,255,255,0.8);
+  cursor: pointer;
+}
 .footer {
   background: linear-gradient(180deg, #0661c9 0%, #033063 100%);
 }

+ 26 - 37
packages/web/src/components/header.vue

@@ -13,18 +13,10 @@
 
     <div class="search-box w-full flex justify-center items-center flex-col">
       <n-h1 class="font-size-[48px] font-500">{{ $t('helperTip') }}</n-h1>
-   
-      <n-auto-complete
-        v-model:value="keySearch"
-        :options="searchOptions"
-        class="max-w-[640px]"
-        size="large"
-        round
-        placeholder="输入关键字"
-        blur-after-select
-        @select="(index:number)=>handleAutoSelect(index,searchOptions)"
-        @keydown.enter="handleSearch"
-      >
+
+      <n-auto-complete v-model:value="keySearch" :options="searchOptions" class="max-w-[640px]" size="large" round
+        placeholder="输入关键字" blur-after-select @select="(index: number) => handleAutoSelect(index, searchOptions)"
+        @keydown.enter="handleSearch">
         <template #prefix>
           <n-icon :component="SearchOutline" />
         </template>
@@ -33,10 +25,10 @@
   </div>
 </template>
 <script setup lang="ts">
-import { NH1, NInput, NIcon, NDropdown, NAutoComplete,NButton } from 'naive-ui'
+import { NH1, NIcon, NDropdown, NAutoComplete, NButton } from 'naive-ui'
 import { SearchOutline } from '@vicons/ionicons5'
 import { computedAsync } from '@vueuse/core'
-import { type ArticleDetailType, getArticleSearch } from '@/api'
+import { getArticleSearch } from '@/api'
 
 const { t, locale } = useI18n()
 
@@ -58,40 +50,37 @@ const options = ref([
 
 const searchOptions = computedAsync(
   async () => {
-    if(keySearch.value){
+    if (keySearch.value) {
       const list = await getArticleSearch(keySearch.value)
-      console.log('list',list.data)
-      return Array.from(list.data ||[]).map((suffix) => {
-          return {
-            label: suffix.title,
-            value: suffix.id
-          }
-        })
+      console.log('list', list.data)
+      return Array.from(list.data || []).map((suffix) => {
+        return {
+          label: suffix.title,
+          value: suffix.id
+        }
+      })
     }
- 
+
   },
   null, // initial state
 )
 
-// const searchOptions = computed(()=>{
-
-//   return ['@gmail.com', '@163.com', '@qq.com'].map((suffix) => {
-//           const value = keySearch.value === null ? '' : keySearch.value
-//           const prefix = value.split('@')[0]
-//           return {
-//             label: prefix + suffix,
-//             value: prefix + suffix
-//           }
-//         })
-// })
 
 
 const handleSelect = (key: string) => {
   locale.value = key
+  localStorage.setItem('locale', key)
+  location.reload();
 }
-const handleAutoSelect =(index:number,list: any[])=>{
-  const item = list[index-1]
-  console.log('handleAutoUpdate',item)
+onMounted(() => {
+  const localeValue = localStorage.getItem('locale') || 'en'
+  locale.value = String(localeValue)
+
+})
+const handleAutoSelect = (index: number, list: any[]) => {
+  const item = list.find((it) => it.value === index)
+  // debugger;
+  console.log('handleAutoUpdate', item)
   router.push({ path: `/showdoc/${item.value}` })
 }
 const handleSearch = () => {

+ 7 - 0
packages/web/src/components/subHeader.vue

@@ -31,7 +31,14 @@ const options = ref([
 
 const handleSelect = (key: string) => {
   locale.value = key
+  localStorage.setItem('locale', key)
+  location.reload();
 }
+onMounted(() => {
+  const localeValue = localStorage.getItem('locale') || 'en'
+  locale.value = String(localeValue)
+
+})
 </script>
 <style>
 .header {

+ 14 - 7
packages/web/src/pages/index.vue

@@ -52,7 +52,14 @@
                   {{ child.title }}
                 </div>
               </div>
+           
             </swiper-slide>
+            <!-- <div class="swiper-button-prev">
+              <button @click="swiperInstance.slidePrev()">Prev</button>
+              </div>
+              <div class="swiper-button-next">
+                <button @click="swiperInstance.slideNext()">next</button>
+              </div> -->
           </swiper>
         </template>
 
@@ -125,24 +132,24 @@ import { NH1, NGrid, NGi } from 'naive-ui'
 import { getMenuList, type ArticleDetailType } from '@/api'
 import type { MenuItem } from '@/api'
 import { Swiper, SwiperSlide } from 'swiper/vue'
-
-// Import Swiper styles
 import 'swiper/css'
 import router from '@/plugins/router.ts'
+// import { useSwiper } from 'swiper/vue';
 
 const list = ref<MenuItem[]>([])
-
+const swiperInstance =ref();
 getMenuList().then((data) => {
   if (data.data) {
     list.value = data.data
   }
 })
 
-const onSwiper = () => {
-  // console.log(swiper)
+const onSwiper = (swiper: unknown) => {
+  console.log(swiper)
+  swiperInstance.value = swiper
 }
-const onSlideChange = () => {
-  console.log('slide change')
+const onSlideChange = (index:number) => {
+  console.log('slide change', index)
 }
 
 const handleToDoc = (child: ArticleDetailType) => {