This commit is contained in:
xuziqiang
2024-05-15 17:29:42 +08:00
commit d0155dbe3c
7296 changed files with 1832517 additions and 0 deletions

View File

@@ -0,0 +1,679 @@
<template>
<div style="display: flex" v-bind="$attrs">
<!-- {{ $attrs.value }} -->
<!-- {{simpleDayOptions}} -->
<!-- <div v-if="columsType == 'complexTable'" style="color: red; display: block; width: 100%">
服务频次对应每天每周每月每年均需要设置起止时间
</div>
<br /> -->
<div v-if="columsType == 'complexTable'">
<div v-if="columsType == 'complexTable'" style="color: red; display: block; width: 100%">
&nbsp;&nbsp;&nbsp; 服务频次对应每天每周每月每年均需要设置起止时间
<br />
<br />
</div>
<a-table :columns="colums" :data-source="$attrs.value" bordered :pagination="false">
<template
v-for="(item, index) in colums"
:key="index"
#[item.dataIndex]="text, record, index"
>
<!-- {{ text }} -->
<a-input
v-if="
item.otherConditions
? item.otherConditions && item.inputType == 'input'
: item.inputType == 'input'
"
style="margin: -5px 0"
:value="text.text"
@change="(e) => handleChangeIndex(e, text.index, item.dataIndex, item)"
/>
<div v-else-if="item.inputType == 'select'">
<div v-if="text.record[item.otherConditions] === 3 && item.dataIndex == 'day'">
<div style="display: inline-block">
<a-select
style="margin: -5px 0"
:value="text.text"
@change="(e) => handleChangeIndex(e, text.index, item.dataIndex)"
>
<a-select-option
v-for="(i, index) in simpleDayOptions"
:key="index"
:value="i.value"
>
{{ i.label }}
</a-select-option>
</a-select>
</div>
<div style="display: inline-block"> 日</div>
</div>
<div v-else-if="text.record[item.otherConditions] === 4 && item.dataIndex == 'month'">
<div style="display: inline-block">
<a-select
style="margin: -5px 0; display: inline-block"
:value="text.text"
@change="(e) => handleChangeIndex(e, text.index, item.dataIndex)"
>
<a-select-option
v-for="(i, index) in item.componentProps.options"
:key="index"
:value="i.value"
>
{{ i.label }}
</a-select-option>
</a-select>
</div>
<div style="display: inline-block">月</div>
</div>
<div v-else-if="text.record[item.otherConditions] === 4 && item.dataIndex == 'day'">
<div style="display: inline-block">
<a-select
style="margin: -5px 0"
:value="text.text"
@change="(e) => handleChangeIndex(e, text.index, item.dataIndex)"
>
<a-select-option
v-for="(i, index) in item.componentProps.options"
:key="index"
:value="i.value"
>
{{ i.label }}
</a-select-option>
</a-select>
</div>
<div style="display: inline-block">日</div>
</div>
<div v-else-if="text.record[item.otherConditions] === 2 && item.dataIndex == 'week'">
<a-select
style="margin: -5px 0"
:value="text.text"
@change="(e) => handleChangeIndex(e, text.index, item.dataIndex)"
>
<a-select-option
v-for="(i, index) in item.componentProps.options"
:key="index"
:value="i.value"
>
{{ i.label }}
</a-select-option>
</a-select>
</div>
</div>
<!-- <a-select
v-else-if="
text.record[item.otherConditions] == item.otherValue && item.inputType == 'select'
"
style="margin: -5px 0"
:value="text.text"
@change="(e) => handleChangeIndex(e.target.value, index, 'name')"
>
<a-select-option v-for="(i, index) in item.componentProps.options" :key="index">
{{ i.label }}
</a-select-option>
</a-select> -->
<a-time-picker
v-else-if="
item.otherConditions
? item.otherConditions && item.inputType == 'date'
: item.inputType == 'date'
"
style="width: 100px"
size="small"
:defaultValue="text.text ? moment(text.text, 'HH:mm:ss') : ''"
@change="(val, dateStrings) => changeTime(val, dateStrings, text.index, 'startTime')"
format="HH:mm:ss"
/>
<template
v-else-if="
item.otherConditions
? item.otherConditions && item.inputType == 'modal'
: item.inputType == 'modal'
"
>请选择</template
>
<template
v-else-if="
otherConditions
? otherConditions && item.inputType == 'input'
: item.inputType == 'operation'
"
>删除</template
>
<template v-else>{{ text.text }}</template>
</template>
</a-table>
</div>
<div v-else-if="columsType == 'normalTable'">
<!-- {{ $attrs.value }}--900099 -->
<a-table :columns="colums" :data-source="$attrs.value" bordered :pagination="false">
<template
v-for="(item, index) in colums"
:key="index"
#[item.dataIndex]="text, record, index"
>
<!-- {{ item }} -->
<a-input
v-if="item.inputType == 'input'"
style="margin: -5px 0"
:value="text.text"
@change="(e) => handleChangeIndex(e, text.index, item.dataIndex, item)"
/>
<div v-else-if="item.inputType == 'select'">
<a-select
style="margin: -5px 0; display: inline-block"
:value="text.text"
@change="(e) => handleChangeIndex(e, text.index, item.dataIndex)"
>
<a-select-option
v-for="(i, index) in item.componentProps.options"
:key="index"
:value="i.value"
>
{{ i.label }}
</a-select-option>
</a-select>
</div>
<div v-else-if="item.inputType == 'selectElse'">
<!-- {{ item.componentProps }} -->
<a-select
style="margin: -5px 0; display: inline-block"
:value="text.text"
@change="(e) => handleChangeIndex(e, text.index, item.dataIndex, item)"
>
<a-select-option
v-for="(i, index) in item.componentProps.options"
:key="index"
:value="i.value"
>
{{ i.label }}
</a-select-option>
</a-select>
</div>
<div v-else-if="item.inputType == 'selectApi'">
<NsSelectApi
v-bind="item.componentProps"
:value="text.text"
@change="(e) => handleChangeIndex(e, text.index, item.dataIndex)"
/>
</div>
<div v-else-if="item.inputType == 'upload'">
<NvUpload v-bind="item.componentProps" :value="text.text" />
</div>
<div v-else-if="item.inputType == 'date'">
<a-time-picker
style="width: 100px"
size="small"
:value="text.text ? moment(text.text, 'HH:mm:ss') : ''"
:defaultValue="text.text ? moment(text.text, 'HH:mm:ss') : ''"
@change="
(val, dateStrings) => changeTime(val, dateStrings, text.index, item.dataIndex)
"
format="HH:mm:ss"
/></div>
<template v-else-if="item.inputType == 'modal'">
<!-- 请选择 -->
<NsModalTable
v-bind="{
...item.componentProps,
record: text.record,
valueP: text.text,
dataIndex: item.dataIndex,
}"
@changeTable="changeTable"
:value="text.text"
/>
</template>
<template v-else-if="item.inputType == 'operation'">
<span v-for="(it, indexs) in item.componentProps.actionOptions" :key="indexs">
<span
:style="{ color: it.color }"
style="margin-left: 5px"
@click="optionA(it.value, text.record, text.index)"
>{{ it.name }}</span
>
</span>
</template>
<template v-else>{{ text.text }}</template>
</template>
<template #footer="currentPageData">
<!-- {{ currentPageData }} -->
<span style="font-size: 22px; margin-left: 50%" @click="add(currentPageData)">+</span>
</template>
</a-table>
</div>
<div v-else>
<a-row>
<a-col :span="12">
<div>未选择</div>
<br />
<a-row>
<a-col :span="12">护理类别:</a-col>
<a-col :span="12"
><ns-select :options="optionSlect" @change="handleChangeViewList"
/></a-col>
</a-row>
<br />
<div>
<a-table
:columns="viewColums"
:data-source="careItems"
:row-selection="rowSelection"
:pagination="false"
bordered
/>
</div>
</a-col>
<a-col :span="12">
<div>已选择</div>
<!-- <br /> -->
<div style="height: 8px"></div>
<br />
<br />
<br />
<a-table :columns="colums" :data-source="$attrs.value" :pagination="false" bordered>
<template
v-for="(item, index) in colums"
:key="index"
#[item.dataIndex]="text, record, index"
>
<!-- {{ text }} -->
<a-input
v-if="item.inputType == 'input'"
style="margin: -5px 0"
:value="text.text"
@change="(e) => handleChangeIndex(e, text.index, item.dataIndex, item)"
/>
<a-select
v-else-if="item.inputType == 'select'"
style="margin: -5px 0"
:value="text.text"
@change="(e) => handleChangeIndex(e, text.index, item.dataIndex, item)"
>
<a-select-option v-for="(i, index) in item.componentProps.options" :key="index">
{{ i.label }}
</a-select-option>
</a-select>
<template v-else-if="item.inputType == 'modal'">请选择</template>
<template v-else-if="item.inputType == 'operation'"
><span @click="handleDelete(text.index)" style="cursor: pointer">
删除
</span></template
>
<template v-else>{{ text.text }}</template>
</template>
</a-table>
</a-col>
</a-row>
</div>
</div>
</template>
<script lang="ts">
import moment from 'moment';
import { defineComponent, ref, watch } from 'vue';
import { NsMessage } from '../../message';
import { http } from '/nerv-lib/util/http';
import NsModalTable from './modal-table.vue';
import NvUpload from './uplods.vue';
export default defineComponent({
name: 'NsEtable',
components: {
NsModalTable,
NvUpload,
},
props: {
colums: {
type: Array,
},
viewColums: {
type: Array,
},
tableData: {
type: Array,
},
attribute: {
type: String,
},
onchange: {
type: Function,
},
columsType: {
type: String,
},
getChildrenOptions: {
type: Function,
},
addlist: {
type: Object,
},
},
emits: ['change', 'updata:longLat', 'validate', 'getChildrenOptions'],
setup(props, context) {
let data = [];
let propsData = ref();
let ids = ref(9);
const dependency = ref();
const selectElseOption = ref([]);
const rowSelection = {
type: 'checkbox',
onChange: (selectedRowKeys: [], selectedRows: []) => {
let dpData = context.attrs.value ? JSON.parse(JSON.stringify(context.attrs)) : [];
const newData = [...dpData.value];
selectedRows.forEach((item) => {
newData.push({
nursingItemUuid: item['uuid'],
nursingItemName: item['itemName'],
frequency: 1,
times: 1,
});
});
context.emit('change', newData);
},
};
const optionSlect = [
{
label: '全部',
value: 'all',
},
{
label: '生活护理',
value: 1,
},
{
label: '医疗护理',
value: 2,
},
{
label: '康复护理',
value: 3,
},
];
propsData = context.attrs.value ? JSON.parse(JSON.stringify(context.attrs.value)) : [];
console.log(propsData, '98777');
let simpleDayOptions = ref([]);
for (let i = 0; i < 28; i++) {
let item = {
label: '' + (i + 1),
value: i + 1,
};
simpleDayOptions.value.push(item);
}
let careItems = ref([]);
const handleChangeViewList = (value) => {
let api = '/api/pension/pension/objs/NursingItem';
http
.get(api, {
itemType: value == 'all' ? '' : value,
enable: true,
pageSize: 10,
})
.then((res) => {
if (res && res.success) {
careItems.value = res.data.data;
// NsMessage.success('操作成功');
}
})
.catch(() => {
NsMessage.error('列表获取失败');
});
};
handleChangeViewList('all');
const add = (e) => {
console.log(props.addlist, 'opopop');
// let data = {
// regionUuid: null,
// inspectionTime: null,
// personList: null,
// relation: null,
// // uuid:
// };
let list = JSON.parse(JSON.stringify(props.addlist));
let data = { ...list };
let edList = context.attrs.value ? JSON.parse(JSON.stringify(context.attrs.value)) : [];
ids.value += 1;
edList.push({ ...data, uuid: ids.value + 'uuid' });
context.emit('change', edList);
// console.log(e, JSON.parse(JSON.stringify(context.attrs.value)), 'add');
};
const changeTable = (item) => {
let currentList = JSON.parse(JSON.stringify(context.attrs.value));
currentList &&
currentList instanceof Array &&
currentList.length > 0 &&
currentList.forEach((its) => {
if (its.uuid == item.uuid) {
its = Object.assign(its, item);
}
});
context.emit('change', currentList);
};
// 表格列操作方法
const optionA = (name, actionInfo, ind) => {
let edList = context.attrs.value ? JSON.parse(JSON.stringify(context.attrs.value)) : [];
if (name == 'delete') {
edList.splice(ind, 1);
// console.log(edList, 'edlist');
} else if (name == 'copy') {
// console.log('00000');
ids.value += 1;
edList.push({ ...actionInfo, uuid: ids.value + 'uuid' });
}
context.emit('change', edList);
};
const getElseOptins = (name, value, fieldName, index) => {
console.log(name, value, fieldName, index, 'zhougg');
let acinfo = props && props.colums && props.colums[index];
console.log(acinfo, 'acinfo');
let api = acinfo.componentProps.api;
let params = {
...acinfo.componentProps.params,
[name]: value,
};
console.log(params, 'acparams');
// let api = '/api/pension/pension/objs/NursingItem';
http
.get(api, { ...params })
.then((res) => {
if (res && res.success) {
console.log(acinfo.componentProps.selectElseOption, 'acinfo.componentProps');
res.data &&
res.data.forEach((item) => {
if (item.dictValue == value) {
let arr = [];
item.subList &&
item.subList.forEach((it) => {
arr.push({
label: it.dictName,
value: it.dictValue,
});
});
selectElseOption.value = arr;
console.log(item.subList, 'sublist');
}
});
// careItems.value = res.data.data;
// NsMessage.success('操作成功');
}
})
.catch(() => {
NsMessage.error('列表获取失败');
});
};
// dependency
watch(dependency, (newValue, oldValue) => {
console.log('old', oldValue);
console.log('new', newValue);
});
return {
data,
simpleDayOptions,
rowSelection,
optionSlect,
handleChangeViewList,
careItems,
add,
changeTable,
optionA,
getElseOptins,
selectElseOption,
};
},
data() {
return {
editingKey: '',
propsList: [],
Month2Day: {
1: 31,
2: 28,
3: 31,
4: 30,
5: 31,
6: 30,
7: 31,
8: 31,
9: 30,
10: 31,
11: 30,
12: 31,
},
};
},
created() {
this.propsList = this.$attrs.value ? JSON.parse(JSON.stringify(this.$attrs.value)) : [];
},
methods: {
moment,
changeTime(val, dateStrings, key, type) {
let datapro = this.$attrs.value ? JSON.parse(JSON.stringify(this.$attrs.value)) : [];
const newData = [...datapro];
const target = newData.filter((item, index) => key === index)[0];
if (type == 'startTime' && target['endTime']) {
if (this.timeCompare(dateStrings, target['endTime'])) {
NsMessage.error('开始时间不能大于结束时间');
}
} else if (type == 'endTime') {
if (this.timeCompare(target['startTime'], dateStrings)) {
NsMessage.error('开始时间不能大于结束时间');
}
}
if (target) {
target[type] = dateStrings;
this.$emit('change', newData);
// this.$emit('validate', false);
// this.propsList = newData;
}
},
timeCompare(start, end) {
let flag = true;
if (!start || !end) return true;
let startH = +start.split(':')[0];
let startM = +start.split(':')[1];
let endH = +end.split(':')[0];
let endM = +end.split(':')[1];
// 开始小时大于结束小时
if (startH > endH) {
flag = false;
} else if (startH == endH) {
// 小时相等时,开始分钟大于结束分钟
if (startM >= endM) {
flag = false;
}
}
return flag;
},
handleChangeIndex(value, key, type, item) {
console.log(value, key, type, 'zhouhaha');
let propsInfo = this.$attrs.value ? JSON.parse(JSON.stringify(this.$attrs.value)) : [];
const newData = [...propsInfo];
console.log(newData, 'newData');
console.log([...this.propsList], 'newData');
console.log(this.propsList, 'newData');
const target = newData.filter((item, index) => key === index)[0];
if (type == 'month') {
this.colums &&
this.colums.forEach((item: any) => {
if (item.dataIndex == 'day') {
item.componentProps.options = this.setOptions(this.Month2Day[value], 'dayOptions');
}
});
}
console.log(target, 'target');
if (target) {
target[type] = value;
console.log(newData, 'newData');
this.$emit('change', newData);
// this.propsList = newData;
}
this.colums &&
this.colums.forEach((item, index) => {
console.log(item, item.dependency, '564');
if (item.dependency == type) {
// console.log('lopppp');
this.$emit('getChildrenOptions', item.dependency, value, item.dataIndex);
this.getElseOptins(item.dependency, value, item.dataIndex, index);
}
});
},
handleDelete(e) {
let data = this.$attrs.value ? JSON.parse(JSON.stringify(this.$attrs.value)) : [];
let newData = data.filter((item, index) => e !== index);
// console.log(newData);
this.$emit('change', newData);
},
setOptions(number: number, type: string) {
let arr = [];
for (let i = 0; i < number; i++) {
let item = {
label: '' + (i + 1),
value: i + 1,
};
arr.push(item);
}
return arr;
},
},
});
</script>
<style lang="less" scoped>
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
}
#map-container {
width: 600px;
height: 400px;
}
.leftBox,
.rightBox {
flex: 1;
}
.inputArea {
display: flex;
line-height: 30px;
}
.inputSearch {
.inputAdress {
width: 300px;
margin-right: 10px;
}
}
</style>

