fix
This commit is contained in:
parent
3c65fc7606
commit
56159bd2fd
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"navigationBarTitleText": "人员管理",
|
||||
"usingComponents": {
|
||||
"l-button": "../../lin-ui/button/index",
|
||||
"l-card": "../../lin-ui/card/index",
|
||||
"l-tag": "../../lin-ui/tag/index",
|
||||
"l-icon": "../../lin-ui/icon/index",
|
||||
"l-status-show": "../../lin-ui/status-show/index",
|
||||
"l-search-bar": "../../lin-ui/search-bar/index",
|
||||
"l-price": "../../lin-ui/price/index",
|
||||
"divider": "../../components/divider/index",
|
||||
"fab": "../../components/fab/index",
|
||||
"l-checkbox": "../../lin-ui/checkbox/index",
|
||||
"l-message": "../../lin-ui/message/index"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/** index.wxss **/
|
||||
@import "../../config/styles/_base.less";
|
||||
@import "../../config/styles/_mixins.less";
|
||||
|
||||
page {
|
||||
height: 100%;
|
||||
background-color: @background-color-base;
|
||||
}
|
||||
|
||||
.container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
align-items: stretch;
|
||||
padding: 0;
|
||||
.safe-area-inset-bottom();
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
background-color: #fff;
|
||||
padding-top: 10rpx;
|
||||
padding-bottom: 10rpx;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.card-view {
|
||||
margin-top: @size-spacing-small !important;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
font-size: 28rpx;
|
||||
color: @text-color;
|
||||
}
|
||||
|
||||
.col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.name {
|
||||
font-size: @size-font-large;
|
||||
color: @title-color;
|
||||
}
|
||||
.mobile {
|
||||
font-size: @size-font-base;
|
||||
color: @text-color;
|
||||
}
|
||||
.img {
|
||||
width: 140rpx;
|
||||
height: 140rpx;
|
||||
margin-right: @size-spacing-small;
|
||||
border-radius: 50%;
|
||||
background-color: @background-color-base;
|
||||
}
|
||||
.card-view {
|
||||
margin: @size-spacing-small;
|
||||
padding: @size-spacing-small;
|
||||
margin-bottom: 0;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
|
@ -0,0 +1,188 @@
|
|||
|
||||
export default OakComponent(
|
||||
{
|
||||
path: 'userSearch:search',
|
||||
entity: 'user',
|
||||
projection: {
|
||||
id: 1,
|
||||
name: 1,
|
||||
nickname: 1,
|
||||
mobile$user: {
|
||||
$entity: 'mobile',
|
||||
data: {
|
||||
id: 1,
|
||||
userId: 1,
|
||||
mobile: 1,
|
||||
},
|
||||
},
|
||||
// extraFile$entity: {
|
||||
// $entity: 'extraFile',
|
||||
// data: {
|
||||
// id: 1,
|
||||
// tag1: 1,
|
||||
// origin: 1,
|
||||
// bucket: 1,
|
||||
// objectId: 1,
|
||||
// filename: 1,
|
||||
// extra1: 1,
|
||||
// type: 1,
|
||||
// entity: 1,
|
||||
// extension: 1,
|
||||
// },
|
||||
// filter: {
|
||||
// tag1: 'avatar',
|
||||
// },
|
||||
// indexFrom: 0,
|
||||
// count: 1,
|
||||
// },
|
||||
},
|
||||
filters: [
|
||||
// {
|
||||
// filter: async ({ onLoadOptions }) => {
|
||||
// return {
|
||||
// id: {
|
||||
// $in: {
|
||||
// entity: 'mobile',
|
||||
// data: {
|
||||
// userId: 1,
|
||||
// },
|
||||
// filter: {
|
||||
// mobile: {
|
||||
// $eq: '111111111112',
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
// },
|
||||
// '#name': 'mobile',
|
||||
// },
|
||||
],
|
||||
isList: false,
|
||||
formData: async function ({ data: users, params, features }) {
|
||||
|
||||
const isRoot = await features.token.isRoot();
|
||||
const filter = await this.getFilterByName('name');
|
||||
|
||||
return {
|
||||
users: users?.map((ele: any) => {
|
||||
const { mobile$user, extraFile$entity } =
|
||||
ele || {};
|
||||
const mobile = mobile$user && mobile$user[0]?.mobile;
|
||||
const avatar =
|
||||
extraFile$entity &&
|
||||
extraFile$entity[0] &&
|
||||
composeFileUrl(extraFile$entity[0]);
|
||||
const user2 = Object.assign({}, ele, {
|
||||
mobile,
|
||||
avatar,
|
||||
});
|
||||
return user2;
|
||||
}),
|
||||
searchValue: (
|
||||
filter?.$or as [{ name: { $includes: string } }]
|
||||
)[0].name.$includes,
|
||||
isRoot,
|
||||
};
|
||||
},
|
||||
properties: {
|
||||
},
|
||||
data: {},
|
||||
lifetimes: {
|
||||
ready() {
|
||||
const searchStr = wx.getStorageSync('user_searchList') as string;
|
||||
if (searchStr.length) {
|
||||
const searchArr = JSON.parse(searchStr) as Array<string>;
|
||||
this.addNamedFilter({
|
||||
filter: {
|
||||
id: {
|
||||
$in: {
|
||||
entity: 'mobile',
|
||||
data: {
|
||||
userId: 1,
|
||||
},
|
||||
filter: {
|
||||
$or: searchArr.map(ele => {
|
||||
{
|
||||
mobile: {
|
||||
$eq: ele
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'#name': 'mobile',
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async searchChange(input: any) {
|
||||
},
|
||||
async searchCancel() {
|
||||
this.setState({
|
||||
searchValue: '',
|
||||
})
|
||||
},
|
||||
async searchConfirm(input: any) {
|
||||
const { value } = this.resolveInput(input);
|
||||
if (value.length < 11) {
|
||||
this.setState({
|
||||
msgType: 'warning',
|
||||
showMsg: true,
|
||||
content: '手机号位数不足11位'
|
||||
})
|
||||
return;
|
||||
}
|
||||
const searchStr = wx.getStorageSync('user_searchList') as string;
|
||||
let searchArr: Array<string> = [];
|
||||
if (!searchStr) {
|
||||
searchArr.push(value)
|
||||
}
|
||||
else {
|
||||
searchArr = JSON.parse(searchStr) as Array<string>;
|
||||
}
|
||||
wx.setStorageSync('user_searchList', JSON.stringify(searchArr));
|
||||
this.addNamedFilter({
|
||||
filter: {
|
||||
id: {
|
||||
$in: {
|
||||
entity: 'mobile',
|
||||
data: {
|
||||
userId: 1,
|
||||
},
|
||||
filter: {
|
||||
mobile: {
|
||||
$eq: value,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'#name': 'mobile',
|
||||
});
|
||||
this.refresh();
|
||||
},
|
||||
goUpsertUser() {
|
||||
const { entity, entityId } = this.props;
|
||||
this.navigateTo({
|
||||
url: '../../user/manage/upsert/index',
|
||||
});
|
||||
},
|
||||
handleCardClick(event: any) {
|
||||
const { entity, entityId } = this.props;
|
||||
const { dataset } = this.resolveInput(event);
|
||||
const { id } = dataset!;
|
||||
this.navigateTo({
|
||||
url: '../detail/index',
|
||||
oakId: id,
|
||||
entity,
|
||||
entityId,
|
||||
relations: JSON.stringify(['manager', 'owner']),
|
||||
});
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<!-- index.wxml -->
|
||||
<view class="container">
|
||||
<view class="search-bar">
|
||||
<l-search-bar placeholder="输入手机号" shape="circle" value="{{searchValue}}" bind:lincancel="searchCancel" bind:linclear="searchCancel" bind:linchange="searchChange" bind:linconfirm="searchConfirm" />
|
||||
</view>
|
||||
<block wx:if="{{ users && users.length > 0 }}">
|
||||
<block wx:for="{{users}}" wx:key="index" wx:for-item="item">
|
||||
<view class="card-view">
|
||||
<view class="row">
|
||||
<l-checkbox key="{{item.id || '1'}}" checked="{{false}}"></l-checkbox>
|
||||
<image mode="aspectFill" class="img" src="{{item.avatar}}" lazy-load></image>
|
||||
<view class="col">
|
||||
<text class="name">{{item.name}}</text>
|
||||
<text class="mobile">{{item.nickname}}</text>
|
||||
<text class="mobile">{{item.mobile}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</block>
|
||||
<block wx:if="{{isRoot}}">
|
||||
<fab bind:click="goUpsertUser">
|
||||
<l-icon name="add" type="material" color="#fff" size="48" />
|
||||
</fab>
|
||||
</block>
|
||||
</block>
|
||||
<block wx:elif="{{isRoot}}">
|
||||
<l-status-show show="{{true}}" type="data" button-text="添加人员" bind:lintap="goUpsertUser"></l-status-show>
|
||||
</block>
|
||||
<l-message type="{{msgType}}" show="{{showMsg}}" content="{{content}}" />
|
||||
</view>
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/** index.wxss **/
|
||||
@import "../../../styles/base.less";
|
||||
@import "../../../config/_base.less";
|
||||
|
||||
.page-body {
|
||||
height: 100vh;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
@import "../../../styles/base.less";
|
||||
@import "../../../config/_base.less";
|
||||
.container {
|
||||
height: 100vh;
|
||||
background-color: @background-color-base;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/** index.wxss **/
|
||||
@import "../../../styles/base.less";
|
||||
@import "../../../config/_base.less";
|
||||
|
||||
.page-body {
|
||||
height: 100vh;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/** index.wxss **/
|
||||
@import "../../../styles/base.less";
|
||||
@import "../../../config/_base.less";
|
||||
|
||||
page {
|
||||
height: 100%;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"navigationBarTitleText": "人员管理",
|
||||
"usingComponents": {
|
||||
"l-button": "../../../lin-ui/button/index",
|
||||
"l-card": "../../../lin-ui/card/index",
|
||||
"l-tag": "../../../lin-ui/tag/index",
|
||||
"l-icon": "../../../lin-ui/icon/index",
|
||||
"l-status-show": "../../../lin-ui/status-show/index",
|
||||
"l-search-bar": "../../../lin-ui/search-bar/index",
|
||||
"l-price": "../../../lin-ui/price/index",
|
||||
"divider": "../../../components/divider/index",
|
||||
"fab": "../../../components/fab/index",
|
||||
"l-checkbox": "../../../lin-ui/checkbox/index",
|
||||
"l-message": "../../../lin-ui/message/index"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/** index.wxss **/
|
||||
@import "../../../config/styles/_base.less";
|
||||
@import "../../../config/styles/_mixins.less";
|
||||
|
||||
page {
|
||||
height: 100%;
|
||||
background-color: @background-color-base;
|
||||
}
|
||||
|
||||
.container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
align-items: stretch;
|
||||
padding: 0;
|
||||
.safe-area-inset-bottom();
|
||||
}
|
||||
|
||||
.search-bar {
|
||||
display: flex;
|
||||
height: 40px;
|
||||
background-color: #fff;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
|
||||
.col {
|
||||
padding: @size-spacing-small;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: @size-font-base;
|
||||
margin-bottom: @size-spacing-small;
|
||||
}
|
||||
.drawer-view {
|
||||
position: fixed;
|
||||
top: 40px;
|
||||
width: 100%;
|
||||
background-color: @background-color-base;
|
||||
}
|
||||
.drawer-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 38px;
|
||||
color: @text-color;
|
||||
margin-top: 1px;
|
||||
padding: 0rpx @size-spacing-small;
|
||||
background-color: #fff;
|
||||
}
|
||||
.search-value {
|
||||
color: @error-color;
|
||||
}
|
||||
.null {
|
||||
text-align: center;
|
||||
}
|
||||
.delete-btn {
|
||||
padding: @size-spacing-small;
|
||||
font-size: @size-font-base;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: @default-color;
|
||||
}
|
||||
.tag {
|
||||
margin: 4rpx;
|
||||
}
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
|
||||
export default OakPage(
|
||||
{
|
||||
path: 'userSearch:search',
|
||||
entity: 'user',
|
||||
projection: {
|
||||
id: 1,
|
||||
name: 1,
|
||||
nickname: 1,
|
||||
mobile$user: {
|
||||
$entity: 'mobile',
|
||||
data: {
|
||||
id: 1,
|
||||
userId: 1,
|
||||
mobile: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
filters: [
|
||||
{
|
||||
filter: {
|
||||
id: {
|
||||
$in: {
|
||||
entity: 'mobile',
|
||||
data: {
|
||||
userId: 1,
|
||||
},
|
||||
filter: {
|
||||
mobile: {
|
||||
$eq: '11111111112',
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
'#name': 'userSearch'
|
||||
}
|
||||
],
|
||||
isList: true,
|
||||
formData: async function ({ data: users, params, features }) {
|
||||
const { searchValue, go } = this.data;
|
||||
go && this.goPage(users);
|
||||
const isRoot = await features.token.isRoot();
|
||||
let nodeStr = '';
|
||||
const userIds: Array<string> = [];
|
||||
if (users.length) {
|
||||
for (let i = 0; i < users.length; i++) {
|
||||
userIds.push(users[i].id);
|
||||
const { mobile$user, name } = users[i] || {};
|
||||
let itemStr: String = name || '';
|
||||
const mobile = mobile$user && mobile$user[0]?.mobile;
|
||||
if (!mobile && !name) {
|
||||
continue;
|
||||
}
|
||||
if (mobile) {
|
||||
itemStr += " " + mobile;
|
||||
}
|
||||
const itemStr2 = itemStr.replace(searchValue, `<span class='search-value'>${searchValue}</span>`)
|
||||
nodeStr += `<div class="drawer-item" bind:tap="itemClick"><span>${itemStr2}</span></divider>`
|
||||
}
|
||||
}
|
||||
return {
|
||||
users,
|
||||
userIds,
|
||||
nodeStr,
|
||||
isRoot,
|
||||
showList: !!userIds.length
|
||||
};
|
||||
},
|
||||
properties: {
|
||||
toUrl: String,
|
||||
},
|
||||
data: {
|
||||
go: false,
|
||||
showList: false,
|
||||
},
|
||||
lifetimes: {
|
||||
ready() {
|
||||
const searchStr = wx.getStorageSync('user_searchList') as string;
|
||||
if (searchStr.length) {
|
||||
this.setState({
|
||||
searchArr: JSON.parse(searchStr),
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
setFilter(value: string) {
|
||||
this.addNamedFilter({
|
||||
filter: {
|
||||
$or: [
|
||||
{
|
||||
name: {
|
||||
$includes: value!,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: {
|
||||
$in: {
|
||||
entity: 'mobile',
|
||||
data: {
|
||||
userId: 1,
|
||||
},
|
||||
filter: {
|
||||
mobile: {
|
||||
$includes: value!,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
},
|
||||
'#name': 'userSearch',
|
||||
});
|
||||
},
|
||||
goPage(data: any) {
|
||||
const { toUrl } = this.data;
|
||||
const userIds = data?.map((ele: any) => ele.id);
|
||||
this.navigateTo({
|
||||
url: toUrl,
|
||||
userIds,
|
||||
});
|
||||
this.setState({
|
||||
go: false,
|
||||
})
|
||||
},
|
||||
tagClick(event: any) {
|
||||
const { value } = event.currentTarget.dataset;
|
||||
this.setFilter(value);
|
||||
this.setState({
|
||||
go: true,
|
||||
})
|
||||
this.refresh();
|
||||
},
|
||||
itemClick(event: any) {
|
||||
//由于rich-text屏蔽了所有子节点的事件,所以这里根据触摸点进行判断
|
||||
//搜索栏高度40px 每个可点击项38px
|
||||
const { toUrl, searchValue, userIds } = this.data;
|
||||
const { pageY } = event.touches[0];
|
||||
const index = Math.floor((pageY - 40) / 38);
|
||||
if (index + 1 > userIds.length) {
|
||||
this.setState({
|
||||
showList: false,
|
||||
})
|
||||
return;
|
||||
}
|
||||
const searchStr = wx.getStorageSync('user_searchList') as string;
|
||||
let searchArr: Array<string> = [];
|
||||
if (!searchStr) {
|
||||
searchArr.push(searchValue)
|
||||
}
|
||||
else {
|
||||
searchArr = JSON.parse(searchStr) as Array<string>;
|
||||
if (!searchArr.includes(searchValue)) {
|
||||
searchArr.push(searchValue);
|
||||
}
|
||||
}
|
||||
wx.setStorageSync('user_searchList', JSON.stringify(searchArr));
|
||||
this.navigateTo({
|
||||
url: toUrl,
|
||||
userIds: userIds[index],
|
||||
})
|
||||
},
|
||||
clearSearchHistory() {
|
||||
this.setState({
|
||||
searchArr: [],
|
||||
});
|
||||
wx.setStorageSync('user_searchList', '');
|
||||
},
|
||||
async searchChange(input: any) {
|
||||
const { value } = this.resolveInput(input);
|
||||
if (!value) {
|
||||
this.setState({
|
||||
searchValue: value,
|
||||
showList: false,
|
||||
})
|
||||
return;
|
||||
}
|
||||
this.setFilter(value);
|
||||
this.setState({
|
||||
searchValue: value,
|
||||
})
|
||||
this.refresh();
|
||||
},
|
||||
async searchCancel() {
|
||||
this.setState({
|
||||
searchValue: '',
|
||||
showList: false,
|
||||
})
|
||||
},
|
||||
async searchConfirm(input: any) {
|
||||
const { value } = this.resolveInput(input);
|
||||
const searchStr = wx.getStorageSync('user_searchList') as string;
|
||||
let searchArr: Array<string> = [];
|
||||
if (!searchStr) {
|
||||
searchArr.push(value)
|
||||
this.setState({
|
||||
searchArr,
|
||||
})
|
||||
}
|
||||
else {
|
||||
searchArr = JSON.parse(searchStr) as Array<string>;
|
||||
if (!searchArr.includes(value)) {
|
||||
searchArr.push(value);
|
||||
}
|
||||
this.setState({
|
||||
searchArr,
|
||||
})
|
||||
}
|
||||
wx.setStorageSync('user_searchList', JSON.stringify(searchArr));
|
||||
this.setFilter(value);
|
||||
this.refresh();
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<!-- index.wxml -->
|
||||
<view class="container">
|
||||
<view class="search-bar">
|
||||
<l-search-bar style="width: 100%; margin: auto 0rpx" placeholder="输入手机号/姓名" shape="circle" value="{{searchValue}}" bind:lincancel="searchCancel" bind:linclear="searchCancel" bind:linchange="searchChange" bind:linconfirm="goPage" />
|
||||
</view>
|
||||
<block wx:if="{{showList}}">
|
||||
<view class="drawer-view">
|
||||
<rich-text nodes="{{nodeStr}}" bind:tap="itemClick"></rich-text>
|
||||
</view>
|
||||
</block>
|
||||
<view wx:if="{{searchArr.length}}" class="col">
|
||||
<text class="title">搜索历史</text>
|
||||
<view class="row">
|
||||
<l-tag wx:for="{{searchArr}}" bind:tap="tagClick" wx:key="index" wx:for-item="searchItem" class="tag" data-value="searchItem">
|
||||
{{searchItem}}
|
||||
</l-tag>
|
||||
</view>
|
||||
<view class="delete-btn" bind:tap="clearSearchHistory">
|
||||
<l-icon name="delete" size="28"></l-icon>
|
||||
<text style="margin-left: 4px">清空搜索历史</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/** index.wxss **/
|
||||
@import "../../../styles/base.less";
|
||||
@import "../../../config/_base.less";
|
||||
@import "../../../styles/mixins.less";
|
||||
|
||||
.page-body {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/** index.wxss **/
|
||||
@import "../../../styles/base.less";
|
||||
@import "../../../config/_base.less";
|
||||
@import "../../../styles/mixins.less";
|
||||
|
||||
.page-body {
|
||||
|
|
|
|||
Loading…
Reference in New Issue