update&add 增加了选房及片区service

This commit is contained in:
2021-05-28 21:16:19 +08:00
parent 34c47e78b2
commit 7cef14c7fd
49 changed files with 2034 additions and 110 deletions

View File

@@ -4,16 +4,17 @@
background-color: @white;
}
.yo-list {
@title-color: lighten(@black, 70%);
@value-color: lighten(@black, 30%);
&-content--h {
display: flex;
align-items: center;
&--item {
min-width: 120px;
margin-left: @padding-xl;
>span {
line-height: 20px;
color: lighten(@black, 70%);
color: @title-color;
}
>p {
line-height: 22px;
@@ -21,11 +22,26 @@
margin-top: @padding-xxs;
margin-bottom: 0;
color: lighten(@black, 30%);
color: @value-color;
}
}
}
>.ant-pagination {
margin: @padding-md 0;
}
.ant-descriptions {
.ant-descriptions-item-label {
color: @title-color;
}
.ant-descriptions-item-content {
color: @value-color;
}
.ant-descriptions-row {
&:last-child {
>td {
padding-bottom: 0;
}
}
}
}
}

View File

@@ -23,4 +23,8 @@
.width-height(@i + 1);
}
.width-height(0);
.width-height(0);
.flex-1 {
flex: 1;
}

View File

