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,452 @@
<template>
<div>
<div class="container clearfix">
<!-- 图片显示框 -->
<template v-if="currentImg.length">
<div class="imgList" v-for="(item, index) in fileList" :key="item">
<div class="imgContainer" @mouseenter="mouseEnter(index)" @mouseleave="mouseLeave(index)">
<img :src="currentImg[index]" class="imgCover" />
<span v-if="maskShow[index]" class="mask">
<EyeOutlined v-if="false" @click="handlePreview(item, index)" />
<DeleteOutlined @click="deleteImg(index)" />
</span>
</div>
</div>
</template>
<!-- 图片显示框 /-->
<!-- 上传图片框/内置了input -->
<a-upload
list-type="picture-card"
:before-upload="beforeUpload"
@change="handleChange"
:multiple="count != 1"
:customRequest="selfUpload"
:showUploadList="false"
>
<!-- :disabled="count == 1 && fileUuid ? true : false" -->
<div v-if="count === 1 ? 'true' : fileList.length < count">
<template v-if="isLt5M && isJpgOrPngOrJpeg">
<UploadOutlined :style="{ fontSize: '14px' }" />
<div class="ant-upload-text">上传图片</div>
</template>
<template v-else>
<LoadingOutlined />
<div class="ant-upload-text">校验失败</div>
</template>
</div>
</a-upload>
<!-- 上传图片框/内置input /-->
</div>
<!-- 预览图片弹窗 -->
<a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
<img alt="example" style="width: 100%" :src="'/api/ihorn/objs/pictureBack/' + previewImage" />
</a-modal>
<!-- 预览图片弹窗 /-->
<!-- 错误消息提示 -->
<div class="err-msg" v-if="!isJpgOrPngOrJpeg">
<p>{{ fileName }} 文件上传失败</p>
<p :style="{ color: 'red' }"> 请选择{{ fileType.join(',') }}的图片 </p>
</div>
<div class="err-msg" v-if="isJpgOrPngOrJpeg ? !isLt5M : ''">
<p>{{ fileName }} 文件上传失败</p>
<p :style="{ color: 'red' }"> 请选择{{ maxSize / 1024 / 1024 }}M内的图片 </p>
</div>
<!-- 错误消息提示 /-->
</div>
</template>
<script lang="ts">
import {
UploadOutlined,
LoadingOutlined,
EyeOutlined,
DeleteOutlined,
} from '@ant-design/icons-vue';
import { defineComponent, ref, computed } from 'vue';
import { http } from '/nerv-lib/util/http';
import { NsMessage } from '/nerv-lib/component/message';
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) => {
console.log(file);
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = () => resolve(reader.result);
reader.onerror = (error) => reject(error);
});
}
export default defineComponent({
name: 'NsUpload',
components: {
UploadOutlined,
LoadingOutlined,
DeleteOutlined,
EyeOutlined,
},
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,
},
baseImageUrl: {
type: [String, Object],
},
},
emits: ['change'],
setup(props, { emit }) {
const previewVisible = ref<boolean>(false);
const isLt5M = ref<boolean>(true);
const isJpgOrPngOrJpeg = ref<boolean>(true);
const previewImage = ref<string | undefined>('');
const fileList = ref<FileItem[]>([]);
const currentImg = ref<string[]>([]);
const isIntImg = ref(false);
if (props.baseImageUrl) {
isIntImg.value = true;
if (typeof props.baseImageUrl == 'object') {
// currentImg.value.concat(props.baseImageUrl);
props.baseImageUrl.map((item, index) => {
fileList.value.push(item);
currentImg.value.push(item);
// previewImage.value = props.baseImageUrl[index];
});
// currentImg.value.unshift(...props.baseImageUrl);
} else {
fileList.value.push({});
currentImg.value.unshift(props.baseImageUrl);
previewImage.value = props.baseImageUrl;
}
}
const fileName = ref<string | undefined>('');
const maskShow = ref<boolean[]>([]);
const fileUuid = ref<string>('');
const acceptType = computed(() =>
props.fileType.map((item: String) => {
return 'image/' + item;
})
);
const beforeUpload = (file: FileItem) => {
// 上传出错后下次上传图片前重置为true让图片可以上传
isLt5M.value = true;
isJpgOrPngOrJpeg.value = true;
// 限制图片格式,服务器不支持gif图片
if (file.type === 'image/gif') {
NsMessage.warn('不支持gif图片');
return false;
}
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) => {
// 单图上传
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 (typeof props.baseImageUrl == 'object') {
// props.baseImageUrl.map((item, index) => {
// console.log(item);
// fileList.value.push(item);
// // currentImg.value.unshift(item);
// // previewImage.value = props.baseImageUrl[index];
// });
// }
if (!isLt5M.value || !isJpgOrPngOrJpeg.value) {
// fileList.value = newFileList.slice(0, newFileList.length - 1);
// fileList.value = fileList.slice(0, fileList.length - 1);
// console.log(123444, fileList.value, newFileList);
} else {
fileList.value.push(newFileList);
emit('change', fill(fileList.value));
// fileList.value = newFileList;
}
}
};
const fill = (data) => {
let arr = [];
if (props.count == 1) return;
data.map((item) => {
if (item.indexOf('ParkPic') !== -1) {
arr.push(item.split('ParkPic/')[1]);
}
});
return arr;
};
const selfUpload = async ({ file }) => {
if (props.count !== 1) {
emit('change', fill(fileList.value));
}
currentImg.value.push(await getBase64(file));
const params = {
uploadType: props.uploadType,
};
const formData = new FormData();
formData.append('file', file);
formData.append('uploadType', props.uploadType);
//formData.append('uploadType', 1);
const config = {
headers: {
'Content-Type': 'multipart/form-data',
},
// params: params,
};
console.log(formData);
if (props.count == 1) {
fileUuid.value = 'ceshi';
}
http
.post(props.url, formData, config)
.then((res) => {
if (props.count > 1) {
// let imgBox = ref([]);
console.log(fileList.value);
fileList.value.push('/api/ihorn/objs/pictureBack/' + res.data.fileUuid);
fileList.value.forEach((item, index) => {
if (typeof item == 'object') {
fileList.value.splice(index, 1);
}
});
emit('change', fill(fileList.value));
} else {
fileUuid.value = res.data.picUuid || res.data.fileUuid;
emit('change', fileUuid.value);
}
})
.catch(() => {
fileList.value.forEach((item, index) => {
if (typeof item == 'object') {
fileList.value.splice(fileList.value.length - 1, 1);
}
});
NsMessage.error('上传失败,请重试');
});
};
const handlePreview = async (item, index: number) => {
// emit('change', fill(fileList.value));
console.log(item, index);
if (props.count > 1) {
previewImage.value = fileList.value[index];
} else {
previewImage.value = fileUuid.value;
}
// if (!isIntImg.value) {
// previewImage.value = (await getBase64(fileList.value[index])) as string;
// // 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);
fileUuid.value = '';
isIntImg.value = false;
if (props.count == 1) {
emit('change', fileUuid.value);
} else {
emit('change', fill(fileList.value));
}
};
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>

View File

@@ -0,0 +1,734 @@
<!-- @format -->
<template>
<div>
<ns-view-add-form
:schemas="formSchema"
:model="data"
:title="uuid ? '编辑角色' : '添加角色'"
:api="uuid ? '/api/community/objs/Role/update' : '/api/community/objs/Role'" />
</div>
</template>
<script lang="ts">
import { defineComponent, reactive, ref, provide, watch } from 'vue';
import { useRouter } from 'vue-router';
import { http } from '/nerv-lib/util/http';
import RoleAuthority from './component/roleAuthority.vue';
export default defineComponent({
name: 'NsViewRoleTypeAddOrEdit',
components: {
RoleAuthority,
},
setup() {
provide('components', () => {
return { RoleAuthority };
});
const router = useRouter();
const uuid = router.currentRoute.value.query['roleUuid'];
let data = ref({});
let show = ref(false);
let originalForm = ref([
{
field: 'roleUuid',
show: false,
component: 'NsInput',
},
{
field: 'fields',
label: '',
displayFormItem: false,
class: 'ns-form-item-full',
component: 'NsChildForm',
componentProps: {
title: '基本信息',
schemas: [
{
field: 'roleName',
label: '角色名称',
component: 'NsInput',
componentProps: {
placeholder: '请输入',
// disabled: uuid && true,
},
rules: [
// {
// required: true,
// message: '不得为空',
// trigger: 'blur',
// },
{
required: true,
validator: async (rule, value) => {
if (!value) {
return Promise.reject('角色名称不能为空');
}
const unicRegexp = new RegExp('[\u4e00-\u9fa5]', 'g');
let unicValue = value;
unicValue = value.replace(unicRegexp, 'aa');
if (!/^[a-zA-Z\d\u4e00-\u9fa5]{1,36}$/.test(unicValue)) {
return Promise.reject(
'不支持特殊字符、空格长度不得超过36个字符中文占2位位',
);
}
},
trigger: 'change',
},
],
},
{
field: 'describe',
label: '角色描述',
component: 'NsInput',
componentProps: {
placeholder: '请输入',
// disabled: uuid && true,
},
rules: [
// {
// required: true,
// message: '不得为空',
// trigger: 'blur',
// },
{
validator: async (rule, value) => {
if (!value) {
return;
}
const unicRegexp = new RegExp('[\u4e00-\u9fa5]', 'g');
let unicValue = value;
unicValue = value.replace(unicRegexp, 'aa');
if (!/^[a-zA-Z\d\u4e00-\u9fa5]{1,32}$/.test(unicValue)) {
return Promise.reject(
'不支持特殊字符、空格长度不得超过32个字符中文占2位',
);
}
},
trigger: 'change',
},
],
},
],
},
},
{
field: 'fields',
label: '',
displayFormItem: false,
class: 'ns-form-item-full',
component: 'NsChildForm',
componentProps: {
title: '角色权限设置(必填)',
schemas: [
{
field: 'resourceCodeMap',
label: '',
class: 'ns-form-item-full ns-form-item-padding',
component: 'RoleAuthority',
componentProps: {
placeholder: '请输入',
field: 'resourceCodeMap',
dataSource: data.value,
// disabled: uuid && true,
},
rules: [
{
required: true,
validator: async (rule, value) => {
if (!value) {
return Promise.reject('权限不能为空!');
} else {
let arr = Object.values(value);
let temp = false;
arr.forEach((ele) => {
if (ele.length > 0) {
temp = true;
}
});
if (!temp) {
return Promise.reject('权限不能为空!');
}
}
},
trigger: 'change',
},
],
},
],
},
},
]);
function load(): void {
if (!uuid) {
return;
}
const requestArr = [];
// 角色基本信息
const request1 = http.get('/api/community/objs/Role/detail', { roleUuid: uuid }).then(); // 角色权限
const request2 = http
.get('/api/community/objs/Role/ResourcesMap', { roleUuid: uuid })
.then();
const request3 = http.get('/api/community/objs/AppResourcesAllList').then(); // 获取当前应用所有权限资源
requestArr.push(request1);
requestArr.push(request2);
requestArr.push(request3);
Promise.all(requestArr)
.then((res) => {
if (res && res.length === 3) {
const roleInfo = res[0] && res[0]['data'] ? res[0]['data'] : '';
const roleAuth = res[1] && res[1]['data']['data'] ? res[1]['data']['data'] : '';
const allResources = res[2] && res[2]['data'] ? res[2]['data'] : [];
// 赋予角色基本信息
if (roleInfo) {
// 角色基本信息
data.value['roleName'] = roleInfo['roleName'];
data.value['describe'] = roleInfo['describe'];
data.value['roleUuid'] = roleInfo['roleUuid'];
}
// 全局应用权限资源信息,数据权限处理, 过滤form中的全局数据权限项
handleDataAuth(allResources, originalForm.value);
show.value = true;
// 本角色权限资源信息
if (roleAuth) {
if (typeof roleAuth == 'string') {
try {
JSON.parse(roleAuth);
} catch (e) {
console.log(e);
}
data.value['resourceCodeMap'] = JSON.parse(roleAuth);
} else if (roleAuth instanceof Array) {
data.value['resourceCodeMap'] = roleAuth;
}
}
}
})
.catch((error) => {
show.value = true;
// this.messageService.error('错误', '获得模块信息失败, 错误原因: ' + error, error);
});
}
async function loadResource() {
/**
* 获得module.json中的配置数据
*/
await http.get('/api/community/objs/AppResourcesAllList').then((res) => {
if (res.data) {
handleDataAuth(res.data, originalForm.value);
show.value = true;
} else {
show.value = true;
}
});
}
if (uuid) {
load();
} else {
loadResource();
}
// handleDataAuth([
// {
// "appLabel": "养老应用a",
// "appId": "11100as",
// "menus": [
// {
// "extend": "扩展信息",
// "code": "index",
// "parentCode": "",
// "icon": "",
// "name": "index",
// "label": "首页",
// "sort": 0,
// "type": "other"
// },
// {
// "code": "business-center",
// "parentCode": "",
// "icon": "",
// "name": "business-center",
// "label": "业务中心",
// "menus": [
// {
// "code": "advice-service",
// "parentCode": "business-center",
// "icon": "",
// "name": "advice-service",
// "label": "咨询入住",
// "menus": [
// {
// "code": "advice-register",
// "parentCode": "advice-service",
// "name": "advice-register",
// "label": "咨询登记",
// "menus": [
// {
// "code": "advice-register/add",
// "parentCode": "advice-register",
// "name": "add",
// "label": "新增",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "advice-register/remove",
// "parentCode": "advice-register",
// "name": "remove",
// "label": "删除",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "advice-register/edit",
// "parentCode": "advice-register",
// "name": "edit",
// "label": "编辑",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "advice-register/export",
// "parentCode": "advice-register",
// "name": "export",
// "label": "导出",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "advice-register/checkIn",
// "parentCode": "advice-register",
// "name": "checkIn",
// "label": "入住",
// "sort": 0,
// "type": "op"
// }
// ],
// "sort": 0,
// "type": "menus"
// },
// {
// "code": "order-register",
// "parentCode": "advice-service",
// "name": "order-register",
// "label": "预约登记",
// "menus": [
// {
// "code": "order-register/detail",
// "parentCode": "order-register",
// "name": "detail",
// "label": "详情",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "order-register/add",
// "parentCode": "order-register",
// "name": "add",
// "label": "新增",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "order-register/remove",
// "parentCode": "order-register",
// "name": "remove",
// "label": "删除",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "order-register/edit",
// "parentCode": "order-register",
// "name": "edit",
// "label": "编辑",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "order-register/export",
// "parentCode": "order-register",
// "name": "export",
// "label": "导出",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "order-register/cancel",
// "parentCode": "order-register",
// "name": "cancel",
// "label": "取消",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "order-register/checkIn",
// "parentCode": "order-register",
// "name": "unsubscribe",
// "label": "入住",
// "sort": 0,
// "type": "op"
// }
// ],
// "sort": 0,
// "type": "menus"
// },
// {
// "code": "check-in",
// "parentCode": "advice-service",
// "name": "check-in",
// "label": "入住登记",
// "menus": [
// {
// "code": "check-in/add",
// "parentCode": "check-in",
// "name": "add",
// "label": "新增",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "check-in/remove",
// "parentCode": "check-in",
// "name": "remove",
// "label": "删除",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "check-in/edit",
// "parentCode": "check-in",
// "name": "edit",
// "label": "编辑",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "check-in/export",
// "parentCode": "check-in",
// "name": "export",
// "label": "导出数据",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "check-in/import",
// "parentCode": "check-in",
// "name": "import",
// "label": "批量导入",
// "sort": 0,
// "type": "op"
// }
// ],
// "sort": 0,
// "type": "menus"
// },
// {
// "code": "bed-search",
// "parentCode": "advice-service",
// "name": "bed-search",
// "label": "床位查询",
// "sort": 0,
// "type": "menus"
// },
// {
// "code": "charging-standard",
// "parentCode": "advice-service",
// "name": "charging-standard",
// "label": "收费标准",
// "sort": 0,
// "type": "menus"
// }
// ],
// "sort": 0,
// "type": "menus"
// }
// ],
// "sort": 0,
// "type": "menus"
// }
// ],
// "dataScope": {
// "dataTips": "",
// "scopeType": "",
// "dataConfig": {},
// "scopeMode": 0
// },
// "version": "1.4.4.201"
// },
// {
// "appLabel": "养老应用app",
// "appId": "11100as2",
// "menus": [
// {
// "code": "homepage",
// "parentCode": "",
// "icon": "",
// "name": "homepage",
// "label": "主页",
// "menus": [
// {
// "code": "gaffer-information",
// "parentCode": "homepage",
// "name": "gaffer-information",
// "label": "老人信息",
// "menus": [
// {
// "code": "gaffer-list",
// "parentCode": "gaffer-information",
// "name": "gaffer-list",
// "label": "老人列表",
// "sort": 0,
// "type": "menus"
// },
// {
// "code": "basic-information",
// "parentCode": "gaffer-information",
// "name": "basic-information",
// "label": "基本信息",
// "sort": 0,
// "type": "menus"
// }
// ],
// "sort": 0,
// "type": "menus"
// },
// {
// "code": "service-transact",
// "parentCode": "homepage",
// "name": "service-transact",
// "label": "服务办理",
// "menus": [
// {
// "code": "bed-record",
// "parentCode": "service-transact",
// "name": "bed-record",
// "label": "换床记录",
// "menus": [
// {
// "code": "bed-record/detail",
// "parentCode": "bed-record",
// "name": "detail",
// "label": "查看",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "bed-record/add",
// "parentCode": "bed-record",
// "name": "add",
// "label": "新增",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "bed-record/edit",
// "parentCode": "bed-record",
// "name": "edit",
// "label": "编辑",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "bed-record/cancel",
// "parentCode": "bed-record",
// "name": "cancel",
// "label": "取消",
// "sort": 0,
// "type": "op"
// }
// ],
// "sort": 0,
// "type": "menus"
// },
// {
// "code": "nursing-level-change",
// "parentCode": "service-transact",
// "name": "nursing-level-change",
// "label": "护理等级更换",
// "menus": [
// {
// "code": "nursing-level-change/detail",
// "parentCode": "nursing-level-change",
// "name": "detail",
// "label": "查看",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "nursing-level-change/add",
// "parentCode": "nursing-level-change",
// "name": "add",
// "label": "新增",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "nursing-level-change/edit",
// "parentCode": "nursing-level-change",
// "name": "edit",
// "label": "编辑",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "nursing-level-change/cancel",
// "parentCode": "nursing-level-change",
// "name": "cancel",
// "label": "取消",
// "sort": 0,
// "type": "op"
// }
// ],
// "sort": 0,
// "type": "menus"
// },
// {
// "code": "nursing-group-change",
// "parentCode": "service-transact",
// "name": "nursing-group-change",
// "label": "护理组更换",
// "menus": [
// {
// "code": "nursing-group-change/detail",
// "parentCode": "nursing-group-change",
// "name": "detail",
// "label": "查看",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "nursing-group-change/add",
// "parentCode": "nursing-group-change",
// "name": "add",
// "label": "新增",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "nursing-group-change/edit",
// "parentCode": "nursing-group-change",
// "name": "edit",
// "label": "编辑",
// "sort": 0,
// "type": "op"
// },
// {
// "code": "nursing-group-change/cancel",
// "parentCode": "nursing-group-change",
// "name": "cancel",
// "label": "取消",
// "sort": 0,
// "type": "op"
// }
// ],
// "sort": 0,
// "type": "menus"
// }
// ],
// "sort": 0,
// "type": "menus"
// }
// ],
// "sort": 0,
// "type": "menus"
// }
// ],
// "version": "1.4.4.7"
// }
// ],originalForm.value)
async function handleDataAuth(allResources, form) {
// 1. 存储所有资源权限
data.value['allResources'] = allResources;
// 2. 确定数据权限模式
/** 目前考虑场景:
* dataScope['scopeMode']为 0:没有数据权限1. 有全局数据权限 2. 各自有数据权限
* 1. 全局数据权限各应用都没有数据权限即各资源无dataScope参数 或 dataScope下面参数 scopeMode 0
* 2. 局部数据权限:各应用有各自数据权限, 即 dataScope下面参数 scopeMode 2
* 3. todo 各个应用有的是全局数据权限,有的是独有的数据权限:暂未处理该场景*/
if (allResources && allResources instanceof Array) {
let modeArr = [];
await allResources.forEach((resource) => {
if (resource['dataScope']) {
const dataScope = resource['dataScope'];
if (Object.keys(dataScope).length > 0) {
const scopeMode = dataScope['scopeMode'];
modeArr.push(scopeMode);
if (scopeMode == 1) {
data.value['commonDataScope'] = dataScope; // 存在全局数据权限,任取一个应用的数据权限定义
}
}
}
});
if (modeArr.length == 0) {
data.value['dataAuthMode'] = 0; // 无数据权限
} else if (modeArr.length > 0) {
let newArr = Array.from(new Set(modeArr));
if (newArr.includes(1)) {
// 可能有全局数据权限
if (newArr.includes(2)) {
// this.messageService.confirm('提示', '权限资源注册有误'); // 有的有全局数据权限,有的有自己的数据权限
return;
} else {
data.value['dataAuthMode'] = 1; // 全局数据权限
}
} else {
// 无数据权限或者有的含有自己的数据权限
if (newArr.includes(2)) {
// 可能有各自的数据权限
data.value['dataAuthMode'] = 2; // 局部数据权限
} else {
data.value['dataAuthMode'] = 0; // 无数据权限
}
}
}
}
// 3.根据数据模式参数确定全局数据权限是否显示
// if (data.value['dataAuthMode'] != 1) {
// const tempForm = JSON.parse(JSON.stringify(form));
// if (tempForm) {
// tempForm = tempForm.filter(fd => {
// return fd['field'] != 'dataScope';
// });
// originalForm = tempForm;
// }
// } else {
// originalForm = form;
// }
}
// async function getData() {
// await http
// .get('/api/ihorn/objs/enterprise/detail', { uuid: uuid })
// .then((res) => {
// if(res.data){
// data.value= res.data
// }
// });
// }
// if(uuid){
// getData()
// }
let formSchema = ref([]);
watch(
() => show.value,
() => {
if (show.value) {
formSchema.value = originalForm.value;
}
},
{
immediate: true,
},
);
return {
data,
formSchema,
uuid,
};
},
});
</script>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,396 @@
<!-- @format -->
<template>
<div class="form-group">
<div class="controls" style="display: flex">
<!--选择区域-->
<div class="controls iaas-input" style="flex: 1; position: relative">
<input style="width: 100%" class="base-input" disabled />
<span @click="searchPerson()" class="select-btn"
>&nbsp;&nbsp;{{ buttonLabel }}&nbsp;&nbsp;
</span>
</div>
</div>
<!--多选结果展示区域-->
<div class="form-group">
<div class="multi-content" style="display: flex; width: 100%">
<label class="control-label"><span></span></label>
<div class="multi-content-show" style="flex: 1">
<div class="multi-content multi-placeholder">{{ multiplePlaceholder }}</div>
<div class="multi-content">
<span class="multi-item-label" v-for="item in selectedItems">
<span style="margin-right: 10px">{{ item[labelField] }}</span>
<ns-icon name="close" @click="onRemove(item)" />
</span>
</div>
</div>
</div>
<ns-modal v-model:visible="visible" @ok="handleOk" width="900px">
<ns-view-list-table
v-if="visible"
ref="nsTableRef"
v-bind="tableConfig"
:model="data"
:rowKey="valueField" />
</ns-modal>
</div>
</div>
</template>
<script lang="ts">
import moment from 'moment';
import { defineComponent, ref, watch, unref, computed } from 'vue';
import { NsMessage } from '/nerv-lib/component/message';
import { http } from '/nerv-lib/util/http';
import { isArray } from 'lodash-es';
export default defineComponent({
name: 'SelectRolePerson',
components: {},
props: {
dataSource: {
type: Object,
default: [],
},
labelField: {
type: String,
default: 'name',
},
valueField: {
type: String,
default: 'uuid',
},
},
emits: ['change', 'updata:longLat', 'validate', 'getChildrenOptions'],
setup(props, { emit }) {
const nsTableRef = ref();
const visible = ref<Boolean>(false);
let buttonLabel = ref('选择员工');
let multiplePlaceholder = ref('点击选择按钮选择');
let selectedItems = ref([]);
let selectedItemsList = ref([]);
const valueField = ref();
valueField.value = props.valueField;
if (props) {
if (props && isArray(props.dataSource)) {
selectedItems.value = props.dataSource;
console.log(props.dataSource);
selectedItems.value.forEach((ele) => {
selectedItemsList.value.push(ele[valueField.value]);
});
change();
}
}
// const changeTable = (item) => {
// emit('change', currentList);
// };
const dealSelectItem = (selectKey: any, selectRow: any) => {
const initList = [];
selectKey.forEach((item) => {
let info = selectRow.filter((x) => x?.[props.valueField] === item)[0];
if (!info) {
let dInfo = props.dataSource.filter((x) => x?.[props.valueField] === item)[0];
!dInfo ? '' : initList.push(dInfo);
} else {
initList.push(info);
}
});
selectedItems.value = initList;
};
const tableConfig = {
api: '/api/parking_merchant/objs/person/pageList',
params: {
page: 0,
pageSize: 10,
},
rowSelection: {
selectedRowKeys: selectedItemsList,
onChange: (selectedRowKeys, selectedRows) => {
// selectedItemsList.value = selectedRowKeys;
// selectedItems.value = selectedRows;
dealSelectItem(selectedRowKeys, selectedRows);
selectedItemsList.value = selectedRowKeys;
},
getCheckboxProps: (record) => {
console.log(record);
return {
undefined,
props: {
disabled: false,
// name: record.name,
defaultChecked: selectedItemsList.value.indexOf(record[valueField.value]) != -1,
},
};
},
},
scroll: { x: 1350 },
columns: [
{
title: '姓名',
dataIndex: 'personName',
width: 200,
},
{
title: '性别',
dataIndex: 'sex',
width: 100,
customRender: (value) => {
switch (value.text) {
case 0:
return '女';
case 1:
return '男';
default:
return '-';
}
},
},
{
title: '员工编号',
dataIndex: 'personNum',
width: 150,
},
{
title: '手机号码',
dataIndex: 'telNum',
width: 150,
},
{
title: '账号状态',
dataIndex: 'accountState',
width: 150,
customRender: (value) => {
switch (value.text) {
case 1:
return '启用';
case 0:
return '禁用';
default:
return '-';
}
},
},
{
title: '用户状态',
dataIndex: 'personStatus',
customRender: (value) => {
switch (value.text) {
case 1:
return '在职';
case 2:
return '离职';
default:
return '-';
}
},
},
],
formConfig: {
schemas: [
{
field: 'accountState',
label: '账号状态',
component: 'NsSelect',
componentProps: {
placeholder: '请选择',
options: [
{
label: '全部',
value: '',
},
{
label: '启用',
value: 1,
},
{
label: '禁用',
value: 0,
},
],
},
},
{
field: 'personStatus',
label: '用户状态',
component: 'NsSelect',
componentProps: {
placeholder: '请选择',
options: [
{
label: '全部',
value: '',
},
{
label: '在职',
value: 1,
},
{
label: '离职',
value: 2,
},
],
},
},
{
field: 'telNum',
label: '手机号码',
component: 'NsInput',
componentProps: {
placeholder: '请输入手机号码',
},
},
{
field: 'personName',
label: '用户姓名',
component: 'NsInput',
componentProps: {
placeholder: '请输入用户姓名',
},
},
],
},
rowKey: 'personUuid',
};
function onRemove(item) {
if (item) {
for (let i = selectedItems.value.length - 1; i >= 0; i--) {
if (selectedItems.value[i][props.valueField] == item[props.valueField]) {
selectedItems.value.splice(i, 1);
}
}
change();
}
}
function searchPerson() {
visible.value = true;
}
const handleOk = async () => {
let selectedRows = unref(nsTableRef).nsTableRef.tableState.selectedRows;
visible.value = false;
if (isArray(selectedRows)) {
selectedRows.forEach((ele) => {
let temp = true;
selectedItems.value.forEach((element) => {
if (ele[props.valueField] == element[props.valueField]) {
temp = false;
}
});
if (temp) {
let obj = {};
obj[props.valueField] = ele[props.valueField];
obj[props.labelField] = ele[props.labelField];
selectedItems.value.push(obj);
}
});
}
change();
};
function change() {
let list = [];
selectedItems.value.forEach((element) => {
list.push(element[props.valueField]);
});
emit('change', list);
}
watch(
() => props.dataSource,
() => {
selectedItems.value = props.dataSource;
change();
},
{
immediate: true,
},
);
return {
buttonLabel,
multiplePlaceholder,
selectedItems,
tableConfig,
visible,
nsTableRef,
valueField,
selectedItemsList,
//方法
handleOk,
searchPerson,
change,
onRemove,
};
},
data() {
return {
editingKey: '',
propsList: [],
};
},
created() {},
methods: {},
});
</script>
<style lang="less" scoped>
.select-btn {
position: absolute;
right: 0;
top: 0;
background: #0ed2bf;
color: white;
bottom: 0;
cursor: pointer;
}
//多选部分显示样式
.multi-content-show {
border: 1px solid #dfdfdf;
margin-top: 10px;
min-height: 90px;
width: 500px;
max-height: 150px;
overflow-y: scroll;
.multi-content {
padding: 10px;
display: flex;
flex-wrap: wrap;
line-height: 22px;
&.multi-placeholder {
color: #354052;
opacity: 0.3;
}
}
.multi-item-label {
height: 24px;
padding: 4px 10px 4px 10px;
font-size: 12px;
color: #37474f;
border: 1px solid #cfd8dc;
background: #f9f9f9;
border-radius: 12px;
margin-right: 20px;
margin-bottom: 5px;
line-height: 24px;
position: relative;
box-sizing: border-box;
display: flex;
align-items: center;
.iconfont {
width: 24px;
height: 24px;
position: absolute;
right: 0.3em;
top: 0;
color: #cfd8dc;
font-size: 12px;
transform: scale(0.67, 0.67);
cursor: pointer;
text-align: center;
&:hover {
color: #607d8b;
}
}
}
}
ul,
li {
list-style: none;
}
</style>

View File

@@ -0,0 +1,124 @@
<!-- @format -->
<template>
<ns-view-list-table ref="nsTableRef" v-bind="tableConfig" :model="data" />
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import moment from 'moment';
import { useRouter } from 'vue-router';
export default defineComponent({
name: 'NsViewRoleType',
setup() {
const sonRef = ref(null);
const nsTableRef = ref(null);
const data = ref({});
const router = useRouter();
const tableConfig = {
api: '/api/community/objs/Role',
title: '角色列表',
pagination: {
page: 0,
pageSize: 10,
},
rowSelection: null,
// scroll: { x: 1100 },
columns: [
{
title: '角色名称',
// width: 200,
dataIndex: 'roleName',
},
{
title: '备注',
// width: 200,
dataIndex: 'describe',
},
{
title: '操作时间',
// width: 200,
dataIndex: 'updateTime',
customRender: (text: any) => {
if (text.record.updateTime) {
return moment(text.record.updateTime).format('YYYY-MM-DD HH:mm:ss');
}
return '--';
},
},
],
headerActions: [
{
label: '新增',
name: 'RoleTypeAdd',
type: 'primary',
handle: () => {
router.push({
name: 'RoleTypeAdd',
});
},
},
],
columnActions: {
title: '操作',
// width: 150,
actions: [
{
label: '人员设置',
name: 'SetRolePerson',
handle: (record: any) => {
router.push({
name: 'SetRolePerson',
query: {
roleUuid: record.roleUuid,
},
});
},
},
{
label: '编辑',
name: 'RoleTypeEdit',
handle: (record: any) => {
router.push({
name: 'RoleTypeEdit',
query: {
roleUuid: record.roleUuid,
},
});
},
},
{
label: '删除',
dynamicParams: ['roleUuid', 'roleUuid'],
name: 'RoleTypeRemove',
confirm: true,
isReload: true,
api: '/api/community/objs/Role/delete',
},
],
},
formConfig: {
schemas: [
{
field: 'roleName',
label: '角色名称',
component: 'NsInput',
defaultValue: '',
},
],
params: {},
},
rowKey: 'roleUuid',
};
return {
tableConfig,
data,
moment,
sonRef,
nsTableRef,
};
},
});
</script>

View File

@@ -0,0 +1,153 @@
<!-- @format -->
<template>
<ns-view-add-form
:schemas="formSchema"
:model="data"
:title="'编辑人员'"
:api="'/api/community/objs/Role/Account'" />
</template>
<script lang="ts">
import { defineComponent, reactive, ref, provide, watch } from 'vue';
import { useRouter } from 'vue-router';
import { http } from '/nerv-lib/util/http';
import SelectRolePerson from './component/selectRolePerson.vue';
export default defineComponent({
name: 'NsViewSetRolePerson',
components: {
SelectRolePerson,
},
setup() {
provide('components', () => {
return { SelectRolePerson };
});
const router = useRouter();
const uuid = router.currentRoute.value.query['roleUuid'];
const show = ref(false);
let data = ref({});
const personList = ref({});
function setOriginalForm(list: []) {
return [
{
field: 'roleUuid',
show: false,
component: 'NsInput',
},
{
field: 'fields',
label: '',
displayFormItem: false,
class: 'ns-form-item-full',
component: 'NsChildForm',
componentProps: {
title: '基本信息',
schemas: [
{
field: 'roleName',
label: '角色名称',
component: 'NsInput',
componentProps: {
disabled: true,
},
},
{
field: 'describe',
label: '角色描述',
component: 'NsInput',
componentProps: {
disabled: true,
},
},
],
},
},
{
field: 'fields',
label: '',
displayFormItem: false,
class: 'ns-form-item-full',
component: 'NsChildForm',
componentProps: {
title: '角色权限设置',
schemas: [
{
field: 'accountCodeList',
label: '',
class: 'ns-form-item-full ns-form-item-padding',
component: 'SelectRolePerson',
componentProps: {
placeholder: '请输入',
field: 'accountCodeList',
labelField: 'personName',
valueField: 'personUuid',
dataSource: list,
// disabled: uuid && true,
},
rules: [
// {
// required: true,
// message: '不得为空',
// trigger: 'blur',
// },
],
},
],
},
},
];
}
function load(): void {
if (!uuid) {
return;
}
const requestArr = [];
// 角色基本信息
const request1 = http.get('/api/community/objs/Role/detail', { roleUuid: uuid }).then(); // 角色权限
const request2 = http.get('/api/community/objs/Role/Account', { roleUuid: uuid }).then();
requestArr.push(request1);
requestArr.push(request2);
Promise.all(requestArr)
.then((res) => {
if (res && res.length === 2) {
data.value = res[0] && res[0]['data'] ? res[0]['data'] : {};
personList.value = res[1] && res[1]['data']['data'] ? res[1]['data']['data'] : [];
personList.value.forEach((ele) => {
ele['personName'] = ele['accountRealName'];
ele['personUuid'] = ele['accountCode'];
});
show.value = true;
} else {
show.value = true;
}
})
.catch((error) => {
show.value = true;
// this.messageService.error('错误', '获得模块信息失败, 错误原因: ' + error, error);
});
}
if (uuid) {
load();
}
let formSchema = ref([]);
watch(
() => show.value,
() => {
if (show.value) {
formSchema.value = setOriginalForm(personList.value);
}
},
{
immediate: true,
},
);
return {
data,
formSchema,
uuid,
setOriginalForm,
};
},
});
</script>

View File

@@ -0,0 +1,481 @@
<!-- @format -->
<template>
<ns-view-add-form
:schemas="formSchema"
title="新增员工"
:model="data"
api="/api/parking_merchant/objs/person/add" />
</template>
<script lang="ts">
import { defineComponent, reactive } from 'vue';
import { dateUtil } from '/nerv-lib/util/date-util';
export default defineComponent({
name: 'NsViewUserAdd',
setup() {
const data = reactive({});
let formSchema = reactive([
{
field: 'information',
label: '基本信息',
displayFormItem: false,
class: 'ns-form-item-full',
component: 'NsChildForm',
componentProps: {
title: '基本信息',
schemas: [
{
field: 'personName',
label: '姓名',
component: 'NsInput',
rules: [
{
required: true,
trigger: 'change',
},
{
pattern: /^[\u4E00-\u9FA5]{1,18}$/,
message: '只支持中文长度不得超过36个字符',
trigger: 'change',
},
],
},
{
field: 'sex',
component: 'NsRadioGroup',
label: '性别',
defaultValue: 1,
componentProps: {
styleType: { flex: true },
options: [
{
label: '男',
value: 1,
},
{
label: '女',
value: 0,
},
],
},
rules: [
{
required: true,
message: '不能为空',
},
],
},
{
field: 'personNum',
label: '员工编号',
component: 'NsInput',
rules: [
{
required: true,
message: '员工编号不能为空',
trigger: 'blur',
},
{
pattern: /^[a-zA-Z\d]{0,16}$/,
message: '不支持特殊字符、中文、空格长度不得超过16个字符',
trigger: 'blur',
},
],
},
{
field: 'idCard',
label: '身份证号',
component: 'NsInput',
rules: [
// {
// required: true,
// trigger: 'blur',
// },
{
pattern:
'^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$',
message: '请输入正确的身份证号',
trigger: 'blur',
},
],
},
{
field: 'telNum',
label: '手机号码',
component: 'NsInput',
rules: [
{
required: true,
message: '手机号码不能为空',
trigger: 'change',
},
{
pattern: '^[1][3456789][\\d]{9}$',
message: '请输入正确的中国大陆手机号',
trigger: 'blur',
},
],
},
{
field: 'nation',
component: 'nsSelectApi',
label: '民族',
componentProps: {
api: '/api/community/objs/DictItem',
params: {
pageSize: 100,
code: 'MZ',
},
placeholder: '请选择用户民族',
resultField: 'data',
labelField: 'dictName',
valueField: 'dictValue',
immediate: true,
autoSelectFirst: false,
},
// rules: [
// {
// required: true,
// message: '请选择民族',
// },
// ],
},
{
field: 'departmentUuidList',
component: 'nsSelectApi',
label: '所属部门',
componentProps: {
api: '/api/community/objs/Department',
params: {
pageSize: 100,
},
mode: 'multiple',
resultField: 'data.data',
labelField: 'departmentName',
valueField: 'departmentUuid',
autoSelectFirst: false,
},
},
{
field: 'departmentMainUuid',
component: 'nsSelectApi',
label: '主部门',
params: {
departmentUuidList: 'fieldLink.departmentUuidList',
},
componentProps: {
api: '/api/community/objs/Department',
resultField: 'data.data',
labelField: 'departmentName',
valueField: 'departmentUuid',
autoSelectFirst: false,
dependency: 'departmentUuidList',
},
},
// {
// field: 'roleUuid',
// component: 'nsSelectApi',
// label: '员工角色',
// componentProps: {
// api: '/api/community/objs/Role',
// params: {
// pageSize: 100,
// },
// resultField: 'data.data',
// labelField: 'roleName',
// valueField: 'roleUuid',
// immediate: true,
// autoSelectFirst: false,
// },
// rules: [
// {
// required: false,
// message: '请选择角色',
// },
// ],
// },
{
field: 'homeAddress',
label: '居住地址',
component: 'NsInputCity',
componentProps: {
api: '/api/parking_merchant/objs/BaseArea',
},
fieldMap: ['homeAddress', 'provinceCode', 'cityCode', 'areaCode'],
// rules: [
// {
// required: true,
// message: '不能为空',
// },
// ],
},
{
field: 'address',
label: '详细地址',
component: 'NsInput',
rules: [
// {
// required: true,
// trigger: 'blur',
// },
{
pattern:
'^[a-zA-Z\\d\u4e00-\u9fa5]{0,36}$|^[\u4e00-\u9fa5][a-zA-Z\\d\u4e00-\u9fa5]{0,36}[\u4e00-\u9fa5]$',
message: '不支持特殊字符、空格长度不得超过36个字符中文占2位',
trigger: 'blur',
},
],
},
{
field: 'personStatus',
component: 'NsSelect',
label: '状态',
componentProps: {
options: [
{
label: '在职',
value: 1,
},
{
label: '离职',
value: 2,
},
],
labelField: 'label',
valueField: 'value',
immediate: false,
// defaultValue: 1,
},
rules: [
{
required: true,
message: '不能为空',
},
],
},
{
field: 'personPicUuid',
component: 'NsUpload',
label: '员工图片',
componentProps: {
// 上传的地址
url: '/api/parking_merchant/objs/sys/FileUpload',
// 上传的图片大小
maxSize: 5242880,
// 上传的图片类型
fileType: ['jpg', 'png', 'jpeg'],
// 展示图片数量
count: 1,
// 上传的文件类型0-证书1-图片2-身份证件
uploadType: 1,
fieldName: 'certificateUuid',
// imgUrl: '/api/community/objs/FacePic/',
// imgModuleUrl:
// '/api/community/objs/FacePic/8f50a2f2dee948c4bfab58928d182897',
},
},
{
field: 'idCardPicUuid',
component: 'NsUpload',
label: '身份证扫描件',
componentProps: {
// 上传的地址
url: '/api/parking_merchant/objs/sys/FileUpload',
// 上传的图片大小
maxSize: 5242880,
// 上传的图片类型
fileType: ['jpg', 'png', 'jpeg'],
// 展示图片数量
count: 1,
// 上传的文件类型0-证书1-图片2-身份证件
uploadType: 2,
// imgUrl: '/api/community/objs/FacePic/',
// imgModuleUrl:
// '/api/community/objs/FacePic/8f50a2f2dee948c4bfab58928d182897',
},
// rules: [
// {
// required: true,
// message: '请上传图片',
// },
// ],
},
],
},
},
{
field: 'location',
label: '其他信息',
displayFormItem: false,
class: 'ns-form-item-full',
component: 'NsChildForm',
componentProps: {
title: '其他信息',
schemas: [
{
field: 'maritalStatus',
component: 'nsSelectApi',
label: '婚姻状况',
componentProps: {
api: '/api/community/objs/DictItem',
params: {
code: 'HYZK',
},
resultField: 'data',
labelField: 'dictName',
valueField: 'dictValue',
immediate: true,
autoSelectFirst: false,
},
// rules: [
// {
// required: true,
// message: '不能为空',
// },
// ],
},
{
field: 'education',
component: 'nsSelectApi',
label: '文化程度',
componentProps: {
api: '/api/community/objs/DictItem',
params: {
code: 'WHCD',
},
resultField: 'data',
labelField: 'dictName',
valueField: 'dictValue',
immediate: true,
autoSelectFirst: false,
},
// rules: [
// {
// required: true,
// message: '不能为空',
// },
// ],
},
{
field: 'entryTime',
component: 'NsDatePicker',
defaultValue: dateUtil(new Date()),
label: '入职日期',
componentProps: {
valueFormat: 'X',
format: 'YYYY-MM-DD',
},
// rules: [
// {
// required: true,
// message: '不能为空',
// },
// ],
},
{
field: 'graduatedSchool',
label: '毕业院校',
component: 'NsInput',
rules: [
// {
// required: true,
// message: '毕业院校不能为空',
// trigger: 'blur',
// },
{
pattern:
/^[a-zA-Z\\d\u4e00-\u9fa5]{0,24}$|^[\u4e00-\u9fa5][a-zA-Z\\d\u4e00-\u9fa5]{0,24}[\u4e00-\u9fa5]$/,
message: '不支持特殊字符、空格长度不得超过24个字符中文占2位',
trigger: 'blur',
},
],
},
{
field: 'major',
label: '所属专业',
component: 'NsInput',
rules: [
{
pattern:
/^[a-zA-Z\\d\u4e00-\u9fa5]{0,24}$|^[\u4e00-\u9fa5][a-zA-Z\\d\u4e00-\u9fa5]{0,24}[\u4e00-\u9fa5]$/,
message: '不支持特殊字符、空格长度不得超过24个字符中文占2位',
trigger: 'blur',
},
],
},
{
field: 'email',
label: '邮箱地址',
component: 'NsInput',
rules: [
{
required: false,
trigger: 'blur',
},
{
pattern: /^\w+@[a-z0-9]+\.[a-z]{2,4}$/,
message: '邮箱格式不正确',
trigger: 'blur',
},
],
},
{
field: 'residenceAddress',
label: '户籍地址',
component: 'NsInput',
rules: [
// {
// required: true,
// message: '户籍地址不能为空',
// trigger: 'blur',
// },
{
pattern:
/^[a-zA-Z\\d\u4e00-\u9fa5]{0,64}$|^[\u4e00-\u9fa5][a-zA-Z\\d\u4e00-\u9fa5]{0,64}[\u4e00-\u9fa5]$/,
message: '不支持特殊字符、空格长度不得超过64个字符中文占2位',
trigger: 'blur',
},
],
},
{
field: 'remarks',
label: '备注',
component: 'NsTextarea',
rules: [
{
required: false,
trigger: 'blur',
},
{
pattern: /^[\u4e00-\u9fa5]{0,120}$|^.{0,255}$/,
message: '0-255个字符中文占2位',
trigger: 'blur',
},
],
},
],
},
},
]);
return {
formSchema,
data,
};
},
});
</script>
<style scoped lang="less">
.top {
border-bottom-color: #ecedef;
border-bottom-style: solid;
border-bottom-width: 1px;
}
</style>

View File

@@ -0,0 +1,186 @@
<template>
<ns-view-detail api="/api/parking_merchant/objs/person/detail" :detail="detail" />
</template>
<script lang="ts">
import { defineComponent, reactive } from 'vue';
import { getCodeNameFromValue } from './index';
import { dateUtil } from '/nerv-lib/util/date-util';
export default defineComponent({
name: 'NsViewUserDetail',
setup() {
const detail = [
{
title: '基本信息',
items: [
{
label: '姓名',
name: 'personName',
},
{
label: '性别',
name: 'sex',
format: (value: any, data: any) => {
switch (value) {
case 1:
return '男';
case 0:
return '女';
default:
return '-';
}
},
},
{
label: '员工编号',
name: 'personNum',
},
{
label: '身份证号',
name: 'idCard',
},
{
label: '手机号码',
name: 'telNum',
},
{
label: '民族',
name: 'nation',
format: (value: any, data: any) => {
console.log(value, data, 'value');
if (!value) return;
let temp = getCodeNameFromValue('MZ', value);
if (temp) {
return temp;
} else {
return '-';
}
},
},
{
label: '所属部门',
name: 'departmentNameList',
format: (value: any, data: any) => {
if (value) {
let temp = '';
let jdgeTemp = false;
value.forEach((element: any[]) => {
if (jdgeTemp) {
temp += ',';
temp += element.join('/');
} else {
jdgeTemp = true;
temp += element.join('/');
}
});
return temp;
} else {
return '-';
}
},
},
{
label: '主部门',
name: 'departmentMainName',
},
{
label: '员工角色',
name: 'roleVOList',
format: (value: any) => {
if (value) {
let apusic = '';
value.forEach((element: any) => {
apusic = element.roleName;
});
return apusic;
} else {
return '-';
}
},
},
{
label: '居住地址',
name: 'homeAddress',
},
{
label: '详细地址',
name: 'address',
},
{
label: '员工图片',
name: 'personPicUuid',
type: 'image',
format: (value: string, data: any) => {
return '/api/parking_merchant/objs/sys/ParkPic/' + value;
},
},
{
label: '身份证扫描件',
name: 'idCardPicUuid',
type: 'image',
format: (value: any, data: any) => {
return '/api/parking_merchant/objs/sys/IdCardPic/' + value;
},
},
],
},
{
title: '其他信息',
items: [
{
label: '婚姻状况',
name: 'maritalStatus',
format: (value: any, data: any) => {
let temp = getCodeNameFromValue('HYZK', value);
if (temp) {
return temp;
} else {
return '-';
}
},
},
{
label: '文化程度',
name: 'education',
format: (value: any, data: any) => {
let temp = getCodeNameFromValue('WHCD', value);
if (temp) {
return temp;
} else {
return '-';
}
},
},
{
label: '入职日期',
name: 'entryTime',
format: (value: any) => {
return dateUtil(value).format('YYYY-MM-DD HH:mm:ss');
},
},
{
label: '毕业院校',
name: 'graduatedSchool',
},
{
label: '所属专业',
name: 'major',
},
{
label: '邮箱地址',
name: 'email',
},
{
label: '户籍地址',
name: 'residenceAddress',
},
{
label: '备注',
name: 'remarks',
},
],
},
];
return { detail };
},
});
</script>

View File

@@ -0,0 +1,461 @@
<!-- @format -->
<template>
<ns-view-add-form
:schemas="formSchema"
title="编辑员工"
:model="data"
api="/api/parking_merchant/objs/person/update" />
</template>
<script lang="ts">
import { defineComponent, reactive, ref } from 'vue';
import moment from 'moment';
import { http } from '/nerv-lib/util/http';
import { useRouter } from 'vue-router';
export default defineComponent({
name: 'NsViewUserEdit',
setup() {
const data = reactive({});
const router = useRouter();
const params = router.currentRoute.value.query;
const homeAddress = ref('');
const provinceCode = ref('');
const areaCode = ref('');
const cityCode = ref('');
const personPicImageUrl = ref('');
const idCardImageUrl = ref('');
if (params.personUuid !== undefined) {
http
.get(`/api/parking_merchant/objs/person/detail`, { personUuid: params.personUuid })
.then((res) => {
data.personName = res.data.personName;
data.sex = res.data.sex;
data.sexName = res.data.sex ? '男' : '女';
data.personNum = res.data.personNum;
data.idCard = res.data.idCard;
data.major = res.data.major;
data.address = res.data.address;
data.graduatedSchool = res.data.graduatedSchool;
data.residenceAddress = res.data.residenceAddress;
data.telNum = res.data.telNum;
data.remarks = res.data.remarks;
data.education = res.data.education;
data.maritalStatus = res.data.maritalStatus;
data.personStatus = res.data.personStatus;
data.nation = res.data.nation;
data.homeAddress = res.data.homeAddress;
data.areaCode = res.data.areaCode;
data.cityCode = res.data.cityCode; //moment(new Date()).format('YYYY-MM-DD 23:59:59')
data.entryTime = moment(new Date(res.data.entryTime)).format('x');
data.provinceCode = res.data.provinceCode;
homeAddress.value = res.data.homeAddress;
areaCode.value = res.data.areaCode;
cityCode.value = res.data.cityCode;
provinceCode.value = res.data.provinceCode;
personPicImageUrl.value = `/api/parking_merchant/objs/sys/ParkPic/${res.data.personPicUuid}`;
idCardImageUrl.value = `/api/parking_merchant/objs/sys/IdCardPic/${res.data.idCardPicUuid}`;
// formSchema.value.filter(
// (item) => item.field === 'avatar'
// )[0].componentProps.baseImageUrl = `/api/community/objs/ParkPic/${data.avatar}`;
})
.catch((err) => {
console.log(err);
});
}
let formSchema = reactive([
{
label: '用户uuid',
field: 'personUuid',
component: 'NsInputText',
show: false,
defaultValue: params.personUuid,
},
{
field: 'information',
label: '基本信息',
displayFormItem: false,
class: 'ns-form-item-full',
component: 'NsChildForm',
componentProps: {
title: '基本信息',
schemas: [
{
field: 'personName',
label: '姓名',
component: 'NsInputText',
},
{
field: 'sexName',
component: 'NsInputText',
label: '性别',
viewOnly: true,
},
{
field: 'sex',
component: 'NsInputText',
show: false,
label: '性别',
},
{
field: 'personNum',
label: '员工编号',
component: 'NsInputText',
},
{
field: 'idCard',
label: '身份证号',
component: 'NsInputText',
// rules: [
// {
// pattern:
// '^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$',
// message: '请输入正确的身份证号',
// trigger: 'blur',
// },
// ],
},
{
field: 'telNum',
label: '手机号码',
component: 'NsInput',
rules: [
{
required: true,
message: '手机号码不能为空',
trigger: 'change',
},
{
pattern: '^[1][3456789][\\d]{9}$',
message: '请输入正确的中国大陆手机号',
trigger: 'blur',
},
],
},
{
field: 'nation',
component: 'nsSelectApi',
label: '民族',
componentProps: {
api: '/api/community/objs/DictItem',
params: {
pageSize: 100,
code: 'MZ',
},
placeholder: '请选择用户民族',
resultField: 'data',
labelField: 'dictName',
valueField: 'dictValue',
immediate: true,
autoSelectFirst: false,
},
rules: [
// {
// required: true,
// message: '请选择民族',
// },
],
},
{
field: 'departmentUuidList',
component: 'nsSelectApi',
label: '所属部门',
componentProps: {
api: '/api/community/objs/Department',
params: {
pageSize: 100,
},
mode: 'multiple',
resultField: 'data.data',
labelField: 'departmentName',
valueField: 'departmentUuid',
autoSelectFirst: false,
},
},
{
field: 'departmentMainUuid',
component: 'nsSelectApi',
label: '主部门',
params: {
departmentUuidList: 'fieldLink.departmentUuidList',
},
componentProps: {
api: '/api/community/objs/Department',
resultField: 'data.data',
labelField: 'departmentName',
valueField: 'departmentUuid',
autoSelectFirst: false,
dependency: 'departmentUuidList',
},
},
{
field: 'homeAddress',
label: '居住地址',
component: 'NsInputCity',
componentProps: {
api: '/api/parking_merchant/objs/BaseArea',
defaultHomeAddress: homeAddress,
defaultProvinceCode: provinceCode,
defaultCityCode: cityCode,
defaultAreaCode: areaCode,
},
fieldMap: ['homeAddress', 'provinceCode', 'cityCode', 'areaCode'],
rules: [
// {
// required: true,
// message: '不能为空',
// },
],
},
{
field: 'address',
label: '详细地址',
component: 'NsInput',
rules: [
// {
// required: true,
// trigger: 'blur',
// },
{
pattern:
'^[a-zA-Z\\d\u4e00-\u9fa5]{0,36}$|^[\u4e00-\u9fa5][a-zA-Z\\d\u4e00-\u9fa5]{0,36}[\u4e00-\u9fa5]$',
message: '不支持特殊字符、空格长度不得超过36个字符中文占2位',
trigger: 'blur',
},
],
},
{
field: 'personStatus',
component: 'NsSelect',
label: '状态',
componentProps: {
options: [
{
label: '在职',
value: 1,
},
{
label: '离职',
value: 2,
},
],
labelField: 'label',
valueField: 'value',
immediate: false,
// defaultValue: 1,
},
rules: [
{
required: true,
message: '不能为空',
},
],
},
{
field: 'personPicUuid',
component: 'NsUpload',
label: '员工图片',
componentProps: {
// 上传的地址
url: '/api/parking_merchant/objs/sys/FileUpload',
// 上传的图片大小
maxSize: 5242880,
// 上传的图片类型
fileType: ['jpg', 'png', 'jpeg'],
// 展示图片数量
count: 1,
// 上传的文件类型0-证书1-图片2-身份证件
uploadType: 1,
fieldName: 'certificateUuid',
baseImageUrl: personPicImageUrl,
},
},
{
field: 'idCardPicUuid',
component: 'NsUpload',
label: '身份证扫描件',
componentProps: {
// 上传的地址
url: '/api/parking_merchant/objs/sys/FileUpload',
// 上传的图片大小
maxSize: 5242880,
// 上传的图片类型
fileType: ['jpg', 'png', 'jpeg'],
// 展示图片数量
count: 1,
// 上传的文件类型0-证书1-图片2-身份证件
uploadType: 2,
baseImageUrl: idCardImageUrl,
},
// rules: [
// {
// required: true,
// message: '请上传图片',
// },
// ],
},
],
},
},
{
field: 'location',
label: '其他信息',
displayFormItem: false,
class: 'ns-form-item-full',
component: 'NsChildForm',
componentProps: {
title: '其他信息',
schemas: [
{
field: 'maritalStatus',
component: 'nsSelectApi',
label: '婚姻状况',
componentProps: {
api: '/api/community/objs/DictItem',
params: {
code: 'HYZK',
},
resultField: 'data',
labelField: 'dictName',
valueField: 'dictValue',
immediate: true,
autoSelectFirst: false,
},
// rules: [
// {
// required: true,
// message: '不能为空',
// },
// ],
},
{
field: 'education',
component: 'nsSelectApi',
// type: 'WHCD',
label: '文化程度',
componentProps: {
api: '/api/community/objs/DictItem',
params: {
code: 'WHCD',
},
resultField: 'data',
labelField: 'dictName',
valueField: 'dictValue',
immediate: true,
defaultValue: '4',
autoSelectFirst: false,
},
// rules: [
// {
// required: true,
// message: '不能为空',
// },
// ],
},
{
field: 'entryTime',
component: 'NsDatePicker',
label: '入职日期',
componentProps: {
valueFormat: 'x',
format: 'YYYY-MM-DD',
},
// rules: [
// {
// required: true,
// message: '不能为空',
// },
// ],
},
{
field: 'graduatedSchool',
label: '毕业院校',
component: 'NsInput',
rules: [
// {
// required: true,
// message: '毕业院校不能为空',
// trigger: 'blur',
// },
{
pattern:
/^[a-zA-Z\\d\u4e00-\u9fa5]{0,24}$|^[\u4e00-\u9fa5][a-zA-Z\\d\u4e00-\u9fa5]{0,24}[\u4e00-\u9fa5]$/,
message: '不支持特殊字符、空格长度不得超过24个字符中文占2位',
trigger: 'blur',
},
],
},
{
field: 'major',
label: '所属专业',
component: 'NsInput',
rules: [
{
pattern:
/^[a-zA-Z\\d\u4e00-\u9fa5]{0,24}$|^[\u4e00-\u9fa5][a-zA-Z\\d\u4e00-\u9fa5]{0,24}[\u4e00-\u9fa5]$/,
message: '不支持特殊字符、空格长度不得超过24个字符中文占2位',
trigger: 'blur',
},
],
},
{
field: 'email',
label: '邮箱地址',
component: 'NsInput',
rules: [
{
pattern: /^\w+@[a-z0-9]+\.[a-z]{2,4}$/,
message: '邮箱格式不正确',
trigger: 'blur',
},
],
},
{
field: 'residenceAddress',
label: '户籍地址',
component: 'NsInput',
rules: [
{
pattern:
/^[a-zA-Z\\d\u4e00-\u9fa5]{0,64}$|^[\u4e00-\u9fa5][a-zA-Z\\d\u4e00-\u9fa5]{0,64}[\u4e00-\u9fa5]$/,
message: '不支持特殊字符、空格长度不得超过64个字符中文占2位',
trigger: 'blur',
},
],
},
{
field: 'remarks',
label: '备注',
component: 'NsTextarea',
rules: [
{
pattern: /^[\u4e00-\u9fa5]{0,120}$|^.{0,255}$/,
message: '0-255个字符中文占2位',
trigger: 'blur',
},
],
},
],
},
},
]);
return {
formSchema,
data,
};
},
});
</script>
<style scoped lang="less">
.top {
border-bottom-color: #ecedef;
border-bottom-style: solid;
border-bottom-width: 1px;
}
</style>

View File

@@ -0,0 +1,81 @@
import { http } from '/nerv-lib/util/http';
let dictionary: any;
let dicCodeValueMap: any;
export function getDicCodeValue() {
asyncLoadDictTree();
return dicCodeValueMap;
}
export function getDictionary() {
return dictionary;
}
export function asyncLoadDictTree(): Promise<any> {
return http
.get('/api/community/objs/DictTree')
.then((res) => {
if (res) {
const response = res;
if (response && response['success']) {
const mainMap = {};
const codeValueMap = {};
transferData(response, 'data', mainMap);
setCodeValueMap(response, 'data', codeValueMap);
dicCodeValueMap = codeValueMap;
dictionary = mainMap;
return mainMap;
}
}
})
.catch((error) => {
console.log(error);
});
}
export function transferData(data, attri, mainMap): {} {
const objs = data[attri];
if (objs && objs instanceof Array && objs.length > 0) {
objs.forEach((it) => {
mainMap[it['dictCode']] = it;
mainMap[it['dictCode'] + '_' + 'name'] = it['dictName'];
if (it['subList'] && it['subList'] instanceof Array) {
mainMap[it['dictCode'] + '_' + 'subList'] = it['subList'];
transferData(it, 'subList', mainMap);
} else {
mainMap[it['dictCode'] + '_' + 'subList'] = [];
return;
}
});
} else {
return '';
}
}
export function setCodeValueMap(data: any, attri: any, map: any) {
const objs = data[attri];
if (objs && objs instanceof Array && objs.length > 0) {
objs.forEach((it) => {
map[it['dictParentCode'] + '_' + it['dictValue']] = it['dictName'];
map[it['dictParentCode'] + '_' + it['dictCode']] = it['dictName'];
if (it['subList'] && it['subList'] instanceof Array) {
setCodeValueMap(it, 'subList', map);
} else {
// map[it['dictParentCode'] + '_' + it['dictCode']] = '';
// map[it['dictParentCode'] + '_' + it['dictValue']] = '';
return;
}
});
} else {
return;
}
}
/**
* 根据code和value获取显示名
* @param code 字典code
* @param value 值
*/
export function getCodeNameFromValue(code, value): string {
console.log(code, value, 'code, value');
const name =
getDicCodeValue() && getDicCodeValue()[code + '_' + value]
? getDicCodeValue()[code + '_' + value]
: '';
return name;
}

View File

@@ -0,0 +1,218 @@
<template>
<ns-view-list-table v-bind="tableConfig" rowKey="uuid" />
</template>
<script lang="ts">
import { defineComponent } from 'vue';
export default defineComponent({
name: 'NsViewUserList',
setup() {
const tableConfig = {
title: '员工管理',
api: '/api/parking_merchant/objs/person/pageList',
params: {
page: 0,
pageSize: 10,
},
rowSelection: null,
// scroll: { x: 1150 },
columns: [
{
title: '姓名',
dataIndex: 'personName',
width: 200,
},
{
title: '性别',
dataIndex: 'sex',
width: 100,
customRender: (value) => {
switch (value.text) {
case 0:
return '女';
case 1:
return '男';
default:
return '-';
}
},
},
{
title: '员工编号',
dataIndex: 'personNum',
width: 150,
},
{
title: '手机号码',
dataIndex: 'telNum',
width: 150,
},
{
title: '账号状态',
dataIndex: 'accountState',
width: 100,
customRender: (value) => {
switch (value.text) {
case 1:
return '启用';
case 0:
return '禁用';
default:
return '-';
}
},
},
{
title: '用户状态',
width: 100,
dataIndex: 'personStatus',
customRender: (value) => {
switch (value.text) {
case 1:
return '在职';
case 2:
return '离职';
default:
return '-';
}
},
},
],
columnActions: {
title: '操作',
// width: 250,
actions: [
// {
// label: '查看',
// name: 'userDetail',
// dynamicParams: 'personUuid',
// route: '/userManage/user/detail',
// },
{
label: '重置密码',
dynamicParams: 'personUuid',
name: 'UserReset',
confirm: {
title: '提示',
content: `确认重置密码吗?`,
},
isReload: true,
api: '/api/parking_merchant/objs/person/reset',
},
{
label: '编辑',
dynamicParams: 'personUuid',
name: 'UserEdit',
route: '/userManage/user/edit',
},
{
label: '删除',
dynamicParams: {
personUuid: 'personUuid',
},
name: 'UserRemove',
ifShow: (record: any) => {
return record.personStatus !== 1;
},
confirm: true,
isReload: true,
api: '/api/parking_merchant/objs/person/delete',
},
{
label: '删除',
name: 'UserRemove',
dynamicParams: {
uuid: 'uuid',
},
ifShow: (record: any) => {
return record.personStatus === 1;
},
confirm: {
title: '警告',
content: '在职员工不可删除!',
},
},
],
},
headerActions: [
{
label: '新增用户',
name: 'UserAdd',
type: 'primary',
route: '/userManage/user/add',
},
],
formConfig: {
schemas: [
{
field: 'accountState',
label: '账号状态',
component: 'NsSelect',
componentProps: {
placeholder: '请选择',
options: [
{
label: '全部',
value: '',
},
{
label: '启用',
value: 1,
},
{
label: '禁用',
value: 0,
},
],
},
},
{
field: 'personStatus',
label: '用户状态',
component: 'NsSelect',
componentProps: {
placeholder: '请选择',
options: [
{
label: '全部',
value: '',
},
{
label: '在职',
value: 1,
},
{
label: '离职',
value: 2,
},
],
},
},
{
field: 'telNum',
label: '手机号码',
component: 'NsInput',
componentProps: {
placeholder: '请输入手机号码',
},
},
{
field: 'personName',
label: '用户姓名',
component: 'NsInput',
componentProps: {
placeholder: '请输入用户姓名',
},
},
],
},
rowKey: 'personUuid',
};
return {
tableConfig,
};
},
});
</script>
<style lang="less" scoped></style>