Ver Fonte

Merge branch 'master' of http://47.100.37.243:10191/wutt/manHourHousekeeper

Min há 1 ano atrás
pai
commit
041916457f
20 ficheiros alterados com 524 adições e 79 exclusões
  1. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/index.html
  2. 9 0
      fhKeeper/formulahousekeeper/customerBuler-crm/package-lock.json
  3. 1 0
      fhKeeper/formulahousekeeper/customerBuler-crm/package.json
  4. 18 2
      fhKeeper/formulahousekeeper/customerBuler-crm/src/App.vue
  5. BIN
      fhKeeper/formulahousekeeper/customerBuler-crm/src/assets/404.png
  6. 5 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/main.ts
  7. 11 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/404.vue
  8. 3 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/api.ts
  9. 54 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/home.vue
  10. 0 8
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/index.vue
  11. 80 19
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/login.vue
  12. 197 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/register.vue
  13. 1 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/api.ts
  14. 9 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/index.vue
  15. 80 34
      fhKeeper/formulahousekeeper/customerBuler-crm/src/router/index.ts
  16. 14 8
      fhKeeper/formulahousekeeper/customerBuler-crm/src/store/index.ts
  17. 0 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/styles.css
  18. 13 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/styles/global.scss
  19. 6 6
      fhKeeper/formulahousekeeper/customerBuler-crm/src/utils/request.ts
  20. 22 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/utils/tools.ts

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/index.html

@@ -4,7 +4,7 @@
     <meta charset="UTF-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 + TS</title>
+    <title>客户管家</title>
   </head>
   <body>
     <div id="app"></div>

+ 9 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/package-lock.json

@@ -14,6 +14,7 @@
         "echarts": "^5.5.0",
         "element-plus": "^2.5.6",
         "pinia": "^2.1.7",
+        "pinia-plugin-persistedstate": "^3.2.1",
         "vue": "^3.4.19",
         "vue-router": "^4.3.0"
       },
@@ -2180,6 +2181,14 @@
         }
       }
     },
+    "node_modules/pinia-plugin-persistedstate": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/pinia-plugin-persistedstate/-/pinia-plugin-persistedstate-3.2.1.tgz",
+      "integrity": "sha512-MK++8LRUsGF7r45PjBFES82ISnPzyO6IZx3CH5vyPseFLZCk1g2kgx6l/nW8pEBKxxd4do0P6bJw+mUSZIEZUQ==",
+      "peerDependencies": {
+        "pinia": "^2.0.0"
+      }
+    },
     "node_modules/pinia/node_modules/vue-demi": {
       "version": "0.14.7",
       "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz",

+ 1 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/package.json

@@ -16,6 +16,7 @@
     "echarts": "^5.5.0",
     "element-plus": "^2.5.6",
     "pinia": "^2.1.7",
+    "pinia-plugin-persistedstate": "^3.2.1",
     "vue": "^3.4.19",
     "vue-router": "^4.3.0"
   },

+ 18 - 2
fhKeeper/formulahousekeeper/customerBuler-crm/src/App.vue

@@ -2,6 +2,22 @@
   <router-view></router-view>
 </template>
 
-<script setup lang="ts"></script>
+<script setup lang="ts">
+import { useStore } from '@/store/index'
+const { setAsyncRoutesMark } = useStore()
+window.addEventListener('beforeunload', () => beforeunloadFn())
+const beforeunloadFn = (() => {
+  setAsyncRoutesMark(false)
+})
+</script>
 
-<style scoped></style>
+<style>
+html,
+body,
+#app,
+.layouts {
+  width: 100%;
+  height: 100%;
+  overflow: hidden;
+}
+</style>

BIN
fhKeeper/formulahousekeeper/customerBuler-crm/src/assets/404.png


+ 5 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/main.ts

@@ -4,12 +4,15 @@ import ElementPlus from 'element-plus'
 import "./TailWindCss/index.css";
 import 'element-plus/dist/index.css'
 import * as ElementPlusIconsVue from '@element-plus/icons-vue'
+import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
 import App from './App.vue'
 import router from './router/index'
-import "./styles.css"
 import * as echarts from 'echarts';
 
 const app = createApp(App)
+const pinia = createPinia()
+
+pinia.use(piniaPluginPersistedstate)
 
 for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
   app.component(key, component)
@@ -20,4 +23,5 @@ app
   .use(ElementPlus)
   .use(createPinia())
   .use(router)