View File

@@ -0,0 +1,4 @@
import etable from './etable.vue';
import { withInstall } from '/nerv-lib/util';
export const NsEtable = withInstall(etable);

View File

@@ -0,0 +1,308 @@
<template>
<div style="">
<span @click="chose" v-if="!label" style="cursor: pointer">请选择</span>
<span @click="chose" v-else style="cursor: pointer; color: rgb(14, 210, 191)">
{{ label }}
</span>
</div>
<div id="inputarea">
<a-modal
v-model:visible="visible"
:maskClosable="false"
@ok="handleOk"
@cancel="cancel"
width="900px"
style="top: 3%"
:title="title"
>
<!-- <p class="title">{{ title }}</p> -->
<div v-if="ifTab">
<a-tabs v-model:activeKey="activeKey">
<a-tab-pane v-for="(item, index) in tabs" :key="index">
<template #tab>
<span> {{ item.name }} </span>
</template>
<ns-view-list-table v-bind="item.tableConfig" :row-selection="rowSelection" />
</a-tab-pane>
</a-tabs>
</div>
<div v-else>
<ns-view-list-table v-bind="tableConfig" :row-selection="rowSelection" />
</div>
</a-modal>
</div>
</template>
<script lang="ts">
import { runInThisContext } from 'node:vm';
import { defineComponent, ref } from 'vue';
import AppVue from '/@/App.vue';
// let rowSelection='';
export default defineComponent({
name: 'NsModalTable',
props: {
api: {
type: String,
default: '',
},
defaultKey: {
type: String || Array,
default: '',
},
alert: {
type: String,
default: '',
},
addonAfter: {
type: String,
default: '',
},
ifTab: {
type: Boolean,
default: false,
},
tabs: {
type: Array,
default: () => [],
},
tableConfig: {
type: Object,
default: () => {},
},
labelValue: {
type: String,
default: '',
},
keyValue: {
type: String || Array,
default: '',
},
field: {
type: String,
},
type: {
type: String,
default: 'radio',
},
formModel: {
type: Object,
},
allowClear: { type: Boolean },
size: { type: String },
disabled: { type: Boolean },
id: { type: String },
title: {
type: String,
},
changeTable: {
type: Function,
},
record: {
type: Object,
},
dataIndex: {
type: String,
},
// 需要该条数据上的更多信息
extraSelect: {
type: Array,
},
valueP: {
type: Object || String,
},
// 显示在界面上的字段名
showLabelValue: {
type: String,
},
},
emits: ['change', 'blur', 'changeTable'],
setup(props, { emit, attrs }) {
// console.log(JSON.parse(JSON.stringify(props.record)), 'zhouzhoutedfg');
// console.log(attrs, 'attrs123');
let newValue = attrs.value;
var label = '';
let showlabel = ref();
showlabel = props.showLabelValue;
// console.log(props.dataIndex, 'zhouzhou');
let actionInfo = props.record;
if (props.dataIndex) {
label = actionInfo && actionInfo[props.dataIndex + 'Name'];
// console.log(label, 'zhouxxlabel');
}
if (showlabel) {
label = props.record && props.record[showlabel];
let labelType = props.valueP;
if (labelType && labelType instanceof Array && labelType.length > 0) {
let arr: any[] = [];
labelType.forEach((element: { [x: string]: any }) => {
if (element[showlabel]) {
arr.push(element[showlabel]);
}
});
label = arr.join(',');
}
// console.log(props.valueP, 'valueP');
emit('change', props.valueP);
}
if (newValue) {
// console.log(newValue, 'label');
label = newValue;
emit('change', props.valueP);
}
return {
label,
};
},
data(props) {
return {
activeKey: 0,
visible: false,
key: props.defaultKey || '' || [],
roomUuid: '',
//是否选中后在取消的值
iflabelValue: '',
ifkeyValue: props.defaultKey || '' || [],
selectedRows: [],
// label: '',
rowSelection: {
type: props.type,
//默认选中
getCheckboxProps(record: { [x: string]: string }) {
let uuid = [] || '';
//如果有多个table
if (props.ifTab) {
for (const iterator of props.tabs) {
(uuid as Array<any>).push(iterator.tableConfig.rowKey);
}
//单选
if (props.type == 'radio') {
for (const iterator of uuid) {
if (iterator in record) {
return {
defaultChecked: record[iterator] == props.defaultKey, // 配置默认勾选的列
};
}
}
}
//多选
else if (props.type == 'checkbox') {
for (const iterator of uuid) {
if (iterator in record) {
for (const defaultKey of props.defaultKey) {
return {
defaultChecked: record[iterator] == defaultKey, // 配置默认勾选的列
};
}
}
}
}
}
//单个table
else {
if (props.type == 'radio') {
return {
defaultChecked: record[props.keyValue] == props.defaultKey, // 配置默认勾选的列
};
} else if (props.type == 'checkbox') {
for (const iterator of props.defaultKey) {
return {
defaultChecked: record[props.keyValue] == iterator, // 配置默认勾选的列
};
}
}
}
},
onChange: (selectedRowKeys: [], selectedRows: []) => {
let labelDemo = [];
let selectedRowsValue = JSON.parse(JSON.stringify(selectedRows));
this.selectedRows = JSON.parse(JSON.stringify(selectedRows));
if (props.type == 'radio') {
this.ifkeyValue = selectedRowKeys[0];
this.iflabelValue = selectedRowsValue[0][this.labelValue];
} else if (props.type == 'checkbox') {
for (const iterator of selectedRowsValue) {
labelDemo.push(iterator[this.labelValue]);
}
this.ifkeyValue = selectedRowKeys;
this.iflabelValue = labelDemo.join();
}
},
},
};
},
mounted() {
// this.set(obj, "newField", "newData")
},
methods: {
chose() {
this.visible = true;
},
handleOk() {
//确定--需要赋值
let that = this;
this.label = this.iflabelValue;
this.key = this.ifkeyValue;
// console.log(this.label, this.key, '我是周周子组件,哈哈哈');
let data = {
name: this.label,
value: this.key,
};
let moreSelects: any;
let selectedItems = JSON.parse(JSON.stringify(this.selectedRows));
// console.log(selectedItems, 'selectedItemszhouzhou ');
selectedItems &&
selectedItems.forEach((it) => {
if (this.extraSelect) {
this.extraSelect.forEach((element) => {
moreSelects = {
...moreSelects,
[element.name]: it[element.value],
};
});
// item = Object.assign(item, moreSelects);
}
});
let changeData = Object.assign(this.record, moreSelects);
changeData[this.dataIndex] = this.key;
changeData[this.dataIndex + `Name`] = this.label;
// console.log(changeData, 'changeData');
this.$emit('changeTable', changeData);
this.visible = false;
},
cancel() {
console.log('cancle');
//取消-不需要赋值
this.visible = false;
},
},
});
</script>
<style lang="less" scoped>
.ns-area:hover,
:focus {
color: white !important;
}
.ns-area {
color: white;
}
:deep(.ant-input) {
background: rgba(223, 227, 233, 0.5);
border-right: 0;
}
:deep(.ant-input:focus) {
border-color: rgba(223, 227, 233, 0.5);
border-right-width: 0 !important;
outline: 0;
box-shadow: none;
}
:deep(.ns-area) {
border: 0;
}
</style>

View File

@@ -0,0 +1,323 @@
<template>
<div>
<div>
<a-upload
:before-upload="beforeUpload"
@change="handleChange"
:multiple="count != 1"
:customRequest="selfUpload"
:showUploadList="false"
>
<!-- {{ $attrs.value }} -->
<span style="color: #17be6b">{{ $attrs.value ? '证书文件' : fileName }}&nbsp;&nbsp;</span>
<span>上传pdf文件</span>
</a-upload>
<!-- 上传图片框/内置input /-->
</div>
<!-- 错误消息提示 -->
<div class="err-msg" v-if="!isJpgOrPngOrJpeg">
<p>{{ fileName }} 文件上传失败</p>
<p :style="{ color: 'red' }"> 请选择{{ fileType.join(',') }}123 </p>
</div>
<div class="err-msg" v-if="isJpgOrPngOrJpeg ? !isLt5M : ''">
<p>{{ fileName }} 文件上传失败</p>
<p :style="{ color: 'red' }"> 请选择{{ maxSize / 1024 / 1024 }} </p>
</div>
<!-- 错误消息提示 /-->
</div>
</template>
<script lang="ts">
import { defineComponent, ref, computed } from 'vue';
import { http } from '/nerv-lib/util/http';
import { NsMessage } from '../../message';
import { context } from 'ant-design-vue/es/vc-image/src/PreviewGroup';
interface FileItem {
uid: string;
type: string;
size: number;
name?: string;
status?: string;
response?: string;
percent?: number;
url?: string;
preview?: string;
originFileObj?: any;
}
interface FileInfo {
file: FileItem;
fileList: FileItem[];
}
// 转base64
function getBase64(file: File) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = (error) => reject(error);
});
}
export default defineComponent({
name: 'NvUpload',
components: {},
props: {
// 上传的地址
url: {
type: String,
require: true,
},
// 上传的图片大小
// maxSize: {
// type: Number,
// / default: 5242880,
// },
// 上传的图片类型
fileType: {
type: Array,
default: () => {
return ['jpg', 'png', 'jpeg'];
},
},
// 展示图片数量
count: {
type: Number,
default: 1,
},
// 上传文件类型0-证书1-图片2-身份证件
uploadType: {
type: Number,
default: 1,
},
},
emits: ['change'],
setup(props, { emit, attrs }) {
console.log(props, 'propslk');
const host = window.location.host;
const previewVisible = ref<boolean>(false);
const isLt5M = ref<boolean>(true);
const isJpgOrPngOrJpeg = ref<boolean>(true);
const previewImage = ref<string | undefined>('');
const fileName = ref<string | undefined>('');
const fileList = ref<FileItem[]>([]);
const currentImg = ref<string[]>([]);
const maskShow = ref<boolean[]>([]);
const fileUuid = ref<string>('');
// console.log(attrs.value, 'uuuuiiiii');
// fileName = `http://` + host + `/api/pension/pension/objs/CertificateFile/` + attrs.value;
const acceptType = computed(() =>
props.fileType.map((item: String) => {
return 'application/' + item;
})
);
const beforeUpload = (file: FileItem) => {
// 上传出错后下次上传图片前重置为true让图片可以上传
isLt5M.value = true;
isJpgOrPngOrJpeg.value = true;
// 限制图片格式,服务器不支持gif图片
if (file.type === 'image/gif') {
NsMessage.warn('不支持gif图片');
return false;
}
console.log(file.type, acceptType.value, 'zhouzhuupload');
isJpgOrPngOrJpeg.value = acceptType.value.includes(file.type);
// 如果大于指定的大小,显示错误信息
// if (file.size > props.maxSize) {
// isLt5M.value = false;
// }
fileName.value = file.name;
return isLt5M.value && isJpgOrPngOrJpeg.value;
};
const handleChange = ({ fileList: newFileList }: FileInfo) => {
console.log(fileList, 'FileInfo');
// 单图上传
// if (props.count === 1) {
// // 删除图片时newFileList.length = 0
// // 图片大小不符合规范时,!isLt5M.value为true
// if (!isLt5M.value || !isJpgOrPngOrJpeg.value || newFileList.length - 1 < 0) {
// // 让图片不显示,也不上传
// fileList.value = [];
// } else {
// // 添加\更换图片
// // newFileList[newFileList.length - 1]的目的是为了只显示最新一张图片
// fileList.value = [newFileList[newFileList.length - 1]];
// }
// } else {
// // 多图上传
// if (!isLt5M.value || !isJpgOrPngOrJpeg.value) {
// fileList.value = newFileList.slice(0, newFileList.length - 1);
// } else {
// fileList.value = newFileList;
// }
// }
};
const selfUpload = async ({ file }) => {
console.log(file, 'file');
const params = {
uploadType: props.uploadType,
};
const formData = new FormData();
formData.append('file', file);
formData.append('uploadType', props.uploadType);
const config = {
headers: {
'Content-Type': 'multipart/form-data',
},
params: params,
};
console.log('uploading....', props.url, formData, config);
http
.post(props.url, formData, config)
.then((res) => {
fileUuid.value = res.data.fileUuid;
emit('change', fileUuid.value);
})
.catch((e) => {
console.log(e, 'e');
NsMessage.error('上传失败,请重试');
});
};
const handlePreview = async (index: number) => {
previewImage.value = (await getBase64(fileList.value[index].originFileObj)) as string;
previewVisible.value = true;
};
const deleteImg = (index: number) => {
currentImg.value.splice(index, 1);
fileList.value.splice(index, 1);
};
const handleCancel = () => {
previewVisible.value = false;
};
const mouseEnter = (index: number) => {
maskShow.value[index] = true;
};
const mouseLeave = (index: number) => {
maskShow.value[index] = false;
};
return {
previewVisible,
previewImage,
fileList,
isLt5M,
isJpgOrPngOrJpeg,
fileName,
currentImg,
maskShow,
fileUuid,
selfUpload,
handleCancel,
handlePreview,
handleChange,
beforeUpload,
mouseEnter,
mouseLeave,
deleteImg,
};
},
});
</script>
<style>
.ant-upload-picture-card-wrapper .ant-upload.ant-upload-select-picture-card {
margin: 0;
width: 80px;
height: 80px;
border: 1px solid #d9d9d9;
}
.ant-upload-picture-card-wrapper .ant-upload.ant-upload-select-picture-card:hover {
border-color: #d9d9d9;
}
.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
color: #666;
font-size: 12px;
}
.ant-upload-picture-card-wrapper .ant-upload-list-picture-card-container {
width: 88px;
height: 80px;
}
.ant-upload-picture-card-wrapper .ant-upload-list-picture-card .ant-upload-list-item {
margin: 0;
padding: 0;
width: 80px;
height: 80px;
}
.title,
.err-msg {
text-align: left;
}
.err-msg p {
margin: 0;
}
.container {
display: flex;
}
.imgList {
display: flex;
}
.imgContainer {
margin-right: 16px;
border: 1px solid #d9d9d9;
position: relative;
}
.imgCover {
width: 80px;
height: 80px;
object-fit: contain;
}
.imgContainer .mask {
position: absolute;
top: 0;
left: 0;
width: 80px;
height: 80px;
background: rgba(0, 0, 0, 0.5);
text-align: center;
line-height: 80px;
}
.mask .anticon-eye {
color: white;
margin-right: 18px;
}
.mask .anticon-eye:hover {
color: #00acff;
margin-right: 18px;
}
.mask .anticon-delete {
color: white;
}
.mask .anticon-delete:hover {
color: #00acff;
}
</style>