128 changed files with 3528 additions and 2184 deletions
@ -0,0 +1,10 @@ |
|||||
|
import { i18n } from '@/platform/plugin'; |
||||
|
|
||||
|
const menuTypeFormater = (value) => { |
||||
|
if (value) { |
||||
|
return i18n.global.t('io.sc.platform.system.enums.MenuType.' + value); |
||||
|
} |
||||
|
return ''; |
||||
|
}; |
||||
|
|
||||
|
export { menuTypeFormater }; |
@ -0,0 +1,91 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<q-input |
||||
|
v-show="!hideIfComputed" |
||||
|
ref="textareaRef" |
||||
|
:hide-bottom-space="true" |
||||
|
:hide-hint="true" |
||||
|
:outlined="true" |
||||
|
:dense="true" |
||||
|
v-bind="attrs" |
||||
|
type="textarea" |
||||
|
:rules="rulesComputed" |
||||
|
:readonly="readonlyIfComputed" |
||||
|
:disable="disableIfComputed" |
||||
|
> |
||||
|
<template #label> <span v-if="requiredIfComputed" style="color: red">*</span> {{ attrs.label }}</template> |
||||
|
</q-input> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"> |
||||
|
import { ref, computed, defineProps, useAttrs } from 'vue'; |
||||
|
import { FormValidators } from '@/platform/components'; |
||||
|
|
||||
|
const textareaRef = ref(); |
||||
|
const attrs = useAttrs(); |
||||
|
const inRules = attrs.rules; |
||||
|
const props = defineProps({ |
||||
|
hideIf: { |
||||
|
type: Function, |
||||
|
default: () => { |
||||
|
return false; |
||||
|
}, |
||||
|
}, |
||||
|
required: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
requiredIf: { |
||||
|
type: Function, |
||||
|
default: undefined, |
||||
|
}, |
||||
|
readonlyIf: { |
||||
|
type: Function, |
||||
|
default: () => { |
||||
|
return false; |
||||
|
}, |
||||
|
}, |
||||
|
disableIf: { |
||||
|
type: Function, |
||||
|
default: () => { |
||||
|
return false; |
||||
|
}, |
||||
|
}, |
||||
|
form: { |
||||
|
type: Object, |
||||
|
default: undefined, |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
const rulesComputed = computed(() => { |
||||
|
let rules = inRules || <any>[]; |
||||
|
if (!hideIfComputed.value && requiredIfComputed.value) { |
||||
|
rules.push(FormValidators.required()); |
||||
|
} else if (hideIfComputed.value) { |
||||
|
rules = []; |
||||
|
} |
||||
|
if (textareaRef?.value) { |
||||
|
textareaRef.value.resetValidation(); |
||||
|
} |
||||
|
return rules; |
||||
|
}); |
||||
|
|
||||
|
const hideIfComputed = computed(() => { |
||||
|
return props.hideIf(props.form); |
||||
|
}); |
||||
|
const requiredIfComputed = computed(() => { |
||||
|
if (props.requiredIf) { |
||||
|
return props.requiredIf(props.form) || false; |
||||
|
} else if (props.required) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
}); |
||||
|
const readonlyIfComputed = computed(() => { |
||||
|
return props.readonlyIf(props.form); |
||||
|
}); |
||||
|
const disableIfComputed = computed(() => { |
||||
|
return props.disableIf(props.form); |
||||
|
}); |
||||
|
</script> |
@ -0,0 +1,11 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<q-chip v-if="enable" color="green" text-color="white" :label="$t('normal')" dense></q-chip> |
||||
|
<q-chip v-if="!enable" color="red" text-color="white" :label="$t('disable')" dense></q-chip> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
const props = defineProps({ |
||||
|
enable: { type: Boolean, default: true }, |
||||
|
}); |
||||
|
</script> |
@ -0,0 +1,69 @@ |
|||||
|
<template> |
||||
|
<w-dialog |
||||
|
ref="setPasswordDialogRef" |
||||
|
:title="$t('system.user.action.' + actionType)" |
||||
|
width="500px" |
||||
|
height="230px" |
||||
|
:can-maximize="false" |
||||
|
:buttons="[ |
||||
|
{ |
||||
|
label: $t('submit'), |
||||
|
click: () => { |
||||
|
axios |
||||
|
.post(Environment.apiContextPath('/api/system/user/' + actionType), { |
||||
|
userIds: userIds, |
||||
|
password: setPasswordFormRef.getData().password, |
||||
|
}) |
||||
|
.then(() => { |
||||
|
setPasswordDialogRef.hide(); |
||||
|
NotifyManager.info($t('operationSuccess')); |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
]" |
||||
|
> |
||||
|
<w-form |
||||
|
ref="setPasswordFormRef" |
||||
|
:cols-num="1" |
||||
|
:fields="[ |
||||
|
{ name: 'password', label: $t('password'), type: 'password', required: true }, |
||||
|
{ |
||||
|
name: 'confirmPassword', |
||||
|
label: $t('confirmPassword'), |
||||
|
type: 'password', |
||||
|
required: true, |
||||
|
rules: [ |
||||
|
(value) => { |
||||
|
return Tools.stringEquals(setPasswordFormRef.getData().password, value) ? true : $t('passwordAndConfirmPasswordMustEqual'); |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
]" |
||||
|
class="p-2" |
||||
|
></w-form> |
||||
|
</w-dialog> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref } from 'vue'; |
||||
|
import { axios, Environment, NotifyManager, Tools } from '@/platform'; |
||||
|
|
||||
|
const setPasswordDialogRef = ref(); |
||||
|
const setPasswordFormRef = ref(); |
||||
|
let actionType = ref(); |
||||
|
let userIds = []; |
||||
|
|
||||
|
const open = (type, users) => { |
||||
|
actionType.value = type; |
||||
|
userIds = Tools.extractProperties(users, 'id'); |
||||
|
setPasswordDialogRef.value.show(); |
||||
|
}; |
||||
|
|
||||
|
const close = () => { |
||||
|
setPasswordDialogRef.value.hide(); |
||||
|
}; |
||||
|
|
||||
|
defineExpose({ |
||||
|
open, |
||||
|
close, |
||||
|
}); |
||||
|
</script> |
@ -0,0 +1,55 @@ |
|||||
|
package io.sc.platform.core.util; |
||||
|
|
||||
|
import net.sourceforge.pinyin4j.PinyinHelper; |
||||
|
|
||||
|
/** |
||||
|
* 汉语拼音辅助类 |
||||
|
* @author wangshaoping |
||||
|
* |
||||
|
*/ |
||||
|
public class PinyinUtil { |
||||
|
/** |
||||
|
* 采用汉语拼音比较两个字符串 |
||||
|
* @param o1 字符串1 |
||||
|
* @param o2 字符串2 |
||||
|
* @return 汉语拼音比较结果 |
||||
|
*/ |
||||
|
public static int compare(String o1, String o2) { |
||||
|
for (int i = 0; i < o1.length() && i < o2.length(); i++) { |
||||
|
int codePoint1 = o1.charAt(i); |
||||
|
int codePoint2 = o2.charAt(i); |
||||
|
|
||||
|
if (Character.isSupplementaryCodePoint(codePoint1) |
||||
|
|| Character.isSupplementaryCodePoint(codePoint2)) { |
||||
|
i++; |
||||
|
} |
||||
|
|
||||
|
if (codePoint1 != codePoint2) { |
||||
|
if (Character.isSupplementaryCodePoint(codePoint1) |
||||
|
|| Character.isSupplementaryCodePoint(codePoint2)) { |
||||
|
return codePoint1 - codePoint2; |
||||
|
} |
||||
|
|
||||
|
String pinyin1 = hanyuPinyin((char) codePoint1); |
||||
|
String pinyin2 = hanyuPinyin((char) codePoint2); |
||||
|
|
||||
|
if (pinyin1 != null && pinyin2 != null) { |
||||
|
if (!pinyin1.equals(pinyin2)) { |
||||
|
return pinyin1.compareTo(pinyin2); |
||||
|
} |
||||
|
} else { |
||||
|
return codePoint1 - codePoint2; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return o1.length() - o2.length(); |
||||
|
} |
||||
|
|
||||
|
private static String hanyuPinyin(char c) { |
||||
|
String[] pinyins = PinyinHelper.toHanyuPinyinStringArray(c); |
||||
|
if (pinyins == null) { |
||||
|
return null; |
||||
|
} |
||||
|
return pinyins[0]; |
||||
|
} |
||||
|
} |
@ -1,33 +0,0 @@ |
|||||
package io.sc.platform.lcdp.configure.converter; |
|
||||
|
|
||||
import io.sc.platform.lcdp.configure.jpa.entity.ConfigureEntity; |
|
||||
import io.sc.platform.lcdp.configure.api.Configure; |
|
||||
import io.sc.platform.orm.EntityVoConverter; |
|
||||
import org.slf4j.Logger; |
|
||||
import org.slf4j.LoggerFactory; |
|
||||
|
|
||||
public class ConfigureEntityVoConverter implements EntityVoConverter<ConfigureEntity, Configure> { |
|
||||
private static final Logger log = LoggerFactory.getLogger(ConfigureEntityVoConverter.class); |
|
||||
|
|
||||
@Override |
|
||||
public Configure toVo(ConfigureEntity entity) { |
|
||||
if(entity==null){ |
|
||||
return null; |
|
||||
} |
|
||||
Configure result =new Configure(); |
|
||||
result.setSetting(entity.getSetting()); |
|
||||
result.setTheme(entity.getTheme()); |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public ConfigureEntity fromVo(Configure vo) { |
|
||||
if(vo==null){ |
|
||||
return null; |
|
||||
} |
|
||||
ConfigureEntity entity =new ConfigureEntity(); |
|
||||
entity.setSetting(vo.getSetting()); |
|
||||
entity.setTheme(vo.getTheme()); |
|
||||
return entity; |
|
||||
} |
|
||||
} |
|
@ -1,72 +0,0 @@ |
|||||
package io.sc.platform.orm; |
|
||||
|
|
||||
import io.sc.platform.orm.repository.DaoRepository; |
|
||||
import io.sc.platform.orm.service.support.QueryResult; |
|
||||
import org.springframework.data.domain.Page; |
|
||||
import org.springframework.data.domain.PageImpl; |
|
||||
import org.springframework.data.domain.PageRequest; |
|
||||
import org.springframework.data.domain.Pageable; |
|
||||
|
|
||||
import java.util.ArrayList; |
|
||||
import java.util.Collections; |
|
||||
import java.util.List; |
|
||||
|
|
||||
public interface EntityVoConverter<E,V> { |
|
||||
public V toVo(E entity); |
|
||||
public E fromVo(V vo); |
|
||||
|
|
||||
/** |
|
||||
* 脱敏实体对象 |
|
||||
* @param entity 实体对象 |
|
||||
* @return Vo对象 |
|
||||
*/ |
|
||||
public default V desensitize(E entity){ |
|
||||
return toVo(entity); |
|
||||
} |
|
||||
|
|
||||
public default void detach(DaoRepository repository, E entity){ |
|
||||
if(entity!=null) { |
|
||||
repository.getEntityManager().detach(entity); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public default void detach(DaoRepository repository, List<E> entities){ |
|
||||
if(entities!=null && !entities.isEmpty()) { |
|
||||
for(E entity : entities) { |
|
||||
detach(repository,entity); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
public default List<V> toVo(List<E> entities){ |
|
||||
if(entities==null || entities.isEmpty()){ |
|
||||
return Collections.emptyList(); |
|
||||
} |
|
||||
List<V> result =new ArrayList<>(); |
|
||||
for(E entity : entities){ |
|
||||
result.add(toVo(entity)); |
|
||||
} |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
public default Page<V> toVo(Page<E> page){ |
|
||||
if(page==null){ |
|
||||
return QueryResult.emptyPage(); |
|
||||
} |
|
||||
|
|
||||
List<E> entities =page.getContent(); |
|
||||
List<V> vos =toVo(entities); |
|
||||
return new PageImpl<>(vos,page.getPageable(),page.getTotalElements()); |
|
||||
} |
|
||||
|
|
||||
public default List<E> fromVo(List<V> vos){ |
|
||||
if(vos==null || vos.isEmpty()){ |
|
||||
return Collections.emptyList(); |
|
||||
} |
|
||||
List<E> result =new ArrayList<>(); |
|
||||
for(V vo : vos){ |
|
||||
result.add(fromVo(vo)); |
|
||||
} |
|
||||
return result; |
|
||||
} |
|
||||
} |
|
@ -1,13 +0,0 @@ |
|||||
package io.sc.platform.orm.entity; |
|
||||
|
|
||||
public class EntityVoConverter implements io.sc.platform.orm.EntityVoConverter { |
|
||||
@Override |
|
||||
public Object toVo(Object entity) { |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public Object fromVo(Object vo) { |
|
||||
return null; |
|
||||
} |
|
||||
} |
|
@ -1,54 +0,0 @@ |
|||||
package io.sc.platform.orm.util; |
|
||||
|
|
||||
import io.sc.platform.orm.api.vo.BaseVo; |
|
||||
import io.sc.platform.orm.entity.BaseEntity; |
|
||||
import org.springframework.data.domain.Page; |
|
||||
import org.springframework.data.domain.PageImpl; |
|
||||
|
|
||||
import java.util.ArrayList; |
|
||||
import java.util.Collections; |
|
||||
import java.util.List; |
|
||||
|
|
||||
/** |
|
||||
* 实体和值对象转换器 |
|
||||
*/ |
|
||||
public class EntityVoConvertor { |
|
||||
/** |
|
||||
* 将实体分页对象转换成值分页对象 |
|
||||
* @param page 实体分页对象 |
|
||||
* @return 值分页对象 |
|
||||
* @param <E> 实体类型 |
|
||||
* @param <V> 值类型 |
|
||||
*/ |
|
||||
public static <E extends BaseEntity,V extends BaseVo> Page<V> toVo(Page<E> page){ |
|
||||
if(page!=null && !page.getContent().isEmpty()) { |
|
||||
List<E> entities =page.getContent(); |
|
||||
List<V> list =new ArrayList<>(entities.size()); |
|
||||
for(E entity : entities){ |
|
||||
list.add((V)entity.toVo()); |
|
||||
} |
|
||||
return new PageImpl<V>(list,page.getPageable(),page.getTotalElements()); |
|
||||
}else{ |
|
||||
return new PageImpl<V>(Collections.emptyList()); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/** |
|
||||
* 将实体列表转换成值列表 |
|
||||
* @param entities 实体列表 |
|
||||
* @return 值列表 |
|
||||
* @param <E> 实体类型 |
|
||||
* @param <V> 值类型 |
|
||||
*/ |
|
||||
public static <E extends BaseEntity,V extends BaseVo> List<V> toVo(List<E> entities){ |
|
||||
if(entities!=null && !entities.isEmpty()) { |
|
||||
List<V> list =new ArrayList<>(entities.size()); |
|
||||
for(E entity : entities){ |
|
||||
list.add((V)entity.toVo()); |
|
||||
} |
|
||||
return list; |
|
||||
}else{ |
|
||||
return Collections.emptyList(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
@ -0,0 +1,106 @@ |
|||||
|
package io.sc.platform.orm.util; |
||||
|
|
||||
|
import io.sc.platform.orm.api.vo.BaseVo; |
||||
|
import io.sc.platform.orm.entity.BaseEntity; |
||||
|
import io.sc.platform.orm.repository.DaoRepository; |
||||
|
import org.springframework.data.domain.Page; |
||||
|
import org.springframework.data.domain.PageImpl; |
||||
|
|
||||
|
import java.util.ArrayList; |
||||
|
import java.util.Collections; |
||||
|
import java.util.Comparator; |
||||
|
import java.util.List; |
||||
|
|
||||
|
/** |
||||
|
* 实体和值对象转换器 |
||||
|
*/ |
||||
|
public class EntityVoUtil { |
||||
|
/** |
||||
|
* 将实体脱离持久化(即将实体和持久化 Session 脱钩) |
||||
|
* @param repository 持久化 |
||||
|
* @param entity 实体 |
||||
|
* @param <E> 实体类型 |
||||
|
*/ |
||||
|
public static <E> void detach(DaoRepository repository, E entity){ |
||||
|
if(entity!=null) { |
||||
|
repository.getEntityManager().detach(entity); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将实体集合脱离持久化(即将实体和持久化 Session 脱钩) |
||||
|
* @param repository 持久化 |
||||
|
* @param entities 实体集合 |
||||
|
* @param <E> 实体类型 |
||||
|
*/ |
||||
|
public static <E> void detach(DaoRepository repository, List<E> entities){ |
||||
|
if(entities!=null && !entities.isEmpty()) { |
||||
|
for(E entity : entities) { |
||||
|
detach(repository,entity); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将实体分页对象转换成值分页对象 |
||||
|
* @param page 实体分页对象 |
||||
|
* @return 值分页对象 |
||||
|
* @param <E> 实体类型 |
||||
|
* @param <V> 值类型 |
||||
|
*/ |
||||
|
public static <E extends BaseEntity,V extends BaseVo> Page<V> toVo(Page<E> page){ |
||||
|
if(page!=null && !page.getContent().isEmpty()) { |
||||
|
List<E> entities =page.getContent(); |
||||
|
List<V> list =new ArrayList<>(entities.size()); |
||||
|
for(E entity : entities){ |
||||
|
list.add((V)entity.toVo()); |
||||
|
} |
||||
|
return new PageImpl<V>(list,page.getPageable(),page.getTotalElements()); |
||||
|
}else{ |
||||
|
return new PageImpl<V>(Collections.emptyList()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static <T> Page<T> sort(Page<T> page, Comparator<T> comparator){ |
||||
|
if(page!=null){ |
||||
|
List<T> content =page.getContent(); |
||||
|
if(content!=null && !content.isEmpty()){ |
||||
|
List<T> result =new ArrayList<>(content.size()); |
||||
|
for(T e : content){ |
||||
|
result.add(e); |
||||
|
} |
||||
|
result.sort(comparator); |
||||
|
return new PageImpl<T>(result,page.getPageable(),page.getTotalElements()); |
||||
|
} |
||||
|
} |
||||
|
return page; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将实体列表转换成值列表 |
||||
|
* @param entities 实体列表 |
||||
|
* @return 值列表 |
||||
|
* @param <E> 实体类型 |
||||
|
* @param <V> 值类型 |
||||
|
*/ |
||||
|
public static <E extends BaseEntity,V extends BaseVo> List<V> toVo(List<E> entities){ |
||||
|
if(entities!=null && !entities.isEmpty()) { |
||||
|
List<V> list =new ArrayList<>(entities.size()); |
||||
|
for(E entity : entities){ |
||||
|
list.add((V)entity.toVo()); |
||||
|
} |
||||
|
return list; |
||||
|
}else{ |
||||
|
return Collections.emptyList(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 脱敏实体对象 |
||||
|
* @param entity 实体对象 |
||||
|
* @return Vo对象 |
||||
|
*/ |
||||
|
public static <E extends BaseEntity,V extends BaseVo> V desensitize(E entity){ |
||||
|
return (V)entity.desensitize(); |
||||
|
} |
||||
|
} |
@ -0,0 +1,59 @@ |
|||||
|
package io.sc.platform.system.api.menu; |
||||
|
|
||||
|
import io.sc.platform.system.enums.MenuType; |
||||
|
|
||||
|
import java.util.HashMap; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
public class MenuRouteActionVo extends MenuRouteVo { |
||||
|
private String id; |
||||
|
private String name; |
||||
|
private String i18nKey; |
||||
|
private String parent; |
||||
|
|
||||
|
public MenuRouteActionVo(){} |
||||
|
public MenuRouteActionVo(String id,String name,String i18nKey,String parent){ |
||||
|
this.id =id; |
||||
|
this.name =name; |
||||
|
this.i18nKey =i18nKey; |
||||
|
this.parent =parent; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String getId() { |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void setId(String id) { |
||||
|
this.id = id; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String getName() { |
||||
|
return name; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void setName(String name) { |
||||
|
this.name = name; |
||||
|
} |
||||
|
|
||||
|
public String getI18nKey() { |
||||
|
return i18nKey; |
||||
|
} |
||||
|
|
||||
|
public void setI18nKey(String i18nKey) { |
||||
|
this.i18nKey = i18nKey; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String getParent() { |
||||
|
return parent; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void setParent(String parent) { |
||||
|
this.parent = parent; |
||||
|
} |
||||
|
} |
@ -0,0 +1,4 @@ |
|||||
|
package io.sc.platform.system.api.menu; |
||||
|
|
||||
|
public class MenuSeparatorVo extends MenuVo { |
||||
|
} |
@ -1,4 +0,0 @@ |
|||||
package io.sc.platform.system.api.menu; |
|
||||
|
|
||||
public class MenuSeperatorVo extends MenuVo { |
|
||||
} |
|
@ -0,0 +1,71 @@ |
|||||
|
package io.sc.platform.system.api.notification; |
||||
|
|
||||
|
import io.sc.platform.orm.api.vo.CorporationAuditorVo; |
||||
|
|
||||
|
import java.util.Date; |
||||
|
|
||||
|
public class NotificationVo extends CorporationAuditorVo { |
||||
|
private String id; |
||||
|
private String title; |
||||
|
private String content; |
||||
|
private String sender; |
||||
|
protected Date sendDate; |
||||
|
private String receiver; |
||||
|
private Date receiveDate; |
||||
|
|
||||
|
public String getId() { |
||||
|
return id; |
||||
|
} |
||||
|
|
||||
|
public void setId(String id) { |
||||
|
this.id = id; |
||||
|
} |
||||
|
|
||||
|
public String getTitle() { |
||||
|
return title; |
||||
|
} |
||||
|
|
||||
|
public void setTitle(String title) { |
||||
|
this.title = title; |
||||
|
} |
||||
|
|
||||
|
public String getContent() { |
||||
|
return content; |
||||
|
} |
||||
|
|
||||
|
public void setContent(String content) { |
||||
|
this.content = content; |
||||
|
} |
||||
|
|
||||
|
public String getSender() { |
||||
|
return sender; |
||||
|
} |
||||
|
|
||||
|
public void setSender(String sender) { |
||||
|
this.sender = sender; |
||||
|
} |
||||
|
|
||||
|
public Date getSendDate() { |
||||
|
return sendDate; |
||||
|
} |
||||
|
|
||||
|
public void setSendDate(Date sendDate) { |
||||
|
this.sendDate = sendDate; |
||||
|
} |
||||
|
|
||||
|
public String getReceiver() { |
||||
|
return receiver; |
||||
|
} |
||||
|
|
||||
|
public void setReceiver(String receiver) { |
||||
|
this.receiver = receiver; |
||||
|
} |
||||
|
|
||||
|
public Date getReceiveDate() { |
||||
|
return receiveDate; |
||||
|
} |
||||
|
|
||||
|
public void setReceiveDate(Date receiveDate) { |
||||
|
this.receiveDate = receiveDate; |
||||
|
} |
||||
|
} |
@ -0,0 +1,5 @@ |
|||||
|
{ |
||||
|
"includes":[ |
||||
|
"io/sc/platform/system/api/i18n/enums" |
||||
|
] |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
io.sc.platform.system.enums.MenuType.GROUP=Group |
||||
|
io.sc.platform.system.enums.MenuType.ROUTE=Route |
||||
|
io.sc.platform.system.enums.MenuType.SEPARATOR=Seperator |
||||
|
io.sc.platform.system.enums.MenuType.URL=URL |
||||
|
io.sc.platform.system.enums.MenuType.JAVASCRIPT=JavaScript |
||||
|
|
||||
|
io.sc.platform.system.enums.UrlOpenType.SELF=Selft |
||||
|
io.sc.platform.system.enums.UrlOpenType.NEW_WINDOW=New Window |
||||
|
io.sc.platform.system.enums.UrlOpenType.EMBEDDED=Embedded |
@ -0,0 +1,9 @@ |
|||||
|
io.sc.platform.system.enums.MenuType.GROUP=\u83DC\u55AE\u7EC4 |
||||
|
io.sc.platform.system.enums.MenuType.ROUTE=\u8DEF\u7531 |
||||
|
io.sc.platform.system.enums.MenuType.SEPARATOR=\u5206\u9694\u7B26 |
||||
|
io.sc.platform.system.enums.MenuType.URL=URL |
||||
|
io.sc.platform.system.enums.MenuType.JAVASCRIPT=JavaScript |
||||
|
|
||||
|
io.sc.platform.system.enums.UrlOpenType.SELF=\u7576\u524D\u7A97\u53E3 |
||||
|
io.sc.platform.system.enums.UrlOpenType.NEW_WINDOW=\u65B0\u7A97\u53E3 |
||||
|
io.sc.platform.system.enums.UrlOpenType.EMBEDDED=\u5D4C\u5165\u5F0F |
@ -0,0 +1,9 @@ |
|||||
|
io.sc.platform.system.enums.MenuType.GROUP=\u83DC\u5355\u7EC4 |
||||
|
io.sc.platform.system.enums.MenuType.ROUTE=\u8DEF\u7531 |
||||
|
io.sc.platform.system.enums.MenuType.SEPARATOR=\u5206\u9694\u7B26 |
||||
|
io.sc.platform.system.enums.MenuType.URL=URL |
||||
|
io.sc.platform.system.enums.MenuType.JAVASCRIPT=JavaScript |
||||
|
|
||||
|
io.sc.platform.system.enums.UrlOpenType.SELF=\u5F53\u524D\u7A97\u53E3 |
||||
|
io.sc.platform.system.enums.UrlOpenType.NEW_WINDOW=\u65B0\u7A97\u53E3 |
||||
|
io.sc.platform.system.enums.UrlOpenType.EMBEDDED=\u5D4C\u5165\u5F0F |
@ -1,4 +0,0 @@ |
|||||
<template> |
|
||||
<div>AnnouncementManager</div> |
|
||||
</template> |
|
||||
<script setup lang="ts"></script> |
|
@ -1,4 +0,0 @@ |
|||||
<template> |
|
||||
<div>I18n</div> |
|
||||
</template> |
|
||||
<script setup lang="ts"></script> |
|
@ -1,4 +0,0 @@ |
|||||
<template> |
|
||||
<div>Log</div> |
|
||||
</template> |
|
||||
<script setup lang="ts"></script> |
|
@ -1,4 +0,0 @@ |
|||||
<template> |
|
||||
<div>Menu</div> |
|
||||
</template> |
|
||||
<script setup lang="ts"></script> |
|
@ -1,4 +0,0 @@ |
|||||
<template> |
|
||||
<div>NotificationManager</div> |
|
||||
</template> |
|
||||
<script setup lang="ts"></script> |
|
@ -1,4 +0,0 @@ |
|||||
<template> |
|
||||
<div>User</div> |
|
||||
</template> |
|
||||
<script setup lang="ts"></script> |
|
@ -1,4 +0,0 @@ |
|||||
<template> |
|
||||
<div>Role</div> |
|
||||
</template> |
|
||||
<script setup lang="ts"></script> |
|
@ -0,0 +1,59 @@ |
|||||
|
<template> |
||||
|
<w-grid |
||||
|
ref="announcementGridRef" |
||||
|
:title="$t('system.announcementManager.grid.title')" |
||||
|
selection="multiple" |
||||
|
:data-url="Environment.apiContextPath('/api/system/announcement')" |
||||
|
:pagination="{ |
||||
|
sortBy: 'lastModifyDate', |
||||
|
descending: true, |
||||
|
}" |
||||
|
:query-form-fields="[ |
||||
|
{ name: 'title', label: $t('title'), type: 'text' }, |
||||
|
{ name: 'dataComeFrom', label: $t('dataComeFrom'), type: 'select', options: Options.enum(DataComeFromEnum), queryOperator: 'equals' }, |
||||
|
]" |
||||
|
:toolbar-configure="{ noIcon: false }" |
||||
|
:toolbar-actions="['query', 'refresh', 'separator', 'add', 'clone', 'edit', 'remove', 'separator', 'view', 'export']" |
||||
|
:columns="[ |
||||
|
{ width: 300, name: 'title', label: $t('title') }, |
||||
|
{ width: '100%', name: 'content', label: $t('content') }, |
||||
|
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) }, |
||||
|
{ name: 'lastModifier', label: $t('lastModifier') }, |
||||
|
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() }, |
||||
|
]" |
||||
|
:editor="{ |
||||
|
dialog: { |
||||
|
width: '600px', |
||||
|
height: '380px', |
||||
|
}, |
||||
|
form: { |
||||
|
colsNum: 1, |
||||
|
fields: [ |
||||
|
{ name: 'title', label: $t('title'), type: 'text', required: true }, |
||||
|
{ name: 'content', label: $t('content'), type: 'q-editor', required: true, minHeight: '10rem' }, |
||||
|
], |
||||
|
}, |
||||
|
}" |
||||
|
:viewer="{ |
||||
|
panel: { |
||||
|
columnNum: 1, |
||||
|
fields: [ |
||||
|
{ name: 'id', label: $t('id') }, |
||||
|
{ name: 'title', label: $t('title') }, |
||||
|
{ name: 'content', label: $t('content') }, |
||||
|
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) }, |
||||
|
{ name: 'creator', label: $t('creator') }, |
||||
|
{ name: 'createDate', label: $t('createDate') }, |
||||
|
{ name: 'lastModifier', label: $t('lastModifier') }, |
||||
|
{ name: 'lastModifyDate', label: $t('lastModifyDate') }, |
||||
|
{ name: 'corporationCode', label: $t('corporationCode') }, |
||||
|
], |
||||
|
}, |
||||
|
}" |
||||
|
></w-grid> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { Environment, EnumTools, Options, Formater } from 'platform-core'; |
||||
|
|
||||
|
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom'); |
||||
|
</script> |
@ -0,0 +1,76 @@ |
|||||
|
<template> |
||||
|
<q-editor v-model="editor" min-height="5rem" v-bind="attrs" /> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts"> |
||||
|
import { ref, computed, defineProps, useAttrs } from 'vue'; |
||||
|
import { FormValidators } from 'platform-core'; |
||||
|
|
||||
|
const editor = ref(); |
||||
|
const textareaRef = ref(); |
||||
|
const attrs = useAttrs(); |
||||
|
const inRules = attrs.rules; |
||||
|
const props = defineProps({ |
||||
|
hideIf: { |
||||
|
type: Function, |
||||
|
default: () => { |
||||
|
return false; |
||||
|
}, |
||||
|
}, |
||||
|
required: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
requiredIf: { |
||||
|
type: Function, |
||||
|
default: undefined, |
||||
|
}, |
||||
|
readonlyIf: { |
||||
|
type: Function, |
||||
|
default: () => { |
||||
|
return false; |
||||
|
}, |
||||
|
}, |
||||
|
disableIf: { |
||||
|
type: Function, |
||||
|
default: () => { |
||||
|
return false; |
||||
|
}, |
||||
|
}, |
||||
|
form: { |
||||
|
type: Object, |
||||
|
default: undefined, |
||||
|
}, |
||||
|
}); |
||||
|
|
||||
|
const rulesComputed = computed(() => { |
||||
|
let rules = inRules || <any>[]; |
||||
|
if (!hideIfComputed.value && requiredIfComputed.value) { |
||||
|
rules.push(FormValidators.required()); |
||||
|
} else if (hideIfComputed.value) { |
||||
|
rules = []; |
||||
|
} |
||||
|
if (textareaRef?.value) { |
||||
|
textareaRef.value.resetValidation(); |
||||
|
} |
||||
|
return rules; |
||||
|
}); |
||||
|
|
||||
|
const hideIfComputed = computed(() => { |
||||
|
return props.hideIf(props.form); |
||||
|
}); |
||||
|
const requiredIfComputed = computed(() => { |
||||
|
if (props.requiredIf) { |
||||
|
return props.requiredIf(props.form) || false; |
||||
|
} else if (props.required) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
}); |
||||
|
const readonlyIfComputed = computed(() => { |
||||
|
return props.readonlyIf(props.form); |
||||
|
}); |
||||
|
const disableIfComputed = computed(() => { |
||||
|
return props.disableIf(props.form); |
||||
|
}); |
||||
|
</script> |
@ -1,54 +1,144 @@ |
|||||
<template> |
<template> |
||||
<div> |
<q-splitter :model-value="65" class="w-full h-full"> |
||||
<w-tree-grid ref="corporationTreeGridRef" title="法人树" label-key="name" :actions="corporationConfigure.actions" /> |
<template #before> |
||||
</div> |
<div class="pr-1"> |
||||
|
<w-grid |
||||
|
ref="corporationTreeGridRef" |
||||
|
:tree="true" |
||||
|
dense-body |
||||
|
:title="$t('system.corporation.grid.title')" |
||||
|
:data-url="Environment.apiContextPath('/api/system/corporation')" |
||||
|
selection="multiple" |
||||
|
:checkbox-selection="false" |
||||
|
:pageable="false" |
||||
|
:full-screen-button="false" |
||||
|
:tree-icon=" |
||||
|
(row) => { |
||||
|
return { name: 'folder', color: 'amber' }; |
||||
|
} |
||||
|
" |
||||
|
:toolbar-configure="{ noIcon: false }" |
||||
|
:toolbar-actions="['refresh', 'separator', ['addTop', 'addChild'], 'edit', 'remove', 'separator', 'view']" |
||||
|
:columns="[ |
||||
|
{ width: 250, name: 'name', label: $t('name') }, |
||||
|
{ name: 'code', label: $t('code') }, |
||||
|
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) }, |
||||
|
{ name: 'lastModifier', label: $t('lastModifier') }, |
||||
|
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() }, |
||||
|
{ width: 100, name: 'enable', label: $t('status'), format: Formater.enableTag() }, |
||||
|
]" |
||||
|
:editor="{ |
||||
|
dialog: { |
||||
|
width: '600px', |
||||
|
height: '300px', |
||||
|
}, |
||||
|
form: { |
||||
|
colsNum: 1, |
||||
|
fields: [ |
||||
|
{ name: 'code', label: $t('code'), type: 'text', required: true }, |
||||
|
{ name: 'name', label: $t('name'), type: 'text', required: true }, |
||||
|
{ name: 'description', label: $t('description'), type: 'textarea', rows: 1 }, |
||||
|
{ name: 'enable', label: $t('enable'), type: 'checkbox', defaultValue: true }, |
||||
|
], |
||||
|
}, |
||||
|
}" |
||||
|
:viewer="{ |
||||
|
panel: { |
||||
|
columnNum: 1, |
||||
|
fields: [ |
||||
|
{ name: 'id', label: $t('id') }, |
||||
|
{ name: 'code', label: $t('code') }, |
||||
|
{ name: 'name', label: $t('name') }, |
||||
|
{ name: 'description', label: $t('description') }, |
||||
|
{ name: 'enable', label: $t('enable'), format: (value) => value }, |
||||
|
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: (value) => value }, |
||||
|
{ name: 'creator', label: $t('creator') }, |
||||
|
{ name: 'createDate', label: $t('createDate') }, |
||||
|
{ name: 'lastModifier', label: $t('lastModifier') }, |
||||
|
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: (value) => value }, |
||||
|
], |
||||
|
}, |
||||
|
}" |
||||
|
@row-click=" |
||||
|
(evt, row, index) => { |
||||
|
currentSelectedCorporationCode = row.code; |
||||
|
userGridRef?.refresh(); |
||||
|
} |
||||
|
" |
||||
|
></w-grid> |
||||
|
</div> |
||||
|
</template> |
||||
|
<template #after> |
||||
|
<div class="pl-1"> |
||||
|
<SelectUserGrid |
||||
|
ref="userGridRef" |
||||
|
:fetch-data-url="Environment.apiContextPath('/api/system/user/queryUsersByCorporation')" |
||||
|
:fetch-other-data-url="Environment.apiContextPath('/api/system/user/queryOtherUsersByCorporation')" |
||||
|
foreign-key="corporationCode" |
||||
|
:foreign-value="currentSelectedCorporationCode" |
||||
|
@add="add" |
||||
|
@remove="remove" |
||||
|
@add-all="addAll" |
||||
|
@remove-all="removeAll" |
||||
|
> |
||||
|
</SelectUserGrid> |
||||
|
</div> |
||||
|
</template> |
||||
|
</q-splitter> |
||||
</template> |
</template> |
||||
<script setup lang="ts"> |
<script setup lang="ts"> |
||||
import { ref, onMounted, toRaw } from 'vue'; |
import { ref } from 'vue'; |
||||
import { useRoute } from 'vue-router'; |
import { axios, Environment, Formater, EnumTools } from 'platform-core'; |
||||
import { useI18n } from 'vue-i18n'; |
import SelectUserGrid from '../shared/SelectUserGrid.vue'; |
||||
import { Environment, axios } from 'platform-core'; |
|
||||
|
|
||||
const route = useRoute(); |
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom'); |
||||
console.log(toRaw(route)); |
|
||||
const { t } = useI18n(); |
|
||||
|
|
||||
const corporationTreeGridRef = ref(); |
const corporationTreeGridRef = ref(); |
||||
|
const userGridRef = ref(); |
||||
|
const currentSelectedCorporationCode = ref(''); |
||||
|
|
||||
const corporationConfigure = { |
const add = (ids: string[], gridComponent, dialogComponent) => { |
||||
actions: [ |
axios |
||||
{ |
.post(Environment.apiContextPath('/api/system/corporation/addUsers'), { |
||||
name: 'refresh', |
one: corporationTreeGridRef.value.getSelectedRows()[0].code, |
||||
label: t('refresh'), |
many: ids, |
||||
click: () => {}, |
}) |
||||
}, |
.then(() => { |
||||
|
gridComponent?.refresh(); |
||||
|
dialogComponent?.close(); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const remove = (ids, gridComponent) => { |
||||
|
axios |
||||
|
.post(Environment.apiContextPath('/api/system/corporation/removeUsers'), { |
||||
|
one: corporationTreeGridRef.value.getSelectedRows()[0].code, |
||||
|
many: ids, |
||||
|
}) |
||||
|
.then(() => { |
||||
|
gridComponent?.refresh(); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
{ |
const addAll = (gridComponent) => { |
||||
name: 'addRoot', |
axios |
||||
label: t('system.corporation.action.addTop'), |
.post(Environment.apiContextPath('/api/system/corporation/addAllUsers'), { |
||||
click: () => {}, |
one: corporationTreeGridRef.value.getSelectedRows()[0].code, |
||||
}, |
many: [], |
||||
{ |
}) |
||||
name: 'addChild', |
.then(() => { |
||||
label: t('system.corporation.action.addChild'), |
gridComponent?.refresh(); |
||||
click: () => {}, |
}); |
||||
}, |
|
||||
{ |
|
||||
name: 'edit', |
|
||||
label: t('edit'), |
|
||||
click: () => {}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'delete', |
|
||||
label: t('delete'), |
|
||||
click: () => {}, |
|
||||
}, |
|
||||
], |
|
||||
}; |
}; |
||||
|
|
||||
onMounted(() => { |
const removeAll = (gridComponent) => { |
||||
axios.get(Environment.apiContextPath('/api/system/corporation?pageable=false&sortBy=name')).then((response) => { |
axios |
||||
corporationTreeGridRef.value.setNodes(response.data.content); |
.post(Environment.apiContextPath('/api/system/corporation/removeAllUsers'), { |
||||
}); |
one: corporationTreeGridRef.value.getSelectedRows()[0].code, |
||||
}); |
many: [], |
||||
|
}) |
||||
|
.then(() => { |
||||
|
gridComponent?.refresh(); |
||||
|
}); |
||||
|
}; |
||||
</script> |
</script> |
||||
|
@ -1,332 +1,255 @@ |
|||||
<template> |
<template> |
||||
<q-splitter :model-value="70" class="w-full h-full"> |
<q-splitter :model-value="60" class="w-full h-full"> |
||||
<template #before> |
<template #before> |
||||
<w-tree-grid |
<div class="pr-1"> |
||||
ref="menuTreeGridRef" |
<w-grid |
||||
title="菜单树" |
ref="menuTreeGridRef" |
||||
label-key="titleI18nKey" |
:tree="true" |
||||
label-i18n |
dense-body |
||||
label-empty="--------------------" |
:title="$t('system.menu.grid.title')" |
||||
:actions="menuConfigure.actions" |
:data-url="Environment.apiContextPath('/api/system/menu')" |
||||
tick-strategy="none" |
selection="multiple" |
||||
@update:selected="menuSelected" |
:checkbox-selection="false" |
||||
/> |
:pageable="false" |
||||
|
:full-screen-button="false" |
||||
|
:tree-icon=" |
||||
|
(row) => { |
||||
|
if (row.type === 'SEPARATOR') { |
||||
|
return { name: 'bi-dash-lg' }; |
||||
|
} else if (row.type === 'ROUTE_ACTION') { |
||||
|
return { name: 'sym_o_crop_16_9' }; |
||||
|
} else { |
||||
|
return { name: row.icon }; |
||||
|
} |
||||
|
} |
||||
|
" |
||||
|
:toolbar-configure="{ noIcon: false }" |
||||
|
:toolbar-actions="[ |
||||
|
'refresh', |
||||
|
'separator', |
||||
|
['addTop', 'addChild'], |
||||
|
'edit', |
||||
|
'remove', |
||||
|
'separator', |
||||
|
{ |
||||
|
name: 'import', |
||||
|
label: $t('import'), |
||||
|
click: () => {}, |
||||
|
}, |
||||
|
'separator', |
||||
|
'view', |
||||
|
'export', |
||||
|
]" |
||||
|
:columns="[ |
||||
|
{ |
||||
|
width: '100%', |
||||
|
name: 'titleI18nKey', |
||||
|
label: $t('name'), |
||||
|
sortable: false, |
||||
|
format: (value, row) => { |
||||
|
if (row.type === 'SEPARATOR') { |
||||
|
return `<hr style='width:100px'/>`; |
||||
|
} else if (row.type === 'ROUTE_ACTION') { |
||||
|
return $t(row.i18nKey); |
||||
|
} else { |
||||
|
return $t(value); |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
{ name: 'type', label: $t('type'), sortable: false, format: Formater.menuType() }, |
||||
|
{ name: 'order', label: $t('order'), align: 'right', sortable: false }, |
||||
|
{ name: 'dataComeFrom', label: $t('dataComeFrom'), sortable: false, format: Formater.enum(DataComeFromEnum) }, |
||||
|
{ name: 'lastModifier', label: $t('lastModifier'), sortable: false }, |
||||
|
{ name: 'lastModifyDate', label: $t('lastModifyDate'), sortable: false, format: Formater.dateOnly() }, |
||||
|
{ width: 100, name: 'enable', label: $t('status'), sortable: false, format: Formater.enableTag() }, |
||||
|
]" |
||||
|
:editor="{ |
||||
|
dialog: { |
||||
|
width: '600px', |
||||
|
height: '550px', |
||||
|
}, |
||||
|
form: { |
||||
|
colsNum: 1, |
||||
|
fields: [ |
||||
|
{ name: 'type', label: $t('type'), type: 'select', required: true, options: Options.enum(MenuTypeEnum, false) }, |
||||
|
{ name: 'titleI18nKey', label: $t('titleI18nKey'), type: 'text', required: true }, |
||||
|
{ name: 'icon', label: $t('icon'), type: 'text' }, |
||||
|
{ name: 'enable', label: $t('enable'), type: 'checkbox', defaultValue: true }, |
||||
|
{ name: 'order', label: $t('order'), type: 'text' }, |
||||
|
{ |
||||
|
name: 'javaScript', |
||||
|
label: $t('javascript'), |
||||
|
type: 'text', |
||||
|
enableIf: (row) => { |
||||
|
console.log(row); |
||||
|
}, |
||||
|
}, |
||||
|
{ name: 'routeName', label: $t('routeName'), type: 'text' }, |
||||
|
{ name: 'routeQuery', label: $t('routeQuery'), type: 'text' }, |
||||
|
{ name: 'url', label: $t('url'), type: 'text' }, |
||||
|
{ |
||||
|
name: 'urlOpenType', |
||||
|
label: $t('urlOpenType'), |
||||
|
type: 'select', |
||||
|
options: Options.enum(UrlOpenTypeEnum, false), |
||||
|
defaultValue: 'NEW_WINDOW', |
||||
|
}, |
||||
|
], |
||||
|
}, |
||||
|
}" |
||||
|
:viewer="{ |
||||
|
panel: { |
||||
|
columnNum: 1, |
||||
|
fields: [ |
||||
|
{ name: 'id', label: $t('id') }, |
||||
|
{ name: 'type', label: $t('type') }, |
||||
|
{ name: 'name', label: $t('name') }, |
||||
|
{ name: 'titleI18nKey', label: $t('titleI18nKey') }, |
||||
|
{ name: 'icon', label: $t('icon') }, |
||||
|
{ name: 'enable', label: $t('enable') }, |
||||
|
{ name: 'order', label: $t('order') }, |
||||
|
{ name: 'javaScript', label: $t('javaScript') }, |
||||
|
{ name: 'url', label: $t('url') }, |
||||
|
{ name: 'urlOpenType', label: $t('urlOpenType') }, |
||||
|
{ name: 'routeName', label: $t('routeName') }, |
||||
|
{ name: 'routeQuery', label: $t('routeQuery') }, |
||||
|
|
||||
|
{ name: 'dataComeFrom', label: $t('dataComeFrom') }, |
||||
|
{ name: 'creator', label: $t('creator') }, |
||||
|
{ name: 'createDate', label: $t('createDate') }, |
||||
|
{ name: 'lastModifier', label: $t('lastModifier') }, |
||||
|
{ name: 'lastModifyDate', label: $t('lastModifyDate') }, |
||||
|
{ name: 'corporationCode', label: $t('corporationCode') }, |
||||
|
], |
||||
|
}, |
||||
|
}" |
||||
|
@row-click=" |
||||
|
(evt, row, index) => { |
||||
|
currentSelectedMenuId = row.id; |
||||
|
roleGridRef?.refresh(); |
||||
|
orgTreeGridRef?.refresh(); |
||||
|
} |
||||
|
" |
||||
|
></w-grid> |
||||
|
</div> |
||||
</template> |
</template> |
||||
<template #after> |
<template #after> |
||||
<q-tabs v-model="selectedTabRef" inline-label align="left" :breakpoint="0"> |
<div class="pl-1"> |
||||
<q-tab name="role" icon="bi-diagram-3" :label="$t('role')" /> |
<q-tabs v-model="selectedTabRef" inline-label align="left" :breakpoint="0"> |
||||
<q-tab name="org" icon="bi-people" :label="$t('org')" /> |
<q-tab name="role" icon="bi-diagram-3" :label="$t('role')" /> |
||||
</q-tabs> |
<q-tab name="org" icon="bi-people" :label="$t('org')" /> |
||||
|
</q-tabs> |
||||
|
|
||||
<q-tab-panels v-model="selectedTabRef" animated swipeable keep-alive> |
<q-tab-panels v-model="selectedTabRef" animated swipeable keep-alive> |
||||
<q-tab-panel name="user"> |
<q-tab-panel name="role" class="px-0"> |
||||
<platform-grid |
<SelectRoleGrid |
||||
ref="roleGridRef" |
ref="roleGridRef" |
||||
:table-props="{ borderded: false, flat: true }" |
:fetch-data-url="Environment.apiContextPath('/api/system/role/queryRolesByMenu')" |
||||
:query-form-cols-number="roleConfigure.queryFormColsNumber" |
:fetch-other-data-url="Environment.apiContextPath('/api/system/role/queryOtherRolesByMenu')" |
||||
:hide-bottom="roleConfigure.hideBottom" |
foreign-key="menuId" |
||||
:query-form-cols-auto="roleConfigure.queryFormColsAuto" |
:foreign-value="currentSelectedMenuId" |
||||
:table-title="roleConfigure.tableTitle" |
@add="add" |
||||
:table-row-key="roleConfigure.tableRowKey" |
@remove="remove" |
||||
:table-init-load-data="roleConfigure.tableInitLoadData" |
@add-all="addAll" |
||||
:table-data-url="roleConfigure.tableDataUrl" |
@remove-all="removeAll" |
||||
:table-show-sort-no="false" |
></SelectRoleGrid> |
||||
:table-columns="roleConfigure.tableColumns" |
</q-tab-panel> |
||||
:table-left-column-sticky-number="roleConfigure.tableLeftColumnStickyNumber" |
|
||||
:table-buttons="roleConfigure.tableButtons" |
|
||||
:query-form-fields="roleConfigure.queryFormFields" |
|
||||
:table-pagination="roleConfigure.tablePagination" |
|
||||
table-selection="multiple" |
|
||||
:table-dense="false" |
|
||||
> |
|
||||
</platform-grid> |
|
||||
</q-tab-panel> |
|
||||
|
|
||||
<q-tab-panel name="org"> |
<q-tab-panel name="org" class="px-0"> |
||||
<w-tree-grid |
<SelectOrgTreeGrid |
||||
ref="orgTreeGridRef" |
ref="orgTreeGridRef" |
||||
title="机构树" |
:fetch-data-url="Environment.apiContextPath('/api/system/org/listAllOrgsWithSelectedStatusByMenu')" |
||||
label-key="titleI18nKey" |
foreign-key="menuId" |
||||
label-i18n |
:foreign-value="currentSelectedMenuId" |
||||
label-empty="--------------------" |
@update="update" |
||||
:actions="orgConfigure.actions" |
></SelectOrgTreeGrid> |
||||
/> |
</q-tab-panel> |
||||
</q-tab-panel> |
</q-tab-panels> |
||||
</q-tab-panels> |
</div> |
||||
</template> |
</template> |
||||
<SelectRoleDialog ref="selectRoleDialog" title="可选角色列表" :maximized="false" width="50%" height="500px"></SelectRoleDialog> |
|
||||
<AddTopMenuDialog ref="addTopMenuDialog" title="菜单" :maximized="false" width="50%" height="340px"></AddTopMenuDialog> |
<AddTopMenuDialog ref="addTopMenuDialog" title="菜单" :maximized="false" width="50%" height="340px"></AddTopMenuDialog> |
||||
<AddMenuDialog ref="addMenuDialog" title="菜单" :maximized="false" width="50%" height="440px"></AddMenuDialog> |
<AddMenuDialog ref="addMenuDialog" title="菜单" :maximized="false" width="50%" height="440px"></AddMenuDialog> |
||||
<EditMenuDialog ref="editMenuDialog" title="菜单" :maximized="false" width="50%" height="440px"></EditMenuDialog> |
<EditMenuDialog ref="editMenuDialog" title="菜单" :maximized="false" width="50%" height="440px"></EditMenuDialog> |
||||
</q-splitter> |
</q-splitter> |
||||
</template> |
</template> |
||||
<script setup lang="ts"> |
<script setup lang="ts"> |
||||
import { ref, onMounted } from 'vue'; |
import { ref } from 'vue'; |
||||
import { useI18n } from 'vue-i18n'; |
import { Environment, axios, EnumTools, Formater, Options } from 'platform-core'; |
||||
import { useQuasar } from 'quasar'; |
import SelectRoleGrid from '../shared/SelectRoleGrid.vue'; |
||||
import { Environment, axios } from 'platform-core'; |
import SelectOrgTreeGrid from '../shared/SelectOrgTreeGrid.vue'; |
||||
import SelectRoleDialog from './SelectRoleDialog.vue'; |
|
||||
import AddTopMenuDialog from './AddTopMenuDialog.vue'; |
import AddTopMenuDialog from './AddTopMenuDialog.vue'; |
||||
import AddMenuDialog from './AddMenuDialog.vue'; |
import AddMenuDialog from './AddMenuDialog.vue'; |
||||
import EditMenuDialog from './EditMenuDialog.vue'; |
import EditMenuDialog from './EditMenuDialog.vue'; |
||||
|
|
||||
const { t } = useI18n(); |
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom'); |
||||
const quasar = useQuasar(); |
const MenuTypeEnum = await EnumTools.fetch('io.sc.platform.system.enums.MenuType'); |
||||
|
const UrlOpenTypeEnum = await EnumTools.fetch('io.sc.platform.system.enums.UrlOpenType'); |
||||
|
console.log(Options.enum(UrlOpenTypeEnum, false)); |
||||
|
|
||||
const menuTreeGridRef = ref(); |
const menuTreeGridRef = ref(); |
||||
const roleGridRef = ref(); |
const roleGridRef = ref(); |
||||
const orgTreeGridRef = ref(); |
const orgTreeGridRef = ref(); |
||||
|
|
||||
const selectRoleDialog = ref(); |
const selectedTabRef = ref('role'); |
||||
|
const currentSelectedMenuId = ref(''); |
||||
|
|
||||
const addTopMenuDialog = ref(); |
const addTopMenuDialog = ref(); |
||||
const addMenuDialog = ref(); |
const addMenuDialog = ref(); |
||||
const editMenuDialog = ref(); |
const editMenuDialog = ref(); |
||||
const selectedTabRef = ref('user'); |
|
||||
let selectedMenuId = ''; |
|
||||
|
|
||||
const roleConfigure = { |
const add = (ids: string[], gridComponent, dialogComponent) => { |
||||
queryFormColsNumber: 4, |
axios |
||||
queryFormColsAuto: false, |
.post(Environment.apiContextPath('/api/system/menu/addRoles'), { |
||||
queryFormFields: [], |
one: menuTreeGridRef.value.getSelectedRows()[0].id, |
||||
hideBottom: true, |
many: ids, |
||||
tableInitLoadData: false, |
}) |
||||
tableLeftColumnStickyNumber: 0, |
.then(() => { |
||||
tableTitle: t('system.role.gridTitle'), |
gridComponent?.refresh(); |
||||
tableRowKey: 'id', |
dialogComponent?.close(); |
||||
tableDataUrl: '', |
}); |
||||
tablePagination: { |
|
||||
sortBy: 'lastModifyDate', |
|
||||
descending: true, |
|
||||
reqPageStart: 0, |
|
||||
rowsPerPage: 0, |
|
||||
}, |
|
||||
tableButtons: [ |
|
||||
'refresh', |
|
||||
'inFullscreen', |
|
||||
{ |
|
||||
name: 'addRole', |
|
||||
label: t('system.role.action.addRole'), |
|
||||
icon: '', |
|
||||
enable: () => {}, |
|
||||
click: () => { |
|
||||
selectRoleDialog.value.show({ roleGridRef: roleGridRef, menuTreeGridRef: menuTreeGridRef }); |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'addAllRole', |
|
||||
label: t('system.role.action.addAllRole'), |
|
||||
icon: '', |
|
||||
enable: () => {}, |
|
||||
click: () => { |
|
||||
const menuId = menuTreeGridRef.value.getSelected(); |
|
||||
axios |
|
||||
.post(Environment.apiContextPath('/api/system/menu/addAllRoles'), { |
|
||||
source: menuId, |
|
||||
sourceParents: menuTreeGridRef.value.getCascadeParentIds(menuId), |
|
||||
sourceChildren: menuTreeGridRef.value.getCascadeChildrenIds(menuId), |
|
||||
targets: [], |
|
||||
}) |
|
||||
.then((response) => { |
|
||||
axios.get(Environment.apiContextPath('/api/system/role/queryRolesByMenu?menuId=') + menuId).then((response) => { |
|
||||
roleGridRef.value.replaceRowsFun(response.data.content); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'removeRole', |
|
||||
label: t('system.role.action.removeRole'), |
|
||||
icon: '', |
|
||||
enable: () => {}, |
|
||||
click: () => { |
|
||||
const menuId = menuTreeGridRef.value.getSelected(); |
|
||||
const roleIds = []; |
|
||||
for (const role of roleGridRef.value.getSelectedRows()) { |
|
||||
roleIds.push(role.id); |
|
||||
} |
|
||||
axios |
|
||||
.post(Environment.apiContextPath('/api/system/menu/removeRoles'), { |
|
||||
source: menuId, |
|
||||
sourceParents: menuTreeGridRef.value.getCascadeParentIds(menuId), |
|
||||
sourceChildren: menuTreeGridRef.value.getCascadeChildrenIds(menuId), |
|
||||
targets: roleIds, |
|
||||
}) |
|
||||
.then((response) => { |
|
||||
axios.get(Environment.apiContextPath('/api/system/role/queryRolesByMenu?menuId=') + menuId).then((response) => { |
|
||||
roleGridRef.value.replaceRowsFun(response.data.content); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'removeAllRole', |
|
||||
label: t('system.role.action.removeAllRole'), |
|
||||
icon: '', |
|
||||
enable: () => {}, |
|
||||
click: () => { |
|
||||
const menuId = menuTreeGridRef.value.getSelected(); |
|
||||
axios |
|
||||
.post(Environment.apiContextPath('/api/system/menu/removeAllRoles'), { |
|
||||
source: menuId, |
|
||||
sourceParents: menuTreeGridRef.value.getCascadeParentIds(menuId), |
|
||||
sourceChildren: menuTreeGridRef.value.getCascadeChildrenIds(menuId), |
|
||||
targets: [], |
|
||||
}) |
|
||||
.then((response) => { |
|
||||
axios.get(Environment.apiContextPath('/api/system/role/queryRolesByMenu?menuId=') + menuId).then((response) => { |
|
||||
roleGridRef.value.replaceRowsFun(response.data.content); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
}, |
|
||||
], |
|
||||
tableColumns: [ |
|
||||
{ width: 100, name: 'code', label: t('code') }, |
|
||||
{ width: 100, name: 'name', label: t('name') }, |
|
||||
{ width: 80, name: 'enable', label: t('isEnable'), format: (value) => (value ? t('yes') : t('no')) }, |
|
||||
], |
|
||||
}; |
}; |
||||
|
|
||||
const menuConfigure = { |
const remove = (ids, gridComponent) => { |
||||
actions: [ |
axios |
||||
{ |
.post(Environment.apiContextPath('/api/system/menu/removeRoles'), { |
||||
name: 'refresh', |
one: menuTreeGridRef.value.getSelectedRows()[0].id, |
||||
label: t('refresh'), |
many: ids, |
||||
enable: () => { |
}) |
||||
return true; |
.then(() => { |
||||
}, |
gridComponent?.refresh(); |
||||
click: () => { |
}); |
||||
refresh(); |
|
||||
}, |
|
||||
}, |
|
||||
|
|
||||
{ |
|
||||
name: 'addRoot', |
|
||||
label: t('system.menu.action.addTop'), |
|
||||
enable: () => { |
|
||||
return true; |
|
||||
}, |
|
||||
click: () => { |
|
||||
addTopMenuDialog.value.show(refresh); |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'addChild', |
|
||||
label: t('system.menu.action.addChild'), |
|
||||
enable: () => { |
|
||||
return true; |
|
||||
}, |
|
||||
click: () => { |
|
||||
const node = menuTreeGridRef.value.getNodeById(selectedMenuId); |
|
||||
if (node && node.type === 'GROUP') { |
|
||||
addMenuDialog.value.show(selectedMenuId, refresh); |
|
||||
} else { |
|
||||
quasar |
|
||||
.dialog({ |
|
||||
title: '提示', |
|
||||
message: '请在菜单组中添加子菜单', |
|
||||
persistent: true, |
|
||||
}) |
|
||||
.onOk(() => {}); |
|
||||
} |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'edit', |
|
||||
label: t('edit'), |
|
||||
enable: () => { |
|
||||
return true; |
|
||||
}, |
|
||||
click: () => { |
|
||||
const node = menuTreeGridRef.value.getNodeById(selectedMenuId); |
|
||||
if (node && node.type === 'ROUTE') { |
|
||||
editMenuDialog.value.show(menuTreeGridRef.value.getNodeById(selectedMenuId), refresh); |
|
||||
} else { |
|
||||
quasar |
|
||||
.dialog({ |
|
||||
title: '提示', |
|
||||
message: '请选择一个菜单项', |
|
||||
persistent: true, |
|
||||
}) |
|
||||
.onOk(() => {}); |
|
||||
} |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'delete', |
|
||||
label: t('delete'), |
|
||||
enable: () => { |
|
||||
return true; |
|
||||
}, |
|
||||
click: () => { |
|
||||
const node = menuTreeGridRef.value.getNodeById(selectedMenuId); |
|
||||
if (node) { |
|
||||
quasar |
|
||||
.dialog({ |
|
||||
title: t('confirm'), |
|
||||
message: '您确定要删除该菜单吗?', |
|
||||
cancel: true, |
|
||||
persistent: true, |
|
||||
}) |
|
||||
.onOk(() => { |
|
||||
axios.delete(Environment.apiContextPath('/api/system/menu/' + selectedMenuId)).then((response) => { |
|
||||
refresh(); |
|
||||
}); |
|
||||
}); |
|
||||
} else { |
|
||||
quasar |
|
||||
.dialog({ |
|
||||
title: '提示', |
|
||||
message: '请选择一个菜单项', |
|
||||
persistent: true, |
|
||||
}) |
|
||||
.onOk(() => {}); |
|
||||
} |
|
||||
}, |
|
||||
}, |
|
||||
], |
|
||||
}; |
}; |
||||
|
|
||||
const orgConfigure = { |
const addAll = (gridComponent) => { |
||||
actions: [ |
axios |
||||
{ |
.post(Environment.apiContextPath('/api/system/menu/addAllRoles'), { |
||||
name: 'save', |
one: menuTreeGridRef.value.getSelectedRows()[0].id, |
||||
label: '保存', |
many: [], |
||||
click: () => { |
}) |
||||
const orgId = menuTreeGridRef.value.getSelected()[0]; |
.then(() => { |
||||
axios |
gridComponent?.refresh(); |
||||
.post(Environment.apiContextPath('/api/system/menu/updateOrgs'), { |
}); |
||||
one: orgId, |
|
||||
many: menuTreeGridRef.value.getTicked(), |
|
||||
}) |
|
||||
.then((response) => {}); |
|
||||
}, |
|
||||
}, |
|
||||
], |
|
||||
}; |
}; |
||||
|
|
||||
const menuSelected = (target) => { |
const removeAll = (gridComponent) => { |
||||
selectedMenuId = target; |
axios |
||||
if (roleGridRef.value) { |
.post(Environment.apiContextPath('/api/system/menu/removeAllRoles'), { |
||||
axios.get(Environment.apiContextPath('/api/system/role/queryRolesByMenu?menuId=') + selectedMenuId).then((response) => { |
one: menuTreeGridRef.value.getSelectedRows()[0].id, |
||||
roleGridRef.value.replaceRowsFun(response.data.content); |
many: [], |
||||
|
}) |
||||
|
.then(() => { |
||||
|
gridComponent?.refresh(); |
||||
}); |
}); |
||||
} |
|
||||
|
|
||||
// if (orgTreeGridRef.value) { |
|
||||
// axios.get(Environment.apiContextPath('/api/system/org/listAllOrgsWithSelectedStatusByMenu?menuId=') + selectedMenuId).then((response) => { |
|
||||
// orgTreeGridRef.value.setNodes(response.data); |
|
||||
// }); |
|
||||
// } |
|
||||
}; |
}; |
||||
|
|
||||
const refresh = () => { |
const update = (ids, gridComponent) => { |
||||
axios.get(Environment.apiContextPath('/api/system/menu?pageable=false&sortBy=order')).then((response) => { |
axios |
||||
menuTreeGridRef.value.setNodes(response.data.content); |
.post(Environment.apiContextPath('/api/system/menu/updateOrgs'), { |
||||
}); |
one: menuTreeGridRef.value.getSelectedRows()[0].id, |
||||
|
many: ids, |
||||
|
}) |
||||
|
.then(() => { |
||||
|
gridComponent.refresh(); |
||||
|
}); |
||||
}; |
}; |
||||
|
|
||||
onMounted(() => { |
|
||||
refresh(); |
|
||||
}); |
|
||||
</script> |
</script> |
||||
|
@ -1,155 +1,105 @@ |
|||||
<template> |
<template> |
||||
<div> |
<w-dialog |
||||
<q-dialog ref="dialogRef" allow-focus-outside v-bind="attrs"> |
ref="dialogRef" |
||||
<q-card |
:title="$t('system.selectRoleByUserDialog.title')" |
||||
:style="{ |
width="800px" |
||||
width: attrs.maximized ? '100vw' : width, |
height="500px" |
||||
'max-width': '100vw', |
:can-maximize="false" |
||||
height: attrs.maximized ? '100vh' : height, |
:buttons="[ |
||||
'max-height': '100vh', |
{ |
||||
}" |
label: $t('confirm'), |
||||
> |
click: () => { |
||||
<q-card-section :style="headerStyle"> |
const roleIds = Tools.extractProperties(gridRef.getSelectedRows(), 'id'); |
||||
<div class="flex justify-between"> |
axios |
||||
<div class="text-h6">{{ title }}</div> |
.post(Environment.apiContextPath('/api/system/user/addRoles'), { |
||||
<div class="flex justify-end q-gutter-md"> |
one: parentId, |
||||
<q-btn :label="$t('confirm')" dense color="primary" style="width: 100px" @click="addRoles" /> |
many: roleIds, |
||||
<q-btn v-close-popup dense flat icon="close" :title="$t('close')"> </q-btn> |
}) |
||||
</div> |
.then((response) => { |
||||
</div> |
parentComponent?.refresh(); |
||||
</q-card-section> |
close(); |
||||
<q-card-section class="q-pt-none" :style="bodyStyle"> |
}); |
||||
<platform-grid |
}, |
||||
ref="gridRef" |
}, |
||||
:table-props="{ borderded: false, flat: true }" |
]" |
||||
:query-form-cols-number="roleConfigure.queryFormColsNumber" |
> |
||||
:hide-bottom="roleConfigure.hideBottom" |
<div class="px-2"> |
||||
:query-form-cols-auto="roleConfigure.queryFormColsAuto" |
<w-grid |
||||
:table-title="roleConfigure.tableTitle" |
ref="gridRef" |
||||
:table-row-key="roleConfigure.tableRowKey" |
:title="$t('system.role.grid.title')" |
||||
:table-init-load-data="roleConfigure.tableInitLoadData" |
selection="multiple" |
||||
:table-data-url="roleConfigure.tableDataUrl" |
:full-screen-button="false" |
||||
:table-show-sort-no="false" |
:toolbar-configure="{ noIcon: false }" |
||||
:table-columns="roleConfigure.tableColumns" |
:toolbar-actions="['query', 'refresh']" |
||||
:table-left-column-sticky-number="roleConfigure.tableLeftColumnStickyNumber" |
:query-form-fields="[ |
||||
:table-buttons="roleConfigure.tableButtons" |
{ name: 'code', label: $t('code'), type: 'text' }, |
||||
:query-form-fields="roleConfigure.queryFormFields" |
{ name: 'name', label: $t('name'), type: 'text' }, |
||||
:table-pagination="roleConfigure.tablePagination" |
{ |
||||
table-selection="multiple" |
name: 'enable', |
||||
:table-dense="false" |
label: $t('enable'), |
||||
> |
type: 'select', |
||||
</platform-grid> |
options: Options.yesNo(), |
||||
</q-card-section> |
queryOperator: 'equals', |
||||
</q-card> |
}, |
||||
</q-dialog> |
{ |
||||
</div> |
name: 'dataComeFrom', |
||||
|
label: $t('dataComeFrom'), |
||||
|
type: 'select', |
||||
|
options: Options.enum(DataComeFromEnum), |
||||
|
queryOperator: 'equals', |
||||
|
}, |
||||
|
]" |
||||
|
:auto-fetch-data="false" |
||||
|
:fetch-data-url="Environment.apiContextPath('/api/system/role/queryOtherRolesByUser?userId=' + parentId)" |
||||
|
:columns="[ |
||||
|
{ name: 'code', label: $t('code') }, |
||||
|
{ name: 'name', label: $t('name') }, |
||||
|
{ |
||||
|
name: 'status', |
||||
|
label: t('status'), |
||||
|
format: Formater.enableTag(), |
||||
|
}, |
||||
|
{ name: 'lastModifier', label: t('lastModifier') }, |
||||
|
{ name: 'lastModifyDate', label: t('lastModifyDate') }, |
||||
|
]" |
||||
|
></w-grid> |
||||
|
</div> |
||||
|
</w-dialog> |
||||
</template> |
</template> |
||||
<script setup lang="ts"> |
<script setup lang="ts"> |
||||
import { useAttrs, ref, onMounted, nextTick } from 'vue'; |
import { ref, nextTick } from 'vue'; |
||||
import { useI18n } from 'vue-i18n'; |
import { useI18n } from 'vue-i18n'; |
||||
import { axios, Environment } from 'platform-core'; |
import { axios, Environment, Tools, EnumTools, Options, Formater } from 'platform-core'; |
||||
|
|
||||
const attrs = useAttrs(); |
|
||||
|
|
||||
const props = defineProps({ |
|
||||
headerStyle: { type: String, default: 'width:100%;padding: 16px 8px 4px 16px' }, |
|
||||
bodyStyle: { type: String, default: 'padding: 0px 8px 0px 8px;height:calc(100%)' }, |
|
||||
title: { type: String, default: '' }, |
|
||||
width: { type: String, default: '70%' }, |
|
||||
height: { type: String, default: '70%' }, |
|
||||
}); |
|
||||
|
|
||||
const { t } = useI18n(); |
const { t } = useI18n(); |
||||
|
|
||||
const dialogRef = ref(); |
const dialogRef = ref(); |
||||
const gridRef = ref(); |
const gridRef = ref(); |
||||
let menuTreeGridRef, roleGridRef; |
|
||||
|
|
||||
const roleConfigure = { |
let DataComeFromEnum = ref(); |
||||
queryFormColsNumber: 4, |
EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom').then((data) => { |
||||
queryFormColsAuto: false, |
DataComeFromEnum.value = data; |
||||
hideBottom: true, |
}); |
||||
tableInitLoadData: false, |
|
||||
tableLeftColumnStickyNumber: 0, |
|
||||
tableTitle: '', |
|
||||
tableRowKey: 'id', |
|
||||
tableDataUrl: '', |
|
||||
tablePagination: { |
|
||||
sortBy: 'lastModifyDate', |
|
||||
descending: true, |
|
||||
reqPageStart: 0, |
|
||||
rowsPerPage: 0, |
|
||||
}, |
|
||||
tableButtons: ['query', 'refresh'], |
|
||||
queryFormFields: [ |
|
||||
{ label: t('code'), modelName: 'code', type: 'text' }, |
|
||||
{ label: t('name'), modelName: 'name', type: 'text' }, |
|
||||
{ |
|
||||
label: t('enable'), |
|
||||
modelName: 'enable', |
|
||||
type: 'select', |
|
||||
options: [ |
|
||||
{ value: true, label: '是' }, |
|
||||
{ value: false, label: '否' }, |
|
||||
], |
|
||||
}, |
|
||||
{ |
|
||||
label: t('dataComeFrom'), |
|
||||
modelName: 'dataComeFrom', |
|
||||
type: 'select', |
|
||||
options: [ |
|
||||
{ value: 'MANUAL', label: t('io.sc.platform.orm.api.enums.DataComeFrom.MANUAL') }, |
|
||||
{ value: 'AUTO', label: t('io.sc.platform.orm.api.enums.DataComeFrom.AUTO') }, |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
tableColumns: [ |
|
||||
{ width: 100, name: 'code', label: t('code') }, |
|
||||
{ width: 100, name: 'name', label: t('name') }, |
|
||||
{ width: 80, name: 'enable', label: t('isEnable'), format: (value) => (value ? t('yes') : t('no')) }, |
|
||||
], |
|
||||
}; |
|
||||
|
|
||||
const addRoles = () => { |
let parentId, parentComponent; |
||||
const menuId = menuTreeGridRef.value.getSelected(); |
|
||||
const roleIds = []; |
|
||||
for (const role of gridRef.value.getSelectedRows()) { |
|
||||
roleIds.push(role.id); |
|
||||
} |
|
||||
axios |
|
||||
.post(Environment.apiContextPath('/api/system/menu/addRoles'), { |
|
||||
source: menuId, |
|
||||
sourceParents: menuTreeGridRef.value.getCascadeParentIds(menuId), |
|
||||
sourceChildren: menuTreeGridRef.value.getCascadeChildrenIds(menuId), |
|
||||
targets: roleIds, |
|
||||
}) |
|
||||
.then((response) => { |
|
||||
axios.get(Environment.apiContextPath('/api/system/role/queryRolesByMenu?menuId=') + menuId).then((response) => { |
|
||||
roleGridRef.value.replaceRowsFun(response.data.content); |
|
||||
}); |
|
||||
dialogRef.value.hide(); |
|
||||
}); |
|
||||
}; |
|
||||
|
|
||||
const show = (param: object) => { |
const open = (param: object) => { |
||||
menuTreeGridRef = param.menuTreeGridRef; |
parentId = param.parentId; |
||||
roleGridRef = param.roleGridRef; |
parentComponent = param.parentComponent; |
||||
const currentMenuId = menuTreeGridRef.value.getSelected()[0]; |
|
||||
|
|
||||
dialogRef.value.show(); |
dialogRef.value.show(); |
||||
|
|
||||
nextTick(() => { |
nextTick(() => { |
||||
axios.get(Environment.apiContextPath('/api/system/role/queryOtherRolesByMenu?menuId=') + currentMenuId).then((response) => { |
gridRef.value.refresh(); |
||||
gridRef.value.replaceRowsFun(response.data.content); |
|
||||
}); |
|
||||
}); |
}); |
||||
}; |
}; |
||||
|
|
||||
const hide = () => { |
const close = () => { |
||||
dialogRef.value.hide(); |
dialogRef.value.hide(); |
||||
}; |
}; |
||||
|
|
||||
defineExpose({ |
defineExpose({ |
||||
show, |
open, |
||||
hide, |
close, |
||||
}); |
}); |
||||
</script> |
</script> |
||||
|
@ -0,0 +1,60 @@ |
|||||
|
<template> |
||||
|
<w-grid |
||||
|
ref="notificationGridRef" |
||||
|
:title="$t('system.notification.grid.title')" |
||||
|
selection="multiple" |
||||
|
:data-url="Environment.apiContextPath('/api/system/notification')" |
||||
|
:pagination="{ |
||||
|
sortBy: 'lastModifyDate', |
||||
|
descending: true, |
||||
|
}" |
||||
|
:query-form-fields="[ |
||||
|
{ name: 'title', label: $t('title'), type: 'text' }, |
||||
|
{ name: 'dataComeFrom', label: $t('dataComeFrom'), type: 'select', options: Options.enum(DataComeFromEnum), queryOperator: 'equals' }, |
||||
|
]" |
||||
|
:toolbar-configure="{ noIcon: false }" |
||||
|
:toolbar-actions="['query', 'refresh', 'separator', 'add', 'clone', 'edit', 'remove', 'separator', 'view', 'export']" |
||||
|
:columns="[ |
||||
|
{ width: 300, name: 'title', label: $t('title') }, |
||||
|
{ width: '100%', name: 'content', label: $t('content') }, |
||||
|
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) }, |
||||
|
{ name: 'lastModifier', label: $t('lastModifier') }, |
||||
|
{ name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() }, |
||||
|
]" |
||||
|
:editor="{ |
||||
|
dialog: { |
||||
|
width: '600px', |
||||
|
height: '380px', |
||||
|
}, |
||||
|
form: { |
||||
|
colsNum: 1, |
||||
|
fields: [ |
||||
|
{ name: 'receiver', label: $t('receiver'), type: 'text', required: true }, |
||||
|
{ name: 'title', label: $t('title'), type: 'text', required: true }, |
||||
|
{ name: 'content', label: $t('content'), type: 'q-editor', required: true, minHeight: '10rem' }, |
||||
|
], |
||||
|
}, |
||||
|
}" |
||||
|
:viewer="{ |
||||
|
panel: { |
||||
|
columnNum: 1, |
||||
|
fields: [ |
||||
|
{ name: 'id', label: $t('id') }, |
||||
|
{ name: 'title', label: $t('title') }, |
||||
|
{ name: 'content', label: $t('content') }, |
||||
|
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) }, |
||||
|
{ name: 'creator', label: $t('creator') }, |
||||
|
{ name: 'createDate', label: $t('createDate') }, |
||||
|
{ name: 'lastModifier', label: $t('lastModifier') }, |
||||
|
{ name: 'lastModifyDate', label: $t('lastModifyDate') }, |
||||
|
{ name: 'corporationCode', label: $t('corporationCode') }, |
||||
|
], |
||||
|
}, |
||||
|
}" |
||||
|
></w-grid> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { Environment, EnumTools, Options, Formater } from 'platform-core'; |
||||
|
|
||||
|
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom'); |
||||
|
</script> |
@ -1,244 +1,175 @@ |
|||||
<template> |
<template> |
||||
<q-splitter :model-value="70" class="w-full h-full"> |
<q-splitter :model-value="60" class="w-full h-full"> |
||||
<template #before> |
<template #before> |
||||
<w-tree-grid ref="orgTreeGridRef" title="机构树" label-key="name" :actions="orgConfigure.actions" @update:selected="orgSelected" /> |
<div class="pr-1"> |
||||
|
<w-grid |
||||
|
ref="orgTreeGridRef" |
||||
|
:tree="true" |
||||
|
:title="$t('system.org.grid.title')" |
||||
|
dense-body |
||||
|
:data-url="Environment.apiContextPath('/api/system/org')" |
||||
|
selection="multiple" |
||||
|
:checkbox-selection="false" |
||||
|
:pageable="false" |
||||
|
:tree-icon=" |
||||
|
(row) => { |
||||
|
return { name: 'folder', color: 'amber' }; |
||||
|
} |
||||
|
" |
||||
|
:toolbar-configure="{ noIcon: false }" |
||||
|
:toolbar-actions="['refresh', 'separator', ['addTop', 'addChild'], 'edit', 'remove', 'separator', 'view', 'export']" |
||||
|
:columns="[ |
||||
|
{ width: '100%', name: 'name', label: $t('name') }, |
||||
|
{ width: 200, name: 'code', label: $t('code') }, |
||||
|
{ width: 100, name: 'enable', label: $t('status'), sortable: false, format: Formater.enableTag() }, |
||||
|
]" |
||||
|
:editor="{ |
||||
|
dialog: { |
||||
|
width: '600px', |
||||
|
height: '300px', |
||||
|
}, |
||||
|
form: { |
||||
|
colsNum: 1, |
||||
|
fields: [ |
||||
|
{ name: 'code', label: $t('code'), type: 'text', required: true }, |
||||
|
{ name: 'name', label: $t('name'), type: 'text', required: true }, |
||||
|
{ name: 'description', label: $t('description'), type: 'textarea', rows: 1 }, |
||||
|
{ name: 'enable', label: $t('enable'), type: 'checkbox', defaultValue: true }, |
||||
|
], |
||||
|
}, |
||||
|
}" |
||||
|
:viewer="{ |
||||
|
panel: { |
||||
|
columnNum: 1, |
||||
|
fields: [ |
||||
|
{ name: 'id', label: $t('id') }, |
||||
|
{ name: 'code', label: $t('code') }, |
||||
|
{ name: 'name', label: $t('name') }, |
||||
|
{ name: 'description', label: $t('description') }, |
||||
|
{ name: 'enable', label: $t('enable'), format: Formater.yesNo() }, |
||||
|
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) }, |
||||
|
{ name: 'creator', label: $t('creator') }, |
||||
|
{ name: 'createDate', label: $t('createDate') }, |
||||
|
{ name: 'lastModifier', label: $t('lastModifier') }, |
||||
|
{ name: 'lastModifyDate', label: $t('lastModifyDate') }, |
||||
|
{ name: 'corporationCode', label: $t('corporationCode') }, |
||||
|
], |
||||
|
}, |
||||
|
}" |
||||
|
@row-click=" |
||||
|
(evt, row, index) => { |
||||
|
currentSelectedOrgId = row.id; |
||||
|
userGridRef?.refresh(); |
||||
|
menuTreeGridRef?.refresh(); |
||||
|
} |
||||
|
" |
||||
|
></w-grid> |
||||
|
</div> |
||||
</template> |
</template> |
||||
<template #after> |
<template #after> |
||||
<q-tabs v-model="selectedTabRef" inline-label align="left" :breakpoint="0"> |
<div class="pl-1"> |
||||
<q-tab name="user" icon="bi-diagram-3" :label="$t('user')" /> |
<q-tabs v-model="selectedTabRef" inline-label align="left" :breakpoint="0"> |
||||
<q-tab name="menu" icon="bi-people" :label="$t('menu')" /> |
<q-tab name="user" icon="bi-diagram-3" :label="$t('user')" /> |
||||
</q-tabs> |
<q-tab name="menu" icon="bi-people" :label="$t('menu')" /> |
||||
|
</q-tabs> |
||||
|
|
||||
<q-tab-panels v-model="selectedTabRef" animated swipeable keep-alive> |
<q-tab-panels v-model="selectedTabRef" animated swipeable keep-alive> |
||||
<q-tab-panel name="user"> |
<q-tab-panel name="user" class="px-0"> |
||||
<platform-grid |
<SelectUserGrid |
||||
ref="userGridRef" |
ref="userGridRef" |
||||
:table-props="{ borderded: false, flat: true }" |
:fetch-data-url="Environment.apiContextPath('/api/system/user/queryUsersByOrg')" |
||||
:query-form-cols-number="userConfigure.queryFormColsNumber" |
:fetch-other-data-url="Environment.apiContextPath('/api/system/user/queryOtherUsersByOrg')" |
||||
:hide-bottom="userConfigure.hideBottom" |
foreign-key="orgId" |
||||
:query-form-cols-auto="userConfigure.queryFormColsAuto" |
:foreign-value="currentSelectedOrgId" |
||||
:table-title="userConfigure.tableTitle" |
@add="add" |
||||
:table-row-key="userConfigure.tableRowKey" |
@remove="remove" |
||||
:table-init-load-data="userConfigure.tableInitLoadData" |
@add-all="addAll" |
||||
:table-data-url="userConfigure.tableDataUrl" |
@remove-all="removeAll" |
||||
:table-show-sort-no="false" |
> |
||||
:table-columns="userConfigure.tableColumns" |
</SelectUserGrid> |
||||
:table-left-column-sticky-number="userConfigure.tableLeftColumnStickyNumber" |
</q-tab-panel> |
||||
:table-buttons="userConfigure.tableButtons" |
<q-tab-panel name="menu" class="px-0"> |
||||
:query-form-fields="userConfigure.queryFormFields" |
<SelectMenuTreeGrid |
||||
:table-pagination="userConfigure.tablePagination" |
ref="menuTreeGridRef" |
||||
table-selection="multiple" |
:fetch-data-url="Environment.apiContextPath('/api/system/menu/listAllMenusWithSelectedStatusByOrg')" |
||||
:table-dense="false" |
foreign-key="orgId" |
||||
> |
:foreign-value="currentSelectedOrgId" |
||||
</platform-grid> |
@update="update" |
||||
</q-tab-panel> |
></SelectMenuTreeGrid> |
||||
|
</q-tab-panel> |
||||
<q-tab-panel name="menu"> |
</q-tab-panels> |
||||
<w-tree-grid |
</div> |
||||
ref="menuTreeGridRef" |
|
||||
title="菜单树" |
|
||||
label-key="titleI18nKey" |
|
||||
label-i18n |
|
||||
label-empty="--------------------" |
|
||||
tick-strategy="leaf" |
|
||||
:actions="menuConfigure.actions" |
|
||||
/> |
|
||||
</q-tab-panel> |
|
||||
</q-tab-panels> |
|
||||
</template> |
</template> |
||||
<SelectUserDialog ref="selectUserDialog" title="可选用户列表" :maximized="false" width="50%" height="500px"></SelectUserDialog> |
|
||||
</q-splitter> |
</q-splitter> |
||||
</template> |
</template> |
||||
<script setup lang="ts"> |
<script setup lang="ts"> |
||||
import { ref, onMounted } from 'vue'; |
import { ref } from 'vue'; |
||||
import { useI18n } from 'vue-i18n'; |
import { Environment, axios, EnumTools, Formater } from 'platform-core'; |
||||
import { Environment, axios } from 'platform-core'; |
import SelectUserGrid from '../shared/SelectUserGrid.vue'; |
||||
import SelectUserDialog from './SelectUserDialog.vue'; |
import SelectMenuTreeGrid from '../shared/SelectMenuTreeGrid.vue'; |
||||
|
|
||||
const { t } = useI18n(); |
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom'); |
||||
|
|
||||
const orgTreeGridRef = ref(); |
const orgTreeGridRef = ref(); |
||||
const userGridRef = ref(); |
const userGridRef = ref(); |
||||
const menuTreeGridRef = ref(); |
const menuTreeGridRef = ref(); |
||||
|
|
||||
const selectUserDialog = ref(); |
|
||||
const selectedTabRef = ref('user'); |
const selectedTabRef = ref('user'); |
||||
let selectedOrgId = ''; |
const currentSelectedOrgId = ref(''); |
||||
|
|
||||
const userConfigure = { |
const add = (ids: string[], gridComponent, dialogComponent) => { |
||||
queryFormColsNumber: 4, |
axios |
||||
queryFormColsAuto: false, |
.post(Environment.apiContextPath('/api/system/org/addUsers'), { |
||||
queryFormFields: [], |
one: orgTreeGridRef.value.getSelectedRows()[0].id, |
||||
hideBottom: true, |
many: ids, |
||||
tableInitLoadData: false, |
}) |
||||
tableLeftColumnStickyNumber: 0, |
.then(() => { |
||||
tableTitle: t('system.user.gridTitle'), |
gridComponent?.refresh(); |
||||
tableRowKey: 'id', |
dialogComponent?.close(); |
||||
tableDataUrl: '', |
}); |
||||
tablePagination: { |
|
||||
sortBy: 'lastModifyDate', |
|
||||
descending: true, |
|
||||
reqPageStart: 0, |
|
||||
rowsPerPage: 0, |
|
||||
}, |
|
||||
tableButtons: [ |
|
||||
'refresh', |
|
||||
'inFullscreen', |
|
||||
{ |
|
||||
name: 'addUser', |
|
||||
label: t('system.user.action.addUser'), |
|
||||
icon: '', |
|
||||
enable: () => {}, |
|
||||
click: () => { |
|
||||
selectUserDialog.value.show({ userGrid: userGridRef, orgTreeGridRef: orgTreeGridRef }); |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'addAllUser', |
|
||||
label: t('system.user.action.addAllUser'), |
|
||||
icon: '', |
|
||||
enable: () => {}, |
|
||||
click: () => { |
|
||||
const orgId = orgTreeGridRef.value.getSelected()[0]; |
|
||||
axios |
|
||||
.post(Environment.apiContextPath('/api/system/org/addAllUsers'), { |
|
||||
one: orgId, |
|
||||
many: [], |
|
||||
}) |
|
||||
.then((response) => { |
|
||||
axios.get(Environment.apiContextPath('/api/system/user/queryUsersByOrg?orgId=') + orgId).then((response) => { |
|
||||
userGridRef.value.replaceRowsFun(response.data.content); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'removeUser', |
|
||||
label: t('system.user.action.removeUser'), |
|
||||
icon: '', |
|
||||
enable: () => {}, |
|
||||
click: () => { |
|
||||
const orgId = orgTreeGridRef.value.getSelected()[0]; |
|
||||
const userIds = []; |
|
||||
for (const user of userGridRef.value.getSelectedRows()) { |
|
||||
userIds.push(user.id); |
|
||||
} |
|
||||
axios |
|
||||
.post(Environment.apiContextPath('/api/system/org/removeUsers'), { |
|
||||
one: orgId, |
|
||||
many: userIds, |
|
||||
}) |
|
||||
.then((response) => { |
|
||||
axios.get(Environment.apiContextPath('/api/system/user/queryUsersByOrg?orgId=') + orgId).then((response) => { |
|
||||
userGridRef.value.replaceRowsFun(response.data.content); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'removeAllUser', |
|
||||
label: t('system.user.action.removeAllUser'), |
|
||||
icon: '', |
|
||||
enable: () => {}, |
|
||||
click: () => { |
|
||||
const orgId = orgTreeGridRef.value.getSelected()[0]; |
|
||||
axios |
|
||||
.post(Environment.apiContextPath('/api/system/org/removeAllUsers'), { |
|
||||
one: orgId, |
|
||||
many: [], |
|
||||
}) |
|
||||
.then((response) => { |
|
||||
axios.get(Environment.apiContextPath('/api/system/user/queryUsersByOrg?orgId=') + orgId).then((response) => { |
|
||||
userGridRef.value.replaceRowsFun(response.data.content); |
|
||||
}); |
|
||||
}); |
|
||||
}, |
|
||||
}, |
|
||||
], |
|
||||
tableColumns: [ |
|
||||
{ width: 100, name: 'loginName', label: t('loginName') }, |
|
||||
{ width: 100, name: 'userName', label: t('userName') }, |
|
||||
{ width: 80, name: 'enable', label: t('isEnable'), format: (value) => (value ? t('yes') : t('no')) }, |
|
||||
], |
|
||||
}; |
}; |
||||
|
|
||||
const orgConfigure = { |
const remove = (ids, gridComponent) => { |
||||
actions: [ |
axios |
||||
/* |
.post(Environment.apiContextPath('/api/system/org/removeUsers'), { |
||||
{ |
one: orgTreeGridRef.value.getSelectedRows()[0].id, |
||||
name: 'refresh', |
many: ids, |
||||
label: t('refresh'), |
}) |
||||
click: () => {}, |
.then(() => { |
||||
}, |
gridComponent?.refresh(); |
||||
{ |
}); |
||||
name: 'expandAll', |
|
||||
label: t('expandAll'), |
|
||||
click: () => {}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'selectAll', |
|
||||
label: t('selectAll'), |
|
||||
click: () => {}, |
|
||||
}, |
|
||||
*/ |
|
||||
{ |
|
||||
name: 'addRoot', |
|
||||
label: t('添加顶级机构'), |
|
||||
click: () => {}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'addChild', |
|
||||
label: t('添加子机构'), |
|
||||
click: () => {}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'edit', |
|
||||
label: t('edit'), |
|
||||
click: () => {}, |
|
||||
}, |
|
||||
{ |
|
||||
name: 'delete', |
|
||||
label: t('delete'), |
|
||||
click: () => {}, |
|
||||
}, |
|
||||
], |
|
||||
}; |
}; |
||||
|
|
||||
const menuConfigure = { |
const addAll = (gridComponent) => { |
||||
actions: [ |
axios |
||||
{ |
.post(Environment.apiContextPath('/api/system/org/addAllUsers'), { |
||||
name: 'save', |
one: orgTreeGridRef.value.getSelectedRows()[0].id, |
||||
label: '保存', |
many: [], |
||||
click: () => { |
}) |
||||
const orgId = orgTreeGridRef.value.getSelected()[0]; |
.then(() => { |
||||
axios |
gridComponent?.refresh(); |
||||
.post(Environment.apiContextPath('/api/system/org/updateMenus'), { |
}); |
||||
one: orgId, |
|
||||
many: menuTreeGridRef.value.getTicked(), |
|
||||
}) |
|
||||
.then((response) => {}); |
|
||||
}, |
|
||||
}, |
|
||||
], |
|
||||
}; |
}; |
||||
|
|
||||
const orgSelected = (target) => { |
const removeAll = (gridComponent) => { |
||||
selectedOrgId = target; |
axios |
||||
if (userGridRef.value) { |
.post(Environment.apiContextPath('/api/system/org/removeAllUsers'), { |
||||
axios.get(Environment.apiContextPath('/api/system/user/queryUsersByOrg?orgId=') + selectedOrgId).then((response) => { |
one: orgTreeGridRef.value.getSelectedRows()[0].id, |
||||
userGridRef.value.replaceRowsFun(response.data.content); |
many: [], |
||||
|
}) |
||||
|
.then(() => { |
||||
|
gridComponent?.refresh(); |
||||
}); |
}); |
||||
} |
|
||||
if (menuTreeGridRef.value) { |
|
||||
axios.get(Environment.apiContextPath('/api/system/menu/listAllMenusWithSelectedStatusByOrg?orgId=') + selectedOrgId).then((response) => { |
|
||||
menuTreeGridRef.value.setNodes(response.data); |
|
||||
}); |
|
||||
} |
|
||||
}; |
}; |
||||
|
|
||||
onMounted(() => { |
const update = (ids, gridComponent) => { |
||||
axios.get(Environment.apiContextPath('/api/system/org?pageable=false&sortBy=name')).then((response) => { |
axios |
||||
orgTreeGridRef.value.setNodes(response.data.content); |
.post(Environment.apiContextPath('/api/system/org/updateMenus'), { |
||||
}); |
one: orgTreeGridRef.value.getSelectedRows()[0].id, |
||||
}); |
many: ids, |
||||
|
}) |
||||
|
.then(() => { |
||||
|
gridComponent.refresh(); |
||||
|
}); |
||||
|
}; |
||||
</script> |
</script> |
||||
|
@ -1,154 +0,0 @@ |
|||||
<template> |
|
||||
<div> |
|
||||
<q-dialog ref="dialogRef" allow-focus-outside v-bind="attrs"> |
|
||||
<q-card |
|
||||
:style="{ |
|
||||
width: attrs.maximized ? '100vw' : width, |
|
||||
'max-width': '100vw', |
|
||||
height: attrs.maximized ? '100vh' : height, |
|
||||
'max-height': '100vh', |
|
||||
}" |
|
||||
> |
|
||||
<q-card-section :style="headerStyle"> |
|
||||
<div class="flex justify-between"> |
|
||||
<div class="text-h6">{{ title }}</div> |
|
||||
<div class="flex justify-end q-gutter-md"> |
|
||||
<q-btn :label="$t('confirm')" dense color="primary" style="width: 100px" @click="addUsers" /> |
|
||||
<q-btn v-close-popup dense flat icon="close" :title="$t('close')"> </q-btn> |
|
||||
</div> |
|
||||
</div> |
|
||||
</q-card-section> |
|
||||
<q-card-section class="q-pt-none" :style="bodyStyle"> |
|
||||
<platform-grid |
|
||||
ref="gridRef" |
|
||||
:table-props="{ borderded: false, flat: true }" |
|
||||
:query-form-cols-number="userConfigure.queryFormColsNumber" |
|
||||
:hide-bottom="userConfigure.hideBottom" |
|
||||
:query-form-cols-auto="userConfigure.queryFormColsAuto" |
|
||||
:table-title="userConfigure.tableTitle" |
|
||||
:table-row-key="userConfigure.tableRowKey" |
|
||||
:table-init-load-data="userConfigure.tableInitLoadData" |
|
||||
:table-data-url="userConfigure.tableDataUrl" |
|
||||
:table-show-sort-no="false" |
|
||||
:table-columns="userConfigure.tableColumns" |
|
||||
:table-left-column-sticky-number="userConfigure.tableLeftColumnStickyNumber" |
|
||||
:table-buttons="userConfigure.tableButtons" |
|
||||
:query-form-fields="userConfigure.queryFormFields" |
|
||||
:table-pagination="userConfigure.tablePagination" |
|
||||
table-selection="multiple" |
|
||||
:table-dense="false" |
|
||||
> |
|
||||
</platform-grid> |
|
||||
</q-card-section> |
|
||||
</q-card> |
|
||||
</q-dialog> |
|
||||
</div> |
|
||||
</template> |
|
||||
<script setup lang="ts"> |
|
||||
import { useAttrs, ref, onMounted, nextTick } from 'vue'; |
|
||||
import { useI18n } from 'vue-i18n'; |
|
||||
import { axios, Environment } from 'platform-core'; |
|
||||
|
|
||||
const attrs = useAttrs(); |
|
||||
|
|
||||
const props = defineProps({ |
|
||||
headerStyle: { type: String, default: 'width:100%;padding: 16px 8px 4px 16px' }, |
|
||||
bodyStyle: { type: String, default: 'padding: 0px 8px 0px 8px;height:calc(100%)' }, |
|
||||
title: { type: String, default: '' }, |
|
||||
width: { type: String, default: '70%' }, |
|
||||
height: { type: String, default: '70%' }, |
|
||||
}); |
|
||||
|
|
||||
const { t } = useI18n(); |
|
||||
|
|
||||
const dialogRef = ref(); |
|
||||
const gridRef = ref(); |
|
||||
let userGridRef, orgTreeGridRef; |
|
||||
|
|
||||
const userConfigure = { |
|
||||
queryFormColsNumber: 4, |
|
||||
queryFormColsAuto: false, |
|
||||
hideBottom: true, |
|
||||
tableInitLoadData: false, |
|
||||
tableLeftColumnStickyNumber: 0, |
|
||||
tableTitle: '', |
|
||||
tableRowKey: 'id', |
|
||||
tableDataUrl: '', |
|
||||
tablePagination: { |
|
||||
sortBy: 'lastModifyDate', |
|
||||
descending: true, |
|
||||
reqPageStart: 0, |
|
||||
rowsPerPage: 0, |
|
||||
}, |
|
||||
tableButtons: ['query', 'refresh'], |
|
||||
queryFormFields: [ |
|
||||
{ label: t('loginName'), modelName: 'loginName', type: 'text' }, |
|
||||
{ label: t('userName'), modelName: 'userName', type: 'text' }, |
|
||||
{ |
|
||||
label: t('enable'), |
|
||||
modelName: 'enable', |
|
||||
type: 'select', |
|
||||
options: [ |
|
||||
{ value: true, label: '是' }, |
|
||||
{ value: false, label: '否' }, |
|
||||
], |
|
||||
}, |
|
||||
{ |
|
||||
label: t('dataComeFrom'), |
|
||||
modelName: 'dataComeFrom', |
|
||||
type: 'select', |
|
||||
options: [ |
|
||||
{ value: 'MANUAL', label: t('io.sc.platform.orm.api.enums.DataComeFrom.MANUAL') }, |
|
||||
{ value: 'AUTO', label: t('io.sc.platform.orm.api.enums.DataComeFrom.AUTO') }, |
|
||||
], |
|
||||
}, |
|
||||
], |
|
||||
tableColumns: [ |
|
||||
{ width: 100, name: 'loginName', label: t('loginName') }, |
|
||||
{ width: 100, name: 'userName', label: t('userName') }, |
|
||||
{ width: 80, name: 'enable', label: t('isEnable'), format: (value) => (value ? t('yes') : t('no')) }, |
|
||||
], |
|
||||
}; |
|
||||
|
|
||||
const addUsers = () => { |
|
||||
const orgId = orgTreeGridRef.value.getSelected()[0]; |
|
||||
const userIds = []; |
|
||||
for (const user of gridRef.value.getSelectedRows()) { |
|
||||
userIds.push(user.id); |
|
||||
} |
|
||||
|
|
||||
axios |
|
||||
.post(Environment.apiContextPath('/api/system/org/addUsers'), { |
|
||||
one: orgId, |
|
||||
many: userIds, |
|
||||
}) |
|
||||
.then((response) => { |
|
||||
axios.get(Environment.apiContextPath('/api/system/user/queryUsersByOrg?orgId=') + orgId).then((response) => { |
|
||||
userGridRef.value.replaceRowsFun(response.data.content); |
|
||||
}); |
|
||||
dialogRef.value.hide(); |
|
||||
}); |
|
||||
}; |
|
||||
|
|
||||
const show = (param: object) => { |
|
||||
userGridRef = param.userGrid; |
|
||||
orgTreeGridRef = param.orgTreeGridRef; |
|
||||
const currentOrgId = orgTreeGridRef.value.getSelected()[0]; |
|
||||
|
|
||||
dialogRef.value.show(); |
|
||||
nextTick(() => { |
|
||||
axios.get(Environment.apiContextPath('/api/system/user/queryOtherUsersByOrg?orgId=') + currentOrgId).then((response) => { |
|
||||
gridRef.value.replaceRowsFun(response.data.content); |
|
||||
}); |
|
||||
}); |
|
||||
}; |
|
||||
|
|
||||
const hide = () => { |
|
||||
dialogRef.value.hide(); |
|
||||
}; |
|
||||
|
|
||||
defineExpose({ |
|
||||
show, |
|
||||
hide, |
|
||||
}); |
|
||||
</script> |
|
@ -0,0 +1,108 @@ |
|||||
|
<template> |
||||
|
<w-grid |
||||
|
ref="treeGridRef" |
||||
|
:tree="true" |
||||
|
:title="$t('system.shared.selectMenu.grid.title')" |
||||
|
dense-body |
||||
|
:fetch-data-url="fetchDataUrl + '?' + foreignKey + '=' + foreignValue" |
||||
|
selection="multiple" |
||||
|
:tree-icon=" |
||||
|
(row) => { |
||||
|
if (row.type === 'SEPARATOR') { |
||||
|
return { name: 'bi-dash-lg' }; |
||||
|
} else if (row.type === 'ROUTE_ACTION') { |
||||
|
return { name: 'sym_o_crop_16_9' }; |
||||
|
} else { |
||||
|
return { name: row.icon }; |
||||
|
} |
||||
|
} |
||||
|
" |
||||
|
:pageable="false" |
||||
|
:full-screen-button="false" |
||||
|
:toolbar-configure="{ noIcon: true }" |
||||
|
:toolbar-actions="[ |
||||
|
'refresh', |
||||
|
'separator', |
||||
|
{ |
||||
|
name: 'save', |
||||
|
label: $t('system.shared.selectMenu.grid.toolbar.save'), |
||||
|
click: (selecteds) => { |
||||
|
DialogManager.confirm($t('system.shared.selectMenu.grid.toolbar.save.tip'), () => { |
||||
|
const ids = Tools.extractProperties(selecteds, 'id'); |
||||
|
emit('update', ids, treeGridRef); |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
'separator', |
||||
|
'view', |
||||
|
]" |
||||
|
:columns="[ |
||||
|
{ |
||||
|
width: '100%', |
||||
|
name: 'titleI18nKey', |
||||
|
label: $t('name'), |
||||
|
sortable: false, |
||||
|
format: (value, row) => { |
||||
|
if (row.type === 'SEPARATOR') { |
||||
|
return `<hr style='width:100px'/>`; |
||||
|
} else if (row.type === 'ROUTE_ACTION') { |
||||
|
return $t(row.i18nKey); |
||||
|
} else { |
||||
|
return $t(value); |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
{ width: 100, name: 'enable', label: $t('status'), format: Formater.enableTag(), sortable: false }, |
||||
|
]" |
||||
|
:viewer="{ |
||||
|
panel: { |
||||
|
columnNum: 1, |
||||
|
fields: [ |
||||
|
{ name: 'id', label: $t('id') }, |
||||
|
{ name: 'type', label: $t('type') }, |
||||
|
{ name: 'name', label: $t('name') }, |
||||
|
{ name: 'titleI18nKey', label: $t('titleI18nKey') }, |
||||
|
{ name: 'icon', label: $t('icon') }, |
||||
|
{ name: 'enable', label: $t('enable') }, |
||||
|
{ name: 'order', label: $t('order') }, |
||||
|
{ name: 'javaScript', label: $t('javaScript') }, |
||||
|
{ name: 'url', label: $t('url') }, |
||||
|
{ name: 'urlOpenType', label: $t('urlOpenType') }, |
||||
|
{ name: 'routeName', label: $t('routeName') }, |
||||
|
{ name: 'routeQuery', label: $t('routeQuery') }, |
||||
|
|
||||
|
{ name: 'dataComeFrom', label: $t('dataComeFrom') }, |
||||
|
{ name: 'creator', label: $t('creator') }, |
||||
|
{ name: 'createDate', label: $t('createDate') }, |
||||
|
{ name: 'lastModifier', label: $t('lastModifier') }, |
||||
|
{ name: 'lastModifyDate', label: $t('lastModifyDate') }, |
||||
|
{ name: 'corporationCode', label: $t('corporationCode') }, |
||||
|
], |
||||
|
}, |
||||
|
}" |
||||
|
></w-grid> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref } from 'vue'; |
||||
|
import { DialogManager, Formater, Tools } from 'platform-core'; |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
fetchDataUrl: { type: String, default: '' }, |
||||
|
foreignKey: { type: String, default: '' }, |
||||
|
foreignValue: { type: String, default: '' }, |
||||
|
}); |
||||
|
|
||||
|
const emit = defineEmits<{ |
||||
|
(e: 'update', ids: string[], gridComponent: any): void; |
||||
|
}>(); |
||||
|
|
||||
|
const treeGridRef = ref(); |
||||
|
|
||||
|
const refresh = () => { |
||||
|
treeGridRef.value.refresh(); |
||||
|
}; |
||||
|
|
||||
|
defineExpose({ |
||||
|
refresh, |
||||
|
}); |
||||
|
</script> |
@ -0,0 +1,81 @@ |
|||||
|
<template> |
||||
|
<w-grid |
||||
|
ref="treeGridRef" |
||||
|
:tree="true" |
||||
|
:title="$t('system.shared.selectOrg.grid.title')" |
||||
|
dense-body |
||||
|
:fetch-data-url="fetchDataUrl + '?' + foreignKey + '=' + foreignValue" |
||||
|
selection="multiple" |
||||
|
:tree-icon=" |
||||
|
(row) => { |
||||
|
return { name: 'folder', color: 'amber' }; |
||||
|
} |
||||
|
" |
||||
|
:pageable="false" |
||||
|
:full-screen-button="false" |
||||
|
:toolbar-configure="{ noIcon: true }" |
||||
|
:toolbar-actions="[ |
||||
|
'refresh', |
||||
|
'separator', |
||||
|
{ |
||||
|
name: 'save', |
||||
|
label: $t('system.shared.selectOrg.grid.toolbar.save'), |
||||
|
click: (selecteds) => { |
||||
|
DialogManager.confirm($t('system.shared.selectOrg.grid.toolbar.save.tip'), () => { |
||||
|
const ids = Tools.extractProperties(selecteds, 'id'); |
||||
|
emit('update', ids, treeGridRef); |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
'separator', |
||||
|
'view', |
||||
|
]" |
||||
|
:columns="[ |
||||
|
{ width: '100%', name: 'name', label: $t('name') }, |
||||
|
{ width: 100, name: 'code', label: $t('code') }, |
||||
|
{ width: 60, name: 'enable', label: $t('status'), format: Formater.enableTag(), sortable: false }, |
||||
|
]" |
||||
|
:viewer="{ |
||||
|
panel: { |
||||
|
columnNum: 1, |
||||
|
fields: [ |
||||
|
{ name: 'id', label: $t('id') }, |
||||
|
{ name: 'code', label: $t('code') }, |
||||
|
{ name: 'name', label: $t('name') }, |
||||
|
{ name: 'description', label: $t('description') }, |
||||
|
{ name: 'enable', label: $t('enable') }, |
||||
|
{ name: 'dataComeFrom', label: $t('dataComeFrom') }, |
||||
|
{ name: 'creator', label: $t('creator') }, |
||||
|
{ name: 'createDate', label: $t('createDate') }, |
||||
|
{ name: 'lastModifier', label: $t('lastModifier') }, |
||||
|
{ name: 'lastModifyDate', label: $t('lastModifyDate') }, |
||||
|
{ name: 'corporationCode', label: $t('corporationCode') }, |
||||
|
], |
||||
|
}, |
||||
|
}" |
||||
|
></w-grid> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref } from 'vue'; |
||||
|
import { Environment, DialogManager, Formater, Tools } from 'platform-core'; |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
fetchDataUrl: { type: String, default: '' }, |
||||
|
foreignKey: { type: String, default: '' }, |
||||
|
foreignValue: { type: String, default: '' }, |
||||
|
}); |
||||
|
|
||||
|
const emit = defineEmits<{ |
||||
|
(e: 'update', ids: string[], gridComponent: any): void; |
||||
|
}>(); |
||||
|
|
||||
|
const treeGridRef = ref(); |
||||
|
|
||||
|
const refresh = () => { |
||||
|
treeGridRef.value.refresh(); |
||||
|
}; |
||||
|
|
||||
|
defineExpose({ |
||||
|
refresh, |
||||
|
}); |
||||
|
</script> |
@ -0,0 +1,102 @@ |
|||||
|
<template> |
||||
|
<w-dialog |
||||
|
ref="dialogRef" |
||||
|
:title="$t('system.shared.selectRole.dialog.title')" |
||||
|
width="800px" |
||||
|
height="500px" |
||||
|
:can-maximize="false" |
||||
|
:buttons="[ |
||||
|
{ |
||||
|
label: $t('confirm'), |
||||
|
click: () => { |
||||
|
const ids = Tools.extractProperties(gridRef.getSelectedRows(), 'id'); |
||||
|
emit('afterSelected', ids, dialogRef); |
||||
|
}, |
||||
|
}, |
||||
|
]" |
||||
|
> |
||||
|
<div class="px-2"> |
||||
|
<w-grid |
||||
|
ref="gridRef" |
||||
|
:title="$t('system.shared.selectRole.dialog.grid.title')" |
||||
|
selection="multiple" |
||||
|
:full-screen-button="false" |
||||
|
:toolbar-configure="{ noIcon: false }" |
||||
|
:toolbar-actions="['query', 'refresh']" |
||||
|
:query-form-fields="[ |
||||
|
{ name: 'code', label: $t('code'), type: 'text' }, |
||||
|
{ name: 'name', label: $t('name'), type: 'text' }, |
||||
|
{ |
||||
|
name: 'enable', |
||||
|
label: $t('enable'), |
||||
|
type: 'select', |
||||
|
options: Options.yesNo(), |
||||
|
queryOperator: 'equals', |
||||
|
}, |
||||
|
{ |
||||
|
name: 'dataComeFrom', |
||||
|
label: $t('dataComeFrom'), |
||||
|
type: 'select', |
||||
|
options: Options.enum(DataComeFromEnum), |
||||
|
queryOperator: 'equals', |
||||
|
}, |
||||
|
]" |
||||
|
:auto-fetch-data="false" |
||||
|
:fetch-data-url="fetchDataUrl + '?' + foreignKey + '=' + foreignValue" |
||||
|
:columns="[ |
||||
|
{ name: 'code', label: $t('code') }, |
||||
|
{ name: 'name', label: $t('name') }, |
||||
|
{ |
||||
|
name: 'status', |
||||
|
label: t('status'), |
||||
|
format: Formater.enableTag(), |
||||
|
}, |
||||
|
{ name: 'lastModifier', label: t('lastModifier') }, |
||||
|
{ name: 'lastModifyDate', label: t('lastModifyDate') }, |
||||
|
]" |
||||
|
></w-grid> |
||||
|
</div> |
||||
|
</w-dialog> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref, nextTick } from 'vue'; |
||||
|
import { useI18n } from 'vue-i18n'; |
||||
|
import { Environment, Tools, EnumTools, Options, Formater } from 'platform-core'; |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
opener: { type: Object, default: undefined }, |
||||
|
fetchDataUrl: { type: String, default: '' }, |
||||
|
foreignKey: { type: String, default: '' }, |
||||
|
foreignValue: { type: String, default: '' }, |
||||
|
}); |
||||
|
|
||||
|
const emit = defineEmits<{ |
||||
|
(e: 'afterSelected', ids: string[], dialogComponent: any): void; |
||||
|
}>(); |
||||
|
|
||||
|
const { t } = useI18n(); |
||||
|
|
||||
|
const dialogRef = ref(); |
||||
|
const gridRef = ref(); |
||||
|
const foreignKeyRef = ref(); |
||||
|
|
||||
|
const open = (foreignKey: string) => { |
||||
|
foreignKeyRef.value = foreignKey; |
||||
|
dialogRef.value.show(); |
||||
|
|
||||
|
nextTick(() => { |
||||
|
gridRef.value.refresh(); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const close = () => { |
||||
|
dialogRef.value.hide(); |
||||
|
}; |
||||
|
|
||||
|
defineExpose({ |
||||
|
open, |
||||
|
close, |
||||
|
}); |
||||
|
|
||||
|
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom'); |
||||
|
</script> |
@ -0,0 +1,138 @@ |
|||||
|
<template> |
||||
|
<w-grid |
||||
|
ref="gridRef" |
||||
|
:title="$t('system.shared.selectRole.grid.title')" |
||||
|
:fetch-data-url="fetchDataUrl + '?' + foreignKey + '=' + foreignValue" |
||||
|
:auto-fetch-data="false" |
||||
|
selection="multiple" |
||||
|
:full-screen-button="false" |
||||
|
:toolbar-configure="{ noIcon: true }" |
||||
|
:toolbar-actions="[ |
||||
|
'refresh', |
||||
|
'separator', |
||||
|
{ |
||||
|
name: 'addRoles', |
||||
|
label: $t('system.shared.selectRole.grid.toolbar.add'), |
||||
|
enableIf: () => { |
||||
|
return foreignValue ? true : false; |
||||
|
}, |
||||
|
click: () => { |
||||
|
dialogRef.open(foreignValue); |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
name: 'removeRoles', |
||||
|
label: $t('system.shared.selectRole.grid.toolbar.remove'), |
||||
|
enableIf: () => { |
||||
|
return foreignValue && gridRef?.getSelectedRows()?.length > 0; |
||||
|
}, |
||||
|
click: (selecteds) => { |
||||
|
const ids = Tools.extractProperties(selecteds, 'id'); |
||||
|
DialogManager.confirm($t('system.shared.selectRole.grid.toolbar.remove.tip'), () => { |
||||
|
emit('remove', ids, gridRef); |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
'separator', |
||||
|
{ |
||||
|
name: 'addAllRoles', |
||||
|
label: $t('system.shared.selectRole.grid.toolbar.addAll'), |
||||
|
enableIf: () => { |
||||
|
return foreignValue ? true : false; |
||||
|
}, |
||||
|
click: () => { |
||||
|
DialogManager.confirm($t('system.shared.selectRole.grid.toolbar.addAll.tip'), () => { |
||||
|
emit('addAll', gridRef); |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
name: 'removeAllRoles', |
||||
|
label: $t('system.shared.selectRole.grid.toolbar.removeAll'), |
||||
|
enableIf: () => { |
||||
|
return foreignValue && gridRef?.getRows()?.length > 0; |
||||
|
}, |
||||
|
click: () => { |
||||
|
DialogManager.confirm($t('system.shared.selectRole.grid.toolbar.removeAll.tip'), () => { |
||||
|
emit('removeAll', gridRef); |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
'separator', |
||||
|
'view', |
||||
|
]" |
||||
|
:columns="[ |
||||
|
{ width: 100, name: 'code', label: $t('code') }, |
||||
|
{ width: 100, name: 'name', label: $t('name') }, |
||||
|
{ |
||||
|
width: 60, |
||||
|
name: 'enable', |
||||
|
label: $t('status'), |
||||
|
format: Formater.enableTag(), |
||||
|
}, |
||||
|
]" |
||||
|
:viewer="{ |
||||
|
panel: { |
||||
|
columnNum: 1, |
||||
|
fields: [ |
||||
|
{ name: 'id', label: $t('id') }, |
||||
|
{ name: 'code', label: $t('code') }, |
||||
|
{ name: 'name', label: $t('name') }, |
||||
|
{ name: 'description', label: $t('description') }, |
||||
|
{ name: 'enable', label: $t('enable'), format: Formater.yesNo() }, |
||||
|
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) }, |
||||
|
{ name: 'creator', label: $t('creator') }, |
||||
|
{ name: 'createDate', label: $t('createDate') }, |
||||
|
{ name: 'lastModifier', label: $t('lastModifier') }, |
||||
|
{ name: 'lastModifyDate', label: $t('lastModifyDate') }, |
||||
|
{ name: 'corporationCode', label: $t('corporationCode') }, |
||||
|
], |
||||
|
}, |
||||
|
}" |
||||
|
></w-grid> |
||||
|
<SelectRoleDialog |
||||
|
ref="dialogRef" |
||||
|
:opener="gridRef" |
||||
|
:fetch-data-url="fetchOtherDataUrl" |
||||
|
:foreign-key="foreignKey" |
||||
|
:foreign-value="foreignValue" |
||||
|
@after-selected=" |
||||
|
(ids: string[]) => { |
||||
|
emit('add', ids, gridRef, dialogRef); |
||||
|
} |
||||
|
" |
||||
|
></SelectRoleDialog> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref, nextTick } from 'vue'; |
||||
|
import { useI18n } from 'vue-i18n'; |
||||
|
import { Environment, axios, EnumTools, NotifyManager, DialogManager, Formater, Options, Tools, OperatorTypeEnum } from 'platform-core'; |
||||
|
import SelectRoleDialog from './SelectRoleDialog.vue'; |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
fetchDataUrl: { type: String, default: '' }, |
||||
|
fetchOtherDataUrl: { type: String, default: '' }, |
||||
|
foreignKey: { type: String, default: '' }, |
||||
|
foreignValue: { type: String, default: '' }, |
||||
|
}); |
||||
|
|
||||
|
const emit = defineEmits<{ |
||||
|
(e: 'add', ids: string[], gridComponent: any, dialogComponent: any): void; |
||||
|
(e: 'remove', ids: string[], gridComponent: any): void; |
||||
|
(e: 'addAll', gridComponent: any): void; |
||||
|
(e: 'removeAll', gridComponent: any): void; |
||||
|
}>(); |
||||
|
|
||||
|
const gridRef = ref(); |
||||
|
const dialogRef = ref(); |
||||
|
|
||||
|
const refresh = () => { |
||||
|
gridRef.value.refresh(); |
||||
|
}; |
||||
|
|
||||
|
defineExpose({ |
||||
|
refresh, |
||||
|
}); |
||||
|
|
||||
|
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom'); |
||||
|
</script> |
@ -0,0 +1,106 @@ |
|||||
|
<template> |
||||
|
<w-dialog |
||||
|
ref="dialogRef" |
||||
|
:title="$t('system.shared.selectUser.dialog.title')" |
||||
|
width="800px" |
||||
|
height="500px" |
||||
|
:can-maximize="false" |
||||
|
:buttons="[ |
||||
|
{ |
||||
|
label: $t('confirm'), |
||||
|
click: () => { |
||||
|
const ids = Tools.extractProperties(gridRef.getSelectedRows(), 'id'); |
||||
|
emit('afterSelected', ids, dialogRef); |
||||
|
}, |
||||
|
}, |
||||
|
]" |
||||
|
> |
||||
|
<div class="px-2"> |
||||
|
<w-grid |
||||
|
ref="gridRef" |
||||
|
:title="$t('system.shared.selectUser.dialog.grid.title')" |
||||
|
selection="multiple" |
||||
|
:full-screen-button="false" |
||||
|
:toolbar-configure="{ noIcon: false }" |
||||
|
:toolbar-actions="['query', 'refresh']" |
||||
|
:query-form-fields="[ |
||||
|
{ name: 'loginName', label: $t('loginName'), type: 'text' }, |
||||
|
{ name: 'userName', label: $t('userName'), type: 'text' }, |
||||
|
{ |
||||
|
name: 'enable', |
||||
|
label: $t('enable'), |
||||
|
type: 'select', |
||||
|
options: Options.yesNo(), |
||||
|
queryOperator: 'equals', |
||||
|
}, |
||||
|
{ |
||||
|
name: 'dataComeFrom', |
||||
|
label: $t('dataComeFrom'), |
||||
|
type: 'select', |
||||
|
options: Options.enum(DataComeFromEnum), |
||||
|
queryOperator: 'equals', |
||||
|
}, |
||||
|
]" |
||||
|
:auto-fetch-data="false" |
||||
|
:fetch-data-url="fetchDataUrl + '?' + foreignKey + '=' + foreignValue" |
||||
|
:columns="[ |
||||
|
{ width: 100, name: 'loginName', label: t('loginName') }, |
||||
|
{ width: 100, name: 'userName', label: t('userName') }, |
||||
|
{ |
||||
|
name: 'status', |
||||
|
label: $t('status'), |
||||
|
format: (value, row) => { |
||||
|
return { |
||||
|
componentType: UserStatusTag, |
||||
|
attrs: row, |
||||
|
}; |
||||
|
}, |
||||
|
}, |
||||
|
]" |
||||
|
></w-grid> |
||||
|
</div> |
||||
|
</w-dialog> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref, nextTick } from 'vue'; |
||||
|
import { useI18n } from 'vue-i18n'; |
||||
|
import { Environment, Tools, EnumTools, Options, Formater } from 'platform-core'; |
||||
|
import UserStatusTag from './UserStatusTag.vue'; |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
opener: { type: Object, default: undefined }, |
||||
|
fetchDataUrl: { type: String, default: '' }, |
||||
|
foreignKey: { type: String, default: '' }, |
||||
|
foreignValue: { type: String, default: '' }, |
||||
|
}); |
||||
|
|
||||
|
const emit = defineEmits<{ |
||||
|
(e: 'afterSelected', ids: string[], dialogComponent: any): void; |
||||
|
}>(); |
||||
|
|
||||
|
const { t } = useI18n(); |
||||
|
|
||||
|
const dialogRef = ref(); |
||||
|
const gridRef = ref(); |
||||
|
const foreignKeyRef = ref(); |
||||
|
|
||||
|
const open = (foreignKey: string) => { |
||||
|
foreignKeyRef.value = foreignKey; |
||||
|
dialogRef.value.show(); |
||||
|
|
||||
|
nextTick(() => { |
||||
|
gridRef.value.refresh(); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
const close = () => { |
||||
|
dialogRef.value.hide(); |
||||
|
}; |
||||
|
|
||||
|
defineExpose({ |
||||
|
open, |
||||
|
close, |
||||
|
}); |
||||
|
|
||||
|
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom'); |
||||
|
</script> |
@ -0,0 +1,150 @@ |
|||||
|
<template> |
||||
|
<w-grid |
||||
|
ref="gridRef" |
||||
|
:title="$t('system.shared.selectUser.grid.title')" |
||||
|
:fetch-data-url="fetchDataUrl + '?' + foreignKey + '=' + foreignValue" |
||||
|
:auto-fetch-data="false" |
||||
|
selection="multiple" |
||||
|
:full-screen-button="false" |
||||
|
:toolbar-configure="{ noIcon: true }" |
||||
|
:toolbar-actions="[ |
||||
|
'refresh', |
||||
|
'separator', |
||||
|
{ |
||||
|
name: 'addUsers', |
||||
|
label: $t('system.shared.selectUser.grid.toolbar.add'), |
||||
|
enableIf: () => { |
||||
|
return foreignValue ? true : false; |
||||
|
}, |
||||
|
click: () => { |
||||
|
dialogRef.open(foreignValue); |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
name: 'removeUsers', |
||||
|
label: $t('system.shared.selectUser.grid.toolbar.remove'), |
||||
|
enableIf: () => { |
||||
|
return foreignValue && gridRef?.getSelectedRows()?.length > 0; |
||||
|
}, |
||||
|
click: (selecteds) => { |
||||
|
const ids = Tools.extractProperties(selecteds, 'id'); |
||||
|
DialogManager.confirm($t('system.shared.selectUser.grid.toolbar.remove.tip'), () => { |
||||
|
emit('remove', ids, gridRef); |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
'separator', |
||||
|
{ |
||||
|
name: 'addAllUsers', |
||||
|
label: $t('system.shared.selectUser.grid.toolbar.addAll'), |
||||
|
enableIf: () => { |
||||
|
return foreignValue ? true : false; |
||||
|
}, |
||||
|
click: () => { |
||||
|
DialogManager.confirm($t('system.shared.selectUser.grid.toolbar.addAll.tip'), () => { |
||||
|
emit('addAll', gridRef); |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
name: 'removeAllUsers', |
||||
|
label: $t('system.shared.selectUser.grid.toolbar.removeAll'), |
||||
|
enableIf: () => { |
||||
|
return foreignValue && gridRef?.getRows()?.length > 0; |
||||
|
}, |
||||
|
click: () => { |
||||
|
DialogManager.confirm($t('system.shared.selectUser.grid.toolbar.removeAll.tip'), () => { |
||||
|
emit('removeAll', gridRef); |
||||
|
}); |
||||
|
}, |
||||
|
}, |
||||
|
'separator', |
||||
|
'view', |
||||
|
]" |
||||
|
:columns="[ |
||||
|
{ width: 100, name: 'loginName', label: $t('loginName') }, |
||||
|
{ width: 100, name: 'userName', label: $t('userName') }, |
||||
|
{ |
||||
|
name: 'enable', |
||||
|
label: $t('status'), |
||||
|
format: (value, row) => { |
||||
|
return { |
||||
|
componentType: UserStatusTag, |
||||
|
attrs: row, |
||||
|
}; |
||||
|
}, |
||||
|
}, |
||||
|
]" |
||||
|
:viewer="{ |
||||
|
panel: { |
||||
|
columnNum: 1, |
||||
|
fields: [ |
||||
|
{ name: 'id', label: $t('id') }, |
||||
|
{ name: 'loginName', label: $t('loginName') }, |
||||
|
{ name: 'userName', label: $t('userName') }, |
||||
|
{ name: 'description', label: $t('description') }, |
||||
|
{ name: 'enable', label: $t('enable'), format: Formater.yesNo() }, |
||||
|
{ name: 'accountExpired', label: $t('accountExpired'), format: Formater.yesNo() }, |
||||
|
{ name: 'accountLocked', label: $t('accountLocked'), format: Formater.yesNo() }, |
||||
|
{ name: 'credentialsExpired', label: $t('credentialsExpired'), format: Formater.yesNo() }, |
||||
|
{ name: 'email', label: $t('email') }, |
||||
|
{ name: 'phone', label: $t('phone') }, |
||||
|
{ name: 'mobile', label: $t('mobile') }, |
||||
|
{ name: 'weixin', label: $t('weixin') }, |
||||
|
{ name: 'qq', label: $t('qq') }, |
||||
|
{ name: 'dataComeFrom', label: $t('dataComeFrom'), format: Formater.enum(DataComeFromEnum) }, |
||||
|
{ name: 'creator', label: $t('creator') }, |
||||
|
{ name: 'createDate', label: $t('createDate') }, |
||||
|
{ name: 'lastModifier', label: $t('lastModifier') }, |
||||
|
{ name: 'lastModifyDate', label: $t('lastModifyDate') }, |
||||
|
{ name: 'corporationCode', label: $t('corporationCode') }, |
||||
|
], |
||||
|
}, |
||||
|
}" |
||||
|
></w-grid> |
||||
|
<SelectUserDialog |
||||
|
ref="dialogRef" |
||||
|
:opener="gridRef" |
||||
|
:fetch-data-url="fetchOtherDataUrl" |
||||
|
:foreign-key="foreignKey" |
||||
|
:foreign-value="foreignValue" |
||||
|
@after-selected=" |
||||
|
(ids: string[]) => { |
||||
|
emit('add', ids, gridRef, dialogRef); |
||||
|
} |
||||
|
" |
||||
|
></SelectUserDialog> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
import { ref } from 'vue'; |
||||
|
import { EnumTools, DialogManager, Formater, Tools } from 'platform-core'; |
||||
|
import SelectUserDialog from './SelectUserDialog.vue'; |
||||
|
import UserStatusTag from './UserStatusTag.vue'; |
||||
|
|
||||
|
const props = defineProps({ |
||||
|
fetchDataUrl: { type: String, default: '' }, |
||||
|
fetchOtherDataUrl: { type: String, default: '' }, |
||||
|
foreignKey: { type: String, default: '' }, |
||||
|
foreignValue: { type: String, default: '' }, |
||||
|
}); |
||||
|
|
||||
|
const emit = defineEmits<{ |
||||
|
(e: 'add', ids: string[], gridComponent: any, dialogComponent: any): void; |
||||
|
(e: 'remove', ids: string[], gridComponent: any): void; |
||||
|
(e: 'addAll', gridComponent: any): void; |
||||
|
(e: 'removeAll', gridComponent: any): void; |
||||
|
}>(); |
||||
|
|
||||
|
const gridRef = ref(); |
||||
|
const dialogRef = ref(); |
||||
|
|
||||
|
const refresh = () => { |
||||
|
gridRef.value.refresh(); |
||||
|
}; |
||||
|
|
||||
|
defineExpose({ |
||||
|
refresh, |
||||
|
}); |
||||
|
|
||||
|
const DataComeFromEnum = await EnumTools.fetch('io.sc.platform.orm.api.enums.DataComeFrom'); |
||||
|
</script> |
@ -0,0 +1,17 @@ |
|||||
|
<template> |
||||
|
<div> |
||||
|
<q-chip v-if="enable && !accountExpired && !accountLocked && !credentialsExpired" color="green" text-color="white" :label="$t('normal')" dense></q-chip> |
||||
|
<q-chip v-if="!enable" color="red" text-color="white" :label="$t('disable')" dense></q-chip> |
||||
|
<q-chip v-if="accountExpired" color="red" text-color="white" :label="$t('accountExpired')" dense></q-chip> |
||||
|
<q-chip v-if="accountLocked" color="red" text-color="white" :label="$t('accountLocked')" dense></q-chip> |
||||
|
<q-chip v-if="credentialsExpired" color="red" text-color="white" :label="$t('credentialsExpired')" dense></q-chip> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script setup lang="ts"> |
||||
|
const props = defineProps({ |
||||
|
enable: { type: Boolean, default: true }, |
||||
|
accountExpired: { type: Boolean, default: false }, |
||||
|
accountLocked: { type: Boolean, default: false }, |
||||
|
credentialsExpired: { type: Boolean, default: false }, |
||||
|
}); |
||||
|
</script> |
@ -1,15 +1,64 @@ |
|||||
package io.sc.platform.system.corporation.controller; |
package io.sc.platform.system.corporation.controller; |
||||
|
|
||||
import io.sc.platform.mvc.controller.support.RestCrudController; |
import io.sc.platform.mvc.controller.support.RestCrudController; |
||||
|
import io.sc.platform.mvc.support.One2Many; |
||||
import io.sc.platform.system.api.corporation.CorporationVo; |
import io.sc.platform.system.api.corporation.CorporationVo; |
||||
import io.sc.platform.system.corporation.jpa.entity.CorporationEntity; |
import io.sc.platform.system.corporation.jpa.entity.CorporationEntity; |
||||
import io.sc.platform.system.corporation.jpa.repository.CorporationRepository; |
import io.sc.platform.system.corporation.jpa.repository.CorporationRepository; |
||||
import io.sc.platform.system.corporation.service.CorporationService; |
import io.sc.platform.system.corporation.service.CorporationService; |
||||
|
import org.springframework.web.bind.annotation.PostMapping; |
||||
|
import org.springframework.web.bind.annotation.RequestBody; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RestController; |
import org.springframework.web.bind.annotation.RestController; |
||||
|
|
||||
@RestController |
@RestController |
||||
@RequestMapping("api/system/corporation") |
@RequestMapping("api/system/corporation") |
||||
public class CorporationWebController extends RestCrudController<CorporationVo,CorporationEntity,String,CorporationRepository, CorporationService> { |
public class CorporationWebController extends RestCrudController<CorporationVo,CorporationEntity,String,CorporationRepository, CorporationService> { |
||||
|
/** |
||||
|
* 给法人添加用户 |
||||
|
* @param wrapper 一对多关系(ID关系)封装器, one: 代表法人代码, many: 代表用户ID集合 |
||||
|
* @throws Exception 违例 |
||||
|
*/ |
||||
|
@PostMapping("addUsers") |
||||
|
public void addCorporations(@RequestBody One2Many<String,String> wrapper) throws Exception{ |
||||
|
if(wrapper!=null){ |
||||
|
service.addUsers(wrapper.getOne(),wrapper.getMany()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 给法人添加所有用户 |
||||
|
* @param wrapper 一对多关系(ID关系)封装器, one: 代表法人代码, many: 空 |
||||
|
* @throws Exception 违例 |
||||
|
*/ |
||||
|
@PostMapping("addAllUsers") |
||||
|
public void addAllUsers(@RequestBody One2Many<String,String> wrapper) throws Exception{ |
||||
|
if(wrapper!=null){ |
||||
|
service.addAllUsers(wrapper.getOne()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 移除法人下的用户 |
||||
|
* @param wrapper 一对多关系(ID关系)封装器, one: 代表法人代码, many: 代表用户ID集合 |
||||
|
* @throws Exception 违例 |
||||
|
*/ |
||||
|
@PostMapping("removeUsers") |
||||
|
public void removeUsers(@RequestBody One2Many<String,String> wrapper) throws Exception{ |
||||
|
if(wrapper!=null){ |
||||
|
service.removeUsers(wrapper.getOne(),wrapper.getMany()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 移除法人下的所有用户 |
||||
|
* @param wrapper 一对多关系(ID关系)封装器, one: 代表法人代码, many: 空 |
||||
|
* @throws Exception 违例 |
||||
|
*/ |
||||
|
@PostMapping("removeAllUsers") |
||||
|
public void removeAllUsers(@RequestBody One2Many<String,String> wrapper) throws Exception{ |
||||
|
if(wrapper!=null){ |
||||
|
service.removeAllUsers(wrapper.getOne()); |
||||
|
} |
||||
|
} |
||||
} |
} |
||||
|
@ -1,12 +1,59 @@ |
|||||
package io.sc.platform.system.corporation.service.impl; |
package io.sc.platform.system.corporation.service.impl; |
||||
|
|
||||
|
import io.sc.platform.orm.api.vo.CorporationAuditorVo; |
||||
import io.sc.platform.orm.service.impl.DaoServiceImpl; |
import io.sc.platform.orm.service.impl.DaoServiceImpl; |
||||
import io.sc.platform.system.corporation.jpa.entity.CorporationEntity; |
import io.sc.platform.system.corporation.jpa.entity.CorporationEntity; |
||||
import io.sc.platform.system.corporation.jpa.repository.CorporationRepository; |
import io.sc.platform.system.corporation.jpa.repository.CorporationRepository; |
||||
import io.sc.platform.system.corporation.service.CorporationService; |
import io.sc.platform.system.corporation.service.CorporationService; |
||||
|
import org.springframework.beans.factory.annotation.Autowired; |
||||
|
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; |
||||
import org.springframework.stereotype.Service; |
import org.springframework.stereotype.Service; |
||||
|
import org.springframework.util.StringUtils; |
||||
|
|
||||
|
import java.util.HashMap; |
||||
|
import java.util.Map; |
||||
|
import java.util.Set; |
||||
|
|
||||
@Service |
@Service |
||||
public class CorporationServiceImpl extends DaoServiceImpl<CorporationEntity, String, CorporationRepository> implements CorporationService { |
public class CorporationServiceImpl extends DaoServiceImpl<CorporationEntity, String, CorporationRepository> implements CorporationService { |
||||
|
@Autowired private NamedParameterJdbcTemplate namedParameterJdbcTemplate; |
||||
|
|
||||
|
@Override |
||||
|
public void addUsers(String corporationCode, Set<String> userIds) throws Exception { |
||||
|
if(StringUtils.hasText(corporationCode) && userIds!=null && !userIds.isEmpty()){ |
||||
|
Map<String, Object> params = new HashMap<String, Object>(); |
||||
|
params.put("corporationCode", corporationCode); |
||||
|
params.put("userIds", userIds); |
||||
|
namedParameterJdbcTemplate.update("update SYS_USER set CORP_CODE_=:corporationCode where ID_ in (:userIds)",params); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void addAllUsers(String corporationCode) throws Exception { |
||||
|
if(StringUtils.hasText(corporationCode)) { |
||||
|
Map<String, Object> params = new HashMap<String, Object>(); |
||||
|
params.put("corporationCode", corporationCode); |
||||
|
namedParameterJdbcTemplate.update("update SYS_USER set CORP_CODE_=:corporationCode", params); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void removeUsers(String corporationCode, Set<String> userIds) throws Exception { |
||||
|
if(StringUtils.hasText(corporationCode) && userIds!=null && !userIds.isEmpty()){ |
||||
|
Map<String, Object> params = new HashMap<String, Object>(); |
||||
|
params.put("defaultCorporationCode", CorporationAuditorVo.DEFAULT_CODE); |
||||
|
params.put("userIds", userIds); |
||||
|
namedParameterJdbcTemplate.update("update SYS_USER set CORP_CODE_=:defaultCorporationCode where ID_ in (:userIds)",params); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public void removeAllUsers(String corporationCode) throws Exception { |
||||
|
if(StringUtils.hasText(corporationCode)) { |
||||
|
Map<String, Object> params = new HashMap<String, Object>(); |
||||
|
params.put("defaultCorporationCode", CorporationAuditorVo.DEFAULT_CODE); |
||||
|
params.put("corporationCode", corporationCode); |
||||
|
namedParameterJdbcTemplate.update("update SYS_USER set CORP_CODE_=:defaultCorporationCode where CORP_CODE_=:corporationCode",params); |
||||
|
} |
||||
|
} |
||||
} |
} |
||||
|
@ -0,0 +1,26 @@ |
|||||
|
package io.sc.platform.system.menu.jpa.entity; |
||||
|
|
||||
|
import io.sc.platform.system.api.menu.MenuSeparatorVo; |
||||
|
import io.sc.platform.system.api.menu.MenuVo; |
||||
|
|
||||
|
import javax.persistence.DiscriminatorValue; |
||||
|
import javax.persistence.Entity; |
||||
|
|
||||
|
/** |
||||
|
* 分隔符菜单项实体类 |
||||
|
*/ |
||||
|
@Entity |
||||
|
@DiscriminatorValue("SEPARATOR") |
||||
|
public class MenuSeparatorEntity extends MenuEntity { |
||||
|
public MenuSeparatorEntity() {} |
||||
|
public MenuSeparatorEntity(String id) { |
||||
|
this.id =id; |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public MenuVo toVo() { |
||||
|
MenuSeparatorVo vo =new MenuSeparatorVo(); |
||||
|
super.toVo(vo); |
||||
|
return vo; |
||||
|
} |
||||
|
} |
@ -1,27 +0,0 @@ |
|||||
package io.sc.platform.system.menu.jpa.entity; |
|
||||
|
|
||||
import io.sc.platform.system.api.menu.MenuRouteVo; |
|
||||
import io.sc.platform.system.api.menu.MenuSeperatorVo; |
|
||||
import io.sc.platform.system.api.menu.MenuVo; |
|
||||
|
|
||||
import javax.persistence.DiscriminatorValue; |
|
||||
import javax.persistence.Entity; |
|
||||
|
|
||||
/** |
|
||||
* 分隔符菜单项实体类 |
|
||||
*/ |
|
||||
@Entity |
|
||||
@DiscriminatorValue("SEPERATOR") |
|
||||
public class MenuSeperatorEntity extends MenuEntity { |
|
||||
public MenuSeperatorEntity() {} |
|
||||
public MenuSeperatorEntity(String id) { |
|
||||
this.id =id; |
|
||||
} |
|
||||
|
|
||||
@Override |
|
||||
public MenuVo toVo() { |
|
||||
MenuSeperatorVo vo =new MenuSeperatorVo(); |
|
||||
MenuEntity.toVo(vo,this); |
|
||||
return vo; |
|
||||
} |
|
||||
} |
|
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue