@ -0,0 +1,8 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$" />
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/Nursing-home-management-system.iml" filepath="$PROJECT_DIR$/.idea/Nursing-home-management-system.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PrettierConfiguration">
|
||||
<option name="myConfigurationMode" value="AUTOMATIC" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,4 @@
|
||||
> 1%
|
||||
last 2 versions
|
||||
not dead
|
||||
not ie 11
|
@ -0,0 +1,28 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
node: true,
|
||||
/** 解决defineProps没有导入的警告 */
|
||||
"vue/setup-compiler-macros": true
|
||||
},
|
||||
extends: [
|
||||
"plugin:vue/vue3-essential",
|
||||
"eslint:recommended",
|
||||
"@vue/typescript/recommended",
|
||||
"plugin:prettier/recommended"
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020
|
||||
},
|
||||
rules: {
|
||||
"linebreak-style": [0, "error", "windows"],
|
||||
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off",
|
||||
indent: 0,
|
||||
"space-before-function-paren": 0,
|
||||
"vue/multi-word-component-names": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"vue/no-mutating-props": "off", // 不允许组件 prop的改变
|
||||
"prettier/prettier": "off"
|
||||
}
|
||||
};
|
@ -0,0 +1,23 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
npx --no-install commitlint --edit
|
@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env sh
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
npx lint-staged
|
@ -0,0 +1,9 @@
|
||||
/dist/*
|
||||
.local
|
||||
.output.js
|
||||
/node_modules/**
|
||||
|
||||
**/*.svg
|
||||
**/*.sh
|
||||
|
||||
/public/*
|
@ -0,0 +1,29 @@
|
||||
# geracomium-admin-web
|
||||
|
||||
## Project setup
|
||||
|
||||
```
|
||||
yarn install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
|
||||
```
|
||||
yarn serve
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
|
||||
```
|
||||
yarn build
|
||||
```
|
||||
|
||||
### Lints and fixes files
|
||||
|
||||
```
|
||||
yarn lint
|
||||
```
|
||||
|
||||
### Customize configuration
|
||||
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
@ -0,0 +1,5 @@
|
||||
// Generated by 'unplugin-auto-import'
|
||||
export {}
|
||||
declare global {
|
||||
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
presets: ['@vue/cli-plugin-babel/preset']
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
// generated by unplugin-vue-components
|
||||
// We suggest you to commit this file into source control
|
||||
// Read more: https://github.com/vuejs/core/pull/3399
|
||||
import '@vue/runtime-core'
|
||||
|
||||
export {}
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
export interface GlobalComponents {
|
||||
ColSetting: typeof import('./src/components/ProTable/components/ColSetting.vue')['default']
|
||||
DynamicAdditionComponent: typeof import('./src/components/wen-test/DynamicAdditionComponent.vue')['default']
|
||||
ElAside: typeof import('element-plus/es')['ElAside']
|
||||
ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
|
||||
ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
|
||||
ElButton: typeof import('element-plus/es')['ElButton']
|
||||
ElCol: typeof import('element-plus/es')['ElCol']
|
||||
ElContainer: typeof import('element-plus/es')['ElContainer']
|
||||
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
|
||||
ElderListDialog: typeof import('./src/components/elderListDialog/index.vue')['default']
|
||||
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||
ElDrawer: typeof import('element-plus/es')['ElDrawer']
|
||||
ElDropdown: typeof import('element-plus/es')['ElDropdown']
|
||||
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
|
||||
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
|
||||
ElEmpty: typeof import('element-plus/es')['ElEmpty']
|
||||
ElForm: typeof import('element-plus/es')['ElForm']
|
||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||
ElHeader: typeof import('element-plus/es')['ElHeader']
|
||||
ElIcon: typeof import('element-plus/es')['ElIcon']
|
||||
ElInput: typeof import('element-plus/es')['ElInput']
|
||||
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
||||
ElMain: typeof import('element-plus/es')['ElMain']
|
||||
ElMenu: typeof import('element-plus/es')['ElMenu']
|
||||
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
|
||||
ElOption: typeof import('element-plus/es')['ElOption']
|
||||
ElPagination: typeof import('element-plus/es')['ElPagination']
|
||||
ElPopconfirm: typeof import('element-plus/es')['ElPopconfirm']
|
||||
ElRadio: typeof import('element-plus/es')['ElRadio']
|
||||
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
|
||||
ElRow: typeof import('element-plus/es')['ElRow']
|
||||
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
|
||||
ElSelect: typeof import('element-plus/es')['ElSelect']
|
||||
ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
|
||||
ElSwitch: typeof import('element-plus/es')['ElSwitch']
|
||||
ElTable: typeof import('element-plus/es')['ElTable']
|
||||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
||||
ElTag: typeof import('element-plus/es')['ElTag']
|
||||
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
||||
ElTree: typeof import('element-plus/es')['ElTree']
|
||||
ElUpload: typeof import('element-plus/es')['ElUpload']
|
||||
Grid: typeof import('./src/components/Grid/index.vue')['default']
|
||||
GridItem: typeof import('./src/components/Grid/components/GridItem.vue')['default']
|
||||
IconPark: typeof import('./src/components/IconPark/index.vue')['default']
|
||||
Image: typeof import('./src/components/upload/image/index.vue')['default']
|
||||
MyCard: typeof import('./src/components/my-card/my-card.vue')['default']
|
||||
Pagination: typeof import('./src/components/ProTable/components/Pagination.vue')['default']
|
||||
ProTable: typeof import('./src/components/ProTable/index.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
SearchForm: typeof import('./src/components/SearchForm/index.vue')['default']
|
||||
SearchFormItem: typeof import('./src/components/SearchForm/components/SearchFormItem.vue')['default']
|
||||
Src: typeof import('./src/components/ReImageVerify/src/index.vue')['default']
|
||||
SvgIcon: typeof import('./src/components/SvgIcon/index.vue')['default']
|
||||
TableColumn: typeof import('./src/components/ProTable/components/TableColumn.vue')['default']
|
||||
TreeDialog: typeof import('./src/components/treeDialog/index.vue')['default']
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
VUE_APP_BASE_URL=https://coderwhy.org/dev
|
||||
VUE_APP_BASE_NAME=coderwhy
|
@ -0,0 +1,2 @@
|
||||
VUE_APP_BASE_URL=https://coderwhy.org/prod
|
||||
VUE_APP_BASE_NAME=kobe
|
@ -0,0 +1,2 @@
|
||||
VUE_APP_BASE_URL=https://coderwhy.org/test
|
||||
VUE_APP_BASE_NAME=james
|
@ -0,0 +1,72 @@
|
||||
{
|
||||
"name": "geracomium-admin-web",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint",
|
||||
"prettier": "prettier --write .",
|
||||
"prepare": "husky install"
|
||||
},
|
||||
"dependencies": {
|
||||
"@commitlint/cli": "^17.3.0",
|
||||
"@commitlint/config-conventional": "^17.3.0",
|
||||
"@icon-park/vue-next": "^1.4.2",
|
||||
"@pureadmin/utils": "^1.8.5",
|
||||
"@vueuse/motion": "^2.0.0-beta.12",
|
||||
"axios": "^1.2.2",
|
||||
"core-js": "^3.8.3",
|
||||
"cz-customizable": "^7.0.0",
|
||||
"echarts": "^5.4.1",
|
||||
"element-plus": "^2.2.28",
|
||||
"file-saver": "^2.0.5",
|
||||
"global": "^4.4.0",
|
||||
"husky": "^8.0.2",
|
||||
"screenfull": "^6.0.2",
|
||||
"svg-sprite-loader": "^6.0.11",
|
||||
"unplugin-auto-import": "^0.12.1",
|
||||
"unplugin-vue-components": "^0.22.12",
|
||||
"vue": "^3.2.13",
|
||||
"vue-i18n": "^9.2.2",
|
||||
"vue-property-decorator": "^9.1.2",
|
||||
"vue-router": "^4.0.3",
|
||||
"vuex": "^4.0.0",
|
||||
"vuex-persistedstate": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/file-saver": "^2.0.5",
|
||||
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||
"@typescript-eslint/parser": "^5.4.0",
|
||||
"@vue/cli-plugin-babel": "~5.0.0",
|
||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||
"@vue/cli-plugin-router": "~5.0.0",
|
||||
"@vue/cli-plugin-typescript": "~5.0.0",
|
||||
"@vue/cli-plugin-vuex": "~5.0.0",
|
||||
"@vue/cli-service": "~5.0.0",
|
||||
"@vue/eslint-config-typescript": "^9.1.0",
|
||||
"autoprefixer": "^9.8.8",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-vue": "^8.0.3",
|
||||
"postcss": "^8.4.21",
|
||||
"prettier": "^2.4.1",
|
||||
"sass": "^1.32.7",
|
||||
"sass-loader": "^12.0.0",
|
||||
"tailwindcss": "^3.2.7",
|
||||
"typescript": "~4.5.5",
|
||||
"unplugin-vue-macros": "^1.7.3"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
"path": "node_modules/cz-customizable"
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"src/**/*.{js,vue}": [
|
||||
"eslint --fix",
|
||||
"git add"
|
||||
]
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
// postcss.config.js
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {}
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 4.2 KiB |
@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
|
||||
<link rel="icon" href="<%= BASE_URL %>logo.ico" />
|
||||
<title>敬老院管理系统</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong
|
||||
>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
|
||||
properly without JavaScript enabled. Please enable it to
|
||||
continue.</strong
|
||||
>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 261 KiB |
@ -0,0 +1,18 @@
|
||||
<template>
|
||||
<el-config-provider :locale="locale">
|
||||
<router-view />
|
||||
</el-config-provider>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ElConfigProvider } from 'element-plus'
|
||||
import zhCn from 'element-plus/lib/locale/lang/zh-cn'
|
||||
|
||||
const locale = zhCn
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.app {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,80 @@
|
||||
import { http } from "@/utils";
|
||||
import { IPageSearchElderByKey } from "@/apis/bookManage";
|
||||
|
||||
interface IPageAccidentByKey {
|
||||
elderName: string;
|
||||
staffName: string;
|
||||
}
|
||||
|
||||
interface IAddAccident {
|
||||
id: number;
|
||||
elderId: number;
|
||||
staffId: number;
|
||||
occurDate: string;
|
||||
description: string;
|
||||
picture: string;
|
||||
}
|
||||
|
||||
interface IGetAccidentById {
|
||||
accidentId: string;
|
||||
}
|
||||
|
||||
interface IEditAccident {
|
||||
id: number;
|
||||
name: string;
|
||||
phone: string;
|
||||
relation: string;
|
||||
accidentDateStr: string;
|
||||
accidentNum: number;
|
||||
}
|
||||
|
||||
// 分页查询事故登记
|
||||
export async function pageAccidentByKey(data: IPageAccidentByKey) {
|
||||
return http.get("/api/accident/pageAccidentByKey", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 分页搜索老人
|
||||
export async function pageSearchElderByKey(data: IPageSearchElderByKey) {
|
||||
return http.get("/api/accident/pageSearchElderByKey", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 获取护工列表
|
||||
export async function listAccidentStaff() {
|
||||
return http.get("/api/accident/listAccidentStaff");
|
||||
}
|
||||
|
||||
// 新增事故登记
|
||||
export function addAccident(data: IAddAccident) {
|
||||
return http.post("/api/accident/addAccident", data);
|
||||
}
|
||||
|
||||
// 根据编号获取事故登记
|
||||
export async function getAccidentById(data: IGetAccidentById) {
|
||||
return http.get("/api/accident/getAccidentById", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 编辑事故登记
|
||||
export function editAccident(data: IEditAccident) {
|
||||
return http.put("/api/accident/editAccident", data);
|
||||
}
|
||||
|
||||
// 删除事故登记
|
||||
export async function deleteAccident(data: IGetAccidentById) {
|
||||
return http.delete("/api/accident/deleteAccident", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
import { http } from "@/utils";
|
||||
|
||||
interface IListRoomByKey {
|
||||
buildingId: string;
|
||||
floorId: string;
|
||||
elderName: string;
|
||||
}
|
||||
|
||||
// 获取楼栋列表
|
||||
export async function listBuilding() {
|
||||
return http.get("/api/bedPanorama/listBuilding");
|
||||
}
|
||||
|
||||
// 获取楼层列表
|
||||
export function listFloorByBuildingId(buildingId: string) {
|
||||
return http.get("/api/bedPanorama/listFloorByBuildingId", {
|
||||
params: {
|
||||
buildingId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 获取房间列表
|
||||
export function listRoomByKey(data: IListRoomByKey) {
|
||||
return http.get("/api/bedPanorama/listRoomByKey", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
import { http } from '@/utils'
|
||||
|
||||
interface ISearchFormReserveByKey {
|
||||
pageNum: number
|
||||
pageSize: number
|
||||
elderName?: string
|
||||
payerPhone?: string
|
||||
}
|
||||
|
||||
export interface IPageSearchElderByKey {
|
||||
pageNum: number
|
||||
pageSize: number
|
||||
elderName?: string
|
||||
elderPhone?: string
|
||||
}
|
||||
|
||||
interface IAddReserve {
|
||||
bedId: string
|
||||
deposit: string
|
||||
dueDate: string
|
||||
elderAddress: string
|
||||
elderAge: string
|
||||
elderName: string
|
||||
elderPhone: string
|
||||
elderSex: string
|
||||
idNum: string
|
||||
payerName: string
|
||||
payerPhone: string
|
||||
staffId: string
|
||||
}
|
||||
|
||||
interface IGetReserveById {
|
||||
elderId: string
|
||||
reserveId: string
|
||||
}
|
||||
|
||||
interface IRefund {
|
||||
reserveId: string
|
||||
}
|
||||
|
||||
// 分页查询预定
|
||||
export async function pageReserveByKey(data: ISearchFormReserveByKey) {
|
||||
return http.get('/api/reserve/pageReserveByKey', {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 分页搜索老人
|
||||
export function pageSearchElderByKey(data: IPageSearchElderByKey) {
|
||||
return http.get('/api/reserve/pageSearchElderByKey', {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 获取营销人员
|
||||
export function listReserveStaff() {
|
||||
return http.get('/api/reserve/listReserveStaff')
|
||||
}
|
||||
|
||||
// 获取楼栋树
|
||||
export function getBuildTree() {
|
||||
return http.get('/api/reserve/getBuildTree')
|
||||
}
|
||||
|
||||
// 新增预定
|
||||
export function addReserve(data: IAddReserve) {
|
||||
return http.post('/api/reserve/addReserve', data)
|
||||
}
|
||||
|
||||
// 根据预定编号和老人编号获取预定信息
|
||||
export function getReserveById(data: IGetReserveById) {
|
||||
return http.get('/api/reserve/getReserveByReserveIdAndElderId', {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 退款
|
||||
export function refund(data: IRefund) {
|
||||
return http.put('/api/reserve/refund',data)
|
||||
}
|
@ -0,0 +1,180 @@
|
||||
import { http } from "@/utils";
|
||||
|
||||
interface IPageBedByKey {
|
||||
buildId: string;
|
||||
floorId: string;
|
||||
roomId: string;
|
||||
bedFlag: string;
|
||||
}
|
||||
|
||||
interface IAddBuilding {
|
||||
id: string;
|
||||
name: string;
|
||||
floorNum: string;
|
||||
}
|
||||
|
||||
interface IGetBuildingById {
|
||||
buildingId: string;
|
||||
}
|
||||
|
||||
interface IAddFloor {
|
||||
id: string;
|
||||
name: string;
|
||||
roomNum: string;
|
||||
buildingId: string;
|
||||
floorLimit: string;
|
||||
}
|
||||
|
||||
interface IGetFloorById {
|
||||
floorId: string;
|
||||
}
|
||||
|
||||
interface IAddRoom {
|
||||
id: string;
|
||||
name: string;
|
||||
typeId: string;
|
||||
bedNum: string;
|
||||
floorId: string;
|
||||
roomLimit: string;
|
||||
}
|
||||
|
||||
interface IGetRoomById {
|
||||
roomId: string;
|
||||
}
|
||||
|
||||
interface IDeleteNode {
|
||||
id: string;
|
||||
mark: string;
|
||||
}
|
||||
|
||||
interface IAddBed {
|
||||
id: string;
|
||||
name: string;
|
||||
roomId: string;
|
||||
bedLimit: string;
|
||||
}
|
||||
|
||||
interface IGetBedById {
|
||||
bedId: string;
|
||||
}
|
||||
|
||||
// 床位状态
|
||||
export const IBedFlagList = [
|
||||
{ label: "空闲", value: "空闲" },
|
||||
{ label: "预定", value: "预定" },
|
||||
{ label: "入住", value: "入住" },
|
||||
{ label: "退住审核", value: "退住审核" }
|
||||
];
|
||||
|
||||
// 获取楼栋-楼层-房间树
|
||||
export async function getNoBedTree() {
|
||||
return http.get("/api/build/getNoBedTree");
|
||||
}
|
||||
|
||||
// 分页查询床位
|
||||
export async function pageBedByKey(data: IPageBedByKey) {
|
||||
return http.get("/api/build/pageBedByKey", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 新增楼栋
|
||||
export function addBuilding(data: IAddBuilding) {
|
||||
return http.post("/api/build/addBuilding", data);
|
||||
}
|
||||
|
||||
// 根据编号获取楼栋
|
||||
export async function getBuildingById(data: IGetBuildingById) {
|
||||
return http.get("/api/build/getBuildingById", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 编辑楼栋
|
||||
export function editBuilding(data: IAddBuilding) {
|
||||
return http.put("/api/build/editBuilding", data);
|
||||
}
|
||||
|
||||
// 新增楼层
|
||||
export function addFloor(data: IAddFloor) {
|
||||
return http.post("/api/build/addFloor", data);
|
||||
}
|
||||
|
||||
// 根据编号获取楼层
|
||||
export async function getFloorById(data: IGetFloorById) {
|
||||
return http.get("/api/build/getFloorById", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 编辑楼层
|
||||
export function editFloor(data: IAddFloor) {
|
||||
return http.put("/api/build/editFloor", data);
|
||||
}
|
||||
|
||||
// 获取房间类型列表
|
||||
export async function listRoomType() {
|
||||
return http.get("/api/build/listRoomType");
|
||||
}
|
||||
|
||||
// 新增房间
|
||||
export function addRoom(data: IAddRoom) {
|
||||
return http.post("/api/build/addRoom", data);
|
||||
}
|
||||
|
||||
// 根据编号获取房间
|
||||
export async function getRoomById(data: IGetRoomById) {
|
||||
return http.get("/api/build/getRoomById", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 编辑房间
|
||||
export function editRoom(data: IAddRoom) {
|
||||
return http.put("/api/build/editRoom", data);
|
||||
}
|
||||
|
||||
// 删除节点
|
||||
export async function deleteNode(data: IDeleteNode) {
|
||||
return http.delete("/api/build/deleteNode", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 新增床位
|
||||
export function addBed(data: IAddBed) {
|
||||
return http.post("/api/build/addBed", data);
|
||||
}
|
||||
|
||||
// 根据编号获取床位
|
||||
export async function getBedById(data: IGetBedById) {
|
||||
return http.get("/api/build/getBedById", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 编辑床位
|
||||
export function editBed(data: IAddBed) {
|
||||
return http.put("/api/build/editBed", data);
|
||||
}
|
||||
|
||||
// 删除床位
|
||||
export async function deleteBed(data: IGetBedById) {
|
||||
return http.delete("/api/build/deleteBed", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
import { http } from "@/utils";
|
||||
import { IPageSearchElderByKey } from "@/apis/bookManage";
|
||||
|
||||
interface IPageCheckContractByKey {
|
||||
name: string;
|
||||
sex: string;
|
||||
idNum: string;
|
||||
}
|
||||
|
||||
interface IAddCheckContract {
|
||||
id: string;
|
||||
nursingGradeId: string;
|
||||
cateringSetId: string;
|
||||
bedId: string;
|
||||
name: string;
|
||||
idNum: string;
|
||||
age: string;
|
||||
sex: string;
|
||||
phone: string;
|
||||
address: string;
|
||||
staffId: string;
|
||||
signDate: string;
|
||||
startDate: string;
|
||||
endDate: string;
|
||||
operateEmergencyContactQueryList: IEmergencyContact[];
|
||||
}
|
||||
|
||||
interface IEmergencyContact {
|
||||
name: string;
|
||||
phone: string;
|
||||
email: string;
|
||||
relation: string;
|
||||
receiveFlag: string;
|
||||
}
|
||||
|
||||
interface IGetCheckContractById {
|
||||
elderId: string
|
||||
}
|
||||
|
||||
// 分页查询入住签约
|
||||
export async function pageCheckContractByKey(data: IPageCheckContractByKey) {
|
||||
return http.get("/api/checkContract/pageCheckContractByKey", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 分页搜索老人
|
||||
export async function pageSearchElderByKey(data: IPageSearchElderByKey) {
|
||||
return http.get("/api/checkContract/pageSearchElderByKey", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 获取护理等级列表
|
||||
export async function listNurseGrade() {
|
||||
return http.get("/api/checkContract/listNurseGrade");
|
||||
}
|
||||
|
||||
// 根据编号查询护理等级
|
||||
export async function getNurseGradeById(nurseGradeId: string) {
|
||||
return http.get("/api/checkContract/getNurseGradeById", {
|
||||
params: {
|
||||
nurseGradeId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 获取餐饮套餐列表
|
||||
export async function listCateringSet() {
|
||||
return http.get("/api/checkContract/listCateringSet");
|
||||
}
|
||||
|
||||
// 根据编号查询餐饮套餐
|
||||
export async function getCateringSetById(cateringSetId: string) {
|
||||
return http.get("/api/checkContract/getCateringSetById", {
|
||||
params: {
|
||||
cateringSetId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 获取楼栋树
|
||||
export async function getBuildTree() {
|
||||
return http.get("/api/checkContract/getBuildTree");
|
||||
}
|
||||
|
||||
// 根据编号查询床位
|
||||
export async function getBedById(bedId: string) {
|
||||
return http.get("/api/checkContract/getBedById", {
|
||||
params: {
|
||||
bedId
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 获取营销人员
|
||||
export async function listReserveStaff() {
|
||||
return http.get("/api/checkContract/listReserveStaff");
|
||||
}
|
||||
|
||||
// 新增入住签约
|
||||
export function addCheckContract(data: IAddCheckContract) {
|
||||
return http.post("/api/checkContract/addCheckContract", data);
|
||||
}
|
||||
|
||||
// 根据老人编号查询入住签约
|
||||
export async function getCheckContractById(data: IGetCheckContractById) {
|
||||
return http.get("/api/checkContract/getCheckContractById", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 编辑入住签约
|
||||
export function editCheckContract(data: IAddCheckContract) {
|
||||
return http.put("/api/checkContract/editCheckContract", data);
|
||||
}
|
||||
|
||||
// 删除入住签约
|
||||
export async function deleteCheckContract(data: IGetCheckContractById) {
|
||||
return http.delete("/api/checkContract/deleteCheckContract", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
import { http } from "@/utils";
|
||||
|
||||
interface IPageConsumeByKey {
|
||||
elderName: string;
|
||||
startTime: string;
|
||||
endTime: string;
|
||||
}
|
||||
|
||||
// 分页查询消费记录
|
||||
export async function pageConsumeByKey(data: IPageConsumeByKey) {
|
||||
return http.get("/api/consume/pageConsumeByKey", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
import { http } from "@/utils";
|
||||
|
||||
interface IListDishesType {
|
||||
dishesTypeName: string;
|
||||
}
|
||||
|
||||
export interface IPageDishesByKey {
|
||||
dishesName: string;
|
||||
typeId: number;
|
||||
}
|
||||
|
||||
interface IAddDishesType {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface IGetDishesTypeById {
|
||||
dishesTypeId: string;
|
||||
}
|
||||
|
||||
interface IAddDishes {
|
||||
id: number;
|
||||
name: string;
|
||||
price: string;
|
||||
typeId: number;
|
||||
}
|
||||
|
||||
export interface IGetDishesById {
|
||||
dishesId: string;
|
||||
}
|
||||
|
||||
// 获取菜品分类列表
|
||||
export async function listDishesType(data: IListDishesType) {
|
||||
return http.get("/api/dishes/listDishesType", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 分页查询菜品
|
||||
export async function pageDishesByKey(data: IPageDishesByKey) {
|
||||
return http.get("/api/dishes/pageDishesByKey", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 新增菜品分类
|
||||
export function addDishesType(data: IAddDishesType) {
|
||||
return http.post("/api/dishes/addDishesType", data);
|
||||
}
|
||||
|
||||
// 根据编号获取菜品分类
|
||||
export async function getDishesTypeById(data: IGetDishesTypeById) {
|
||||
return http.get("/api/dishes/getDishesTypeById", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 编辑菜品分类
|
||||
export function editDishesType(data: IAddDishesType) {
|
||||
return http.put("/api/dishes/editDishesType", data);
|
||||
}
|
||||
|
||||
// 删除菜品分类
|
||||
export async function deleteDishesType(data: IGetDishesTypeById) {
|
||||
return http.delete("/api/dishes/deleteDishesType", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 新增菜品
|
||||
export function addDishes(data: IAddDishes) {
|
||||
return http.post("/api/dishes/addDishes", data);
|
||||
}
|
||||
|
||||
// 根据编号获取菜品
|
||||
export async function getDishesById(data: IGetDishesById) {
|
||||
return http.get("/api/dishes/getDishesById", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 编辑菜品
|
||||
export function editDishes(data: IAddDishes) {
|
||||
return http.put("/api/dishes/editDishes", data);
|
||||
}
|
||||
|
||||
// 删除菜品
|
||||
export async function deleteDishes(data: IGetDishesById) {
|
||||
return http.delete("/api/dishes/deleteDishes", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { http } from '@/utils'
|
||||
// 可售床位
|
||||
export async function getAvailableBed() {
|
||||
return http.get('/api/home/availableBed')
|
||||
}
|
||||
// 业务趋势
|
||||
export async function getBusinessTrend() {
|
||||
return http.get('/api/home/businessTrend')
|
||||
}
|
||||
// 客户来源渠道
|
||||
export async function getClientSource() {
|
||||
return http.get('/api/home/clientSource')
|
||||
}
|
||||
// 本月业绩排行
|
||||
export async function getMonthPerformanceRank() {
|
||||
return http.get('/api/home/monthPerformanceRank')
|
||||
}
|
||||
// 今日概览
|
||||
export async function getTodayOverview() {
|
||||
return http.get('/api/home/todayOverview')
|
||||
}
|
||||
// 今日销售跟进
|
||||
export async function getTodaySaleFollow() {
|
||||
return http.get('/api/home/todaySaleFollow')
|
||||
}
|
@ -0,0 +1,107 @@
|
||||
import { http } from "@/utils";
|
||||
import { IPageSearchElderByKey } from "@/apis/bookManage";
|
||||
|
||||
interface IPageOutwardByKey {
|
||||
elderName: string;
|
||||
chaperoneType: string;
|
||||
startTime: string;
|
||||
endTime: string;
|
||||
}
|
||||
|
||||
interface IListContactByElderId {
|
||||
elderId: string;
|
||||
}
|
||||
|
||||
interface IAddOutward {
|
||||
elderId: number;
|
||||
chaperoneName: string;
|
||||
chaperonePhone: string;
|
||||
chaperoneType: string;
|
||||
outwardDate: string;
|
||||
planReturnDate: string;
|
||||
}
|
||||
|
||||
interface IGetOutwardById {
|
||||
outwardId: string;
|
||||
}
|
||||
|
||||
interface IDelayReturn {
|
||||
id: string;
|
||||
planReturnDate: string;
|
||||
}
|
||||
|
||||
interface IRecordReturn {
|
||||
id: string;
|
||||
realReturnDate: any;
|
||||
}
|
||||
|
||||
// 陪同人类型
|
||||
export const typeList = [
|
||||
{ label: "护工", value: "护工" },
|
||||
{ label: "家属", value: "家属" }
|
||||
];
|
||||
|
||||
// 分页查询外出登记
|
||||
export async function pageOutwardByKey(data: IPageOutwardByKey) {
|
||||
return http.get("/api/outward/pageOutwardByKey", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 分页搜索老人
|
||||
export async function pageSearchElderByKey(data: IPageSearchElderByKey) {
|
||||
return http.get("/api/outward/pageSearchElderByKey", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 获取护工列表
|
||||
export async function listOutwardStaff() {
|
||||
return http.get("/api/outward/listOutwardStaff");
|
||||
}
|
||||
|
||||
// 获取紧急联系人列表
|
||||
export async function listContactByElderId(data: IListContactByElderId) {
|
||||
return http.get("/api/outward/listContactByElderId", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 新增外出登记
|
||||
export function addOutward(data: IAddOutward) {
|
||||
return http.post("/api/outward/addOutward", data);
|
||||
}
|
||||
|
||||
// 根据编号获取外出登记
|
||||
export async function getOutwardById(data: IGetOutwardById) {
|
||||
return http.get("/api/outward/getOutwardById", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 延期返回
|
||||
export function delayReturn(data: IDelayReturn) {
|
||||
return http.put("/api/outward/delayReturn", data);
|
||||
}
|
||||
|
||||
// 登记返回
|
||||
export function recordReturn(data: IRecordReturn) {
|
||||
return http.put("/api/outward/recordReturn", data);
|
||||
}
|
||||
|
||||
// 删除外出登记
|
||||
export async function deleteOutward(data: IGetOutwardById) {
|
||||
return http.delete("/api/outward/deleteOutward", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
import { http } from "@/utils";
|
||||
import { IPageSearchElderByKey } from "@/apis/bookManage";
|
||||
|
||||
interface IPageRetreatApplyByKey {
|
||||
bedName: string;
|
||||
elderName: string;
|
||||
elderSex: string;
|
||||
idNum: string;
|
||||
}
|
||||
|
||||
interface IAddRetreatApply {
|
||||
elderId: number;
|
||||
}
|
||||
|
||||
// 分页查询退住申请
|
||||
export async function pageRetreatApplyByKey(data: IPageRetreatApplyByKey) {
|
||||
return http.get("/api/retreatApply/pageRetreatApplyByKey", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 分页搜索老人
|
||||
export async function pageSearchElderByKey(data: IPageSearchElderByKey) {
|
||||
return http.get("/api/retreatApply/pageSearchElderByKey", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 新增退住申请
|
||||
export function addRetreatApply(data: IAddRetreatApply) {
|
||||
return http.post("/api/retreatApply/addRetreatApply", data);
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
import { http } from "@/utils";
|
||||
|
||||
interface IPageRetreatAuditByKey {
|
||||
elderName: string;
|
||||
elderSex: string;
|
||||
idNum: string;
|
||||
}
|
||||
|
||||
interface IGetElderFeeById {
|
||||
elderId: number;
|
||||
}
|
||||
|
||||
interface IAuditElderFee {
|
||||
applyId: number;
|
||||
elderId: number;
|
||||
auditResult: number;
|
||||
}
|
||||
|
||||
// 审核结果
|
||||
export const IAuditResultList = [
|
||||
{ label: "通过", value: "通过" },
|
||||
{ label: "不通过", value: "不通过" }
|
||||
];
|
||||
|
||||
// 分页查询退住审核
|
||||
export async function pageRetreatAuditByKey(data: IPageRetreatAuditByKey) {
|
||||
return http.get("/api/retreatAudit/pageRetreatAuditByKey", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 根据编号获取老人费用详情
|
||||
export async function getElderFeeById(data: IGetElderFeeById) {
|
||||
return http.get("/api/retreatAudit/getElderFeeById", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 审核老人费用详情
|
||||
export function auditElderFee(data: IAuditElderFee) {
|
||||
return http.put("/api/retreatAudit/auditElderFee", data);
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
import { http } from '@/utils'
|
||||
|
||||
interface ILoginForm {
|
||||
pass: string
|
||||
phone: string
|
||||
}
|
||||
|
||||
interface ISendCodeForm {
|
||||
pass: string
|
||||
account: string
|
||||
}
|
||||
|
||||
interface IForgetPass {
|
||||
code: string
|
||||
pass: string
|
||||
account: string
|
||||
}
|
||||
|
||||
interface IEditPass {
|
||||
newPass: string
|
||||
oldPass: string
|
||||
}
|
||||
|
||||
export class IEditPassImpl implements IEditPass {
|
||||
newPass: string
|
||||
oldPass: string
|
||||
constructor(newPass: string, oldPass: string) {
|
||||
this.newPass = newPass
|
||||
this.oldPass = oldPass
|
||||
}
|
||||
}
|
||||
|
||||
// 登录
|
||||
export function getLogin(data: ILoginForm) {
|
||||
return http.post('/api/account/login', data)
|
||||
}
|
||||
|
||||
// 发送验证码
|
||||
export async function sendCode(data: ISendCodeForm) {
|
||||
return http.get('/api/account/sendCode', {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 忘记密码
|
||||
export async function forgetPass(data: IForgetPass) {
|
||||
return http.put('/api/account/forget', data)
|
||||
}
|
||||
|
||||
// 修改密码
|
||||
export async function editPass(data: IEditPass) {
|
||||
return http.put('/api/account/edit', data)
|
||||
}
|
||||
|
||||
// 退出登录
|
||||
export async function getLogout() {
|
||||
return http.delete('/api/account/logout')
|
||||
}
|
@ -0,0 +1,94 @@
|
||||
import { http } from "@/utils";
|
||||
import { IPageSearchElderByKey } from "@/apis/bookManage";
|
||||
|
||||
interface IPageVisitByKey {
|
||||
elderName: string;
|
||||
visitName: string;
|
||||
visitPhone: string;
|
||||
visitFlag: string;
|
||||
}
|
||||
|
||||
interface IAddVisit {
|
||||
id: number;
|
||||
elderId: number;
|
||||
name: string;
|
||||
phone: string;
|
||||
relation: string;
|
||||
visitDate: string;
|
||||
visitNum: number;
|
||||
}
|
||||
|
||||
interface IGetVisitById {
|
||||
visitId: string;
|
||||
}
|
||||
|
||||
interface IEditVisit {
|
||||
id: number;
|
||||
name: string;
|
||||
phone: string;
|
||||
relation: string;
|
||||
visitDateStr: string;
|
||||
visitNum: number;
|
||||
}
|
||||
|
||||
interface IRecordLeave {
|
||||
id: string;
|
||||
leaveDate: any;
|
||||
}
|
||||
|
||||
// 来访状态
|
||||
export const typeList = [
|
||||
{ label: "待离开", value: "待离开" },
|
||||
{ label: "已离开", value: "已离开" }
|
||||
];
|
||||
|
||||
// 分页查询来访登记
|
||||
export async function pageVisitByKey(data: IPageVisitByKey) {
|
||||
return http.get("/api/visit/pageVisitByKey", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 分页搜索老人
|
||||
export async function pageSearchElderByKey(data: IPageSearchElderByKey) {
|
||||
return http.get("/api/visit/pageSearchElderByKey", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 新增来访登记
|
||||
export function addVisit(data: IAddVisit) {
|
||||
return http.post("/api/visit/addVisit", data);
|
||||
}
|
||||
|
||||
// 根据编号获取来访登记
|
||||
export async function getVisitById(data: IGetVisitById) {
|
||||
return http.get("/api/visit/getVisitById", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 编辑来访登记
|
||||
export function editVisit(data: IEditVisit) {
|
||||
return http.put("/api/visit/editVisit", data);
|
||||
}
|
||||
|
||||
// 登记离开
|
||||
export function recordLeave(data: IRecordLeave) {
|
||||
return http.put("/api/visit/recordLeave", data);
|
||||
}
|
||||
|
||||
// 删除来访登记
|
||||
export async function deleteVisit(data: IGetVisitById) {
|
||||
return http.delete("/api/visit/deleteVisit", {
|
||||
params: {
|
||||
...data
|
||||
}
|
||||
});
|
||||
}
|
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 8.7 KiB |
After Width: | Height: | Size: 253 KiB |
After Width: | Height: | Size: 132 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 223 KiB |
After Width: | Height: | Size: 65 KiB |
After Width: | Height: | Size: 54 KiB |
@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<div :style="style" v-show="isShow">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts" name="GridItem">
|
||||
import { computed, inject, Ref, ref, useAttrs, watch } from 'vue'
|
||||
import { BreakPoint, Responsive } from '../interface/index'
|
||||
|
||||
type Props = {
|
||||
offset?: number
|
||||
span?: number
|
||||
suffix?: boolean
|
||||
xs?: Responsive
|
||||
sm?: Responsive
|
||||
md?: Responsive
|
||||
lg?: Responsive
|
||||
xl?: Responsive
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
offset: 0,
|
||||
span: 1,
|
||||
suffix: false,
|
||||
xs: undefined,
|
||||
sm: undefined,
|
||||
md: undefined,
|
||||
lg: undefined,
|
||||
xl: undefined
|
||||
})
|
||||
|
||||
const attrs = useAttrs() as any
|
||||
const isShow = ref(true)
|
||||
|
||||
// 注入断点
|
||||
const breakPoint = inject<Ref<BreakPoint>>('breakPoint', ref('xl'))
|
||||
const shouldHiddenIndex = inject<Ref<number>>('shouldHiddenIndex', ref(-1))
|
||||
watch(
|
||||
() => [shouldHiddenIndex.value, breakPoint.value],
|
||||
n => {
|
||||
if (attrs.index) {
|
||||
isShow.value = !(n[0] !== -1 && parseInt(attrs.index) >= n[0])
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
const gap = inject('gap', 0)
|
||||
const cols = inject<Ref<number>>('cols', ref(4))
|
||||
const style = computed(() => {
|
||||
let span = props[breakPoint.value]?.span ?? props.span
|
||||
let offset = props[breakPoint.value]?.offset ?? props.offset
|
||||
if (props.suffix) {
|
||||
return {
|
||||
gridColumnStart: cols.value - span - offset + 1,
|
||||
gridColumnEnd: `span ${span + offset}`,
|
||||
marginLeft:
|
||||
offset !== 0
|
||||
? `calc(((100% + ${gap}px) / ${span + offset}) * ${offset})`
|
||||
: 'unset'
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
gridColumn: `span ${
|
||||
span + offset > cols.value ? cols.value : span + offset
|
||||
}/span ${span + offset > cols.value ? cols.value : span + offset}`,
|
||||
marginLeft:
|
||||
offset !== 0
|
||||
? `calc(((100% + ${gap}px) / ${span + offset}) * ${offset})`
|
||||
: 'unset'
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
@ -0,0 +1,176 @@
|
||||
<template>
|
||||
<div :style="style">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="Grid">
|
||||
import {
|
||||
ref,
|
||||
watch,
|
||||
useSlots,
|
||||
computed,
|
||||
provide,
|
||||
onBeforeMount,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
onDeactivated,
|
||||
onActivated,
|
||||
VNodeArrayChildren,
|
||||
VNode
|
||||
} from 'vue'
|
||||
import type { BreakPoint } from './interface/index'
|
||||
|
||||
type Props = {
|
||||
cols?: number | Record<BreakPoint, number>
|
||||
collapsed?: boolean
|
||||
collapsedRows?: number
|
||||
gap?: [number, number] | number
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
cols: () => ({ xs: 1, sm: 2, md: 2, lg: 3, xl: 4 }),
|
||||
collapsed: false,
|
||||
collapsedRows: 1,
|
||||
gap: 0
|
||||
})
|
||||
|
||||
onBeforeMount(() => props.collapsed && findIndex())
|
||||
onMounted(() => {
|
||||
resize({ target: { innerWidth: window.innerWidth } } as any)
|
||||
window.addEventListener('resize', resize)
|
||||
})
|
||||
onActivated(() => {
|
||||
resize({ target: { innerWidth: window.innerWidth } } as any)
|
||||
window.addEventListener('resize', resize)
|
||||
})
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', resize)
|
||||
})
|
||||
onDeactivated(() => {
|
||||
window.removeEventListener('resize', resize)
|
||||
})
|
||||
|
||||
// 监听屏幕变化
|
||||
const resize = (e: UIEvent) => {
|
||||
let width = (e.target as Window).innerWidth
|
||||
switch (!!width) {
|
||||
case width < 768:
|
||||
breakPoint.value = 'xs'
|
||||
break
|
||||
case width >= 768 && width < 992:
|
||||
breakPoint.value = 'sm'
|
||||
break
|
||||
case width >= 992 && width < 1200:
|
||||
breakPoint.value = 'md'
|
||||
break
|
||||
case width >= 1200 && width < 1920:
|
||||
breakPoint.value = 'lg'
|
||||
break
|
||||
case width >= 1920:
|
||||
breakPoint.value = 'xl'
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 注入 gap 间距
|
||||
provide('gap', Array.isArray(props.gap) ? props.gap[0] : props.gap)
|
||||
|
||||
// 注入响应式断点
|
||||
let breakPoint = ref<BreakPoint>('xl')
|
||||
provide('breakPoint', breakPoint)
|
||||
|
||||
// 注入要开始折叠的 index
|
||||
const hiddenIndex = ref(-1)
|
||||
provide('shouldHiddenIndex', hiddenIndex)
|
||||
|
||||
// 注入 cols
|
||||
const cols = computed(() => {
|
||||
if (typeof props.cols === 'object')
|
||||
return props.cols[breakPoint.value] ?? props.cols
|
||||
return props.cols
|
||||
})
|
||||
provide('cols', cols)
|
||||
|
||||
const slots = useSlots().default!()
|
||||
|
||||
// 寻找需要开始折叠的字段 index
|
||||
const findIndex = () => {
|
||||
let fields: VNodeArrayChildren = []
|
||||
let suffix: any = null
|
||||
slots.forEach((slot: any) => {
|
||||
if (
|
||||
typeof slot.type === 'object' &&
|
||||
slot.type.name === 'GridItem' &&
|
||||
slot.props?.suffix !== undefined
|
||||
)
|
||||
suffix = slot
|
||||
if (typeof slot.type === 'symbol' && Array.isArray(slot.children))
|
||||
slot.children.forEach((child: any) => fields.push(child))
|
||||
})
|
||||
|
||||
// 计算 suffix 所占用的列
|
||||
let suffixCols = 0
|
||||
if (suffix) {
|
||||
suffixCols =
|
||||
(suffix.props![breakPoint.value]?.span ?? suffix.props?.span ?? 1) +
|
||||
(suffix.props![breakPoint.value]?.offset ?? suffix.props?.offset ?? 0)
|
||||
}
|
||||
try {
|
||||
let find = false
|
||||
fields.reduce((prev = 0, current, index) => {
|
||||
prev +=
|
||||
((current as VNode)!.props![breakPoint.value]?.span ??
|
||||
(current as VNode)!.props?.span ??
|
||||
1) +
|
||||
((current as VNode)!.props![breakPoint.value]?.offset ??
|
||||
(current as VNode)!.props?.offset ??
|
||||
0)
|
||||
if ((prev as number) > props.collapsedRows * cols.value - suffixCols) {
|
||||
hiddenIndex.value = index
|
||||
find = true
|
||||
throw 'find it'
|
||||
}
|
||||
return prev
|
||||
}, 0)
|
||||
if (!find) hiddenIndex.value = -1
|
||||
} catch (e) {
|
||||
// console.warn(e);
|
||||
}
|
||||
}
|
||||
|
||||
// 断点变化时 执行 findIndex
|
||||
watch(
|
||||
() => breakPoint.value,
|
||||
() => {
|
||||
if (props.collapsed) findIndex()
|
||||
}
|
||||
)
|
||||
|
||||
// 监听 collapsed
|
||||
watch(
|
||||
() => props.collapsed,
|
||||
value => {
|
||||
if (value) return findIndex()
|
||||
hiddenIndex.value = -1
|
||||
}
|
||||
)
|
||||
|
||||
// 设置间距
|
||||
const gap = computed(() => {
|
||||
if (typeof props.gap === 'number') return `${props.gap}px`
|
||||
if (Array.isArray(props.gap)) return `${props.gap[1]}px ${props.gap[0]}px`
|
||||
return 'unset'
|
||||
})
|
||||
|
||||
// 设置 style
|
||||
const style = computed(() => {
|
||||
return {
|
||||
display: 'grid',
|
||||
gridGap: gap.value,
|
||||
gridTemplateColumns: `repeat(${cols.value}, minmax(0, 1fr))`
|
||||
}
|
||||
})
|
||||
|
||||
defineExpose({ breakPoint })
|
||||
</script>
|
@ -0,0 +1,6 @@
|
||||
export type BreakPoint = 'xs' | 'sm' | 'md' | 'lg' | 'xl'
|
||||
|
||||
export type Responsive = {
|
||||
span?: number
|
||||
offset?: number
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<Component
|
||||
:is="icon"
|
||||
:theme="theme"
|
||||
:size="size"
|
||||
:spin="spin"
|
||||
:fill="fill"
|
||||
:strokeLinecap="strokeLinecap"
|
||||
:strokeLinejoin="strokeLinejoin"
|
||||
:strokeWidth="strokeWidth"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Icon } from '@icon-park/vue-next/lib/runtime'
|
||||
|
||||
defineProps<{
|
||||
icon: Icon
|
||||
theme?: 'outline' | 'filled' | 'two-tone' | 'multi-color'
|
||||
size?: number | string
|
||||
spin?: boolean
|
||||
fill?: string | string[]
|
||||
strokeLinecap?: 'butt' | 'round' | 'square'
|
||||
strokeLinejoin?: 'miter' | 'round' | 'bevel'
|
||||
strokeWidth?: number
|
||||
}>()
|
||||
</script>
|
@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<!-- 列设置 -->
|
||||
<el-drawer title="列设置" v-model="drawerVisible" size="450px">
|
||||
<div class="table-main">
|
||||
<el-table
|
||||
:data="colSetting"
|
||||
:border="true"
|
||||
row-key="prop"
|
||||
default-expand-all
|
||||
:tree-props="{ children: '_children' }"
|
||||
>
|
||||
<el-table-column prop="label" align="center" label="列名" />
|
||||
<el-table-column
|
||||
prop="isShow"
|
||||
align="center"
|
||||
label="显示"
|
||||
v-slot="scope"
|
||||
>
|
||||
<el-switch v-model="scope.row.isShow"></el-switch>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="sortable"
|
||||
align="center"
|
||||
label="排序"
|
||||
v-slot="scope"
|
||||
>
|
||||
<el-switch v-model="scope.row.sortable"></el-switch>
|
||||
</el-table-column>
|
||||
<template #empty>
|
||||
<div class="table-empty">
|
||||
<div>暂无可配置列</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="ColSetting">
|
||||
import { ref } from 'vue'
|
||||
import { ColumnProps } from '@/components/ProTable/interface'
|
||||
|
||||
defineProps<{ colSetting: ColumnProps[] }>()
|
||||
|
||||
const drawerVisible = ref<boolean>(false)
|
||||
// 打开列设置
|
||||
const openColSetting = () => {
|
||||
drawerVisible.value = true
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
openColSetting
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.cursor-move {
|
||||
cursor: move;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<!-- 分页组件 -->
|
||||
<el-pagination
|
||||
:current-page="pageable.pageNum"
|
||||
:page-size="pageable.pageSize"
|
||||
:page-sizes="[10, 25, 50, 100]"
|
||||
:background="true"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
:total="pageable.total"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
></el-pagination>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="Pagination">
|
||||
interface Pageable {
|
||||
pageNum: number
|
||||
pageSize: number
|
||||
total: number
|
||||
}
|
||||
|
||||
interface PaginationProps {
|
||||
pageable: Pageable
|
||||
handleSizeChange: (size: number) => void
|
||||
handleCurrentChange: (currentPage: number) => void
|
||||
}
|
||||
|
||||
defineProps<PaginationProps>()
|
||||
</script>
|
@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<component :is="renderLoop(column)"></component>
|
||||
</template>
|
||||
|
||||
<script lang="tsx" setup name="TableColumn">
|
||||
import { inject, ref, useSlots } from 'vue'
|
||||
import { ColumnProps } from '@/components/ProTable/interface'
|
||||
import { filterEnum, formatValue, handleRowAccordingToProp } from '@/utils/util'
|
||||
|
||||
defineProps<{ column: ColumnProps }>()
|
||||
|
||||
const slots = useSlots()
|
||||
|
||||
const enumMap = inject('enumMap', ref(new Map()))
|
||||
|
||||
// 渲染表格数据
|
||||
const renderCellData = (item: ColumnProps, scope: { [key: string]: any }) => {
|
||||
return enumMap.value.get(item.prop) && item.isFilterEnum
|
||||
? filterEnum(
|
||||
handleRowAccordingToProp(scope.row, item.prop!),
|
||||
enumMap.value.get(item.prop)!,
|
||||
item.fieldNames
|
||||
)
|
||||
: formatValue(handleRowAccordingToProp(scope.row, item.prop!))
|
||||
}
|
||||
|
||||
// 获取 tag 类型
|
||||
const getTagType = (item: ColumnProps, scope: { [key: string]: any }) => {
|
||||
return filterEnum(
|
||||
handleRowAccordingToProp(scope.row, item.prop!),
|
||||
enumMap.value.get(item.prop),
|
||||
item.fieldNames,
|
||||
'tag'
|
||||
) as any
|
||||
}
|
||||
|
||||
const renderLoop = (item: ColumnProps) => {
|
||||
return (
|
||||
<>
|
||||
{item.isShow && (
|
||||
<el-table-column
|
||||
{...item}
|
||||
align={item.align ?? 'center'}
|
||||
showOverflowTooltip={
|
||||
item.showOverflowTooltip ?? item.prop !== 'operation'
|
||||
}
|
||||
>
|
||||
{{
|
||||
default: (scope: any) => {
|
||||
if (item._children)
|
||||
return item._children.map(child => renderLoop(child))
|
||||
if (item.render) return item.render(scope)
|
||||
if (slots[item.prop!]) return slots[item.prop!]!(scope)
|
||||
if (item.tag)
|
||||
return (
|
||||
<el-tag type={getTagType(item, scope)}>
|
||||
{renderCellData(item, scope)}
|
||||
</el-tag>
|
||||
)
|
||||
return renderCellData(item, scope)
|
||||
},
|
||||
header: () => {
|
||||
if (item.headerRender) return item.headerRender(item)
|
||||
if (slots[`${item.prop}Header`])
|
||||
return slots[`${item.prop}Header`]!({ row: item })
|
||||
return item.label
|
||||
}
|
||||
}}
|
||||
</el-table-column>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
</script>
|
@ -0,0 +1,6 @@
|
||||
import reImageVerify from './src/index.vue'
|
||||
|
||||
/** 图形验证码组件 */
|
||||
export const ReImageVerify = reImageVerify
|
||||
|
||||
export default ReImageVerify
|
@ -0,0 +1,85 @@
|
||||
import { ref, onMounted } from 'vue'
|
||||
|
||||
/**
|
||||
* 绘制图形验证码
|
||||
* @param width - 图形宽度
|
||||
* @param height - 图形高度
|
||||
*/
|
||||
export const useImageVerify = (width = 120, height = 40) => {
|
||||
const domRef = ref<HTMLCanvasElement>()
|
||||
const imgCode = ref('')
|
||||
|
||||
function setImgCode(code: string) {
|
||||
imgCode.value = code
|
||||
}
|
||||
|
||||
function getImgCode() {
|
||||
if (!domRef.value) return
|
||||
imgCode.value = draw(domRef.value, width, height)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getImgCode()
|
||||
})
|
||||
|
||||
return {
|
||||
domRef,
|
||||
imgCode,
|
||||
setImgCode,
|
||||
getImgCode
|
||||
}
|
||||
}
|
||||
|
||||
function randomNum(min: number, max: number) {
|
||||
const num = Math.floor(Math.random() * (max - min) + min)
|
||||
return num
|
||||
}
|
||||
|
||||
function randomColor(min: number, max: number) {
|
||||
const r = randomNum(min, max)
|
||||
const g = randomNum(min, max)
|
||||
const b = randomNum(min, max)
|
||||
return `rgb(${r},${g},${b})`
|
||||
}
|
||||
|
||||
function draw(dom: HTMLCanvasElement, width: number, height: number) {
|
||||
let imgCode = ''
|
||||
|
||||
const NUMBER_STRING = '0123456789'
|
||||
|
||||
const ctx = dom.getContext('2d')
|
||||
if (!ctx) return imgCode
|
||||
|
||||
ctx.fillStyle = randomColor(180, 230)
|
||||
ctx.fillRect(0, 0, width, height)
|
||||
for (let i = 0; i < 4; i += 1) {
|
||||
const text = NUMBER_STRING[randomNum(0, NUMBER_STRING.length)]
|
||||
imgCode += text
|
||||
const fontSize = randomNum(18, 41)
|
||||
const deg = randomNum(-30, 30)
|
||||
ctx.font = `${fontSize}px Simhei`
|
||||
ctx.textBaseline = 'top'
|
||||
ctx.fillStyle = randomColor(80, 150)
|
||||
ctx.save()
|
||||
ctx.translate(30 * i + 15, 15)
|
||||
ctx.rotate((deg * Math.PI) / 180)
|
||||
ctx.fillText(text, -15 + 5, -15)
|
||||
ctx.restore()
|
||||
}
|
||||
for (let i = 0; i < 5; i += 1) {
|
||||
ctx.beginPath()
|
||||
ctx.moveTo(randomNum(0, width), randomNum(0, height))
|
||||
ctx.lineTo(randomNum(0, width), randomNum(0, height))
|
||||
ctx.strokeStyle = randomColor(180, 230)
|
||||
ctx.closePath()
|
||||
ctx.stroke()
|
||||
}
|
||||
for (let i = 0; i < 41; i += 1) {
|
||||
ctx.beginPath()
|
||||
ctx.arc(randomNum(0, width), randomNum(0, height), 1, 0, 2 * Math.PI)
|
||||
ctx.closePath()
|
||||
ctx.fillStyle = randomColor(150, 200)
|
||||
ctx.fill()
|
||||
}
|
||||
return imgCode
|
||||
}
|
@ -0,0 +1,42 @@
|
||||
<script setup lang="ts">
|
||||
import { watch } from 'vue'
|
||||
import { useImageVerify } from './hooks'
|
||||
|
||||
interface Props {
|
||||
code?: string
|
||||
}
|
||||
|
||||
interface Emits {
|
||||
(e: 'update:code', code: string): void
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
code: ''
|
||||
})
|
||||
|
||||
const emit = defineEmits<Emits>()
|
||||
|
||||
const { domRef, imgCode, setImgCode, getImgCode } = useImageVerify()
|
||||
|
||||
watch(
|
||||
() => props.code,
|
||||
newValue => {
|
||||
setImgCode(newValue)
|
||||
}
|
||||
)
|
||||
watch(imgCode, newValue => {
|
||||
emit('update:code', newValue)
|
||||
})
|
||||
|
||||
defineExpose({ getImgCode })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<canvas
|
||||
ref="domRef"
|
||||
width="120"
|
||||
height="40"
|
||||
class="cursor-pointer"
|
||||
@click="getImgCode"
|
||||
/>
|
||||
</template>
|
@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<MyCard
|
||||
><div class="card table-search" v-if="columns.length">
|
||||
<el-form ref="formRef" :model="searchParam">
|
||||
<Grid
|
||||
ref="gridRef"
|
||||
:collapsed="collapsed"
|
||||
:gap="[20, 0]"
|
||||
:cols="searchCol"
|
||||
>
|
||||
<GridItem
|
||||
v-for="(item, index) in columns"
|
||||
:key="item.prop"
|
||||
v-bind="getResponsive(item)"
|
||||
:index="index"
|
||||
>
|
||||
<el-form-item :label="`${item.label} :`">
|
||||
<SearchFormItem :column="item" :searchParam="searchParam" />
|
||||
</el-form-item>
|
||||
</GridItem>
|
||||
<GridItem suffix>
|
||||
<div class="operation">
|
||||
<el-button
|
||||
class="bg-blue clickSearchBtn"
|
||||
type="primary"
|
||||
:icon="Search"
|
||||
@click="search"
|
||||
>
|
||||
搜索
|
||||
</el-button>
|
||||
<el-button :icon="Delete" @click="reset">重置</el-button>
|
||||
<el-button
|
||||
v-if="showCollapse"
|
||||
link
|
||||
class="search-isOpen"
|
||||
@click="collapsed = !collapsed"
|
||||
>
|
||||
{{ collapsed ? '展开' : '合并' }}
|
||||
<el-icon class="el-icon--right">
|
||||
<component :is="collapsed ? ArrowDown : ArrowUp"></component>
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
</GridItem>
|
||||
</Grid>
|
||||
</el-form></div
|
||||
></MyCard>
|
||||
</template>
|
||||
<script setup lang="ts" name="SearchForm">
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { ColumnProps } from '@/components/ProTable/interface'
|
||||
import { BreakPoint } from '@/components/Grid/interface'
|
||||
import { Delete, Search, ArrowDown, ArrowUp } from '@element-plus/icons-vue'
|
||||
import SearchFormItem from './components/SearchFormItem.vue'
|
||||
import Grid from '@/components/Grid/index.vue'
|
||||
import GridItem from '@/components/Grid/components/GridItem.vue'
|
||||
import MyCard from '../my-card/my-card.vue'
|
||||
|
||||
interface ProTableProps {
|
||||
columns?: ColumnProps[] // 搜索配置列
|
||||
searchParam?: { [key: string]: any } // 搜索参数
|
||||
searchCol: number | Record<BreakPoint, number>
|
||||
search: (params: any) => void // 搜索方法
|
||||
reset: (params: any) => void // 重置方法
|
||||
}
|
||||
|
||||
// 默认值
|
||||
const props = withDefaults(defineProps<ProTableProps>(), {
|
||||
columns: () => [],
|
||||
searchParam: () => ({})
|
||||
})
|
||||
|
||||
// 获取响应式设置
|
||||
const getResponsive = (item: ColumnProps) => {
|
||||
return {
|
||||
span: item.search?.span,
|
||||
offset: item.search?.offset ?? 0,
|
||||
xs: item.search?.xs,
|
||||
sm: item.search?.sm,
|
||||
md: item.search?.md,
|
||||
lg: item.search?.lg,
|
||||
xl: item.search?.xl
|
||||
}
|
||||
}
|
||||
|
||||
// 是否默认折叠搜索项
|
||||
const collapsed = ref(true)
|
||||
|
||||
// 获取响应式断点
|
||||
const gridRef = ref()
|
||||
const breakPoint = computed<BreakPoint>(() => gridRef.value?.breakPoint)
|
||||
|
||||
// 判断是否显示 展开/合并 按钮
|
||||
const showCollapse = computed(() => {
|
||||
let show = false
|
||||
props.columns.reduce((prev, current) => {
|
||||
prev +=
|
||||
(current.search![breakPoint.value]?.span ?? current.search?.span ?? 1) +
|
||||
(current.search![breakPoint.value]?.offset ?? current.search?.offset ?? 0)
|
||||
if (typeof props.searchCol !== 'number') {
|
||||
if (prev >= props.searchCol[breakPoint.value]) show = true
|
||||
} else {
|
||||
if (prev > props.searchCol) show = true
|
||||
}
|
||||
return prev
|
||||
}, 0)
|
||||
return show
|
||||
})
|
||||
</script>
|
@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<svg class="svg-icon" area-hidden="true">
|
||||
<use :xlink:href="iconName"></use>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { defineProps, computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
icon: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
size: {
|
||||
type: [Number, String],
|
||||
default: 16
|
||||
}
|
||||
})
|
||||
|
||||
const iconName = computed(() => {
|
||||
return `#icon-${props.icon}`
|
||||
})
|
||||
const iconSize = computed(() => {
|
||||
return props.size + 'px'
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.svg-icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
fill: currentColor;
|
||||
font-size: v-bind(iconSize);
|
||||
}
|
||||
</style>
|
@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<div class="flex flex-col rounded card-wrap p-3">
|
||||
<div class="pb-2" v-if="title">{{ title }}</div>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
defineProps<{
|
||||
title?: string
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-wrap {
|
||||
background-color: #ffffff;
|
||||
border: 1px solid #eee;
|
||||
font-size: 18px;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
style="width: 70%"
|
||||
v-model="dialogVisible"
|
||||
title="选择床位"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-tree
|
||||
:data="data"
|
||||
:props="defaultProps"
|
||||
accordion
|
||||
@node-click="checkBed"
|
||||
/>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="useProTable">
|
||||
import { ref } from "vue";
|
||||
import { getBuildTree } from "@/apis/bookManage";
|
||||
|
||||
const data: any = ref();
|
||||
const dialogVisible = ref(false);
|
||||
const drawerProps = ref<DialogProps>();
|
||||
|
||||
interface DialogProps {
|
||||
treeApi: (params: any) => Promise<any>;
|
||||
}
|
||||
|
||||
const defaultProps = {
|
||||
id: "id",
|
||||
label: "name",
|
||||
children: "childrenList"
|
||||
};
|
||||
|
||||
// 接收父组件传过来的参数
|
||||
const treeAcceptParams = async (params: DialogProps) => {
|
||||
drawerProps.value = params;
|
||||
dialogVisible.value = true;
|
||||
const res: any = await getBuildTree();
|
||||
data.value = res.data;
|
||||
};
|
||||
// 将方法主动暴露出来
|
||||
defineExpose({
|
||||
treeAcceptParams
|
||||
});
|
||||
|
||||
// const emit = defineEmits(['getCheckElderInfo'])
|
||||
const emit = defineEmits<{
|
||||
(event: "getCheckBedInfo", val: any): void
|
||||
}>();
|
||||
// 向父组件传值
|
||||
const checkBed = (bed: any) => {
|
||||
if (bed.level === 4) {
|
||||
emit("getCheckBedInfo", bed);
|
||||
dialogVisible.value = false;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
@ -0,0 +1,27 @@
|
||||
export namespace Table {
|
||||
export interface Pageable {
|
||||
pageNum: number
|
||||
pageSize: number
|
||||
total: number
|
||||
}
|
||||
export interface TableStateProps {
|
||||
tableData: any[]
|
||||
pageable: Pageable
|
||||
searchParam: {
|
||||
[key: string]: any
|
||||
}
|
||||
searchInitParam: {
|
||||
[key: string]: any
|
||||
}
|
||||
totalParam: {
|
||||
[key: string]: any
|
||||
}
|
||||
icon?: {
|
||||
[key: string]: any
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export namespace HandleData {
|
||||
export type MessageType = '' | 'success' | 'warning' | 'info' | 'error'
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
import { ElMessageBox, ElMessage } from 'element-plus'
|
||||
import { HandleData } from './interface'
|
||||
|
||||
/**
|
||||
* @description 操作单条数据信息(二次确认【删除、禁用、启用、重置密码】)
|
||||
* @param {Function} api 操作数据接口的api方法(必传)
|
||||
* @param {Object} params 携带的操作数据参数 {id,params}(必传)
|
||||
* @param {String} message 提示信息(必传)
|
||||
* @param {String} confirmType icon类型(不必传,默认为 warning)
|
||||
* @return Promise
|
||||
*/
|
||||
export const useHandleData = <P = any, R = any>(
|
||||
api: (params: P) => Promise<R>,
|
||||
params: Parameters<typeof api>[0],
|
||||
message: string,
|
||||
confirmType: HandleData.MessageType = 'warning'
|
||||
) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
ElMessageBox.confirm(`是否${message}?`, '温馨提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: confirmType,
|
||||
draggable: true
|
||||
}).then(async () => {
|
||||
const res = await api(params)
|
||||
if (!res) return reject(false)
|
||||
ElMessage({
|
||||
type: 'success',
|
||||
message: `${message}成功!`
|
||||
})
|
||||
resolve(true)
|
||||
})
|
||||
})
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
import SvgIcon from '@/components/SvgIcon/index.vue'
|
||||
import { h, defineComponent } from 'vue'
|
||||
|
||||
export function useRenderIcon(iconName: string, attrs?: any) {
|
||||
return defineComponent({
|
||||
name: 'SvgIcon',
|
||||
render() {
|
||||
return h(SvgIcon, {
|
||||
icon: iconName,
|
||||
...attrs
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
// import { ref } from 'vue'
|
||||
// import { useRoute, onBeforeRouteUpdate } from 'vue-router'
|
||||
// import { useCookies } from '@vueuse/integrations/useCookies'
|
||||
// import { router } from '~/router'
|
||||
|
||||
// export function useTabList() {
|
||||
// const route = useRoute()
|
||||
// const cookie = useCookies()
|
||||
|
||||
// const activeTab = ref(route.path)
|
||||
// const tabList = ref([
|
||||
// {
|
||||
// title: '后台首页',
|
||||
// path: '/'
|
||||
// }
|
||||
// ])
|
||||
|
||||
// // 添加标签导航
|
||||
// function addTab(tab) {
|
||||
// let noTab = tabList.value.findIndex((t) => t.path == tab.path) == -1
|
||||
// if (noTab) {
|
||||
// tabList.value.push(tab)
|
||||
// }
|
||||
|
||||
// cookie.set('tabList', tabList.value)
|
||||
// }
|
||||
|
||||
// // 初始化标签导航列表
|
||||
// function initTabList() {
|
||||
// let tbs = cookie.get('tabList')
|
||||
// if (tbs) {
|
||||
// tabList.value = tbs
|
||||
// }
|
||||
// }
|
||||
|
||||
// initTabList()
|
||||
|
||||
// onBeforeRouteUpdate((to, from) => {
|
||||
// activeTab.value = to.path
|
||||
// addTab({
|
||||
// title: to.meta.title,
|
||||
// path: to.path
|
||||
// })
|
||||
// })
|
||||
|
||||
// const changeTab = (t) => {
|
||||
// activeTab.value = t
|
||||
// router.push(t)
|
||||
// }
|
||||
|
||||
// const removeTab = (t) => {
|
||||
// let tabs = tabList.value
|
||||
// let a = activeTab.value
|
||||
// if (a == t) {
|
||||
// tabs.forEach((tab, index) => {
|
||||
// if (tab.path == t) {
|
||||
// const nextTab = tabs[index + 1] || tabs[index - 1]
|
||||
// if (nextTab) {
|
||||
// a = nextTab.path
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
|
||||
// activeTab.value = a
|
||||
// tabList.value = tabList.value.filter((tab) => tab.path != t)
|
||||
|
||||
// cookie.set('tabList', tabList.value)
|
||||
// }
|
||||
|
||||
// const handleClose = (c) => {
|
||||
// if (c == 'clearAll') {
|
||||
// // 切换回首页
|
||||
// activeTab.value = '/'
|
||||
// // 过滤只剩下首页
|
||||
// tabList.value = [
|
||||
// {
|
||||
// title: '后台首页',
|
||||
// path: '/'
|
||||
// }
|
||||
// ]
|
||||
// } else if (c == 'clearOther') {
|
||||
// // 过滤只剩下首页和当前激活
|
||||
// tabList.value = tabList.value.filter(
|
||||
// (tab) => tab.path == '/' || tab.path == activeTab.value
|
||||
// )
|
||||
// }
|
||||
// cookie.set('tabList', tabList.value)
|
||||
// }
|
||||
|
||||
// return {
|
||||
// activeTab,
|
||||
// tabList,
|
||||
// changeTab,
|
||||
// removeTab,
|
||||
// handleClose
|
||||
// }
|
||||
// }
|
After Width: | Height: | Size: 764 B |
After Width: | Height: | Size: 283 B |
After Width: | Height: | Size: 382 B |
After Width: | Height: | Size: 659 B |
After Width: | Height: | Size: 549 B |
After Width: | Height: | Size: 983 B |
After Width: | Height: | Size: 356 B |
After Width: | Height: | Size: 316 B |