zhangqiOMG 2 năm trước cách đây
mục cha
commit
2f1b8eca6c

BIN
src/assets/logo_slices/logo.png


BIN
src/assets/logo_slices/logo@2x.png


+ 45 - 3
src/components/layout/header.vue

@@ -1,14 +1,56 @@
 <template>
   <div class="header">
+    <img height="30" src="@/assets/logo_slices/logo@2x.png" alt="">
+    <div>
+      <a-space>
+        <QuestionCircleOutlined :style="{marginRight:'16px',color:'#fff',fontSize:'16px',cursor: 'pointer'}"/>
+        <BellOutlined :style="{marginRight:'24px',color:'#fff',fontSize:'16px',cursor: 'pointer'}"/>
+        <a-dropdown class="dropdown-link">
+            <a class="ant-dropdown-link" @click.prevent>
+              <a-avatar size="small">
+                <template #icon><UserOutlined /></template>
+              </a-avatar>
+              {{nowAccount.name}}
+              <DownOutlined />
+            </a>
+            <template #overlay>
+              <a-menu>
+                <a-menu-item v-for="item in accountList" :key="item.index">
+                  <a @click="accountItemClick(item,false)">{{item.sitename + '-' + item.name}}</a>
+                </a-menu-item>
+                <a-menu-divider />
+                <a-menu-item>
+                  <logout-outlined />
+                  <a class="color-red" @click="loginOut">&nbsp;退出登录</a>
+                </a-menu-item>
+              </a-menu>
+            </template>
+        </a-dropdown>
+      </a-space>
+      </div>
   </div>
 </template>
 
 <script setup>
