@xizs/nuxt-antui 0.0.3 → 0.0.5
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 +24 -19
- package/app/components/global/FormTable.tsx +166 -172
- package/app/components/layout/Base.vue +19 -112
- package/app/composables/modal.ts +9 -8
- package/app/composables/table.ts +12 -4
- package/i18n/locales/en.json +19 -0
- package/i18n/locales/zh.json +19 -0
- package/nuxt.config.ts +10 -3
- package/package.json +3 -2
|
@@ -2,7 +2,8 @@ import { AForm, AFormItem, AInput, ASelect,AInputNumber, LineOutlined, ASwitch,
|
|
|
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,42 +17,39 @@ 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>
|
|
22
25
|
},
|
|
23
26
|
button:(form:any,item:FormItemType)=>{
|
|
24
27
|
console.log(item.bind)
|
|
25
28
|
return <AButton {...item.bind}>{ item.bind.content}</AButton>
|
|
26
29
|
},
|
|
27
30
|
textarea:(form:any,item:FormItemType)=>{
|
|
28
|
-
return <ATextarea v-model:value={form[item.key]}></ATextarea>
|
|
31
|
+
return <ATextarea v-model:value={form[item.key as string]}></ATextarea>
|
|
29
32
|
},
|
|
30
33
|
inputNumber:(form:any,item:FormItemType)=>{
|
|
31
|
-
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>
|
|
32
35
|
},
|
|
33
36
|
inputNumberRange:(form:any,item:FormItemType)=>{
|
|
34
37
|
return <div class="flex items-center gap-2">
|
|
35
|
-
<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>
|
|
36
39
|
<LineOutlined />
|
|
37
|
-
<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>
|
|
38
41
|
</div>
|
|
39
42
|
},
|
|
40
43
|
select:(form:any,item:FormItemType)=>{
|
|
41
|
-
return <ASelect v-model:value={form[item.key]} options={item.bind.options}></ASelect>
|
|
42
|
-
},
|
|
43
|
-
countrySelect:(form:any,item:FormItemType)=>{
|
|
44
|
-
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>
|
|
45
45
|
},
|
|
46
46
|
switch:(form:any,item:FormItemType)=>{
|
|
47
|
-
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>
|
|
48
48
|
},
|
|
49
49
|
radio: (form: any, item: FormItemType) => {
|
|
50
|
-
return <ARadioGroup v-model:value={form[item.key]} {...item.bind}></ARadioGroup>
|
|
50
|
+
return <ARadioGroup v-model:value={form[item.key as string]} {...item.bind}></ARadioGroup>
|
|
51
51
|
},
|
|
52
|
-
|
|
53
|
-
return <UploadImg v-model:value={form[item.key]} {...item.bind}></UploadImg>
|
|
54
|
-
}
|
|
52
|
+
|
|
55
53
|
}
|
|
56
54
|
|
|
57
55
|
export default defineComponent({
|
|
@@ -77,7 +75,9 @@ export default defineComponent({
|
|
|
77
75
|
default: () => ({})
|
|
78
76
|
}
|
|
79
77
|
},
|
|
80
|
-
setup(props,{expose}){
|
|
78
|
+
setup(props, { expose }) {
|
|
79
|
+
|
|
80
|
+
const {t:$t} = useI18n()
|
|
81
81
|
|
|
82
82
|
let thisRef = ref(null)
|
|
83
83
|
let formData = ref(props.defaultFormData)
|
|
@@ -124,7 +124,7 @@ export default defineComponent({
|
|
|
124
124
|
|
|
125
125
|
|
|
126
126
|
|
|
127
|
-
return ()=><AForm ref={thisRef} model={formData.value} rules={rules.value} label-col={{ span:
|
|
127
|
+
return ()=><AForm ref={thisRef} model={formData.value} rules={rules.value} label-col={{ span: 8 }} wrapper-col={{ span: 16 }}>
|
|
128
128
|
{/* {JSON.stringify(formData.value)} */}
|
|
129
129
|
{
|
|
130
130
|
ADParse(props.form, formData.value).map(item => {
|
|
@@ -132,7 +132,12 @@ export default defineComponent({
|
|
|
132
132
|
return typeof item.is === 'function'? item.is(formData.value) :
|
|
133
133
|
FormComs[item.is](formData.value,item)
|
|
134
134
|
}
|
|
135
|
-
return <AFormItem
|
|
135
|
+
return <AFormItem
|
|
136
|
+
key={item.key} name={item.key} {...item.bind} class={{ 'hidden': item.show === false }}
|
|
137
|
+
v-slots={{
|
|
138
|
+
label:()=><span class="whitespace-break-spaces">{$t(item.label)}</span>
|
|
139
|
+
}}
|
|
140
|
+
>
|
|
136
141
|
{
|
|
137
142
|
typeof item.is === 'function'? item.is(formData.value) :
|
|
138
143
|
FormComs[item.is](formData.value,item)
|
|
@@ -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] as string] = nv[0].format('YYYY-MM-DD 00:00:00')
|
|
30
|
+
props.form[props.item.key[1] as string] = nv[1].format('YYYY-MM-DD 23:59:59')
|
|
31
|
+
}else{
|
|
32
|
+
props.form[props.item.key[0] as string] = ''
|
|
33
|
+
props.form[props.item.key[1] as string] = ''
|
|
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
|
|
|
@@ -73,14 +76,17 @@ export type TablePropsType = {
|
|
|
73
76
|
},
|
|
74
77
|
footerOptions?: {
|
|
75
78
|
show: boolean
|
|
76
|
-
}
|
|
79
|
+
},
|
|
80
|
+
'v-slots'?:any
|
|
77
81
|
}
|
|
78
82
|
|
|
79
83
|
export type AttributeType = {
|
|
80
84
|
selectItems:any[],
|
|
81
85
|
selectKeys:any[],
|
|
82
86
|
page:number,
|
|
83
|
-
pageSize:number
|
|
87
|
+
pageSize: number,
|
|
88
|
+
tableData: any[],
|
|
89
|
+
form:any
|
|
84
90
|
}
|
|
85
91
|
|
|
86
92
|
export const FormTableProps = {
|
|
@@ -116,7 +122,7 @@ export const FormTableProps = {
|
|
|
116
122
|
enableSelection: false,
|
|
117
123
|
columns: [],
|
|
118
124
|
data: () => [],
|
|
119
|
-
rowKey:(row:any)=>
|
|
125
|
+
rowKey:(row:any)=>{}
|
|
120
126
|
})
|
|
121
127
|
},
|
|
122
128
|
footerOptions: {
|
|
@@ -128,157 +134,145 @@ export const FormTableProps = {
|
|
|
128
134
|
})
|
|
129
135
|
},
|
|
130
136
|
attribute:{
|
|
131
|
-
|
|
137
|
+
type: Object as () => AttributeType,
|
|
138
|
+
default:()=>{}
|
|
132
139
|
},
|
|
133
140
|
control:{
|
|
134
|
-
type:Object,
|
|
141
|
+
type:Object as () => any,
|
|
135
142
|
required:true
|
|
136
143
|
},
|
|
137
144
|
}
|
|
138
145
|
|
|
139
146
|
export default defineComponent({
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
147
|
+
name: 'TableLayout',
|
|
148
|
+
props: FormTableProps,
|
|
149
|
+
setup(props,{slots}) {
|
|
150
|
+
const {t:$t} = useI18n()
|
|
143
151
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
pageSize:20,
|
|
152
|
-
total:0
|
|
153
|
-
})
|
|
152
|
+
//form 初始化
|
|
153
|
+
const form = ref({})
|
|
154
|
+
props.form?.forEach((item) => {
|
|
155
|
+
form.value[item.key] = item.value
|
|
156
|
+
})
|
|
157
|
+
props.attribute.form = form.value
|
|
158
|
+
const metaForm = JSON.parse(JSON.stringify(form.value))
|
|
154
159
|
|
|
160
|
+
//table初始化
|
|
161
|
+
props.table.columns?.forEach((item) => {
|
|
162
|
+
item.title = $t(item.title)
|
|
163
|
+
})
|
|
155
164
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
meta:{
|
|
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
|
-
},[])
|
|
165
|
+
let pagination =reactive({
|
|
166
|
+
page:1,
|
|
167
|
+
pageSize:20,
|
|
168
|
+
total:0
|
|
169
|
+
})
|
|
178
170
|
|
|
179
171
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
return () => (
|
|
192
|
-
<div class="flex flex-col gap-2 h-full ">
|
|
193
|
-
{/* {JSON.stringify(form.value)} */}
|
|
194
|
-
{props.form&&<AForm layout="inline gap-2">
|
|
195
|
-
{props.form?.map((item) => {
|
|
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>}
|
|
210
|
-
|
|
211
|
-
<div class="flex items-center justify-between">
|
|
212
|
-
<div>{props.action.other}</div>
|
|
213
|
-
|
|
214
|
-
{/* <div class="flex gap-2">
|
|
215
|
-
{props.action.search && <AButton type="primary" onClick={()=>tableData.load()}>搜索</AButton>}
|
|
216
|
-
{props.action.reset && <AButton>重置</AButton>}
|
|
217
|
-
{props.action.export && <AButton type="primary">导出</AButton>}
|
|
218
|
-
</div> */}
|
|
219
|
-
</div>
|
|
220
|
-
{/* <a-descriptions bordered size="small" column={5} layout="vertical">
|
|
221
|
-
<a-descriptions-item label="游玩人数">33</a-descriptions-item>
|
|
222
|
-
<a-descriptions-item label="游玩人次">1810000000</a-descriptions-item>
|
|
223
|
-
<a-descriptions-item label="转入/下注">33</a-descriptions-item>
|
|
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)
|
|
172
|
+
const tableData = asyncReactive<any[]>(async ()=>{
|
|
173
|
+
let res:any = await props.table.data({...form.value,...pagination})
|
|
174
|
+
if(Array.isArray(res)){
|
|
175
|
+
res = {
|
|
176
|
+
list:res,
|
|
177
|
+
meta:{
|
|
178
|
+
pagination:{
|
|
179
|
+
total:0,
|
|
180
|
+
per_page:pagination.pageSize,
|
|
181
|
+
current_page:pagination.page
|
|
245
182
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
pagination.total = res.meta.pagination.total
|
|
187
|
+
pagination.pageSize = res.meta.pagination.per_page
|
|
188
|
+
pagination.page = res.meta.pagination.current_page
|
|
189
|
+
props.attribute.tableData = res.list
|
|
190
|
+
return res.list
|
|
191
|
+
},[])
|
|
249
192
|
|
|
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
193
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
194
|
+
const rowSelection = {
|
|
195
|
+
selectedRowKeys: props.attribute?.selectKeys,
|
|
196
|
+
onChange: (keys:any,rows:any)=>{
|
|
197
|
+
props.attribute!.selectKeys.splice(0,props.attribute!.selectKeys.length,...keys)
|
|
198
|
+
props.attribute!.selectItems.splice(0,props.attribute!.selectItems.length,...rows)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
280
201
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
202
|
+
props.control.refresh = ()=>tableData.load()
|
|
203
|
+
|
|
204
|
+
return () => (
|
|
205
|
+
<div class="flex flex-col gap-2 h-full ">
|
|
206
|
+
{props.form&&<AForm layout="inline gap-2">
|
|
207
|
+
{props.form?.map((item) => {
|
|
208
|
+
form[item.key] = item.value?? ''
|
|
209
|
+
return (
|
|
210
|
+
<AFormItem label={$t(item.label)}>
|
|
211
|
+
{FormItems[item.is](form.value,item)}
|
|
212
|
+
</AFormItem>
|
|
213
|
+
)
|
|
214
|
+
})}
|
|
215
|
+
<div class="flex gap-2">
|
|
216
|
+
{props.formOptions.search && <AButton type="primary" onClick={()=>tableData.load()}>{$t('搜索')}</AButton>}
|
|
217
|
+
{props.formOptions.reset && <AButton onClick={() => patch(metaForm,form.value)}>{$t('重置')}</AButton>}
|
|
218
|
+
{props.formOptions.export && <AButton type="primary">{$t('导出')}</AButton>}
|
|
219
|
+
</div>
|
|
220
|
+
</AForm>}
|
|
221
|
+
{slots.center?.()}
|
|
222
|
+
<div class="flex-1 overflow-scroll flex flex-col">
|
|
223
|
+
{slots.content?.(tableData.value) ??
|
|
224
|
+
<ATable
|
|
225
|
+
row-selection={props.table.enableSelection?rowSelection:null}
|
|
226
|
+
rowKey={props.table.rowKey??((row,key)=>key)}
|
|
227
|
+
loading={tableData.loading}
|
|
228
|
+
// scroll={{x: true}}
|
|
229
|
+
columns={props.table.columns}
|
|
230
|
+
pagination={false}
|
|
231
|
+
// sticky={tableData.value.length>0}
|
|
232
|
+
v-slots={{
|
|
233
|
+
headerCell: ({ title,column }: any) => (
|
|
234
|
+
<div style={{'white-space': 'nowrap'}}>
|
|
235
|
+
{title}
|
|
236
|
+
</div>
|
|
237
|
+
),
|
|
238
|
+
bodyCell:(row)=>{
|
|
239
|
+
if(row.column?.customRender!=null){
|
|
240
|
+
return row.column.customRender(row)
|
|
241
|
+
}
|
|
242
|
+
return <div class="whitespace-nowrap" style={{ width:row.column.width??'100px'}}>{row.text}</div>
|
|
243
|
+
},
|
|
244
|
+
...props.table['v-slots']
|
|
245
|
+
}}
|
|
246
|
+
dataSource={tableData.value}
|
|
247
|
+
/>
|
|
248
|
+
}
|
|
249
|
+
</div>
|
|
250
|
+
|
|
251
|
+
{props.footerOptions.show && <div class="mt-3 flex items-center justify-between">
|
|
252
|
+
<div>
|
|
253
|
+
{ props.table.enableSelection && (`${$t('选中项')}: ${props.attribute.selectKeys.length}`)}
|
|
254
|
+
</div>
|
|
255
|
+
<div class="flex items-center gap-2">
|
|
256
|
+
<APagination
|
|
257
|
+
hideOnSinglePage={true}
|
|
258
|
+
v-model:current={pagination.page}
|
|
259
|
+
total={pagination.total}
|
|
260
|
+
pageSize={pagination.pageSize}
|
|
261
|
+
onChange={(page) => {
|
|
262
|
+
pagination.page = page
|
|
263
|
+
tableData.load()
|
|
264
|
+
}}
|
|
265
|
+
pageSizeOptions={['20','50','100']}
|
|
266
|
+
onShowSizeChange={(current, size) => {
|
|
267
|
+
pagination.pageSize = size
|
|
268
|
+
pagination.page = 1
|
|
269
|
+
tableData.load()
|
|
270
|
+
}}
|
|
271
|
+
/>
|
|
272
|
+
<AButton icon={h(RedoOutlined)} loading={tableData.loading} onClick={tableData.load} />
|
|
273
|
+
</div>
|
|
274
|
+
</div>}
|
|
275
|
+
</div>
|
|
276
|
+
)
|
|
277
|
+
}
|
|
284
278
|
})
|
|
@@ -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>
|
|
@@ -30,11 +27,25 @@
|
|
|
30
27
|
<div class=" flex items-center">
|
|
31
28
|
<div >
|
|
32
29
|
<a-dropdown >
|
|
33
|
-
<div class="h-[30px] leading-[30px]">{{ useAdmin().value?.username ?? 'Admin'}}</div>
|
|
30
|
+
<div class="h-[30px] leading-[30px] cursor-pointer">{{ useAdmin().value?.username ?? 'Admin'}}</div>
|
|
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/modal.ts
CHANGED
|
@@ -84,6 +84,7 @@ export const FormModal = (params: FormModalParamsType) => {
|
|
|
84
84
|
|
|
85
85
|
let control = NormalModal(h(defineComponent({
|
|
86
86
|
setup() {
|
|
87
|
+
const { t: $t } = useI18n()
|
|
87
88
|
let formRef = ref(null)
|
|
88
89
|
let loading = ref(false)
|
|
89
90
|
|
|
@@ -101,16 +102,15 @@ export const FormModal = (params: FormModalParamsType) => {
|
|
|
101
102
|
})
|
|
102
103
|
|
|
103
104
|
return () => h(AModal, {
|
|
104
|
-
title: params.title,
|
|
105
|
+
title: $t(params.title),
|
|
105
106
|
width: params.width,
|
|
106
|
-
okText: '提交',
|
|
107
|
-
cancelText: '取消',
|
|
107
|
+
okText: $t('提交'),
|
|
108
|
+
cancelText: $t('取消'),
|
|
108
109
|
confirmLoading: loading.value,
|
|
109
110
|
onOk: async () => {
|
|
110
111
|
await submit()
|
|
111
112
|
control.close()
|
|
112
113
|
}
|
|
113
|
-
|
|
114
114
|
}, h(Form, {
|
|
115
115
|
ref: formRef,
|
|
116
116
|
form: params.form,
|
|
@@ -129,12 +129,13 @@ export const MModal = {
|
|
|
129
129
|
|
|
130
130
|
export const Confirm = {
|
|
131
131
|
delete: () => {
|
|
132
|
+
// const { t: $t } = useI18n()
|
|
132
133
|
return new Promise((resolve, reject) => {
|
|
133
134
|
Modal.confirm({
|
|
134
|
-
title: '确认删除',
|
|
135
|
-
content: '确认删除该条数据吗?',
|
|
136
|
-
okText: '确定',
|
|
137
|
-
cancelText: '取消',
|
|
135
|
+
title: ('确认删除'),
|
|
136
|
+
content: ('确认删除该条数据吗?'),
|
|
137
|
+
okText: ('确定'),
|
|
138
|
+
cancelText: ('取消'),
|
|
138
139
|
onOk: () => {
|
|
139
140
|
resolve(true)
|
|
140
141
|
},
|
package/app/composables/table.ts
CHANGED
|
@@ -9,15 +9,17 @@ export const FormTable = (props: TablePropsType) => {
|
|
|
9
9
|
selectItems: [],
|
|
10
10
|
selectKeys: [],
|
|
11
11
|
page: 1,
|
|
12
|
-
pageSize: 10
|
|
12
|
+
pageSize: 10,
|
|
13
|
+
tableData: [],
|
|
14
|
+
form: {}
|
|
13
15
|
})
|
|
14
16
|
|
|
15
17
|
const control = {
|
|
16
18
|
refresh: () => { }
|
|
17
19
|
}
|
|
18
|
-
|
|
20
|
+
console.log({ ...props, attribute, control })
|
|
19
21
|
return {
|
|
20
|
-
com: h(FormTableCom, { ...props, attribute, control }),
|
|
22
|
+
com: h(FormTableCom, { ...props, attribute, control }, props['v-slots']),
|
|
21
23
|
attribute,
|
|
22
24
|
control
|
|
23
25
|
}
|
|
@@ -28,7 +30,13 @@ export const TablePage = (props: TablePropsType) => {
|
|
|
28
30
|
|
|
29
31
|
return {
|
|
30
32
|
...TableParams,
|
|
31
|
-
com: h(ACard, { class: "absolute top-0 left-0 right-0 bottom-0 h-full", bodyStyle:
|
|
33
|
+
com: h(ACard, { class: "absolute top-0 left-0 right-0 bottom-0 h-full", bodyStyle: { height: '100%' } }, TableParams.com)
|
|
32
34
|
|
|
33
35
|
}
|
|
34
36
|
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
export const Table = {
|
|
40
|
+
Normal: FormTable,
|
|
41
|
+
Page: TablePage
|
|
42
|
+
}
|
|
@@ -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.5",
|
|
5
5
|
"main": "./nuxt.config.ts",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "nuxi dev .playground",
|
|
@@ -13,8 +13,9 @@
|
|
|
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
|
-
"@xizs/nuxt-base": "
|
|
18
|
+
"@xizs/nuxt-base": "0.0.4",
|
|
18
19
|
"ant-design-vue": ">=4",
|
|
19
20
|
"nuxt": "^3.16.2",
|
|
20
21
|
"tailwindcss": "^4.0.14",
|