jinx 3 years ago
parent
commit
4cebd685b6

+ 5 - 0
.gitignore

@@ -0,0 +1,5 @@
+node_modules
+.DS_Store
+dist
+dist-ssr
+*.local

+ 3 - 0
.vscode/extensions.json

@@ -0,0 +1,3 @@
+{
+  "recommendations": ["johnsoncodehk.volar"]
+}

+ 3 - 0
.vscode/settings.json

@@ -0,0 +1,3 @@
+{
+    "vue3snippets.enable-compile-vue-file-on-did-save-code": true
+}

+ 14 - 0
index.html

@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="UTF-8" />
+    <link rel="icon" href="/favicon.ico" />
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <title>Vite App</title>
+  </head>
+  <body>
+    <div id="app"></div>
+    <script src="https://use.fontawesome.com/276552fbe7.js"></script>
+    <script type="module" src="/src/main.js"></script>
+  </body>
+</html>

File diff suppressed because it is too large
+ 2403 - 0
package-lock.json


+ 25 - 0
package.json

@@ -0,0 +1,25 @@
+{
+  "name": "vite-zfb",
+  "version": "0.0.0",
+  "scripts": {
+    "dev": "vite",
+    "build": "vite build",
+    "serve": "vite preview"
+  },
+  "dependencies": {
+    "axios": "^0.23.0",
+    "element-plus": "^1.1.0-beta.24",
+    "js-base64": "^3.7.2",
+    "qs": "^6.10.1",
+    "sass": "^1.43.3",
+    "vue": "^3.2.16",
+    "vue-router": "^4.0.12",
+    "vuex": "^4.0.2"
+  },
+  "devDependencies": {
+    "@vitejs/plugin-vue": "^1.9.3",
+    "node-sass": "^6.0.1",
+    "sass-loader": "^12.2.0",
+    "vite": "^2.6.4"
+  }
+}

BIN
public/favicon.ico


+ 25 - 0
src/App.vue

@@ -0,0 +1,25 @@
+<script setup>
+// This starter template is using Vue 3 <script setup> SFCs
+// Check out https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup
+// import HelloWorld from "./components/HelloWorld.vue";
+import layout from "./layout/index.vue";
+</script>
+
+<template>
+  <router-view></router-view>
+</template>
+
+<style>
+* {
+  margin: 0;
+  padding: 0;
+}
+#app {
+  /* font-family: Avenir, Helvetica, Arial, sans-serif;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  text-align: center;
+  color: #2c3e50;
+  margin-top: 60px; */
+}
+</style>

+ 2 - 0
src/api/api.js

@@ -0,0 +1,2 @@
+import { get,post } from "@/util/http/request"
+export const loginapi = params => post('/sys/login', params)

BIN
src/assets/logo.png


+ 27 - 0
src/components/confirm/index.js

@@ -0,0 +1,27 @@
+import {
+    ElMessageBox,
+    ElMessage
+} from "element-plus";
+const confirm = (data) => {
+    return new Promise((resolve, reject) => {
+        ElMessageBox.confirm(data.title || '', data.tip || '提示', {
+                confirmButtonText: data.confirmText || "确定",
+                cancelButtonText: data.cancelText || "取消",
+                type: data.type || "info",
+            })
+            .then(() => {
+                resolve(true)
+            })
+            .catch(() => {
+                reject(false)
+                ElMessage({
+                    type: "warning",
+                    message: data.cancelTetx || "取消操作",
+                });
+
+            });
+    })
+
+}
+
+export default confirm

+ 135 - 0
src/components/searchForm/index.vue