+  .use(pinia)
   .mount('#app')

+ 11 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/404.vue

@@ -0,0 +1,11 @@
+<template>
+  <div>
+    404
+  </div>
+</template>
+
+<script lang="ts" setup>
+
+</script>
+
+<style lang="scss" scoped></style>

+ 3 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/api.ts

@@ -0,0 +1,3 @@
+export const SENDVCODE = "/user/sendVcode";     //发送验证码
+export const REGISTER = "/user/insertCompany";  //注册
+export const LOGIN = "/user/loginAdmin";        //登录

+ 54 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/home.vue

@@ -0,0 +1,54 @@
+<template>
+    <div class="common-layout layouts">
+        <el-container class="flex flex-col layouts">
+            <!-- 头部 -->
+            <el-header></el-header>
+            <!-- 左侧菜单 -->
+            <el-container class="flex-1 layouts">
+                <el-aside class="home-el-aside" width="220px">
+                    <el-menu default-active="1" class="el-menu-vertical-demo">
+                        <el-menu-item :index="(index + 1) + ''" v-for="(item, index) in 10" :key="index">
+                            <el-icon><setting /></el-icon>
+                            <span>第{{ index + 1 }}个</span>
+                        </el-menu-item>
+
+                        <el-sub-menu index="11">
+                            <template #title>
+                                <el-icon>
+                                    <location />
+                                </el-icon>
+                                <span>第十一个</span>
+                            </template>
+                            <el-menu-item :index="'11'">
+                                <el-icon><icon-menu /></el-icon>
+                                <span>第11-1个</span>
+                            </el-menu-item>
+                        </el-sub-menu>
+                    </el-menu>
+                </el-aside>
+                <!-- 主体 -->
+                <el-main>
+                    <router-view></router-view>
+                </el-main>
+            </el-container>
+        </el-container>
+    </div>
+</template>
+<script lang="ts" setup>
+
+</script>
+<style scoped lang="scss">
+.common-layout {
+    .el-header {
+        background: $darkBlue;
+    }
+
+    .el-menu-vertical-demo {
+        height: 100%;
+    }
+    .el-main {
+        padding: 0 20px;
+        background: $backColor;
+    }
+}
+</style>

+ 0 - 8
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/index.vue

@@ -1,8 +0,0 @@
-<template>
-    <div>
-        indexyemian
-    </div>
-</template>
-<script setup lang="ts">
-</script>
-<style scoped lang="scss"></style>

+ 80 - 19
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/login.vue

@@ -1,47 +1,108 @@
 <template>
   <div class="loginView w-screen h-screen overflow-hidden flex">
-    <div class="w-1/5 h-1/2 bg-white m-auto border-t-8 border-blue-400 shadow-xl rounded-md pl-9 pr-9">
+    <div class="w-96 bg-white m-auto border-t-8 border-blue-400 shadow-xl rounded-md pl-9 pr-9">
       <div class="m-auto pt-4">
         <img class="w-1/5 h-1/5 m-auto" :src="loginLogo" alt="">
       </div>
       <h2 class="text-xl text-center pt-4 font-bold">客户管家</h2>
-      <div class="pt-4">
-        <el-input :prefix-icon="UserFilled" size="large" class="mt-2" v-model="username" placeholder="账号/手机号" />
-        <el-input :prefix-icon="Lock" show-password size="large" class="mt-6" v-model="password" placeholder="密码" />
-        <div class="pt-6">
-          <el-button type="primary" size="large" class="w-full" :loading="loginLoading" @click="login">登录</el-button>
+      <el-form class="pt-4" ref="ruleFormRef" :model="ruleForm" :rules="rules">
+        <el-form-item prop="username">
+          <el-input clearable :prefix-icon="UserFilled" size="large" class="mt-2" v-model="ruleForm.username"
+            autocomplete="off" placeholder="账号/手机号" />
+        </el-form-item>
+        <el-form-item prop="password">
+          <el-input clearable :prefix-icon="Lock" show-password size="large" class="mt-4" v-model="ruleForm.password"
+            autocomplete="off" placeholder="密码" />
+        </el-form-item>
+        <div class="pt-4">
+          <el-button type="primary" size="large" class="w-full" :loading="loginLoading"
+            @click="login(ruleFormRef)">登录</el-button>
         </div>
