Ver código fonte

Merge branch 'ysy/v3.0.6'

master
yinsiyu 3 semanas atrás
pai
commit
1576a62a1a
22 arquivos alterados com 2930 adições e 362 exclusões
  1. +4
    -1
      .env.development
  2. +3
    -0
      .env.production
  3. +1813
    -236
      package-lock.json
  4. +6
    -2
      package.json
  5. +7
    -0
      postcss.config.js
  6. BIN
      public/template/therapeuticTemplate.xlsx
  7. +70
    -0
      src/api/dictManage/therapeutic.js
  8. +3
    -0
      src/assets/styles/tailwindcss.css
  9. +29
    -2
      src/config/vxeGrid.js
  10. +1
    -0
      src/layout/components/Sidebar/Logo.vue
  11. +7
    -6
      src/main.js
  12. +38
    -24
      src/router/admin.js
  13. +5
    -1
      src/store/modules/permission.js
  14. +9
    -6
      src/views/dictManage/deptManage/deptList/components/CrudPopup/index.vue
  15. +12
    -10
      src/views/dictManage/diseaseManage/diseaseList/index.vue
  16. +349
    -0
      src/views/dictManage/therapeuticRegimen/list/components/AddTherapeuticDialog.vue
  17. +402
    -0
      src/views/dictManage/therapeuticRegimen/list/index.vue
  18. +78
    -57
      src/views/operationManage/recommendDoctorConfig/components/selectRecommend/index.vue
  19. +10
    -6
      src/views/userManage/staffManage/staffList/components/StaffSelectorPopup/index.vue
  20. +13
    -11
      src/views/userManage/staffManage/staffList/index.vue
  21. +68
    -0
      tailwind.config.js
  22. +3
    -0
      vue.config.js

+ 4
- 1
.env.development Ver arquivo

@@ -5,8 +5,11 @@ VUE_APP_TITLE = 院端内控管理平台

VUE_APP_ADMIN_LOGIN_URL =/hisca/#/sub-login
VUE_APP_ADMIN_HOME_URL = http://localhost:80/#/
VUE_APP_BASE_API = '/base-api'
VUE_APP_BASE_API = '/khcrm-admin/api'
VUE_APP_BASE_PATH = '/sf-admin/'
VUE_APP_SURVEY_PREFIX = /dw
# 路由懒加载
VUE_CLI_BABEL_TRANSPILE_MODULES = true

# 神火医院定制化
VUE_APP_SHEN_HUO_CLIENTID = 2015112716143758

+ 3
- 0
.env.production Ver arquivo

@@ -9,3 +9,6 @@ VUE_APP_BASE_PATH = /sf-admin/
VUE_APP_ADMIN_LOGIN_URL = /hisca/#/sub-login
VUE_APP_ADMIN_HOME_URL = /hisca/
VUE_APP_SURVEY_PREFIX = /dw

# 神火医院定制化
VUE_APP_SHEN_HUO_CLIENTID = 2024060415545011

+ 1813
- 236
package-lock.json
Diferenças do arquivo suprimidas por serem muito extensas
Ver arquivo


+ 6
- 2
package.json Ver arquivo

@@ -5,7 +5,8 @@
"author": "",
"license": "MIT",
"scripts": {
"dev": "vue-cli-service serve",
"dev": "vue-cli-service serve --mode development",
"build:dev": "vue-cli-service build --mode development",
"build": "vue-cli-service build --mode production",
"build:stage": "vue-cli-service build --mode staging",
"preview": "node build/index.js --preview",
@@ -26,11 +27,13 @@
},
"dependencies": {
"@riophae/vue-treeselect": "0.4.0",
"@tailwindcss/postcss7-compat": "^2.2.17",
"await-to-js": "^3.0.0",
"axios": "0.24.0",
"clipboard": "2.0.8",
"core-js": "3.25.3",
"dayjs": "^1.11.11",
"decimal.js": "^10.4.3",
"echarts": "5.4.0",
"element-ui": "2.15.13",
"file-saver": "2.0.5",
@@ -44,6 +47,7 @@
"quill": "1.3.7",
"screenfull": "5.0.2",
"sortablejs": "1.10.2",
"tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.17",
"vue": "2.6.12",
"vue-count-to": "1.0.13",
"vue-cropper": "0.5.5",
@@ -52,7 +56,7 @@
"vuedraggable": "^2.24.3",
"vuex": "3.6.0",
"vuex-persistedstate": "^4.1.0",
"vxe-table": "^3.8.6",
"vxe-table": "~3.8.12",
"xe-utils": "^3.5.27"
},
"devDependencies": {


+ 7
- 0
postcss.config.js Ver arquivo

@@ -0,0 +1,7 @@
// postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
}
}

BIN
public/template/therapeuticTemplate.xlsx Ver arquivo


+ 70
- 0
src/api/dictManage/therapeutic.js Ver arquivo

@@ -0,0 +1,70 @@
import request from "@/utils/request";

const BASE_URL = "/internal/medical-treatment-plan";

/**
* 治疗方案
*/
// 治疗方案列表
export function getTherapeuticListApi(params) {
return request({
url: `${BASE_URL}`,
method: "get",
params,
});
}

// 新增治疗方案
export function addTherapeuticApi(data) {
return request({
url: `${BASE_URL}`,
method: "post",
data,
});
}

// 编辑治疗方案
export function editTherapeuticApi(data) {
return request({
url: `${BASE_URL}`,
method: "put",
data,
});
}