@@ -0,0 +1,135 @@
+<template>
+  <div id="searchForm">
+    <div
+      class="searchBox"
+      v-if="searchFormData.searchList && searchFormData.searchList.length > 0"
+    >
+      <div v-for="(i, index) in searchFormData.searchList" :key="index">
+        <div v-if="i.type == 'input'" class="inputBox">
+          <!-- <el-input
+            v-model.trim="searchData.data[index].value" -->
+          <el-input v-model="searchData[i.model]" placeholder="Please input" />
+        </div>
+        <div class="selectBox" v-if="i.type == 'select'">
+          <el-select v-model="searchData[i.model]" placeholder="Select">
+            <el-option
+              v-for="item in i.options"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-select>
+        </div>
+      </div>
+
+      <el-button type="primary" @click="handleSearch">查询</el-button>
+    </div>
+    <div class="buttonBox">
+      <slot name="button"></slot>
+    </div>
+  </div>
+</template>
+
+<script>
+import {
+  defineComponent,
+  reactive,
+  ref,
+  toRefs,
+  onMounted,
+  getCurrentInstance,
+} from "vue";
+import { useRoute, useRouter } from "vue-router";
+export default defineComponent({
+  props: {
+    searchFormData: {
+      type: Object,
+      default: {},
+    },
+  },
+  setup() {
+    const { ctx } = getCurrentInstance();
+    const data = reactive({
+      searchData: {},
+
+      input: ref(""),
+      value: ref(""),
+      options: [
+        {
+          value: "Option1",
+          label: "Option1",
+        },
+        {
+          value: "Option2",
+          label: "Option2",
+        },
+        {
+          value: "Option3",
+          label: "Option3",
+        },
+        {
+          value: "Option4",
+          label: "Option4",
+        },
+        {
+          value: "Option5",
+          label: "Option5",
+        },
+      ],
+    });
+    onMounted(() => {
+      initSearch(ctx.searchFormData.searchList);
+    });
+    const handleSearch = () => {
+      ctx.$emit('handleSearch',data.searchData)
+    };
+    const initSearch = (list) => {
+      console.log(list.length);
+      if (list && list.length > 0) {
+        list.forEach((item, index) => {
+          data.searchData[item.model] = item.text || "";
+        });
+      }
+    };
+    return {
+        handleSearch,
+      ...toRefs(data),
+    };
+  },
+  components: {},
+});
+</script>
+
+<style scoped lang="scss">
+#searchForm {
+  width: 100%;
+  height: 80px;
+  box-shadow: 0 0 12px 0 rgba(0, 0, 0, 0.1);
+  background: #fff;
+  padding: 0 20px;
+  line-height: 80px;
+  box-sizing: border-box;
+  border-radius: 3px;
+  //   display: flex;
+  //   align-items: center;
+  //   justify-content: space-between;
+  .searchBox {
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+    float: left;
+    .inputBox {
+      width: 150px;
+      margin-right: 10px;
+    }
+    .selectBox {
+      width: 150px;
+      margin-right: 10px;
+    }
+  }
+  .buttonBox {
+    float: right;
+  }
+}
+</style>

+ 89 - 0
src/components/tableForm/index.vue

@@ -0,0 +1,89 @@
+<template>
+  <div id="tableForm">
+    <div class="tableContent">
+      <el-table :data="tableData" style="width: 100%">
+        <el-table-column align="center" prop="date" label="Date" />
+        <el-table-column align="center" prop="name" label="Name" />
+        <el-table-column align="center" prop="address" label="Address" />
+      </el-table>
+    </div>
+    <div class="paginationBox">
+      <el-pagination
+        v-model:currentPage="currentPage2"
+        :page-sizes="sizes"
+        :page-size="sizes[0]"
+        layout="sizes, prev, pager, next"
+        :total="1000"
+        @size-change="handleSizeChange"
+        @current-change="handleCurrentChange"
+      >
+      </el-pagination>
+    </div>
+  </div>
+</template>
+
+<script>
+import { defineComponent, reactive, ref, toRefs, onMounted } from "vue";
+import { useRoute, useRouter } from "vue-router";
+export default defineComponent({
+  setup() {
+    const data = reactive({
+      sizes: [10, 30, 50, 100],
+      currentPage2: ref(5),
+      tableData: [
+        {
+          date: "2016-05-03",
+          name: "Tom",
+          address: "No. 189, Grove St, Los Angeles",
+        },
+        {
+          date: "2016-05-02",
+          name: "Tom",
+          address: "No. 189, Grove St, Los Angeles",
+        },
+        {
+          date: "2016-05-04",
+          name: "Tom",
+          address: "No. 189, Grove St, Los Angeles",
+        },
+        {
+          date: "2016-05-01",
+          name: "Tom",
+          address: "No. 189, Grove St, Los Angeles",
+        },
+      ],
+    });
+
+    const handleSizeChange = (val) => {
+      console.log(`${val} items per page`);
+    };
+    const handleCurrentChange = (val) => {
+      console.log(`current page: ${val}`);
+    };
+    return {
+      handleSizeChange,
+      handleCurrentChange,
+      ...toRefs(data),
+    };
+  },
+  components: {},
+});
+</script>
+
+<style lang="scss">
+#tableForm {
+  margin-top: 20px;
+  box-shadow: 0 0 12px 0 rgba(0, 0, 0, 0.1);
+  border-radius: 4px;
+  background: #fff;
+  overflow: hidden;
+  padding: 20px;
+  box-sizing: border-box;
+}
+.paginationBox {
+  display: flex;
+  align-items: center;
+  justify-content: flex-end;
+  margin-top: 20px;
+}
+</style>