-      </div>
+      </el-form>
       <el-divider content-position="center">或</el-divider>
       <div class="m-auto mb-5">
         <img class="w-9 m-auto p-1 rounded-full border-blue-300 border-2 cursor-pointer" :src="qiyeweixin" alt="">
       </div>
-      <div class="flex justify-between">
+      <div class="flex justify-between pb-5">
         <div class="cursor-pointer text-blue-400 hover:text-blue-300">联系客服</div>
         <div class="flex justify-around">
-          <div class="mr-4 cursor-pointer text-blue-400 hover:text-blue-300">使用说明</div>
-          <div class="cursor-pointer text-blue-400 hover:text-blue-300">企业注册</div>
+          <div class="mr-4 cursor-pointer text-blue-400 hover:text-blue-300" @click="useHelp()">使用说明</div>
+          <div class="cursor-pointer text-blue-400 hover:text-blue-300" @click="toRegister()">企业注册</div>
         </div>
       </div>
+      <el-dialog v-model="helpDialog" width="30%" title="使用说明">
+        <div class="p-2 text-xl">文档水水水水</div>
+        <div>文档水水水水</div>
+        <div>文档水水水水</div>
+      </el-dialog>
     </div>
   </div>
 </template>
 
 <script lang="ts" setup>
+import { reactive, ref } from "vue";
+import { useRouter } from "vue-router";
 import loginLogo from "@/assets/login/login_logo.png";
 import qiyeweixin from "@/assets/login/qiyeweixin.png";
 import { UserFilled, Lock } from '@element-plus/icons-vue'
-import { ref } from "vue";
-const username = ref("");
-const password = ref("");
+import type { FormInstance, FormRules } from 'element-plus'
+import { useStore } from '@/store/index'
+import { post } from "@/utils/request";
+import { LOGIN } from "./api";
+const { setRouters } = useStore()
+const router = useRouter();
+const ruleFormRef = ref<FormInstance>();
+const ruleForm = ref({
+  username: "",
+  password: "",
+});
 const loginLoading = ref(false);
