This commit is contained in:
2023-06-07 10:41:59 +08:00
parent e6dfe8008a
commit 575bbc3962
17 changed files with 2129 additions and 737 deletions

View File

@ -24,6 +24,7 @@
"element-plus": "2.1.8",
"file-saver": "2.0.5",
"fuse.js": "6.5.3",
"infinite-select": "^0.0.5",
"js-cookie": "3.0.1",
"js-md5": "^0.7.3",
"jsencrypt": "3.2.1",
@ -38,7 +39,7 @@
"@vue/compiler-sfc": "3.2.36",
"sass": "1.52.1",
"unplugin-auto-import": "0.8.5",
"vite": "2.9.9",
"vite": "2.9.13",
"vite-plugin-compression": "0.5.1",
"vite-plugin-svg-icons": "2.0.1",
"vite-plugin-vue-setup-extend": "0.4.0"

View File

@ -2,51 +2,81 @@ import request from "@/utils/request";
// 实验室列表
export function casLaboratoryList(params) {
return request({
url: "/business/casLaboratory/list",
method: "GET",
params,
});
return request({
url: "/business/casLaboratory/list",
method: "GET",
params,
});
}
// 新增
export function casLaboratoryAdd(data) {
return request({
url: "/business/casLaboratory",
method: "POST",
data,
});
return request({
url: "/business/casLaboratory",
method: "POST",
data,
});
}
// 修改
export function casLaboratoryUpdate(data) {
return request({
url: "/business/casLaboratory",
method: "PUT",
data,
});
return request({
url: "/business/casLaboratory",
method: "PUT",
data,
});
}
// id详情
export function casLaboratoryDetail(id) {
return request({
url: `/business/casLaboratory/${id}`,
method: "GET",
});
return request({
url: `/business/casLaboratory/${id}`,
method: "GET",
});
}
// 删除
export function casLaboratoryDelete(ids) {
return request({
url: `/business/casLaboratory`,
method: "DELETE",
data: {
ids,
},
});
return request({
url: `/business/casLaboratory`,
method: "DELETE",
data: {
ids,
},
});
}
// 导入
export function casLaboratoryImportData(data) {
return request({
url: `/business/casLaboratory/importData`,
method: "POST",
data,
});
return request({
url: `/business/casLaboratory/importData`,
method: "POST",
data,
});
}
// 实验室获取账号
export function getAccount(id) {
return request({
url: `/business/casLaboratory/getAccount/${id}`,
method: "GET",
});
}
// 实验室分配账号
export function allocateAccount(data) {
return request({
url: "/business/casLaboratory/allocateAccount",
method: "post",
data,
});
}
// 实验室重置密码
export function restPassword(id, password) {
return request({
url: `/business/casLaboratory/restPassword/${id}/${password}`,
method: "put",
});
}

View File

@ -0,0 +1,5 @@
.el-popover {
.el-scrollbar {
height: 260px;
}
}

View File