+ 139 - 0
src/layout/aside/index.vue

@@ -0,0 +1,139 @@
+<template>
+  <div id="aside">
+    <h3 class="productName">四维指房宝</h3>
+    <div class="menuList">
+      <el-menu
+        :default-active="activeName"
+        :unique-opened="true"
+        class="el-menu-vertical"
+        @open="handleOpen"
+        @close="handleClose"
+        @select="handleClick"
+        router
+      >
+        <div v-for="(item, index) in muenList" :key="index">
+          <el-menu-item v-if="!item.children" :index="item.path">
+            <i :class="item.icon"></i>
+            <span>{{ item.name }}</span>
+          </el-menu-item>
+          <el-sub-menu v-else :index="item.key">
+            <template #title>
+              <i :class="item.icon"></i>
+              <span>{{ item.name }}</span>
+            </template>
+            <div v-for="(j, j_index) in item.children" :key="j_index">
+              <el-menu-item :index="j.path">{{ j.name }}</el-menu-item>
+            </div>
+          </el-sub-menu>
+        </div>
+      </el-menu>
+    </div>
+  </div>
+</template>
+<script>
+import { defineComponent, reactive, ref, toRefs, onMounted } from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { useStore } from "vuex";
+export default defineComponent({
+  name: "Aside",
+  components: {},
+  setup(props, ctx) {
+    const router = useRouter();
+    const route = useRoute();
+    const store = useStore();
+    const data = reactive({
+      muenList: [
+        {
+          name: "首页",
+          path: "/home",
+          icon: "el-icon-location",
+          key: "home",
+        },
+        {
+          name: "VR场景",
+          path: null,
+          icon: "el-icon-document",
+          key: "vrList",
+          children: [
+            {
+              name: "场景列表",
+              path: "/list",
+              icon: "",
+              key: "list",
+            },
+            {
+              name: "直播间",
+              path: "/brand",
+              icon: "",
+              key: "brand",
+            },
+          ],
+        },
+        {
+          name: "商品管理",
+          path: null,
+          icon: "el-icon-setting",
+          key: "product",
+          children: [
+            {
+              name: "商品属性",
+              path: "/productNature",
+              icon: "",
+              key: "productNature",
+            },
+            {
+              name: "商品列表",
+              path: "/productList",
+              icon: "",
+              key: "productList",
+            },
+          ],
+        },
+      ],
+      activeName: "",
+    });
+    onMounted(() => {
+      //   data.activeName = route.meta.title;
+      data.activeName = route.path;
+      console.log(data.activeName);
+      //   console.log(route.meta.title);
+    });
+    const handleOpen = (key, keyPath) => {
+      //   console.log(key, keyPath);
+    };
+    const handleClose = (key, keyPath) => {
+      //   console.log(key, keyPath);
+    };
+    const handleClick = (key, keyPath) => {
+      //   console.log(key, keyPath);
+      //   console.log(route);
+      store.commit("setNavTitle", route.name);
+      console.log(store.state.navTitle);
+    };
+    return {
+      handleOpen,
+      handleClose,
+      handleClick,
+      ...toRefs(data),
+    };
+  },
+});
+</script>
+
+<style scoped lang="scss">
+#aside {
+  width: 200px;
+  height: 100vh;
+  background: #2f4050;
+  .productName {
+    color: #fff;
+    text-align: center;
+    padding: 13px 0;
+    box-sizing: border-box;
+  }
+  .menuList {
+    .el-menu {
+    }
+  }
+}
+</style>