// 批量删除
export function batchDelTherapeuticApi(data) {
return request({
url: `${BASE_URL}`,
method: "delete",
data,
});
}
// 批量导入
export function bathImportTherapeuticApi(file) {
const formData = new FormData();
formData.append("file", file);
return request({
url: `${BASE_URL}/import`,
timeout: 60 * 1000 * 10, // 10分钟
method: "post",
data: formData,
headers: {
"Content-Type": "multipart/form-data",
},
});
}
// 治疗方案详情
export function getTherapeuticApi(id) {
return request({
url: `${BASE_URL}/${id}`,
method: "get",
});
}
// 治疗方案详情
export function delTherapeuticApi(id) {
return request({
url: `${BASE_URL}/${id}`,
method: "delete",
});
}

+ 3
- 0
src/assets/styles/tailwindcss.css Ver arquivo

@@ -0,0 +1,3 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

+ 29
- 2
src/config/vxeGrid.js Ver arquivo

@@ -12,11 +12,38 @@ export const commonGridConfig1 = {
showHeaderOverflow: true,
showOverflow: true,
columnConfig: {
resizable: true
resizable: true,
},
rowConfig: {
isCurrent: true,
isHover: true
isHover: true,
},
pagerConfig: {
pageSize: 10,
pageSizes: [10, 20, 50, 100, 200],
},
};

export const commonGridConfig2 = {
autoResize: true, // 自动监听父元素的变化去重新计算表格
stripe: true,
border: true,
round: false,
size: "medium",
loading: false,
align: "center",
showOverflow: true,
// resizable: true, 替换掉
showHeaderOverflow: true,
showOverflow: true,
headerRowClassName: "vxe-grid-header-default",
layouts: ["Top", "Form", "Toolbar", "Table", "Bottom", "Pager"],
columnConfig: {
resizable: true,
},
rowConfig: {
isCurrent: true,
isHover: true,
},
pagerConfig: {
pageSize: 10,


+ 1
- 0
src/layout/components/Sidebar/Logo.vue Ver arquivo

@@ -90,6 +90,7 @@ export default {
width: 100%;

& .sidebar-logo {
display: inline-block;
width: 32px;
height: 32px;
vertical-align: middle;


+ 7
- 6
src/main.js Ver arquivo

@@ -4,8 +4,8 @@ import Cookies from "js-cookie";

import Element from "element-ui";
import "./assets/styles/element-variables.scss";
import VXETable from 'vxe-table'
import 'vxe-table/lib/style.css'
import VXETable from "vxe-table";
import "vxe-table/lib/style.css";
import "@/assets/styles/index.scss"; // global css
import "@/assets/styles/ruoyi.scss"; // ruoyi css
import App from "./App";
@@ -30,9 +30,10 @@ import Pagination from "@/components/Pagination";
// 字典标签组件
// 头部标签组件
import VueMeta from "vue-meta";
import '@/styles/vxeCommon.scss';
import '@/styles/public.scss';
import registComps from '@/plugins/registComps';
import "@/styles/vxeCommon.scss";
import "@/styles/public.scss";
import "@/assets/styles/tailwindcss.css";
import registComps from "@/plugins/registComps";

// 全局方法挂载
Vue.prototype.parseTime = parseTime;
@@ -45,7 +46,7 @@ Vue.prototype.handleTree = handleTree;

// 全局组件挂载
Vue.component("Pagination", Pagination);
Vue.use(VXETable)
Vue.use(VXETable);
Vue.use(directive);
Vue.use(plugins);
Vue.use(registComps);


+ 38
- 24
src/router/admin.js Ver arquivo

@@ -113,27 +113,41 @@ export const dynamicRoutes = [
},
},
{
name: 'ReminderType',
path: 'reminderType',
name: "TherapeuticRegimen",
path: "therapeuticRegimen",
hidden: false,
component: () => import("@/views/dictManage/therapeuticRegimen/list"),
clientId: [process.env.VUE_APP_SHEN_HUO_CLIENTID], // 只有神火有该权限
meta: {
title: "治疗方案维护",
noCache: false,
link: null,
},
},
{
name: "ReminderType",
path: "reminderType",
hidden: false,
component: () => import("@/views/dictManage/reminderType"),
// permissions: ["820005"],
meta: {
title: '提醒类型维护',
title: "提醒类型维护",
noCache: false,
link: null
}
link: null,
},
},
{
name: 'ReturnType',
path: 'returnType',
name: "ReturnType",
path: "returnType",
hidden: false,
component: () => import("@/views/dictManage/returnType"),
// permissions: ["820006"],
meta: {
title: '回访类型维护',
title: "回访类型维护",
noCache: false,
link: null
}
}
link: null,
},
},
],
},
{
@@ -174,28 +188,28 @@ export const dynamicRoutes = [
],
},
{
name: 'OperationManage',
path: '/operationManage',
name: "OperationManage",
path: "/operationManage",
hidden: false,
component: Layout,
alwaysShow: true,
meta: {
title: '运营管理',
title: "运营管理",
noCache: false,
link: null
link: null,
},
children: [
{
name: 'RecommendDoctorConfig',
path: 'recommendDoctor',
name: "RecommendDoctorConfig",
path: "recommendDoctor",
hidden: false,
component: () => import('@/views/operationManage/recommendDoctorConfig'),
component: () => import("@/views/operationManage/recommendDoctorConfig"),
meta: {
title: '医生推荐配置',
title: "医生推荐配置",
noCache: false,
link: null
}
}
]
}
link: null,
},
},
],
},
];