@ -0,0 +1,295 @@
<script setup>
import {nextTick, onMounted, onUnmounted, ref, toRefs, watch, watchEffect,} from "vue";
import InfiniteLoading from "v3-infinite-loading";
import "v3-infinite-loading/lib/style.css";
import {debounce} from "lodash-es"; //required if you're not going to override default slots
import {ElInput, ElPopover, ElScrollbar} from "element-plus";
const props = defineProps({
modelValue: {},
remoteMethod: {
type: Function,
required: true,
},
size: {
type: String,
},
width: {
type: Number,
},
prefixIcon: {type: String},
query: {
type: Object,
required: true,
},
prop: {
type: Object,
required: true,
},
placeholder: {
type: String,
default: "请选择",
},
defaultLabel: {
type: String,
},
});
const {modelValue} = toRefs(props);
const loadKey = ref(0);
const emit = defineEmits(["update:modelValue", "change", "confirm"]);
const showPopOver = ref(false);
const inputRefWhenShowPop = ref();
const placeholderWhenShowPop = ref("");
const placeholderWhenNotShowPop = ref("");
const optionLabelWhenShowPop = ref("");
const optionLabelWhenNotShowPop = ref("");
const echoLabel = ref("");
const options = ref([]);
const page = ref(0);
const initOptions = (keyword) => {
props
.remoteMethod({
[props.query.page]: page.value,
[props.query.size]: 10,
[props.query.searchKey]: keyword,
})
.then((rows) => {
options.value = rows;
});
};
const loadMore = async ($state) => {
page.value++;
props
.remoteMethod({
[props.query.page]: page.value,
[props.query.size]: 10,
[props.query.searchKey]: showPopOver.value
? optionLabelWhenShowPop.value ?? null
: null,
})
.then((rows) => {
options.value.push(...rows);
if (rows.length < 10) {
$state.complete();
} else {
$state.loaded();
}
})
.catch(() => {
$state.error();
});
};
const handleInputClick = () => {
showPopOver.value = true;
placeholderWhenShowPop.value = optionLabelWhenNotShowPop.value;
nextTick(() => {
if (inputRefWhenShowPop.value) {
inputRefWhenShowPop.value.focus();
}
});
};
/**
* 清除选项
*/
const handleClearSeletion = () => {
emit("update:modelValue", null);
};
/**
* 点击选项
* @param option
*/
const selectOption = (option) => {
emit("update:modelValue", option[props.prop.value]);
emit("confirm", option);
/*重新加载选项*/
if (optionLabelWhenShowPop.value) {
page.value = 0;
options.value = [];
loadKey.value++;
}
showPopOver.value = false;
echoLabel.value = option[props.prop.label];
optionLabelWhenShowPop.value = "";
};
/**
* 输入时,搜索选项
* @type {DebouncedFuncLeading<(function(*): void)|*> | DebouncedFunc<(function(*): void)|*>}
*/
const handleInputChange = debounce((value) => {
page.value = 0;
options.value = [];
loadKey.value++;
}, 500);
watchEffect(() => {
if (showPopOver.value) return;
if (modelValue.value) {
console.log(modelValue.value)
optionLabelWhenNotShowPop.value =
options.value.find((el) => el[props.prop.value] === modelValue.value)?.[
props.prop.label
] ??
(echoLabel.value.length ? echoLabel.value : null) ??
props.defaultLabel ??
"...";
} else {
optionLabelWhenNotShowPop.value = "";
placeholderWhenNotShowPop.value = props.placeholder;
}
});
watch(modelValue, (value) => {
emit("change", value);
});
/**
* 点击空白关闭弹出选项列表
* @param event
*/
const handleBodyClick = (event) => {
if (showPopOver.value) {
if (optionLabelWhenShowPop.value) {
page.value = 0;
options.value = [];
loadKey.value++;
}
showPopOver.value = false;
optionLabelWhenShowPop.value = "";
}
};
onMounted(() => {
page.value++;
initOptions();
document.body.addEventListener("click", handleBodyClick);
});
onUnmounted(() => {
document.body.removeEventListener("click", handleBodyClick);
});
</script>
<template>
<el-popover
:popper-style="{
padding: 0,
}"
:visible="showPopOver"
:width="width ?? 240"
placement="bottom"
>
<template #reference>
<div :style="`width: ${width ?? 240}px`">
<!--选项显示时-->
<el-input
v-if="showPopOver"
ref="inputRefWhenShowPop"
v-model="optionLabelWhenShowPop"
:placeholder="placeholderWhenShowPop"
:prefix-icon="prefixIcon"
:size="size ?? 'default'"
class="select-inner"
suffix-icon="ArrowUp"
@input="handleInputChange"
@click.stop
>
<template #prefix>
<slot name="prefix"/>
</template>
</el-input>
<!--选项隐藏时-->
<el-input
v-else
v-model="optionLabelWhenNotShowPop"
:placeholder="placeholderWhenNotShowPop"
:prefix-icon="prefixIcon"
:size="size ?? 'default'"
class="select-inner"
clearable
suffix-icon="ArrowDown"
@clear="handleClearSeletion"
@click.stop="handleInputClick"
>
<!-- @blur="handleInputBlur"-->
<template #prefix>
<slot name="prefix"/>
</template>
</el-input>
</div>
</template>
<el-scrollbar :height="260" class="options-wrap" @click.stop>
<ul class="options">
<li
v-for="option in options"
:key="option[prop.value]"
:class="`option-item ${
option[prop.value] === modelValue ? 'selected' : null
}`"
@click.stop="selectOption(option)"
>
{{ option[prop.label] }}
</li>
</ul>
<infinite-loading :identifier="loadKey" @infinite="loadMore">
<template #spinner>
<div style="text-align: center; font-size: 12px">......</div>
</template>
<template #complete>
<div
style="display: flex; justify-content: center; align-items: center"
>
-
</div>
</template>
</infinite-loading>
</el-scrollbar>
</el-popover>
</template>
<style lang="scss" scoped>
.options-wrap {
margin: 6px 0;
.options {
list-style: none;
margin: 0;
padding: 0;
.option-item {
height: 32px;
cursor: pointer;
font-size: 14px;
display: flex;
align-items: center;
padding: 0 32px 0 20px;
font-weight: 700;
width: 238px;
//width: 200px; /* 设置容器的宽度 */
overflow: hidden; /* 隐藏超出容器的文本 */
white-space: nowrap; /* 将文本强制为一行 */
text-overflow: ellipsis; /* 显示省略号 */
&.selected {
color: #409eff;
}
&:hover {
background-color: #f5f7fa;
}
}
}
}
.select-inner {
cursor: pointer;
}
</style>

View File

@ -2,12 +2,12 @@
<div class="app-container">
<div style="width: 50%">
<expert-form
:isAdd="false"
v-model="form"
:showTitle="true"
:formType="formType"
:labelWidth="140"
ref="expertFormRef"
ref="expertFormRef"
v-model="form"
:formType="formType"
:isAdd="false"
:labelWidth="140"
:showTitle="true"
/>
</div>
@ -19,17 +19,13 @@
</div>
</template>
<script setup name="EnterpriseAdd">
<script name="EnterpriseAdd" setup>
import ExpertForm from "@/views/components/ExpertForm/index.vue";
import tab from "@/plugins/tab";
import {
companyAdd,
companyDetail,
companyEdit,
} from "@/api/dataList/enterprise";
import { reactive, toRefs } from "vue";
import { useRoute, useRouter } from "vue-router";
import { ElMessage } from "element-plus";
import {companyDetail, companyEdit,} from "@/api/dataList/enterprise";
import {reactive, toRefs} from "vue";
import {useRoute, useRouter} from "vue-router";
import {ElMessage} from "element-plus";
import useUserStore from "@/store/modules/user";
// const testCount = () => {
@ -63,35 +59,22 @@ const data = reactive({
},
});
const { form } = toRefs(data);
const {form} = toRefs(data);
const cancel = () => {
router.back();
tab.closeOpenPage();
};
const submitForm = async (state) => {
// const valid = await expertFormRef.value.validateForm();
// if (valid) {
// if (form.value.id != undefined) {
form.value.examineStatus = state;
await companyEdit(form.value);
await companyEdit({id: form.value.id, examineStatus: state});
useUserStore().getUnApprovedBusiness();
cancel();
ElMessage.success("已审核");
// } else {
// await companyAdd(form.value);
// useUserStore().getApprovalCount();
// cancel();
// ElMessage.success("新增成功");
// }
// } else {
// console.log("校验未通过");
// }
};
const getDetailById = async () => {
if (route.query.id) {
const { data } = await companyDetail(route.query.id);
const {data} = await companyDetail(route.query.id);
form.value = data;
}
};

View File

@ -1,20 +1,19 @@
<template>
<el-form
ref="formRef"
:model="modelValue"
:rules="rules"
:disabled="!isAdd"
:label-width="labelWidth + 'px'"
ref="formRef"
:label-width="labelWidth + 'px'"
:model="modelValue"
:rules="rules"
>
<div class="form_title" v-if="showTitle">基本信息</div>
<div v-if="showTitle" class="form_title">基本信息</div>
<el-row>
<el-col :span="24">
<el-form-item :label="imageName" prop="image">
<ImageUpload
:disabled="!isAdd"
v-model="modelValue.image"
:fileSize="2"
:limit="1"
v-model="modelValue.image"
:fileSize="2"
:limit="1"
/>
</el-form-item>
</el-col>
@ -24,8 +23,8 @@
<el-col :span="24">
<el-form-item :label="nameName" prop="name">
<el-input
v-model="modelValue.name"
:disabled="isAdd ? false : true"
v-model="modelValue.name"
:disabled="isAdd ? false : true"
></el-input>
</el-form-item>
</el-col>
@ -36,10 +35,10 @@
<el-form-item label="组织机构代码:" prop="code">
<el-row type="flex" justify="space-between">
<el-col :span="20">
<el-input v-model="modelValue.code" :disabled="!isAdd"></el-input>
<el-input v-model="modelValue.code" ></el-input>
</el-col>
<el-col :span="3">
<el-button type="primary" @click="" :disabled="!isAdd"
<el-button type="primary" @click=""
>查找</el-button
>
</el-col>
@ -59,9 +58,9 @@
<el-col :span="24">
<el-form-item label="联系方式" prop="phone">
<el-input
v-model="modelValue.phone"
:maxlength="11"
oninput="
v-model="modelValue.phone"
:maxlength="11"
oninput="
value = value
.replace(/[^\d.]/g, '')
.replace(/\.{2,}/g, '.')
@ -89,10 +88,10 @@
<el-form-item label="企业类型:" prop="kind">
<el-select v-model="modelValue.kind" placeholder="请选择">
<el-option
v-for="item in enterpriseOptions"
:key="item.key"
:label="item.value"
:value="item.key"
v-for="item in enterpriseOptions"
:key="item.key"
:label="item.value"
:value="item.key"
>
</el-option>
</el-select>
@ -109,16 +108,16 @@
<el-col :span="12">
<el-form-item label="姓名:" prop="name">
<el-input
v-model="modelValue.name"
:disabled="isAdd ? false : true"
v-model="modelValue.name"
:disabled="isAdd ? false : true"
></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="手机号:" prop="mobile">
<el-input
v-model="modelValue.mobile"
:disabled="isAdd ? false : true"
v-model="modelValue.mobile"
:disabled="isAdd ? false : true"
></el-input>
</el-form-item>
</el-col>
@ -132,49 +131,39 @@
</el-col>
</el-row> -->
<!-- <el-row v-if="formType == 1">
<el-col :span="12">
<el-form-item label="所属单位:" prop="researchId">
<el-select
v-model="modelValue.researchId"
filterable
placeholder="请选择"
@change="setLaboratory"
>
<el-option
v-for="item in researchOptions"
:key="item.id"
:label="item.name"
:value="item.id"
>
</el-option>
</el-select>
</el-form-item>
</el-col>
<el-row v-if="formType == 1">
<!-- <el-col :span="12">-->
<!-- <el-form-item label="所属单位:" prop="researchId">-->
<!-- <el-select-->
<!-- v-model="modelValue.researchId"-->
<!-- filterable-->
<!-- placeholder="请选择"-->
<!-- @change="setLaboratory"-->
<!-- >-->
<!-- <el-option-->
<!-- v-for="item in researchOptions"-->
<!-- :key="item.id"-->
<!-- :label="item.name"-->
<!-- :value="item.id"-->
<!-- >-->
<!-- </el-option>-->
<!-- </el-select>-->
<!-- </el-form-item>-->
<!-- </el-col>-->
<el-col :span="12">
<el-form-item label="所属实验室:">
<el-select
v-model="modelValue.laboratory_id"
filterable
placeholder="请选择"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
<infinite-select v-model="modelValue.laboratoryId" :prop="{label:'name',value:'id',}" :query="{page:'pageNum',size:'pageSize',searchKey:'name'}"
:remote-method="loadLabOptions"
class="infinite-select" prefix-icon="pointer"/>
</el-form-item>
</el-col>
</el-row> -->
</el-row>
<CityOptions
:disabled="!isAdd"
v-model="modelValue"
:labelWidth="labelWidth"
ref="cityFormRef"
ref="cityFormRef"
v-model="modelValue"
:labelWidth="labelWidth"
/>
<el-row>
@ -202,10 +191,10 @@
<el-col :span="12">
<el-form-item label="最高学历:" prop="education">
<el-select v-model="modelValue.education" placeholder="请选择">
<el-option value="博士" label="博士"> </el-option>
<el-option value="硕士" label="硕士"> </el-option>
<el-option value="本科" label="本科"> </el-option>
<el-option value="专科" label="专科"> </el-option>
<el-option label="博士" value="博士"></el-option>
<el-option label="硕士" value="硕士"></el-option>
<el-option label="本科" value="本科"></el-option>
<el-option label="专科" value="专科"></el-option>
</el-select>
</el-form-item>
</el-col>
@ -233,11 +222,11 @@
<el-col :span="12">
<el-form-item label="从业时间:" prop="workTime">
<el-date-picker
v-model="modelValue.workTime"
type="month"
format="YYYY-MM"
value-format="YYYY-MM"
placeholder="选择日期"
v-model="modelValue.workTime"
format="YYYY-MM"
placeholder="选择日期"
type="month"
value-format="YYYY-MM"
>
</el-date-picker>
</el-form-item>
@ -251,30 +240,30 @@
</el-row>
<FieldOptions
:disabled="!isAdd"
v-model="modelValue"
:labelWidth="labelWidth"
ref="fieldFormRef"
ref="fieldFormRef"
v-model="modelValue"
:labelWidth="labelWidth"
/>
<InputBoxAdd
:disabled="!isAdd"
:labelWidth="labelWidth"
v-model="modelValue"
title="关键词"
placeholder="应用场景关键词+技术产品关键词"
fieldKey="keywords"
ref="keywordsFormRef"
ref="keywordsFormRef"
v-model="modelValue"
:labelWidth="labelWidth"
fieldKey="keywords"
placeholder="应用场景关键词+技术产品关键词"
title="关键词"
/>
<InputBoxAdd
v-if="formType != 2"
:labelWidth="labelWidth"
v-model="modelValue"
title="研究方向"
placeholder="请输入研究方向"
fieldKey="researchs"
ref="researchsFormRef"
v-if="formType != 2"
ref="researchsFormRef"
v-model="modelValue"
:labelWidth="labelWidth"
fieldKey="researchs"
placeholder="请输入研究方向"
title="研究方向"
/>
<!-- <InputBoxAdd
@ -282,7 +271,7 @@
:labelWidth="labelWidth"
v-model="modelValue"
title="生产方向"
:disabled="!isAdd"
placeholder="请输入生产方向"
fieldKey="directions"
ref="directionsFormRef"
@ -293,7 +282,7 @@
<el-form-item label="邀请码:">
<el-input
v-model="modelValue.inviterCode"
:disabled="!isAdd"
></el-input>
</el-form-item>
</el-col> -->
@ -308,9 +297,9 @@
<el-col :span="24">
<el-form-item label="营业执照:" prop="license">
<ImageUpload
v-model="modelValue.license"
:isShowTip="false"
:limit="1"
v-model="modelValue.license"
:isShowTip="false"
:limit="1"
/>
</el-form-item>
</el-col>
@ -326,9 +315,8 @@
/> -->
<!-- v-else -->
<WangEditor
:readOnly="!isAdd"
v-model="modelValue.introduce"
minHeight="150px"
v-model="modelValue.introduce"
minHeight="150px"
/>
<!-- <Editor
v-else
@ -342,21 +330,24 @@
</el-row>
</el-form>
</template>
<script setup name="ExpertForm">
<script name="ExpertForm" setup>
import CityOptions from "@/views/components/CityOptions";
// import FieldOptions from "@/views/components/FieldOptions";
import InputBoxAdd from "@/views/components/InputBoxAdd";
// import { researchSelect } from "@/api/dataList/research";
// import { laboratorySelect } from "@/api/dataList/laboratory";
import { tenantSelect } from "@/api/subPlatform/tenant";
import { enterpriseOptions } from "@/utils/parameter";
import { reactive, ref, toRefs } from "vue";
import {tenantSelect} from "@/api/subPlatform/tenant";
import {enterpriseOptions} from "@/utils/parameter";
import {reactive, ref, toRefs} from "vue";
import WangEditor from "@/components/WangEditor/index.vue";
// import SiteOptions from "@/views/components/SiteOptions";
import FieldOptions from "@/views/components/FieldOptions";
import {casLaboratoryList} from "@/api/dataList/laboratory";
import InfiniteSelect from '@/components/InfiniteSelect'
const props = defineProps({
modelValue: { type: Object },
modelValue: {type: Object},
isAdd: {
type: Boolean,
default: true,
@ -374,7 +365,7 @@ const props = defineProps({
default: 120,
},
});
const { formType, modelValue, labelWidth, showTitle, isAdd } = toRefs(props);
const {formType, modelValue, labelWidth, showTitle, isAdd} = toRefs(props);
const cityFormRef = ref(null);
const formRef = ref(null);
const keywordsFormRef = ref(null);
@ -386,10 +377,10 @@ const options = ref([]);
const siteList = ref([]);
const data = reactive({
rules: {
product: [{ required: true, message: "请输入", trigger: "blur" }],
name: [{ required: true, message: "请输入", trigger: "blur" }],
kind: [{ required: true, message: "请选择", trigger: "change" }],
code: [{ required: true, message: "请输入", trigger: "blur" }],
product: [{required: true, message: "请输入", trigger: "blur"}],
name: [{required: true, message: "请输入", trigger: "blur"}],
kind: [{required: true, message: "请选择", trigger: "change"}],
code: [{required: true, message: "请输入", trigger: "blur"}],
// mobile: [
// { required: true, message: "请输入", trigger: "blur" },
// {
@ -398,7 +389,7 @@ const data = reactive({
// trigger: "blur",
// },
// ],
researchId: [{ message: "请选择", trigger: "change" }],
researchId: [{message: "请选择", trigger: "change"}],
tenantId: [
{
required: true,
@ -406,12 +397,12 @@ const data = reactive({
trigger: ["blur", "change"],
},
],
school: [{ required: true, message: "请输入", trigger: "blur" }],
organization: [{ required: true, message: "请输入", trigger: "blur" }],
education: [{ message: "请选择", trigger: "change" }],
school: [{required: true, message: "请输入", trigger: "blur"}],
organization: [{required: true, message: "请输入", trigger: "blur"}],
education: [{message: "请选择", trigger: "change"}],
// major: [{ required: true, message: "请输入", trigger: "blur" }],
// job: [{ required: true, message: "请输入", trigger: "blur" }],
title: [{ required: true, message: "请输入", trigger: "blur" }],
title: [{required: true, message: "请输入", trigger: "blur"}],
workTime: [
{
required: true,
@ -426,10 +417,10 @@ const data = reactive({
trigger: ["blur", "change"],
},
],
introduce: [{ required: true, message: "请输入", trigger: "blur" }],
introduce: [{required: true, message: "请输入", trigger: "blur"}],
},
});
const { rules } = toRefs(data);
const {rules} = toRefs(data);
const introduceName = computed(() => {
if (formType.value === 1) {
return "个人简介:";
@ -475,9 +466,9 @@ const validateForm = async () => {
//企业
// const directionsFormValid = await directionsFormRef.value.validateForm(); //生产方向验证
return (
formValid && cityFormValid && fieldFormValid
// keywordsFormValid &&
// directionsFormValid
formValid && cityFormValid && fieldFormValid
// keywordsFormValid &&
// directionsFormValid
);
} else {
throw "未知的formType";
@ -489,6 +480,8 @@ const getSiteList = async () => {
const resp = await tenantSelect();
siteList.value = resp.rows;
};
const loadLabOptions = (query) => casLaboratoryList({...query, examineStatus: "1"}).then(resp => resp.rows)
getSiteList();
defineExpose({
validateForm,
@ -545,4 +538,6 @@ export default {
font-weight: 700;
margin-bottom: 30px;
}
</style>

View File

@ -1,18 +1,18 @@
<template>
<el-form
ref="formRef"
:model="modelValue"
:rules="rules"
:label-width="labelWidth + 'px'"
ref="formRef"
:label-width="labelWidth + 'px'"
:model="modelValue"
:rules="rules"
>
<div class="form_title" v-if="showTitle">基本信息</div>
<div v-if="showTitle" class="form_title">基本信息</div>
<el-row>
<el-col :span="24">
<el-form-item label="实验室名称" prop="name">
<el-input
v-model="modelValue.name"
placeholder="请输入实验室全称"
:disabled="!isAdd"
v-model="modelValue.name"
:disabled="!isAdd"
placeholder="请输入实验室全称"
></el-input>
</el-form-item>
</el-col>
@ -22,8 +22,8 @@
<el-col :span="24">
<el-form-item label="所属单院所或高校:" prop="school">
<el-input
v-model="modelValue.school"
placeholder="请输入所属单院所或高校"
v-model="modelValue.school"
placeholder="请输入所属单院所或高校"
></el-input>
<!-- <el-option
v-for="item in researchOptions"
@ -53,17 +53,17 @@
<el-col :span="24">
<el-form-item label="实验室网站:">
<el-input
v-model="modelValue.url"
placeholder="请输入实验室网站"
v-model="modelValue.url"
placeholder="请输入实验室网站"
></el-input>
</el-form-item>
</el-col>
</el-row>
<FieldOptions
v-model="modelValue"
:labelWidth="labelWidth"
ref="fieldFormRef"
ref="fieldFormRef"
v-model="modelValue"
:labelWidth="labelWidth"
/>
<!-- <FieldSingle
@ -74,73 +74,85 @@
/> -->
<InputBoxAdd
:labelWidth="labelWidth"
v-model="modelValue"
title="关键词"
placeholder="应用场景关键词+技术产品关键词"
fieldKey="keywords"
ref="keywordsFormRef"
ref="keywordsFormRef"
v-model="modelValue"
:labelWidth="labelWidth"
fieldKey="keywords"
placeholder="应用场景关键词+技术产品关键词"
title="关键词"
/>
<!-- <InputBoxAdd
:labelWidth="labelWidth"
v-model="modelValue"
title="研究方向"
placeholder="请输入研究方向"
fieldKey="researchs"
ref="directionsForm"
/> -->
<el-row>
<el-col :span="24">
<el-form-item label="研究方向" prop="researchDirection">
<el-input
v-model="modelValue.researchDirection"
type="textarea"
:autosize="{ minRows: 4 }"
placeholder="请输入研究方向"
></el-input> </el-form-item></el-col
></el-row>
<InputBoxAdd
ref="directionsFormRef"
v-model="modelValue"
:labelWidth="labelWidth"
fieldKey="researchs"
placeholder="请输入研究方向"
title="研究方向"
/>
<!-- <el-row>-->
<!-- <el-col :span="24">-->
<!-- <el-form-item label="研究方向" prop="researchDirection">-->
<!-- <el-input-->
<!-- v-model="modelValue.researchDirection"-->
<!-- type="textarea"-->
<!-- :autosize="{ minRows: 4 }"-->
<!-- placeholder="请输入研究方向"-->
<!-- ></el-input> </el-form-item></el-col-->
<!-- ></el-row>-->
<el-row>
<el-col :span="24">
<el-form-item label="主要技术应用场景" prop="primaryTechnology">
<el-input
v-model="modelValue.primaryTechnology"
type="textarea"
:autosize="{ minRows: 4 }"
placeholder="请输入主要技术应用场景"
></el-input> </el-form-item></el-col
></el-row>
v-model="modelValue.primaryTechnology"
:autosize="{ minRows: 4 }"
placeholder="请输入主要技术应用场景"
type="textarea"
></el-input>
</el-form-item>
</el-col
>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="承担科研项目情况" prop="researchProject">
<el-input
v-model="modelValue.researchProject"
type="textarea"
:autosize="{ minRows: 4 }"
placeholder="请输入承担科研项目情况"
></el-input> </el-form-item></el-col
></el-row>
v-model="modelValue.researchProject"
:autosize="{ minRows: 4 }"
placeholder="请输入承担科研项目情况"
type="textarea"
></el-input>
</el-form-item>
</el-col
>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="代表性科技成果" prop="achievement">
<el-input
v-model="modelValue.achievement"
type="textarea"
:autosize="{ minRows: 4 }"
placeholder="请输入代表性科技成果"
></el-input> </el-form-item></el-col
></el-row>
v-model="modelValue.achievement"
:autosize="{ minRows: 4 }"
placeholder="请输入代表性科技成果"
type="textarea"
></el-input>
</el-form-item>
</el-col
>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="联系电话" prop="phone">
<el-input
v-model="modelValue.phone"
maxlength="11"
oninput="value = value.replace(/[\D]+/, '')"
placeholder="请输入联系电话"
></el-input> </el-form-item></el-col
></el-row>
v-model="modelValue.phone"
maxlength="11"
oninput="value = value.replace(/[\D]+/, '')"
placeholder="请输入联系电话"
></el-input>
</el-form-item>
</el-col
>
</el-row>
<!-- <el-row>
<el-col :span="24">
<el-form-item label="网址" prop="url">
@ -153,10 +165,10 @@
<el-col :span="24">
<el-form-item label="实验室简介" prop="introduction">
<WangEditor
v-model="modelValue.introduction"
minHeight="320px"
ref="introductionRef"
@blur="formRef.validateField(`introduction`)"
ref="introductionRef"
v-model="modelValue.introduction"
minHeight="320px"
@blur="formRef.validateField(`introduction`)"
/>
<!-- @click.native="handleEditAble" -->
</el-form-item>
@ -166,10 +178,10 @@
<el-col :span="24">
<el-form-item label="核心成员及简介" prop="member">
<WangEditor
v-model="modelValue.member"
minHeight="320px"
ref="memberRef"
@blur="formRef.validateField(`member`)"
ref="memberRef"
v-model="modelValue.member"
minHeight="320px"
@blur="formRef.validateField(`member`)"
/>
<!-- @click.native="handleEditAble" -->
</el-form-item>
@ -179,12 +191,9 @@
</template>
<script setup>
import CityOptions from "@/views/components/CityOptions";
import FieldSingle from "@/views/components/FieldSingle";
import FieldOptions from "@/views/components/FieldOptions";
import InputBoxAdd from "@/views/components/InputBoxAdd";
import { researchSelect } from "@/api/dataList/research";
import { reactive, ref, toRefs, watch } from "vue";
import {reactive, ref, toRefs} from "vue";
const props = defineProps({
modelValue: Object,
@ -201,16 +210,16 @@ const props = defineProps({
default: 120,
},
});
const { modelValue, isAdd, showTitle, labelWidth } = toRefs(props);
const {modelValue, isAdd, showTitle, labelWidth} = toRefs(props);
const researchOptions = ref([]);
const options = ref([]);
const data = reactive({
rules: {
product: [{ required: true, message: "请输入", trigger: "blur" }],
name: [{ required: true, message: "请输入", trigger: "blur" }],
kind: [{ required: true, message: "请选择", trigger: "change" }],
code: [{ required: true, message: "请输入", trigger: "blur" }],
product: [{required: true, message: "请输入", trigger: "blur"}],
name: [{required: true, message: "请输入", trigger: "blur"}],
kind: [{required: true, message: "请选择", trigger: "change"}],
code: [{required: true, message: "请输入", trigger: "blur"}],
phone: [
// { required: true, message: "请输入联系电话", trigger: "blur" },
{
@ -219,7 +228,7 @@ const data = reactive({
trigger: "blur",
},
],
researchId: [{ required: true, message: "请选择", trigger: "change" }],
researchId: [{required: true, message: "请选择", trigger: "change"}],
tenantId: [
{
required: true,
@ -227,11 +236,11 @@ const data = reactive({
trigger: ["blur", "change"],
},
],
school: [{ required: true, message: "请输入", trigger: "blur" }],
education: [{ required: true, message: "请选择", trigger: "change" }],
major: [{ required: true, message: "请输入", trigger: "blur" }],
job: [{ required: true, message: "请输入", trigger: "blur" }],
title: [{ required: true, message: "请输入", trigger: "blur" }],
school: [{required: true, message: "请输入", trigger: "blur"}],
education: [{required: true, message: "请选择", trigger: "change"}],
major: [{required: true, message: "请输入", trigger: "blur"}],
job: [{required: true, message: "请输入", trigger: "blur"}],
title: [{required: true, message: "请输入", trigger: "blur"}],
workAt: [
{
required: true,
@ -247,12 +256,12 @@ const data = reactive({
},
],
introduce: [
{ required: true, message: "请输入实验室简介", trigger: "blur" },
{required: true, message: "请输入实验室简介", trigger: "blur"},
],
},
});
const { rules } = toRefs(data);
const {rules} = toRefs(data);
const formRef = ref();
const fieldFormRef = ref();
@ -347,6 +356,7 @@ export default {
font-weight: 700;
margin-bottom: 30px;
}
// 上传图片框限制
// ::v-deep .el-upload--picture-card {
// width: 120px;

View File

@ -1,30 +1,28 @@
<template>
<div class="app-container">
<el-form :model="queryParams" :inline="true">
<el-form :inline="true" :model="queryParams">
<el-form-item label="姓名" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入关键字"
clearable
size="default"
style="width: 240px"
v-model="queryParams.name"
clearable
placeholder="请输入关键字"
size="default"
style="width: 240px"
/>
</el-form-item>
<!-- <el-form-item label="所属站点" prop="tenantId">
<SiteOptions v-model="queryParams.tenantId" :site-list="siteList" />
</el-form-item> -->
<el-form-item>
<el-button
type="primary"
icon="search"
size="default"
@click="handleQuery"
>搜索</el-button
icon="search"
size="default"
type="primary"
@click="handleQuery"
>搜索
</el-button
>
<el-button icon="refresh" size="default" @click="resetQuery"
>重置</el-button
>重置
</el-button
>
</el-form-item>
</el-form>
@ -32,98 +30,106 @@
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="plus"
size="default"
@click="handleAdd"
>新增</el-button
icon="plus"
plain
size="default"
type="primary"
@click="handleAdd"
>新增
</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="upload"
size="default"
@click="handleImport"
>导入</el-button
icon="upload"
plain
size="default"
type="info"
@click="handleImport"
>导入
</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
:disabled="!ids.length"
type="danger"
icon="delete"
@click="handleDelete()"
>批量删除</el-button
:disabled="!ids.length"
icon="delete"
type="danger"
@click="handleDelete()"
>批量删除
</el-button
>
</el-col>
<right-toolbar
:showSearch.sync="showSearch"
@queryTable="getList"
:showSearch.sync="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row>
<!-- 表格区域 -->
<el-table
v-loading="loading"
:data="dataList"
@selection-change="handleSelectionChange"
v-loading="loading"
:data="dataList"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="数据编号" align="center" prop="id" />
<el-table-column label="专家姓名" align="center" prop="name" />
<el-table-column label="研究领域" align="center" show-overflow-tooltip>
<el-table-column type="selection" width="55"/>
<el-table-column align="center" label="数据编号" prop="id"/>
<el-table-column align="center" label="专家姓名" prop="name"/>
<el-table-column align="center" label="研究领域" show-overflow-tooltip>
<template #default="{ row }">
<div>{{ row.industryStr }}</div>
</template>
</el-table-column>
<el-table-column label="学历" align="center" prop="education" />
<el-table-column align="center" label="学历" prop="education"/>
<!-- <el-table-column label="备注" align="center" prop="introduce" /> -->
<!-- <el-table-column label="站点" align="center">
<template #default="{ row }">
{{ siteList.find((el) => el.id === row.tenantId)?.name ?? "无" }}
</template>
</el-table-column> -->
<el-table-column label="所在地" align="center" prop="address" />
<el-table-column label="操作" align="center">
<el-table-column align="center" label="所在地" prop="address"/>
<el-table-column align="center" label="操作">
<template #default="{ row }">
<el-button
size="small"
type="text"
icon="edit"
@click="handleDetail(row.id)"
>修改</el-button
icon="edit"
size="small"
type="text"
@click="handleDetail(row.id)"
>修改
</el-button
>
<el-button
size="small"
type="text"
icon="edit"
@click="handleDelete(row.id)"
>删除</el-button
icon="edit"
size="small"
type="text"
@click="handleDelete(row.id)"
>删除
</el-button
>
<el-button
size="small"
type="text"
icon="plus"
@click="handleClaim(row.id)"
>已认领专利</el-button
icon="plus"
size="small"
type="text"
@click="handleClaim(row.id)"
>已认领专利
</el-button
>
<el-button
size="small"
type="text"
icon="edit"
@click="openAssignAccount(row.id)"
>分配账号</el-button
icon="edit"
size="small"
type="text"
@click="openAssignAccount(row.id)"
>分配账号
</el-button
>
<el-button
size="small"
type="text"
icon="edit"
@click="openResetPassword(row.id)"
>重置密码</el-button
icon="edit"
size="small"
type="text"
@click="openResetPassword(row.id)"
>重置密码
</el-button
>
</template>
</el-table-column>
@ -131,33 +137,35 @@
<!-- 分页器 -->
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
v-show="total > 0"
v-model:limit="queryParams.pageSize"
v-model:page="queryParams.pageNum"
:total="total"
@pagination="getList"
/>
<!-- 用户导入对话框 -->
<el-dialog
:title="upload.title"
v-model="upload.open"
width="400px"
append-to-body
v-model="upload.open"
:title="upload.title"
append-to-body
width="400px"
>
<el-upload
ref="uploadRef"
:limit="1"
accept=".xlsx, .xls"
:headers="upload.headers"
:action="upload.url"
:disabled="upload.isUploading"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
:auto-upload="false"
drag
ref="uploadRef"
:action="upload.url"
:auto-upload="false"
:disabled="upload.isUploading"
:headers="upload.headers"
:limit="1"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
accept=".xlsx, .xls"
drag
>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<el-icon class="el-icon--upload">
<upload-filled/>
</el-icon>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<template #tip>
<div class="el-upload__tip text-center">
@ -186,31 +194,32 @@
</el-dialog>
<el-dialog
title="分配账号"
v-model="showAssignAccount"
width="400px"
append-to-body
v-model="showAssignAccount"
append-to-body
title="分配账号"
width="400px"
>
<el-form
:model="assignAccountForm"
:rules="assignAccoutRules"
label-width="80px"
ref="assignAccountFormRef"
ref="assignAccountFormRef"
:model="assignAccountForm"
:rules="assignAccoutRules"
label-width="80px"
>
<el-form-item label="用户名" prop="username">
<el-input v-model="assignAccountForm.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input
v-model="assignAccountForm.password"
show-password
v-model="assignAccountForm.password"
show-password
></el-input>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitAssignAccount"
> </el-button
>
</el-button
>
<el-button @click="closeAssignAccount"> </el-button>
</div>
@ -218,28 +227,29 @@
</el-dialog>
<el-dialog
title="重置密码"
v-model="showResetPassword"
width="400px"
append-to-body
v-model="showResetPassword"
append-to-body
title="重置密码"
width="400px"
>
<el-form
:model="resetPasswordForm"
:rules="assignAccoutRules"
label-width="80px"
ref="resetPasswordFormRef"
ref="resetPasswordFormRef"
:model="resetPasswordForm"
:rules="assignAccoutRules"
label-width="80px"
>
<el-form-item label="密码" prop="password">
<el-input
v-model="resetPasswordForm.password"
show-password
v-model="resetPasswordForm.password"
show-password
></el-input>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitResetPassword"
> </el-button
>
</el-button
>
<el-button @click="closeResetPassword"> </el-button>
</div>
@ -248,23 +258,17 @@
</div>
</template>
<script setup>
import {
expertDelete,
allocateAccount,
getAccount,
restPassword,
} from "@/api/dataList/expert";
import {allocateAccount, expertDelete, getAccount, restPassword,} from "@/api/dataList/expert";
import md5 from "js-md5";
// import SiteOptions from "@/views/components/SiteOptions";
import { tenantSelect } from "@/api/subPlatform/tenant";
import { expertList } from "@/api/expert/expert";
import { useRouter } from "vue-router";
import { getToken } from "@/utils/auth";
import { tansParams, blobValidate } from "@/utils/ruoyi";
import FieldOptions from "@/views/components/FieldOptions";
import { ElLoading, ElMessageBox, ElMessage } from "element-plus";
import {expertList} from "@/api/expert/expert";
import {useRouter} from "vue-router";
import {getToken} from "@/utils/auth";
import {blobValidate} from "@/utils/ruoyi";
import {ElLoading, ElMessage, ElMessageBox} from "element-plus";
import dayjs from "dayjs";
import request from "@/utils/request";
const router = useRouter();
// const siteList = ref([]);
const dataList = ref([]);
@ -292,19 +296,19 @@ const upload = reactive({
// 是否更新已经存在的用户数据
// updateSupport: 0,
// 设置上传的请求头部
headers: { Authorization: "Bearer " + getToken() },
headers: {Authorization: "Bearer " + getToken()},
// 上传的地址
url: import.meta.env.VITE_APP_BASE_API + "/business/casExpert/importData",
});
const { queryParams } = toRefs(data);
const {queryParams} = toRefs(data);
const assignAccoutRules = {
username: [{ required: true, message: "请输入用户名", trigger: "blur" }],
password: [{ required: true, message: "请输入密码", trigger: "blur" }],
vipType: [{ required: true, message: "请选择会员类型", trigger: "change" }],
username: [{required: true, message: "请输入用户名", trigger: "blur"}],
password: [{required: true, message: "请输入密码", trigger: "blur"}],
vipType: [{required: true, message: "请选择会员类型", trigger: "change"}],
expireTime: [
{ required: true, message: "请选择到期时间", trigger: "change" },
{required: true, message: "请选择到期时间", trigger: "change"},
],
};
const showAssignAccount = ref(false);
@ -321,7 +325,7 @@ const showResetPassword = ref(false);
const openAssignAccount = async (id) => {
resetForm();
const { have, data } = await getAccount(id);
const {have, data} = await getAccount(id);
if (have) {
ElMessageBox.alert(`已经存在账号:${data}`, "账号已经存在");
} else {
@ -332,7 +336,7 @@ const openAssignAccount = async (id) => {
const openResetPassword = async (id) => {
resetForm();
const { have } = await getAccount(id);
const {have} = await getAccount(id);
if (have) {
resetPasswordForm.id = id;
showResetPassword.value = true;
@ -400,14 +404,14 @@ const handleAdd = () => {
const handleDetail = (id) => {
router.push({
path: "/dataList/expert/add",
query: { id },
query: {id},
});
};
// 认领专利
const handleClaim = (id) => {
router.push({
path: "/dataList/expert/claim",
query: { id },
query: {id},
});
};
/** 搜索按钮操作 */
@ -422,19 +426,22 @@ const resetQuery = () => {
handleQuery();
};
const uploadRef = ref(null);
/** 导入按钮操作 */
function handleImport() {
upload.title = "用户导入";
upload.open = true;
}
/** 下载模板操作 */
function importTemplate() {
proxy.download(
"system/user/importTemplate",
{},
`user_template_${new Date().getTime()}.xlsx`
"system/user/importTemplate",
{},
`user_template_${new Date().getTime()}.xlsx`
);
}
/**文件上传中处理 */
const handleFileUploadProgress = (event, file, fileList) => {
upload.isUploading = true;
@ -445,27 +452,30 @@ const handleFileSuccess = (response, file, fileList) => {
upload.isUploading = false;
uploadRef.value.handleRemove(file);
ElMessageBox.alert(
"<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
"<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
response.msg +
"</div>",
"导入结果",
{ dangerouslyUseHTMLString: true }
"导入结果",
{dangerouslyUseHTMLString: true}
);
getList();
};
/** 提交上传文件 */
function submitFileForm() {
uploadRef.value.submit();
}
const handleDelete = async (id) => {
const delIds = id || ids.value.join(",");
ElMessageBox.confirm(`是否确认删除编号为${delIds}的数据项?`)
.then(async () => {
await expertDelete(delIds);
getList();
ElMessage.success("删除成功");
})
.catch(() => {});
.then(async () => {
await expertDelete(delIds);
getList();
ElMessage.success("删除成功");
})
.catch(() => {
});
};
let downloadLoadingInstance;
@ -475,41 +485,41 @@ const download = (url, filename) => {
background: "rgba(0, 0, 0, 0.7)",
});
return request
.get(url, {
// transformRequest: [
// (params) => {
// return tansParams(params);
// },
// ],
headers: { "Content-Type": "application/x-www-form-urlencoded" },
responseType: "blob",
})
.then(async (data) => {
const isLogin = await blobValidate(data);
if (isLogin) {
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();
});
.get(url, {
// transformRequest: [
// (params) => {
// return tansParams(params);
// },
// ],
headers: {"Content-Type": "application/x-www-form-urlencoded"},
responseType: "blob",
})
.then(async (data) => {
const isLogin = await blobValidate(data);
if (isLogin) {
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();
});
};
const handleExport = () => {
ElMessageBox.confirm(`是否确认企业列表?`).then(() => {
download(
`/business/enterprise/export`,
`企业信息(${dayjs().format("YYYYMMDDHHmmss")}).xlsx`
`/business/enterprise/export`,
`企业信息(${dayjs().format("YYYYMMDDHHmmss")}).xlsx`
);
});
};

View File

@ -2,11 +2,11 @@
<div class="app-container">
<div style="width: 50%">
<LaboratoryForm
v-model="form"
:showTitle="true"
:formType="formType"
:labelWidth="140"
ref="laboratoryFormRef"
ref="laboratoryFormRef"
v-model="form"
:formType="formType"
:labelWidth="140"
:showTitle="true"
/>
</div>
<el-button @click="cancel">取消</el-button>
@ -14,17 +14,14 @@
</div>
</template>
<script setup name="LaboratoryAdd">
<script name="LaboratoryAdd" setup>
import LaboratoryForm from "@/views/components/LaboratoryForm";
import tab from "@/plugins/tab";
import {
casLaboratoryAdd,
casLaboratoryDetail,
casLaboratoryUpdate,
} from "@/api/dataList/laboratory";
import { reactive, toRefs } from "vue";
import { useRoute, useRouter } from "vue-router";
import { ElMessage } from "element-plus";
import {casLaboratoryAdd, casLaboratoryDetail, casLaboratoryUpdate,} from "@/api/dataList/laboratory";
import {reactive, toRefs} from "vue";
import {useRoute, useRouter} from "vue-router";
import {ElMessage} from "element-plus";
const router = useRouter();
const route = useRoute();
const formType = ref(1);
@ -50,7 +47,7 @@ const data = reactive({
// license: undefined,
},
});
const { form } = toRefs(data);
const {form} = toRefs(data);
const cancel = () => {
router.back();
tab.closeOpenPage();
@ -59,6 +56,7 @@ const submitForm = async () => {
const valid = await laboratoryFormRef.value.validateForm();
if (valid) {
form.value.keyword = form.value.keywords.join(",");
form.value.researchDirection = form.value.researchs?.join(",") ?? null;
if (form.value.id != undefined) {
await casLaboratoryUpdate(form.value);
cancel();
@ -75,8 +73,9 @@ const submitForm = async () => {
const getDetailById = async () => {
if (route.query.id) {
const { data } = await casLaboratoryDetail(route.query.id);
const {data} = await casLaboratoryDetail(route.query.id);
form.value = data;
form.value.researchs = data.researchDirection?.split(',') ?? []
form.value.keywords = data.keyword ? data.keyword.split(",") : [];
// form.value.district = data.area;
}

View File

@ -1,13 +1,13 @@
<template>
<div class="app-container">
<el-form :model="queryParams" :inline="true">
<el-form :inline="true" :model="queryParams">
<el-form-item label="姓名" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入关键字"
clearable
size="default"
style="width: 240px"
v-model="queryParams.name"
clearable
placeholder="请输入关键字"
size="default"
style="width: 240px"
/>
</el-form-item>
<!--
@ -17,14 +17,16 @@
<el-form-item>
<el-button
type="primary"
icon="search"
size="default"
@click="handleQuery"
>搜索</el-button
icon="search"
size="default"
type="primary"
@click="handleQuery"
>搜索
</el-button
>
<el-button icon="refresh" size="default" @click="resetQuery"
>重置</el-button
>重置
</el-button
>
</el-form-item>
</el-form>
@ -32,58 +34,61 @@
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="plus"
size="default"
@click="handleAdd"
>新增</el-button
icon="plus"
plain
size="default"
type="primary"
@click="handleAdd"
>新增
</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
type="info"
plain
icon="upload"
size="default"
@click="handleImport"
>导入</el-button
icon="upload"
plain
size="default"
type="info"
@click="handleImport"
>导入
</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
:disabled="!ids.length"
type="danger"
icon="delete"
@click="handleDelete()"
>批量删除</el-button
:disabled="!ids.length"
icon="delete"
type="danger"
@click="handleDelete()"
>批量删除
</el-button
>
</el-col>
<right-toolbar
:showSearch.sync="showSearch"
@queryTable="getList"
:showSearch.sync="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row>
<!-- 表格区域 -->
<el-table
v-loading="loading"
:data="dataList"
@selection-change="handleSelectionChange"
v-loading="loading"
:data="dataList"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55" />
<el-table-column label="数据编号" align="center" prop="id" />
<el-table-column label="实验室全称" align="center" prop="name" />
<el-table-column label="所属院所或高校" align="center" prop="school" />
<el-table-column label="实验室简介" align="center" show-overflow-tooltip>
<el-table-column type="selection" width="55"/>
<el-table-column align="center" label="数据编号" prop="id"/>
<el-table-column align="center" label="实验室全称" prop="name"/>
<el-table-column align="center" label="所属院所或高校" prop="school"/>
<el-table-column align="center" label="实验室简介" show-overflow-tooltip>
<template #default="{ row }">
<div v-html="row.introduction"></div>
</template>
</el-table-column>
<el-table-column
label="核心成员及简介"
align="center"
show-overflow-tooltip
align="center"
label="核心成员及简介"
show-overflow-tooltip
>
<template #default="{ row }">
<div v-html="row.member"></div>
@ -91,35 +96,53 @@
</template>
</el-table-column>
<el-table-column
label="研究方向"
align="center"
prop="researchDirection"
show-overflow-tooltip
align="center"
label="研究方向"
prop="researchDirection"
show-overflow-tooltip
/>
<el-table-column
label="主要技术应用场景"
align="center"
prop="primaryTechnology"
align="center"
label="主要技术应用场景"
prop="primaryTechnology"
/>
<el-table-column label="所属行业领域" align="center" prop="industryStr" />
<el-table-column label="联系电话" align="center" prop="phone" />
<el-table-column label="网址" align="center" prop="url" />
<el-table-column align="center" label="所属行业领域" prop="industryStr"/>
<el-table-column align="center" label="联系电话" prop="phone"/>
<el-table-column align="center" label="网址" prop="url"/>
<!-- <el-table-column label="关键词" align="center" prop="address" /> -->
<el-table-column label="操作" align="center">
<el-table-column align="center" label="操作">
<template #default="{ row }">
<el-button
size="small"
type="text"
icon="edit"
@click="handleDetail(row.id)"
>修改</el-button
icon="edit"
size="small"
type="text"
@click="handleDetail(row.id)"
>修改
</el-button
>
<el-button
size="small"
type="text"
icon="edit"
@click="handleDelete(row.id)"
>删除</el-button
icon="edit"
size="small"
type="text"
@click="handleDelete(row.id)"
>删除
</el-button
>
<el-button
icon="edit"
size="small"
type="text"
@click="openAssignAccount(row.id)"
>分配账号
</el-button
>
<el-button
icon="edit"
size="small"
type="text"
@click="openResetPassword(row.id)"
>重置密码
</el-button
>
<!-- <el-button
size="small"
@ -136,46 +159,42 @@
@click="openAssignAccount(row.id)"
>分配账号</el-button
>
<el-button
size="small"
type="text"
icon="edit"
@click="openResetPassword(row.id)"
>重置密码</el-button
> -->
-->
</template>
</el-table-column>
</el-table>
<!-- 分页器 -->
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
v-show="total > 0"
v-model:limit="queryParams.pageSize"
v-model:page="queryParams.pageNum"
:total="total"
@pagination="getList"
/>
<!-- 用户导入对话框 -->
<el-dialog
:title="upload.title"
v-model="upload.open"
width="400px"
append-to-body
v-model="upload.open"
:title="upload.title"
append-to-body
width="400px"
>
<el-upload
ref="uploadRef"
:limit="1"
accept=".xlsx, .xls"
:headers="upload.headers"
:action="upload.url"
:disabled="upload.isUploading"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
:auto-upload="false"
drag
ref="uploadRef"
:action="upload.url"
:auto-upload="false"
:disabled="upload.isUploading"
:headers="upload.headers"
:limit="1"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
accept=".xlsx, .xls"
drag
>
<el-icon class="el-icon--upload"><upload-filled /></el-icon>
<el-icon class="el-icon--upload">
<upload-filled/>
</el-icon>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<template #tip>
<div class="el-upload__tip text-center">
@ -203,32 +222,33 @@
</template>
</el-dialog>
<!-- <el-dialog
title="分配账号"
v-model="showAssignAccount"
width="400px"
append-to-body
<el-dialog
v-model="showAssignAccount"
append-to-body
title="分配账号"
width="400px"
>
<el-form
:model="assignAccountForm"
:rules="assignAccoutRules"
label-width="80px"
ref="assignAccountFormRef"
ref="assignAccountFormRef"
:model="assignAccountForm"
:rules="assignAccoutRules"
label-width="80px"
>
<el-form-item label="用户名" prop="username">
<el-input v-model="assignAccountForm.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input
v-model="assignAccountForm.password"
show-password
v-model="assignAccountForm.password"
show-password
></el-input>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitAssignAccount"
> </el-button
>
</el-button
>
<el-button @click="closeAssignAccount"> </el-button>
</div>
@ -236,57 +256,56 @@
</el-dialog>
<el-dialog
title="重置密码"
v-model="showResetPassword"
width="400px"
append-to-body
v-model="showResetPassword"
append-to-body
title="重置密码"
width="400px"
>
<el-form
:model="resetPasswordForm"
:rules="assignAccoutRules"
label-width="80px"
ref="resetPasswordFormRef"
ref="resetPasswordFormRef"
:model="resetPasswordForm"
:rules="assignAccoutRules"
label-width="80px"
>
<el-form-item label="密码" prop="password">
<el-input
v-model="resetPasswordForm.password"
show-password
autocomplete="off"
v-model="resetPasswordForm.password"
show-password
></el-input>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitResetPassword"
> </el-button
>
</el-button
>
<el-button @click="closeResetPassword"> </el-button>
</div>
</template>
</el-dialog> -->
</el-dialog>
</div>
</template>
<script setup>
// import {
// expertDelete,
// allocateAccount,
// getAccount,
// restPassword,
// } from "@/api/dataList/expert";
// import md5 from "js-md5";
// import SiteOptions from "@/views/components/SiteOptions";
import { tenantSelect } from "@/api/subPlatform/tenant";
// import { expertList } from "@/api/expert/expert";
import { useRouter } from "vue-router";
import { getToken } from "@/utils/auth";
import { tansParams, blobValidate } from "@/utils/ruoyi";
import {tenantSelect} from "@/api/subPlatform/tenant";
import {
casLaboratoryList,
allocateAccount,
casLaboratoryDelete,
} from "@/api/dataList/laboratory";
import FieldOptions from "@/views/components/FieldOptions";
import { ElLoading, ElMessageBox, ElMessage } from "element-plus";
import dayjs from "dayjs";
casLaboratoryList,
getAccount,
restPassword
} from "@/api/dataList/laboratory"
import {useRouter} from "vue-router";
import {getToken} from "@/utils/auth";
import {blobValidate} from "@/utils/ruoyi";
import {ElLoading, ElMessage, ElMessageBox} from "element-plus";
import request from "@/utils/request";
import {reactive, ref, toRefs} from "vue";
import errorCode from "@/utils/errorCode";
import md5 from 'js-md5'
const router = useRouter();
const siteList = ref([]);
const dataList = ref([]);
@ -310,90 +329,90 @@ const upload = reactive({
// 是否更新已经存在的用户数据
// updateSupport: 0,
// 设置上传的请求头部
headers: { Authorization: "Bearer " + getToken() },
headers: {Authorization: "Bearer " + getToken()},
// 上传的地址
url: import.meta.env.VITE_APP_BASE_API + "/business/casLaboratory/importData",
});
const { queryParams } = toRefs(data);
const {queryParams} = toRefs(data);
// const assignAccoutRules = {
// username: [{ required: true, message: "请输入用户名", trigger: "blur" }],
// password: [{ required: true, message: "请输入密码", trigger: "blur" }],
// vipType: [{ required: true, message: "请选择会员类型", trigger: "change" }],
// expireTime: [
// { required: true, message: "请选择到期时间", trigger: "change" },
// ],
// };
// const showAssignAccount = ref(false);
// const assignAccountForm = reactive({
// username: undefined,
// password: undefined,
// });
// const assignAccountFormRef = ref();
// const resetPasswordForm = reactive({
// password: undefined,
// });
// const resetPasswordFormRef = ref();
// const showResetPassword = ref(false);
const assignAccoutRules = {
username: [{required: true, message: "请输入用户名", trigger: "blur"}],
password: [{required: true, message: "请输入密码", trigger: "blur"}],
vipType: [{required: true, message: "请选择会员类型", trigger: "change"}],
expireTime: [
{required: true, message: "请选择到期时间", trigger: "change"},
],
};
const showAssignAccount = ref(false);
const assignAccountForm = reactive({
username: undefined,
password: undefined,
});
const assignAccountFormRef = ref();
const resetPasswordForm = reactive({
password: undefined,
});
const resetPasswordFormRef = ref();
const showResetPassword = ref(false);
// const openAssignAccount = async (id) => {
// resetForm();
// const { have, data } = await getAccount(id);
// if (have) {
// ElMessageBox.alert(`已经存在账号:${data}`, "账号已经存在");
// } else {
// assignAccountForm.id = id;
// showAssignAccount.value = true;
// }
// };
const openAssignAccount = async (id) => {
resetForm();
const {have, data} = await getAccount(id);
if (have) {
ElMessageBox.alert(`已经存在账号:${data}`, "账号已经存在");
} else {
assignAccountForm.id = id;
showAssignAccount.value = true;
}
};
// const openResetPassword = async (id) => {
// resetForm();
// const { have } = await getAccount(id);
// if (have) {
// resetPasswordForm.id = id;
// showResetPassword.value = true;
// } else {
// ElMessageBox.alert(`尚未分配账号,请先分配账号`, "尚未分配账号");
// }
// };
// const resetForm = () => {
// if (resetPasswordFormRef.value) {
// resetPasswordFormRef.value.resetFields();
// }
// if (assignAccountFormRef.value) {
// assignAccountFormRef.value.resetFields();
// }
// resetPasswordForm.password = undefined;
// assignAccountForm.username = undefined;
// assignAccountForm.password = undefined;
// };
// const closeResetPassword = () => {
// resetForm();
// showResetPassword.value = false;
// };
// const closeAssignAccount = () => {
// resetForm();
// showAssignAccount.value = false;
// };
const openResetPassword = async (id) => {
resetForm();
const {have} = await getAccount(id);
if (have) {
resetPasswordForm.id = id;
showResetPassword.value = true;
} else {
ElMessageBox.alert(`尚未分配账号,请先分配账号`, "尚未分配账号");
}
};
const resetForm = () => {
if (resetPasswordFormRef.value) {
resetPasswordFormRef.value.resetFields();
}
if (assignAccountFormRef.value) {
assignAccountFormRef.value.resetFields();
}
resetPasswordForm.password = undefined;
assignAccountForm.username = undefined;
assignAccountForm.password = undefined;
};
const closeResetPassword = () => {
resetForm();
showResetPassword.value = false;
};
const closeAssignAccount = () => {
resetForm();
showAssignAccount.value = false;
};
// const submitAssignAccount = async () => {
// await assignAccountFormRef.value.validate();
// await allocateAccount({
// ...assignAccountForm,
// password: md5(assignAccountForm.password),
// });
// ElMessage.success("账号分配成功");
// showAssignAccount.value = false;
// };
const submitAssignAccount = async () => {
await assignAccountFormRef.value.validate();
await allocateAccount({
...assignAccountForm,
password: md5(assignAccountForm.password),
});
ElMessage.success("账号分配成功");
showAssignAccount.value = false;
};
// const submitResetPassword = async () => {
// await resetPasswordFormRef.value.validate();
// await restPassword(resetPasswordForm.id, md5(resetPasswordForm.password));
// ElMessage.success("密码重置成功");
// showResetPassword.value = false;
// };
const submitResetPassword = async () => {
await resetPasswordFormRef.value.validate();
await restPassword(resetPasswordForm.id, md5(resetPasswordForm.password));
ElMessage.success("密码重置成功");
showResetPassword.value = false;
};
const ids = ref([]);
const handleSelectionChange = (selection) => {
ids.value = selection.map((el) => el.id);
@ -422,7 +441,7 @@ const handleAdd = () => {
const handleDetail = (id) => {
router.push({
path: "/dataList/laboratory/add",
query: { id },
query: {id},
});
};
// 认领专利
@ -444,19 +463,22 @@ const resetQuery = () => {
handleQuery();
};
const uploadRef = ref(null);
/** 导入按钮操作 */
function handleImport() {
upload.title = "用户导入";
upload.open = true;
}
/** 下载模板操作 */
function importTemplate() {
proxy.download(
"system/user/importTemplate",
{},
`user_template_${new Date().getTime()}.xlsx`
"system/user/importTemplate",
{},
`user_template_${new Date().getTime()}.xlsx`
);
}
/**文件上传中处理 */
const handleFileUploadProgress = (event, file, fileList) => {
upload.isUploading = true;
@ -467,18 +489,20 @@ const handleFileSuccess = (response, file, fileList) => {
upload.isUploading = false;
uploadRef.value.handleRemove(file);
ElMessageBox.alert(
"<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
"<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
response.msg +
"</div>",
"导入结果",
{ dangerouslyUseHTMLString: true }
"导入结果",
{dangerouslyUseHTMLString: true}
);
getList();
};
/** 提交上传文件 */
function submitFileForm() {
uploadRef.value.submit();
}
const handleDelete = async (id) => {
let delIds;
if (id) {
@ -487,12 +511,13 @@ const handleDelete = async (id) => {
delIds = ids.value;
}
ElMessageBox.confirm(`是否确认删除编号为${delIds.join(",")}的数据项?`)
.then(async () => {
await casLaboratoryDelete(delIds);
getList();
ElMessage.success("删除成功");
})
.catch(() => {});
.then(async () => {
await casLaboratoryDelete(delIds);
getList();
ElMessage.success("删除成功");
})
.catch(() => {
});
};
let downloadLoadingInstance;
@ -502,34 +527,34 @@ const download = (url, filename) => {
background: "rgba(0, 0, 0, 0.7)",
});
return request
.get(url, {
// transformRequest: [
// (params) => {
// return tansParams(params);
// },
// ],
headers: { "Content-Type": "application/x-www-form-urlencoded" },
responseType: "blob",
})
.then(async (data) => {
const isLogin = await blobValidate(data);
if (isLogin) {
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();
});
.get(url, {
// transformRequest: [
// (params) => {
// return tansParams(params);
// },
// ],
headers: {"Content-Type": "application/x-www-form-urlencoded"},
responseType: "blob",
})
.then(async (data) => {
const isLogin = await blobValidate(data);
if (isLogin) {
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();
});
};
// const handleExport = () => {

View File

@ -0,0 +1,109 @@
<template>
<div class="app-container">
<div style="width: 50%">
<!-- <ExpertForm-->
<!-- ref="expertFormRef"-->
<!-- v-model="form"-->
<!-- :formType="formType"-->
<!-- :labelWidth="140"-->
<!-- :showTitle="true"-->
<!-- />-->
<research-form ref="researchFormRef" v-model="form"
:labelWidth="140"
:showTitle="true"></research-form>
</div>
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="submitForm">提交</el-button>
</div>
</template>
<script name="EnterpriseAdd" setup>
import ResearchForm from '@/views/components/ResearchForm'
import tab from "@/plugins/tab";
import {companyAdd, companyDetail, companyEdit,} from "@/api/dataList/enterprise";
import {reactive, ref, toRefs} from "vue";
import {useRoute, useRouter} from "vue-router";
import {ElMessage} from "element-plus";
const router = useRouter();
const route = useRoute();
const formType = ref(2);
const expertFormRef = ref(null);
const data = reactive({
form: {
image: undefined,
name: undefined,
tenantId: undefined,
province: undefined, // 省code
city: undefined, // 市code
district: undefined, // 区code
address: undefined, // 详细地址
product: undefined,
kind: undefined,
code: undefined,
inviterCode: undefined,
url: undefined,
industrys: [],
industry: "",
keywords: [],
directions: [],
introduce: undefined,
license: undefined,
workTime: "",
},
});
const {form} = toRefs(data);
const cancel = () => {
router.back();
tab.closeOpenPage();
};
const submitForm = async () => {
const valid = await expertFormRef.value.validateForm();
if (valid) {
if (form.value.id != undefined) {
await companyEdit(form.value);
cancel();
ElMessage.success("修改成功");
} else {
await companyAdd(form.value);
cancel();
ElMessage.success("新增成功");
}
} else {
console.log("校验未通过");
}
};
const getDetailById = async () => {
if (route.query.id) {
const {data} = await companyDetail(route.query.id);
form.value = data;
}
};
getDetailById();
</script>
<!-- <script>
export default {
components: {
ExpertForm,
},
data() {
return {
// formType: 2,
// labelWidth: 140,
};
},
methods: {},
created() {
const { id } = this.$route.query;
if (id) {
companyDetail({ id }).then((res) => {
form.value = res.data;
});
}
},
};
</script> -->

View File

@ -0,0 +1,667 @@
<template>
<div class="app-container">
<el-form
v-show="showSearch"
ref="queryFormRef"
:inline="true"
:model="queryParams"
label-width="68px"
>
<el-form-item label="企业名称" prop="name">
<el-input
v-model="queryParams.name"
clearable
placeholder="请输入企业名称"
size="default"
style="width: 240px"
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<!-- <el-form-item label="所属站点" prop="tenantId">
<SiteOptions v-model="queryParams.tenantId" :site-list="siteList" />
</el-form-item> -->
<el-form-item>
<el-button
icon="search"
size="default"
type="primary"
@click="handleQuery"
>搜索
</el-button
>
<el-button icon="refresh" size="default" @click="resetQuery"
>重置
</el-button
>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button
icon="plus"
plain
size="default"
type="primary"
@click="handleAdd"
>新增
</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
icon="upload"
plain
size="default"
type="info"
@click="handleImport"
>导入
</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
icon="download"
plain
size="default"
type="warning"
@click="handleExport"
>导出
</el-button
>
</el-col>
<el-col :span="1.5">
<el-button
:disabled="!ids.length"
icon="delete"
type="danger"
@click="handleDelete()"
>批量删除
</el-button
>
</el-col>
<right-toolbar
:showSearch.sync="showSearch"
@queryTable="getList"
></right-toolbar>
</el-row>
<el-table
v-loading="loading"
:data="dataList"
@selection-change="handleSelectionChange"
>
<el-table-column type="selection" width="55"/>
<el-table-column align="center" label="数据编号" prop="id"/>
<el-table-column align="center" label="企业名称" prop="name"/>
<!-- <el-table-column label="统一社会信用代码" align="center" prop="code" /> -->
<el-table-column align="center" label="所属领域" show-overflow-tooltip>
<template #default="{ row }">
<div>{{ row.industrys[row.industrys.length - 1] }}</div>
</template>
</el-table-column>
<!-- <el-table-column label="站点" align="center">
<template #default="{ row }">
{{ siteList.find((el) => el.id === row.tenantId)?.name ?? "无" }}
</template>
</el-table-column> -->
<el-table-column align="center" label="所在地" prop="address"/>
<el-table-column align="center" label="企业类型" prop="kind">
<template #default="{ row }">
<div>
{{ enterpriseOptions.find((e) => row.kind == e.key).value }}
</div>
</template>
</el-table-column>
<el-table-column align="center" label="申请时间">
<template #default="{ row }">
<span>{{ row.createdAt }}</span>
</template>
</el-table-column>
<el-table-column align="center" label="操作">
<template #default="{ row }">
<el-button
icon="edit"
size="small"
type="text"
@click="handleDetail(row.id)"
>修改
</el-button
>
<el-button
icon="delete"
size="small"
type="text"
@click="handleDelete(row.id)"
>删除
</el-button
>
<el-button
icon="edit"
size="small"
type="text"
@click="openAssignAccount(row.id)"
>分配账号
</el-button
>
<el-button
icon="edit"
size="small"
type="text"
@click="openResetPassword(row.id)"
>重置密码
</el-button
>
<el-button
icon="edit"
size="small"
type="text"
@click="handleOpenVip(row.id)"
>开通会员
</el-button
>
</template>
</el-table-column>
</el-table>
<pagination
v-show="total > 0"
v-model:limit="queryParams.pageSize"
v-model:page="queryParams.pageNum"
:total="total"
@pagination="getList"
/>
<!-- 用户导入对话框 -->
<el-dialog
v-model="upload.open"
:title="upload.title"
append-to-body
width="400px"
>
<el-upload
ref="uploadRef"
:action="upload.url"
:auto-upload="false"
:disabled="upload.isUploading"
:headers="upload.headers"
:limit="1"
:on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess"
accept=".xlsx, .xls"
drag
>
<el-icon class="el-icon--upload">
<upload-filled/>
</el-icon>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<template #tip>
<div class="el-upload__tip text-center">
<!-- <div class="el-upload__tip">
<el-checkbox
v-model="upload.updateSupport"
/>是否更新已经存在的用户数据
</div> -->
<span>仅允许导入xlsxlsx格式文件</span>
<!-- <el-link
type="primary"
:underline="false"
style="font-size: 12px; vertical-align: baseline"
@click="importTemplate"
>下载模板</el-link
> -->
</div>
</template>
</el-upload>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitFileForm"> </el-button>
<el-button @click="upload.open = false"> </el-button>
</div>
</template>
</el-dialog>
<el-dialog
v-model="showAssignAccount"
append-to-body
title="分配账号"
width="400px"
>
<el-form
ref="assignAccountFormRef"
:model="assignAccountForm"
:rules="assignAccoutRules"
label-width="80px"
>
<el-form-item label="用户名" prop="username">
<el-input v-model="assignAccountForm.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input
v-model="assignAccountForm.password"
show-password
></el-input>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitAssignAccount"
>
</el-button
>
<el-button @click="closeAssignAccount"> </el-button>
</div>
</template>
</el-dialog>
<el-dialog
v-model="showResetPassword"
append-to-body
title="重置密码"
width="400px"
>
<el-form
ref="resetPasswordFormRef"
:model="resetPasswordForm"
:rules="assignAccoutRules"
label-width="80px"
>
<el-form-item label="密码" prop="password">
<el-input
v-model="resetPasswordForm.password"
show-password
></el-input>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitResetPassword"
>
</el-button
>
<el-button @click="closeResetPassword"> </el-button>
</div>
</template>
</el-dialog>
<el-dialog
v-model="showOpenVip"
:title="vipForm.id ? `修改会员` : `开通会员`"
append-to-body
width="400px"
>
<el-form
ref="vipFormRef"
:model="vipForm"
:rules="assignAccoutRules"
label-width="80px"
>
<el-form-item label="会员类型" prop="vipType">
<el-radio-group v-model="vipForm.vipType">
<el-radio label="0">普通会员</el-radio>
<el-radio label="1">VIP</el-radio>
<el-radio label="2">SVIP</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
v-if="vipForm.vipType != '0'"
label="到期时间"
prop="expireTime"
>
<el-date-picker
v-model="vipForm.expireTime"
placeholder="选择到期时间"
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button
:disabled="vipForm.vipType == 0"
type="primary"
@click="submitVip"
>
</el-button
>
<el-button @click="closeVip"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script name="Enterprise" setup>
import {
allocateAccount,
companyDelete,
companyList,
getAccount,
getCasVip,
openCasVip,
restPassword,
updateCasVip,
} from "@/api/dataList/enterprise";
import md5 from "js-md5";
import {getToken} from "@/utils/auth";
// import SiteOptions from "@/views/components/SiteOptions";
// import axios from "axios";
// import { download } from "@/utils/request";
// import dayjs from "dayjs";
import {blobValidate} from "@/utils/ruoyi";
import {saveAs} from "file-saver";
import {reactive, ref, toRefs} from "vue";
import {useRouter} from "vue-router";
import {enterpriseOptions} from "@/utils/parameter";
import {ElLoading, ElMessage, ElMessageBox} from "element-plus";
import request from "@/utils/request";
import dayjs from "dayjs";
const router = useRouter();
const data = reactive({
queryParams: {
pageNum: 1,
pageSize: 10,
examine_status: 2,
name: undefined,
tenantId: undefined,
},
});
/*** 用户导入参数 */
const upload = reactive({
// 是否显示弹出层(用户导入)
open: false,
// 弹出层标题(用户导入)
title: "",
// 是否禁用上传
isUploading: false,
// 是否更新已经存在的用户数据
// updateSupport: 0,
// 设置上传的请求头部
headers: {Authorization: "Bearer " + getToken()},
// 上传的地址
url: import.meta.env.VITE_APP_BASE_API + "/business/enterprise/importData",
});
const {queryParams} = toRefs(data);
const showSearch = ref(true);
// const siteList = ref([]);
const loading = ref(true);
const total = ref(0);
const dataList = ref([]);
const ids = ref([]);
const handleSelectionChange = (selection) => {
ids.value = selection.map((el) => el.id);
};
/** 查询企业列表 */
const getList = async () => {
loading.value = true;
const resp = await companyList(queryParams.value);
dataList.value = resp.rows;
total.value = resp.total;
loading.value = false;
};
// 获取站点列表
// const getSiteList = async () => {
// const resp = await tenantSelect();
// siteList.value = resp.rows;
// };
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
const assignAccoutRules = {
username: [{required: true, message: "请输入用户名", trigger: "blur"}],
password: [{required: true, message: "请输入密码", trigger: "blur"}],
vipType: [{required: true, message: "请选择会员类型", trigger: "change"}],
expireTime: [
{required: true, message: "请选择到期时间", trigger: "change"},
],
};
const showAssignAccount = ref(false);
const assignAccountForm = reactive({
username: undefined,
password: undefined,
});
const assignAccountFormRef = ref();
const resetPasswordForm = reactive({
password: undefined,
});
const resetPasswordFormRef = ref();
const showResetPassword = ref(false);
const openAssignAccount = async (id) => {
resetForm();
const {have, data} = await getAccount(id);
if (have) {
ElMessageBox.alert(`已经存在账号:${data}`, "账号已经存在");
} else {
assignAccountForm.id = id;
showAssignAccount.value = true;
}
};
const openResetPassword = async (id) => {
resetForm();
const {have} = await getAccount(id);
if (have) {
resetPasswordForm.id = id;
showResetPassword.value = true;
} else {
ElMessageBox.alert(`尚未分配账号,请先分配账号`, "尚未分配账号");
}
};
const resetForm = () => {
if (resetPasswordFormRef.value) {
resetPasswordFormRef.value.resetFields();
}
if (assignAccountFormRef.value) {
assignAccountFormRef.value.resetFields();
}
resetPasswordForm.password = undefined;
assignAccountForm.username = undefined;
assignAccountForm.password = undefined;
};
const closeResetPassword = () => {
resetForm();
showResetPassword.value = false;
};
const closeAssignAccount = () => {
resetForm();
showAssignAccount.value = false;
};
const submitAssignAccount = async () => {
await assignAccountFormRef.value.validate();
await allocateAccount({
...assignAccountForm,
password: md5(assignAccountForm.password),
});
ElMessage.success("账号分配成功");
showAssignAccount.value = false;
};
const submitResetPassword = async () => {
await resetPasswordFormRef.value.validate();
await restPassword(resetPasswordForm.id, md5(resetPasswordForm.password));
ElMessage.success("密码重置成功");
showResetPassword.value = false;
};
//TODO:
/** 开通vip操作 */
const vipData = reactive({
vipForm: {userType: "1"},
});
const {vipForm} = toRefs(vipData);
const showOpenVip = ref(false);
const vipFormRef = ref();
const handleOpenVip = async (id) => {
resetVipForm();
const {have, userId} = await getAccount(id);
if (have) {
const resp = await getCasVip(userId);
if (resp.have) {
vipForm.value = resp.data;
showOpenVip.value = true;
} else {
vipForm.value.userId = userId;
vipForm.value.vipType = "0";
showOpenVip.value = true;
}
} else {
ElMessageBox.alert(`尚未分配账号,请先分配账号`, "尚未分配账号");
}
};
const submitVip = async () => {
await vipFormRef.value.validate();
if (vipForm.value.id) {
await updateCasVip(vipForm.value);
ElMessage.success("会员修改成功");
} else {
await openCasVip(vipForm.value);
ElMessage.success("会员开通成功");
}
showOpenVip.value = false;
};
const resetVipForm = () => {
vipForm.value = {userType: "1"};
if (vipFormRef.value) {
vipFormRef.value.resetFields();
}
};
const closeVip = () => {
resetVipForm();
showOpenVip.value = false;
};
/** 重置按钮操作 */
const resetQuery = () => {
dateRange.value = [];
if (queryFormRef.value) {
queryFormRef.value.resetFields();
}
handleQuery();
};
const handleAdd = () => {
router.push({
path: "/dataList/research-institutions/edit",
});
};
const handleDetail = (id) => {
router.push({
path: "/dataList/research-institutions/edit",
query: {id},
});
};
const uploadRef = ref(null);
/** 导入按钮操作 */
function handleImport() {
upload.title = "用户导入";
upload.open = true;
}
/** 下载模板操作 */
function importTemplate() {
proxy.download(
"system/user/importTemplate",
{},
`user_template_${new Date().getTime()}.xlsx`
);
}
/**文件上传中处理 */
const handleFileUploadProgress = (event, file, fileList) => {
upload.isUploading = true;
};
/** 文件上传成功处理 */
const handleFileSuccess = (response, file, fileList) => {
upload.open = false;
upload.isUploading = false;
uploadRef.value.handleRemove(file);
ElMessageBox.alert(
"<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" +
response.msg +
"</div>",
"导入结果",
{dangerouslyUseHTMLString: true}
);
getList();
};
/** 提交上传文件 */
function submitFileForm() {
uploadRef.value.submit();
}
const handleDelete = async (id) => {
const delIds = id || ids.value.join(",");
ElMessageBox.confirm(`是否确认删除编号为${delIds}的数据项?`)
.then(async () => {
await companyDelete(delIds);
getList();
ElMessage.success("删除成功");
})
.catch(() => {
});
};
let downloadLoadingInstance;
const download = (url, filename) => {
downloadLoadingInstance = ElLoading.service({
text: "正在下载数据,请稍候",
background: "rgba(0, 0, 0, 0.7)",
});
return request
.get(url, {
// transformRequest: [
// (params) => {
// return tansParams(params);
// },
// ],
headers: {"Content-Type": "application/x-www-form-urlencoded"},
responseType: "blob",
})
.then(async (data) => {
const isLogin = await blobValidate(data);
if (isLogin) {
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();
});
};
const handleExport = () => {
ElMessageBox.confirm(`是否确认企业列表?`).then(() => {
download(
`/business/enterprise/export`,
`企业信息(${dayjs().format("YYYYMMDDHHmmss")}).xlsx`
);
});
};
getList();
// getSiteList();
</script>

View File

@ -2,12 +2,12 @@
<div class="app-container">
<div style="width: 50%">
<ExpertForm
:isAdd="false"
v-model="form"
:showTitle="true"
:formType="formType"
:labelWidth="140"
ref="expertFormRef"
ref="expertFormRef"
v-model="form"
:formType="formType"
:isAdd="false"
:labelWidth="140"
:showTitle="true"
/>
</div>
<div :style="{ marginLeft: labelWidth + 'px' }">
@ -18,14 +18,15 @@
</div>
</template>
<script setup name="EnterpriseAdd">
<script name="EnterpriseAdd" setup>
import ExpertForm from "@/views/components/ExpertForm";
import tab from "@/plugins/tab";
import { companyAdd, companyDetail, companyEdit } from "@/api/expert/expert";
import { reactive, toRefs } from "vue";
import { useRoute, useRouter } from "vue-router";
import { ElMessage } from "element-plus";
import {companyDetail, companyEdit} from "@/api/expert/expert";
import {reactive, toRefs} from "vue";
import {useRoute, useRouter} from "vue-router";
import {ElMessage} from "element-plus";
import useUserStore from "@/store/modules/user";
const router = useRouter();
const route = useRoute();
const formType = ref(1);
@ -52,33 +53,21 @@ const data = reactive({
license: undefined,
},
});
const { form } = toRefs(data);
const {form} = toRefs(data);
const cancel = () => {
router.back();
tab.closeOpenPage();
};
const submitForm = async (state) => {
// const valid = await expertFormRef.value.validateForm();
// if (valid) {
// if (form.value.id != undefined) {
form.value.examineStatus = state;
await companyEdit(form.value);
await companyEdit({id: form.value.id, examineStatus: state});
useUserStore().getUnApprovedExpert();
cancel();
ElMessage.success("已审核");
// } else {
// await companyAdd(form.value);
// cancel();
// ElMessage.success("新增成功");
// }
// } else {
// console.log("校验未通过");
// }
};
const getDetailById = async () => {
if (route.query.id) {
const { data } = await companyDetail(route.query.id);
const {data} = await companyDetail(route.query.id);
form.value = data;
form.value.keywords = data.keyword ? data.keyword.split(",") : [];
form.value.district = data.area;

View File

@ -96,6 +96,7 @@ import SiteOptions from "@/views/components/SiteOptions";
import { tenantSelect } from "@/api/subPlatform/tenant";
import { expertList } from "@/api/expert/expert";
import { useRouter } from "vue-router";
import {reactive, ref, toRefs} from "vue";
const router = useRouter();
const data = reactive({
queryData: {

View File

@ -0,0 +1,115 @@
<template>
<div class="app-container">
<div style="width: 50%">
<laboratory-form
ref="expertFormRef"
v-model="form"
:isAdd="false"
:labelWidth="140"
:showTitle="true"
/>
</div>
<div :style="{ marginLeft: labelWidth + 'px' }">
<el-button @click="submitForm('2')">审核拒绝</el-button>
<el-button type="primary" @click="submitForm('1')">通过审核</el-button>
</div>
</div>
</template>
<script name="EnterpriseAdd" setup>
import LaboratoryForm from '@/views/components/LaboratoryForm'
import tab from "@/plugins/tab";
import {reactive, ref, toRefs} from "vue";
import {useRoute, useRouter} from "vue-router";
import {casLaboratoryDetail, casLaboratoryUpdate} from "@/api/dataList/laboratory";
const router = useRouter();
const route = useRoute();
const formType = ref(1);
const expertFormRef = ref(null);
const labelWidth = ref(140);
const data = reactive({
form: {
image: undefined,
name: undefined,
tenantId: undefined,
province: undefined, // 省code
city: undefined, // 市code
district: undefined, // 区code
address: undefined, // 详细地址
product: undefined,
kind: undefined,
code: undefined,
inviterCode: undefined,
url: undefined,
industrys: [],
keywords: [],
directions: [],
introduce: undefined,
license: undefined,
},
});
const {form} = toRefs(data);
const cancel = () => {
router.back();
tab.closeOpenPage();
};
const submitForm = async (state) => {
form.value.examineStatus = state;
await casLaboratoryUpdate({
id: form.value.id,
examineStatus: state
});
cancel()
// const valid = await expertFormRef.value.validateForm();
// if (valid) {
// if (form.value.id !== undefined) {
// form.value.examineStatus = state;
// await casLaboratoryUpdate(form.value);
// cancel();
// ElMessage.success("修改成功");
// }/* else {
// await companyAdd(form.value);
// useUserStore().getApprovalCount();
// cancel();
// ElMessage.success("新增成功");
// }*/
// } else {
// console.log("校验未通过");
// }
};
const getDetailById = async () => {
if (route.query.id) {
const {data} = await casLaboratoryDetail(route.query.id);
form.value = data;
form.value.researchDirection = data.researchDirection?.split(",")
form.value.district = data.area;
}
};
getDetailById();
</script>
<!-- <script>
export default {
components: {
ExpertForm,
},
data() {
return {
// formType: 2,
// labelWidth: 140,
};
},
methods: {},
created() {
const { id } = this.$route.query;
if (id) {
companyDetail({ id }).then((res) => {
form.value = res.data;
});
}
},
};
</script> -->

View File

@ -0,0 +1,158 @@
<template>
<div class="app-container">
<!-- 顶部搜索区域 -->
<el-form :inline="true" :model="queryData">
<el-form-item label="实验室名称">
<el-input
v-model="queryData.name"
placeholder="请输入关键字"
style="width: 150px"
></el-input>
</el-form-item>
<el-form-item label="审核状态">
<el-select
v-model="queryData.examineStatus"
class="m-2"
placeholder="请选择"
style="width: 100px"
>
<el-option :value="1" label="已审核"/>
<el-option :value="2" label="已拒绝"/>
</el-select>
</el-form-item>
<el-form-item style="float: right">
<el-button
icon="search"
size="default"
type="primary"
@click="handleQuery"
>搜索
</el-button
>
<el-button icon="refresh" size="default" @click="resetQuery"
>重置
</el-button
>
</el-form-item>
</el-form>
<!--表格区域-->
<el-table :data="dataList" style="width: 100%">
<el-table-column type="selection" width="55"/>
<el-table-column align="center" label="数据编号" prop="id"/>
<el-table-column align="center" label="实验室全称" prop="name"/>
<el-table-column align="center" label="所属院所或高校" prop="school"/>
<el-table-column align="center" label="实验室简介" show-overflow-tooltip>
<template #default="{ row }">
<div v-html="row.introduction"></div>
</template>
</el-table-column>
<el-table-column
align="center"
label="核心成员及简介"
show-overflow-tooltip
>
<template #default="{ row }">
<div v-html="row.member"></div>
<!-- {{ siteList.find((el) => el.id === row.tenantId)?.name ?? "无" }} -->
</template>
</el-table-column>
<el-table-column
align="center"
label="研究方向"
prop="researchDirection"
show-overflow-tooltip
/>
<el-table-column
align="center"
label="主要技术应用场景"
prop="primaryTechnology"
/>
<el-table-column align="center" label="所属行业领域" prop="industryStr"/>
<el-table-column align="center" label="联系电话" prop="phone"/>
<el-table-column align="center" label="网址" prop="url"/>
<el-table-column align="center" label="审核状态" prop="examineStatus">
<template #default="{ row }">
{{ examineStatusDict[row.examineStatus] }}
</template>
</el-table-column>
<el-table-column align="center" label="操作" prop="">
<template #default="{ row }">
<el-button size="small" type="text" @click="btnAudit(row.id)"
>审核
</el-button
>
</template>
</el-table-column>
</el-table>
<!-- 分页器 -->
<pagination
v-show="total > 0"
v-model:limit="queryData.page_size"
v-model:page="queryData.pageNum"
:total="total"
@pagination="getList"
/>
</div>
</template>
<script setup>
import {tenantSelect} from "@/api/subPlatform/tenant";
import {useRouter} from "vue-router";
import {reactive, ref, toRefs} from "vue";
import {casLaboratoryList} from "@/api/dataList/laboratory";
const router = useRouter();
const data = reactive({
queryData: {
pageNum: 1,
pageSize: 10,
examineStatus: "",
},
});
const total = ref(0);
const dataList = ref([]);
const siteList = ref([]);
const {queryData} = toRefs(data);
const examineStatusDict = {
0: "审核中",
1: "已通过",
2: "已拒绝",
};
// 获取专家列表
const getList = async () => {
const res = await casLaboratoryList(queryData.value);
dataList.value = res.rows;
total.value = res.total;
};
// 获取站点列表
const getSiteList = async () => {
const resp = await tenantSelect();
siteList.value = resp.rows;
};
// 搜索查询
const handleQuery = () => {
getList(queryData.value);
};
// 重置按钮
const resetQuery = () => {
queryData.value = {
pageNum: 1,
pageSize: 10,
examineStatus: "",
};
getList();
};
// 审核按钮
const btnAudit = (id) => {
router.push({
path: "/approval/data-list/laboratory/approval",
query: {id},
});
};
getList();
// getSiteList();
</script>
<style></style>

View File

@ -32,7 +32,7 @@ export default defineConfig(({ mode, command }) => {
// https://cn.vitejs.dev/config/#server-proxy
"/dev-api": {
// target: "http://192.168.110.10:1618",
target: "http://101.34.131.16:1618",
target: "http://192.168.0.201:1618",
changeOrigin: true,
rewrite: (p) => p.replace(/^\/dev-api/, ""),
},