YangJian0701 hace 1 año
padre
commit
a655235811

+ 1 - 0
package.json

@@ -13,6 +13,7 @@
     "echarts": "^5.4.3",
     "element-plus": "^2.4.2",
     "js-md5": "^0.8.3",
+    "qs": "^6.11.2",
     "register-service-worker": "^1.7.2",
     "vue": "^3.2.13",
     "vue-class-component": "^8.0.0-0",

+ 2 - 1
src/App.vue

@@ -20,7 +20,8 @@
 }
 body,html{
   height: 100%;
-  background: linear-gradient( #d7e4f4,#afd1fe);
+  // background: linear-gradient( #d7e4f4,#afd1fe);
+  background: #fff;
   // background: rgb(241, 243, 244);
 
   // linear-gradient(to bottom #d7e4f4,#afd1fe)

+ 6 - 8
src/api/module/login.ts

@@ -1,9 +1,7 @@
-import {axios} from '@/utils/index'
 
-export const login = (data:any)=>{
-    return axios({
-        url:'/v3/Login_verification',
-        method: 'post',
-		data
-    })
-}
+import $http from '@/utils/index'
+
+// 项目列表(财务)
+export const login = (params: any) => $http.post('/v3/Login_verification', params)
+
+export const CompanyTree = (params: any) => $http.post('/v3/DeviceWarning/List', params)

BIN
src/assets/img/1700037181284.jpg


BIN
src/assets/img/1700038020592.jpg


BIN
src/assets/img/1700038451579.jpg


BIN
src/assets/img/down.webp


+ 2 - 0
src/assets/scss/config.scss

@@ -18,4 +18,6 @@
     --y-padding:20px;
     /*外边距*/
     --y-margin:20px;
+    /*外边距*/
+    --y-margin-home:40px;
 }

+ 1 - 1
src/components/echart/echart-line.vue

@@ -1,6 +1,6 @@
 <!-- 柱图 -->
 <template>
-    <div style="height:200px;" :id="props.id" class="myChart"></div>
+    <div style="height:150px;" :id="props.id" class="myChart"></div>
 </template>
 
 <script setup lang="ts">

+ 40 - 16
src/components/table.vue

@@ -1,23 +1,48 @@
 <!--  -->
 <template>
     <div class="y-tabs">
-        123456
-        <el-table :data="tableData">
-            <template>
-                <el-table-column v-for="(item, index) in tableColumns" :key="index" v-bind="item" v-slot="scope">
-                    <slot :name="item.prop" :row="scope.row">{{ scope.row.prop }}</slot>
+        <el-table v-loading="loading" :data="tableData" @row-click="props.rowClick"
+            @selection-change="props.selectionChange" :row-key="props.getRowKey"
+            :row-style="tableRowClassName">
+            <!-- 默认插槽 -->
+            <slot></slot>
+            <template v-for="item in tableColumns" :key="item">
+                <!-- selection || index -->
+                <el-table-column v-bind="item" :align="item.align ?? 'left'" :reserve-selection="item.type == 'selection'"
+                    v-if="item.type == 'selection' || item.type == 'index'" :show-overflow-tooltip="true"></el-table-column>
+                <!-- <el-table-column v-bind="item" v-slot="scope">
+                    {{ scope.row.prop }}
+                </el-table-column> -->
+
+                <!-- 普通渲染 -->
+                <el-table-column v-bind="item" :align="item.align ?? 'left'" :show-overflow-tooltip="true"
+                    v-if="!item.type && item.prop && item.name !== item.prop" v-slot="scope">
+                    <div v-if="item.prop == 'T_wait_audit'" style="color: red;">
+                        {{ scope.row[item.prop] == true ? '待审核' : '' }}
+                    </div>
+                    <el-tooltip v-if="item.ellipsis" effect="dark" :content="scope.row[item.prop]" placement="bottom">
+                        {{ scope.row[item.prop] }}
+                    </el-tooltip>
+                    <slot v-if="item.fixed" :name="item.fixed" :row="scope.row"></slot>
+                </el-table-column>
+
+                <!-- 自定义slot 可以显示一些tab等等-->
+                <el-table-column v-bind="item" :align="item.align ?? 'left'" :show-overflow-tooltip="true"
+                    v-if="!item.type && item.prop && item.name === item.prop" v-slot="scope">
+                    <slot :name="item.prop" :row="scope.row"></slot>
                 </el-table-column>
             </template>
         </el-table>
-        <Pagination layout="total, sizes, prev, pager, next, jumper" :pageable="pageable"
-            :handleSizeChange="handleSizeChange" :handleCurrentChange="handleCurrentChange" />
+        <!-- 分页组件 -->
+        <el-pagination v-model:current-page="pageable.pageNum" v-model:page-size="pageable.pageNum"
+         :layout="props.layout" :total="pageable.total" style="margin-top: 50px;"
+         @size-change="handleSizeChange" @current-change="handleCurrentChange" />
     </div>
 </template>
 
 <script setup lang="ts">
 import { ref, CSSProperties } from "vue";
 import { useTable } from '@/hooks/useTable'
-
 import { TableProps } from 'element-plus'
 import { ColumnProps } from './interface/index'
 interface ProTableProps extends Partial<Omit<TableProps<any>, 'data'>> {
@@ -40,8 +65,8 @@ interface ProTableProps extends Partial<Omit<TableProps<any>, 'data'>> {
 // 接受父组件参数,配置默认值
 const props = withDefaults(defineProps<ProTableProps>(), {
     columns: () => [],//渲染表格
-    pagination: true,//是否显示分页
-    layout: 'total, sizes, prev, pager, next, jumper',
+    pagination: true,
+    layout: 'total, prev, pager, next, jumper',
     initParam: {},//请求参数
     border: false,
     toolButton: true,
@@ -52,10 +77,10 @@ const props = withDefaults(defineProps<ProTableProps>(), {
 
 
 // 表格操作 Hooks
-const { tableData, getTableList, pageable, handleSizeChange, handleCurrentChange } = useTable(
-    props.requestApi, 
-    props.initParam, 
-    props.pagination, 
+const { tableData, getTableList, pageable, loading, handleSizeChange, handleCurrentChange } = useTable(
+    props.requestApi,
+    props.initParam,
+    props.pagination,
     props.dataCallback
 )
 
@@ -69,8 +94,7 @@ const tableColumns = ref<ColumnProps[]>(props.columns)
 .y-tabs {
     background: var(--y-card-background);
     border-radius: var(--y-radius);
-    margin-bottom: var(--y-margin);
-    padding: var(--y-padding);
+    margin-top: var(--y-margin);
 
     &-headers {
         border-bottom: var(--y-border);

+ 109 - 0
src/components/tableCustom.vue

@@ -0,0 +1,109 @@
+<!--  -->
+<template>
+    <div class="y-tabs">
+        <el-table v-loading="loading" :data="tableData" @row-click="props.rowClick"
+            @selection-change="props.selectionChange" :row-key="props.getRowKey"
+            :row-style="tableRowClassName">
+            <!-- 默认插槽 -->
+            <slot></slot>
+            <template v-for="item in tableColumns" :key="item">
+                <!-- selection || index -->
+                <el-table-column v-bind="item" :align="item.align ?? 'left'" :reserve-selection="item.type == 'selection'"
+                    v-if="item.type == 'selection' || item.type == 'index'" :show-overflow-tooltip="true"></el-table-column>
+                <!-- <el-table-column v-bind="item" v-slot="scope">
+                    {{ scope.row.prop }}
+                </el-table-column> -->
+
+                <!-- 普通渲染 -->
+                <el-table-column v-bind="item" :align="item.align ?? 'left'" :show-overflow-tooltip="true"
+                    v-if="!item.type && item.prop && item.name !== item.prop" v-slot="scope">
+                    <div v-if="item.prop == 'T_wait_audit'" style="color: red;">
+                        {{ scope.row[item.prop] == true ? '待审核' : '' }}
+                    </div>
+                    <el-tooltip v-if="item.ellipsis" effect="dark" :content="scope.row[item.prop]" placement="bottom">
+                        {{ scope.row[item.prop] }}
+                    </el-tooltip>
+                    <slot v-if="item.fixed" :name="item.fixed" :row="scope.row"></slot>
+                </el-table-column>
+
+                <!-- 自定义slot 可以显示一些tab等等-->
+                <el-table-column v-bind="item" :align="item.align ?? 'left'" :show-overflow-tooltip="true"
+                    v-if="!item.type && item.prop && item.name === item.prop" v-slot="scope">
+                    <slot :name="item.prop" :row="scope.row"></slot>
+                </el-table-column>
+            </template>
+        </el-table>
+        <!-- 分页组件 -->
+        <el-pagination v-model:current-page="pageable.pageNum" v-model:page-size="pageable.pageNum"
+         :layout="props.layout" :total="pageable.total" style="margin-top: 50px;"
+         @size-change="handleSizeChange" @current-change="handleCurrentChange" />
+    </div>
+</template>
+
+<script setup lang="ts">
+import { ref, CSSProperties } from "vue";
+import { useTable } from '@/hooks/useTable'
+import { TableProps } from 'element-plus'
+import { ColumnProps } from './interface/index'
+interface ProTableProps extends Partial<Omit<TableProps<any>, 'data'>> {
+    columns: ColumnProps[] // 列配置项
+    requestApi: (params: any) => Promise<any> // 请求表格数据的api ==> 必传
+    dataCallback?: (data: any) => any // 返回数据的回调函数,可以对数据进行处理 ==> 非必传
+    title?: string // 表格标题,目前只在打印的时候用到 ==> 非必传
+    pagination?: boolean // 是否需要分页组件 ==> 非必传(默认为true)
+    layout?: string
+    initParam?: any // 初始化请求参数 ==> 非必传(默认为{})
+    border?: boolean // 是否带有纵向边框 ==> 非必传(默认为true)
+    toolButton?: boolean // 是否显示表格功能按钮 ==> 非必传(默认为true)
+    selectId?: string // 当表格数据多选时,所指定的 id ==> 非必传(默认为 id)
+    displayHeader?: boolean // 是否隐藏头部
+    rowClick?: (row: any, column: any, event: any) => void // 点击行
+    selectionChange?: (row: any) => void // 选择函数
+    getRowKey?: ((row: any) => string) | string // 用于优化select勾选框
+    tableRowClassName?: (data: any) => CSSProperties
+}
+// 接受父组件参数,配置默认值
+const props = withDefaults(defineProps<ProTableProps>(), {
+    columns: () => [],//渲染表格
+    pagination: true,
+    layout: 'total, prev, pager, next, jumper',
+    initParam: {},//请求参数
+    border: false,
+    toolButton: true,
+    selectId: 'id',
+    searchCol: () => ({ xs: 1, sm: 2, md: 2, lg: 3, xl: 4 })
+})
+
+
+
+// 表格操作 Hooks
+const { tableData, getTableList, pageable, loading, handleSizeChange, handleCurrentChange } = useTable(
+    props.requestApi,
+    props.initParam,
+    props.pagination,
+    props.dataCallback
+)
+
+getTableList()
+// 接收 columns 并设置为响应式
+const tableColumns = ref<ColumnProps[]>(props.columns)
+
+
+</script>
+<style lang="scss">
+.y-tabs {
+    background: var(--y-card-background);
+    border-radius: var(--y-radius);
+    margin-top: var(--y-margin);
+
+    &-headers {
+        border-bottom: var(--y-border);
+        box-sizing: border-box;
+        padding: var(--y-padding);
+    }
+
+    &-item {
+        padding: var(--y-padding);
+    }
+}
+</style>

+ 0 - 35
src/components/tabs.vue

@@ -1,35 +0,0 @@
-<!--  -->
-<template>
-    <div class="y-tabs">
-        <el-tabs v-model="activeName" class="demo-tabs" @tab-click="handleClick">
-            <el-tab-pane :label="item.label" :name="item.name" v-for="(item,index) in props.tabData" :key="index">
-                <slot name="tabs-content"></slot>
-            </el-tab-pane>
-        </el-tabs>
-    </div>
-</template>
-
-<script setup lang="ts">
-import {ref,onMounted} from "vue";
-import type { TabsPaneContext } from 'element-plus'
-const activeName = ref('first')
-const props: any = defineProps({
-    tabData: {
-        type: Array,
-        default: () => '',
-    }
-})
-onMounted(()=>{
-    activeName.value = props.tabData[0].name
-})
-const handleClick = (tab: TabsPaneContext, event: Event) => {
-  console.log(tab, event)
-}
-</script>
-<style lang="scss">
-.y-tabs {
-    background: var(--y-card-background);
-    border-radius: var(--y-radius);
-    margin-bottom: var(--y-margin);
-}
-</style>

+ 1 - 0
src/components/titles.vue

@@ -20,6 +20,7 @@ const props = defineProps({
     width: 100%;
     display: flex;
     align-items: center;
+    margin-bottom: var(--y-margin);
     &-biao{
         width: 10px;
         height: 10px;

+ 11 - 8
src/hooks/useTable.ts

@@ -60,14 +60,17 @@ export const useTable = (
       page_z: state.pageable.pageSize,
       ...initParam
     }
-    const res = await requestApi(params)
-    state.tableData = res.Data?.Data
-    dataCallback && (state.tableData = dataCallback(res))
-    state.pageable.total = res.Data?.Num
-    if (res.Data?.RemainingTime) {
-      state.pageable.RemainingTime = res.Data.RemainingTime
-    }
-    state.loading = false
+    requestApi(params).then(res => {
+      state.tableData = res.Data?.Data
+      // dataCallback && (state.tableData = dataCallback(res))
+      state.pageable.total = res.Data?.Num
+      // console.log('返回数据', res, state.tableData)
+
+      if (res.Data?.RemainingTime) {
+        state.pageable.RemainingTime = res.Data.RemainingTime
+      }
+      state.loading = false
+    })
   }
   if (isPagination) {
   }

+ 10 - 1
src/router/module/dynamicRoutes.ts

@@ -14,13 +14,22 @@ export const dynamicRoutes = [{
             title: '系统首页',
         },
     },{
+        path: '/user',
+        name: 'user', 
+        icon: "icon-zhuye1",
+        component: () => import('@/views/user/index.vue'),
+        meta: {
+            roles:false,
+            title: '用户管理',
+        },
+    },{
         path: '/storageInquire',
         name: 'storageInquire', 
         icon: "icon-zhuye1",
         component: () => import('@/views/storageInquire/index.vue'),
         meta: {
             roles:false,
-            title: '库存查询',
+            title: '库存统计',
         },
     },{
         path: '/storagePut',

+ 92 - 59
src/utils/index.ts

@@ -1,67 +1,100 @@
-import axios from "axios";
+
+import axios from 'axios'
+import type { AxiosInstance, AxiosError, AxiosRequestConfig, InternalAxiosRequestConfig, AxiosResponse } from 'axios'
 import { ElMessage, ElNotification } from 'element-plus'
-const service = axios.create({
-    baseURL:process.env.VUE_APP_BASE_URL,
-    timeout:3000,
-    withCredentials: false,// 是否跨站点访问控制请求
-    headers:{
-        "Content-Type":'application/x-www-form-urlencoded'
-    }
-})
+import { ResultEnum, ResultData, ContentType } from './interface/index'
+import router from '@/router/index'
+type LoadingType = {
+	close?: () => void
+}
+let loadingInstance: LoadingType = {}
+const config = {
+	// 默认地址请求地址,可在 .env.*** 文件中修改
+	// baseURL: process.env.NODE_ENV ?(import.meta.env.VITE_BZD_ERP_APP_API as string) : '' ,
 
-//请求拦截器
-service.interceptors.request.use(config =>{
-    console.log('请求',config)
-    return config
-},(error)=>{
-    error.data = {}
-	return Promise.resolve(error)
-})
+	baseURL: process.env.VUE_APP_BASE_URL,
+	// 设置超时时间(10s)
+	timeout: ResultEnum.TIMEOUT as number,
+	// 跨域时候允许携带凭证
+	withCredentials: false,
+	headers: {
+		'Content-Type': 'application/x-www-form-urlencoded',//x-www-form-urlencoded
+	},
+}
+class RequestHttp {
+	service: AxiosInstance
+	public constructor(config: AxiosRequestConfig) {
+		// 实例化axios
+		this.service = axios.create(config)
 
+		/**
+		 * @description 请求拦截器
+		 * 客户端发送请求 -> [请求拦截器] -> 服务器
+		 * token校验(JWT) : 接受服务器返回的token,存储到vuex/pinia/本地储存当中
+		 */
 
-service.interceptors.response.use(response=>{
-    showStatus(response.data)
-    return response
-},error=>{
-    console.log('错误码',error)
-})
+		this.service.interceptors.request.use((config: InternalAxiosRequestConfig) => {
+			config.data.User_tokey = sessionStorage.getItem('User_tokey')
+			return config
+		},
+			(err: any) => err
+		)
 
-const showStatus = (status:any) => {
-	switch (status.Code) {
-		case 200:
-			break
-		case 201:
-            ElMessage.error('登录过期,请重新登陆')
-			// store.commit('setuserInfo', {
-			// 	username: store.state.userInfo.bzd_username,
-			// 	password: store.state.userInfo.bzd_password,
-			// 	token: ''
-			// })
-			// setTimeout(function() {
-			// 	router.replace({
-			// 		name: 'login',
-			// 	})
-			// }, 1000)
-			break	
-		case 202:
-            ElMessage.error(status.Msg)
-			break
-		case 500:
-            ElMessage.error('服务器错误')
-			break
-		case 501:
-            ElMessage.error('服务未实现')
-			break
-		case 502:
-            ElMessage.error('网络错误')
-			break
-		default:
-            ElMessage.error(status.Msg)
+		/**
+		 * @description 响应拦截器
+		 *  服务器换返回信息 -> [拦截统一处理] -> 客户端JS获取到信息
+		 */
+		this.service.interceptors.response.use(
+			(response: AxiosResponse) => {
+				const { data } = response
+				// * 在请求结束后,并关闭请求 loading
+				// loadingInstance.close && loadingInstance.close()
+				// 无权限访问 || 登录密码错误(code == 202)
+				// if (data.Code === ResultEnum.ROLE) {
+				//   return Promise.reject(data)
+				// }
+				// * 登陆失效(code == 201)
+				if (data.Code === ResultEnum.OVERDUE) {
+					ElNotification.error({
+						title: '登陆失效',
+						message: data.Msg,
+						position: 'bottom-right'
+					})
+					localStorage.clear()
+					router.replace('/')
+					return Promise.reject(data)
+				}
+				// * 全局错误信息拦截(防止下载文件得时候返回数据流,没有code,直接报错)
+				if (data.Code && data.Code !== ResultEnum.SUCCESS) {
+					ElMessage.error(data.Msg)
+					return Promise.reject(data)
+				}
+				// * 成功请求(在页面上除非特殊情况,否则不用在页面处理失败逻辑)
+				return data
+			},
+			async (error: AxiosError) => {
+				loadingInstance.close && loadingInstance.close()
+
+				// 请求超时 && 网络错误单独判断,没有 response
+				if (error.message.indexOf('timeout') !== -1) ElMessage.error('请求超时!请您稍后重试')
+				if (error.message.indexOf('Network Error') !== -1) ElMessage.error('网络错误!请您稍后重试')
+				return Promise.reject(error)
+			}
+		)
+	}
+	// * 常用请求方法封装
+	get<T>(url: string, params?: object, _object = {}): Promise<ResultData<T>> {
+		return this.service.get(url, { params, ..._object })
+	}
+	post<T>(url: string, params?: object, _object = {}): Promise<ResultData<T>> {
+		return this.service.post(url, params, _object)
+	}
+	put<T>(url: string, params?: object, _object = {}): Promise<ResultData<T>> {
+		return this.service.put(url, params, _object)
+	}
+	delete<T>(url: string, params?: any, _object = {}): Promise<ResultData<T>> {
+		return this.service.delete(url, { params, ..._object })
 	}
 }
 
-export {
-	service as axios
-}
-console.log(process.env,'process.env')
-console.log(process.env, "VUE_APP_URL");
+export default new RequestHttp(config)

+ 39 - 0
src/utils/interface/index.ts

@@ -0,0 +1,39 @@
+// * 请求枚举配置
+/**
+ * @description:请求配置
+ */
+export enum ResultEnum {
+  SUCCESS = 200,
+  ERROR = 500,
+  OVERDUE = 201,
+  ROLE = 202,
+  TIMEOUT = 30000,
+  TYPE = 'success'
+}
+
+/**
+ * @description:请求方法
+ */
+export enum RequestEnum {
+  GET = 'GET',
+  POST = 'POST',
+  PATCH = 'PATCH',
+  PUT = 'PUT',
+  DELETE = 'DELETE'
+}
+
+export enum ContentType {
+  URLENCODED = 'application/x-www-form-urlencoded',
+  JSON = 'application/json; charset=utf-8'
+}
+
+// * 请求响应参数(不包含data)
+export interface Result {
+  Code: string
+  msg: string
+}
+
+// * 请求响应参数(包含data)
+export interface ResultData<T = any> extends Result {
+  Data: T
+}

+ 7 - 6
src/views/home/index.vue

@@ -12,11 +12,11 @@
         <!-- <echartbarlR id="bar2"></echartbarlR> -->
       </div>
       <div class="home-main-right">
-        <div style="flex: 1;">
+        <div style="flex: .4;">
           <titles name="电池租用量/库存量统计"></titles>
           <echartbar id="bar3"></echartbar>
         </div>
-        <div style="flex: 1;">
+        <div style="flex: .4;">
           <titles name="电池租用量/库存量统计"></titles>
           <echartbar id="bar4"></echartbar>
         </div>
@@ -61,7 +61,8 @@ const data = reactive({
   overflow-y: auto;
   display: flex;
   flex-direction: column;
-
+  // background: url(@/assets/img/home-bg1.png) no-repeat center center;
+  //   background-size: cover;
   &-main {
     flex: 1;
     display: grid;
@@ -71,13 +72,13 @@ const data = reactive({
     &-left {
       // border: 5px solid red;
       // box-sizing: border-box;
-      padding: 40px;
+      // padding: 40px;
     }
 
     &-conter {
       // border: 5px solid #000;
       // box-sizing: border-box;
-      padding: 40px;
+      // padding: 40px;
 
     }
 
@@ -87,7 +88,7 @@ const data = reactive({
       display: flex;
       flex-direction: column;
       grid-gap: 80px 0;
-      padding: 40px;
+      // padding: 40px;
 
     }
   }

+ 4 - 3
src/views/layout/index.vue

@@ -21,12 +21,13 @@ import backTop from "@/components/backTop.vue";
     overflow: hidden;
     display: flex;
     flex-direction: column;
-    background: url(@/assets/img/home-bg1.png) no-repeat center center;
-    background-size: cover;
+    // background: rgb(241, 249, 255);
+    // background: rgb(255, 255, 255);
 
     &-route {
         flex: 1;
-        overflow: hidden;
+        overflow-y: auto;
+        margin: var(--y-margin);
     }
 }
 </style>

+ 1 - 1
src/views/layout/menu.vue

@@ -22,7 +22,7 @@ import logo from "@/components/logo.vue";
 .menus {
     height: 60px;
     padding: 0 20px;
-    background:rgba(#fff,.2);
+    background:rgba(#fff,.5);
     user-select: none;
     display: flex;
     justify-content: space-between;

+ 5 - 4
src/views/login/index.vue

@@ -45,10 +45,11 @@ const data = reactive({
 const submitForm = async () => {
     const froms = {...data.form}
     froms.bzd_password = md5(froms.bzd_password)
-    const {data:resIt} = await login(froms)
-    console.log(resIt)
-    if(resIt.Code==200){
-        sessionStorage.setItem('User_tokey', resIt.Data)
+    const result:any = await login(froms)
+
+    console.log(result)
+    if(result.Code==200){
+        sessionStorage.setItem('User_tokey', result.Data)
         router.push('/home')
     }
 }

+ 43 - 4
src/views/personalInfo/index.vue

@@ -1,13 +1,52 @@
 <!--  -->
 <template>
-    <div class="">
-        个人信息
+    <div class="personalInfo">
+        <el-tabs v-model="activeName" tab-position="top" class="demo-tabs" @tab-click="handleClick">
+            <el-tab-pane :label="item.label" :name="item.name" v-for="(item,index) in tabData" :key="index">
+                <tables :requestApi="CompanyTree" :columns="columns" :initParam="initParam" v-if="item.name==activeName">
+                    <template #right="{ row }">
+                        <el-button link type="primary" size="small">编辑</el-button>
+                        <el-button link type="danger" size="small">删除</el-button>
+                    </template>
+                </tables>
+            </el-tab-pane>
+        </el-tabs>
     </div>
 </template>
 
-<script setup>
+<script setup lang="ts">
+import tables from "@/components/table.vue";
+import tableCustom from "@/components/tableCustom.vue";
+
+import { CompanyTree } from "@/api/index";
+import {ref} from "vue";
+import type { TabsPaneContext } from 'element-plus'
+
+const tabData = [
+    { name: 'first', label: '疫苗名称' },
+    { name: 'first1', label: '生产企业' },
+    { name: 'first2', label: '规格' },
+    { name: 'first3', label: '剂型' },
+    { name: 'first4', label: '单位' },
+]
+const activeName = ref('first')
+// 渲染表格
+const columns: any = [
+    { type: 'index', label: '编号', width: 80, },
+    { prop: 'T_D_name', label: '名称', width: 200 },
+    { prop: 'operation', label: '操作', fixed: 'right', 'min-width': 200 }
+]
+//请求参数
+const initParam = { T_name: '' }
+const handleClick = (tab: TabsPaneContext, event: Event) => {
+  console.log(tab, event)
+}
+
 </script>
 <style lang="scss">
 /* @import url(); 引入css类 */
-
+.personalInfo {
+    background: var(--y-card-background);
+    padding: var(--y-padding);
+}
 </style>

+ 74 - 11
src/views/sellManage/index.vue

@@ -1,34 +1,97 @@
 <!--  -->
 <template>
     <div class="sellManage">
-        <tables :requestApi="login" :columns="columns" :initParam="initParam" :dataCallback="dataCallback"></tables>
+        <!-- <titles name="电池租用量/库存量统计"></titles> -->
+        <el-form :inline="true" :model="formInline" class="demo-form-inline">
+            <el-form-item label="疫苗名称">
+                <el-input v-model="formInline.user" placeholder="疫苗名称" clearable />
+            </el-form-item>
+            <el-form-item label="生产企业">
+                <el-select v-model="formInline.region" placeholder="生产企业" clearable>
+                    <el-option label="Zone one" value="shanghai" />
+                    <el-option label="Zone two" value="beijing" />
+                </el-select>
+            </el-form-item>
+            <el-form-item label="疫苗批号">
+                <el-input v-model="formInline.user" placeholder="疫苗批号" clearable />
+            </el-form-item>
+            <el-form-item label="疫苗效期">
+                <el-date-picker v-model="formInline.date" type="date" placeholder="疫苗效期" clearable />
+            </el-form-item>
+            <el-form-item label="出/入库日期">
+                <el-date-picker v-model="formInline.date" type="date" placeholder="出/入库日期" clearable />
+            </el-form-item>
+            <el-form-item>
+                <el-button type="primary">Query</el-button>
+            </el-form-item>
+        </el-form>
+        <tables :requestApi="CompanyTree" :columns="columns" :initParam="initParam" :dataCallback="dataCallback">
+            <template #right="{ row }">
+                <el-button link type="primary" size="small">编辑</el-button>
+                <el-button link type="success" size="small">权限</el-button>
+                <el-button link type="danger" size="small">删除</el-button>
+            </template>
+            <template #T_State="{ row }">
+                <el-tag class="ml-2" v-if="row.T_State === 1">正常</el-tag>
+                <el-tag class="ml-2" type="danger" v-else>离职</el-tag>
+            </template>
+        </tables>
     </div>
 </template>
 
 <script setup lang="ts">
-
+import { reactive } from 'vue'
 import tables from "@/components/table.vue";
-import {login} from "@/api/index";
-
+import titles from '@/components/titles.vue'
+import { CompanyTree } from "@/api/index";
+const formInline = reactive({
+  user: '',
+  region: '',
+  date: '',
+})
 
 // 渲染表格
 const columns: any = [
-    { prop: 'T_name', label: '姓名' },
-    { prop: 'T_id', label: 'id' },
-    // { prop: 'operation', label: '操作', width: 200, fixed: 'right' }
+    // { type: 'index', label: '#', width: 50, },
+    { prop: 'T_D_name', label: '疫苗名称', width: 200 },
+    { prop: 'T_sn', label: '生产企业', width: 200 },
+    { prop: 'T_D_name', label: '批准文号', width: 200 },
+    { prop: 'T_sn', label: '批签发合格编号', width: 200  },
+
+    { prop: 'T_D_name', label: '规格(剂/支或粒)', width: 200  },
+    { prop: 'T_sn', label: '生产日期', width: 200  },
+    { prop: 'T_D_name', label: '疫苗批号', width: 200 },
+    { prop: 'T_sn', label: '疫苗效期', width: 200 },
+
+    { prop: 'T_D_name', label: '类型', width: 200 },
+    { prop: 'T_sn', label: '收入数量' , width: 200 },
+    { prop: 'T_D_name', label: '发出数量', width: 200 },
+    { prop: 'T_sn', label: '结余数量', width: 200  },
+    { prop: 'T_D_name', label: '单位', width: 200 },
+    { prop: 'T_sn', label: '剂型', width: 200  },
+
+    { prop: 'T_D_name', label: '领苗人', width: 200 },
+    { prop: 'T_sn', label: '发货单位' , width: 200 },
+    { prop: 'T_D_name', label: '收货单位', width: 200  },
+    { prop: 'T_sn', label: '入/出库日期' , width: 200 },
+    { prop: 'operation', label: '操作', fixed: 'right', width: 200 }
+
+    // { prop: 'T_State', label: '状态', name: 'T_State' },
 ]
 //请求参数
-const initParam = {T_name: '' }
+const initParam = { T_name: '' }
 
 //函数
-const dataCallback = async ()=>{
+const dataCallback = async () => {
 
 }
 </script>
 <style lang="scss">
 /* @import url(); 引入css类 */
 
-.sellManage{
-    padding: 40px;
+.sellManage {
+    background: var(--y-card-background);
+    padding: var(--y-padding);
+    border-radius: var(--y-radius);
 }
 </style>

+ 39 - 5
src/views/storageFrom/index.vue

@@ -1,13 +1,47 @@
 <!--  -->
 <template>
-    <div class="">
-        疫苗出库
+    <div class="storageFrom">
+        <el-result title="扫码添加" sub-title="扫条形码,可以自动识别填写信息哦">
+            <template #icon>
+                <el-image :src="srcimg" style="width: 400px;height: auto;"/>
+            </template>
+            <template #extra>
+                <el-button type="primary">扫码添加</el-button>
+            </template>
+        </el-result>
+        <el-result title="手动添加" sub-title="手动填写信息">
+            <template #icon>
+                <el-image :src="srcimg1" style="width: 400px;height: auto;"/>
+            </template>
+            <template #extra>
+                <el-button type="primary">手动添加</el-button>
+            </template>
+        </el-result>
+        <el-result title="查看入库" sub-title="管理入库信息,查看入库情况">
+            <template #icon>
+                <el-image :src="srcimg2" style="width: 400px;height: auto;"/>
+            </template>
+            <template #extra>
+                <el-button type="primary">查看出库数据</el-button>
+            </template>
+        </el-result>
     </div>
 </template>
 
-<script setup>
+<script setup lang="ts">
+const srcimg:any = require('@/assets/img/1700037181284.jpg')
+const srcimg1:any = require('@/assets/img/1700038020592.jpg')
+const srcimg2:any = require('@/assets/img/down.webp')
+
+
+
 </script>
 <style lang="scss">
-/* @import url(); 引入css类 */
-
+.storageFrom {
+    display: flex;
+    gap: 20px;
+    justify-content: center;
+    align-items: center;
+    height: 100%;
+}
 </style>

+ 39 - 5
src/views/storagePut/index.vue

@@ -1,13 +1,47 @@
 <!--  -->
 <template>
-    <div class="">
-        疫苗入库
+    <div class="storagePut">
+        <el-result title="扫码添加" sub-title="扫条形码,可以自动识别填写信息哦">
+            <template #icon>
+                <el-image :src="srcimg" style="width: 400px;height: auto;" />
+            </template>
+            <template #extra>
+                <el-button type="primary">扫码添加</el-button>
+            </template>
+        </el-result>
+        <el-result title="手动添加" sub-title="手动填写信息">
+            <template #icon>
+                <el-image :src="srcimg1" style="width: 400px;height: auto;" />
+            </template>
+            <template #extra>
+                <el-button type="primary">手动添加</el-button>
+            </template>
+        </el-result>
+        <el-result title="查看入库" sub-title="管理入库信息,查看入库情况">
+            <template #icon>
+                <el-image :src="srcimg" style="width: 400px;height: auto;" />
+            </template>
+            <template #extra>
+                <el-button type="primary">查看入库数据</el-button>
+            </template>
+        </el-result>
     </div>
 </template>
 
-<script setup>
+<script setup lang="ts">
+const srcimg: any = require('@/assets/img/1700037181284.jpg')
+const srcimg1: any = require('@/assets/img/1700038020592.jpg')
+const srcimg2: any = require('@/assets/img/1700038451579.jpg')
+
+
+
 </script>
 <style lang="scss">
-/* @import url(); 引入css类 */
-
+.storagePut {
+    display: flex;
+    gap: 20px;
+    justify-content: center;
+    align-items: center;
+    height: 100%;
+}
 </style>

+ 16 - 0
src/views/user/index.vue

@@ -0,0 +1,16 @@
+<!--  -->
+<template>
+  <div class="user">
+    用户管理
+  </div>
+</template>
+
+<script setup lang="ts">
+import { reactive, provide, ref } from "vue";
+
+</script>
+<style lang="scss">
+.user {
+  border:1px solid red;
+}
+</style>