+ 80 - 0
src/layout/content/components/topbar.vue

@@ -0,0 +1,80 @@
+<template>
+  <div id="topBar">
+    <div>{{ title }}</div>
+
+    <div class="accountMsg">
+      <div class="name"><i class="fa fa-user"></i>项王装饰</div>
+      <div class="password">
+        <i class="fa fa-lock"></i>
+        修改密码
+      </div>
+      <div class="exit" @click="logout"><i class="fa fa fa-sign-out"></i>退出</div>
+    </div>
+  </div>
+</template>
+
+<script>
+import {
+  defineComponent,
+  reactive,
+  ref,
+  toRefs,
+  onMounted,
+  getCurrentInstance,
+} from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { ElMessage } from "element-plus";
+import confirm from "@/components/confirm";
+export default defineComponent({
+  setup() {
+    const router = useRouter();
+    const route = useRoute();
+    const data = reactive({
+      title: route.name,
+    });
+
+    const logout = async () => {
+      let res = await confirm({
+        title: "注:您确定要安全退出本次登录吗?",
+      });
+      if (res) {
+        router.push("/login");
+        ElMessage({
+          type: "success",
+          message: "退出成功",
+        });
+      }
+    };
+
+    return {
+      logout,
+      ...toRefs(data),
+    };
+  },
+  components: {},
+});
+</script>
+
+<style scoped lang="scss">
+#topBar {
+  width: 100%;
+  height: 60px;
+  box-shadow: 0 0 12px 0 rgba(0, 0, 0, 0.1);
+  background: #fff;
+  padding: 0 20px;
+  line-height: 60px;
+  box-sizing: border-box;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  .accountMsg {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    > div {
+      margin-left: 10px;
+      cursor: pointer;
+    }
+  }
+}
+</style>

+ 30 - 0
src/layout/content/index.vue

@@ -0,0 +1,30 @@
+<template>
+  <div id="layout_content">
+    <topBar />
+    <div class="views_content">
+      <router-view></router-view>
+    </div>
+  </div>
+</template>
+
+<script>
+import topBar from "./components/topbar.vue";
+export default {
+  data() {
+    return {};
+  },
+  components: { topBar },
+};
+</script>
+
+<style scoped lang="scss">
+#layout_content {
+  width: calc(100% - 200px);
+  height: 100vh;
+  background-color: #f2f2f2;
+  .views_content{
+      padding: 20px;
+      box-sizing: border-box;
+  }
+}
+</style>

+ 34 - 0
src/layout/header/index.vue

@@ -0,0 +1,34 @@
+<template>
+  <div id="layoutHader">
+    <nav role="navigation" class="navbar navbar-static-top" style="margin-bottom: 0px">
+      <ul class="nav navbar-top-links navbar-right">
+        <li><div style="color: red"></div></li>
+        <li>
+          <a><i class="fa fa-user"></i>用户17324327132</a>
+        </li>
+        <li>
+          <a href="javascript:;"><i class="fa fa-lock"></i> &nbsp;修改密码</a>
+        </li>
+        <li>
+          <a><i class="fa fa fa-sign-out"></i>退出</a>
+        </li>
+      </ul>
+    </nav>
+  </div>
+</template>
+
+<script>
+import { defineComponent, reactive, ref, toRefs, onMounted } from "vue";
+import { useRoute, useRouter } from "vue-router";
+export default defineComponent({
+  setup() {
+    const data = reactive({});
+    return {
+      ...toRefs(data),
+    };
+  },
+  components: {},
+});
+</script>
+
+<style scoped lang="scss"></style>

+ 28 - 0
src/layout/index.vue

@@ -0,0 +1,28 @@
+<template>
+  <div id="layout">
+      <layoutAside/>
+      <layoutContent/>
+  </div>
+</template>
+
+<script>
+import layoutAside from "./aside/index.vue";
+import layoutContent from "./content/index.vue";
+export default {
+  data() {
+    return {};
+  },
+  components: {
+    layoutAside,
+    layoutContent
+  },
+};
+</script>
+
+<style scoped lang="scss">
+#layout {
+    display: flex;
+    align-content: center;
+    justify-content: flex-start;
+}
+</style>