-const login = () => {
-  loginLoading.value = true;
-  console.log(username.value, password.value);
-  setTimeout(() => {
-    loginLoading.value = false;
-  }, 1000);
+const rules = reactive<FormRules<typeof ruleForm>>({
+  username: [{ required: true, trigger: "blur", message: "请输入账号/手机号" }],
+  password: [{ required: true, trigger: "blur", message: "请输入密码" }],
+})
+const helpDialog = ref(false);
+
+const login = (formEl: FormInstance | undefined) => {
+  if (!formEl) {
+    return
+  }
+  formEl.validate((valid) => {
+    if (!valid) {
+      return false;
+    }
+    loginLoading.value = true;
+    console.log(ruleForm.value);
+    post(LOGIN, { ...ruleForm.value }).then(res => {
+      console.log(res);
+      setTimeout(() => {
+        loginLoading.value = false;
+      }, 1000)
+      // loginLoading.value = false;
+    }).catch(err => {
+      loginLoading.value = false;
+    })
+    return
+    let newRouter = [
+      {
+        path: '/thread',
+        name: 'thread'
+      }
+    ]
+    setRouters(newRouter)
+    setTimeout(() => {
+      loginLoading.value = false;
+      router.push(newRouter[0].path);
+    }, 1000);
+  })
+
 };
+const useHelp = () => {
+  helpDialog.value = true;
+}
+const toRegister = () => {
+  router.push("/register");
+}
 </script>
 
 <style lang="scss" scoped>

+ 197 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/register.vue

@@ -0,0 +1,197 @@
+<template>
+  <div class="loginView w-screen h-screen overflow-hidden flex">
+    <div class="w-[32rem] bg-white m-auto border-t-8 border-blue-400 shadow-xl rounded-md pl-9 pr-9">
+      <h2 class="text-xl text-center pt-4 font-bold">注册</h2>
+      <el-form class="pt-4" ref="ruleFormRef" :model="ruleForm" :rules="rules">
+        <el-form-item class="pt-1" prop="companyName">
+          <el-input type="text" size="large" v-model="ruleForm.companyName" autocomplete="off" placeholder="公司名"
+            clearable :prefix-icon="HomeFilled"></el-input>
+        </el-form-item>
+        <el-form-item class="pt-1" prop="name">
+          <el-input type="text" size="large" v-model="ruleForm.name" autocomplete="off" placeholder="姓名" clearable
+            :prefix-icon="UserFilled"></el-input>
+        </el-form-item>
+        <el-form-item class="pt-1" prop="phone">
+          <el-input type="text" size="large" v-model="ruleForm.phone" autocomplete="off" placeholder="手机号" clearable
+            :prefix-icon="Iphone"></el-input>
+        </el-form-item>
+        <el-form-item class="pt-1" prop="vcode">
+          <el-input type="text" size="large" v-model="ruleForm.vcode" autocomplete="off" placeholder="验证码" clearable
+            :prefix-icon="Tickets">
+            <template #append>
+              <el-button @click="sendVcode()" :disabled="ruleForm.phone == '' || showTimer">发送验证码<span
+                  v-if="showTimer">({{ countNum }})</span></el-button>
+            </template>
+          </el-input>
+        </el-form-item>
+        <el-form-item class="pt-1" prop="password">
+          <el-input type="password" size="large" v-model="ruleForm.password" autocomplete="off"
+            placeholder="设置密码,长度不低于6位" clearable :prefix-icon="Lock">
+          </el-input>
+        </el-form-item>
+        <el-form-item class="pt-1" prop="repwd">
+          <el-input type="password" size="large" v-model="ruleForm.repwd" autocomplete="off" placeholder="重复密码"
+            clearable :prefix-icon="Lock">
+          </el-input>
+        </el-form-item>
+        <div class="pt-4 mb-5">
+          <el-button type="primary" size="large" class="w-full" :loading="registerLoading"
+            @click="register(ruleFormRef)">注册</el-button>
+        </div>
+      </el-form>
+      <div class="text-right mb-5 cursor-pointer text-blue-400 hover:text-blue-300" @click="router.push('/login')">
+        已有账号?返回登录
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { reactive, ref } from "vue";
+import { useRouter, useRoute } from "vue-router";
+import { HomeFilled, UserFilled, Lock, Iphone, Tickets } from '@element-plus/icons-vue'
+import { ElNotification, ElMessage, type FormInstance, type FormRules } from 'element-plus'
+import { isValueEmpty } from "@/utils/tools";
+import { post } from "@/utils/request";
+import { REGISTER, SENDVCODE } from "./api";
+const router = useRouter();
+const route = useRoute();
+const ruleFormRef = ref<FormInstance>();
+const ruleForm = ref({
+  companyName: "",
+  name: "",
+  phone: "",
+  vcode: "",
+  password: "",
+  repwd: ""
+});
+const rules = reactive<FormRules<typeof ruleForm>>({
+  companyName: [{ required: true, message: '请输入公司名', trigger: 'blur' },],
+  name: [{ required: true, message: '请输入姓名', trigger: 'blur' },],
+  phone: [
+    { required: true, message: '请输入手机号', trigger: 'blur' },
+    { min: 11, max: 11, message: '请输入正确的手机号', trigger: 'blur' },
+  ],
+  vcode: [
+    { required: true, message: '请输入验证码', trigger: 'blur' },
+  ],
+  password: [
+    { required: true, message: '请设置密码,长度不低于6位', trigger: 'blur' },
+    { min: 6, message: '密码长度不少于6位', trigger: 'blur' },
+  ],
+  repwd: [
+    { required: true, message: '请重复输入密码', trigger: 'blur' },
+    {
+      validator: (_rule, value, callback) => {
+        if (value !== ruleForm.value.password) {
+          callback(new Error('两次密码不一致'));
+        } else {
+          callback();
+        }
+      }, trigger: 'blur'
+    }
+  ]
+})
+
+const registerLoading = ref(false);
+const showTimer = ref(false);
+const countNum = ref(10);
+const countDown = () => {
+  if (countNum.value > 0) {
+    setTimeout(() => {
+      countNum.value -= 1;
+      countDown()
+    }, 1000)
+  } else {
+    showTimer.value = false;
+    countNum.value = 10;
+  }
+}
+const sendVcode = () => {
+  showTimer.value = true;
+  countDown();
+  if (ruleForm.value.phone.trim().length != 11) {
+    ElMessage.error({
+      message: "请输入正确的手机号",
+      type: "error",
+      duration: 2000,
+    })
+    return
+  }
+  post(SENDVCODE, {
+    mobile: ruleForm.value.phone
+  }).then(res => {
+    if (res.code == "ok") {
+      ElMessage.success({
+        message: "发送成功",
+        type: "success",
+        duration: 2000,
+      })
+      showTimer.value = true;
+      countDown();
+    }
+  })
+}
+const register = (formEl: FormInstance | undefined) => {
+  if (!formEl) {
+    return
+  }
+
+  formEl.validate((valid) => {
+    if (!valid) {
+      return false;
+    }
+    registerLoading.value = true;
+    let params = {
+      ...ruleForm.value,
+    }
+    /* 如果地址栏有参数,就带上 */
+    if (!isValueEmpty(route.query)) {
+      params = {
+        ...params,
+        ...route.query
+      }
+    }
+    // console.log(params);
+    post(REGISTER, params).then(res => {
+      if (res.code == "ok") {
+        ElNotification.success({
+          title: "提示",
+          message: "注册成功",
+          type: "success",
+          duration:3000,
+          onClose: () => {
+            registerLoading.value = false;
+            router.back()
+          }
+        })
+      } else {
+        ElNotification.error({
+          title: "提示",
+          message: res.message || res.msg,
+          type: "success",
+          duration: 3000,
+        })
+        registerLoading.value = false;
+      }
+    }).catch(err => {
+      ElNotification.error({
+        title: "提示",
+        message: err.message || err.msg,
+        type: "success",
+        duration: 3000,
+      })
+      registerLoading.value = false;
+    })
+
+  })
+
+};
+
+</script>
+
+<style lang="scss" scoped>
+.loginView {
+  background: #f0f2f5 url("../assets/login/background.png") no-repeat;
+}
+</style>

+ 1 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/api.ts

@@ -0,0 +1 @@
+export const TEST_API = "/api/test"; //发送验证码

+ 9 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/index.vue

@@ -0,0 +1,9 @@
+<template>
+<div id="" class="h100">
+    线索文件
+</div>
+</template>
+<script setup lang="ts">
+</script>
+<style scoped lang="scss">
+</style>

+ 80 - 34
fhKeeper/formulahousekeeper/customerBuler-crm/src/router/index.ts

@@ -1,36 +1,82 @@
-import { createRouter, createWebHistory, } from 'vue-router'
-import Login from '../pages/login.vue';
+import { RouteRecordRaw,createRouter, createWebHistory } from "vue-router";
+import { useStore } from "@/store/index";
+export const routes: RouteRecordRaw[] = [
+  {
+    path: "/",
+    redirect: "/login",
+  },
+  {
+    name: "login",
+    path: "/login",
+    component: () => import("../pages/login.vue"),
+  },
+  {
+    name: "register",
+    path: "/register",
+    component: () => import("../pages/register.vue"),
+  },
+  {
+    name: "home",
+    path: "/home",
+    component: () => import("../pages/home.vue"),
+    children: [
+      // {
+      //     name: 'thread',
+      //     path: '/thread',
+      //     component: () => import("../pages/thread/thread.vue")
+      // },
+    ],
+  },
+  {
+    name: "test",
+    path: "/test",
+    component: () => import("../pages/test/index.vue"),
+  },
+  {
+    name: "testEcharts",
+    path: "/testEcharts",
+    component: () => import("../pages/test/echarts.vue"),
+  },
+];
 
-export const routes = [
-    {
-        path: '/',
-        redirect: '/login'
-    },
-    {
-        name: 'login',
-        path: '/login',
-        component: Login
-    },
-    {
-        name: 'index',
-        path: '/index',
-        component: () => import("../pages/index.vue")
-    }, {
-        name: "test",
-        path: "/test",
-        component: () => import("../pages/test/index.vue")
-    }, {
-        name: "testEcharts",
-        path: "/testEcharts",
-        component: () => import("../pages/test/echarts.vue")
-    }
-]
 const router = createRouter({
-    scrollBehavior: () => ({ left: 0, top: 0 }),
-    history: createWebHistory(),
-    routes,
-})
-router.beforeEach((_to, _from, next) => {
-    next()
-})
-export default router
+  scrollBehavior: () => ({ left: 0, top: 0 }),
+  history: createWebHistory(),
+  routes,
+});
+router.beforeEach((to, _from, next) => {
+  const routerList = useStore().routers;
+  const routers = router.getRoutes();
+  console.log(routerList, routers);
+  const { setAsyncRoutesMark, asyncRoutesMark } = useStore();
+  const token = true;
+  const skipPath = ['/login', '/register', '/test', '/testEcharts']
+  if (skipPath.includes(to.path)) {
+    next();
+  } else {
+    if (token && routerList && routerList.length > 0) {
+      if (asyncRoutesMark) {
+        next();
+      } else {
+        setAsyncRoutesMark(true)
+        const newRouters: any = routers
+        const addNewRouter = newRouters.find((item: any) => item.name == 'home')
+        routerList.forEach((item: any) => {
+          addNewRouter?.children.push({
+            path: item.path,
+            name: item.name,
+            meta: {},
+            component: () => import(`@/pages/${item.name}/index.vue`),
+          })
+        })
+        router.addRoute(addNewRouter);
+        next({ ...to, replace: true });
+      }
+    } else {
+      console.log("无登录信息,跳转到登录页");
+      next(`/login`);
+    }
+  }
+  console.log(routerList);
+});
+export default router;