@@ -105,13 +105,15 @@ for (let key in urls) {
_url = url
Object.keys(params).forEach(key => {
const value = params[key]
switch (value.constructor) {
case Array:
_params.push(...value.map(p => `${key}=${p}`))
break
default:
_params.push(`${key}=${value}`)
break
if (value) {
switch (value.constructor) {
case Array:
_params.push(...value.map(p => `${key}=${p}`))
break
default:
_params.push(`${key}=${value}`)
break
}
}
})
if (_params.length) {

View File

@@ -0,0 +1,12 @@
export default {
houseMemberPage: ['/houseMember/page', 'post'],
houseMemberAdd: ['/houseMember/add', 'post'],
houseMemberEdit: ['/houseMember/edit', 'post'],
houseMemberDelete: ['/houseMember/delete', 'post'],
houseMemberOwnRole: ['/houseMember/ownRole', 'get'],
houseMemberOwnData: ['/houseMember/ownData', 'get'],
houseMemberGrantData: ['/houseMember/grantData', 'post'],
houseMemberChangeStatus: ['/houseMember/changeStatus', 'post'],
houseMemberDefaultRole: ['/houseMember/defaultRole', 'get'],
houseMemberDefaultRoleList: ['/houseMember/defaultRoleRange', 'get']
}

View File

@@ -0,0 +1,3 @@
export default {
houseZoneList: '/houseZone/list'
}

View File

@@ -1,7 +1,11 @@
import houseProjectInfo from './houseProjectInfo'
import houseZone from './houseZone'
import houseCode from './houseCode'
import houseMember from './houseMember'
export default {
...houseProjectInfo,
...houseCode
...houseZone,
...houseCode,
...houseMember
}

View File

@@ -39,9 +39,7 @@ export default {
methods: {
onLoading() {
this.loading = {
indicator: <a-icon type="loading" spin />
}
this.loading = true
},
onLoaded() {
@@ -80,7 +78,6 @@ export default {
render() {
const props = {
loading: this.loading,
dataSource: this.data,
rowKey: record => record.id,
...this.$attrs
@@ -100,19 +97,22 @@ export default {
</div>
</div>
<div class="yo-list">
<a-list {...{ props, on, scopedSlots: { ...this.$scopedSlots } }}>
{Object.keys(this.$slots).map((name) => (
<template slot={name}>{this.$slots[name]}</template>
))}
</a-list>
{
!!this.data && !!this.data.length && <a-pagination
size="small"
{... { props: this.pagination }}
onChange={this.onListChange}
onShowSizeChange={this.onListChange}
/>
}
<a-spin spinning={this.loading}>
<a-icon slot="indicator" type="loading" spin />
<a-list {...{ props, on, scopedSlots: { ...this.$scopedSlots } }}>
{Object.keys(this.$slots).map((name) => (
<template slot={name}>{this.$slots[name]}</template>
))}
</a-list>
{
!!this.data && !!this.data.length && <a-pagination
size="small"
{... { props: this.pagination }}
onChange={this.onListChange}
onShowSizeChange={this.onListChange}
/>
}
</a-spin>
</div>
</section>
)

View File

@@ -21,6 +21,10 @@ export default {
},
moreQuery: {
type: Function
},
autoLoad: {
type: Boolean,
default: true
}
},
@@ -52,7 +56,8 @@ export default {
},
created() {
this.onLoadData()
if (this.autoLoad)
this.onLoadData()
},
methods: {

View File

@@ -8,7 +8,7 @@
<div class="yo-form-page">
<!-- 表单主体 -->
<!-- 如果不想使用固钉,删除a-row->a-col,只留内部的template层即可 -->
<container>
<container mode="container">
<a-row :gutter="16" type="flex">
<a-col flex="1">
<br />
@@ -39,7 +39,7 @@
<!-- 底部工具栏 -->
<div class="yo-form-page--bar">
<container>
<container mode="container">
<div class="yo-form-page--bar-inner">
<span>
<!-- 可以在工具栏中增加其他控件(只能在一行内) -->
@@ -124,15 +124,6 @@ export default {
.then(({ success }) => {
if (success) {
this.$message.success('保存成功');
this.$confirm({
content: '编辑成功,是否继续保留当前页?',
onOk: () => {
this.$refs.forms[0].onProjectChange();
},
onCancel: () => {
this.closeContentWindow();
},
});
}
})
.finally(() => {

View File

@@ -93,6 +93,15 @@
<a-form-model-item :colon="false" :label="true" class="ant-row-flex" v-if="houseCode">
<a-tag :key="index" color="purple" v-for="(item, index) in houseCode">{{ item}}</a-tag>
</a-form-model-item>
<a-form-model-item class="ant-row-flex" label="所属片区" prop="zoneId">
<a-select placeholder="请选择所属片区" v-model="form.zoneId">
<a-select-option
:key="item.id"
:value="item.id"
v-for="item in options.zones"
>{{ item.name }}</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item class="ant-row-flex" label="房屋地址" prop="address">
<a-input placeholder="请输入房屋地址或在地图上选择地点" v-model="form.address" />
</a-form-model-item>
@@ -130,9 +139,6 @@
<div class="h-500" ref="map"></div>
</div>
</a-form-model-item>
<a-form-model-item class="ant-row-flex" label="所属片区">
<a-select placeholder="请选择所属片区"></a-select>
</a-form-model-item>
</a-spin>
</a-form-model>
</template>
@@ -142,7 +148,6 @@ const defaultForm = {
/* ... */
type: '1',
no: '001',
zoneId: 'test',
};
export default {
@@ -171,6 +176,7 @@ export default {
areaCode: [{ required: true, message: '请选择房屋所在区域' }],
projectId: [{ required: true, message: '请选择项目' }],
no: [{ required: true, message: '请输入房屋序号', trigger: 'blur' }],
zoneId: [{ required: true, message: '请选择片区' }],
address: [{ required: true, message: '请输入房屋地址', trigger: 'blur' }],
lng: [{ required: true, message: '请在地图中选择坐标' }],
lat: [{ required: true, message: '请在地图中选择坐标' }],
@@ -189,6 +195,7 @@ export default {
options: {
areaTree: [],
projects: [],
zones: [],
},
};
},
@@ -477,22 +484,27 @@ export default {
/**
* 切换房屋性质
*/
onTypeChange() {
async onTypeChange() {
if (this.form.industry) {
this.form.industry = undefined;
}
this.getProjects();
this.loading = true;
await this.getProjects();
this.loading = false;
},
/**
* 切换区域
*/
onAreaCodeChange(autoChange = false) {
async onAreaCodeChange(autoChange = false) {
if (this.form.areaCode.length != 4) {
this.form.areaCode = [];
}
this.getProjects(autoChange);
this.loading = true;
await this.getProjects(autoChange);
await this.getZones(autoChange);
this.loading = false;
},
async getProjects(autoChange = false) {
@@ -500,7 +512,6 @@ export default {
this.form.projectId = undefined;
}
if (this.form.areaCode && this.form.areaCode.length === 4) {
this.loading = true;
const projects = await this.$api
.houseProjectList({
areaCode: this.form.areaCode[3],
@@ -510,7 +521,6 @@ export default {
return data;
});
this.options.projects = projects;
this.loading = false;
}
},
@@ -529,6 +539,23 @@ export default {
this.$set(this.form, 'no', no);
this.loading = false;
},
async getZones(autoChange = false) {
if (this.form.zoneId && !autoChange) {
this.form.zoneId = undefined;
}
if (this.form.areaCode && this.form.areaCode.length === 4) {
const zones = await this.$api
.houseZoneList({
areaCode: this.form.areaCode[3],
})
.then(({ data }) => {
return data;
});
this.options.zones = zones;
}
},
},
};
</script>

View File

@@ -97,19 +97,13 @@
</container>
</template>
<script>
import FormBody from './form';
/* 在此管理整个页面需要的接口名称 */
const api = {
page: 'houseCodePage',
delete: 'testDeleteApi...',
/* ... */
};
export default {
components: {
FormBody,
},
data() {
return {
api,
@@ -257,12 +251,12 @@ export default {
*/
onOpen(record) {
this.openContentWindow({
key: record ? record.id : 'business/house/houseCode/form',
key: record ? record.id : 'business/house/code/form',
title: record ? '修改房屋编码' : '新增房屋编码',
subTitle:
record &&
`${record.areaName}-${record.roadName}-${record.commName}-${record.note}-${`000${record.no}`.slice(-3)}`,
path: 'business/house/houseCode/form',
path: 'business/house/code/form',
param: {
record,
},

View File

@@ -0,0 +1,141 @@
<template>
<a-modal
:confirmLoading="confirmLoading"
:visible="visible"
@cancel="onCancel"
@ok="onOk"
class="yo-modal-form"
title="授权额外数据"
>
<a-form-model class="yo-form" ref="form">
<a-spin :spinning="loading">
<a-icon slot="indicator" spin type="loading" />
<div class="yo-form-group">
<a-form-model-item label="选择机构">
<a-tree-select
:show-checked-strategy="SHOW_PARENT"
:tree-data="orgTreeData"
placeholder="请选择机构"
search-placeholder="请检索"
tree-checkable
v-model="orgs"
/>
</a-form-model-item>
<a-form-model-item label="区域">
<a-tree-select
:replace-fields="{ title: 'name', value: 'code', children: 'children' }"
:show-checked-strategy="SHOW_PARENT"
:tree-data="arerTreeData"
placeholder="请区域"
search-placeholder="请检索"
tree-checkable
v-model="areas"
/>
</a-form-model-item>
</div>
</a-spin>
</a-form-model>
</a-modal>
</template>
<script>
import { TreeSelect } from 'ant-design-vue';
const SHOW_PARENT = TreeSelect.SHOW_PARENT;
export default {
data() {
return {
visible: false,
confirmLoading: false,
loading: false,
id: '',
orgs: [],
orgTreeData: [],
areas: [],
arerTreeData: [],
SHOW_PARENT,
};
},
methods: {
/**
* 必要的方法
* 从外部调用打开本窗口
*/
async onOpen(params) {
this.visible = true;
this.id = params.record.id;
this.$nextTick(() => {
this.onInit();
});
},
/**
* 必要的方法
* 点击保存时的操作
*/
onOk() {
this.confirmLoading = true;
this.$api
/** !!此处必须修改调用的接口方法 */
.houseMemberGrantData({
id: this.id,
grantOrgIdList: this.orgs,
grantAreaCodeList: this.areas,
})
.then(({ success }) => {
if (success) {
this.$message.success('授权成功');
this.onCancel();
this.$emit('ok');
}
})
.finally(() => {
this.confirmLoading = false;
});
},
/**
* 必要的方法
* 关闭窗口时的操作
*/
onCancel() {
this.visible = false;
setTimeout(() => {
this.orgs = [];
this.areas = [];
}, 300);
},
async onInit() {
this.loading = true;
this.orgTreeData = await this.onLoadOrgTreeData();
this.orgs = await this.onLoadOrg();
this.arerTreeData = await this.onLoadAreaTreeData();
this.loading = false;
},
onLoadOrgTreeData() {
return this.$api.getOrgTree().then(({ data }) => {
return data;
});
},
onLoadAreaTreeData() {
return this.$api.getAreaTree().then(({ data }) => {
return data;
});
},
onLoadOrg() {
return this.$api.houseMemberOwnData({ id: this.id }).then(({ data }) => {
return data;
});
},
},
};
</script>

View File

@@ -0,0 +1,323 @@
<template>
<!--
普通编辑窗体
v 1.2
2021-04-30
Lufthafen
-->
<a-form-model :model="form" :rules="rules" class="yo-form" ref="form">
<a-spin :spinning="loading">
<a-icon slot="indicator" spin type="loading" />
<div class="yo-form-group">
<a-form-model-item label="所属组织机构" prop="sysEmpParam.orgId" v-if="form.sysEmpParam">
<a-tree-select
:dropdown-style="{ maxHeight: '300px', overflow: 'auto' }"
:tree-data="orgData"
@change="onOrgChange"
placeholder="请选择所属组织机构"
tree-default-expand-all
v-model="form.sysEmpParam.orgId"
/>
</a-form-model-item>
<a-form-model-item prop="roleId">
<span slot="label">
角色
<a-tooltip title="片区内第一个用户必定为片区监管员,创建后不可更改角色">
<a-icon theme="twoTone" type="info-circle" />
</a-tooltip>
</span>
<a-select :disabled="lockRole" placeholder="请选择角色" v-model="form.roleId">
<a-select-option :key="item.id" :value="item.id" v-for="item in roleData">{{item.name}}</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item label="账号" prop="account">
<a-input placeholder="请输入账号" v-model="form.account" />
</a-form-model-item>
<a-form-model-item label="姓名" prop="name">
<a-input placeholder="请输入姓名" v-model="form.name" />
</a-form-model-item>
<template v-if="mode == 'add'">
<a-form-model-item label="密码" prop="password">
<a-input-password placeholder="请输入密码" v-model="form.password" />
</a-form-model-item>
<a-form-model-item label="确认密码" prop="confirm">
<a-input-password placeholder="请确认密码" v-model="form.confirm" />
</a-form-model-item>
</template>
<a-form-model-item label="昵称">
<a-input placeholder="请输入昵称" v-model="form.nickName" />
</a-form-model-item>
<a-form-model-item label="生日">
<a-date-picker
@change="(date) => (form.birthday = date ? $moment(date).format('YYYY-MM-DD') : null)"
class="w-100-p"
placeholder="请选择生日"
v-model="form.birthday"
/>
</a-form-model-item>
<a-form-model-item label="性别" prop="sex">
<a-radio-group v-model="form.sex">
<a-radio-button :value="0">
<a-icon class="mr-xxs" type="stop" />
<span>保密</span>
</a-radio-button>
<a-radio-button :value="1">
<a-icon :style="{ color: '#1890ff' }" class="mr-xxs" type="man" />
<span></span>
</a-radio-button>
<a-radio-button :value="2">
<a-icon :style="{ color: '#eb2f96' }" class="mr-xxs" type="woman" />
<span></span>
</a-radio-button>
</a-radio-group>
</a-form-model-item>
<a-form-model-item label="邮箱" prop="email">
<a-input placeholder="请输入邮箱" v-model="form.email" />
</a-form-model-item>
<a-form-model-item label="手机号" prop="phone">
<a-input placeholder="请输入手机号" v-model="form.phone" />
</a-form-model-item>
<a-form-model-item label="电话" prop="tel">
<a-input placeholder="请输入电话" v-model="form.tel" />
</a-form-model-item>
</div>
</a-spin>
</a-form-model>
</template>
<script>
const validateToNextPassword = (rule, value, callback) => {
callback();
};
const compareToFirstPassword = (rule, value, callback) => {
callback();
};
/* 表单内容默认值 */
const defaultForm = {
/* ... */
sex: 0,
sysEmpParam: {},
};
export default {
props: {
mode: {
type: String,
default: 'edit',
},
},
data() {
return {
/** 表单数据 */
form: {},
/** 验证格式 */
rules: {
/* ... */
roleId: [{ required: true, message: '请选择角色' }],
account: [{ required: true, min: 5, message: '请输入至少五个字符的账号', trigger: 'blur' }],
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
password: [
{ required: true, min: 5, message: '请输入至少五个字符的密码', trigger: 'blur' },
{ validator: validateToNextPassword, trigger: 'blur' },
],
confirm: [
{ required: true, message: '请确认密码', trigger: 'blur' },
{ validator: compareToFirstPassword, trigger: 'blur' },
],
phone: [
{
pattern: /^((13[0-9])|(14[5,7])|(15[^4,\\D])|(17[0,1,3,6-8])|(18[0-9])|(19[8,9])|(166))[0-9]{8}$/,
message: '手机号格式不正确',
trigger: 'blur',
},
],
email: [
{ pattern: /^\w{3,}(\.\w+)*@[A-z0-9]+(\.[A-z]{2,5}){1,2}$/, message: '邮箱格式不正确', trigger: 'blur' },
],
'sysEmpParam.orgId': [{ required: true, message: '请选择所属组织机构' }],
'sysEmpParam.posIdList': [{ required: true, message: '请选择职位信息' }],
},
/** 加载异步数据状态 */
loading: false,
/** 其他成员属性 */
/* ... */
orgData: [],
roleData: [],
defaultRole: undefined,
lockRole: false,
};
},
methods: {
/**
* 必要的方法
* 在打开编辑页时允许填充数据
*/
onFillData(params) {
const form = this.$_.cloneDeep(params.record || {});
// 日期特殊处理
if (form.birthday) {
form.birthday = this.$moment(form.birthday).format('YYYY-MM-DD');
}
// 提交的时候是"param",而获取下来却是"info",在这里转换一下
if (form.sysEmpInfo) {
form.sysEmpParam = form.sysEmpInfo;
delete form.sysEmpInfo;
} else if (!form.sysEmpParam) {
form.sysEmpParam = {
extIds: [],
};
}
// 转换职位信息列表
if (form.sysEmpParam.positions) {
form.sysEmpParam.posIdList = form.sysEmpParam.positions.map((p) => p.posId);
}
// 附加信息
if (form.sysEmpParam.extOrgPos) {
form.sysEmpParam.extIds = form.sysEmpParam.extOrgPos.map((p, i) => {
return {
key: i,
orgId: p.orgId,
posId: p.posId,
};
});
}
if (params.orgId) {
form.sysEmpParam.orgId = params.orgId;
}
if (this.defaultRole.constructor === Array) {
form.roleId = this.defaultRole[0];
} else {
form.roleId = this.defaultRole.id;
}
this.doLockRole();
/** 将默认数据覆盖到form */
this.form = this.$_.cloneDeep({
...defaultForm,
...form,
/** 在此处添加其他默认数据转换 */
/* ... */
});
},
/**
* 必要方法
* 验证表单并获取表单数据
*/
onGetData() {
return new Promise((reslove, reject) => {
this.$refs.form.validate((valid) => {
if (valid) {
const record = this.$_.cloneDeep(this.form);
/** 验证通过后可以对数据进行转换得到想要提交的格式 */
/* ... */
reslove(record);
} else {
reject();
}
});
});
},
/**
* 必要的方法
* 在外部窗口进行保存时调用表单验证
*/
onValidate(callback) {
this.$refs.form.validate(callback);
},
/**
* 必要的方法
* 在外部窗口关闭或重置时对表单验证进行初始化
*/
onResetFields() {
setTimeout(() => {
this.$refs.form.resetFields();
/** 在这里可以初始化当前组件中其他属性 */
/* ... */
this.form = {
...defaultForm,
};
this.defaultRole = undefined;
this.lockRole = false;
}, 300);
},
/**
* 必要方法
* 加载当前表单中所需要的异步数据
*/
async onInit(params) {
this.loading = true;
/** 可以在这里await获取一些异步数据 */
/* ... */
this.orgData = await this.onLoadOrgData();
this.roleData = await this.onLoadDefaultRoleList();
if (params.record) {
this.defaultRole = await this.onLoadOwnRole(params.record.id);
} else {
this.defaultRole = await this.onLoadDefaultRole(params.orgId);
}
this.loading = false;
},
/** 当前组件的其他方法 */
/* ... */
onLoadOrgData() {
return this.$api.getOrgTree().then(({ data }) => {
return data;
});
},
onLoadDefaultRole(orgId) {
return this.$api.houseMemberDefaultRole({ orgId }).then(({ data }) => {
return data;
});
},
onLoadDefaultRoleList() {
return this.$api.houseMemberDefaultRoleList().then(({ data }) => {
return data;
});
},
onLoadOwnRole(id) {
return this.$api.houseMemberOwnRole({ id }).then(({ data }) => {
return data;
});
},
async onOrgChange(orgId) {
this.loading = true;
if (!this.form.roleName) {
this.defaultRole = await this.onLoadDefaultRole(orgId);
this.form.roleId = this.defaultRole.id;
this.doLockRole();
}
this.loading = false;
},
doLockRole() {
if (this.defaultRole.constructor === Array) {
this.lockRole = true;
} else {
this.lockRole = this.defaultRole.code === 'zone_manager';
}
},
},
};
</script>

View File

@@ -0,0 +1,349 @@
<template>
<!--
普通树查询表格
v 1.2
2021-04-30
Lufthafen
-->
<yo-tree-layout
:load-data="loadTreeData"
@select="onSelect"
default-expanded-keys
ref="tree-layout"
>
<container>
<a-alert>
<template slot="message">在片区中必须...</template>
</a-alert>
<br />
<a-card :bordered="false">
<Auth auth="houseMember:page">
<div class="yo-query-bar">
<a-form-model :model="query" @submit.native.prevent layout="inline">
<a-form-model-item label="关键词">
<a-input allow-clear placeholder="请输入姓名、账号、手机号" v-model="query.searchValue" />
</a-form-model-item>
<a-form-model-item label="状态">
<a-select
:style="{ width: '170px' }"
allow-clear
placeholder="请选择状态"
v-model="query.searchStatus"
>
<a-select-option
:key="i"
:value="item.code"
v-for="(item, i) in codes.common_status"
>{{ item.value }}</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item>
<a-button-group>
<a-button @click="onQuery" html-type="submit" type="primary">查询</a-button>
<a-button @click="onResetQuery">重置</a-button>
</a-button-group>
</a-form-model-item>
</a-form-model>
</div>
</Auth>
<yo-list :load-data="loadData" item-layout="horizontal" ref="list" size="large">
<Auth auth="houseMember:add" slot="operator">
<a-button @click="onOpen('add-form')" icon="plus">新增用户</a-button>
</Auth>
<a-list-item key="record.id" slot="renderItem" slot-scope="record">
<Auth auth="houseMember:edit" slot="actions">
<a @click="onOpen('edit-form', record)">编辑</a>
</Auth>
<Auth auth="houseMember:delete" slot="actions">
<a-popconfirm @confirm="onDelete(record)" placement="topRight" title="是否确认删除">
<a>删除</a>
</a-popconfirm>
</Auth>
<Auth auth="houseMember:grantData" slot="actions">
<a @click="onOpen('data-form', record)">授权额外数据</a>
</Auth>
<a-list-item-meta>
<div slot="title">
{{ record.nickName || record.name }}
<template v-if="record.roleName">
<a-tag
:key="index"
color="pink"
v-for="(roleName, index) in record.roleName.split(',')"
>{{ roleName }}</a-tag>
</template>
</div>
<div slot="description">{{ record.account }}</div>
<div slot="avatar">
<yo-image :id="record.avatar" :size="48" icon="user" shape="square" type="avatar" />
<a-button
@click="$refs['selector-modal'].onOpen()"
class="block w-100-p mt-xxs"
size="small"
type="primary"
v-if="record.roleCode && record.roleCode.indexOf('house_security_manager') > -1"
>选房</a-button>
</div>
</a-list-item-meta>
<a-descriptions class="flex-1">
<a-descriptions-item label="部门">{{ record.orgName }}</a-descriptions-item>
<a-descriptions-item label="性别">{{ bindCodeValue(record.sex, 'sex') }}</a-descriptions-item>
<a-descriptions-item label="手机">{{ record.phone || '未设置' }}</a-descriptions-item>
<a-descriptions-item label="邮箱">{{ record.email || '未设置' }}</a-descriptions-item>
</a-descriptions>
<div class="yo-list-content--h">
<Auth auth="houseMember:changeStatus">
<div class="yo-list-content--h--item text-center">
<a-switch
:checked="!record.status"
:checked-children="bindCodeValue(0, 'common_status')"
:loading="record.statusChanging"
:un-checked-children="bindCodeValue(1, 'common_status')"
@change="(checked) => onSetUserStatus(record, checked)"
/>
</div>
</Auth>
</div>
</a-list-item>
</yo-list>
</a-card>
</container>
<!-- 新增表单 -->
<yo-modal-form :action="$api[api.add]" :title="'新增' + name" @ok="onReloadData" ref="add-form">
<form-body mode="add" />
</yo-modal-form>
<!-- 编辑表单 -->
<yo-modal-form :action="$api[api.edit]" :title="'编辑' + name" @ok="onReloadData" ref="edit-form">
<form-body mode="edit" />
</yo-modal-form>
<data-form @ok="onReloadData" ref="data-form" />
<selector @ok="onReloadData" ref="selector-modal" />
</yo-tree-layout>
</template>
<script>
/* 需要引用YoTreeLayout组件 */
import YoTreeLayout from '@/components/yoTreeLayout';
import YoList from '@/components/yoList';
import FormBody from './form';
import DataForm from './dataForm';
import Selector from './selector';
/* 在此管理整个页面需要的接口名称 */
const api = {
tree: 'getOrgTree',
page: 'houseMemberPage',
add: 'houseMemberAdd',
edit: 'houseMemberEdit',
delete: 'houseMemberDelete',
/* ... */
};
export default {
components: {
YoTreeLayout,
YoList,
FormBody,
DataForm,
Selector,
},
data() {
return {
api,
name: '用户',
/* 查询条件 */
query: {
sysEmpParam: {},
},
/* 表格字段 */
columns: [],
/* 字典编码储存格式 */
codes: {
sex: [],
common_status: [],
},
};
},
created() {
this.onLoadCodes();
/** 根据权限添加操作列 */
const flag = this.$auth({ houseMember: [['edit'], ['delete'], ['grantData']] });
if (flag) {
this.columns.push({
title: '操作',
width: '150px',
dataIndex: 'action',
scopedSlots: { customRender: 'action' },
});
}
},
methods: {
/**
* 树形选择界面必要的方法
* 传给yo-table-layout以示意数据接口
*/
loadTreeData() {
return this.$api[api.tree]().then((res) => {
return res.data;
});
},
/**
* 树形选择界面必要的方法
* 选择树节点事件
*/
onSelect([id]) {
/** 在选择事件中可以对右侧表格添加父节点id的查询条件 */
this.query = {
sysEmpParam: {
orgId: id,
},
};
this.onQuery();
},
/**
* 必要的方法
* 传给yo-table以示意数据接口及其参数和返回的数据结构
*/
loadData(params) {
return this.$api[api.page]({
...params,
...this.query,
}).then((res) => {
return res.data;
});
},
/**
* 有查询功能时的必要方法
* 加载数据时初始化分页信息
*/
onQuery() {
this.$refs.list.onReloadData(true);
},
/**
* 必要方法
* 重新列表数据
*/
onResetQuery() {
/* 与普通查询页不同的是,这里的父节点参数不应该在重置后被清空 */
Object.keys(this.query).forEach((p) => {
if (p !== 'sysEmpParam') {
this.query[p] = undefined;
}
});
this.onQuery();
},
/**
* 必要方法
* 重新列表数据
*/
onReloadData() {
this.$refs.list.onReloadData();
this.$refs['tree-layout'].onReloadData();
},
/**
* 必要方法
* 加载字典数据
* 如果不需要获取相应的字典数据,此方法内容可空
*/
onLoadCodes() {
this.$api
.$queue([
this.$api.sysDictTypeDropDownAwait({ code: 'sex' }),
this.$api.sysDictTypeDropDownAwait({ code: 'common_status' }),
/* ... */
])
.then(([sex, common_status]) => {
this.codes.sex = sex.data;
this.codes.common_status = common_status.data;
/* ... */
});
},
/**
* 必要方法
* 绑定数据字典值
*/
bindCodeValue(code, name) {
const c = this.codes[name].find((p) => p.code == code);
if (c) {
return c.value;
}
return null;
},
/**
* 有编辑新增功能的必要方法
* 从列表页调用窗口的打开方法
*/
onOpen(formName, record) {
this.$refs[formName].onOpen({
record,
orgId: this.query.sysEmpParam.orgId,
/* 按需添加其他参数 */
/* ... */
});
},
/**
* 必要方法
* 可以用做一系列操作的公共回调,此方法中会重新加载当前列表
*/
onResult(success, successMessage) {
if (success) {
this.$message.success(successMessage);
this.onReloadData();
}
},
/**
* 必要方法
* 删除时调用
*/
onDelete(record) {
this.$refs.table.onLoading();
this.$api[api.delete](record)
.then(({ success }) => {
this.onResult(success, '删除成功');
})
.finally(() => {
this.$refs.table.onLoaded();
});
},
onSetUserStatus(record, checked) {
this.$set(record, 'statusChanging', true);
this.$api
.houseMemberChangeStatus({
id: record.id,
status: +!checked,
})
.then(({ success }) => {
this.onResult(success, '操作成功');
})
.finally(() => {
record.statusChanging = false;
});
},
},
};
</script>

View File

@@ -0,0 +1,60 @@
<template>
<a-modal
:body-style="{ padding: 0 }"
:footer="false"
:visible="visible"
@cancel="visible = false"
destroy-on-close
width="80%"
>
<a-tabs :animated="false" :tab-bar-style="{ marginBottom: 0 }" default-active-key="1">
<a-tab-pane key="1" tab="选房">
<selector-list />
</a-tab-pane>
<a-tab-pane key="2" tab="已选">
<selected-list />
</a-tab-pane>
</a-tabs>
</a-modal>
</template>
<script>
import SelectorList from './selectorList';
import SelectedList from './selectedList';
export default {
components: {
SelectorList,
SelectedList,
},
data() {
return {
visible: false,
loading: false,
/** 其他成员属性 */
/* ... */
};
},
methods: {
onOpen(param) {
this.visible = true;
},
/**
* 必要方法
* 加载当前表单中所需要的异步数据
*/
async onInit(params) {
this.loading = true;
/** 可以在这里await获取一些异步数据 */
/* ... */
this.loading = false;
},
/** 当前组件的其他方法 */
/* ... */
},
};
</script>

View File

@@ -0,0 +1,3 @@
<template>
<div></div>
</template>

View File

@@ -0,0 +1,265 @@
<template>
<!--
普通查询表格
v 1.2
2021-04-30
Lufthafen
-->
<a-card :bordered="false" class="mb-none">
<yo-table
:auto-load="false"
:columns="columns"
:load-data="loadData"
:row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
@query="onQuery"
@resetQuery="onResetQuery"
ref="table"
>
<Auth auth="houseCode:page" slot="query">
<!-- 此处添加查询表单控件 -->
<!-- ... -->
<a-form-model-item label="编号">
<a-input-number
:formatter="(number) => number && `000${number}`.slice(-3)"
:max="999"
:min="1"
:precision="0"
:step="1"
placeholder="请输入房屋序号"
v-model="query.no"
/>
</a-form-model-item>
<a-form-model-item label="房屋性质">
<a-radio-group @change="onChangeQueryType" button-style="solid" v-model="query.type">
<a-radio-button :value="0">全部</a-radio-button>
<a-radio-button
:key="item.code"
:value="+item.code"
v-for="item in codes.type"
>{{item.value}}</a-radio-button>
</a-radio-group>
</a-form-model-item>
<a-form-model-item label="行业" v-if="query.type == 2">
<a-select class="w-150" placeholder="请选择行业" v-model="query.industry">
<a-select-option
:key="item.code"
:value="+item.code"
v-for="item in codes.industry"
>{{item.value}}</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item label="地址">
<a-input placeholder="请输入地址" v-model="query.address" />
</a-form-model-item>
<a-form-model-item label="房屋唯一编码">
<a-input placeholder="请输入房屋唯一编码" v-model="query.houseCode" />
</a-form-model-item>
</Auth>
<Auth auth="houseCode:add" slot="operator">
<a-button type="primary">确认选择</a-button>
</Auth>
<!-- 格式化字段内容 -->
<!-- ... -->
<template slot="houseCode" slot-scope="text, record">
<span>{{`${record.areaName}-${record.roadName}-${record.commName}-${record.note}-${`000${record.no}`.slice(-3)}`}}</span>
</template>
<template slot="type" slot-scope="text, record">
<span>{{bindCodeValue(text, 'type') + (text === 2 ? `(${bindCodeValue(record.industry, 'industry')})` : '')}}</span>
</template>
</yo-table>
</a-card>
</template>
<script>
/* 在此管理整个页面需要的接口名称 */
const api = {
page: 'houseCodePage',
/* ... */
};
export default {
data() {
return {
api,
name: '',
/* 查询条件 */
query: {
type: 0,
},
/* 表格字段 */
columns: [
{
title: '房屋编码',
dataIndex: 'houseCode',
sorter: true,
scopedSlots: { customRender: 'houseCode' },
width: 300,
},
{
title: '房屋性质及行业',
dataIndex: 'type',
sorter: true,
scopedSlots: { customRender: 'type' },
width: 150,
},
{
title: '地址',
dataIndex: 'address',
sorter: true,
},
{
title: '登记时间',
dataIndex: 'createdTime',
sorter: true,
width: 150,
},
],
/* 字典编码储存格式 */
codes: {
type: [],
industry: [],
},
options: {},
selectedRowKeys: [],
};
},
async created() {
/** 按需加载字典编码 */
await this.onLoadCodes();
this.onQuery();
},
methods: {
/**
* 必要的方法
* 传给yo-table以示意数据接口及其参数和返回的数据结构
*/
loadData(params) {
const query = this.$_.cloneDeep(this.query);
if (query.areaCode) {
query.areaCode = query.areaCode[query.areaCode.length - 1];
}
return this.$api[api.page]({
...params,
...query,
}).then((res) => {
return res.data;
});
},
/**
* 有查询功能时的必要方法
* 加载数据时初始化分页信息
*/
onQuery() {
this.$refs.table.onReloadData(true);
},
/**
* 有查询功能时的必要方法
* 重置查询条件
*/
onResetQuery() {
/** 在这里重置查询条件时,可对特殊的字段做保留处理 */
this.query = {
type: 0,
};
this.onQuery();
},
/**
* 必要方法
* 重新列表数据
*/
onReloadData() {
this.$refs.table.onReloadData();
},
/**
* 必要方法
* 加载字典数据
* 如果不需要获取相应的字典数据,此方法内容可空
*/
onLoadCodes() {
return this.$api
.sysDictTypeDropDowns({ code: ['dic_house_type', 'dic_house_industry'] })
.then(({ data: { dic_house_type, dic_house_industry } }) => {
this.codes.type = dic_house_type;
this.codes.industry = dic_house_industry;
});
},
/**
* 必要方法
* 绑定数据字典值
*/
bindCodeValue(code, name) {
const c = this.codes[name].find((p) => p.code == code);
if (c) {
return c.value;
}
return null;
},
/**
* 必要方法
* 从列表页调用窗口的打开方法
*/
onOpen(record) {
this.openContentWindow({
key: record ? record.id : 'business/house/code/form',
title: record ? '修改房屋编码' : '新增房屋编码',
subTitle:
record &&
`${record.areaName}-${record.roadName}-${record.commName}-${record.note}-${`000${record.no}`.slice(-3)}`,
path: 'business/house/code/form',
param: {
record,
},
});
},
/**
* 必要方法
* 可以用做一系列操作的公共回调,此方法中会重新加载当前列表
*/
onResult(success, successMessage) {
if (success) {
this.$message.success(successMessage);
this.onReloadData();
}
},
/**
* 必要方法
* 删除时调用
*/
onDelete(record) {
this.$refs.table.onLoading();
this.$api[api.delete](record)
.then(({ success }) => {
this.onResult(success, '删除成功');
})
.finally(() => {
this.$refs.table.onLoaded();
});
},
onChangeQueryType() {
if (this.query.type < 2 && this.query.hasOwnProperty('industry')) {
this.$delete(this.query, 'industry');
}
},
onSelectChange(selectedRowKeys) {
this.selectedRowKeys = selectedRowKeys;
},
},
};
</script>

View File

@@ -8,7 +8,7 @@
<br />
<div class="yo-form-group">
<!-- 表单控件 -->
<h3>基本信息</h3>
<h3 class="h3">基本信息</h3>
<div class="yo-form-group">
<a-form-model-item label="菜单类型" prop="type">
<template slot="help">
@@ -50,7 +50,7 @@
</a-form-model-item>
</div>
<h3>扩展信息</h3>
<h3 class="h3">扩展信息</h3>
<div class="yo-form-group">
<a-form-model-item label="打开方式" prop="openType" v-if="form.type == 1">
<a-radio-group @change="onOpenTypeChange" v-model="form.openType">

View File

@@ -5,7 +5,12 @@
2021-04-30
Lufthafen
-->
<yo-tree-layout :load-data="loadTreeData" @select="onSelect" default-expanded-keys ref="tree-layout">
<yo-tree-layout
:load-data="loadTreeData"
@select="onSelect"
default-expanded-keys
ref="tree-layout"
>
<container>
<a-card :bordered="false">
<Auth auth="sysUser:page">
@@ -15,8 +20,17 @@
<a-input allow-clear placeholder="请输入姓名、账号、手机号" v-model="query.searchValue" />
</a-form-model-item>
<a-form-model-item label="状态">
<a-select :style="{ width: '170px' }" allow-clear placeholder="请选择状态" v-model="query.searchStatus">
<a-select-option :key="i" :value="item.code" v-for="(item, i) in codes.common_status">{{ item.value }}</a-select-option>
<a-select
:style="{ width: '170px' }"
allow-clear
placeholder="请选择状态"
v-model="query.searchStatus"
>
<a-select-option
:key="i"
:value="item.code"
v-for="(item, i) in codes.common_status"
>{{ item.value }}</a-select-option>
</a-select>
</a-form-model-item>
<a-form-model-item>
@@ -65,24 +79,30 @@
<a-list-item-meta>
<div slot="title">{{ record.nickName || record.name }}</div>
<div slot="description">{{ record.account }}</div>
<yo-image :id="record.avatar" :size="48" icon="user" shape="square" slot="avatar" type="avatar" />
<yo-image
:id="record.avatar"
:size="48"
icon="user"
shape="square"
slot="avatar"
type="avatar"
/>
</a-list-item-meta>
<a-descriptions :column="2" class="flex-1">
<a-descriptions-item label="性别">{{ bindCodeValue(record.sex, 'sex') }}</a-descriptions-item>
<a-descriptions-item label="手机">{{ record.phone || '未设置' }}</a-descriptions-item>
<a-descriptions-item :span="2" label="邮箱">{{ record.email || '未设置' }}</a-descriptions-item>
</a-descriptions>
<div class="yo-list-content--h">
<div class="yo-list-content--h--item">
<span>性别</span>
<p>{{ bindCodeValue(record.sex, 'sex') }}</p>
</div>
<div class="yo-list-content--h--item">
<span>手机</span>
<p>{{ record.phone || '未设置' }}</p>
</div>
<div class="yo-list-content--h--item">
<span>邮箱</span>
<p>{{ record.email || '未设置' }}</p>
</div>
<Auth auth="sysUser:changeStatus">
<div class="yo-list-content--h--item text-center">
<a-switch :checked="!record.status" :checked-children="bindCodeValue(0, 'common_status')" :loading="record.statusChanging" :un-checked-children="bindCodeValue(1, 'common_status')" @change="(checked) => onSetUserStatus(record, checked)" />
<a-switch
:checked="!record.status"
:checked-children="bindCodeValue(0, 'common_status')"
:loading="record.statusChanging"
:un-checked-children="bindCodeValue(1, 'common_status')"
@change="(checked) => onSetUserStatus(record, checked)"
/>
</div>
</Auth>
</div>
@@ -92,12 +112,24 @@
</container>
<!-- 新增表单 -->
<yo-modal-form :action="$api[api.add]" :title="'新增' + name" :width="1024" @ok="onReloadData" ref="add-form">
<yo-modal-form
:action="$api[api.add]"
:title="'新增' + name"
:width="1024"
@ok="onReloadData"
ref="add-form"
>
<form-body mode="add" />
</yo-modal-form>
<!-- 编辑表单 -->
<yo-modal-form :action="$api[api.edit]" :title="'编辑' + name" :width="1024" @ok="onReloadData" ref="edit-form">
<yo-modal-form
:action="$api[api.edit]"
:title="'编辑' + name"
:width="1024"
@ok="onReloadData"
ref="edit-form"
>
<form-body mode="edit" />
</yo-modal-form>
@@ -140,7 +172,9 @@ export default {
name: '用户',
/* 查询条件 */
query: {},
query: {
sysEmpParam: {},
},
/* 表格字段 */
columns: [],