+ 69 - 0
src/layout/login/login.vue

@@ -0,0 +1,69 @@
+<template>
+  <div id="login">
+    <el-button type="primary" @click="login">登录</el-button>
+    <input v-model="captcha" type="" name="" />
+    <img src="https://plaza.4dkankan.com/captcha.jpg" alt="" />
+    <a v-if="show">文本</a>
+    <router-view></router-view>
+  </div>
+</template>
+
+<script>
+import { defineComponent, reactive, ref, toRefs, onMounted } from "vue";
+import { useRoute, useRouter } from "vue-router";
+import { useStore } from "vuex";
+import { Base64 } from "js-base64";
+import { loginapi } from "@/api/api";
+import { encodeStr } from "@/util/common";
+export default defineComponent({
+  name: "login",
+  components: {},
+  setup(props, ctx) {
+    const store = useStore();
+    const wenben = ref(null);
+    console.log(props);
+    console.log(ctx);
+    const router = useRouter();
+    console.log(router);
+    const data = reactive({
+      show: false,
+      username: "18819272208",
+      password: "zfb123456",
+      //   captcha: "",
+    });
+    console.log(data);
+    const login = () => {
+      data.show = true;
+      console.log(data.show);
+      let params = {
+        username: data.username,
+        password: encodeStr(Base64.encode(data.password)),
+        // password: data.password,
+        captcha: data.captcha,
+      };
+      store.dispatch("setUserInfo", params);
+      console.log(store.state.userInfo);
+      loginapi(params)
+        .then((res) => {
+          console.log(res);
+          router.push("/home");
+        })
+        .catch((err) => {
+          console.log(params);
+          console.log(err);
+        });
+    };
+
+    onMounted(() => {
+      //   wenben.value.style = "display:none;";
+    });
+
+    return {
+      login,
+      ...toRefs(data),
+    };
+  },
+});
+</script>
+
+<style scoped lang="scss"></style>

+ 21 - 0
src/main.js

@@ -0,0 +1,21 @@
+import {
+    createApp
+} from 'vue'
+import ElementPlus from 'element-plus'
+import locale from 'element-plus/lib/locale/lang/zh-cn'
+import 'element-plus/dist/index.css'
+import App from './App.vue'
+import router from "./router"
+import store from './store'
+
+const app = createApp(App);
+app.config.productionTip = false;
+app.use(ElementPlus, {
+    locale
+})
+app.use(router)
+app.use(store)
+app.mount('#app');
+
+
+// createApp(App).mount('#app')

+ 58 - 0
src/router/index.js

@@ -0,0 +1,58 @@
+import list from './router.config';
+import {
+    createRouter,
+    createWebHashHistory
+} from "vue-router";
+
+const routes = [{
+        path: '/',
+        component: list.layout,
+        children: [{
+                path: '/home',
+                name: '首页',
+                component: list.home,
+                meta: {
+                    title: 'home',
+                    role: [1, 2, 3]
+                },
+            },
+            {
+                path: '/brand',
+                name: '直播间',
+                component: list.brand,
+                meta: {
+                    title: 'brand',
+                    role: [1, 2, 3]
+                },
+            },
+
+        ]
+    },
+
+    {
+        path: '/login',
+        component: list.login,
+        
+        // children: [{
+        //     path: 'list',
+        //     name: 'list',
+        //     component: list.list,
+        //     meta: {
+        //         title: 'list',
+        //         role: [1, 2, 3]
+        //     },
+        // }, ]
+    },
+    {
+        path: '/:pathMatch(.*)*',
+        redirect: '/home'
+    },
+]
+
+
+const router = createRouter({
+    history: createWebHashHistory(),
+    routes
+});
+
+export default router

+ 14 - 0
src/router/router.config.js

@@ -0,0 +1,14 @@
+ 
+ import login from "@/layout/login/login.vue"
+ import layout from "@/layout/index.vue"
+ import home from "@/views/home/home.vue"
+ import brand from "@/views/brand/brand.vue"
+ import list from "@/views/brand/list.vue"
+
+ export default {
+     layout,
+     login,
+     home,
+     brand,
+     list
+ }

