简单适配手机端:
1. 工作台招呼语一行显示,多余显示省略号 2. 查询框宽度统一,需手动调整(强迫症建议) 3. 分页符更新,电脑端与手机端分页功能不同 4. 表格工具栏更新,手机端取消文字显示 5. 表格操作按钮多的时候自动叠起
16
README.md
@ -96,6 +96,14 @@ github地址:https://github.com/vvandk/kinit 👩👦👦
|
|||||||
|
|
||||||
- [x] 手机验证码登录功能
|
- [x] 手机验证码登录功能
|
||||||
|
|
||||||
|
- [x] 简单适配手机端:
|
||||||
|
|
||||||
|
1. 工作台招呼语一行显示,多余显示省略号
|
||||||
|
2. 查询框宽度统一,需手动调整(强迫症建议)
|
||||||
|
3. 分页符更新,电脑端与手机端分页功能不同
|
||||||
|
4. 表格工具栏更新,手机端取消文字显示
|
||||||
|
5. 表格操作按钮多的时候自动叠起
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
- [ ] 考虑支持多机部署方案,如果接口使用多机,那么用户是否支持统一认证
|
- [ ] 考虑支持多机部署方案,如果接口使用多机,那么用户是否支持统一认证
|
||||||
@ -308,6 +316,12 @@ pnpm run build:pro
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
BIN
images/1.png
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 75 KiB |
BIN
images/2.png
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 84 KiB |
BIN
images/3.png
Before Width: | Height: | Size: 865 KiB After Width: | Height: | Size: 84 KiB |
BIN
images/4.png
Before Width: | Height: | Size: 97 KiB After Width: | Height: | Size: 67 KiB |
BIN
images/5.png
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 75 KiB |
BIN
images/6.jpg
Normal file
After Width: | Height: | Size: 95 KiB |
BIN
images/7.jpg
Normal file
After Width: | Height: | Size: 24 KiB |
BIN
images/8.jpg
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
images/9.jpg
Normal file
After Width: | Height: | Size: 21 KiB |
@ -14,6 +14,9 @@ import { useIcon } from '@/hooks/web/useIcon'
|
|||||||
import { ref, PropType } from 'vue'
|
import { ref, PropType } from 'vue'
|
||||||
import { propTypes } from '@/utils/propTypes'
|
import { propTypes } from '@/utils/propTypes'
|
||||||
import draggable from 'vuedraggable'
|
import draggable from 'vuedraggable'
|
||||||
|
import { useAppStore } from '@/store/modules/app'
|
||||||
|
|
||||||
|
const appStore = useAppStore()
|
||||||
|
|
||||||
const emit = defineEmits(['getList', 'update:tableSize'])
|
const emit = defineEmits(['getList', 'update:tableSize'])
|
||||||
|
|
||||||
@ -57,16 +60,20 @@ const handleCheckChange = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
handleCheckChange()
|
handleCheckChange()
|
||||||
|
|
||||||
|
const mobile = appStore.getMobile
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<ElRow :gutter="10">
|
<ElRow :gutter="10">
|
||||||
<ElCol :span="1.5">
|
<ElCol :span="1.5">
|
||||||
<ElButton link :icon="refresh" @click="handleClickRefresh">刷新数据</ElButton>
|
<ElButton link :icon="refresh" @click="handleClickRefresh">{{
|
||||||
|
mobile ? '' : '刷新数据'
|
||||||
|
}}</ElButton>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
<ElCol :span="1.5" class="pt-4px">
|
<ElCol :span="1.5" class="pt-4px">
|
||||||
<ElDropdown trigger="click" @command="handleCommand">
|
<ElDropdown trigger="click" @command="handleCommand">
|
||||||
<ElButton link :icon="spacing">密度调整</ElButton>
|
<ElButton link :icon="spacing">{{ mobile ? '' : '密度调整' }}</ElButton>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<ElDropdownMenu>
|
<ElDropdownMenu>
|
||||||
<ElDropdownItem command="default">默认</ElDropdownItem>
|
<ElDropdownItem command="default">默认</ElDropdownItem>
|
||||||
@ -104,7 +111,7 @@ handleCheckChange()
|
|||||||
</draggable>
|
</draggable>
|
||||||
</ElScrollbar>
|
</ElScrollbar>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<ElButton link :icon="settings">字段设置</ElButton>
|
<ElButton link :icon="settings">{{ mobile ? '' : '字段设置' }}</ElButton>
|
||||||
</template>
|
</template>
|
||||||
</ElPopover>
|
</ElPopover>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
|
@ -8,7 +8,7 @@ import { useForm } from '@/hooks/web/useForm'
|
|||||||
import { findIndex } from '@/utils'
|
import { findIndex } from '@/utils'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
import { set } from 'lodash-es'
|
import { set } from 'lodash-es'
|
||||||
import { FormSchema } from '@/types/form'
|
import { FormSchema, FormSetPropsType } from '@/types/form'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
|
@ -7,6 +7,10 @@ import { getSlot } from '@/utils/tsxHelper'
|
|||||||
import type { TableProps } from './types'
|
import type { TableProps } from './types'
|
||||||
import { set } from 'lodash-es'
|
import { set } from 'lodash-es'
|
||||||
import { TableColumn, TableSlotDefault, Pagination, TableSetPropsType } from '../../../types/table'
|
import { TableColumn, TableSlotDefault, Pagination, TableSetPropsType } from '../../../types/table'
|
||||||
|
import { useAppStore } from '@/store/modules/app'
|
||||||
|
|
||||||
|
const appStore = useAppStore()
|
||||||
|
const mobile = appStore.getMobile
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'Table',
|
name: 'Table',
|
||||||
@ -112,7 +116,9 @@ export default defineComponent({
|
|||||||
small: false,
|
small: false,
|
||||||
background: false,
|
background: false,
|
||||||
pagerCount: 7,
|
pagerCount: 7,
|
||||||
layout: 'sizes, prev, pager, next, jumper, ->, total',
|
layout: mobile
|
||||||
|
? 'prev, pager, next, ->, total'
|
||||||
|
: 'sizes, prev, pager, next, jumper, ->, total',
|
||||||
limits: [10, 20, 30, 40, 50, 100],
|
limits: [10, 20, 30, 40, 50, 100],
|
||||||
disabled: false,
|
disabled: false,
|
||||||
hideOnSinglePage: false,
|
hideOnSinglePage: false,
|
||||||
|
@ -113,8 +113,8 @@ const user = wsCache.get(appStore.getUserInfo)
|
|||||||
alt=""
|
alt=""
|
||||||
class="w-70px h-70px rounded-[50%] mr-20px"
|
class="w-70px h-70px rounded-[50%] mr-20px"
|
||||||
/>
|
/>
|
||||||
<div>
|
<div class="truncate">
|
||||||
<div class="text-20px text-700">
|
<div class="text-20px text-700 truncate">
|
||||||
{{ t('workplace.goodMorning') }},{{ user.name }},{{ t('workplace.happyDay') }}
|
{{ t('workplace.goodMorning') }},{{ user.name }},{{ t('workplace.happyDay') }}
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-10px text-14px text-gray-500">
|
<div class="mt-10px text-14px text-gray-500">
|
||||||
|
@ -1,310 +0,0 @@
|
|||||||
import { EChartsOption } from 'echarts'
|
|
||||||
import { EChartsOption as EChartsWordOption } from 'echarts-wordcloud'
|
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
|
||||||
|
|
||||||
export const lineOptions: EChartsOption = {
|
|
||||||
title: {
|
|
||||||
text: t('analysis.monthlySales'),
|
|
||||||
left: 'center'
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
data: [
|
|
||||||
t('analysis.january'),
|
|
||||||
t('analysis.february'),
|
|
||||||
t('analysis.march'),
|
|
||||||
t('analysis.april'),
|
|
||||||
t('analysis.may'),
|
|
||||||
t('analysis.june'),
|
|
||||||
t('analysis.july'),
|
|
||||||
t('analysis.august'),
|
|
||||||
t('analysis.september'),
|
|
||||||
t('analysis.october'),
|
|
||||||
t('analysis.november'),
|
|
||||||
t('analysis.december')
|
|
||||||
],
|
|
||||||
boundaryGap: false,
|
|
||||||
axisTick: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
grid: {
|
|
||||||
left: 20,
|
|
||||||
right: 20,
|
|
||||||
bottom: 20,
|
|
||||||
top: 80,
|
|
||||||
containLabel: true
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
axisPointer: {
|
|
||||||
type: 'cross'
|
|
||||||
},
|
|
||||||
padding: [5, 10]
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
axisTick: {
|
|
||||||
show: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
data: [t('analysis.estimate'), t('analysis.actual')],
|
|
||||||
top: 50
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: t('analysis.estimate'),
|
|
||||||
smooth: true,
|
|
||||||
type: 'line',
|
|
||||||
data: [100, 120, 161, 134, 105, 160, 165, 114, 163, 185, 118, 123],
|
|
||||||
animationDuration: 2800,
|
|
||||||
animationEasing: 'cubicInOut'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: t('analysis.actual'),
|
|
||||||
smooth: true,
|
|
||||||
type: 'line',
|
|
||||||
itemStyle: {},
|
|
||||||
data: [120, 82, 91, 154, 162, 140, 145, 250, 134, 56, 99, 123],
|
|
||||||
animationDuration: 2800,
|
|
||||||
animationEasing: 'quadraticOut'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
export const pieOptions: EChartsOption = {
|
|
||||||
title: {
|
|
||||||
text: t('analysis.userAccessSource'),
|
|
||||||
left: 'center'
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'item',
|
|
||||||
formatter: '{a} <br/>{b} : {c} ({d}%)'
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
orient: 'vertical',
|
|
||||||
left: 'left',
|
|
||||||
data: [
|
|
||||||
t('analysis.directAccess'),
|
|
||||||
t('analysis.mailMarketing'),
|
|
||||||
t('analysis.allianceAdvertising'),
|
|
||||||
t('analysis.videoAdvertising'),
|
|
||||||
t('analysis.searchEngines')
|
|
||||||
]
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: t('analysis.userAccessSource'),
|
|
||||||
type: 'pie',
|
|
||||||
radius: '55%',
|
|
||||||
center: ['50%', '60%'],
|
|
||||||
data: [
|
|
||||||
{ value: 335, name: t('analysis.directAccess') },
|
|
||||||
{ value: 310, name: t('analysis.mailMarketing') },
|
|
||||||
{ value: 234, name: t('analysis.allianceAdvertising') },
|
|
||||||
{ value: 135, name: t('analysis.videoAdvertising') },
|
|
||||||
{ value: 1548, name: t('analysis.searchEngines') }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
export const barOptions: EChartsOption = {
|
|
||||||
title: {
|
|
||||||
text: t('analysis.weeklyUserActivity'),
|
|
||||||
left: 'center'
|
|
||||||
},
|
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
axisPointer: {
|
|
||||||
type: 'shadow'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
grid: {
|
|
||||||
left: 50,
|
|
||||||
right: 20,
|
|
||||||
bottom: 20
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
type: 'category',
|
|
||||||
data: [
|
|
||||||
t('analysis.monday'),
|
|
||||||
t('analysis.tuesday'),
|
|
||||||
t('analysis.wednesday'),
|
|
||||||
t('analysis.thursday'),
|
|
||||||
t('analysis.friday'),
|
|
||||||
t('analysis.saturday'),
|
|
||||||
t('analysis.sunday')
|
|
||||||
],
|
|
||||||
axisTick: {
|
|
||||||
alignWithLabel: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
type: 'value'
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: t('analysis.activeQuantity'),
|
|
||||||
data: [13253, 34235, 26321, 12340, 24643, 1322, 1324],
|
|
||||||
type: 'bar'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
export const radarOption: EChartsOption = {
|
|
||||||
legend: {
|
|
||||||
data: [t('workplace.personal'), t('workplace.team')]
|
|
||||||
},
|
|
||||||
radar: {
|
|
||||||
// shape: 'circle',
|
|
||||||
indicator: [
|
|
||||||
{ name: t('workplace.quote'), max: 65 },
|
|
||||||
{ name: t('workplace.contribution'), max: 160 },
|
|
||||||
{ name: t('workplace.hot'), max: 300 },
|
|
||||||
{ name: t('workplace.yield'), max: 130 },
|
|
||||||
{ name: t('workplace.follow'), max: 100 }
|
|
||||||
]
|
|
||||||
},
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
name: `xxx${t('workplace.index')}`,
|
|
||||||
type: 'radar',
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
value: [42, 30, 20, 35, 80],
|
|
||||||
name: t('workplace.personal')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: [50, 140, 290, 100, 90],
|
|
||||||
name: t('workplace.team')
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
export const wordOptions: EChartsWordOption = {
|
|
||||||
series: [
|
|
||||||
{
|
|
||||||
type: 'wordCloud',
|
|
||||||
gridSize: 2,
|
|
||||||
sizeRange: [12, 50],
|
|
||||||
rotationRange: [-90, 90],
|
|
||||||
shape: 'pentagon',
|
|
||||||
width: 600,
|
|
||||||
height: 400,
|
|
||||||
drawOutOfBound: true,
|
|
||||||
textStyle: {
|
|
||||||
color: function () {
|
|
||||||
return (
|
|
||||||
'rgb(' +
|
|
||||||
[
|
|
||||||
Math.round(Math.random() * 160),
|
|
||||||
Math.round(Math.random() * 160),
|
|
||||||
Math.round(Math.random() * 160)
|
|
||||||
].join(',') +
|
|
||||||
')'
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
emphasis: {
|
|
||||||
textStyle: {
|
|
||||||
shadowBlur: 10,
|
|
||||||
shadowColor: '#333'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data: [
|
|
||||||
{
|
|
||||||
name: 'Sam S Club',
|
|
||||||
value: 10000,
|
|
||||||
textStyle: {
|
|
||||||
color: 'black'
|
|
||||||
},
|
|
||||||
emphasis: {
|
|
||||||
textStyle: {
|
|
||||||
color: 'red'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Macys',
|
|
||||||
value: 6181
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Amy Schumer',
|
|
||||||
value: 4386
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Jurassic World',
|
|
||||||
value: 4055
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Charter Communications',
|
|
||||||
value: 2467
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Chick Fil A',
|
|
||||||
value: 2244
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Planet Fitness',
|
|
||||||
value: 1898
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Pitch Perfect',
|
|
||||||
value: 1484
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Express',
|
|
||||||
value: 1112
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Home',
|
|
||||||
value: 965
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Johnny Depp',
|
|
||||||
value: 847
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Lena Dunham',
|
|
||||||
value: 582
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Lewis Hamilton',
|
|
||||||
value: 555
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'KXAN',
|
|
||||||
value: 550
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Mary Ellen Mark',
|
|
||||||
value: 462
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Farrah Abraham',
|
|
||||||
value: 366
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Rita Ora',
|
|
||||||
value: 360
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Serena Williams',
|
|
||||||
value: 282
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'NCAA baseball tournament',
|
|
||||||
value: 273
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Point Break',
|
|
||||||
value: 265
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -149,7 +149,10 @@ export const searchSchema = reactive<FormSchema[]>([
|
|||||||
label: '角色名称',
|
label: '角色名称',
|
||||||
component: 'Input',
|
component: 'Input',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
clearable: false
|
clearable: false,
|
||||||
|
style: {
|
||||||
|
width: '214px'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -157,7 +160,10 @@ export const searchSchema = reactive<FormSchema[]>([
|
|||||||
label: '权限字符',
|
label: '权限字符',
|
||||||
component: 'Input',
|
component: 'Input',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
clearable: false
|
clearable: false,
|
||||||
|
style: {
|
||||||
|
width: '214px'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -166,7 +172,7 @@ export const searchSchema = reactive<FormSchema[]>([
|
|||||||
component: 'Select',
|
component: 'Select',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
style: {
|
style: {
|
||||||
width: '100%'
|
width: '214px'
|
||||||
},
|
},
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@ export const columns = reactive<TableColumn[]>([
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'last_login',
|
field: 'last_login',
|
||||||
label: '最近一次登录时间',
|
label: '最近登录时间',
|
||||||
show: true
|
show: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -62,7 +62,12 @@ export const schema = reactive<FormSchema[]>([
|
|||||||
colProps: {
|
colProps: {
|
||||||
span: 12
|
span: 12
|
||||||
},
|
},
|
||||||
component: 'Input'
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%'
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'telephone',
|
field: 'telephone',
|
||||||
@ -70,7 +75,12 @@ export const schema = reactive<FormSchema[]>([
|
|||||||
colProps: {
|
colProps: {
|
||||||
span: 12
|
span: 12
|
||||||
},
|
},
|
||||||
component: 'Input'
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%'
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'nickname',
|
field: 'nickname',
|
||||||
@ -78,7 +88,12 @@ export const schema = reactive<FormSchema[]>([
|
|||||||
colProps: {
|
colProps: {
|
||||||
span: 12
|
span: 12
|
||||||
},
|
},
|
||||||
component: 'Input'
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
style: {
|
||||||
|
width: '100%'
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
field: 'gender',
|
field: 'gender',
|
||||||
@ -156,7 +171,10 @@ export const searchSchema = reactive<FormSchema[]>([
|
|||||||
label: '姓名',
|
label: '姓名',
|
||||||
component: 'Input',
|
component: 'Input',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
clearable: false
|
clearable: false,
|
||||||
|
style: {
|
||||||
|
width: '214px'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -164,7 +182,10 @@ export const searchSchema = reactive<FormSchema[]>([
|
|||||||
label: '手机号',
|
label: '手机号',
|
||||||
component: 'Input',
|
component: 'Input',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
clearable: false
|
clearable: false,
|
||||||
|
style: {
|
||||||
|
width: '214px'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -173,7 +194,7 @@ export const searchSchema = reactive<FormSchema[]>([
|
|||||||
component: 'Select',
|
component: 'Select',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
style: {
|
style: {
|
||||||
width: '100%'
|
width: '214px'
|
||||||
},
|
},
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
|
@ -16,7 +16,17 @@ import Write from './components/Write.vue'
|
|||||||
import Import from './components/Import.vue'
|
import Import from './components/Import.vue'
|
||||||
import Password from './components/Password.vue'
|
import Password from './components/Password.vue'
|
||||||
import { Dialog } from '@/components/Dialog'
|
import { Dialog } from '@/components/Dialog'
|
||||||
import { ElButton, ElMessage, ElSwitch, ElRow, ElCol } from 'element-plus'
|
import {
|
||||||
|
ElButton,
|
||||||
|
ElMessage,
|
||||||
|
ElSwitch,
|
||||||
|
ElRow,
|
||||||
|
ElCol,
|
||||||
|
ElDropdown,
|
||||||
|
ElDropdownMenu,
|
||||||
|
ElDropdownItem,
|
||||||
|
ElIcon
|
||||||
|
} from 'element-plus'
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { useI18n } from '@/hooks/web/useI18n'
|
||||||
import { selectDictLabel, DictDetail } from '@/utils/dict'
|
import { selectDictLabel, DictDetail } from '@/utils/dict'
|
||||||
import { useDictStore } from '@/store/modules/dict'
|
import { useDictStore } from '@/store/modules/dict'
|
||||||
@ -24,6 +34,9 @@ import { useAuthStoreWithOut } from '@/store/modules/auth'
|
|||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { RightToolbar } from '@/components/RightToolbar'
|
import { RightToolbar } from '@/components/RightToolbar'
|
||||||
import { Search } from '@/components/Search'
|
import { Search } from '@/components/Search'
|
||||||
|
import { useAppStore } from '@/store/modules/app'
|
||||||
|
|
||||||
|
const appStore = useAppStore()
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
@ -171,6 +184,21 @@ const sendPasswordToSMS = async () => {
|
|||||||
return ElMessage.warning('请先选择数据')
|
return ElMessage.warning('请先选择数据')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mobile = appStore.getMobile
|
||||||
|
|
||||||
|
// 下拉菜单处理事件
|
||||||
|
const handleCommand = (command: string) => {
|
||||||
|
if (command === 'a') {
|
||||||
|
importList()
|
||||||
|
} else if (command === 'b') {
|
||||||
|
exportQueryList()
|
||||||
|
} else if (command === 'c') {
|
||||||
|
sendPasswordToSMS()
|
||||||
|
} else if (command === 'd') {
|
||||||
|
delDatas(null, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -182,18 +210,44 @@ const sendPasswordToSMS = async () => {
|
|||||||
<ElCol :span="1.5" v-hasPermi="['auth.user.create']">
|
<ElCol :span="1.5" v-hasPermi="['auth.user.create']">
|
||||||
<ElButton type="primary" @click="AddAction">新增用户</ElButton>
|
<ElButton type="primary" @click="AddAction">新增用户</ElButton>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
<ElCol :span="1.5" v-hasPermi="['auth.user.import']">
|
<ElCol :span="1.5" v-hasPermi="['auth.user.import']" v-if="!mobile">
|
||||||
<ElButton @click="importList">批量导入用户</ElButton>
|
<ElButton @click="importList">批量导入用户</ElButton>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
<ElCol :span="1.5" v-hasPermi="['auth.user.export']">
|
<ElCol :span="1.5" v-hasPermi="['auth.user.export']" v-if="!mobile">
|
||||||
<ElButton @click="exportQueryList">导出筛选用户</ElButton>
|
<ElButton @click="exportQueryList">导出筛选用户</ElButton>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
<ElCol :span="1.5" v-hasPermi="['auth.user.reset']">
|
<ElCol :span="1.5" v-hasPermi="['auth.user.reset']" v-if="!mobile">
|
||||||
<ElButton @click="sendPasswordToSMS">重置密码通知短信</ElButton>
|
<ElButton @click="sendPasswordToSMS">重置密码通知短信</ElButton>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
<ElCol :span="1.5" v-hasPermi="['auth.user.delete']">
|
<ElCol :span="1.5" v-hasPermi="['auth.user.delete']" v-if="!mobile">
|
||||||
<ElButton type="danger" @click="delDatas(null, true)">批量删除</ElButton>
|
<ElButton type="danger" @click="delDatas(null, true)">批量删除</ElButton>
|
||||||
</ElCol>
|
</ElCol>
|
||||||
|
<ElCol :span="1.5" v-if="mobile">
|
||||||
|
<ElDropdown trigger="click" @command="handleCommand">
|
||||||
|
<ElButton>
|
||||||
|
更多
|
||||||
|
<el-icon class="el-icon--right">
|
||||||
|
<Icon icon="mdi:keyboard-arrow-down" />
|
||||||
|
</el-icon>
|
||||||
|
</ElButton>
|
||||||
|
<template #dropdown>
|
||||||
|
<ElDropdownMenu>
|
||||||
|
<ElDropdownItem command="a" v-hasPermi="['auth.user.import']"
|
||||||
|
>批量导入用户</ElDropdownItem
|
||||||
|
>
|
||||||
|
<ElDropdownItem command="b" v-hasPermi="['auth.user.export']"
|
||||||
|
>导出筛选用户</ElDropdownItem
|
||||||
|
>
|
||||||
|
<ElDropdownItem command="c" v-hasPermi="['auth.user.reset']"
|
||||||
|
>重置密码通知短信</ElDropdownItem
|
||||||
|
>
|
||||||
|
<ElDropdownItem command="d" v-hasPermi="['auth.user.delete']"
|
||||||
|
>批量删除</ElDropdownItem
|
||||||
|
>
|
||||||
|
</ElDropdownMenu>
|
||||||
|
</template>
|
||||||
|
</ElDropdown>
|
||||||
|
</ElCol>
|
||||||
</ElRow>
|
</ElRow>
|
||||||
<RightToolbar @get-list="getList" v-model:table-size="tableSize" v-model:columns="columns" />
|
<RightToolbar @get-list="getList" v-model:table-size="tableSize" v-model:columns="columns" />
|
||||||
</div>
|
</div>
|
||||||
@ -272,3 +326,12 @@ const sendPasswordToSMS = async () => {
|
|||||||
</Dialog>
|
</Dialog>
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.el-dropdown-link {
|
||||||
|
cursor: pointer;
|
||||||
|
color: var(--el-color-primary);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { FormSchema } from '@/types/form'
|
||||||
import { TableColumn } from '@/types/table'
|
import { TableColumn } from '@/types/table'
|
||||||
import { reactive } from 'vue'
|
import { reactive } from 'vue'
|
||||||
|
|
||||||
@ -96,7 +97,10 @@ export const searchSchema = reactive<FormSchema[]>([
|
|||||||
label: '手机号',
|
label: '手机号',
|
||||||
component: 'Input',
|
component: 'Input',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
clearable: false
|
clearable: false,
|
||||||
|
style: {
|
||||||
|
width: '214px'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -104,7 +108,10 @@ export const searchSchema = reactive<FormSchema[]>([
|
|||||||
label: '登陆地址',
|
label: '登陆地址',
|
||||||
component: 'Input',
|
component: 'Input',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
clearable: false
|
clearable: false,
|
||||||
|
style: {
|
||||||
|
width: '214px'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -113,7 +120,7 @@ export const searchSchema = reactive<FormSchema[]>([
|
|||||||
component: 'Select',
|
component: 'Select',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
style: {
|
style: {
|
||||||
width: '100%'
|
width: '214px'
|
||||||
},
|
},
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
|