+import {ref} from 'vue'
+import { UserOutlined, DownOutlined,BellOutlined,QuestionCircleOutlined } from '@ant-design/icons-vue';
+import { useAuthStore } from '@/stores/modules/auth'
+import { storeToRefs } from 'pinia'
+const store = useAuthStore()
+let { accountList,nowAccount } = storeToRefs(store)
+const accountItemClick= ()=>{}
 </script>
 <style scoped>
 .header{
-  height: 50px;
-  background: #fff;
-  border-bottom:1px solid #f1f2f3
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  height: 56px;
+  padding:0 32px 0 16px;
+  background-image:linear-gradient(90deg, #001D6A 0%, #0060B2 82%, #007BD5 100%);
+  /* border-bottom:1px solid #001D6A */
+}
+.ant-dropdown-link{
+  color:#fff;
 }
 </style>

+ 5 - 4
src/components/layout/index.vue

@@ -20,9 +20,9 @@
         </div>
       </a-layout-content>
     </div>
-    <a-layout-footer class="footer">
+    <!-- <a-layout-footer class="footer">
       Copyright © 2023 嘉兴市云链信息技术有限公司
-    </a-layout-footer>
+    </a-layout-footer> -->
   </a-layout>
 </template>
 <script setup>
@@ -37,7 +37,8 @@ const router = useRouter()
 </script>
 <style>
 .layout{
-  background: url('@/assets/bg.png');
+  /* background: url('@/assets/bg.png'); */
+  background-image:linear-gradient(90deg, #001D6A 0%, #0060B2 82%, #007BD5 100%);
   background-size: cover;
 }
 .site-layout-content {
@@ -62,7 +63,7 @@ const router = useRouter()
 }
 .content-height{
   flex:1;
-  height: calc(100vh - 120px);
+  height: calc(100vh - 56px);
   padding:0 10px 10px 10px;
   overflow-y: scroll;
 }

+ 69 - 4
src/components/layout/menu.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="menu">
-    <a-menu style="flex:1" theme="light" v-model:selectedKeys="current" mode="inline" @click="itemClick">
+    <a-menu style="flex:1" :inlineIndent="5" v-model:selectedKeys="current" mode="inline" active-text-color="#000" @click="itemClick">
       <a-sub-menu v-for="item in mods" :key="item.systemmoduleid">
         <template #title>
           <div>
@@ -11,15 +11,35 @@
         <a-menu-item v-for="app in item.apps" :key="app.systemappid" @click="routeChange(app)">{{app.meta.title}}</a-menu-item>
       </a-sub-menu>
     </a-menu>
+    <a-dropdown>
+      <a class="ant-dropdown-link" @click.prevent>
+        切换主题
+        <DownOutlined />
+      </a>
+      <template #overlay>
+        <a-menu>
+          <a-menu-item>
+            <a @click="setTheme('normal')">默认主题</a>
+          </a-menu-item>
+          <a-menu-item>
+            <a @click="setTheme('light')">明亮主题</a>
+          </a-menu-item>
+          <a-menu-item>
+            <a @click="setTheme('caffairs')">商务主题</a>
+          </a-menu-item>
+        </a-menu>
+      </template>
+    </a-dropdown>
   </div>
 </template>
 
 <script setup>
-import { ref,onMounted,watch} from 'vue';
+import { ref,onBeforeMount} from 'vue';
 import { useAuthStore } from '@/stores/modules/auth'
 import { storeToRefs } from 'pinia'
 import { useRouter } from "vue-router"
 import { MenuFoldOutlined,MenuUnfoldOutlined} from '@ant-design/icons-vue'
+import {ConfigProvider, Modal } from 'ant-design-vue';
 const router = useRouter()
 const store = useAuthStore()
 let { mods } = storeToRefs(store)
@@ -32,10 +52,55 @@ const routeChange = (app)=>{
   store.appData(app)
   router.push({path:app.path})
 }
+const colorState = ref({})
+const setTheme = (themeName)=> {
+  if (themeName === 'light') {
+    colorState.value = {
+      primaryColor: '#f23557',
+      errorColor: '#eb586f',
+      warningColor: '#ffde7d',
+      successColor: '#4aa0d5',
+      infoColor: '#d8e9f0',
+    }
+   
+    ConfigProvider.config({
+      theme: colorState.value
+    });
+    
+  } else if (themeName === 'normal') {
+    colorState.value = {
+      primaryColor: '#14317D',
+      errorColor: '#ff4d4f',
+      warningColor: '#faad14',
+      successColor: '#52c41a',
+      infoColor: '#1890ff',
+    }
+    ConfigProvider.config({
+      theme: colorState.value
+    });
+  } else if (themeName === 'caffairs') {
+    colorState.value = {
+      primaryColor: '#404b69',
+      errorColor: '#ff5f5f',
+      warningColor: '#ffc93c',
+      successColor: '#1fab89',
+      infoColor: '#dbedf3',
+      menuBg:'#fff'
+    }
+    ConfigProvider.config({
+      theme: colorState.value
+    });
+  }
+  
+}
+onBeforeMount(()=>{
+ setTheme('light')
+
+})
 </script>
 <style scoped>
 .menu{
-  width: 180px;
-  background: #fff;
+  width: 158px;
+  background: #002671;
 }
 </style>

+ 3 - 10
src/components/layout/systemMod.vue

@@ -59,10 +59,10 @@ watch (()=>system.value,() => {
 <style less scoped>
 .asides{
   position: relative;
-  width:79px;
-  background: #fff;
+  width:58px;
+  background: #002671;
   transition: .1s ease-out all;
-  border-right: 1px solid #f1f2f3;
+  /* border-right: 1px solid #f1f2f3; */
 }
 .aside-item {
   cursor: pointer;
@@ -87,13 +87,6 @@ watch (()=>system.value,() => {
   align-items: center;
   justify-content: space-between;
 }
-.showCollapse{
-  position: absolute;
-  bottom: 0px;
-  height: 40px;
-  width: 79px;
-  text-align: center;
-}
 .menu-icon{
   display: inline-block;
   height: 30px;

+ 1 - 1
src/components/listTemplate/index.vue

@@ -32,7 +32,7 @@
       </template>
       <template #extra>
       </template>
-      <a-table class="ant-table-striped" :loading="loading" size="small" :dataSource="dataSource" :columns="columns" :pagination="{showSizeChanger:true,defaultPageSize:20,total:total}" :scroll="{x:'max-content'}" :row-class-name="(_record, index) => (index % 2 === 1 ? 'table-striped' : null)" @change="onChange" bordered>
+      <a-table class="ant-table-striped" :loading="loading" size="small" :dataSource="dataSource" :columns="columns" :pagination="{showSizeChanger:true,defaultPageSize:20,total:total}" :scroll="{x:'max-content'}" :row-class-name="(_record, index) => (index % 2 === 1 ? 'table-striped' : null)" @change="onChange">
         <template #bodyCell="{ column, record }">
           <template v-if="column.dataIndex === 'status'">
             <a-tag :color="utils.statusAndColor(record.status)">{{record.status}}</a-tag>

+ 8 - 4
src/demo/detail.vue

@@ -1,6 +1,13 @@
+// headData:描述区显示数据
+// title:主标题内容
+// tabs:tab数据页
+// ownertable:数据表名称
+// delParam:删除数据的请求参数
+// utils.isDisabled(数据状态,[与之匹配的数据],()=>{自定义方法,优先级高于前面的判断})
 <template>
   <div>
-    <detail-template :headData="mainAreaData" :title="'订单号:'+orderData.sonum" :tabs="['订单明细']" ownertable="sa_order">
+    <detail-template :headData="mainAreaData" :title="'订单号:' + orderData.sonum" :tabs="['订单明细']" ownertable="sa_order"
+    :delParam="{id:'20221031141202',content:{userids:[router.currentRoute.value.query.id]}}" :disable="utils.isDisabled(userData.status,['ACTIVE'])">
       <template #operation>
       </template>
       <template #tab0>
@@ -12,9 +19,6 @@
 <script setup>
 import Api from '@/api/api'
 import tool  from '@/utils/utils'
-
-import productList from '@/template/billProductTable/index.vue'
-import SelectProduct from '@/template/selectProduct/index.vue'
 import detailTemplate from '@/components/detailTemplate/index.vue'
 import edit from './modules/edit.vue'
 

+ 67 - 0
src/demo/list.vue

@@ -0,0 +1,67 @@
+// keyRouteName:列表链接字段,设置后展示跳转详情的链接
+// param:列表请求数据参数
+// tableName:获取开发管理端表名称
+// searchType:配置搜索项
+// detailPage:跳转详情页参数{路由名称,查询id}
+<template>
+  <div>
+    <listTemp ref="list" keyRouteName="accountno" :param="param" :tableName="'accountTable'" :searchType="searchType" :detailPage="{name:'accountManageDetail',idname:'userid'}">
+      <template #operation>
+        <add @onSuccess="onSuccess"></add>
+      </template>
+     <template #tb_cell="{data}">
+      <template v-if="data.column.dataIndex === 'name'">
+        {{data.record.name}}
+      </template>
+     </template>
+    </listTemp>
+  </div>
+</template>
+<script setup>
+  import utils from '@/utils/utils'
+  import Api from '@/api/api'
+  import listTemp from '@/components/listTemplate/index.vue';
+  import add from './modules/add.vue';
+  import { ref,onMounted } from 'vue'
+  import { useRouter } from "vue-router";
+  const router = useRouter()
+  const list = ref()
+  let columns = ref([])
+  let dataSource = ref([])
+  const statusOptions = ref([])
+  const typeOptions = ref([])
+  let searchType = ref([
+    {label:'时间范围',key:'dateRange',type:'datepickerRange',objKeys:['begindate','enddate']},
+    {label:'状态',key:'status',type:'select',dataSource:statusOptions},
+    {label:'用户类型:',key:'usertype',type:'select',dataSource:typeOptions},
+    {label:'搜索',key:'condition',type:'input'},
+  ])
+  let param = ref({
+    "content": {
+      "pageNumber": 1,
+      "pageSize": 20,
+      "where": {
+        "condition": "",
+      }
+    },
+    "id": 20221031141102,
+  })
+  const onSuccess = ()=>{
+    list.value.tableData()
+  }
+
+  const status = async ()=>{
+    const res = await Api.optionstype('userstatus')
+    statusOptions.value = res.data
+  }
+  const userType = async ()=>{
+    const res = await Api.optionstype('usertype')
+    typeOptions.value = res.data
+  }
+  onMounted(()=>{
+    status()
+    userType()
+  })
+</script>
+<style>
+</style>

+ 4 - 1
src/stores/modules/auth.js

@@ -5,6 +5,8 @@ import Api from '@/api/api'
 export const useAuthStore = defineStore('auth', {
   state: () => {
     return {
+      accountList:[],
+      nowAccount:{},
       system: [],
       mods:[],
       app:{},
@@ -18,7 +20,7 @@ export const useAuthStore = defineStore('auth', {
     strategies: [
       {
         storage: localStorage,
-        paths: ['system', 'mods','app','act_mods']
+        paths: ['system', 'mods','app','act_mods','accountList','nowAccount']
       }
     ]
   },
@@ -73,6 +75,7 @@ export const useAuthStore = defineStore('auth', {
     },
     // 设置默认账号
     defaultAccount (account) {
+      this.nowAccount = account
       sessionStorage.setItem('token',account.token)
     },
 

+ 13 - 9
src/theme/theme.less

@@ -1,6 +1,6 @@
-
+@import '../node_modules/ant-design-vue/dist/antd.variable.less';
 .asides{
-  // background: @primary-color !important;
+  background: @primary-color !important;
 }
 .onSystem{
   color:#333 !important;
@@ -19,11 +19,16 @@
   background:@primary-color !important;
   color:#fff !important;
 }
-.table-striped td {
-  background:#f8f9fd;
-  
+.ant-menu{
+  background:@primary-color !important;
+  color:#fff !important;
+}
+.ant-menu-light .ant-menu-item-active, .ant-menu-light .ant-menu-item:hover, .ant-menu-light .ant-menu-submenu-active, .ant-menu-light .ant-menu-submenu-title:hover, .ant-menu-light .ant-menu:not(.ant-menu-inline) .ant-menu-submenu-open{
+  color:#fff !important;
+}
+.ant-menu-submenu-active,.ant-menu-submenu-selected,.ant-menu-light .ant-menu-submenu-title:hover {
+  color:#fff !important;
 }
-
 .aside-menu-icon{
   display: inline-block;
   height: 20px;
@@ -37,6 +42,5 @@
 }
 .onSystem .aside-menu-icon{
   color:#fff;
-  background: @primary-color;
-}
-@import '../node_modules/ant-design-vue/dist/antd.variable.less';
+  background: @primary-color ;
+}

+ 2 - 3
src/views/login/login.vue

@@ -59,7 +59,7 @@ import { message } from 'ant-design-vue';
 import { useAuthStore } from '@/stores/modules/auth'
 import { storeToRefs } from 'pinia'
 const store = useAuthStore()
-
+let { accountList } = storeToRefs(store)
 export default defineComponent({
   setup() {
     const router = useRouter()
@@ -88,8 +88,7 @@ export default defineComponent({
         if (res.account_list[0].status == 'INACTIVE')
           return message.error('当前账号已停用!')
         loading.value = false
-
-        sessionStorage.setItem('a_list',JSON.stringify(res.account_list))
+        accountList.value = res.accountList
         store.defaultAccount(res.account_list[0])
         router.replace({path:'/home'})
         

+ 1 - 1
vite.config.js

@@ -43,5 +43,5 @@ export default defineConfig({
         javascriptEnabled: true
       }
     }
-  }
+  },
 })