+ 5
- 1
src/store/modules/permission.js Ver arquivo

@@ -1,5 +1,6 @@
import auth from "@/plugins/auth";
import router, { constantRoutes, dynamicRoutes } from "@/router";
import { getClientId } from "@/utils/auth";
const permission = {
state: {
routes: [],
@@ -45,7 +46,10 @@ export function filterDynamicRoutes(routes) {
...route,
children: route.children ? filterDynamicRoutes(route.children) : [],
};
if (auth.hasPermiOr(temp.permissions)) {
if (
(auth.hasPermiOr(temp.permissions) && !temp.clientId) ||
temp.clientId?.includes(getClientId())
) {
res.push(temp);
}
});


+ 9
- 6
src/views/dictManage/deptManage/deptList/components/CrudPopup/index.vue Ver arquivo

@@ -47,8 +47,8 @@
<script>
import Popup from "@/components/Popup";
import { checkDeptUse } from "@/api/userManage/account";
import { addDept, updateDept, getAllFirstDept } from '@/api/dictManage/dept'
import { getAllHospital } from '@/api/dictManage/hosp'
import { addDept, updateDept, getAllFirstDept } from "@/api/dictManage/dept";
import { getAllHospital } from "@/api/dictManage/hosp";
export default {
components: {
Popup,
@@ -119,8 +119,8 @@ export default {
};
},
open(params) {
if(params && params.parentId === '0') {
params.parentId = undefined
if (params && params.parentId === "0") {
params.parentId = undefined;
}

const defaultValue = {};
@@ -132,7 +132,7 @@ export default {
defaultValue.wardName = params.wardName;
}
this.defaultValue = defaultValue;
this.deptLevel = (params && params.parentId && params.parentId !== '0') ? 2 : 1;
this.deptLevel = params && params.parentId && params.parentId !== "0" ? 2 : 1;
this.$refs.popup.open(params);
this.promise = {};
return new Promise((resolve, reject) => {
@@ -172,7 +172,10 @@ export default {
if (this.form.wardId !== this.defaultValue.wardId) {
await checkDeptUse(this.form.id);
}
await updateDept({ ...this.form, parentId: this.form.parentId === '0' ? undefined : this.form.parentId });
await updateDept({
...this.form,
parentId: this.form.parentId === "0" ? undefined : this.form.parentId,
});
this.$message.success("修改成功");
} else {
const res = await addDept(this.form);


+ 12
- 10
src/views/dictManage/diseaseManage/diseaseList/index.vue Ver arquivo

@@ -20,6 +20,7 @@
:options="deptList"
:autoFetch="false"
:props="{ emitPath: true }"
@change="onChangeDept"
/>
</el-form-item>
<el-form-item label="疾病名称" prop="name">
@@ -108,9 +109,9 @@

<script>
import ImportResultPopup from "@/components/ImportResultPopup";
import { getTreeHospDept } from "@/api/index";
import { diseasePageList, deleteDisease, batchImportDisease } from '@/api/dictManage/disease';
import { getAllHospital } from '@/api/dictManage/hosp';
import { getTreeHospDept } from "@/api/index";
import { diseasePageList, deleteDisease, batchImportDisease } from "@/api/dictManage/disease";
import { getAllHospital } from "@/api/dictManage/hosp";
import CrudPopup from "./components/CrudPopup/index.vue";
import TreeDept from "@/components/TreeDept";

@@ -119,7 +120,7 @@ export default {
components: {
ImportResultPopup,
CrudPopup,
TreeDept
TreeDept,
},

data() {
@@ -139,12 +140,12 @@ export default {
pageSize: 10,
name: "",
wardId: "", // 院区ID
deptId: []
deptId: [],
},
pageList: [],
uploading: false,
wardIdList: [], // 院区列表
deptList: [] // 科室数据
deptList: [], // 科室数据
};
},
created() {
@@ -189,15 +190,16 @@ export default {
},
/*获取科室数据*/
async getDeptList(wardId) {
const res = await getTreeHospDept({ wardId : wardId });
const res = await getTreeHospDept({ wardId: wardId });
this.deptList = res.data || [];
},
getList() {
this.loading = true;
const params = JSON.parse(JSON.stringify(this.queryParams));
params.deptId = params.deptId?.length === 2 ?
params.deptId.slice(-1).toString() :
params.deptId?.length === 1 && params.deptId.slice(-1).toString() || '';
params.deptId =
params.deptId?.length === 2
? params.deptId.slice(-1).toString()
: (params.deptId?.length === 1 && params.deptId.slice(-1).toString()) || "";
diseasePageList(this.addDateRange(params, this.dateRange))
.then((res) => {
const { list, page } = res.data;


+ 349
- 0
src/views/dictManage/therapeuticRegimen/list/components/AddTherapeuticDialog.vue Ver arquivo

@@ -0,0 +1,349 @@
<template>
<vxe-modal type="modal" v-bind="modalConfig" v-model="show" :title="showTitle">
<vxe-form
ref="formRef"
v-bind="formConfig"
:data="formData"
:rules="formRules"
:loading="loadingDetail"
>
<template #dept_f_d="{ data }">
<tree-dept
:disabled="!!id"
v-model="data.deptId"
clearable
class="w-full"
:options="deptOptions"
:props="{ emitPath: false, checkStrictly: true }"
:autoFetch="false"
@change="() => onChangeDept(data)"
></tree-dept>
</template>
<template #a3_f_d="{ data }">
<div class="flex justify-center items-center">
<vxe-input
v-model="data.minPrice"
class="flex-1"
type="float"
:min="0"
:max="9999999.99"
:step="1"
:digits="2"
/>
<span>——</span>
<vxe-input
v-model="data.maxPrice"
class="flex-1"
type="float"
:min="0"
:max="9999999.99"
:step="1"
:digits="2"
/>
</div>
</template>
</vxe-form>
<template #footer>
<div class="flex justify-center">
<vxe-button @click="onCancel">取 消</vxe-button>
<vxe-button status="primary" @click="onSubmit" :loading="isLoading">确 认</vxe-button>
</div>
</template>
</vxe-modal>
</template>
<script>
import TreeDept from "@/components/TreeDept";
import { modalConfigMap } from "@/config/vxeModal";
import { requireReg } from "@/regular";
import { getTreeHospDept } from "@/api/index";
import { getAllHospital } from "@/api/dictManage/hosp";
import { diseasePageList } from "@/api/dictManage/disease";
import {
getTherapeuticApi,
addTherapeuticApi,
editTherapeuticApi,
} from "@/api/dictManage/therapeutic";
import { to } from "await-to-js";
import Decimal from "decimal.js";
export default {
name: "AddTherapeuticDialog",
components: {
TreeDept,
},
props: {
visible: {
type: Boolean,
default: false,
},
id: {
default: () => null,
},
getTableList: {
type: Function,
default: () => {},
},
},
computed: {
show: {
get: function () {
return this.visible;
},
set: function (newValue) {
this.$emit("update:visible", newValue);
},
},
showTitle: function () {
return this.id ? "编辑治疗方案" : "新增治疗方案";
},
},
data() {
const priceValidator = ({ data }) => {
if (!data.minPrice || !data.maxPrice) {
return new Error("请输入价格范围");
}
if (new Decimal(data.minPrice).comparedTo(new Decimal(data.maxPrice)) > 0) {
return new Error("请输入正确的价格范围");
}
};
return {
modalConfig: {
...modalConfigMap.get("default"),
},
formConfig: {
span: 24,
titleAlign: "right",
titleWidth: 120,
titleColon: true,
titleAsterisk: true,
items: [
{
field: "wardId",
title: "所属院区",
itemRender: {
name: "VxeSelect",
props: {
placeholder: "请选择",
filterable: true,
disabled: !!this.id,
},
options: [],
optionProps: {
value: "id",
label: "name",
},
events: {
change: this.onChangeWard,
},
},
},
{
field: "deptId",
title: "所属科室",
slots: {
default: "dept_f_d",
},
},
{
field: "medicalLabelId",
title: "潜在疾病",
itemRender: {
name: "VxeSelect",
props: {
placeholder: "请选择",
filterable: true,
disabled: !!this.id,
},
options: [],
optionProps: {
value: "id",
label: "name",
},
},
},
{
field: "name",
title: "治疗方案",
itemRender: {
name: "VxeInput",
props: {
placeholder: "请输入",
clearable: true,
maxlength: 32,
},
},
},
{
field: "minPrice",
title: "价格区间",
titleAsterisk: true,
slots: {
default: "a3_f_d",
},
},
],
},
formRules: {
wardId: [requireReg("请选择所属院区")],
deptId: [requireReg("请选择所属科室")],
medicalLabelId: [requireReg("请选择潜在疾病")],
name: [requireReg("请输入治疗方案")],
minPrice: [
requireReg("请输入价格范围"),
{
validator: priceValidator,
},
],
},
formData: {
id: undefined,
wardId: null,
deptId: null,
medicalLabelId: null,
name: null,
minPrice: null,
maxPrice: null,
},
deptOptions: [],
isLoading: false,
loadingDetail: false,
};
},
methods: {
async init() {
await this.getDetail();
this.getWardOptions();
this.getDeptOptions();
this.getDiseaseOptions();
},
// 获取详情
async getDetail() {
console.log("this.editId=", this.id);
if (this.id) {
this.loadingDetail = true;
const [err, res] = await to(getTherapeuticApi(this.id));
setTimeout(() => {
this.loadingDetail = false;
}, 500);

if (err) {
return;
}
const { id, wardId, deptId, medicalLabelId, name, minPrice, maxPrice } = res?.data || {};
this.formData = {
id,
wardId,
deptId,
medicalLabelId,
name,
minPrice,
maxPrice,
};
}
},
// 获取院区下拉选项
async getWardOptions() {
const [err, res] = await to(getAllHospital());
await this.$nextTick();
const formItem = this.$refs.formRef.getItems();
console.log("formItem=", formItem);
if (err) {
formItem[0].itemRender.options = [];
return;
}
formItem[0].itemRender.options = res.data;
},
// 切换院区
onChangeWard({ data }) {
console.log("切换院区");
data.deptId = null;
data.medicalLabelId = null;
this.getDeptOptions();
this.getDiseaseOptions();
},
// 获取科室下拉选项
async getDeptOptions() {
const { wardId } = this.formData;
const [err, res] = await to(
getTreeHospDept({
wardId,
})
);
console.log("err=", err);
if (err) {
this.deptOptions = [];
return;
}
this.deptOptions = res.data || [];
},
// 切换科室
onChangeDept(data) {
console.log("切换科室");
// 切换科室
data.medicalLabelId = null;
this.getDiseaseOptions();
},
// 获取疾病选项
async getDiseaseOptions() {
const { wardId, deptId } = this.formData;
const [err, res] = await to(
diseasePageList({
pageNum: 1,
pageSize: 999,
wardId,
deptId,
})
);
await this.$nextTick();
const formItem = this.$refs.formRef.getItems();
console.log("formItem=", formItem);
if (err) {
formItem[2].itemRender.options = [];
return;
}
formItem[2].itemRender.options = res.data?.list;
},
// 提交
async onSubmit() {
await this.$nextTick();
const isNoPass = await this.$refs.formRef.validate();
if (isNoPass) {
return;
}
this.isLoading = true;
const { id, wardId, deptId, medicalLabelId, name, minPrice, maxPrice } = this.formData;
const params = {
id,
wardId,
deptId,
medicalLabelId,
name,
minPrice,
maxPrice,
};
if (this.formData.id) {
const [err, res] = await to(editTherapeuticApi(params));
this.isLoading = false;
if (err) {
return;
}
} else {
const [err, res] = await to(addTherapeuticApi(params));
this.isLoading = false;
if (err) {
return;
}
}
this.show = false;
this.$message.success("操作成功");
this.getTableList();
},
// 取消
onCancel() {
this.show = false;
},
},
created() {
this.init();
},
};
</script>

+ 402
- 0
src/views/dictManage/therapeuticRegimen/list/index.vue Ver arquivo

@@ -0,0 +1,402 @@
<template>
<div class="app-container">
<vxe-grid ref="gridRef" v-bind="gridConfig">
<template #toolbar_button_d="{ $grid }">
<vxe-button status="primary" icon="vxe-icon-add" class="mr-10" @click="onAdd">
新增治疗方案
</vxe-button>
<vxe-button
status="danger"
icon="vxe-icon-delete"
class="mr-10"
:disabled="
!($grid && $grid.getCheckboxRecords && $grid.getCheckboxRecords(true).length > 0)
"
@click="onBatchDel"
>
批量删除
</vxe-button>
<el-upload
ref="upload"
action=""
accept=".xlsx, .csv"
list-type="text"
:multiple="false"
:limit="1"
:show-file-list="false"
:http-request="handleUpload"
auto-upload
>
<vxe-button status="success" icon="vxe-icon-upload" class="mr-10">
批量导入数据
</vxe-button>
</el-upload>
<a :href="exportTemplateUrl" download="批量导入治疗方案模版.xlsx">
<vxe-button status="danger" icon="vxe-icon-download" class="mr-10">
下载数据模板
</vxe-button>
</a>
</template>
<template #dept_f_d="{ data }">
<tree-dept
v-model="data.deptId"
clearable
class="w-240"
:options="deptOptions"
:props="{ emitPath: false, checkStrictly: true }"
placeholder="全部"
@change="() => onChangeDept(data)"
></tree-dept>
</template>
<template #op_t_d="{ row }">
<vxe-button type="text" status="primary" @click="onEdit(row)">编辑</vxe-button>
<vxe-button type="text" status="danger" @click="onDelete(row)">删除</vxe-button>
</template>
</vxe-grid>
<add-therapeutic-dialog
v-if="visible"
:visible.sync="visible"
:id="editId"
:getTableList="getTableList"
/>
<ImportResultPopup ref="importResult" />
</div>
</template>
<script>
import ImportResultPopup from "@/components/ImportResultPopup";
import AddTherapeuticDialog from "./components/AddTherapeuticDialog.vue";
import { commonGridConfig2 } from "@/config/vxeGrid";
import { getAllHospital } from "@/api/dictManage/hosp";
import TreeDept from "@/components/TreeDept";
import { getTreeHospDept } from "@/api/index";
import {
getTherapeuticListApi,
delTherapeuticApi,
batchDelTherapeuticApi,
bathImportTherapeuticApi,
} from "@/api/dictManage/therapeutic";
import { diseasePageList } from "@/api/dictManage/disease";
import { to } from "await-to-js";
export default {
name: "TherapeuticRegimen",
components: {
TreeDept,
AddTherapeuticDialog,
ImportResultPopup,
},
data() {
return {
exportTemplateUrl: process.env.VUE_APP_BASE_PATH + "template/therapeuticTemplate.xlsx",
gridConfig: {
...commonGridConfig2,
keepSource: true,
formConfig: {
data: {
wardId: null,
},
titleColon: true,
titleAlign: "right",
titleWidth: 80,
items: [
{
field: "wardId",
title: "院区",
itemRender: {
name: "VxeSelect",
props: {
placeholder: "全部",
className: "w-240",
clearable: true,
filterable: true,
},
options: [],
optionProps: {
value: "id",
label: "name",
},
events: {
change: this.onChangeWard,
},
},
},
{
field: "deptId",
title: "科室",
itemRender: {},
slots: {
default: "dept_f_d",
},
},
{
field: "medicalLabelId",
title: "潜在疾病",
itemRender: {
name: "VxeSelect",
props: {
placeholder: "全部",
className: "w-240",
clearable: true,
filterable: true,
},
options: [],
optionProps: {
value: "id",
label: "name",
},
},
},
{
field: "name",
title: "治疗方案",
itemRender: {
name: "VxeInput",
props: {
placeholder: "请输入治疗方案",
className: "w-240",
},
},
},
{
itemRender: {
name: "VxeButtonGroup",
options: [
{ type: "submit", content: "搜索", status: "primary" },
{ type: "reset", content: "重置" },
],
},
},
],
},
columns: [
{
type: "checkbox",
width: 60,
},
{
type: "seq",
title: "序号",
minWidth: 100,
},
{
field: "medicalLabelName",
title: "潜在疾病",
minWidth: 200,
},
{
field: "name",
title: "治疗方案名称",
minWidth: 200,
},
{
field: "minPrice",
title: "最低价格",
minWidth: 200,
},
{
field: "maxPrice",
title: "最高价格",
minWidth: 200,
},
{
field: "wardName",
title: "院区",
minWidth: 200,
},
{
field: "level1DeptName",
title: "一级科室",
minWidth: 200,
},
{
field: "level2DeptName",
title: "二级科室",
minWidth: 200,
},
{
field: "operation",
title: "操作",
width: 200,
fixed: "right",
slots: {
default: "op_t_d",
},
},
],
checkboxConfig: {
trigger: "cell",
// reserve: true,
},
rowConfig: {
keyField: "id",
isCurrent: true,
isHover: true,
},
proxyConfig: {
form: true,
response: {
result: "data.list",
total: "data.page.total",
},
ajax: {
query: ({ form, page }) => {
console.log("form=", form);
console.log("page=", page);
const { currentPage: pageNum, pageSize } = page;
console.log("pageNum=", pageNum);
console.log("pageSize=", pageSize);
const params = {
pageNum,
pageSize,
...form,
};
return getTherapeuticListApi(params);
},
},
},
toolbarConfig: {
slots: {
buttons: "toolbar_button_d",
},
},
},
deptOptions: [],
uploading: false,
visible: false,
editId: null,
};
},
methods: {
init() {
this.getWardOptions();
this.getDeptOptions();
this.getDiseaseOptions();
},
// 获取院区下拉选项
async getWardOptions() {
const [err, res] = await to(getAllHospital());
await this.$nextTick();
const formItem = this.$refs.gridRef.getFormItems(0);
console.log("formItem=", formItem);
if (err) {
formItem.itemRender.options = [];
return;
}
formItem.itemRender.options = res.data;
},
// 院区改变
onChangeWard({ data }) {
data.deptId = null;
data.medicalLabelId = null;
const { wardId } = data;
const params = {
wardId,
};
this.getDeptOptions(params);
this.getDiseaseOptions(params);
},
// 获取科室选项
async getDeptOptions(params = {}) {
const [err, res] = await to(
getTreeHospDept({
...params,
})
);
console.log("err=", err);
if (err) {
this.deptOptions = [];
return;
}
this.deptOptions = res.data || [];
},
// 选择科室
onChangeDept(formData) {
formData.medicalLabelId = null;
console.log("deptId=", deptId);
const { wardId, deptId } = formData;
const params = { wardId, deptId };
this.getDiseaseOptions(params);
},
// 获取疾病选项
async getDiseaseOptions(params = {}) {
const [err, res] = await to(
diseasePageList({
pageNum: 1,
pageSize: 999,
...params,
})
);
await this.$nextTick();
const formItem = this.$refs.gridRef.getFormItems(2);
if (err) {
formItem.itemRender.options = [];
return;
}
formItem.itemRender.options = res.data?.list;
},
getTableList() {
this.$nextTick(() => {
this.$refs.gridRef.commitProxy("query");
});
},
onAdd() {
this.editId = null;
this.visible = true;
},
// 编辑
onEdit(row) {
console.log("row=", row);
const { id } = row;
this.editId = id;
this.visible = true;
},
// 删除
onDelete(row) {
this.$modal
.confirm("是否确认删除?")
.then(async () => {
console.log("row.id", row.id);
const [err, _] = await to(delTherapeuticApi(row.id));
this.getTableList();
if (err) {
return;
}
this.$message.success("操作成功");
})
.catch(() => {});
},
// 导入
async handleUpload({ file }) {
this.uploading = true;
try {
const res = await bathImportTherapeuticApi(file);
if (res.data.successSize > 0) {
// 刷新
this.getTableList();
}
this.$refs.importResult.open(res.data);
} finally {
this.$refs.upload.clearFiles();
this.uploading = false;
}
},
// 批量删除
onBatchDel() {
this.$modal.confirm("是否确认批量删除?").then(async () => {
await this.$nextTick();
const checkedData = this.$refs.gridRef.getCheckboxRecords(true);
console.log("checkedData=", checkedData);
const ids = checkedData.map((item) => item.id);
const [err, _] = await to(batchDelTherapeuticApi(ids));
this.getTableList();
if (err) {
return;
}
this.$message.success("操作成功");
});
},
},
mounted() {
this.init();
},
};
</script>

+ 78
- 57
src/views/operationManage/recommendDoctorConfig/components/selectRecommend/index.vue Ver arquivo

@@ -1,15 +1,16 @@
<template>
<el-dialog :visible="visible" title="选择推荐医生" center width="80%" :before-close="onBeforeClose">
<el-dialog
:visible="visible"
title="选择推荐医生"
center
width="80%"
:before-close="onBeforeClose"
>
<el-form size="small" :inline="true">
<el-form-item label="院区">
<el-select v-model="formParams.wardId" filterable clearable @change="onChangeWardId">
<el-option label="全部" value=""></el-option>
<el-option
v-for="item in wardList"
:key="item.id"
:label="item.name"
:value="item.id"
/>
<el-option v-for="item in wardList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="科室">
@@ -32,17 +33,37 @@
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleSearch" :disabled="loading">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="handleReset" :disabled="loading">重置</el-button>
<el-button
type="primary"
icon="el-icon-search"
size="mini"
@click="handleSearch"
:disabled="loading"
>
搜索
</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="handleReset" :disabled="loading">
重置
</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="tableData" border>
<el-table-column align="center" label="院区" prop="wardName" :show-overflow-tooltip="true" />
<el-table-column align="center" label="科室" prop="deptName" :show-overflow-tooltip="true" />
<el-table-column align="center" label="医生姓名" prop="doctorName" :show-overflow-tooltip="true" />
<el-table-column
align="center"
label="医生姓名"
prop="doctorName"
:show-overflow-tooltip="true"
/>
<el-table-column align="center" width="55px">
<template slot-scope="{row}">
<el-radio v-model="selectDoctorId" :label="row.id" :disabled="isDisableCheck(row.id)" @input="(val) => onCheckDoctor(val,row)">
<template slot-scope="{ row }">
<el-radio
v-model="selectDoctorId"
:label="row.id"
:disabled="isDisableCheck(row.id)"
@input="(val) => onCheckDoctor(val, row)"
>
<span></span>
</el-radio>
</template>
@@ -62,15 +83,15 @@
</template>

<script>
import { TableMixin } from '@/mixins/tableMixin'
import { getTreeHospDept } from "@/api/index";
import { staffPageList, } from '@/api/userManage/staff'
import { TableMixin } from "@/mixins/tableMixin";
import { getTreeHospDept } from "@/api/index";
import { staffPageList } from "@/api/userManage/staff";
import { getAllHospital } from "@/api/dictManage/hosp";
import TreeDept from "@/components/TreeDept";
export default {
name: "SelectRecommend",
components: {
TreeDept
TreeDept,
},
mixins: [TableMixin],
props: ["list"],
@@ -79,85 +100,85 @@ export default {
visible: false,
apiMethod: staffPageList,
formParams: {
wardId: '',
deptId: '',
userName: ''
wardId: "",
deptId: "",
userName: "",
},
wardList: [],
deptList: [],
selectDoctorId: null,
selectDoctor: null
selectDoctor: null,
};
},
methods: {
async openDialog(doctor) {
this.handleReset()
this.handleReset();
this.visible = true;
},
async loadWardList() {
const res = await getAllHospital()
this.wardList = res.data || []
const res = await getAllHospital();
this.wardList = res.data || [];
},
isDisableCheck(id) {
return this.list.findIndex(item => item.doctorId === id) >= 0
return this.list.findIndex((item) => item.doctorId === id) >= 0;
},
async getDeptList() {
const res = await getTreeHospDept({
wardId: this.formParams.wardId || undefined
})
this.deptList = res.data || []
wardId: this.formParams.wardId || undefined,
});
this.deptList = res.data || [];
},
onChangeWardId() {
this.formParams.deptId = ''
this.getDeptList()
this.formParams.deptId = "";
this.getDeptList();
},
onCheckDoctor(val, row) {
console.log('val=', val, row)
this.selectDoctor = row
console.log("val=", val, row);
this.selectDoctor = row;
},
async loadOptions() {
await this.loadWardList()
await this.getDeptList()
await this.loadWardList();
await this.getDeptList();
},
paramsCallback() {
const { wardId, deptId, userName } = this.formParams
const { wardId, deptId, userName } = this.formParams;
const params = {
...this.pageable,
wardId,
deptId,
userName
}
return params
userName,
};
return params;
},
handleSearch() {
this.selectDoctorId = null
this.selectDoctor = null
this.onSearch()
this.selectDoctorId = null;
this.selectDoctor = null;
this.onSearch();
},
handleReset() {
this.pageable.pageNum = 1
this.pageable.pageNum = 1;
this.formParams = {
wardId: '',
deptId: '',
userName: ''
}
this.selectDoctorId = null
this.selectDoctor = null
this.onSearch()
wardId: "",
deptId: "",
userName: "",
};
this.selectDoctorId = null;
this.selectDoctor = null;
this.onSearch();
},
onBeforeClose(done) {
this.visible = false
done()
this.visible = false;
done();
},
onSubmit() {
console.log('点击确定')
this.visible = false
this.$emit('onOk', this.selectDoctor)
}
console.log("点击确定");
this.visible = false;
this.$emit("onOk", this.selectDoctor);
},
},
mounted() {
this.loadOptions()
console.log("this.props", this.list)
}
this.loadOptions();
console.log("this.props", this.list);
},
};
</script>

+ 10
- 6
src/views/userManage/staffManage/staffList/components/StaffSelectorPopup/index.vue Ver arquivo

@@ -16,7 +16,7 @@
</el-form-item>
</el-form>
</el-card>
<div class="table" v-loading="loading">
<div v-loading="loading">
<el-table :data="tableList" border class="mt20" row-key="uniqueid">
<el-table-column
align="center"
@@ -32,9 +32,7 @@
<el-table-column align="center" label="操作">
<template slot-scope="scope">
<div v-if="addedIds.includes(scope.row.userId)">
<el-button size="mini" type="text" disabled>
已添加
</el-button>
<el-button size="mini" type="text" disabled>已添加</el-button>
</div>
<el-button
v-else-if="getCheckedStatus(scope.row)"
@@ -70,7 +68,11 @@
<script>
import Popup from "@/components/Popup";
import CrudPopup from "../CrudPopup";
import { getTrustDoctorInfos, batchAddStaff, getAllDoctorIdForClient } from '@/api/userManage/staff'
import {
getTrustDoctorInfos,
batchAddStaff,
getAllDoctorIdForClient,
} from "@/api/userManage/staff";
export default {
components: {
Popup,
@@ -97,7 +99,9 @@ export default {
pageSize: this.pageSize,
})
.then((res) => {
const { data: { list, page } } = res
const {
data: { list, page },
} = res;
this.tableList = list || [];
this.total = page?.total || 0;
})


+ 13
- 11
src/views/userManage/staffManage/staffList/index.vue Ver arquivo

@@ -48,13 +48,12 @@
</el-col>
</el-row>

<el-table v-loading="loading" :data="pageList" border>
<el-table class="w-full" v-loading="loading" :data="pageList" border>
<el-table-column
align="center"
label="序号"
type="index"
:index="(index) => (queryParams.pageNum - 1) * queryParams.pageSize + index + 1"
width="120"
/>
<el-table-column align="center" label="院区" prop="wardName" :show-overflow-tooltip="true" />
<el-table-column
@@ -113,8 +112,8 @@ import StaffSelectorPopup from "./components/StaffSelectorPopup";
import CrudPopup from "./components/CrudPopup";
import TreeDept from "@/components/TreeDept";
import { getTreeHospDept } from "@/api/index";
import { staffPageList, editStaff, delStaff } from '@/api/userManage/staff'
import { getAllHospital } from '@/api/dictManage/hosp'
import { staffPageList, editStaff, delStaff } from "@/api/userManage/staff";
import { getAllHospital } from "@/api/dictManage/hosp";

export default {
name: "StaffManage",
@@ -142,11 +141,11 @@ export default {
roleKey: undefined,
status: "",
wardId: "", // 院区ID
deptId: []
deptId: [],
},
pageList: [],
wardIdList: [], // 院区列表
deptList: [] // 科室数据
deptList: [], // 科室数据
};
},
created() {
@@ -191,19 +190,22 @@ export default {
},
/*获取科室数据*/
async getDeptList(wardId) {
const res = await getTreeHospDept({ wardId : wardId });
const res = await getTreeHospDept({ wardId: wardId });
this.deptList = res.data || [];
},
/** 查询角色列表 */
getList() {
this.loading = true;
const params = JSON.parse(JSON.stringify(this.queryParams));
params.deptId = params.deptId?.length === 2 ?
params.deptId.slice(-1).toString() :
params.deptId?.length === 1 && params.deptId.slice(-1).toString() || '';
params.deptId =
params.deptId?.length === 2
? params.deptId.slice(-1).toString()
: (params.deptId?.length === 1 && params.deptId.slice(-1).toString()) || "";
staffPageList(this.addDateRange(params, this.dateRange))
.then((res) => {
const { data: { list, page } } = res
const {
data: { list, page },
} = res;
this.pageList = list || [];
this.total = page?.total || 0;
})


+ 68
- 0
tailwind.config.js Ver arquivo

@@ -0,0 +1,68 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
//文件路径根据自己项目来定,可能是 ./src/**/*.{js,ts,jsx,tsx}
// purge: ["./app/**/*.{js,jsx,vue}", "./app/index.html"],
purge: ["./src/**/*.{js,ts,jsx,tsx,vue}", "./index.html"],
darkMode: false, // or 'media' or 'class'
theme: {
backgroundColor: (theme) => ({
...theme("colors"),
primary: "#1890ff",
}),
textColor: (theme) => ({
...theme("colors"),
'primary': '#1890ff',
}),
marginBottom: Array.from({ length: 1000 }).reduce((map, _, index) => {
map[index] = `${index}px`;
return map;
}, {}),
fontSize: Array.from({ length: 1000 }).reduce((map, _, index) => {
map[index] = `${index}px`;
return map;
}, {}),
fontWeight: Array.from({ length: 1000 }).reduce((map, _, index) => {
map[index] = `${index}`;
return map;
}, {}),
// 内边距
padding: Array.from({ length: 1000 }).reduce((map, _, index) => {
map[index] = `${index}px`;
return map;
}, {}),
// 外边距
spacing: Array.from({ length: 1000 }).reduce((map, _, index) => {
map[index] = `${index}px`;
return map;
}, {}),
// 圆角
borderRadius: Array.from({ length: 1000 }).reduce((map, _, index) => {
map[index] = `${index}px`;
return map;
}, {}),
extend: {
// 宽度
width: Array.from({ length: 1000 }).reduce((map, _, index) => {
map[index] = `${index}px`;
return map;
}, {}),
// 高度
height: Array.from({ length: 1000 }).reduce((map, _, index) => {
map[index] = `${index}px`;
return map;
}, {}),
// 字体大小
fontSize: Array.from({ length: 100 }).reduce((map, _, index) => {
map[index] = `${index}px`;
return map;
}, {}),
// 行高
lineHeight: Array.from({ length: 1000 }).reduce((map, _, index) => {
map[index] = `${index}px`;
return map;
}, {}),
},
},
variants: {},
plugins: [],
};

+ 3
- 0
vue.config.js Ver arquivo

@@ -55,6 +55,9 @@ module.exports = {
},
css: {
loaderOptions: {
postcss: {
plugins: [require("tailwindcss"), require("autoprefixer")],
},
sass: {
sassOptions: { outputStyle: "expanded" },
},


Carregando…
Cancelar
Salvar