+ 7 - 0
src/store/actions.js

@@ -0,0 +1,7 @@
+const actions = {
+    setUserInfo(vuex, v) {
+        console.log('进来了')
+        vuex.commit('setUserInfo', v)
+    },
+}
+export default actions

+ 9 - 0
src/store/getters.js

@@ -0,0 +1,9 @@
+const getters = {
+    getUserInfo: (state) => {
+        return state.userInfo
+    },
+    getNavTitle: (state) => {
+        return state.navTitle
+    },
+}
+export default getters

+ 16 - 0
src/store/index.js

@@ -0,0 +1,16 @@
+import {
+    createStore
+} from "vuex"
+import getters from "./getters"
+import actions from "./actions"
+import mutations from "./mutations"
+import state from "./state"
+
+const store = createStore({
+    getters,
+    actions,
+    mutations,
+    state
+})
+
+export default store

+ 10 - 0
src/store/mutations.js

@@ -0,0 +1,10 @@
+const mutations = {
+    setUserInfo(state, v) {
+        state.userInfo = v
+    },
+    setNavTitle(state,v){
+        state.navTitle = v
+    }
+ 
+}
+export default mutations

+ 5 - 0
src/store/state.js

@@ -0,0 +1,5 @@
+const state ={
+    userInfo:null,
+    navTitle:'',
+}
+export default state

+ 31 - 0
src/util/common.js

@@ -0,0 +1,31 @@
+export function encodeStr(str, strv = '') { 
+    const NUM = 2
+    const front = randomWord(false, 8)
+    const middle = randomWord(false, 8)
+    const end = randomWord(false, 8)
+
+    let str1 = str.substring(0, NUM)
+    let str2 = str.substring(NUM)
+
+    if (strv) {
+        let strv1 = strv.substring(0, NUM)
+        let strv2 = strv.substring(NUM)
+        return [front + str2 + middle + str1 + end, front + strv2 + middle + strv1 + end]
+    }
+
+    return front + str2 + middle + str1 + end
+}
+function randomWord(randomFlag, min, max) { 
+    let str = ''
+    let range = min
+    let arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
+    // 随机产生
+    if (randomFlag) {
+        range = Math.round(Math.random() * (max - min)) + min
+    }
+    for (var i = 0; i < range; i++) {
+        let pos = Math.round(Math.random() * (arr.length - 1))
+        str += arr[pos]
+    }
+    return str
+}

+ 32 - 0
src/util/http/http.js

@@ -0,0 +1,32 @@
+import axios from 'axios'
+import router from '@/router' // 创建axios
+const service = axios.create({
+    baseURL: '/',
+    timeout: 30000,
+    headers: {
+        'Content-Type': 'application/json;charset=UTF-8'
+    }
+});
+
+// 添加请求拦截器
+service.interceptors.request.use(function (config) {
+    // 在发送请求之前做些什么
+    // config.headers['Content-Type'] = 'application/json;charset=UTF-8'
+    return config;
+}, function (error) {
+    // 对请求错误做些什么
+    return Promise.reject(error);
+});
+
+// 添加响应拦截器
+service.interceptors.response.use(function (response) {
+    // 对响应数据做点什么
+    console.log('res', response);
+
+    return response;
+}, function (error) {
+    // 对响应错误做点什么
+    return Promise.reject(error);
+});
+
+export default service;

+ 34 - 0
src/util/http/request.js

@@ -0,0 +1,34 @@
+import request from './http.js'
+// import qs from 'qs';
+/**
+ * get方法,对应get请求
+ * @param {String} url [请求的url地址]
+ * @param {Object} params [请求时携带的参数]
+ */
+export function get(url, params) {
+    return new Promise((resolve, reject) => {
+        request.get(url, {
+           params
+        }).then(res => {
+            resolve(res.data)
+        }).catch(err => {
+            reject(err.data)
+        })
+    })
+}
+/**
+ * post方法,对应post请求
+ * @param {String} url [请求的url地址]
+ * @param {Object} params [请求时携带的参数]
+ */
+export function post(url, params) {
+    return new Promise((resolve, reject) => {
+        request.post(url, params)
+            .then(res => {
+                resolve(res.data)
+            })
+            .catch(err => {
+                reject(err.data)
+            })
+    })
+}

