缓存(默认 false)
+ title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字
+ icon: 'svg-name' // 设置该路由的图标,对应路径src/assets/icons/svg
+ breadcrumb: false // 如果设置为false,则不会在breadcrumb面包屑中显示
+ activeMenu: '/system/user' // 当路由设置了该属性,则会高亮相对应的侧边栏。
+ }
+ */
+
+// 公共路由
+export const constantRoutes = [
+ {
+ path: '/redirect',
+ component: Layout,
+ hidden: true,
+ children: [
+ {
+ path: '/redirect/:path(.*)',
+ component: () => import('@/views/redirect/index.vue')
+ }
+ ]
+ },
+ {
+ path: '/login',
+ component: () => import('@/views/login'),
+ hidden: true
+ },
+ {
+ path: '/register',
+ component: () => import('@/views/register'),
+ hidden: true
+ },
+ {
+ path: "/:pathMatch(.*)*",
+ component: () => import('@/views/error/404'),
+ hidden: true
+ },
+ {
+ path: '/401',
+ component: () => import('@/views/error/401'),
+ hidden: true
+ },
+ {
+ path: '',
+ component: Layout,
+ redirect: '/index',
+ children: [
+ {
+ path: '/index',
+ component: () => import('@/views/index'),
+ name: 'Index',
+ meta: { title: '首页', icon: 'dashboard', affix: true }
+ }
+ ]
+ },
+ {
+ path: '/user',
+ component: Layout,
+ hidden: true,
+ redirect: 'noredirect',
+ children: [
+ {
+ path: 'profile',
+ component: () => import('@/views/system/user/profile/index'),
+ name: 'Profile',
+ meta: { title: '个人中心', icon: 'user' }
+ }
+ ]
+ }
+]
+
+// 动态路由,基于用户权限动态去加载
+export const dynamicRoutes = [
+ {
+ path: '/system/user-auth',
+ component: Layout,
+ hidden: true,
+ permissions: ['system:user:edit'],
+ children: [
+ {
+ path: 'role/:userId(\\d+)',
+ component: () => import('@/views/system/user/authRole'),
+ name: 'AuthRole',
+ meta: { title: '分配角色', activeMenu: '/system/user' }
+ }
+ ]
+ },
+ {
+ path: '/system/role-auth',
+ component: Layout,
+ hidden: true,
+ permissions: ['system:role:edit'],
+ children: [
+ {
+ path: 'user/:roleId(\\d+)',
+ component: () => import('@/views/system/role/authUser'),
+ name: 'AuthUser',
+ meta: { title: '分配用户', activeMenu: '/system/role' }
+ }
+ ]
+ },
+ {
+ path: '/system/dict-data',
+ component: Layout,
+ hidden: true,
+ permissions: ['system:dict:list'],
+ children: [
+ {
+ path: 'index/:dictId(\\d+)',
+ component: () => import('@/views/system/dict/data'),
+ name: 'Data',
+ meta: { title: '字典数据', activeMenu: '/system/dict' }
+ }
+ ]
+ },
+ {
+ path: '/monitor/job-log',
+ component: Layout,
+ hidden: true,
+ permissions: ['monitor:job:list'],
+ children: [
+ {
+ path: 'index/:jobId(\\d+)',
+ component: () => import('@/views/monitor/job/log'),
+ name: 'JobLog',
+ meta: { title: '调度日志', activeMenu: '/monitor/job' }
+ }
+ ]
+ },
+ {
+ path: '/tool/gen-edit',
+ component: Layout,
+ hidden: true,
+ permissions: ['tool:gen:edit'],
+ children: [
+ {
+ path: 'index/:tableId(\\d+)',
+ component: () => import('@/views/tool/gen/editTable'),
+ name: 'GenEdit',
+ meta: { title: '修改生成配置', activeMenu: '/tool/gen' }
+ }
+ ]
+ }
+]
+
+const router = createRouter({
+ history: createWebHistory(),
+ routes: constantRoutes,
+ scrollBehavior(to, from, savedPosition) {
+ if (savedPosition) {
+ return savedPosition
+ } else {
+ return { top: 0 }
+ }
+ },
+});
+
+export default router;
diff --git a/openhis-ui-vue3-miniapp/src/settings.js b/openhis-ui-vue3-miniapp/src/settings.js
new file mode 100644
index 00000000..08a01082
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/settings.js
@@ -0,0 +1,47 @@
+export default {
+ /**
+ * 网页标题
+ */
+ title: import.meta.env.VITE_APP_TITLE,
+ /**
+ * 侧边栏主题 深色主题theme-dark,浅色主题theme-light
+ */
+ sideTheme: 'theme-dark',
+ /**
+ * 是否系统布局配置
+ */
+ showSettings: true,
+
+ /**
+ * 是否显示顶部导航
+ */
+ topNav: false,
+
+ /**
+ * 是否显示 tagsView
+ */
+ tagsView: true,
+
+ /**
+ * 是否固定头部
+ */
+ fixedHeader: false,
+
+ /**
+ * 是否显示logo
+ */
+ sidebarLogo: true,
+
+ /**
+ * 是否显示动态标题
+ */
+ dynamicTitle: false,
+
+ /**
+ * @type {string | array} 'production' | ['production', 'development']
+ * @description Need show err logs component.
+ * The default is only used in the production env
+ * If you want to also use it in dev, you can pass ['production', 'development']
+ */
+ errorLog: 'production'
+}
diff --git a/openhis-ui-vue3-miniapp/src/store/index.js b/openhis-ui-vue3-miniapp/src/store/index.js
new file mode 100644
index 00000000..f10f3895
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/store/index.js
@@ -0,0 +1,3 @@
+const store = createPinia()
+
+export default store
\ No newline at end of file
diff --git a/openhis-ui-vue3-miniapp/src/store/modules/app.js b/openhis-ui-vue3-miniapp/src/store/modules/app.js
new file mode 100644
index 00000000..0b571596
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/store/modules/app.js
@@ -0,0 +1,46 @@
+import Cookies from 'js-cookie'
+
+const useAppStore = defineStore(
+ 'app',
+ {
+ state: () => ({
+ sidebar: {
+ opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true,
+ withoutAnimation: false,
+ hide: false
+ },
+ device: 'desktop',
+ size: Cookies.get('size') || 'default'
+ }),
+ actions: {
+ toggleSideBar(withoutAnimation) {
+ if (this.sidebar.hide) {
+ return false;
+ }
+ this.sidebar.opened = !this.sidebar.opened
+ this.sidebar.withoutAnimation = withoutAnimation
+ if (this.sidebar.opened) {
+ Cookies.set('sidebarStatus', 1)
+ } else {
+ Cookies.set('sidebarStatus', 0)
+ }
+ },
+ closeSideBar({ withoutAnimation }) {
+ Cookies.set('sidebarStatus', 0)
+ this.sidebar.opened = false
+ this.sidebar.withoutAnimation = withoutAnimation
+ },
+ toggleDevice(device) {
+ this.device = device
+ },
+ setSize(size) {
+ this.size = size;
+ Cookies.set('size', size)
+ },
+ toggleSideBarHide(status) {
+ this.sidebar.hide = status
+ }
+ }
+ })
+
+export default useAppStore
diff --git a/openhis-ui-vue3-miniapp/src/store/modules/dict.js b/openhis-ui-vue3-miniapp/src/store/modules/dict.js
new file mode 100644
index 00000000..27fc3086
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/store/modules/dict.js
@@ -0,0 +1,57 @@
+const useDictStore = defineStore(
+ 'dict',
+ {
+ state: () => ({
+ dict: new Array()
+ }),
+ actions: {
+ // 获取字典
+ getDict(_key) {
+ if (_key == null && _key == "") {
+ return null;
+ }
+ try {
+ for (let i = 0; i < this.dict.length; i++) {
+ if (this.dict[i].key == _key) {
+ return this.dict[i].value;
+ }
+ }
+ } catch (e) {
+ return null;
+ }
+ },
+ // 设置字典
+ setDict(_key, value) {
+ if (_key !== null && _key !== "") {
+ this.dict.push({
+ key: _key,
+ value: value
+ });
+ }
+ },
+ // 删除字典
+ removeDict(_key) {
+ var bln = false;
+ try {
+ for (let i = 0; i < this.dict.length; i++) {
+ if (this.dict[i].key == _key) {
+ this.dict.splice(i, 1);
+ return true;
+ }
+ }
+ } catch (e) {
+ bln = false;
+ }
+ return bln;
+ },
+ // 清空字典
+ cleanDict() {
+ this.dict = new Array();
+ },
+ // 初始字典
+ initDict() {
+ }
+ }
+ })
+
+export default useDictStore
diff --git a/openhis-ui-vue3-miniapp/src/store/modules/permission.js b/openhis-ui-vue3-miniapp/src/store/modules/permission.js
new file mode 100644
index 00000000..958fe636
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/store/modules/permission.js
@@ -0,0 +1,142 @@
+import auth from '@/plugins/auth'
+import router, { constantRoutes, dynamicRoutes } from '@/router'
+import { getRouters } from '@/api/menu'
+import Layout from '@/layout/index'
+import ParentView from '@/components/ParentView'
+import InnerLink from '@/layout/components/InnerLink'
+
+// 匹配views里面所有的.vue文件
+const modules = import.meta.glob('./../../views/**/*.vue')
+
+const usePermissionStore = defineStore(
+ 'permission',
+ {
+ state: () => ({
+ routes: [],
+ addRoutes: [],
+ defaultRoutes: [],
+ topbarRouters: [],
+ sidebarRouters: []
+ }),
+ actions: {
+ setRoutes(routes) {
+ this.addRoutes = routes
+ this.routes = constantRoutes.concat(routes)
+ },
+ setDefaultRoutes(routes) {
+ this.defaultRoutes = constantRoutes.concat(routes)
+ },
+ setTopbarRoutes(routes) {
+ this.topbarRouters = routes
+ },
+ setSidebarRouters(routes) {
+ this.sidebarRouters = routes
+ },
+ generateRoutes(roles) {
+ return new Promise(resolve => {
+ // 向后端请求路由数据
+ getRouters().then(res => {
+ const sdata = JSON.parse(JSON.stringify(res.data))
+ const rdata = JSON.parse(JSON.stringify(res.data))
+ const defaultData = JSON.parse(JSON.stringify(res.data))
+ const sidebarRoutes = filterAsyncRouter(sdata)
+ const rewriteRoutes = filterAsyncRouter(rdata, false, true)
+ const defaultRoutes = filterAsyncRouter(defaultData)
+ const asyncRoutes = filterDynamicRoutes(dynamicRoutes)
+ asyncRoutes.forEach(route => { router.addRoute(route) })
+ this.setRoutes(rewriteRoutes)
+ this.setSidebarRouters(constantRoutes.concat(sidebarRoutes))
+ this.setDefaultRoutes(sidebarRoutes)
+ this.setTopbarRoutes(defaultRoutes)
+ resolve(rewriteRoutes)
+ })
+ })
+ }
+ }
+ })
+
+// 遍历后台传来的路由字符串,转换为组件对象
+function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
+ return asyncRouterMap.filter(route => {
+ if (type && route.children) {
+ route.children = filterChildren(route.children)
+ }
+ if (route.component) {
+ // Layout ParentView 组件特殊处理
+ if (route.component === 'Layout') {
+ route.component = Layout
+ } else if (route.component === 'ParentView') {
+ route.component = ParentView
+ } else if (route.component === 'InnerLink') {
+ route.component = InnerLink
+ } else {
+ route.component = loadView(route.component)
+ }
+ }
+ if (route.children != null && route.children && route.children.length) {
+ route.children = filterAsyncRouter(route.children, route, type)
+ } else {
+ delete route['children']
+ delete route['redirect']
+ }
+ return true
+ })
+}
+
+function filterChildren(childrenMap, lastRouter = false) {
+ var children = []
+ childrenMap.forEach((el, index) => {
+ if (el.children && el.children.length) {
+ if (el.component === 'ParentView' && !lastRouter) {
+ el.children.forEach(c => {
+ c.path = el.path + '/' + c.path
+ if (c.children && c.children.length) {
+ children = children.concat(filterChildren(c.children, c))
+ return
+ }
+ children.push(c)
+ })
+ return
+ }
+ }
+ if (lastRouter) {
+ el.path = lastRouter.path + '/' + el.path
+ if (el.children && el.children.length) {
+ children = children.concat(filterChildren(el.children, el))
+ return
+ }
+ }
+ children = children.concat(el)
+ })
+ return children
+}
+
+// 动态路由遍历,验证是否具备权限
+export function filterDynamicRoutes(routes) {
+ const res = []
+ routes.forEach(route => {
+ if (route.permissions) {
+ if (auth.hasPermiOr(route.permissions)) {
+ res.push(route)
+ }
+ } else if (route.roles) {
+ if (auth.hasRoleOr(route.roles)) {
+ res.push(route)
+ }
+ }
+ })
+ return res
+}
+
+export const loadView = (view) => {
+ let res;
+ for (const path in modules) {
+ const dir = path.split('views/')[1].split('.vue')[0];
+ if (dir === view) {
+ res = () => modules[path]();
+ }
+ }
+ return res;
+}
+
+export default usePermissionStore
diff --git a/openhis-ui-vue3-miniapp/src/store/modules/settings.js b/openhis-ui-vue3-miniapp/src/store/modules/settings.js
new file mode 100644
index 00000000..22b73366
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/store/modules/settings.js
@@ -0,0 +1,38 @@
+import defaultSettings from '@/settings'
+import { useDynamicTitle } from '@/utils/dynamicTitle'
+
+const { sideTheme, showSettings, topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle } = defaultSettings
+
+const storageSetting = JSON.parse(localStorage.getItem('layout-setting')) || ''
+
+const useSettingsStore = defineStore(
+ 'settings',
+ {
+ state: () => ({
+ title: '',
+ theme: storageSetting.theme || '#409EFF',
+ sideTheme: storageSetting.sideTheme || sideTheme,
+ showSettings: showSettings,
+ topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
+ tagsView: storageSetting.tagsView === undefined ? tagsView : storageSetting.tagsView,
+ fixedHeader: storageSetting.fixedHeader === undefined ? fixedHeader : storageSetting.fixedHeader,
+ sidebarLogo: storageSetting.sidebarLogo === undefined ? sidebarLogo : storageSetting.sidebarLogo,
+ dynamicTitle: storageSetting.dynamicTitle === undefined ? dynamicTitle : storageSetting.dynamicTitle
+ }),
+ actions: {
+ // 修改布局设置
+ changeSetting(data) {
+ const { key, value } = data
+ if (this.hasOwnProperty(key)) {
+ this[key] = value
+ }
+ },
+ // 设置网页标题
+ setTitle(title) {
+ this.title = title
+ useDynamicTitle();
+ }
+ }
+ })
+
+export default useSettingsStore
diff --git a/openhis-ui-vue3-miniapp/src/store/modules/tagsView.js b/openhis-ui-vue3-miniapp/src/store/modules/tagsView.js
new file mode 100644
index 00000000..9d07f33d
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/store/modules/tagsView.js
@@ -0,0 +1,182 @@
+const useTagsViewStore = defineStore(
+ 'tags-view',
+ {
+ state: () => ({
+ visitedViews: [],
+ cachedViews: [],
+ iframeViews: []
+ }),
+ actions: {
+ addView(view) {
+ this.addVisitedView(view)
+ this.addCachedView(view)
+ },
+ addIframeView(view) {
+ if (this.iframeViews.some(v => v.path === view.path)) return
+ this.iframeViews.push(
+ Object.assign({}, view, {
+ title: view.meta.title || 'no-name'
+ })
+ )
+ },
+ addVisitedView(view) {
+ if (this.visitedViews.some(v => v.path === view.path)) return
+ this.visitedViews.push(
+ Object.assign({}, view, {
+ title: view.meta.title || 'no-name'
+ })
+ )
+ },
+ addCachedView(view) {
+ if (this.cachedViews.includes(view.name)) return
+ if (!view.meta.noCache) {
+ this.cachedViews.push(view.name)
+ }
+ },
+ delView(view) {
+ return new Promise(resolve => {
+ this.delVisitedView(view)
+ this.delCachedView(view)
+ resolve({
+ visitedViews: [...this.visitedViews],
+ cachedViews: [...this.cachedViews]
+ })
+ })
+ },
+ delVisitedView(view) {
+ return new Promise(resolve => {
+ for (const [i, v] of this.visitedViews.entries()) {
+ if (v.path === view.path) {
+ this.visitedViews.splice(i, 1)
+ break
+ }
+ }
+ this.iframeViews = this.iframeViews.filter(item => item.path !== view.path)
+ resolve([...this.visitedViews])
+ })
+ },
+ delIframeView(view) {
+ return new Promise(resolve => {
+ this.iframeViews = this.iframeViews.filter(item => item.path !== view.path)
+ resolve([...this.iframeViews])
+ })
+ },
+ delCachedView(view) {
+ return new Promise(resolve => {
+ const index = this.cachedViews.indexOf(view.name)
+ index > -1 && this.cachedViews.splice(index, 1)
+ resolve([...this.cachedViews])
+ })
+ },
+ delOthersViews(view) {
+ return new Promise(resolve => {
+ this.delOthersVisitedViews(view)
+ this.delOthersCachedViews(view)
+ resolve({
+ visitedViews: [...this.visitedViews],
+ cachedViews: [...this.cachedViews]
+ })
+ })
+ },
+ delOthersVisitedViews(view) {
+ return new Promise(resolve => {
+ this.visitedViews = this.visitedViews.filter(v => {
+ return v.meta.affix || v.path === view.path
+ })
+ this.iframeViews = this.iframeViews.filter(item => item.path === view.path)
+ resolve([...this.visitedViews])
+ })
+ },
+ delOthersCachedViews(view) {
+ return new Promise(resolve => {
+ const index = this.cachedViews.indexOf(view.name)
+ if (index > -1) {
+ this.cachedViews = this.cachedViews.slice(index, index + 1)
+ } else {
+ this.cachedViews = []
+ }
+ resolve([...this.cachedViews])
+ })
+ },
+ delAllViews(view) {
+ return new Promise(resolve => {
+ this.delAllVisitedViews(view)
+ this.delAllCachedViews(view)
+ resolve({
+ visitedViews: [...this.visitedViews],
+ cachedViews: [...this.cachedViews]
+ })
+ })
+ },
+ delAllVisitedViews(view) {
+ return new Promise(resolve => {
+ const affixTags = this.visitedViews.filter(tag => tag.meta.affix)
+ this.visitedViews = affixTags
+ this.iframeViews = []
+ resolve([...this.visitedViews])
+ })
+ },
+ delAllCachedViews(view) {
+ return new Promise(resolve => {
+ this.cachedViews = []
+ resolve([...this.cachedViews])
+ })
+ },
+ updateVisitedView(view) {
+ for (let v of this.visitedViews) {
+ if (v.path === view.path) {
+ v = Object.assign(v, view)
+ break
+ }
+ }
+ },
+ delRightTags(view) {
+ return new Promise(resolve => {
+ const index = this.visitedViews.findIndex(v => v.path === view.path)
+ if (index === -1) {
+ return
+ }
+ this.visitedViews = this.visitedViews.filter((item, idx) => {
+ if (idx <= index || (item.meta && item.meta.affix)) {
+ return true
+ }
+ const i = this.cachedViews.indexOf(item.name)
+ if (i > -1) {
+ this.cachedViews.splice(i, 1)
+ }
+ if(item.meta.link) {
+ const fi = this.iframeViews.findIndex(v => v.path === item.path)
+ this.iframeViews.splice(fi, 1)
+ }
+ return false
+ })
+ resolve([...this.visitedViews])
+ })
+ },
+ delLeftTags(view) {
+ return new Promise(resolve => {
+ const index = this.visitedViews.findIndex(v => v.path === view.path)
+ if (index === -1) {
+ return
+ }
+ this.visitedViews = this.visitedViews.filter((item, idx) => {
+ if (idx >= index || (item.meta && item.meta.affix)) {
+ return true
+ }
+ const i = this.cachedViews.indexOf(item.name)
+ if (i > -1) {
+ this.cachedViews.splice(i, 1)
+ }
+ if(item.meta.link) {
+ const fi = this.iframeViews.findIndex(v => v.path === item.path)
+ this.iframeViews.splice(fi, 1)
+ }
+ return false
+ })
+ resolve([...this.visitedViews])
+ })
+ }
+ }
+ })
+
+export default useTagsViewStore
diff --git a/openhis-ui-vue3-miniapp/src/store/modules/user.js b/openhis-ui-vue3-miniapp/src/store/modules/user.js
new file mode 100644
index 00000000..d439c44a
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/store/modules/user.js
@@ -0,0 +1,72 @@
+import { login, logout, getInfo } from '@/api/login'
+import { getToken, setToken, removeToken } from '@/utils/auth'
+import defAva from '@/assets/images/profile.jpg'
+
+const useUserStore = defineStore(
+ 'user',
+ {
+ state: () => ({
+ token: getToken(),
+ id: '',
+ name: '',
+ avatar: '',
+ roles: [],
+ permissions: []
+ }),
+ actions: {
+ // 登录
+ login(userInfo) {
+ const username = userInfo.username.trim()
+ const password = userInfo.password
+ const code = userInfo.code
+ const uuid = userInfo.uuid
+ return new Promise((resolve, reject) => {
+ login(username, password, code, uuid).then(res => {
+ setToken(res.token)
+ this.token = res.token
+ resolve()
+ }).catch(error => {
+ reject(error)
+ })
+ })
+ },
+ // 获取用户信息
+ getInfo() {
+ return new Promise((resolve, reject) => {
+ getInfo().then(res => {
+ const user = res.user
+ const avatar = (user.avatar == "" || user.avatar == null) ? defAva : import.meta.env.VITE_APP_BASE_API + user.avatar;
+
+ if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
+ this.roles = res.roles
+ this.permissions = res.permissions
+ } else {
+ this.roles = ['ROLE_DEFAULT']
+ }
+ this.id = user.userId
+ this.name = user.userName
+ this.avatar = avatar
+ resolve(res)
+ }).catch(error => {
+ reject(error)
+ })
+ })
+ },
+ // 退出系统
+ logOut() {
+ return new Promise((resolve, reject) => {
+ logout(this.token).then(() => {
+ this.token = ''
+ this.roles = []
+ this.permissions = []
+ removeToken()
+ resolve()
+ }).catch(error => {
+ reject(error)
+ })
+ })
+ }
+ }
+ })
+
+export default useUserStore
diff --git a/openhis-ui-vue3-miniapp/src/utils/auth.js b/openhis-ui-vue3-miniapp/src/utils/auth.js
new file mode 100644
index 00000000..08a43d6e
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/utils/auth.js
@@ -0,0 +1,15 @@
+import Cookies from 'js-cookie'
+
+const TokenKey = 'Admin-Token'
+
+export function getToken() {
+ return Cookies.get(TokenKey)
+}
+
+export function setToken(token) {
+ return Cookies.set(TokenKey, token)
+}
+
+export function removeToken() {
+ return Cookies.remove(TokenKey)
+}
diff --git a/openhis-ui-vue3-miniapp/src/utils/dict.js b/openhis-ui-vue3-miniapp/src/utils/dict.js
new file mode 100644
index 00000000..9648f149
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/utils/dict.js
@@ -0,0 +1,24 @@
+import useDictStore from '@/store/modules/dict'
+import { getDicts } from '@/api/system/dict/data'
+
+/**
+ * 获取字典数据
+ */
+export function useDict(...args) {
+ const res = ref({});
+ return (() => {
+ args.forEach((dictType, index) => {
+ res.value[dictType] = [];
+ const dicts = useDictStore().getDict(dictType);
+ if (dicts) {
+ res.value[dictType] = dicts;
+ } else {
+ getDicts(dictType).then(resp => {
+ res.value[dictType] = resp.data.map(p => ({ label: p.dictLabel, value: p.dictValue, elTagType: p.listClass, elTagClass: p.cssClass }))
+ useDictStore().setDict(dictType, res.value[dictType]);
+ })
+ }
+ })
+ return toRefs(res.value);
+ })()
+}
\ No newline at end of file
diff --git a/openhis-ui-vue3-miniapp/src/utils/dynamicTitle.js b/openhis-ui-vue3-miniapp/src/utils/dynamicTitle.js
new file mode 100644
index 00000000..64404b20
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/utils/dynamicTitle.js
@@ -0,0 +1,15 @@
+import store from '@/store'
+import defaultSettings from '@/settings'
+import useSettingsStore from '@/store/modules/settings'
+
+/**
+ * 动态修改标题
+ */
+export function useDynamicTitle() {
+ const settingsStore = useSettingsStore();
+ if (settingsStore.dynamicTitle) {
+ document.title = settingsStore.title + ' - ' + defaultSettings.title;
+ } else {
+ document.title = defaultSettings.title;
+ }
+}
\ No newline at end of file
diff --git a/openhis-ui-vue3-miniapp/src/utils/errorCode.js b/openhis-ui-vue3-miniapp/src/utils/errorCode.js
new file mode 100644
index 00000000..d2111ee1
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/utils/errorCode.js
@@ -0,0 +1,6 @@
+export default {
+ '401': '认证失败,无法访问系统资源',
+ '403': '当前操作没有权限',
+ '404': '访问资源不存在',
+ 'default': '系统未知错误,请反馈给管理员'
+}
diff --git a/openhis-ui-vue3-miniapp/src/utils/his.js b/openhis-ui-vue3-miniapp/src/utils/his.js
new file mode 100644
index 00000000..25954883
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/utils/his.js
@@ -0,0 +1,264 @@
+
+
+// 日期格式化
+export function parseTime(time, pattern) {
+ if (arguments.length === 0 || !time) {
+ return null
+ }
+ const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
+ let date
+ if (typeof time === 'object') {
+ date = time
+ } else {
+ if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
+ time = parseInt(time)
+ } else if (typeof time === 'string') {
+ time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '');
+ }
+ if ((typeof time === 'number') && (time.toString().length === 10)) {
+ time = time * 1000
+ }
+ date = new Date(time)
+ }
+ const formatObj = {
+ y: date.getFullYear(),
+ m: date.getMonth() + 1,
+ d: date.getDate(),
+ h: date.getHours(),
+ i: date.getMinutes(),
+ s: date.getSeconds(),
+ a: date.getDay()
+ }
+ const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
+ let value = formatObj[key]
+ // Note: getDay() returns 0 on Sunday
+ if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
+ if (result.length > 0 && value < 10) {
+ value = '0' + value
+ }
+ return value || 0
+ })
+ return time_str
+}
+
+// 表单重置
+export function resetForm(refName) {
+ if (this.$refs[refName]) {
+ this.$refs[refName].resetFields();
+ }
+}
+
+// 添加日期范围
+export function addDateRange(params, dateRange, propName) {
+ let search = params;
+ search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {};
+ dateRange = Array.isArray(dateRange) ? dateRange : [];
+ if (typeof (propName) === 'undefined') {
+ search.params['beginTime'] = dateRange[0];
+ search.params['endTime'] = dateRange[1];
+ } else {
+ search.params['begin' + propName] = dateRange[0];
+ search.params['end' + propName] = dateRange[1];
+ }
+ return search;
+}
+export function addDateRanges(params, dateRange1, dateRange2, propName) {
+ let search = params;
+ search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {};
+ dateRange1 = Array.isArray(dateRange1) ? dateRange1 : [];
+ dateRange2 = Array.isArray(dateRange2) ? dateRange2 : [];
+ if (typeof (propName) === 'undefined') {
+ search.params['beginTime'] = dateRange1[0];
+ search.params['endTime'] = dateRange1[1];
+ search.params['timeFrom'] = dateRange2[0];
+ search.params['timeTo'] = dateRange2[1];
+ } else {
+ search.params['begin' + propName] = dateRange1[0];
+ search.params['end' + propName] = dateRange1[1];
+ search.params['from' + propName] = dateRange2[0];
+ search.params['to' + propName] = dateRange2[1];
+ }
+ return search;
+}
+
+// 回显数据字典
+export function selectDictLabel(datas, value) {
+ if (value === undefined) {
+ return "";
+ }
+ var actions = [];
+ Object.keys(datas).some((key) => {
+ if (datas[key].value == ('' + value)) {
+ actions.push(datas[key].label);
+ return true;
+ }
+ })
+ if (actions.length === 0) {
+ actions.push(value);
+ }
+ return actions.join('');
+}
+
+// 回显数据字典(字符串数组)
+export function selectDictLabels(datas, value, separator) {
+ if (value === undefined || value.length ===0) {
+ return "";
+ }
+ if (Array.isArray(value)) {
+ value = value.join(",");
+ }
+ var actions = [];
+ var currentSeparator = undefined === separator ? "," : separator;
+ var temp = value.split(currentSeparator);
+ Object.keys(value.split(currentSeparator)).some((val) => {
+ var match = false;
+ Object.keys(datas).some((key) => {
+ if (datas[key].value == ('' + temp[val])) {
+ actions.push(datas[key].label + currentSeparator);
+ match = true;
+ }
+ })
+ if (!match) {
+ actions.push(temp[val] + currentSeparator);
+ }
+ })
+ return actions.join('').substring(0, actions.join('').length - 1);
+}
+
+// 字符串格式化(%s )
+export function sprintf(str) {
+ var args = arguments, flag = true, i = 1;
+ str = str.replace(/%s/g, function () {
+ var arg = args[i++];
+ if (typeof arg === 'undefined') {
+ flag = false;
+ return '';
+ }
+ return arg;
+ });
+ return flag ? str : '';
+}
+
+// 转换字符串,undefined,null等转化为""
+export function parseStrEmpty(str) {
+ if (!str || str == "undefined" || str == "null") {
+ return "";
+ }
+ return str;
+}
+
+// 千位分隔
+export function thousandNumber (num) {
+ return String(num).replace(/\B(?=(\d{3})+(?!\d))/g, ','); // 3是千分位,4是万分位
+};
+
+// 数据合并
+export function mergeRecursive(source, target) {
+ for (var p in target) {
+ try {
+ if (target[p].constructor == Object) {
+ source[p] = mergeRecursive(source[p], target[p]);
+ } else {
+ source[p] = target[p];
+ }
+ } catch (e) {
+ source[p] = target[p];
+ }
+ }
+ return source;
+};
+
+/**
+ * 构造树型结构数据
+ * @param {*} data 数据源
+ * @param {*} id id字段 默认 'id'
+ * @param {*} parentId 父节点字段 默认 'parentId'
+ * @param {*} children 孩子节点字段 默认 'children'
+ */
+export function handleTree(data, id, parentId, children) {
+ let config = {
+ id: id || 'id',
+ parentId: parentId || 'parentId',
+ childrenList: children || 'children'
+ };
+
+ var childrenListMap = {};
+ var nodeIds = {};
+ var tree = [];
+
+ for (let d of data) {
+ let parentId = d[config.parentId];
+ if (childrenListMap[parentId] == null) {
+ childrenListMap[parentId] = [];
+ }
+ nodeIds[d[config.id]] = d;
+ childrenListMap[parentId].push(d);
+ }
+
+ for (let d of data) {
+ let parentId = d[config.parentId];
+ if (nodeIds[parentId] == null) {
+ tree.push(d);
+ }
+ }
+
+ for (let t of tree) {
+ adaptToChildrenList(t);
+ }
+
+ function adaptToChildrenList(o) {
+ if (childrenListMap[o[config.id]] !== null) {
+ o[config.childrenList] = childrenListMap[o[config.id]];
+ }
+ if (o[config.childrenList]) {
+ for (let c of o[config.childrenList]) {
+ adaptToChildrenList(c);
+ }
+ }
+ }
+ return tree;
+}
+
+/**
+* 参数处理
+* @param {*} params 参数
+*/
+export function tansParams(params) {
+ let result = ''
+ for (const propName of Object.keys(params)) {
+ const value = params[propName];
+ var part = encodeURIComponent(propName) + "=";
+ if (value !== null && value !== "" && typeof (value) !== "undefined") {
+ if (typeof value === 'object') {
+ for (const key of Object.keys(value)) {
+ if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {
+ let params = propName + '[' + key + ']';
+ var subPart = encodeURIComponent(params) + "=";
+ result += subPart + encodeURIComponent(value[key]) + "&";
+ }
+ }
+ } else {
+ result += part + encodeURIComponent(value) + "&";
+ }
+ }
+ }
+ return result
+}
+
+
+// 返回项目路径
+export function getNormalPath(p) {
+ if (p.length === 0 || !p || p == 'undefined') {
+ return p
+ };
+ let res = p.replace('//', '/')
+ if (res[res.length - 1] === '/') {
+ return res.slice(0, res.length - 1)
+ }
+ return res;
+}
+
+// 验证是否为blob格式
+export function blobValidate(data) {
+ return data.type !== 'application/json'
+}
diff --git a/openhis-ui-vue3-miniapp/src/utils/index.js b/openhis-ui-vue3-miniapp/src/utils/index.js
new file mode 100644
index 00000000..7a808a78
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/utils/index.js
@@ -0,0 +1,390 @@
+import { parseTime } from './openhis'
+
+/**
+ * 表格时间格式化
+ */
+export function formatDate(cellValue) {
+ if (cellValue == null || cellValue == "") return "";
+ var date = new Date(cellValue)
+ var year = date.getFullYear()
+ var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
+ var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
+ var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
+ var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
+ var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
+ return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
+}
+
+/**
+ * @param {number} time
+ * @param {string} option
+ * @returns {string}
+ */
+export function formatTime(time, option) {
+ if (('' + time).length === 10) {
+ time = parseInt(time) * 1000
+ } else {
+ time = +time
+ }
+ const d = new Date(time)
+ const now = Date.now()
+
+ const diff = (now - d) / 1000
+
+ if (diff < 30) {
+ return '刚刚'
+ } else if (diff < 3600) {
+ // less 1 hour
+ return Math.ceil(diff / 60) + '分钟前'
+ } else if (diff < 3600 * 24) {
+ return Math.ceil(diff / 3600) + '小时前'
+ } else if (diff < 3600 * 24 * 2) {
+ return '1天前'
+ }
+ if (option) {
+ return parseTime(time, option)
+ } else {
+ return (
+ d.getMonth() +
+ 1 +
+ '月' +
+ d.getDate() +
+ '日' +
+ d.getHours() +
+ '时' +
+ d.getMinutes() +
+ '分'
+ )
+ }
+}
+
+/**
+ * @param {string} url
+ * @returns {Object}
+ */
+export function getQueryObject(url) {
+ url = url == null ? window.location.href : url
+ const search = url.substring(url.lastIndexOf('?') + 1)
+ const obj = {}
+ const reg = /([^?&=]+)=([^?&=]*)/g
+ search.replace(reg, (rs, $1, $2) => {
+ const name = decodeURIComponent($1)
+ let val = decodeURIComponent($2)
+ val = String(val)
+ obj[name] = val
+ return rs
+ })
+ return obj
+}
+
+/**
+ * @param {string} input value
+ * @returns {number} output value
+ */
+export function byteLength(str) {
+ // returns the byte length of an utf8 string
+ let s = str.length
+ for (var i = str.length - 1; i >= 0; i--) {
+ const code = str.charCodeAt(i)
+ if (code > 0x7f && code <= 0x7ff) s++
+ else if (code > 0x7ff && code <= 0xffff) s += 2
+ if (code >= 0xDC00 && code <= 0xDFFF) i--
+ }
+ return s
+}
+
+/**
+ * @param {Array} actual
+ * @returns {Array}
+ */
+export function cleanArray(actual) {
+ const newArray = []
+ for (let i = 0; i < actual.length; i++) {
+ if (actual[i]) {
+ newArray.push(actual[i])
+ }
+ }
+ return newArray
+}
+
+/**
+ * @param {Object} json
+ * @returns {Array}
+ */
+export function param(json) {
+ if (!json) return ''
+ return cleanArray(
+ Object.keys(json).map(key => {
+ if (json[key] === undefined) return ''
+ return encodeURIComponent(key) + '=' + encodeURIComponent(json[key])
+ })
+ ).join('&')
+}
+
+/**
+ * @param {string} url
+ * @returns {Object}
+ */
+export function param2Obj(url) {
+ const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
+ if (!search) {
+ return {}
+ }
+ const obj = {}
+ const searchArr = search.split('&')
+ searchArr.forEach(v => {
+ const index = v.indexOf('=')
+ if (index !== -1) {
+ const name = v.substring(0, index)
+ const val = v.substring(index + 1, v.length)
+ obj[name] = val
+ }
+ })
+ return obj
+}
+
+/**
+ * @param {string} val
+ * @returns {string}
+ */
+export function html2Text(val) {
+ const div = document.createElement('div')
+ div.innerHTML = val
+ return div.textContent || div.innerText
+}
+
+/**
+ * Merges two objects, giving the last one precedence
+ * @param {Object} target
+ * @param {(Object|Array)} source
+ * @returns {Object}
+ */
+export function objectMerge(target, source) {
+ if (typeof target !== 'object') {
+ target = {}
+ }
+ if (Array.isArray(source)) {
+ return source.slice()
+ }
+ Object.keys(source).forEach(property => {
+ const sourceProperty = source[property]
+ if (typeof sourceProperty === 'object') {
+ target[property] = objectMerge(target[property], sourceProperty)
+ } else {
+ target[property] = sourceProperty
+ }
+ })
+ return target
+}
+
+/**
+ * @param {HTMLElement} element
+ * @param {string} className
+ */
+export function toggleClass(element, className) {
+ if (!element || !className) {
+ return
+ }
+ let classString = element.className
+ const nameIndex = classString.indexOf(className)
+ if (nameIndex === -1) {
+ classString += '' + className
+ } else {
+ classString =
+ classString.substr(0, nameIndex) +
+ classString.substr(nameIndex + className.length)
+ }
+ element.className = classString
+}
+
+/**
+ * @param {string} type
+ * @returns {Date}
+ */
+export function getTime(type) {
+ if (type === 'start') {
+ return new Date().getTime() - 3600 * 1000 * 24 * 90
+ } else {
+ return new Date(new Date().toDateString())
+ }
+}
+
+/**
+ * @param {Function} func
+ * @param {number} wait
+ * @param {boolean} immediate
+ * @return {*}
+ */
+export function debounce(func, wait, immediate) {
+ let timeout, args, context, timestamp, result
+
+ const later = function() {
+ // 据上一次触发时间间隔
+ const last = +new Date() - timestamp
+
+ // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
+ if (last < wait && last > 0) {
+ timeout = setTimeout(later, wait - last)
+ } else {
+ timeout = null
+ // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
+ if (!immediate) {
+ result = func.apply(context, args)
+ if (!timeout) context = args = null
+ }
+ }
+ }
+
+ return function(...args) {
+ context = this
+ timestamp = +new Date()
+ const callNow = immediate && !timeout
+ // 如果延时不存在,重新设定延时
+ if (!timeout) timeout = setTimeout(later, wait)
+ if (callNow) {
+ result = func.apply(context, args)
+ context = args = null
+ }
+
+ return result
+ }
+}
+
+/**
+ * This is just a simple version of deep copy
+ * Has a lot of edge cases bug
+ * If you want to use a perfect deep copy, use lodash's _.cloneDeep
+ * @param {Object} source
+ * @returns {Object}
+ */
+export function deepClone(source) {
+ if (!source && typeof source !== 'object') {
+ throw new Error('error arguments', 'deepClone')
+ }
+ const targetObj = source.constructor === Array ? [] : {}
+ Object.keys(source).forEach(keys => {
+ if (source[keys] && typeof source[keys] === 'object') {
+ targetObj[keys] = deepClone(source[keys])
+ } else {
+ targetObj[keys] = source[keys]
+ }
+ })
+ return targetObj
+}
+
+/**
+ * @param {Array} arr
+ * @returns {Array}
+ */
+export function uniqueArr(arr) {
+ return Array.from(new Set(arr))
+}
+
+/**
+ * @returns {string}
+ */
+export function createUniqueString() {
+ const timestamp = +new Date() + ''
+ const randomNum = parseInt((1 + Math.random()) * 65536) + ''
+ return (+(randomNum + timestamp)).toString(32)
+}
+
+/**
+ * Check if an element has a class
+ * @param {HTMLElement} elm
+ * @param {string} cls
+ * @returns {boolean}
+ */
+export function hasClass(ele, cls) {
+ return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
+}
+
+/**
+ * Add class to element
+ * @param {HTMLElement} elm
+ * @param {string} cls
+ */
+export function addClass(ele, cls) {
+ if (!hasClass(ele, cls)) ele.className += ' ' + cls
+}
+
+/**
+ * Remove class from element
+ * @param {HTMLElement} elm
+ * @param {string} cls
+ */
+export function removeClass(ele, cls) {
+ if (hasClass(ele, cls)) {
+ const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')
+ ele.className = ele.className.replace(reg, ' ')
+ }
+}
+
+export function makeMap(str, expectsLowerCase) {
+ const map = Object.create(null)
+ const list = str.split(',')
+ for (let i = 0; i < list.length; i++) {
+ map[list[i]] = true
+ }
+ return expectsLowerCase
+ ? val => map[val.toLowerCase()]
+ : val => map[val]
+}
+
+export const exportDefault = 'export default '
+
+export const beautifierConf = {
+ html: {
+ indent_size: '2',
+ indent_char: ' ',
+ max_preserve_newlines: '-1',
+ preserve_newlines: false,
+ keep_array_indentation: false,
+ break_chained_methods: false,
+ indent_scripts: 'separate',
+ brace_style: 'end-expand',
+ space_before_conditional: true,
+ unescape_strings: false,
+ jslint_happy: false,
+ end_with_newline: true,
+ wrap_line_length: '110',
+ indent_inner_html: true,
+ comma_first: false,
+ e4x: true,
+ indent_empty_lines: true
+ },
+ js: {
+ indent_size: '2',
+ indent_char: ' ',
+ max_preserve_newlines: '-1',
+ preserve_newlines: false,
+ keep_array_indentation: false,
+ break_chained_methods: false,
+ indent_scripts: 'normal',
+ brace_style: 'end-expand',
+ space_before_conditional: true,
+ unescape_strings: false,
+ jslint_happy: true,
+ end_with_newline: true,
+ wrap_line_length: '110',
+ indent_inner_html: true,
+ comma_first: false,
+ e4x: true,
+ indent_empty_lines: true
+ }
+}
+
+// 首字母大小
+export function titleCase(str) {
+ return str.replace(/( |^)[a-z]/g, L => L.toUpperCase())
+}
+
+// 下划转驼峰
+export function camelCase(str) {
+ return str.replace(/_[a-z]/g, str1 => str1.substr(-1).toUpperCase())
+}
+
+export function isNumberStr(str) {
+ return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
+}
+
diff --git a/openhis-ui-vue3-miniapp/src/utils/jsencrypt.js b/openhis-ui-vue3-miniapp/src/utils/jsencrypt.js
new file mode 100644
index 00000000..78d95234
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/utils/jsencrypt.js
@@ -0,0 +1,30 @@
+import JSEncrypt from 'jsencrypt/bin/jsencrypt.min'
+
+// 密钥对生成 http://web.chacuo.net/netrsakeypair
+
+const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdH\n' +
+ 'nzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ=='
+
+const privateKey = 'MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY\n' +
+ '7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKN\n' +
+ 'PuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gA\n' +
+ 'kM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWow\n' +
+ 'cSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99Ecv\n' +
+ 'DQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthh\n' +
+ 'YhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3\n' +
+ 'UP8iWi1Qw0Y='
+
+// 加密
+export function encrypt(txt) {
+ const encryptor = new JSEncrypt()
+ encryptor.setPublicKey(publicKey) // 设置公钥
+ return encryptor.encrypt(txt) // 对数据进行加密
+}
+
+// 解密
+export function decrypt(txt) {
+ const encryptor = new JSEncrypt()
+ encryptor.setPrivateKey(privateKey) // 设置私钥
+ return encryptor.decrypt(txt) // 对数据进行解密
+}
+
diff --git a/openhis-ui-vue3-miniapp/src/utils/openhis.js b/openhis-ui-vue3-miniapp/src/utils/openhis.js
new file mode 100644
index 00000000..4efca08f
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/utils/openhis.js
@@ -0,0 +1,246 @@
+
+
+/**
+ * 通用js方法封装处理
+ * Copyright (c) 2019 ruoyi
+ */
+
+// 日期格式化
+export function parseTime(time, pattern) {
+ if (arguments.length === 0 || !time) {
+ return null
+ }
+ const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}'
+ let date
+ if (typeof time === 'object') {
+ date = time
+ } else {
+ if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
+ time = parseInt(time)
+ } else if (typeof time === 'string') {
+ time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '');
+ }
+ if ((typeof time === 'number') && (time.toString().length === 10)) {
+ time = time * 1000
+ }
+ date = new Date(time)
+ }
+ const formatObj = {
+ y: date.getFullYear(),
+ m: date.getMonth() + 1,
+ d: date.getDate(),
+ h: date.getHours(),
+ i: date.getMinutes(),
+ s: date.getSeconds(),
+ a: date.getDay()
+ }
+ const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
+ let value = formatObj[key]
+ // Note: getDay() returns 0 on Sunday
+ if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
+ if (result.length > 0 && value < 10) {
+ value = '0' + value
+ }
+ return value || 0
+ })
+ return time_str
+}
+
+// 表单重置
+export function resetForm(refName) {
+ if (this.$refs[refName]) {
+ this.$refs[refName].resetFields();
+ }
+}
+
+// 添加日期范围
+export function addDateRange(params, dateRange, propName) {
+ let search = params;
+ search.params = typeof (search.params) === 'object' && search.params !== null && !Array.isArray(search.params) ? search.params : {};
+ dateRange = Array.isArray(dateRange) ? dateRange : [];
+ if (typeof (propName) === 'undefined') {
+ search.params['beginTime'] = dateRange[0];
+ search.params['endTime'] = dateRange[1];
+ } else {
+ search.params['begin' + propName] = dateRange[0];
+ search.params['end' + propName] = dateRange[1];
+ }
+ return search;
+}
+
+// 回显数据字典
+export function selectDictLabel(datas, value) {
+ if (value === undefined) {
+ return "";
+ }
+ var actions = [];
+ Object.keys(datas).some((key) => {
+ if (datas[key].value == ('' + value)) {
+ actions.push(datas[key].label);
+ return true;
+ }
+ })
+ if (actions.length === 0) {
+ actions.push(value);
+ }
+ return actions.join('');
+}
+
+// 回显数据字典(字符串数组)
+export function selectDictLabels(datas, value, separator) {
+ if (value === undefined || value.length ===0) {
+ return "";
+ }
+ if (Array.isArray(value)) {
+ value = value.join(",");
+ }
+ var actions = [];
+ var currentSeparator = undefined === separator ? "," : separator;
+ var temp = value.split(currentSeparator);
+ Object.keys(value.split(currentSeparator)).some((val) => {
+ var match = false;
+ Object.keys(datas).some((key) => {
+ if (datas[key].value == ('' + temp[val])) {
+ actions.push(datas[key].label + currentSeparator);
+ match = true;
+ }
+ })
+ if (!match) {
+ actions.push(temp[val] + currentSeparator);
+ }
+ })
+ return actions.join('').substring(0, actions.join('').length - 1);
+}
+
+// 字符串格式化(%s )
+export function sprintf(str) {
+ var args = arguments, flag = true, i = 1;
+ str = str.replace(/%s/g, function () {
+ var arg = args[i++];
+ if (typeof arg === 'undefined') {
+ flag = false;
+ return '';
+ }
+ return arg;
+ });
+ return flag ? str : '';
+}
+
+// 转换字符串,undefined,null等转化为""
+export function parseStrEmpty(str) {
+ if (!str || str == "undefined" || str == "null") {
+ return "";
+ }
+ return str;
+}
+
+// 数据合并
+export function mergeRecursive(source, target) {
+ for (var p in target) {
+ try {
+ if (target[p].constructor == Object) {
+ source[p] = mergeRecursive(source[p], target[p]);
+ } else {
+ source[p] = target[p];
+ }
+ } catch (e) {
+ source[p] = target[p];
+ }
+ }
+ return source;
+};
+
+/**
+ * 构造树型结构数据
+ * @param {*} data 数据源
+ * @param {*} id id字段 默认 'id'
+ * @param {*} parentId 父节点字段 默认 'parentId'
+ * @param {*} children 孩子节点字段 默认 'children'
+ */
+export function handleTree(data, id, parentId, children) {
+ let config = {
+ id: id || 'id',
+ parentId: parentId || 'parentId',
+ childrenList: children || 'children'
+ };
+
+ var childrenListMap = {};
+ var nodeIds = {};
+ var tree = [];
+
+ for (let d of data) {
+ let parentId = d[config.parentId];
+ if (childrenListMap[parentId] == null) {
+ childrenListMap[parentId] = [];
+ }
+ nodeIds[d[config.id]] = d;
+ childrenListMap[parentId].push(d);
+ }
+
+ for (let d of data) {
+ let parentId = d[config.parentId];
+ if (nodeIds[parentId] == null) {
+ tree.push(d);
+ }
+ }
+
+ for (let t of tree) {
+ adaptToChildrenList(t);
+ }
+
+ function adaptToChildrenList(o) {
+ if (childrenListMap[o[config.id]] !== null) {
+ o[config.childrenList] = childrenListMap[o[config.id]];
+ }
+ if (o[config.childrenList]) {
+ for (let c of o[config.childrenList]) {
+ adaptToChildrenList(c);
+ }
+ }
+ }
+ return tree;
+}
+
+/**
+* 参数处理
+* @param {*} params 参数
+*/
+export function tansParams(params) {
+ let result = ''
+ for (const propName of Object.keys(params)) {
+ const value = params[propName];
+ var part = encodeURIComponent(propName) + "=";
+ if (value !== null && value !== "" && typeof (value) !== "undefined") {
+ if (typeof value === 'object') {
+ for (const key of Object.keys(value)) {
+ if (value[key] !== null && value[key] !== "" && typeof (value[key]) !== 'undefined') {
+ let params = propName + '[' + key + ']';
+ var subPart = encodeURIComponent(params) + "=";
+ result += subPart + encodeURIComponent(value[key]) + "&";
+ }
+ }
+ } else {
+ result += part + encodeURIComponent(value) + "&";
+ }
+ }
+ }
+ return result
+}
+
+
+// 返回项目路径
+export function getNormalPath(p) {
+ if (p.length === 0 || !p || p == 'undefined') {
+ return p
+ };
+ let res = p.replace('//', '/')
+ if (res[res.length - 1] === '/') {
+ return res.slice(0, res.length - 1)
+ }
+ return res;
+}
+
+// 验证是否为blob格式
+export function blobValidate(data) {
+ return data.type !== 'application/json'
+}
diff --git a/openhis-ui-vue3-miniapp/src/utils/permission.js b/openhis-ui-vue3-miniapp/src/utils/permission.js
new file mode 100644
index 00000000..93fee87f
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/utils/permission.js
@@ -0,0 +1,51 @@
+import useUserStore from '@/store/modules/user'
+
+/**
+ * 字符权限校验
+ * @param {Array} value 校验值
+ * @returns {Boolean}
+ */
+export function checkPermi(value) {
+ if (value && value instanceof Array && value.length > 0) {
+ const permissions = useUserStore().permissions
+ const permissionDatas = value
+ const all_permission = "*:*:*";
+
+ const hasPermission = permissions.some(permission => {
+ return all_permission === permission || permissionDatas.includes(permission)
+ })
+
+ if (!hasPermission) {
+ return false
+ }
+ return true
+ } else {
+ console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`)
+ return false
+ }
+}
+
+/**
+ * 角色权限校验
+ * @param {Array} value 校验值
+ * @returns {Boolean}
+ */
+export function checkRole(value) {
+ if (value && value instanceof Array && value.length > 0) {
+ const roles = useUserStore().roles
+ const permissionRoles = value
+ const super_admin = "admin";
+
+ const hasRole = roles.some(role => {
+ return super_admin === role || permissionRoles.includes(role)
+ })
+
+ if (!hasRole) {
+ return false
+ }
+ return true
+ } else {
+ console.error(`need roles! Like checkRole="['admin','editor']"`)
+ return false
+ }
+}
\ No newline at end of file
diff --git a/openhis-ui-vue3-miniapp/src/utils/request.js b/openhis-ui-vue3-miniapp/src/utils/request.js
new file mode 100644
index 00000000..3a9be89d
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/utils/request.js
@@ -0,0 +1,152 @@
+import axios from 'axios'
+import { ElNotification , ElMessageBox, ElMessage, ElLoading } from 'element-plus'
+import { getToken } from '@/utils/auth'
+import errorCode from '@/utils/errorCode'
+import { tansParams, blobValidate } from '@/utils/openhis'
+import cache from '@/plugins/cache'
+import { saveAs } from 'file-saver'
+import useUserStore from '@/store/modules/user'
+
+let downloadLoadingInstance;
+// 是否显示重新登录
+export let isRelogin = { show: false };
+
+axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
+// 创建axios实例
+const service = axios.create({
+ // axios中请求配置有baseURL选项,表示请求URL公共部分
+ baseURL: import.meta.env.VITE_APP_BASE_API,
+ // 超时
+ timeout: 10000
+})
+
+// request拦截器
+service.interceptors.request.use(config => {
+ // 是否需要设置 token
+ const isToken = (config.headers || {}).isToken === false
+ // 是否需要防止数据重复提交
+ const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
+ if (getToken() && !isToken) {
+ config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
+ }
+ // get请求映射params参数
+ if (config.method === 'get' && config.params) {
+ let url = config.url + '?' + tansParams(config.params);
+ url = url.slice(0, -1);
+ config.params = {};
+ config.url = url;
+ }
+ if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
+ const requestObj = {
+ url: config.url,
+ data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
+ time: new Date().getTime()
+ }
+ const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小
+ const limitSize = 5 * 1024 * 1024; // 限制存放数据5M
+ if (requestSize >= limitSize) {
+ console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制,无法进行防重复提交验证。')
+ return config;
+ }
+ const sessionObj = cache.session.getJSON('sessionObj')
+ if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
+ cache.session.setJSON('sessionObj', requestObj)
+ } else {
+ const s_url = sessionObj.url; // 请求地址
+ const s_data = sessionObj.data; // 请求数据
+ const s_time = sessionObj.time; // 请求时间
+ const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交
+ if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
+ const message = '数据正在处理,请勿重复提交';
+ console.warn(`[${s_url}]: ` + message)
+ return Promise.reject(new Error(message))
+ } else {
+ cache.session.setJSON('sessionObj', requestObj)
+ }
+ }
+ }
+ return config
+}, error => {
+ console.log(error)
+ Promise.reject(error)
+})
+
+// 响应拦截器
+service.interceptors.response.use(res => {
+ // 未设置状态码则默认成功状态
+ const code = res.data.code || 200;
+ // 获取错误信息
+ const msg = errorCode[code] || res.data.msg || errorCode['default']
+ // 二进制数据则直接返回
+ if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
+ return res.data
+ }
+ if (code === 401) {
+ if (!isRelogin.show) {
+ isRelogin.show = true;
+ ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
+ isRelogin.show = false;
+ useUserStore().logOut().then(() => {
+ location.href = '/index';
+ })
+ }).catch(() => {
+ isRelogin.show = false;
+ });
+ }
+ return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
+ } else if (code === 500) {
+ ElMessage({ message: msg, type: 'error' })
+ return Promise.reject(new Error(msg))
+ } else if (code === 601) {
+ ElMessage({ message: msg, type: 'warning' })
+ return Promise.reject(new Error(msg))
+ } else if (code !== 200) {
+ ElNotification.error({ title: msg })
+ return Promise.reject('error')
+ } else {
+ return Promise.resolve(res.data)
+ }
+ },
+ error => {
+ console.log('err' + error)
+ let { message } = error;
+ if (message == "Network Error") {
+ message = "后端接口连接异常";
+ } else if (message.includes("timeout")) {
+ message = "系统接口请求超时";
+ } else if (message.includes("Request failed with status code")) {
+ message = "系统接口" + message.substr(message.length - 3) + "异常";
+ }
+ ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
+ return Promise.reject(error)
+ }
+)
+
+// 通用下载方法
+export function download(url, params, filename, config) {
+ downloadLoadingInstance = ElLoading.service({ text: "正在下载数据,请稍候", background: "rgba(0, 0, 0, 0.7)", })
+ return service.post(url, params, {
+ transformRequest: [(params) => { return tansParams(params) }],
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+ responseType: 'blob',
+ ...config
+ }).then(async (data) => {
+ const isBlob = blobValidate(data);
+ if (isBlob) {
+ const blob = new Blob([data])
+ saveAs(blob, filename)
+ } else {
+ const resText = await data.text();
+ const rspObj = JSON.parse(resText);
+ const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
+ ElMessage.error(errMsg);
+ }
+ downloadLoadingInstance.close();
+ }).catch((r) => {
+ console.error(r)
+ ElMessage.error('下载文件出现错误,请联系管理员!')
+ downloadLoadingInstance.close();
+ })
+}
+
+export default service
diff --git a/openhis-ui-vue3-miniapp/src/utils/scroll-to.js b/openhis-ui-vue3-miniapp/src/utils/scroll-to.js
new file mode 100644
index 00000000..c5d8e04e
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/utils/scroll-to.js
@@ -0,0 +1,58 @@
+Math.easeInOutQuad = function(t, b, c, d) {
+ t /= d / 2
+ if (t < 1) {
+ return c / 2 * t * t + b
+ }
+ t--
+ return -c / 2 * (t * (t - 2) - 1) + b
+}
+
+// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
+var requestAnimFrame = (function() {
+ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) }
+})()
+
+/**
+ * Because it's so fucking difficult to detect the scrolling element, just move them all
+ * @param {number} amount
+ */
+function move(amount) {
+ document.documentElement.scrollTop = amount
+ document.body.parentNode.scrollTop = amount
+ document.body.scrollTop = amount
+}
+
+function position() {
+ return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop
+}
+
+/**
+ * @param {number} to
+ * @param {number} duration
+ * @param {Function} callback
+ */
+export function scrollTo(to, duration, callback) {
+ const start = position()
+ const change = to - start
+ const increment = 20
+ let currentTime = 0
+ duration = (typeof (duration) === 'undefined') ? 500 : duration
+ var animateScroll = function() {
+ // increment the time
+ currentTime += increment
+ // find the value with the quadratic in-out easing function
+ var val = Math.easeInOutQuad(currentTime, start, change, duration)
+ // move the document.body
+ move(val)
+ // do the animation unless its over
+ if (currentTime < duration) {
+ requestAnimFrame(animateScroll)
+ } else {
+ if (callback && typeof (callback) === 'function') {
+ // the animation is done so lets callback
+ callback()
+ }
+ }
+ }
+ animateScroll()
+}
diff --git a/openhis-ui-vue3-miniapp/src/utils/theme.js b/openhis-ui-vue3-miniapp/src/utils/theme.js
new file mode 100644
index 00000000..f4badc67
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/utils/theme.js
@@ -0,0 +1,49 @@
+// 处理主题样式
+export function handleThemeStyle(theme) {
+ document.documentElement.style.setProperty('--el-color-primary', theme)
+ for (let i = 1; i <= 9; i++) {
+ document.documentElement.style.setProperty(`--el-color-primary-light-${i}`, `${getLightColor(theme, i / 10)}`)
+ }
+ for (let i = 1; i <= 9; i++) {
+ document.documentElement.style.setProperty(`--el-color-primary-dark-${i}`, `${getDarkColor(theme, i / 10)}`)
+ }
+}
+
+// hex颜色转rgb颜色
+export function hexToRgb(str) {
+ str = str.replace('#', '')
+ let hexs = str.match(/../g)
+ for (let i = 0; i < 3; i++) {
+ hexs[i] = parseInt(hexs[i], 16)
+ }
+ return hexs
+}
+
+// rgb颜色转Hex颜色
+export function rgbToHex(r, g, b) {
+ let hexs = [r.toString(16), g.toString(16), b.toString(16)]
+ for (let i = 0; i < 3; i++) {
+ if (hexs[i].length == 1) {
+ hexs[i] = `0${hexs[i]}`
+ }
+ }
+ return `#${hexs.join('')}`
+}
+
+// 变浅颜色值
+export function getLightColor(color, level) {
+ let rgb = hexToRgb(color)
+ for (let i = 0; i < 3; i++) {
+ rgb[i] = Math.floor((255 - rgb[i]) * level + rgb[i])
+ }
+ return rgbToHex(rgb[0], rgb[1], rgb[2])
+}
+
+// 变深颜色值
+export function getDarkColor(color, level) {
+ let rgb = hexToRgb(color)
+ for (let i = 0; i < 3; i++) {
+ rgb[i] = Math.floor(rgb[i] * (1 - level))
+ }
+ return rgbToHex(rgb[0], rgb[1], rgb[2])
+}
diff --git a/openhis-ui-vue3-miniapp/src/utils/validate.js b/openhis-ui-vue3-miniapp/src/utils/validate.js
new file mode 100644
index 00000000..702add4b
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/utils/validate.js
@@ -0,0 +1,93 @@
+/**
+ * 判断url是否是http或https
+ * @param {string} path
+ * @returns {Boolean}
+ */
+ export function isHttp(url) {
+ return url.indexOf('http://') !== -1 || url.indexOf('https://') !== -1
+}
+
+/**
+ * 判断path是否为外链
+ * @param {string} path
+ * @returns {Boolean}
+ */
+ export function isExternal(path) {
+ return /^(https?:|mailto:|tel:)/.test(path)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function validUsername(str) {
+ const valid_map = ['admin', 'editor']
+ return valid_map.indexOf(str.trim()) >= 0
+}
+
+/**
+ * @param {string} url
+ * @returns {Boolean}
+ */
+export function validURL(url) {
+ const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
+ return reg.test(url)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function validLowerCase(str) {
+ const reg = /^[a-z]+$/
+ return reg.test(str)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function validUpperCase(str) {
+ const reg = /^[A-Z]+$/
+ return reg.test(str)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function validAlphabets(str) {
+ const reg = /^[A-Za-z]+$/
+ return reg.test(str)
+}
+
+/**
+ * @param {string} email
+ * @returns {Boolean}
+ */
+export function validEmail(email) {
+ const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
+ return reg.test(email)
+}
+
+/**
+ * @param {string} str
+ * @returns {Boolean}
+ */
+export function isString(str) {
+ if (typeof str === 'string' || str instanceof String) {
+ return true
+ }
+ return false
+}
+
+/**
+ * @param {Array} arg
+ * @returns {Boolean}
+ */
+export function isArray(arg) {
+ if (typeof Array.isArray === 'undefined') {
+ return Object.prototype.toString.call(arg) === '[object Array]'
+ }
+ return Array.isArray(arg)
+}
diff --git a/openhis-ui-vue3-miniapp/src/views/basicmanage/organization/components/api.js b/openhis-ui-vue3-miniapp/src/views/basicmanage/organization/components/api.js
new file mode 100644
index 00000000..a6e6a017
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/basicmanage/organization/components/api.js
@@ -0,0 +1,61 @@
+import request from '@/utils/request'
+
+export function getList(queryParams) {
+ return request({
+ url: '/basedatamanage/organization/organization',
+ method: 'get',
+ param: queryParams
+ })
+}
+
+export function addOrganization(data) {
+ return request({
+ url: '/basedatamanage/organization/organization',
+ method: 'post',
+ data: data
+ })
+}
+
+export function updateOrganization(data) {
+ return request({
+ url: '/basedatamanage/organization/organization',
+ method: 'put',
+ data: data
+ })
+}
+
+export function deleteOrganization(param) {
+ return request({
+ url: '/basedatamanage/organization/organization',
+ method: 'delete',
+ params: param
+ })
+}
+
+export function getOrgDetail(id) {
+ return request({
+ url: '/basedatamanage/organization/organization?orgId=' + id,
+ method: 'get',
+ })
+}
+
+export function initOrgTypeOption() {
+ return request({
+ url: '/basedatamanage/organization/init',
+ method: 'get',
+ })
+}
+
+export function disableOrg(id) {
+ return request({
+ url: '/basedatamanage/organization/organization-inactive?orgId=' + id,
+ method: 'put',
+ })
+}
+
+export function enableOrg(id) {
+ return request({
+ url: '/basedatamanage/organization/organization-active?orgId=' + id,
+ method: 'put',
+ })
+}
diff --git a/openhis-ui-vue3-miniapp/src/views/basicmanage/organization/index.vue b/openhis-ui-vue3-miniapp/src/views/basicmanage/organization/index.vue
new file mode 100644
index 00000000..73b45976
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/basicmanage/organization/index.vue
@@ -0,0 +1,296 @@
+
+
+
+
+ 新增
+
+
+
+ 删除
+
+
+
+ 导出
+
+
+ 刷新
+
+
+
+
+
+
+
+
+
+
+ 修改
+ 停用
+ 启用
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/openhis-ui-vue3-miniapp/src/views/basicmanage/supplier/components/supplier.js b/openhis-ui-vue3-miniapp/src/views/basicmanage/supplier/components/supplier.js
new file mode 100644
index 00000000..f09dd41a
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/basicmanage/supplier/components/supplier.js
@@ -0,0 +1,71 @@
+import request from '@/utils/request'
+import { parseStrEmpty } from "@/utils/openhis";
+
+// 查询病种目录列表
+export function getSupplierList(query) {
+ return request({
+ url: '/data-dictionary/supplier/get-supplier-list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询病种目录详细
+export function getSupplierOne(id) {
+ return request({
+ url: '/data-dictionary/supplier/get-supplier-detail/' + parseStrEmpty(id),
+ method: 'get'
+ })
+}
+
+// 新增病种目录
+export function addSupplier(data) {
+ return request({
+ url: '/data-dictionary/supplier/add-supplier',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改病种目录
+export function editSupplier(data) {
+ return request({
+ url: '/data-dictionary/supplier/edit-supplier',
+ method: 'put',
+ data: data
+ })
+}
+
+// // 删除病种目录
+// export function delUser(userId) {
+// return request({
+// url: '/system/user/' + userId,
+// method: 'delete'
+// })
+// }
+
+// 停用病种目录
+export function stopSupplier(ids) {
+ return request({
+ url: '/data-dictionary/supplier/information-stop',
+ method: 'put',
+ data: ids
+ })
+}
+
+// 启用病种目录
+export function startSupplier(ids) {
+ return request({
+ url: '/data-dictionary/supplier/information-start',
+ method: 'put',
+ data: ids
+ })
+}
+
+// 查询厂商类型
+export function getSupplierInit() {
+ return request({
+ url: '/data-dictionary/supplier/information-init',
+ method: 'get'
+ })
+}
diff --git a/openhis-ui-vue3-miniapp/src/views/basicmanage/supplier/index.vue b/openhis-ui-vue3-miniapp/src/views/basicmanage/supplier/index.vue
new file mode 100644
index 00000000..152219d0
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/basicmanage/supplier/index.vue
@@ -0,0 +1,505 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加
+
+
+ 停用
+
+
+ 启用
+
+
+ 查询
+
+
+ 清空条件
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+ 查看
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/openhis-ui-vue3-miniapp/src/views/basicserve/register_fee_item/components/AddDialog.vue b/openhis-ui-vue3-miniapp/src/views/basicserve/register_fee_item/components/AddDialog.vue
new file mode 100644
index 00000000..e69de29b
diff --git a/openhis-ui-vue3-miniapp/src/views/basicserve/register_fee_item/components/api.js b/openhis-ui-vue3-miniapp/src/views/basicserve/register_fee_item/components/api.js
new file mode 100644
index 00000000..e69de29b
diff --git a/openhis-ui-vue3-miniapp/src/views/basicserve/register_fee_item/index.vue b/openhis-ui-vue3-miniapp/src/views/basicserve/register_fee_item/index.vue
new file mode 100644
index 00000000..e69de29b
diff --git a/openhis-ui-vue3-miniapp/src/views/catalog/device/components/device.js b/openhis-ui-vue3-miniapp/src/views/catalog/device/components/device.js
new file mode 100644
index 00000000..879ec8b3
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/catalog/device/components/device.js
@@ -0,0 +1,74 @@
+import request from '@/utils/request'
+import { parseStrEmpty } from "@/utils/openhis";
+
+// 查询器材目录列表
+export function getDeviceList(query) {
+ console.log(query,'aaaaa')
+ return request({
+ url: '/datadictionary/device/information-page',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询器材目录详细
+export function getDeviceOne(id) {
+ return request({
+ url: '/datadictionary/device/information-one/' + parseStrEmpty(id),
+ method: 'get'
+ })
+}
+
+// 新增器材目录
+export function addDevice(data) {
+ return request({
+ url: '/datadictionary/device/information',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改器材目录
+export function editDevice(data) {
+ return request({
+ url: '/datadictionary/device/information',
+ method: 'put',
+ data: data
+ })
+}
+
+// // 删除器材目录
+// export function delUser(userId) {
+// return request({
+// url: '/system/user/' + userId,
+// method: 'delete'
+// })
+// }
+
+// 器材目录分类查询
+export function getDiseaseTreatmentInit() {
+ return request({
+ url: '/datadictionary/device/init',
+ method: 'get'
+ })
+}
+
+// 停用病种目录
+export function stopDevice(ids) {
+ console.log(ids)
+ return request({
+ url: '/datadictionary/device/information-stop',
+ method: 'put',
+ data: ids
+ })
+}
+
+// 启用病种目录
+export function startDevice(ids) {
+ console.log(ids)
+ return request({
+ url: '/datadictionary/device/information-start',
+ method: 'put',
+ data: ids
+ })
+}
\ No newline at end of file
diff --git a/openhis-ui-vue3-miniapp/src/views/catalog/device/components/deviceDialog.vue b/openhis-ui-vue3-miniapp/src/views/catalog/device/components/deviceDialog.vue
new file mode 100644
index 00000000..f4d909e1
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/catalog/device/components/deviceDialog.vue
@@ -0,0 +1,431 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/catalog/device/components/deviceViewDialog.vue b/openhis-ui-vue3-miniapp/src/views/catalog/device/components/deviceViewDialog.vue
new file mode 100644
index 00000000..a0087d0e
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/catalog/device/components/deviceViewDialog.vue
@@ -0,0 +1,357 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/catalog/device/index.vue b/openhis-ui-vue3-miniapp/src/views/catalog/device/index.vue
new file mode 100644
index 00000000..9f3df927
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/catalog/device/index.vue
@@ -0,0 +1,623 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加新项目
+
+
+
+ 停用
+
+
+ 启用
+
+
+ 查询
+
+
+ 导出Excel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+ 查看
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/catalog/diagnosisTreatment/components/diagnosisTreatment.js b/openhis-ui-vue3-miniapp/src/views/catalog/diagnosisTreatment/components/diagnosisTreatment.js
new file mode 100644
index 00000000..d0c3b0e5
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/catalog/diagnosisTreatment/components/diagnosisTreatment.js
@@ -0,0 +1,73 @@
+import request from '@/utils/request'
+import { parseStrEmpty } from "@/utils/openhis";
+
+// 查询诊疗目录列表
+export function getDiagnosisTreatmentList(query) {
+ return request({
+ url: '/datadictionary/diagnosistreatment/information-page',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询诊疗目录详细
+export function getDiagnosisTreatmentOne(id) {
+ return request({
+ url: '/datadictionary/diagnosistreatment/information-one/' + parseStrEmpty(id),
+ method: 'get'
+ })
+}
+
+// 新增诊疗目录
+export function addDiagnosisTreatment(data) {
+ return request({
+ url: '/datadictionary/diagnosistreatment/information',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改诊疗目录
+export function editDiagnosisTreatment(data) {
+ return request({
+ url: '/datadictionary/diagnosistreatment/information',
+ method: 'put',
+ data: data
+ })
+}
+
+// // 删除诊疗目录
+// export function delUser(userId) {
+// return request({
+// url: '/system/user/' + userId,
+// method: 'delete'
+// })
+// }
+
+// 诊疗目录分类查询
+export function getDiseaseTreatmentInit() {
+ return request({
+ url: '/datadictionary/diagnosistreatment/init',
+ method: 'get'
+ })
+}
+
+// 停用诊疗目录
+export function stopDiseaseTreatment(ids) {
+ console.log(ids)
+ return request({
+ url: '/datadictionary/diagnosistreatment/information-stop',
+ method: 'put',
+ data: ids
+ })
+}
+
+// 启用诊疗目录
+export function startDiseaseTreatment(ids) {
+ console.log(ids)
+ return request({
+ url: '/datadictionary/diagnosistreatment/information-start',
+ method: 'put',
+ data: ids
+ })
+}
diff --git a/openhis-ui-vue3-miniapp/src/views/catalog/diagnosisTreatment/components/diagnosisTreatmentDialog.vue b/openhis-ui-vue3-miniapp/src/views/catalog/diagnosisTreatment/components/diagnosisTreatmentDialog.vue
new file mode 100644
index 00000000..8d0aed8d
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/catalog/diagnosisTreatment/components/diagnosisTreatmentDialog.vue
@@ -0,0 +1,292 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/catalog/diagnosisTreatment/components/diagnosisTreatmentViewDialog.vue b/openhis-ui-vue3-miniapp/src/views/catalog/diagnosisTreatment/components/diagnosisTreatmentViewDialog.vue
new file mode 100644
index 00000000..a0087d0e
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/catalog/diagnosisTreatment/components/diagnosisTreatmentViewDialog.vue
@@ -0,0 +1,357 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/catalog/diagnosisTreatment/index.vue b/openhis-ui-vue3-miniapp/src/views/catalog/diagnosisTreatment/index.vue
new file mode 100644
index 00000000..f677ae1f
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/catalog/diagnosisTreatment/index.vue
@@ -0,0 +1,544 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加新项目
+
+
+
+ 停用
+
+
+ 启用
+
+
+ 查询
+
+
+ 导出Excel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+ 查看
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/catalog/disease/components/disease.js b/openhis-ui-vue3-miniapp/src/views/catalog/disease/components/disease.js
new file mode 100644
index 00000000..f23551c2
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/catalog/disease/components/disease.js
@@ -0,0 +1,71 @@
+import request from '@/utils/request'
+import { parseStrEmpty } from "@/utils/openhis";
+
+// 查询病种目录列表
+export function getDiseaseList(query) {
+ return request({
+ url: '/datadictionary/disease/information-page',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询病种目录详细
+export function getDiseaseOne(id) {
+ return request({
+ url: '/datadictionary/disease/information-one/' + parseStrEmpty(id),
+ method: 'get'
+ })
+}
+
+// 新增病种目录
+export function addDisease(data) {
+ return request({
+ url: '/datadictionary/disease/information',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改病种目录
+export function editDisease(data) {
+ return request({
+ url: '/datadictionary/disease/information',
+ method: 'put',
+ data: data
+ })
+}
+
+// // 删除病种目录
+// export function delUser(userId) {
+// return request({
+// url: '/system/user/' + userId,
+// method: 'delete'
+// })
+// }
+
+// 病种目录分类查询
+export function getDiseaseCategory() {
+ return request({
+ url: '/datadictionary/disease/information-init',
+ method: 'get'
+ })
+}
+
+// 停用病种目录
+export function stopDisease(ids) {
+ return request({
+ url: '/datadictionary/disease/information-stop',
+ method: 'put',
+ data: ids
+ })
+}
+
+// 启用病种目录
+export function startDisease(ids) {
+ return request({
+ url: '/datadictionary/disease/information-start',
+ method: 'put',
+ data: ids
+ })
+}
\ No newline at end of file
diff --git a/openhis-ui-vue3-miniapp/src/views/catalog/disease/index.vue b/openhis-ui-vue3-miniapp/src/views/catalog/disease/index.vue
new file mode 100644
index 00000000..529d4552
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/catalog/disease/index.vue
@@ -0,0 +1,539 @@
+
+
+
+
+
+
+
+
+
+
+
+ {{ node.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加新项目
+
+
+
+ 停用
+
+
+ 启用
+
+
+ 查询
+
+
+ 导出Excel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+ 查看
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/openhis-ui-vue3-miniapp/src/views/catalog/medicine/components/medicine.js b/openhis-ui-vue3-miniapp/src/views/catalog/medicine/components/medicine.js
new file mode 100644
index 00000000..c4a3cb0f
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/catalog/medicine/components/medicine.js
@@ -0,0 +1,53 @@
+import request from '@/utils/request'
+import { parseStrEmpty } from "@/utils/openhis";
+
+// 查询药品目录列表
+export function getMedicationList(query) {
+ return request({
+ url: '/datadictionary/medication/information-page',
+ method: 'get',
+ params: query
+ })
+}
+
+// 查询药品目录详细
+export function getMedicationOne(id) {
+ return request({
+ url: '/datadictionary/medication/information-one/' + parseStrEmpty(id),
+ method: 'get'
+ })
+}
+
+// 新增药品目录
+export function addMedication(data) {
+ return request({
+ url: '/datadictionary/medication/information',
+ method: 'post',
+ data: data
+ })
+}
+
+// 修改药品目录
+export function editMedication(data) {
+ return request({
+ url: '/datadictionary/medication/information',
+ method: 'put',
+ data: data
+ })
+}
+
+// 删除药品目录
+export function delUser(userId) {
+ return request({
+ url: '/system/user/' + userId,
+ method: 'delete'
+ })
+}
+
+// 药品目录分类查询
+export function getMedicationCategory() {
+ return request({
+ url: '/datadictionary/medication/information-init',
+ method: 'get'
+ })
+}
diff --git a/openhis-ui-vue3-miniapp/src/views/catalog/medicine/components/medicineDialog.vue b/openhis-ui-vue3-miniapp/src/views/catalog/medicine/components/medicineDialog.vue
new file mode 100644
index 00000000..4fab61bb
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/catalog/medicine/components/medicineDialog.vue
@@ -0,0 +1,629 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/catalog/medicine/components/medicineViewDialog.vue b/openhis-ui-vue3-miniapp/src/views/catalog/medicine/components/medicineViewDialog.vue
new file mode 100644
index 00000000..a0087d0e
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/catalog/medicine/components/medicineViewDialog.vue
@@ -0,0 +1,357 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/catalog/medicine/index.vue b/openhis-ui-vue3-miniapp/src/views/catalog/medicine/index.vue
new file mode 100644
index 00000000..d5539ce5
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/catalog/medicine/index.vue
@@ -0,0 +1,738 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 添加新项目
+
+
+
+ 停用
+
+
+
+ 查询
+
+
+ 导出Excel
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 编辑
+ 查看
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/datadictionary/definition/components/definition.js b/openhis-ui-vue3-miniapp/src/views/datadictionary/definition/components/definition.js
new file mode 100644
index 00000000..3bc24713
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/datadictionary/definition/components/definition.js
@@ -0,0 +1,36 @@
+import request from '@/utils/request'
+
+// 查询费用定价信息列表
+export function listDefinition(query) {
+ return request({
+ url: '/dict-dictionary/definition/item-definition-page',
+ method: 'get',
+ params: query
+ })
+}
+
+// 初始化下拉选
+export function initOption(query) {
+ return request({
+ url: '/dict-dictionary/definition/init',
+ method: 'get',
+ params: query
+ })
+}
+
+// 修改费用定价信息
+export function updateDefinition(data) {
+ return request({
+ url: '/dict-dictionary/definition/item-definition',
+ method: 'put',
+ data: data
+ })
+}
+
+// 修改费用定价信息
+export function getOptions() {
+ return request({
+ url: '/dict-dictionary/definition/status-enum-option',
+ method: 'get',
+ })
+}
\ No newline at end of file
diff --git a/openhis-ui-vue3-miniapp/src/views/datadictionary/definition/components/edit.vue b/openhis-ui-vue3-miniapp/src/views/datadictionary/definition/components/edit.vue
new file mode 100644
index 00000000..19769c3d
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/datadictionary/definition/components/edit.vue
@@ -0,0 +1,220 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/openhis-ui-vue3-miniapp/src/views/datadictionary/definition/index.vue b/openhis-ui-vue3-miniapp/src/views/datadictionary/definition/index.vue
new file mode 100644
index 00000000..879d2202
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/datadictionary/definition/index.vue
@@ -0,0 +1,780 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.itemNo ? scope.row.itemNo : "-" }}
+
+
+
+
+ {{ scope.row.chargeName ? scope.row.chargeName : "-" }}
+
+
+
+
+ {{ scope.row.totalVolume ? scope.row.totalVolume : "-" }}
+
+
+
+
+ {{ scope.row.unitCode ? scope.row.unitCode : "-" }}
+
+
+
+
+ {{ scope.row.partPercent ? thousandNumber(scope.row.partPercent) : "-" }}
+
+
+
+
+ {{
+ scope.row.conditionYbCode ? thousandNumber(scope.row.conditionYbCode) : "-"
+ }}
+
+
+
+
+ {{ scope.row.amount ? thousandNumber(scope.row.amount) : "-" }}
+
+
+
+
+ {{
+ scope.row.partMinUnitCode ? scope.row.partMinUnitCode : "-"
+ }}
+
+
+
+
+ {{
+ scope.row.partConditionPrice
+ ? thousandNumber(scope.row.partConditionPrice)
+ : "-"
+ }}
+
+
+
+
+ {{ scope.row.price ? thousandNumber(scope.row.price) : "-" }}
+
+
+
+
+ {{ scope.row.description ? scope.row.description : "-" }}
+
+
+
+
+ {{ scope.row.updateTime ? moment(scope.row.updateTime).format("YYYY-MM-DD HH:mm:ss") : "-" }}
+
+
+
+
+ {{ scope.row.statusEnumText ? scope.row.statusEnumText : "-" }}
+
+
+
+
+ 修改
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.itemNo ? scope.row.itemNo : "-" }}
+
+
+
+
+ {{ scope.row.chargeName ? scope.row.chargeName : "-" }}
+
+
+
+
+ {{ scope.row.totalVolume ? scope.row.totalVolume : "-" }}
+
+
+
+
+ {{ scope.row.unitCode ? scope.row.unitCode : "-" }}
+
+
+
+
+ {{ scope.row.partPercent ? thousandNumber(scope.row.partPercent) : "-" }}
+
+
+
+
+ {{
+ scope.row.conditionYbCode ? thousandNumber(scope.row.conditionYbCode) : "-"
+ }}
+
+
+
+
+ {{ scope.row.price ? thousandNumber(scope.row.price) : "-" }}
+
+
+
+
+ {{
+ scope.row.partMinUnitCode ? scope.row.partMinUnitCode : "-"
+ }}
+
+
+
+
+ {{
+ scope.row.partConditionPrice
+ ? thousandNumber(scope.row.partConditionPrice)
+ : "-"
+ }}
+
+
+
+
+ {{ scope.row.price ? thousandNumber(scope.row.price) : "-" }}
+
+
+
+
+ {{ scope.row.description ? scope.row.description : "-" }}
+
+
+
+
+ {{ scope.row.updateTime ? moment(scope.row.updateTime).format("YYYY-MM-DD HH:mm:ss") : "-" }}
+
+
+
+
+ {{ scope.row.statusEnumText ? scope.row.statusEnumText : "-" }}
+
+
+
+
+ 修改
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.itemNo ? scope.row.itemNo : "-" }}
+
+
+
+
+ {{ scope.row.chargeName ? scope.row.chargeName : "-" }}
+
+
+
+
+ {{ scope.row.totalVolume ? scope.row.totalVolume : "-" }}
+
+
+
+
+ {{ scope.row.unitCode ? scope.row.unitCode : "-" }}
+
+
+
+
+ {{ scope.row.partPercent ? thousandNumber(scope.row.partPercent) : "-" }}
+
+
+
+
+ {{
+ scope.row.conditionYbCode ? thousandNumber(scope.row.conditionYbCode) : "-"
+ }}
+
+
+
+
+ {{ scope.row.price ? thousandNumber(scope.row.price) : "-" }}
+
+
+
+
+ {{
+ scope.row.partMinUnitCode ? scope.row.partMinUnitCode : "-"
+ }}
+
+
+
+
+ {{
+ scope.row.partConditionPrice
+ ? thousandNumber(scope.row.partConditionPrice)
+ : "-"
+ }}
+
+
+
+
+ {{ scope.row.price ? thousandNumber(scope.row.price) : "-" }}
+
+
+
+
+ {{ scope.row.description ? scope.row.description : "-" }}
+
+
+
+
+ {{ scope.row.updateTime ? moment(scope.row.updateTime).format("YYYY-MM-DD HH:mm:ss") : "-" }}
+
+
+
+
+ {{ scope.row.statusEnumText ? scope.row.statusEnumText : "-" }}
+
+
+
+
+ 修改
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/openhis-ui-vue3-miniapp/src/views/error/401.vue b/openhis-ui-vue3-miniapp/src/views/error/401.vue
new file mode 100644
index 00000000..1ba37922
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/error/401.vue
@@ -0,0 +1,82 @@
+
+
+
+ 返回
+
+
+
+
+ 401错误!
+
+ 您没有访问权限!
+ 对不起,您没有访问权限,请不要进行非法操作!您可以返回主页面
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/error/404.vue b/openhis-ui-vue3-miniapp/src/views/error/404.vue
new file mode 100644
index 00000000..f2053032
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/error/404.vue
@@ -0,0 +1,227 @@
+
+
+
+
+
+
+ 404错误!
+
+
+ {{ message }}
+
+
+ 对不起,您正在寻找的页面不存在。尝试检查URL的错误,然后按浏览器上的刷新按钮或尝试在我们的应用程序中找到其他内容。
+
+
+ 返回首页
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/index.vue b/openhis-ui-vue3-miniapp/src/views/index.vue
new file mode 100644
index 00000000..dd05f8f6
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/index.vue
@@ -0,0 +1,141 @@
+
+
+
+
+ OpenHIS后台管理框架
+
+ 一直想做一款HIS后台管理系统,看了很多优秀的开源项目但是发现没有合适自己的。于是利用空闲休息时间开始自己写一套后台系统。如此有了OpenHIS管理系统,她可以用于所有的Web应用程序,如网站管理后台,网站会员中心,CMS,CRM,OA等等,当然,您也可以对她进行深度定制,以做出更强系统。所有前端后台代码封装过后十分精简易上手,出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。
+
+
+ 当前版本: v{{ version }}
+
+
+ ¥免费开源
+
+
+
+
+
+
+
+ 技术选型
+
+
+
+
+ 后端技术
+
+ - SpringBoot
+ - Spring Security
+ - JWT
+ - MyBatis
+ - Druid
+ - Fastjson
+ - ...
+
+
+
+ 前端技术
+
+ - Vue
+ - Vuex
+ - Element-ui
+ - Axios
+ - Sass
+ - Quill
+ - ...
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/login.vue b/openhis-ui-vue3-miniapp/src/views/login.vue
new file mode 100644
index 00000000..233345e5
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/login.vue
@@ -0,0 +1,227 @@
+
+
+
+ OpenHIS后台管理系统
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
![]()
+
+
+ 记住密码
+
+
+ 登 录
+ 登 录 中...
+
+
+ 立即注册
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/monitor/cache/index.vue b/openhis-ui-vue3-miniapp/src/views/monitor/cache/index.vue
new file mode 100644
index 00000000..f2a53a9d
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/monitor/cache/index.vue
@@ -0,0 +1,132 @@
+
+
+
+
+
+ 基本信息
+
+
+
+
+ Redis版本 |
+ {{ cache.info.redis_version }} |
+ 运行模式 |
+ {{ cache.info.redis_mode == "standalone" ? "单机" : "集群" }} |
+ 端口 |
+ {{ cache.info.tcp_port }} |
+ 客户端数 |
+ {{ cache.info.connected_clients }} |
+
+
+ 运行时间(天) |
+ {{ cache.info.uptime_in_days }} |
+ 使用内存 |
+ {{ cache.info.used_memory_human }} |
+ 使用CPU |
+ {{ parseFloat(cache.info.used_cpu_user_children).toFixed(2) }} |
+ 内存配置 |
+ {{ cache.info.maxmemory_human }} |
+
+
+ AOF是否开启 |
+ {{ cache.info.aof_enabled == "0" ? "否" : "是" }} |
+ RDB是否成功 |
+ {{ cache.info.rdb_last_bgsave_status }} |
+ Key数量 |
+ {{ cache.dbSize }} |
+ 网络入口/出口 |
+ {{ cache.info.instantaneous_input_kbps }}kps/{{cache.info.instantaneous_output_kbps}}kps |
+
+
+
+
+
+
+
+
+
+ 命令统计
+
+
+
+
+
+
+ 内存信息
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/monitor/cache/list.vue b/openhis-ui-vue3-miniapp/src/views/monitor/cache/list.vue
new file mode 100644
index 00000000..1696f3a2
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/monitor/cache/list.vue
@@ -0,0 +1,246 @@
+
+
+
+
+
+
+ 缓存列表
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 键名列表
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 缓存内容
+ 清理全部
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/monitor/druid/index.vue b/openhis-ui-vue3-miniapp/src/views/monitor/druid/index.vue
new file mode 100644
index 00000000..13736ec1
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/monitor/druid/index.vue
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/monitor/job/index.vue b/openhis-ui-vue3-miniapp/src/views/monitor/job/index.vue
new file mode 100644
index 00000000..d378f274
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/monitor/job/index.vue
@@ -0,0 +1,483 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+ 日志
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 调用方法
+
+
+
+ Bean调用示例:ryTask.ryParams('openhis')
+
Class类调用示例:com.openhis.quartz.task.RyTask.ryParams('openhis')
+
参数说明:支持字符串,布尔类型,长整型,浮点型,整型
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 生成表达式
+
+
+
+
+
+
+
+
+
+ {{ dict.label }}
+
+
+
+
+
+
+ 立即执行
+ 执行一次
+ 放弃执行
+
+
+
+
+
+
+ 允许
+ 禁止
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ form.jobId }}
+ {{ form.jobName }}
+
+
+ {{ jobGroupFormat(form) }}
+ {{ form.createTime }}
+
+
+ {{ form.cronExpression }}
+
+
+ {{ parseTime(form.nextValidTime) }}
+
+
+ {{ form.invokeTarget }}
+
+
+
+ 正常
+ 暂停
+
+
+
+
+ 允许
+ 禁止
+
+
+
+
+ 默认策略
+ 立即执行
+ 执行一次
+ 放弃执行
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/monitor/job/log.vue b/openhis-ui-vue3-miniapp/src/views/monitor/job/log.vue
new file mode 100644
index 00000000..48f36267
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/monitor/job/log.vue
@@ -0,0 +1,277 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 删除
+
+
+ 清空
+
+
+ 导出
+
+
+ 关闭
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 详细
+
+
+
+
+
+
+
+
+
+
+
+ {{ form.jobLogId }}
+ {{ form.jobName }}
+
+
+ {{ form.jobGroup }}
+ {{ form.createTime }}
+
+
+ {{ form.invokeTarget }}
+
+
+ {{ form.jobMessage }}
+
+
+
+ 正常
+ 失败
+
+
+
+ {{ form.exceptionInfo }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/monitor/logininfor/index.vue b/openhis-ui-vue3-miniapp/src/views/monitor/logininfor/index.vue
new file mode 100644
index 00000000..bd58a5db
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/monitor/logininfor/index.vue
@@ -0,0 +1,225 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 删除
+
+
+ 清空
+
+
+ 解锁
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.loginTime) }}
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/monitor/online/index.vue b/openhis-ui-vue3-miniapp/src/views/monitor/online/index.vue
new file mode 100644
index 00000000..eb17ebc3
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/monitor/online/index.vue
@@ -0,0 +1,106 @@
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ {{ (pageNum - 1) * pageSize + scope.$index + 1 }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.loginTime) }}
+
+
+
+
+ 强退
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/monitor/operlog/index.vue b/openhis-ui-vue3-miniapp/src/views/monitor/operlog/index.vue
new file mode 100644
index 00000000..cb59a472
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/monitor/operlog/index.vue
@@ -0,0 +1,301 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 删除
+
+
+ 清空
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.operTime) }}
+
+
+
+
+ {{ scope.row.costTime }}毫秒
+
+
+
+
+ 详细
+
+
+
+
+
+
+
+
+
+
+
+ {{ form.title }} / {{ typeFormat(form) }}
+ {{ form.operName }} / {{ form.operIp }} / {{ form.operLocation }}
+
+
+ {{ form.operUrl }}
+ {{ form.requestMethod }}
+
+
+ {{ form.method }}
+
+
+ {{ form.operParam }}
+
+
+ {{ form.jsonResult }}
+
+
+
+ 正常
+ 失败
+
+
+
+ {{ form.costTime }}毫秒
+
+
+ {{ parseTime(form.operTime) }}
+
+
+ {{ form.errorMsg }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/monitor/server/index.vue b/openhis-ui-vue3-miniapp/src/views/monitor/server/index.vue
new file mode 100644
index 00000000..a1178b1a
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/monitor/server/index.vue
@@ -0,0 +1,187 @@
+
+
+
+
+
+ CPU
+
+
+
+
+ 属性 |
+ 值 |
+
+
+
+
+ 核心数 |
+ {{ server.cpu.cpuNum }} |
+
+
+ 用户使用率 |
+ {{ server.cpu.used }}% |
+
+
+ 系统使用率 |
+ {{ server.cpu.sys }}% |
+
+
+ 当前空闲率 |
+ {{ server.cpu.free }}% |
+
+
+
+
+
+
+
+
+
+ 内存
+
+
+
+
+ 属性 |
+ 内存 |
+ JVM |
+
+
+
+
+ 总内存 |
+ {{ server.mem.total }}G |
+ {{ server.jvm.total }}M |
+
+
+ 已用内存 |
+ {{ server.mem.used}}G |
+ {{ server.jvm.used}}M |
+
+
+ 剩余内存 |
+ {{ server.mem.free }}G |
+ {{ server.jvm.free }}M |
+
+
+ 使用率 |
+ {{ server.mem.usage }}% |
+ {{ server.jvm.usage }}% |
+
+
+
+
+
+
+
+
+
+ 服务器信息
+
+
+
+
+ 服务器名称 |
+ {{ server.sys.computerName }} |
+ 操作系统 |
+ {{ server.sys.osName }} |
+
+
+ 服务器IP |
+ {{ server.sys.computerIp }} |
+ 系统架构 |
+ {{ server.sys.osArch }} |
+
+
+
+
+
+
+
+
+
+ Java虚拟机信息
+
+
+
+
+ Java名称 |
+ {{ server.jvm.name }} |
+ Java版本 |
+ {{ server.jvm.version }} |
+
+
+ 启动时间 |
+ {{ server.jvm.startTime }} |
+ 运行时长 |
+ {{ server.jvm.runTime }} |
+
+
+ 安装路径 |
+ {{ server.jvm.home }} |
+
+
+ 项目路径 |
+ {{ server.sys.userDir }} |
+
+
+ 运行参数 |
+ {{ server.jvm.inputArgs }} |
+
+
+
+
+
+
+
+
+
+ 磁盘状态
+
+
+
+
+ 盘符路径 |
+ 文件系统 |
+ 盘符类型 |
+ 总大小 |
+ 可用大小 |
+ 已用大小 |
+ 已用百分比 |
+
+
+
+
+ {{ sysFile.dirName }} |
+ {{ sysFile.sysTypeName }} |
+ {{ sysFile.typeName }} |
+ {{ sysFile.total }} |
+ {{ sysFile.free }} |
+ {{ sysFile.used }} |
+ {{ sysFile.usage }}% |
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/patientManagement/patientManagement/component/api.js b/openhis-ui-vue3-miniapp/src/views/patientManagement/patientManagement/component/api.js
new file mode 100644
index 00000000..6d582fc3
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/patientManagement/patientManagement/component/api.js
@@ -0,0 +1,74 @@
+import request from '@/utils/request'
+
+
+export function listmaritalstatus() {
+ return request({
+ url: '/patientmanage/information/list-maritalstatus',
+ method: 'get',
+ })
+}
+
+export function listoccupationtype() {
+ return request({
+ url: '/patientmanage/information/list-occupationtype',
+ method: 'get',
+ })
+}
+
+export function lisadministrativegender() {
+ return request({
+ url: '/patientmanage/information/list-administrativegender',
+ method: 'get',
+ })
+}
+
+export function listbloodtypeabo() {
+ return request({
+ url: '/patientmanage/information/list-bloodtypeabo',
+ method: 'get',
+ })
+}
+
+
+export function listbloodtypearh() {
+ return request({
+ url: '/patientmanage/information/list-bloodtypearh',
+ method: 'get',
+ })
+}
+
+export function listfamilyrelationshiptype() {
+ return request({
+ url: '/patientmanage/information/list-familyrelationshiptype',
+ method: 'get',
+ })
+ }
+
+// 新增
+export function addPatient(data) {
+ return request({
+ url: '/patientmanage/information/patient-information',
+ method: 'post',
+ data: data
+ })
+}
+
+// 查询菜单列表
+export function listPatient(query) {
+ return request({
+ url: '/patientmanage/information/patient-information-page',
+ method: 'get',
+ params: query
+ })
+ }
+
+ // 修改
+export function updatePatient(data) {
+ return request({
+ url: '/patientmanage/information/patient-information',
+ method: 'put',
+ data: data
+ })
+ }
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/patientManagement/patientManagement/index.vue b/openhis-ui-vue3-miniapp/src/views/patientManagement/patientManagement/index.vue
new file mode 100644
index 00000000..d56c4ded
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/patientManagement/patientManagement/index.vue
@@ -0,0 +1,454 @@
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 添加病人
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 修改
+ 查看
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.info }}
+
+
+
+
+
+
+
+
+ {{ dict.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ data.name }}
+ ({{ data.children.length }})
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/openhis-ui-vue3-miniapp/src/views/redirect/index.vue b/openhis-ui-vue3-miniapp/src/views/redirect/index.vue
new file mode 100644
index 00000000..a469960d
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/redirect/index.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/openhis-ui-vue3-miniapp/src/views/register.vue b/openhis-ui-vue3-miniapp/src/views/register.vue
new file mode 100644
index 00000000..26496611
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/register.vue
@@ -0,0 +1,219 @@
+
+
+
+ OpenHIS后台管理系统
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
![]()
+
+
+
+
+ 注 册
+ 注 册 中...
+
+
+ 使用已有账户登录
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/system/config/index.vue b/openhis-ui-vue3-miniapp/src/views/system/config/index.vue
new file mode 100644
index 00000000..34fd53da
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/system/config/index.vue
@@ -0,0 +1,305 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+ 刷新缓存
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ dict.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/system/dept/index.vue b/openhis-ui-vue3-miniapp/src/views/system/dept/index.vue
new file mode 100644
index 00000000..d073a261
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/system/dept/index.vue
@@ -0,0 +1,274 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 展开/折叠
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 新增
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ dict.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/system/dict/data.vue b/openhis-ui-vue3-miniapp/src/views/system/dict/data.vue
new file mode 100644
index 00000000..84740a2f
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/system/dict/data.vue
@@ -0,0 +1,451 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+
+ 重置
+
+
+
+
+
+
+ 新增
+
+
+
+
+ 修改
+
+
+
+
+ 删除
+
+
+
+
+ 导出
+
+
+
+
+ 关闭
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.dictLabel }}
+
+
+ {{ scope.row.dictLabel }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+
+ 修改
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ dict.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/system/dict/index.vue b/openhis-ui-vue3-miniapp/src/views/system/dict/index.vue
new file mode 100644
index 00000000..297ac84f
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/system/dict/index.vue
@@ -0,0 +1,312 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+ 刷新缓存
+
+
+
+
+
+
+
+
+
+
+
+ {{ scope.row.dictType }}
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ dict.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/system/menu/index.vue b/openhis-ui-vue3-miniapp/src/views/system/menu/index.vue
new file mode 100644
index 00000000..bb486e90
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/system/menu/index.vue
@@ -0,0 +1,427 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 展开/折叠
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 新增
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 目录
+ 菜单
+ 按钮
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 是否外链
+
+
+
+ 是
+ 否
+
+
+
+
+
+
+
+
+
+
+ 路由地址
+
+
+
+
+
+
+
+
+
+
+
+
+ 组件路径
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 权限字符
+
+
+
+
+
+
+
+
+
+
+
+
+ 路由参数
+
+
+
+
+
+
+
+
+
+
+
+ 是否缓存
+
+
+
+ 缓存
+ 不缓存
+
+
+
+
+
+
+
+
+
+
+ 显示状态
+
+
+
+ {{ dict.label }}
+
+
+
+
+
+
+
+
+
+
+ 菜单状态
+
+
+
+ {{ dict.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/system/notice/index.vue b/openhis-ui-vue3-miniapp/src/views/system/notice/index.vue
new file mode 100644
index 00000000..c26b8c40
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/system/notice/index.vue
@@ -0,0 +1,283 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ dict.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/system/post/index.vue b/openhis-ui-vue3-miniapp/src/views/system/post/index.vue
new file mode 100644
index 00000000..6fd1b641
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/system/post/index.vue
@@ -0,0 +1,277 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 修改
+ 删除
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ dict.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/system/role/authUser.vue b/openhis-ui-vue3-miniapp/src/views/system/role/authUser.vue
new file mode 100644
index 00000000..66b5f5e6
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/system/role/authUser.vue
@@ -0,0 +1,172 @@
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 添加用户
+
+
+ 批量取消授权
+
+
+ 关闭
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+ 取消授权
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/system/role/index.vue b/openhis-ui-vue3-miniapp/src/views/system/role/index.vue
new file mode 100644
index 00000000..65c82160
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/system/role/index.vue
@@ -0,0 +1,559 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 权限字符
+
+
+
+
+
+
+
+
+
+ {{ dict.label }}
+
+
+
+ 展开/折叠
+ 全选/全不选
+ 父子联动
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 展开/折叠
+ 全选/全不选
+ 父子联动
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/system/role/selectUser.vue b/openhis-ui-vue3-miniapp/src/views/system/role/selectUser.vue
new file mode 100644
index 00000000..9be1ec96
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/system/role/selectUser.vue
@@ -0,0 +1,140 @@
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/system/user/authRole.vue b/openhis-ui-vue3-miniapp/src/views/system/user/authRole.vue
new file mode 100644
index 00000000..0b5c14bc
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/system/user/authRole.vue
@@ -0,0 +1,112 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ (pageNum - 1) * pageSize + scope.$index + 1 }}
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+
+
+
+
+ 提交
+ 返回
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/system/user/index.vue b/openhis-ui-vue3-miniapp/src/views/system/user/index.vue
new file mode 100644
index 00000000..5cd9936e
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/system/user/index.vue
@@ -0,0 +1,612 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 新增
+
+
+ 修改
+
+
+ 删除
+
+
+ 导入
+
+
+ 导出
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ parseTime(scope.row.createTime) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ dict.label }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 将文件拖到此处,或点击上传
+
+
+
+ 是否更新已经存在的用户数据
+
+
仅允许导入xls、xlsx格式文件。
+
下载模板
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/system/user/profile/index.vue b/openhis-ui-vue3-miniapp/src/views/system/user/profile/index.vue
new file mode 100644
index 00000000..5851f05d
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/system/user/profile/index.vue
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+ 个人信息
+
+
+
+
+
+
+
+ -
+ 用户名称
+
{{ state.user.userName }}
+
+ -
+ 手机号码
+
{{ state.user.phonenumber }}
+
+ -
+ 用户邮箱
+
{{ state.user.email }}
+
+ -
+ 所属部门
+
{{ state.user.dept.deptName }} / {{ state.postGroup }}
+
+ -
+ 所属角色
+
{{ state.roleGroup }}
+
+ -
+ 创建日期
+
{{ state.user.createTime }}
+
+
+
+
+
+
+
+
+
+ 基本资料
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/system/user/profile/resetPwd.vue b/openhis-ui-vue3-miniapp/src/views/system/user/profile/resetPwd.vue
new file mode 100644
index 00000000..96daef39
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/system/user/profile/resetPwd.vue
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ 保存
+ 关闭
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/system/user/profile/userAvatar.vue b/openhis-ui-vue3-miniapp/src/views/system/user/profile/userAvatar.vue
new file mode 100644
index 00000000..3b39636c
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/system/user/profile/userAvatar.vue
@@ -0,0 +1,171 @@
+
+
+
![点击上传头像]()
+
+
+
+
+
+
+
+
![]()
+
+
+
+
+
+
+
+
+ 选择
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 提 交
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/openhis-ui-vue3-miniapp/src/views/system/user/profile/userInfo.vue b/openhis-ui-vue3-miniapp/src/views/system/user/profile/userInfo.vue
new file mode 100644
index 00000000..a5e1c773
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/system/user/profile/userInfo.vue
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 男
+ 女
+
+
+
+ 保存
+ 关闭
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/tool/build/index.vue b/openhis-ui-vue3-miniapp/src/views/tool/build/index.vue
new file mode 100644
index 00000000..c3543a92
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/tool/build/index.vue
@@ -0,0 +1,3 @@
+
+ 表单构建
+
\ No newline at end of file
diff --git a/openhis-ui-vue3-miniapp/src/views/tool/gen/basicInfoForm.vue b/openhis-ui-vue3-miniapp/src/views/tool/gen/basicInfoForm.vue
new file mode 100644
index 00000000..39c85150
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/tool/gen/basicInfoForm.vue
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/tool/gen/createTable.vue b/openhis-ui-vue3-miniapp/src/views/tool/gen/createTable.vue
new file mode 100644
index 00000000..00fdfdb4
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/tool/gen/createTable.vue
@@ -0,0 +1,46 @@
+
+
+
+ 创建表语句(支持多个建表语句):
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/tool/gen/editTable.vue b/openhis-ui-vue3-miniapp/src/views/tool/gen/editTable.vue
new file mode 100644
index 00000000..ddcbfd5b
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/tool/gen/editTable.vue
@@ -0,0 +1,198 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ dict.dictName }}
+ {{ dict.dictType }}
+
+
+
+
+
+
+
+
+
+
+
+
+ 提交
+ 返回
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/tool/gen/genInfoForm.vue b/openhis-ui-vue3-miniapp/src/views/tool/gen/genInfoForm.vue
new file mode 100644
index 00000000..7954aa05
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/tool/gen/genInfoForm.vue
@@ -0,0 +1,297 @@
+
+
+
+
+
+ 生成模板
+
+
+
+
+
+
+
+
+
+
+ 前端类型
+
+
+
+
+
+
+
+
+
+
+ 生成包路径
+
+
+
+
+
+
+
+
+
+
+
+ 生成模块名
+
+
+
+
+
+
+
+
+
+
+
+ 生成业务名
+
+
+
+
+
+
+
+
+
+
+
+ 生成功能名
+
+
+
+
+
+
+
+
+
+
+
+ 生成代码方式
+
+
+
+
+ zip压缩包
+ 自定义路径
+
+
+
+
+
+
+ 上级菜单
+
+
+
+
+
+
+
+
+
+
+
+ 自定义路径
+
+
+
+
+
+
+
+
+ 最近路径快速选择
+
+
+
+
+ 恢复默认的生成基础路径
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 树编码字段
+
+
+
+
+
+
+
+
+
+
+
+
+ 树父编码字段
+
+
+
+
+
+
+
+
+
+
+
+
+ 树名称字段
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 关联子表的表名
+
+
+
+
+
+
+
+
+
+
+
+
+ 子表关联的外键名
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/tool/gen/importTable.vue b/openhis-ui-vue3-miniapp/src/views/tool/gen/importTable.vue
new file mode 100644
index 00000000..33b56337
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/tool/gen/importTable.vue
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/tool/gen/index.vue b/openhis-ui-vue3-miniapp/src/views/tool/gen/index.vue
new file mode 100644
index 00000000..8d2974c1
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/tool/gen/index.vue
@@ -0,0 +1,299 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 搜索
+ 重置
+
+
+
+
+
+ 生成
+
+
+ 创建
+
+
+ 导入
+
+
+ 修改
+
+
+ 删除
+
+
+
+
+
+
+
+
+ {{(queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 复制
+ {{ value }}
+
+
+
+
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/src/views/tool/swagger/index.vue b/openhis-ui-vue3-miniapp/src/views/tool/swagger/index.vue
new file mode 100644
index 00000000..a44fa711
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/src/views/tool/swagger/index.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/openhis-ui-vue3-miniapp/vite.config.js b/openhis-ui-vue3-miniapp/vite.config.js
new file mode 100644
index 00000000..90972361
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/vite.config.js
@@ -0,0 +1,58 @@
+import {defineConfig, loadEnv} from 'vite';
+import path from 'path';
+import createVitePlugins from './vite/plugins';
+
+// https://vitejs.dev/config/
+export default defineConfig (({mode, command}) => {
+ const env = loadEnv (mode, process.cwd ());
+ const {VITE_APP_ENV} = env;
+ return {
+ // 部署生产环境和开发环境下的URL。
+ // 默认情况下,vite 会假设你的应用是被部署在一个域名的根路径上
+ // 例如 https://www.openHIS.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.openhis.vip/admin/,则设置 baseUrl 为 /admin/。
+ base: VITE_APP_ENV === 'production' ? '/' : '/',
+ plugins: createVitePlugins (env, command === 'build'),
+ resolve: {
+ // https://cn.vitejs.dev/config/#resolve-alias
+ alias: {
+ // 设置路径
+ '~': path.resolve (__dirname, './'),
+ // 设置别名
+ '@': path.resolve (__dirname, './src'),
+ },
+ // https://cn.vitejs.dev/config/#resolve-extensions
+ extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
+ },
+ // vite 相关配置
+ server: {
+ port: 81,
+ host: true,
+ open: true,
+ proxy: {
+ // https://cn.vitejs.dev/config/#server-proxy
+ '/dev-api': {
+ target: 'http://localhost:18081/openhis',
+ changeOrigin: true,
+ rewrite: p => p.replace (/^\/dev-api/, ''),
+ },
+ },
+ },
+ //fix:error:stdin>:7356:1: warning: "@charset" must be the first rule in the file
+ css: {
+ postcss: {
+ plugins: [
+ {
+ postcssPlugin: 'internal:charset-removal',
+ AtRule: {
+ charset: atRule => {
+ if (atRule.name === 'charset') {
+ atRule.remove ();
+ }
+ },
+ },
+ },
+ ],
+ },
+ },
+ };
+});
diff --git a/openhis-ui-vue3-miniapp/vite/plugins/auto-import.js b/openhis-ui-vue3-miniapp/vite/plugins/auto-import.js
new file mode 100644
index 00000000..a5d35763
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/vite/plugins/auto-import.js
@@ -0,0 +1,12 @@
+import autoImport from 'unplugin-auto-import/vite'
+
+export default function createAutoImport() {
+ return autoImport({
+ imports: [
+ 'vue',
+ 'vue-router',
+ 'pinia'
+ ],
+ dts: false
+ })
+}
diff --git a/openhis-ui-vue3-miniapp/vite/plugins/compression.js b/openhis-ui-vue3-miniapp/vite/plugins/compression.js
new file mode 100644
index 00000000..96ccd30c
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/vite/plugins/compression.js
@@ -0,0 +1,28 @@
+import compression from 'vite-plugin-compression'
+
+export default function createCompression(env) {
+ const { VITE_BUILD_COMPRESS } = env
+ const plugin = []
+ if (VITE_BUILD_COMPRESS) {
+ const compressList = VITE_BUILD_COMPRESS.split(',')
+ if (compressList.includes('gzip')) {
+ // http://doc.openhisis.vip/openhis-vue/other/faq.html#使用gzip解压缩静态文件
+ plugin.push(
+ compression({
+ ext: '.gz',
+ deleteOriginFile: false
+ })
+ )
+ }
+ if (compressList.includes('brotli')) {
+ plugin.push(
+ compression({
+ ext: '.br',
+ algorithm: 'brotliCompress',
+ deleteOriginFile: false
+ })
+ )
+ }
+ }
+ return plugin
+}
diff --git a/openhis-ui-vue3-miniapp/vite/plugins/index.js b/openhis-ui-vue3-miniapp/vite/plugins/index.js
new file mode 100644
index 00000000..10e17c3d
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/vite/plugins/index.js
@@ -0,0 +1,15 @@
+import vue from '@vitejs/plugin-vue'
+
+import createAutoImport from './auto-import'
+import createSvgIcon from './svg-icon'
+import createCompression from './compression'
+import createSetupExtend from './setup-extend'
+
+export default function createVitePlugins(viteEnv, isBuild = false) {
+ const vitePlugins = [vue()]
+ vitePlugins.push(createAutoImport())
+ vitePlugins.push(createSetupExtend())
+ vitePlugins.push(createSvgIcon(isBuild))
+ isBuild && vitePlugins.push(...createCompression(viteEnv))
+ return vitePlugins
+}
diff --git a/openhis-ui-vue3-miniapp/vite/plugins/setup-extend.js b/openhis-ui-vue3-miniapp/vite/plugins/setup-extend.js
new file mode 100644
index 00000000..ed8342e9
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/vite/plugins/setup-extend.js
@@ -0,0 +1,5 @@
+import setupExtend from 'unplugin-vue-setup-extend-plus/vite'
+
+export default function createSetupExtend() {
+ return setupExtend({})
+}
diff --git a/openhis-ui-vue3-miniapp/vite/plugins/svg-icon.js b/openhis-ui-vue3-miniapp/vite/plugins/svg-icon.js
new file mode 100644
index 00000000..30a4140f
--- /dev/null
+++ b/openhis-ui-vue3-miniapp/vite/plugins/svg-icon.js
@@ -0,0 +1,10 @@
+import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
+import path from 'path'
+
+export default function createSvgIcon(isBuild) {
+ return createSvgIconsPlugin({
+ iconDirs: [path.resolve(process.cwd(), 'src/assets/icons/svg')],
+ symbolId: 'icon-[dir]-[name]',
+ svgoOptions: isBuild
+ })
+}