@xizs/nuxt-antui 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/components/global/Form.tsx +40 -20
- package/app/components/global/FormTable.tsx +154 -169
- package/app/components/layout/Base.vue +18 -111
- package/app/composables/form.ts +77 -1
- package/app/composables/modal.ts +7 -4
- package/app/composables/table.ts +8 -2
- package/i18n/locales/en.json +19 -0
- package/i18n/locales/zh.json +19 -0
- package/nuxt.config.ts +10 -3
- package/package.json +2 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { AForm, AFormItem, AInput, ASelect,AInputNumber, LineOutlined, ASwitch, ATextarea, ARadio } from "#components"
|
|
1
|
+
import { AForm, AFormItem, AInput, ASelect,AInputNumber, LineOutlined, ASwitch, ATextarea, ARadio, ARadioGroup, AButton } from "#components"
|
|
2
2
|
|
|
3
3
|
export type FormItemType = {
|
|
4
4
|
label:string,
|
|
5
|
-
key:string|string[],
|
|
5
|
+
key: string | string[],
|
|
6
|
+
value:any,
|
|
6
7
|
is:string,
|
|
7
8
|
bind:any,
|
|
8
9
|
rules:any[]
|
|
@@ -16,35 +17,42 @@ export type FormPropsType = {
|
|
|
16
17
|
showSubmit?:boolean
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
const FormComs
|
|
20
|
+
export const FormComs:{
|
|
21
|
+
[key: string]: (form:any,item:FormItemType)=>VNode
|
|
22
|
+
}= {
|
|
20
23
|
input:(form:any,item:FormItemType)=>{
|
|
21
|
-
return <AInput v-model:value={form[item.key]}></AInput>
|
|
24
|
+
return <AInput v-model:value={form[item.key as string]}></AInput>
|
|
25
|
+
},
|
|
26
|
+
button:(form:any,item:FormItemType)=>{
|
|
27
|
+
console.log(item.bind)
|
|
28
|
+
return <AButton {...item.bind}>{ item.bind.content}</AButton>
|
|
22
29
|
},
|
|
23
30
|
textarea:(form:any,item:FormItemType)=>{
|
|
24
|
-
return <ATextarea v-model:value={form[item.key]}></ATextarea>
|
|
31
|
+
return <ATextarea v-model:value={form[item.key as string]}></ATextarea>
|
|
25
32
|
},
|
|
26
33
|
inputNumber:(form:any,item:FormItemType)=>{
|
|
27
|
-
return <AInputNumber v-model:value={form[item.key]} {...item.bind}></AInputNumber>
|
|
34
|
+
return <AInputNumber v-model:value={form[item.key as string]} {...item.bind}></AInputNumber>
|
|
28
35
|
},
|
|
29
36
|
inputNumberRange:(form:any,item:FormItemType)=>{
|
|
30
37
|
return <div class="flex items-center gap-2">
|
|
31
|
-
<AInputNumber class="flex-1" v-model:value={form[item.key[0]]} {...item.bind[0]}></AInputNumber>
|
|
38
|
+
<AInputNumber class="flex-1" v-model:value={form[item.key[0] as string]} {...item.bind[0]}></AInputNumber>
|
|
32
39
|
<LineOutlined />
|
|
33
|
-
<AInputNumber class="flex-1" v-model:value={form[item.key[1]]} {...item.bind[1]}></AInputNumber>
|
|
40
|
+
<AInputNumber class="flex-1" v-model:value={form[item.key[1] as string]} {...item.bind[1]}></AInputNumber>
|
|
34
41
|
</div>
|
|
35
42
|
},
|
|
36
43
|
select:(form:any,item:FormItemType)=>{
|
|
37
|
-
return <ASelect v-model:value={form[item.key]} options={item.bind.options}></ASelect>
|
|
38
|
-
},
|
|
39
|
-
countrySelect:(form:any,item:FormItemType)=>{
|
|
40
|
-
return <ASelect v-model:value={form[item.key]} options={Const.CountrySelectList()}></ASelect>
|
|
44
|
+
return <ASelect v-model:value={form[item.key as string]} options={item.bind.options}></ASelect>
|
|
41
45
|
},
|
|
42
46
|
switch:(form:any,item:FormItemType)=>{
|
|
43
|
-
return <ASwitch v-model:checked={form[item.key]} {...item.bind}></ASwitch>
|
|
47
|
+
return <ASwitch v-model:checked={form[item.key as string]} {...item.bind}></ASwitch>
|
|
44
48
|
},
|
|
45
49
|
radio: (form: any, item: FormItemType) => {
|
|
46
|
-
return <
|
|
47
|
-
}
|
|
50
|
+
return <ARadioGroup v-model:value={form[item.key as string]} {...item.bind}></ARadioGroup>
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
// uploadImg: (form: any, item: FormItemType) => {
|
|
54
|
+
// return <UploadImg v-model:value={form[item.key as string]} {...item.bind}></UploadImg>
|
|
55
|
+
// }
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
export default defineComponent({
|
|
@@ -65,13 +73,18 @@ export default defineComponent({
|
|
|
65
73
|
type:Boolean,
|
|
66
74
|
default:true
|
|
67
75
|
},
|
|
76
|
+
defaultFormData: {
|
|
77
|
+
type: Object,
|
|
78
|
+
default: () => ({})
|
|
79
|
+
}
|
|
68
80
|
},
|
|
69
81
|
setup(props,{expose}){
|
|
70
82
|
|
|
71
83
|
let thisRef = ref(null)
|
|
72
|
-
let formData = ref(
|
|
84
|
+
let formData = ref(props.defaultFormData)
|
|
73
85
|
let rules = ref({})
|
|
74
|
-
props.form.forEach(item=>{
|
|
86
|
+
ADParse(props.form,formData.value).forEach(item=>{
|
|
87
|
+
if(item.key==null) return
|
|
75
88
|
if(Array.isArray(item.key)){
|
|
76
89
|
item.key.forEach(key=>{
|
|
77
90
|
formData.value[key] = item.value??''
|
|
@@ -115,9 +128,16 @@ export default defineComponent({
|
|
|
115
128
|
return ()=><AForm ref={thisRef} model={formData.value} rules={rules.value} label-col={{ span: 6 }} wrapper-col={{ span: 16 }}>
|
|
116
129
|
{/* {JSON.stringify(formData.value)} */}
|
|
117
130
|
{
|
|
118
|
-
props.form.map(item=>{
|
|
119
|
-
|
|
120
|
-
|
|
131
|
+
ADParse(props.form, formData.value).map(item => {
|
|
132
|
+
if (item.label == null) {
|
|
133
|
+
return typeof item.is === 'function'? item.is(formData.value) :
|
|
134
|
+
FormComs[item.is](formData.value,item)
|
|
135
|
+
}
|
|
136
|
+
return <AFormItem label={item.label} key={item.key} name={item.key} {...item.bind} class={{'hidden':item.show===false}}>
|
|
137
|
+
{
|
|
138
|
+
typeof item.is === 'function'? item.is(formData.value) :
|
|
139
|
+
FormComs[item.is](formData.value,item)
|
|
140
|
+
}
|
|
121
141
|
</AFormItem>
|
|
122
142
|
})
|
|
123
143
|
}
|
|
@@ -11,45 +11,48 @@ type TableFormItemType = {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
let dateRange = defineComponent({
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
props:{
|
|
15
|
+
form:{
|
|
16
|
+
type:Object as ()=>any,
|
|
17
|
+
required:true
|
|
18
|
+
},
|
|
19
|
+
item:{
|
|
20
|
+
type:Object as ()=>TableFormItemType,
|
|
21
|
+
required:true
|
|
22
|
+
}
|
|
18
23
|
},
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
24
|
+
setup(props) {
|
|
25
|
+
let {t:$t} = useI18n()
|
|
26
|
+
|
|
27
|
+
let value = watchRef(ref([]),(nv,ov)=>{
|
|
28
|
+
if(nv?.length>0){
|
|
29
|
+
props.form[props.item.key[0]] = nv[0].format('YYYY-MM-DD 00:00:00')
|
|
30
|
+
props.form[props.item.key[1]] = nv[1].format('YYYY-MM-DD 23:59:59')
|
|
31
|
+
}else{
|
|
32
|
+
props.form[props.item.key[0]] = ''
|
|
33
|
+
props.form[props.item.key[1]] = ''
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
const rangePresets = ref([
|
|
37
|
+
{ label: $t('今天'), value: [dayjs(), dayjs()] },
|
|
38
|
+
{ label: $t('昨天'), value: [dayjs().add(-1, 'd'), dayjs().add(-1, 'd')] },
|
|
39
|
+
{ label: $t('最近7天'), value: [dayjs().add(-7, 'd'), dayjs()] },
|
|
40
|
+
{ label: $t('最近30天'), value: [dayjs().add(-30, 'd'), dayjs()] },
|
|
41
|
+
]);
|
|
42
|
+
|
|
43
|
+
return ()=><ARangePicker presets={rangePresets.value} v-model:value={value.value} />
|
|
22
44
|
}
|
|
23
|
-
},
|
|
24
|
-
setup(props){
|
|
25
|
-
let value = watchRef(ref([]),(nv,ov)=>{
|
|
26
|
-
if(nv?.length>0){
|
|
27
|
-
props.form[props.item.key[0]] = nv[0].format('YYYY-MM-DD 00:00:00')
|
|
28
|
-
props.form[props.item.key[1]] = nv[1].format('YYYY-MM-DD 23:59:59')
|
|
29
|
-
}else{
|
|
30
|
-
props.form[props.item.key[0]] = ''
|
|
31
|
-
props.form[props.item.key[1]] = ''
|
|
32
|
-
}
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
const rangePresets = ref([
|
|
36
|
-
{ label: '今天', value: [dayjs(), dayjs()] },
|
|
37
|
-
{ label: '昨天', value: [dayjs().add(-1, 'd'), dayjs().add(-1, 'd')] },
|
|
38
|
-
{ label: '最近7天', value: [dayjs().add(-7, 'd'), dayjs()] },
|
|
39
|
-
{ label: '最近30天', value: [dayjs().add(-30, 'd'), dayjs()] },
|
|
40
|
-
]);
|
|
41
|
-
|
|
42
|
-
return ()=><ARangePicker presets={rangePresets.value} v-model:value={value.value} />
|
|
43
|
-
}
|
|
44
45
|
})
|
|
45
46
|
|
|
46
47
|
|
|
47
48
|
const FormItems = {
|
|
48
|
-
input:(form:any,item:TableFormItemType)=>{
|
|
49
|
-
|
|
49
|
+
input: (form: any, item: TableFormItemType) => {
|
|
50
|
+
let {t:$t} = useI18n()
|
|
51
|
+
return <AInput size="middle" v-model:value={form[item.key]} placeholder={$t(`请输入{label}`,{label:$t(item.label)})}></AInput>
|
|
50
52
|
},
|
|
51
|
-
select:(form:any,item:TableFormItemType)=>{
|
|
52
|
-
|
|
53
|
+
select: (form: any, item: TableFormItemType) => {
|
|
54
|
+
let {t:$t} = useI18n()
|
|
55
|
+
return <ASelect allowClear class="min-w-[150px]" v-model:value={form[item.key]} options={item.bind?.options} placeholder={$t(`请选择{label}`,{label:$t(item.label)})}></ASelect>
|
|
53
56
|
},
|
|
54
57
|
dateRange:(form:any,item:TableFormItemType)=>{
|
|
55
58
|
|
|
@@ -80,7 +83,8 @@ export type AttributeType = {
|
|
|
80
83
|
selectItems:any[],
|
|
81
84
|
selectKeys:any[],
|
|
82
85
|
page:number,
|
|
83
|
-
pageSize:number
|
|
86
|
+
pageSize: number,
|
|
87
|
+
tableData: any[],
|
|
84
88
|
}
|
|
85
89
|
|
|
86
90
|
export const FormTableProps = {
|
|
@@ -137,148 +141,129 @@ export const FormTableProps = {
|
|
|
137
141
|
}
|
|
138
142
|
|
|
139
143
|
export default defineComponent({
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
const form = ref({})
|
|
145
|
-
props.form?.forEach((item) => {
|
|
146
|
-
form.value[item.key] = item.value?? ''
|
|
147
|
-
})
|
|
148
|
-
const metaForm = JSON.parse(JSON.stringify(form.value))
|
|
149
|
-
let pagination =reactive({
|
|
150
|
-
page:1,
|
|
151
|
-
pageSize:20,
|
|
152
|
-
total:0
|
|
153
|
-
})
|
|
154
|
-
|
|
144
|
+
name: 'TableLayout',
|
|
145
|
+
props: FormTableProps,
|
|
146
|
+
setup(props,{slots}) {
|
|
147
|
+
const {t:$t} = useI18n()
|
|
155
148
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
pagination:{
|
|
163
|
-
total:0,
|
|
164
|
-
per_page:pagination.pageSize,
|
|
165
|
-
current_page:pagination.page
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
console.log(res)
|
|
171
|
-
pagination.total = res.meta.pagination.total
|
|
172
|
-
pagination.pageSize = res.meta.pagination.per_page
|
|
173
|
-
pagination.page = res.meta.pagination.current_page
|
|
174
|
-
console.log(res)
|
|
175
|
-
props.attribute.tableData = res.list
|
|
176
|
-
return res.list
|
|
177
|
-
},[])
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
const rowSelection = {
|
|
181
|
-
selectedRowKeys: props.attribute?.selectKeys,
|
|
182
|
-
onChange: (keys,rows)=>{
|
|
183
|
-
props.attribute!.selectKeys.splice(0,props.attribute!.selectKeys.length,...keys)
|
|
184
|
-
props.attribute!.selectItems.splice(0,props.attribute!.selectItems.length,...rows)
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
props.control.refresh = ()=>tableData.load()
|
|
189
|
-
|
|
149
|
+
const form = ref({})
|
|
150
|
+
props.form?.forEach((item) => {
|
|
151
|
+
form.value[item.key] = item.value
|
|
152
|
+
})
|
|
153
|
+
props.attribute.form = form.value
|
|
154
|
+
const metaForm = JSON.parse(JSON.stringify(form.value))
|
|
190
155
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
form[item.key] = item.value?? ''
|
|
197
|
-
return (
|
|
198
|
-
<AFormItem label={item.label}>
|
|
199
|
-
{/* <AInput type="text" /> */}
|
|
200
|
-
{FormItems[item.is](form.value,item)}
|
|
201
|
-
</AFormItem>
|
|
202
|
-
)
|
|
203
|
-
})}
|
|
204
|
-
<div class="flex gap-2">
|
|
205
|
-
{props.formOptions.search && <AButton type="primary" onClick={()=>tableData.load()}>搜索</AButton>}
|
|
206
|
-
{props.formOptions.reset && <AButton onClick={() => patch(metaForm,form.value)}>重置</AButton>}
|
|
207
|
-
{props.formOptions.export && <AButton type="primary">导出</AButton>}
|
|
208
|
-
</div>
|
|
209
|
-
</AForm>}
|
|
156
|
+
let pagination =reactive({
|
|
157
|
+
page:1,
|
|
158
|
+
pageSize:20,
|
|
159
|
+
total:0
|
|
160
|
+
})
|
|
210
161
|
|
|
211
|
-
<div class="flex items-center justify-between">
|
|
212
|
-
<div>{props.action.other}</div>
|
|
213
162
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
<a-descriptions-item label="转出">12</a-descriptions-item>
|
|
225
|
-
<a-descriptions-item label="人均盈亏"> 11</a-descriptions-item>
|
|
226
|
-
</a-descriptions> */}
|
|
227
|
-
<div class="flex-1 mt-3 overflow-scroll flex flex-col">
|
|
228
|
-
<ATable
|
|
229
|
-
row-selection={props.table.enableSelection?rowSelection:null}
|
|
230
|
-
rowKey={props.table.rowKey??((row,key)=>key)}
|
|
231
|
-
loading={tableData.loading}
|
|
232
|
-
scroll={{x: true}}
|
|
233
|
-
columns={props.table.columns}
|
|
234
|
-
pagination={false}
|
|
235
|
-
sticky={tableData.value.length>0}
|
|
236
|
-
v-slots={{
|
|
237
|
-
headerCell: ({ title,column }: any) => (
|
|
238
|
-
<div style={{'white-space': 'nowrap'}}>
|
|
239
|
-
{title }
|
|
240
|
-
</div>
|
|
241
|
-
),
|
|
242
|
-
bodyCell:(row)=>{
|
|
243
|
-
if(row.column?.customRender!=null){
|
|
244
|
-
return row.column.customRender(row)
|
|
163
|
+
const tableData = asyncReactive<any[]>(async ()=>{
|
|
164
|
+
let res = await props.table.data({...form.value,...pagination})
|
|
165
|
+
if(Array.isArray(res)){
|
|
166
|
+
res = {
|
|
167
|
+
list:res,
|
|
168
|
+
meta:{
|
|
169
|
+
pagination:{
|
|
170
|
+
total:0,
|
|
171
|
+
per_page:pagination.pageSize,
|
|
172
|
+
current_page:pagination.page
|
|
245
173
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
pagination.total = res.meta.pagination.total
|
|
178
|
+
pagination.pageSize = res.meta.pagination.per_page
|
|
179
|
+
pagination.page = res.meta.pagination.current_page
|
|
180
|
+
props.attribute.tableData = res.list
|
|
181
|
+
return res.list
|
|
182
|
+
},[])
|
|
249
183
|
|
|
250
|
-
}}
|
|
251
|
-
dataSource={tableData.value}
|
|
252
|
-
/>
|
|
253
|
-
</div>
|
|
254
|
-
{props.footerOptions.show && <div class="mt-3 flex items-center justify-between">
|
|
255
|
-
<div>
|
|
256
|
-
{ props.table.enableSelection && (`选中项: ${props.attribute.selectKeys.length}`)}
|
|
257
|
-
</div>
|
|
258
|
-
<div class="flex items-center gap-2">
|
|
259
|
-
<APagination
|
|
260
|
-
hideOnSinglePage={true}
|
|
261
|
-
v-model:current={pagination.page}
|
|
262
|
-
total={pagination.total}
|
|
263
|
-
pageSize={pagination.pageSize}
|
|
264
|
-
onChange={(page) => {
|
|
265
|
-
pagination.page = page
|
|
266
|
-
tableData.load()
|
|
267
|
-
}}
|
|
268
|
-
pageSizeOptions={['20','50','100']}
|
|
269
|
-
onShowSizeChange={(current, size) => {
|
|
270
|
-
pagination.pageSize = size
|
|
271
|
-
pagination.page = current
|
|
272
|
-
tableData.load()
|
|
273
|
-
}}
|
|
274
|
-
/>
|
|
275
184
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
185
|
+
const rowSelection = {
|
|
186
|
+
selectedRowKeys: props.attribute?.selectKeys,
|
|
187
|
+
onChange: (keys,rows)=>{
|
|
188
|
+
props.attribute!.selectKeys.splice(0,props.attribute!.selectKeys.length,...keys)
|
|
189
|
+
props.attribute!.selectItems.splice(0,props.attribute!.selectItems.length,...rows)
|
|
190
|
+
}
|
|
191
|
+
}
|
|
280
192
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
193
|
+
props.control.refresh = ()=>tableData.load()
|
|
194
|
+
|
|
195
|
+
return () => (
|
|
196
|
+
<div class="flex flex-col gap-2 h-full ">
|
|
197
|
+
{props.form&&<AForm layout="inline gap-2">
|
|
198
|
+
{props.form?.map((item) => {
|
|
199
|
+
form[item.key] = item.value?? ''
|
|
200
|
+
return (
|
|
201
|
+
<AFormItem label={$t(item.label)}>
|
|
202
|
+
{FormItems[item.is](form.value,item)}
|
|
203
|
+
</AFormItem>
|
|
204
|
+
)
|
|
205
|
+
})}
|
|
206
|
+
<div class="flex gap-2">
|
|
207
|
+
{props.formOptions.search && <AButton type="primary" onClick={()=>tableData.load()}>{$t('搜索')}</AButton>}
|
|
208
|
+
{props.formOptions.reset && <AButton onClick={() => patch(metaForm,form.value)}>{$t('重置')}</AButton>}
|
|
209
|
+
{props.formOptions.export && <AButton type="primary">{$t('导出')}</AButton>}
|
|
210
|
+
</div>
|
|
211
|
+
</AForm>}
|
|
212
|
+
{slots.center?.()}
|
|
213
|
+
<div class="flex-1 overflow-scroll flex flex-col">
|
|
214
|
+
{slots.content?.(tableData.value) ??
|
|
215
|
+
<ATable
|
|
216
|
+
row-selection={props.table.enableSelection?rowSelection:null}
|
|
217
|
+
rowKey={props.table.rowKey??((row,key)=>key)}
|
|
218
|
+
loading={tableData.loading}
|
|
219
|
+
scroll={{x: true}}
|
|
220
|
+
columns={props.table.columns}
|
|
221
|
+
pagination={false}
|
|
222
|
+
sticky={tableData.value.length>0}
|
|
223
|
+
v-slots={{
|
|
224
|
+
headerCell: ({ title,column }: any) => (
|
|
225
|
+
<div style={{'white-space': 'nowrap'}}>
|
|
226
|
+
{title}
|
|
227
|
+
</div>
|
|
228
|
+
),
|
|
229
|
+
bodyCell:(row)=>{
|
|
230
|
+
if(row.column?.customRender!=null){
|
|
231
|
+
return row.column.customRender(row)
|
|
232
|
+
}
|
|
233
|
+
return <div class="whitespace-nowrap" style={{ width:row.column.width??'100px'}}>{row.text}</div>
|
|
234
|
+
},
|
|
235
|
+
...props.table['v-slots']
|
|
236
|
+
}}
|
|
237
|
+
dataSource={tableData.value}
|
|
238
|
+
/>
|
|
239
|
+
}
|
|
240
|
+
</div>
|
|
241
|
+
|
|
242
|
+
{props.footerOptions.show && <div class="mt-3 flex items-center justify-between">
|
|
243
|
+
<div>
|
|
244
|
+
{ props.table.enableSelection && (`${$t('选中项')}: ${props.attribute.selectKeys.length}`)}
|
|
245
|
+
</div>
|
|
246
|
+
<div class="flex items-center gap-2">
|
|
247
|
+
<APagination
|
|
248
|
+
hideOnSinglePage={true}
|
|
249
|
+
v-model:current={pagination.page}
|
|
250
|
+
total={pagination.total}
|
|
251
|
+
pageSize={pagination.pageSize}
|
|
252
|
+
onChange={(page) => {
|
|
253
|
+
pagination.page = page
|
|
254
|
+
tableData.load()
|
|
255
|
+
}}
|
|
256
|
+
pageSizeOptions={['20','50','100']}
|
|
257
|
+
onShowSizeChange={(current, size) => {
|
|
258
|
+
pagination.pageSize = size
|
|
259
|
+
pagination.page = current
|
|
260
|
+
tableData.load()
|
|
261
|
+
}}
|
|
262
|
+
/>
|
|
263
|
+
<AButton icon={h(RedoOutlined)} loading={tableData.loading} onClick={tableData.load} />
|
|
264
|
+
</div>
|
|
265
|
+
</div>}
|
|
266
|
+
</div>
|
|
267
|
+
)
|
|
268
|
+
}
|
|
284
269
|
})
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
breakpoint="lg"
|
|
6
6
|
collapsed-width="0"
|
|
7
7
|
width="220px"
|
|
8
|
+
:trigger="null"
|
|
8
9
|
>
|
|
9
10
|
<div class="text-center text-white p-2 text-lg " >
|
|
10
11
|
LOGO
|
|
@@ -16,11 +17,7 @@
|
|
|
16
17
|
<a-layout-header :style="{ background: '#fff', padding: 0 }">
|
|
17
18
|
<div class="flex h-full items-center justify-between gap-2 px-4">
|
|
18
19
|
<div class="flex items-center gap-2">
|
|
19
|
-
<menu-unfold-outlined
|
|
20
|
-
v-if="collapsed"
|
|
21
|
-
class="trigger text-[20px]"
|
|
22
|
-
@click="() => (collapsed = !collapsed)"
|
|
23
|
-
/>
|
|
20
|
+
<menu-unfold-outlined v-if="collapsed" class="trigger text-[20px]" @click="() => (collapsed = !collapsed)" />
|
|
24
21
|
<menu-fold-outlined v-else class="trigger text-[20px]" @click="() => (collapsed = !collapsed)" />
|
|
25
22
|
<div class="leading-4 gap-1 flex flex-col justify-center h-full">
|
|
26
23
|
<div class="text-[12px] text-[#aaa]">{{routeInfo.names.join(' / ')}}</div>
|
|
@@ -34,7 +31,21 @@
|
|
|
34
31
|
<template #overlay>
|
|
35
32
|
<a-menu>
|
|
36
33
|
<a-menu-item @click="()=>singOut()">
|
|
37
|
-
<a href="javascript:;"
|
|
34
|
+
<a href="javascript:;">{{$t('退出')}}</a>
|
|
35
|
+
</a-menu-item>
|
|
36
|
+
</a-menu>
|
|
37
|
+
</template>
|
|
38
|
+
</a-dropdown>
|
|
39
|
+
</div>
|
|
40
|
+
<div class="flex items-center p-2 ml-2">
|
|
41
|
+
<a-dropdown >
|
|
42
|
+
<div class=" cursor-pointer">
|
|
43
|
+
<GlobalOutlined class="text-[20px]" />
|
|
44
|
+
</div>
|
|
45
|
+
<template #overlay>
|
|
46
|
+
<a-menu>
|
|
47
|
+
<a-menu-item v-for="locale in locales" @click="setLocale(locale.code)">
|
|
48
|
+
{{ locale.name }}
|
|
38
49
|
</a-menu-item>
|
|
39
50
|
</a-menu>
|
|
40
51
|
</template>
|
|
@@ -60,6 +71,7 @@
|
|
|
60
71
|
</template>
|
|
61
72
|
<script lang="ts" setup>
|
|
62
73
|
import type { MenuItemType } from './Menu.vue';
|
|
74
|
+
const { locales, setLocale } = useI18n()
|
|
63
75
|
|
|
64
76
|
const collapsed = ref(false)
|
|
65
77
|
|
|
@@ -67,112 +79,7 @@ const props = defineProps<{
|
|
|
67
79
|
menu: MenuItemType[]
|
|
68
80
|
}>()
|
|
69
81
|
|
|
70
|
-
// const menuItems:MenuItemType = [
|
|
71
|
-
// {
|
|
72
|
-
// title:'首页',
|
|
73
|
-
// icon: () => h(PieChartOutlined),
|
|
74
|
-
// path:'/'
|
|
75
|
-
// },
|
|
76
|
-
// {
|
|
77
|
-
// title:'用户',
|
|
78
|
-
// icon: () => h(PieChartOutlined),
|
|
79
|
-
// path:'/user',
|
|
80
|
-
// children:[
|
|
81
|
-
// {
|
|
82
|
-
// title:'用户列表',
|
|
83
|
-
// icon:'InboxOutlined',
|
|
84
|
-
// path:'/user/list'
|
|
85
|
-
// }
|
|
86
|
-
// ]
|
|
87
|
-
// },
|
|
88
|
-
// {
|
|
89
|
-
// title:'数据报表',
|
|
90
|
-
// icon: () => h(PieChartOutlined),
|
|
91
|
-
// path:'/dataReport',
|
|
92
|
-
// children:[
|
|
93
|
-
// {
|
|
94
|
-
// title:'平台活跃报表',
|
|
95
|
-
// path:'/DataReport/platformActiveReport'
|
|
96
|
-
// },
|
|
97
|
-
// {
|
|
98
|
-
// title:'平台财务报表',
|
|
99
|
-
// path:'/DataReport/platformfinanceReport'
|
|
100
|
-
// },
|
|
101
|
-
// {
|
|
102
|
-
// title:'消耗报表',
|
|
103
|
-
// path:'/DataReport/consumptionReport'
|
|
104
|
-
// }
|
|
105
|
-
// ]
|
|
106
|
-
// },
|
|
107
|
-
// {
|
|
108
|
-
// title:'结算管理',
|
|
109
|
-
// icon: () => h(PieChartOutlined),
|
|
110
|
-
// path:'/settleManage',
|
|
111
|
-
// children:[
|
|
112
|
-
// {
|
|
113
|
-
// title:'分包游戏报表',
|
|
114
|
-
// path:'/settleManage/subGameReport'
|
|
115
|
-
// },
|
|
116
|
-
|
|
117
|
-
// ]
|
|
118
|
-
// },
|
|
119
|
-
// {
|
|
120
|
-
// title:'综艺直播游戏',
|
|
121
|
-
// icon: () => h(PieChartOutlined),
|
|
122
|
-
// path:'/liveGame',
|
|
123
|
-
// children:[
|
|
124
|
-
// {
|
|
125
|
-
// title:'综艺直播间数据',
|
|
126
|
-
// path:'/liveGame/liveData'
|
|
127
|
-
// },
|
|
128
|
-
// {
|
|
129
|
-
// title:'直播间开奖操控',
|
|
130
|
-
// path:'/liveGame/LotteryControl'
|
|
131
|
-
// },
|
|
132
|
-
// {
|
|
133
|
-
// title:'直播间实时监控',
|
|
134
|
-
// path:'/liveGame/liveMonitor'
|
|
135
|
-
// },
|
|
136
|
-
// {
|
|
137
|
-
// title:'机器人管理',
|
|
138
|
-
// path:'/liveGame/robotManage',
|
|
139
|
-
// children:[
|
|
140
|
-
// {
|
|
141
|
-
// title:'机器人列表',
|
|
142
|
-
// path:'/liveGame/robotManage/robotList'
|
|
143
|
-
// },
|
|
144
|
-
// {
|
|
145
|
-
// title:'机器人配置',
|
|
146
|
-
// path:'/liveGame/robotManage/robotConfig'
|
|
147
|
-
// },
|
|
148
|
-
// {
|
|
149
|
-
// title:'机器人资源库',
|
|
150
|
-
// path:'/liveGame/robotManage/robotResourceLibrary'
|
|
151
|
-
// },
|
|
152
|
-
// {
|
|
153
|
-
// title:'机器人类型',
|
|
154
|
-
// path:'/liveGame/robotManage/robotType'
|
|
155
|
-
// },
|
|
156
|
-
// {
|
|
157
|
-
// title:'自动弹幕文本配置',
|
|
158
|
-
// path:'/liveGame/robotManage/autoDanmuTextConfig'
|
|
159
|
-
// },
|
|
160
|
-
// ]
|
|
161
|
-
// },
|
|
162
|
-
// {
|
|
163
|
-
// title:'综艺游戏直播间配置',
|
|
164
|
-
// path:'/liveGame/gameLiveConfig'
|
|
165
|
-
// }
|
|
166
|
-
|
|
167
|
-
// ]
|
|
168
|
-
// }
|
|
169
|
-
|
|
170
|
-
// ]
|
|
171
|
-
const router = useRouter()
|
|
172
|
-
|
|
173
|
-
|
|
174
82
|
let routeInfo = useRouteInfo(props.menu)
|
|
175
83
|
|
|
176
|
-
|
|
177
84
|
</script>
|
|
178
85
|
|
package/app/composables/form.ts
CHANGED
|
@@ -1 +1,77 @@
|
|
|
1
|
-
|
|
1
|
+
// import type { FormItemType } from "../components/global/Form";
|
|
2
|
+
// import { AForm, AFormItem, AInput, ASelect, AInputNumber, LineOutlined, ASwitch, ATextarea, ARadio } from "#components"
|
|
3
|
+
|
|
4
|
+
// export const FormComs = {
|
|
5
|
+
// input: (form: any, item: FormItemType) =>
|
|
6
|
+
// h(AInput, {
|
|
7
|
+
// value: form[item.key as string],
|
|
8
|
+
// 'onUpdate:value': (val: any) => (form[item.key as string] = val)
|
|
9
|
+
// }),
|
|
10
|
+
|
|
11
|
+
// textarea: (form: any, item: FormItemType) =>
|
|
12
|
+
// h(ATextarea, {
|
|
13
|
+
// value: form[item.key as string],
|
|
14
|
+
// 'onUpdate:value': (val: any) => (form[item.key as string] = val)
|
|
15
|
+
// }),
|
|
16
|
+
|
|
17
|
+
// inputNumber: (form: any, item: FormItemType) =>
|
|
18
|
+
// h(AInputNumber, {
|
|
19
|
+
// ...item.bind,
|
|
20
|
+
// value: form[item.key as string],
|
|
21
|
+
// 'onUpdate:value': (val: any) => (form[item.key as string] = val)
|
|
22
|
+
// }),
|
|
23
|
+
|
|
24
|
+
// inputNumberRange: (form: any, item: FormItemType) =>
|
|
25
|
+
// h(
|
|
26
|
+
// 'div',
|
|
27
|
+
// { class: 'flex items-center gap-2' },
|
|
28
|
+
// [
|
|
29
|
+
// h(AInputNumber, {
|
|
30
|
+
// class: 'flex-1',
|
|
31
|
+
// ...item.bind[0],
|
|
32
|
+
// value: form[item.key[0] as string],
|
|
33
|
+
// 'onUpdate:value': (val: any) => (form[item.key[0] as string] = val)
|
|
34
|
+
// }),
|
|
35
|
+
// h(LineOutlined),
|
|
36
|
+
// h(AInputNumber, {
|
|
37
|
+
// class: 'flex-1',
|
|
38
|
+
// ...item.bind[1],
|
|
39
|
+
// value: form[item.key[1] as string],
|
|
40
|
+
// 'onUpdate:value': (val: any) => (form[item.key[1] as string] = val)
|
|
41
|
+
// })
|
|
42
|
+
// ]
|
|
43
|
+
// ),
|
|
44
|
+
|
|
45
|
+
// select: (form: any, item: FormItemType) =>
|
|
46
|
+
// h(ASelect, {
|
|
47
|
+
// value: form[item.key as string],
|
|
48
|
+
// options: item.bind.options,
|
|
49
|
+
// 'onUpdate:value': (val: any) => (form[item.key as string] = val)
|
|
50
|
+
// }),
|
|
51
|
+
|
|
52
|
+
// countrySelect: (form: any, item: FormItemType) =>
|
|
53
|
+
// h(ASelect, {
|
|
54
|
+
// value: form[item.key as string],
|
|
55
|
+
// options: Const.CountrySelectList(),
|
|
56
|
+
// 'onUpdate:value': (val: any) => (form[item.key as string] = val)
|
|
57
|
+
// }),
|
|
58
|
+
|
|
59
|
+
// switch: (form: any, item: FormItemType) =>
|
|
60
|
+
// h(ASwitch, {
|
|
61
|
+
// ...item.bind,
|
|
62
|
+
// checked: form[item.key as string],
|
|
63
|
+
// 'onUpdate:checked': (val: any) => (form[item.key as string] = val)
|
|
64
|
+
// }),
|
|
65
|
+
|
|
66
|
+
// radio: (form: any, item: FormItemType) =>
|
|
67
|
+
// h(ARadio, {
|
|
68
|
+
// ...item.bind,
|
|
69
|
+
// checked: form[item.key as string],
|
|
70
|
+
// 'onUpdate:checked': (val: any) => (form[item.key as string] = val)
|
|
71
|
+
// }),
|
|
72
|
+
|
|
73
|
+
// // upload: (form: any, item: FormItemType) =>
|
|
74
|
+
// // h(UploadImg, {
|
|
75
|
+
// // ...item.bind
|
|
76
|
+
// // })
|
|
77
|
+
// }
|
package/app/composables/modal.ts
CHANGED
|
@@ -102,6 +102,7 @@ export const FormModal = (params: FormModalParamsType) => {
|
|
|
102
102
|
|
|
103
103
|
return () => h(AModal, {
|
|
104
104
|
title: params.title,
|
|
105
|
+
width: params.width,
|
|
105
106
|
okText: '提交',
|
|
106
107
|
cancelText: '取消',
|
|
107
108
|
confirmLoading: loading.value,
|
|
@@ -113,6 +114,7 @@ export const FormModal = (params: FormModalParamsType) => {
|
|
|
113
114
|
}, h(Form, {
|
|
114
115
|
ref: formRef,
|
|
115
116
|
form: params.form,
|
|
117
|
+
defaultFormData: params.defaultFormData,
|
|
116
118
|
submit: params.submit,
|
|
117
119
|
showSubmit: false
|
|
118
120
|
}))
|
|
@@ -127,12 +129,13 @@ export const MModal = {
|
|
|
127
129
|
|
|
128
130
|
export const Confirm = {
|
|
129
131
|
delete: () => {
|
|
132
|
+
const { t: $t } = useI18n()
|
|
130
133
|
return new Promise((resolve, reject) => {
|
|
131
134
|
Modal.confirm({
|
|
132
|
-
title: '确认删除',
|
|
133
|
-
content: '确认删除该条数据吗?',
|
|
134
|
-
okText: '确定',
|
|
135
|
-
cancelText: '取消',
|
|
135
|
+
title: $t('确认删除'),
|
|
136
|
+
content: $t('确认删除该条数据吗?'),
|
|
137
|
+
okText: $t('确定'),
|
|
138
|
+
cancelText: $t('取消'),
|
|
136
139
|
onOk: () => {
|
|
137
140
|
resolve(true)
|
|
138
141
|
},
|
package/app/composables/table.ts
CHANGED
|
@@ -15,9 +15,9 @@ export const FormTable = (props: TablePropsType) => {
|
|
|
15
15
|
const control = {
|
|
16
16
|
refresh: () => { }
|
|
17
17
|
}
|
|
18
|
-
|
|
18
|
+
console.log({ ...props, attribute, control })
|
|
19
19
|
return {
|
|
20
|
-
com: h(FormTableCom, { ...props, attribute, control }),
|
|
20
|
+
com: h(FormTableCom, { ...props, attribute, control }, props['v-slots']),
|
|
21
21
|
attribute,
|
|
22
22
|
control
|
|
23
23
|
}
|
|
@@ -32,3 +32,9 @@ export const TablePage = (props: TablePropsType) => {
|
|
|
32
32
|
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
export const Table = {
|
|
38
|
+
Normal: FormTable,
|
|
39
|
+
Page: TablePage
|
|
40
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"搜索":"Search",
|
|
3
|
+
"重置":"Reset",
|
|
4
|
+
"请输入{label}":"Please enter {label}",
|
|
5
|
+
"请选择{label}":"Please select {label}",
|
|
6
|
+
"今天":"Today",
|
|
7
|
+
"昨天":"Yesterday",
|
|
8
|
+
"最近7天":"Last 7 days",
|
|
9
|
+
"最近30天":"Last 30 days",
|
|
10
|
+
"导出":"Export",
|
|
11
|
+
"选中项":"Selected items",
|
|
12
|
+
"退出":"Exit",
|
|
13
|
+
"确认删除":"Confirm deletion",
|
|
14
|
+
"确认删除该条数据吗?":"Are you sure you want to delete this data?",
|
|
15
|
+
"确定":"Confirm",
|
|
16
|
+
"取消":"Cancel",
|
|
17
|
+
|
|
18
|
+
"":""
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"搜索":"搜索",
|
|
3
|
+
"重置":"重置",
|
|
4
|
+
"请输入{label}":"请输入{label}",
|
|
5
|
+
"请选择{label}":"请选择{label}",
|
|
6
|
+
"今天":"今天",
|
|
7
|
+
"昨天":"昨天",
|
|
8
|
+
"最近7天":"最近7天",
|
|
9
|
+
"最近30天":"最近30天",
|
|
10
|
+
"导出":"导出",
|
|
11
|
+
"选中项":"选中项",
|
|
12
|
+
"退出":"退出",
|
|
13
|
+
"确认删除":"确认删除",
|
|
14
|
+
"确认删除该条数据吗?":"确认删除该条数据吗?",
|
|
15
|
+
"确定":"确定",
|
|
16
|
+
"取消":"取消",
|
|
17
|
+
|
|
18
|
+
"":""
|
|
19
|
+
}
|
package/nuxt.config.ts
CHANGED
|
@@ -12,11 +12,18 @@ export default defineNuxtConfig({
|
|
|
12
12
|
future: {
|
|
13
13
|
compatibilityVersion: 4
|
|
14
14
|
},
|
|
15
|
-
|
|
16
|
-
modules: ['@ant-design-vue/nuxt'],
|
|
15
|
+
modules: ['@ant-design-vue/nuxt', '@nuxtjs/i18n'],
|
|
17
16
|
extends: ['@xizs/nuxt-base'],
|
|
18
17
|
css: [join(currentDir, './app/assets/css/main.css')],
|
|
19
|
-
vite:{
|
|
18
|
+
vite: {
|
|
20
19
|
plugins: [tailwindcss()],
|
|
20
|
+
},
|
|
21
|
+
i18n: {
|
|
22
|
+
defaultLocale: 'zh',
|
|
23
|
+
strategy: 'no_prefix',
|
|
24
|
+
locales: [
|
|
25
|
+
{ code: 'en', name: 'English', file: 'en.json' },
|
|
26
|
+
{ code: 'zh', name: '中文', file: 'zh.json' }
|
|
27
|
+
]
|
|
21
28
|
}
|
|
22
29
|
})
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xizs/nuxt-antui",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.4",
|
|
5
5
|
"main": "./nuxt.config.ts",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "nuxi dev .playground",
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@ant-design-vue/nuxt": "1.4.6",
|
|
16
|
+
"@nuxtjs/i18n": "9.5.4",
|
|
16
17
|
"@tailwindcss/vite": "^4.1.3",
|
|
17
18
|
"@xizs/nuxt-base": "^0.0.4",
|
|
18
19
|
"ant-design-vue": ">=4",
|