+ 100 - 0
src/views/brand/brand.vue

@@ -0,0 +1,100 @@
+<template>
+  <div id="page">
+    <searchForm :searchFormData="searchFormData" @handleSearch="handleSearch">
+      <template #button>
+        <el-button type="success">新增</el-button>
+        <el-button type="danger">删除</el-button>
+      </template>
+    </searchForm>
+    <tableForm />
+  </div>
+</template>
+
+<script>
+import {
+  defineComponent,
+  reactive,
+  ref,
+  toRefs,
+  onMounted,
+  getCurrentInstance,
+} from "vue";
+import { useRoute, useRouter } from "vue-router";
+import searchForm from "@/components/searchForm/index.vue";
+import tableForm from "@/components/tableForm/index.vue";
+export default defineComponent({
+  components: { searchForm, tableForm },
+  setup(props) {
+    const { ctx } = getCurrentInstance();
+    const data = reactive({
+      searchFormData: {
+        btnList: [
+          {
+            type: "bind",
+            text: "绑定主播",
+            function: ctx.bindLive,
+          },
+          {
+            type: "add",
+            text: "新增",
+            function: null,
+          },
+          {
+            type: "edit",
+            text: "修改",
+            function: null,
+          },
+          {
+            type: "delete",
+            text: "删除",
+            function: null,
+          },
+        ],
+        searchList: [
+          {
+            type: "input",
+            model: "input_data",
+            inputType: "text",
+          },
+          {
+            type: "select",
+            model: "select_data",
+            options: [
+              {
+                value: "Option1",
+                label: "Option1",
+              },
+              {
+                value: "Option2",
+                label: "Option2",
+              },
+              {
+                value: "Option3",
+                label: "Option3",
+              },
+              {
+                value: "Option4",
+                label: "Option4",
+              },
+              {
+                value: "Option5",
+                label: "Option5",
+              },
+            ],
+          },
+        ],
+      },
+    });
+    onMounted(() => {});
+    const handleSearch = (res) => {
+      console.log("handleSearch", res);
+    };
+    return {
+      handleSearch,
+      ...toRefs(data),
+    };
+  },
+});
+</script>
+
+<style scoped lang="scss"></style>

+ 19 - 0
src/views/brand/list.vue

@@ -0,0 +1,19 @@
+<template>
+  <div id="page">list</div>
+</template>
+
+<script>
+import { defineComponent, reactive, ref, toRefs, onMounted } from "vue";
+import { useRoute, useRouter } from "vue-router";
+export default defineComponent({
+  setup() {
+    const data = reactive();
+    return {
+      ...toRefs(data),
+    };
+  },
+  components: {},
+});
+</script>
+
+<style scoped lang="scss"></style>

+ 101 - 0
src/views/home/home.vue

@@ -0,0 +1,101 @@
+<template>
+  <div id="page">
+    <searchForm :searchFormData="searchFormData" @handleSearch="handleSearch">
+      <template #button>
+        <el-button type="success">新增</el-button>
+        <el-button type="danger">删除</el-button>
+      </template>
+    </searchForm>
+    <tableForm />
+  </div>
+</template>
+
+<script>
+import {
+  defineComponent,
+  reactive,
+  ref,
+  toRefs,
+  onMounted,
+  getCurrentInstance,
+} from "vue";
+import { useRoute, useRouter } from "vue-router";
+import searchForm from "@/components/searchForm/index.vue";
+import tableForm from "@/components/tableForm/index.vue";
+export default defineComponent({
+  components: { searchForm, tableForm },
+  setup(props) {
+    const { ctx } = getCurrentInstance();
+    const data = reactive({
+      searchFormData: {
+        btnList: [
+          {
+            type: "bind",
+            text: "绑定主播",
+            function: ctx.bindLive,
+          },
+          {
+            type: "add",
+            text: "新增",
+            function: null,
+          },
+          {
+            type: "edit",
+            text: "修改",
+            function: null,
+          },
+          {
+            type: "delete",
+            text: "删除",
+            function: null,
+          },
+        ],
+        searchList: [
+          {
+            type: "input",
+            model: "input_data",
+            inputType: "text",
+          },
+          {
+            type: "select",
+            model: "select_data",
+            options: [
+              {
+                value: "Option1",
+                label: "Option1",
+              },
+              {
+                value: "Option2",
+                label: "Option2",
+              },
+              {
+                value: "Option3",
+                label: "Option3",
+              },
+              {
+                value: "Option4",
+                label: "Option4",
+              },
+              {
+                value: "Option5",
+                label: "Option5",
+              },
+            ],
+          },
+        ],
+      },
+    });
+    onMounted(() => {});
+    const handleSearch = (res) => {
+      console.log("handleSearch", res);
+    };
+
+    return {
+      handleSearch,
+      ...toRefs(data),
+    };
+  },
+});
+</script>
+
+<style scoped lang="scss"></style>