+ 14 - 8
fhKeeper/formulahousekeeper/customerBuler-crm/src/store/index.ts

@@ -1,17 +1,23 @@
 import { defineStore, acceptHMRUpdate } from "pinia";
 export const useStore = defineStore({
     id: "index",
-    state: () => ({name: "old name",}),
-    getters: {
-        myName: (state) => {
-            return `getters ${state.name}`
-        }
+    state: () => ({
+        userInfo: {}, // 当前的用户信息
+        routers: [], // 返回的所有路由
+        asyncRoutesMark: false, // 是否添加过路由
+    }),
+    getters: { // 取值
+        
     },
-    actions: {
-        changeName(name: string) {
-            this.name = name
+    actions: { // 方法
+        setRouters(arr: any) {
+            this.routers = arr;
+        },
+        setAsyncRoutesMark(val: boolean) {
+            this.asyncRoutesMark = val
         }
     },
+    persist: true, // 是否持久化
 });
 if (import.meta.hot) {
     import.meta.hot.accept(acceptHMRUpdate(useStore, import.meta.hot))

+ 0 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/styles.css


+ 13 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/styles/global.scss

@@ -0,0 +1,13 @@
+$darkBlue: #3475C5;
+$ashen: #FEFEFE;
+$backColor: #EEF3F6;
+$black: #000;
+$fontBlack: #333;
+$fontGray: #999;
+
+.text-gray{
+    color : $fontGray
+}
+.text-black {
+    color : $fontBlack
+}

+ 6 - 6
fhKeeper/formulahousekeeper/customerBuler-crm/src/utils/request.ts

@@ -2,10 +2,10 @@ import axios from "axios";
 import { showMessage } from "./errorStatusCode"; // 引入状态码文件
 import type { AxiosRequestConfig, AxiosResponse, AxiosError } from "axios";
 import { ElNotification } from "element-plus";
-
+const baseURL = "/api";
 // 创建axios实例
 const instance = axios.create({
-  baseURL: "/api", // 设置API的基础URL
+  baseURL, // 设置API的基础URL
 });
 
 // 请求拦截器
@@ -42,9 +42,9 @@ instance.interceptors.response.use(
 );
 
 // 封装GET请求
-export async function get<T>(url: string, params?: any): Promise<T> {
+export async function get(url: string, params?: any): Promise<any> {
   return instance
-    .get<T>(url, { params })
+    .get(url, { params })
     .then((response) => response.data)
     .catch((error) => {
       throw error;
@@ -52,9 +52,9 @@ export async function get<T>(url: string, params?: any): Promise<T> {
 }
 
 // 封装POST请求
-export async function post<T>(url: string, data?: any): Promise<T> {
+export async function post(url: string, data?: any): Promise<any> {
   return instance
-    .post<T>(url, data, {
+    .post(url, data, {
       headers: {
         "Content-type": " application/x-www-form-urlencoded; charset=UTF-8",
       },

+ 22 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/utils/tools.ts

@@ -0,0 +1,22 @@
+export function isValueEmpty(value: any): boolean {
+  if (value === null || value === undefined) {
+    return true;
+  }
+  if (typeof value === "string" && value.trim() === "") {
+    return true;
+  }
+  if (Array.isArray(value) && value.length === 0) {
+    return true;
+  }
+  if (
+    typeof value === "object" &&
+    !Array.isArray(value) &&
+    Object.keys(value).length === 0
+  ) {
+    return true;
+  }
+  if (typeof value === "symbol" && value.toString() === "Symbol()") {
+    return true;
+  }
+  return false;
+}