+ 97 - 0
vite.config.js

@@ -0,0 +1,97 @@
+import {
+  defineConfig
+} from 'vite'
+import vue from '@vitejs/plugin-vue'
+import path from 'path'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+  resolve: {
+    alias: {
+      /*
+        路径别名
+        若为文件系统路径必须是绝对路径的形式,否则将以别名原样呈现,不会解析为文件系统路径路径 
+      */
+      //'@': process.cwd()+'/src'
+      //'@':path.resolve('src')
+      //'@':path.resolve(__dirname, 'src')
+      '@': path.resolve(__dirname, './src')
+    },
+  },
+  plugins: [vue()],
+
+  /*
+    Project root directory/项目根目录(index.html所在位置),可以是绝对路径,也可以是相对于本配置文件的路径。
+    default:process.cwd() 返回 Node.js 进程的当前工作目录
+  */
+  //root:process.cwd(),
+
+  /*
+    Default: /
+    Base public path (应用基础请求路径) when served in development or production. Valid values include:
+    
+    Absolute URL pathname, e.g. /foo/
+    Full URL, e.g. https://foo.com/
+    Empty string or ./ (for embedded deployment)
+  */
+  // base: '/admin/',
+
+  /*
+    Directory to serve as plain static assets. 
+    Files in this directory are served at / during dev and copied to the root of outDir during build, and are always served or copied as-is without transform. 
+    The value can be either an absolute file system path or a path relative to project root.
+    静态资源目录,开发模式下会自动放到 / 下,生产模式下会自动放到 outDir 根路径下。
+    该目录可以配置为文件系统绝对目录或者相对于项目根目录的相对路径
+  */
+  publicDir: 'public',
+
+  /*
+    Default: 'development' for serve, 'production' for build
+    Specifying this in config will override the default mode for both serve and build. This value can also be overridden via the command line --mode option.
+  */
+  //mode:'',
+
+  //vite开发服务器配置
+  server: {
+    host: '0.0.0.0',
+    port: 3000,
+    open: false,
+    strictPort: false,
+    https: false,
+
+    // 反向代理
+    proxy: {
+      '/sys': {
+        // target: 'https://plaza.4dkankan.com',
+        target: 'http://192.168.0.47:8190',
+        changeOrigin: true,
+        // rewrite: (path) => path.replace(/^\/sys/, '')
+        pathRewrite: {
+          '^/api': ''
+        }
+      },
+    }
+
+    //proxy: {
+    //   // string shorthand
+    //   '/foo': 'http://localhost:4567/foo',
+    //   // with options
+    //   '/api': {
+    //     target: 'http://jsonplaceholder.typicode.com',
+    //     changeOrigin: true,
+    //     rewrite: (path) => path.replace(/^\/api/, '')
+    //   },
+    //   // with RegEx
+    //   '^/fallback/.*': {
+    //     target: 'http://jsonplaceholder.typicode.com',
+    //     changeOrigin: true,
+    //     rewrite: (path) => path.replace(/^\/fallback/, '')
+    //   }
+    // }
+  },
+
+  //生产模式打包配置
+  build: {
+    outDir: 'dist', //Specify the output directory (relative to project root).
+  }
+})