@befly-addon/admin 1.1.29 → 1.1.30

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.
Files changed (60) hide show
  1. package/apis/admin/cacheRefresh.ts +1 -4
  2. package/apis/admin/del.ts +4 -4
  3. package/apis/admin/detail.ts +8 -40
  4. package/apis/admin/ins.ts +21 -14
  5. package/apis/admin/list.ts +3 -3
  6. package/apis/admin/upd.ts +43 -8
  7. package/apis/api/all.ts +7 -3
  8. package/apis/api/list.ts +8 -17
  9. package/apis/auth/login.ts +19 -16
  10. package/apis/dict/all.ts +21 -4
  11. package/apis/dict/del.ts +7 -15
  12. package/apis/dict/detail.ts +28 -14
  13. package/apis/dict/ins.ts +34 -16
  14. package/apis/dict/items.ts +27 -0
  15. package/apis/dict/list.ts +30 -5
  16. package/apis/dict/upd.ts +51 -17
  17. package/apis/dictType/all.ts +11 -0
  18. package/apis/dictType/del.ts +32 -0
  19. package/apis/dictType/detail.ts +17 -0
  20. package/apis/dictType/ins.ts +30 -0
  21. package/apis/dictType/list.ts +24 -0
  22. package/apis/dictType/upd.ts +42 -0
  23. package/apis/email/logList.ts +2 -2
  24. package/apis/loginLog/list.ts +2 -2
  25. package/apis/menu/all.ts +1 -2
  26. package/apis/menu/list.ts +0 -1
  27. package/apis/operateLog/list.ts +2 -2
  28. package/apis/role/apiSave.ts +4 -3
  29. package/apis/role/{apiDetail.ts → apis.ts} +8 -3
  30. package/apis/role/del.ts +18 -10
  31. package/apis/role/detail.ts +0 -1
  32. package/apis/role/menuSave.ts +4 -3
  33. package/apis/role/{menuDetail.ts → menus.ts} +8 -3
  34. package/apis/role/save.ts +2 -3
  35. package/apis/sysConfig/all.ts +0 -1
  36. package/apis/sysConfig/del.ts +1 -1
  37. package/apis/sysConfig/get.ts +1 -2
  38. package/apis/sysConfig/upd.ts +1 -1
  39. package/package.json +3 -3
  40. package/tables/admin.json +0 -6
  41. package/tables/dict.json +13 -19
  42. package/tables/dictType.json +28 -0
  43. package/views/config/dict/components/edit.vue +76 -122
  44. package/views/config/dict/index.vue +76 -54
  45. package/views/config/dict/meta.json +1 -1
  46. package/views/config/dictType/components/edit.vue +106 -0
  47. package/views/config/dictType/index.vue +206 -0
  48. package/views/config/dictType/meta.json +4 -0
  49. package/views/login_1/index.vue +184 -2
  50. package/views/people/admin/components/edit.vue +5 -5
  51. package/views/permission/role/components/api.vue +3 -3
  52. package/views/permission/role/components/menu.vue +4 -4
  53. package/apis/admin/roleDetail.ts +0 -29
  54. package/apis/admin/roleSave.ts +0 -39
  55. package/apis/auth/logout.ts +0 -17
  56. package/apis/auth/register.ts +0 -43
  57. package/apis/dashboard/changelog.ts +0 -31
  58. package/views/login_1/components/emailLoginForm.vue +0 -174
  59. package/views/login_1/components/registerForm.vue +0 -175
  60. package/views/login_1/components/welcomePanel.vue +0 -61
@@ -1,162 +1,116 @@
1
1
  <template>
2
- <TDialog v-model:visible="$Data.visible" :title="$Prop.actionType === 'upd' ? '编辑字典' : '添加字典'" width="600px" :append-to-body="true" :show-footer="true" :esc-closable="false" top="10vh" @close="$Method.onClose">
3
- <TForm :model="$Data.formData" label-width="120px" label-position="left" :rules="$Data2.formRules" :ref="(el) => ($From.form = el)">
4
- <TFormItem label="字典名称" prop="name">
5
- <TInput v-model="$Data.formData.name" placeholder="请输入字典名称" />
2
+ <TDialog v-model:visible="visible" :header="actionType === 'add' ? '添加字典项' : '编辑字典项'" width="600px" @confirm="$Method.handleSubmit" @close="$Method.handleClose">
3
+ <TForm ref="formRef" :data="$Data.formData" :rules="$Data.rules" label-width="100px">
4
+ <TFormItem label="字典类型" name="typeCode">
5
+ <TSelect v-model="$Data.formData.typeCode" placeholder="请选择字典类型" filterable>
6
+ <TOption v-for="item in typeList" :key="item.code" :value="item.code" :label="item.name" />
7
+ </TSelect>
6
8
  </TFormItem>
7
- <TFormItem label="字典代码" prop="code">
8
- <TInput v-model="$Data.formData.code" placeholder="请输入字典代码,如:gender" />
9
+ <TFormItem label="键值" name="key">
10
+ <TInput v-model="$Data.formData.key" placeholder="请输入键名(英文/数字/下划线)" />
9
11
  </TFormItem>
10
- <TFormItem label="字典值" prop="value">
11
- <TInput v-model="$Data.formData.value" placeholder="请输入字典值" />
12
+ <TFormItem label="标签" name="label">
13
+ <TInput v-model="$Data.formData.label" placeholder="请输入标签(显示名称)" />
12
14
  </TFormItem>
13
- <TFormItem label="父级ID" prop="pid">
14
- <TInputNumber v-model="$Data.formData.pid" :min="0" />
15
+ <TFormItem label="排序" name="sort">
16
+ <TInputNumber v-model="$Data.formData.sort" :min="0" placeholder="请输入排序值" />
15
17
  </TFormItem>
16
- <TFormItem label="排序" prop="sort">
17
- <TInputNumber v-model="$Data.formData.sort" :min="0" :max="9999" />
18
- </TFormItem>
19
- <TFormItem label="描述" prop="description">
20
- <TInput v-model="$Data.formData.description" type="textarea" placeholder="请输入描述" :rows="3" />
21
- </TFormItem>
22
- <TFormItem label="状态" prop="state">
23
- <TRadioGroup v-model="$Data.formData.state">
24
- <TRadio :label="1">正常</TRadio>
25
- <TRadio :label="2">禁用</TRadio>
26
- </TRadioGroup>
18
+ <TFormItem label="备注" name="remark">
19
+ <TTextarea v-model="$Data.formData.remark" placeholder="请输入备注信息" :autosize="{ minRows: 3, maxRows: 6 }" />
27
20
  </TFormItem>
28
21
  </TForm>
29
- <template #footer>
30
- <TButton @click="$Method.onClose">取消</TButton>
31
- <TButton theme="primary" :loading="$Data.submitting" @click="$Method.onSubmit">确定</TButton>
32
- </template>
33
22
  </TDialog>
34
23
  </template>
35
24
 
36
25
  <script setup>
37
- import { watch } from 'vue';
38
- import { Dialog as TDialog, Form as TForm, FormItem as TFormItem, Input as TInput, InputNumber as TInputNumber, RadioGroup as TRadioGroup, Radio as TRadio, Button as TButton, MessagePlugin } from 'tdesign-vue-next';
26
+ import { Dialog as TDialog, Form as TForm, FormItem as TFormItem, Input as TInput, Select as TSelect, Option as TOption, Textarea as TTextarea, InputNumber as TInputNumber, MessagePlugin } from 'tdesign-vue-next';
39
27
  import { $Http } from '@/plugins/http';
40
28
 
41
- const $Prop = defineProps({
42
- modelValue: {
43
- type: Boolean,
44
- default: false
45
- },
46
- actionType: {
47
- type: String,
48
- default: 'add'
49
- },
50
- rowData: {
51
- type: Object,
52
- default: {}
53
- }
29
+ const props = defineProps({
30
+ modelValue: Boolean,
31
+ actionType: String,
32
+ rowData: Object,
33
+ typeList: Array
54
34
  });
55
35
 
56
- const $Emit = defineEmits(['update:modelValue', 'success']);
36
+ const emit = defineEmits(['update:modelValue', 'success']);
57
37
 
58
- // 表单引用
59
- const $From = $shallowRef({
60
- form: null
38
+ const visible = computed({
39
+ get: () => props.modelValue,
40
+ set: (val) => emit('update:modelValue', val)
61
41
  });
62
42
 
43
+ const formRef = $ref(null);
44
+
63
45
  const $Data = $ref({
64
- visible: false,
65
- submitting: false,
66
46
  formData: {
67
- id: 0,
68
- name: '',
69
- code: '',
70
- value: '',
71
- pid: 0,
47
+ typeCode: '',
48
+ key: '',
49
+ label: '',
72
50
  sort: 0,
73
- description: '',
74
- state: 1
75
- }
76
- });
77
-
78
- const $Data2 = $shallowRef({
79
- formRules: {
80
- name: [{ required: true, message: '请输入字典名称', trigger: 'blur' }],
81
- code: [
82
- { required: true, message: '请输入字典代码', trigger: 'blur' },
83
- { pattern: /^[a-zA-Z0-9_]+$/, message: '字典代码只能包含字母、数字和下划线', trigger: 'blur' }
84
- ],
85
- value: [{ required: true, message: '请输入字典值', trigger: 'blur' }]
51
+ remark: ''
52
+ },
53
+ rules: {
54
+ typeCode: [{ required: true, message: '请选择字典类型' }],
55
+ key: [{ required: true, message: '请输入键值' }],
56
+ label: [{ required: true, message: '请输入标签' }]
86
57
  }
87
58
  });
88
59
 
89
- // 方法集合
90
60
  const $Method = {
91
- async initData() {
92
- $Method.onShow();
93
- },
94
-
95
- onShow() {
96
- $Data.visible = true;
97
- if ($Prop.actionType === 'upd' && $Prop.rowData) {
98
- $Data.formData.id = $Prop.rowData.id || 0;
99
- $Data.formData.name = $Prop.rowData.name || '';
100
- $Data.formData.code = $Prop.rowData.code || '';
101
- $Data.formData.value = $Prop.rowData.value || '';
102
- $Data.formData.pid = $Prop.rowData.pid || 0;
103
- $Data.formData.sort = $Prop.rowData.sort || 0;
104
- $Data.formData.description = $Prop.rowData.description || '';
105
- $Data.formData.state = $Prop.rowData.state ?? 1;
106
- } else {
107
- // 重置表单
108
- $Data.formData.id = 0;
109
- $Data.formData.name = '';
110
- $Data.formData.code = '';
111
- $Data.formData.value = '';
112
- $Data.formData.pid = 0;
113
- $Data.formData.sort = 0;
114
- $Data.formData.description = '';
115
- $Data.formData.state = 1;
116
- }
117
- },
118
-
119
- onClose() {
120
- $Data.visible = false;
121
- setTimeout(() => {
122
- $Emit('update:modelValue', false);
123
- }, 300);
124
- },
125
-
126
- async onSubmit() {
61
+ async handleSubmit() {
127
62
  try {
128
- const valid = await $From.form.validate();
129
- if (!valid) return;
130
-
131
- $Data.submitting = true;
132
- const res = await $Http($Prop.actionType === 'add' ? '/addon/admin/dictIns' : '/addon/admin/dictUpd', $Data.formData);
63
+ const valid = await formRef.validate();
64
+ const apiUrl = props.actionType === 'add' ? '/addon/admin/dict/ins' : '/addon/admin/dict/upd';
65
+ const params = {
66
+ typeCode: $Data.formData.typeCode,
67
+ key: $Data.formData.key,
68
+ label: $Data.formData.label,
69
+ sort: $Data.formData.sort,
70
+ remark: $Data.formData.remark
71
+ };
72
+ if (props.actionType === 'upd') {
73
+ params.id = props.rowData.id;
74
+ }
133
75
 
134
- MessagePlugin.success($Prop.actionType === 'add' ? '添加成功' : '编辑成功');
135
- $Method.onClose();
136
- $Emit('success');
76
+ const res = await $Http(apiUrl, params);
77
+ console.log('🔥[ res ]-79', res);
78
+ if (res.code === 0) {
79
+ MessagePlugin.success(props.actionType === 'add' ? '添加成功' : '更新成功');
80
+ visible.value = false;
81
+ emit('success');
82
+ } else {
83
+ MessagePlugin.error(res.msg || '操作失败');
84
+ }
137
85
  } catch (error) {
138
86
  console.error('提交失败:', error);
139
- MessagePlugin.error('提交失败');
140
- } finally {
141
- $Data.submitting = false;
87
+ MessagePlugin.error('操作失败');
142
88
  }
89
+ },
90
+ handleClose() {
91
+ visible.value = false;
143
92
  }
144
93
  };
145
94
 
146
- // 监听 modelValue 变化
147
95
  watch(
148
- () => $Prop.modelValue,
96
+ () => props.modelValue,
149
97
  (val) => {
150
- if (val && !$Data.visible) {
151
- $Method.initData();
152
- } else if (!val && $Data.visible) {
153
- $Data.visible = false;
98
+ if (val) {
99
+ if (props.actionType === 'upd' && props.rowData) {
100
+ $Data.formData.typeCode = props.rowData.typeCode || '';
101
+ $Data.formData.key = props.rowData.key || '';
102
+ $Data.formData.label = props.rowData.label || '';
103
+ $Data.formData.sort = props.rowData.sort || 0;
104
+ $Data.formData.remark = props.rowData.remark || '';
105
+ } else {
106
+ $Data.formData.typeCode = '';
107
+ $Data.formData.key = '';
108
+ $Data.formData.label = '';
109
+ $Data.formData.sort = 0;
110
+ $Data.formData.remark = '';
111
+ }
154
112
  }
155
113
  },
156
114
  { immediate: true }
157
115
  );
158
116
  </script>
159
-
160
- <style scoped lang="scss">
161
- // 可根据需要添加样式
162
- </style>
@@ -9,6 +9,14 @@
9
9
  </TButton>
10
10
  </div>
11
11
  <div class="right">
12
+ <TSelect v-model="$Data.searchTypeCode" placeholder="请选择字典类型" clearable filterable @change="$Method.handleSearch">
13
+ <TOption v-for="item in $Data.typeList" :key="item.code" :value="item.code" :label="item.name" />
14
+ </TSelect>
15
+ <TInput v-model="$Data.searchKeyword" placeholder="搜索键/标签" clearable @enter="$Method.handleSearch" @clear="$Method.handleSearch">
16
+ <template #suffix-icon>
17
+ <ILucideSearch />
18
+ </template>
19
+ </TInput>
12
20
  <TButton shape="circle" @click="$Method.handleRefresh">
13
21
  <template #icon>
14
22
  <ILucideRotateCw />
@@ -18,12 +26,7 @@
18
26
  </div>
19
27
  <div class="main-content">
20
28
  <div class="main-table">
21
- <TTable :data="$Data.dictList" :columns="$Data.columns" :loading="$Data.loading" :active-row-keys="$Data.activeRowKeys" row-key="id" height="calc(100vh - var(--search-height) - var(--pagination-height) - var(--layout-gap) * 4)" active-row-type="single" @active-change="$Method.onActiveChange">
22
- <template #state="{ row }">
23
- <TTag v-if="row.state === 1" shape="round" theme="success" variant="light-outline">正常</TTag>
24
- <TTag v-else-if="row.state === 2" shape="round" theme="warning" variant="light-outline">禁用</TTag>
25
- <TTag v-else shape="round" theme="danger" variant="light-outline">已删除</TTag>
26
- </template>
29
+ <TTable :data="$Data.tableData" :columns="$Data.columns" :loading="$Data.loading" :active-row-keys="$Data.activeRowKeys" row-key="id" height="calc(100vh - var(--search-height) - var(--pagination-height) - var(--layout-gap) * 4)" active-row-type="single" @active-change="$Method.onActiveChange">
27
30
  <template #operation="{ row }">
28
31
  <TDropdown trigger="click" placement="bottom-right" @click="(data) => $Method.onAction(data.value, row)">
29
32
  <TButton theme="primary" size="small">
@@ -54,15 +57,15 @@
54
57
  <TPagination :current-page="$Data.pagerConfig.currentPage" :page-size="$Data.pagerConfig.limit" :total="$Data.pagerConfig.total" @current-change="$Method.onPageChange" @page-size-change="$Method.handleSizeChange" />
55
58
  </div>
56
59
 
57
- <!-- 编辑对话框组件 -->
58
- <EditDialog v-if="$Data.editVisible" v-model="$Data.editVisible" :action-type="$Data.actionType" :row-data="$Data.rowData" @success="$Method.apiDictList" />
60
+ <EditDialog v-if="$Data.editVisible" v-model="$Data.editVisible" :action-type="$Data.actionType" :row-data="$Data.rowData" :type-list="$Data.typeList" @success="$Method.apiDictList" />
59
61
  </div>
60
62
  </template>
61
63
 
62
64
  <script setup>
63
- import { Button as TButton, Table as TTable, Tag as TTag, Dropdown as TDropdown, DropdownMenu as TDropdownMenu, DropdownItem as TDropdownItem, Pagination as TPagination, MessagePlugin, DialogPlugin } from 'tdesign-vue-next';
65
+ import { Button as TButton, Table as TTable, Input as TInput, Select as TSelect, Option as TOption, Dropdown as TDropdown, DropdownMenu as TDropdownMenu, DropdownItem as TDropdownItem, Pagination as TPagination, MessagePlugin, DialogPlugin } from 'tdesign-vue-next';
64
66
  import ILucidePlus from '~icons/lucide/plus';
65
67
  import ILucideRotateCw from '~icons/lucide/rotate-cw';
68
+ import ILucideSearch from '~icons/lucide/search';
66
69
  import ILucidePencil from '~icons/lucide/pencil';
67
70
  import ILucideTrash2 from '~icons/lucide/trash-2';
68
71
  import ILucideChevronDown from '~icons/lucide/chevron-down';
@@ -71,21 +74,22 @@ import DetailPanel from '@/components/DetailPanel.vue';
71
74
  import { $Http } from '@/plugins/http';
72
75
  import { withDefaultColumns } from 'befly-shared/withDefaultColumns';
73
76
 
74
- // 响应式数据
75
77
  const $Data = $ref({
76
- dictList: [],
78
+ tableData: [],
79
+ typeList: [],
77
80
  loading: false,
78
81
  activeRowKeys: [],
79
82
  currentRow: null,
83
+ searchTypeCode: '',
84
+ searchKeyword: '',
80
85
  columns: withDefaultColumns([
81
- { colKey: 'index', title: '序号' },
82
- { colKey: 'name', title: '字典名称' },
83
- { colKey: 'code', title: '字典代码' },
84
- { colKey: 'value', title: '字典值' },
85
- { colKey: 'pid', title: '父级ID' },
86
- { colKey: 'sort', title: '排序' },
87
- { colKey: 'description', title: '描述' },
88
- { colKey: 'state', title: '状态' },
86
+ { colKey: 'id', title: 'ID' },
87
+ { colKey: 'typeName', title: '类型名称' },
88
+ { colKey: 'typeCode', title: '类型代码' },
89
+ { colKey: 'label', title: '标签' },
90
+ { colKey: 'key', title: '键值' },
91
+ { colKey: 'sort', title: '排序', width: 100 },
92
+ { colKey: 'remark', title: '备注' },
89
93
  { colKey: 'operation', title: '操作' }
90
94
  ]),
91
95
  pagerConfig: {
@@ -100,27 +104,34 @@ const $Data = $ref({
100
104
  rowData: {}
101
105
  });
102
106
 
103
- // 方法
104
107
  const $Method = {
105
108
  async initData() {
109
+ await $Method.apiDictTypeAll();
106
110
  await $Method.apiDictList();
107
111
  },
108
-
109
- // 加载字典列表
112
+ async apiDictTypeAll() {
113
+ try {
114
+ const res = await $Http('/addon/admin/dictType/all');
115
+ $Data.typeList = res.data.lists || [];
116
+ } catch (error) {
117
+ console.error('加载字典类型列表失败:', error);
118
+ }
119
+ },
110
120
  async apiDictList() {
111
121
  $Data.loading = true;
112
122
  try {
113
123
  const res = await $Http('/addon/admin/dict/list', {
114
124
  page: $Data.pagerConfig.currentPage,
115
- limit: $Data.pagerConfig.limit
125
+ limit: $Data.pagerConfig.limit,
126
+ typeCode: $Data.searchTypeCode,
127
+ keyword: $Data.searchKeyword
116
128
  });
117
- $Data.dictList = res.data.lists || [];
129
+ $Data.tableData = res.data.lists || [];
118
130
  $Data.pagerConfig.total = res.data.total || 0;
119
131
 
120
- // 自动选中并高亮第一行
121
- if ($Data.dictList.length > 0) {
122
- $Data.currentRow = $Data.dictList[0];
123
- $Data.activeRowKeys = [$Data.dictList[0].id];
132
+ if ($Data.tableData.length > 0) {
133
+ $Data.currentRow = $Data.tableData[0];
134
+ $Data.activeRowKeys = [$Data.tableData[0].id];
124
135
  } else {
125
136
  $Data.currentRow = null;
126
137
  $Data.activeRowKeys = [];
@@ -132,12 +143,10 @@ const $Method = {
132
143
  $Data.loading = false;
133
144
  }
134
145
  },
135
-
136
- // 删除字典
137
146
  async apiDictDel(row) {
138
147
  DialogPlugin.confirm({
139
148
  header: '确认删除',
140
- body: `确定要删除字典“${row.name}吗?`,
149
+ body: `确定要删除字典项"${row.label}"吗?`,
141
150
  status: 'warning'
142
151
  }).then(async () => {
143
152
  try {
@@ -154,53 +163,66 @@ const $Method = {
154
163
  }
155
164
  });
156
165
  },
157
-
158
- // 刷新
166
+ handleSearch() {
167
+ $Data.pagerConfig.currentPage = 1;
168
+ $Method.apiDictList();
169
+ },
159
170
  handleRefresh() {
171
+ $Data.searchTypeCode = '';
172
+ $Data.searchKeyword = '';
173
+ $Data.pagerConfig.currentPage = 1;
160
174
  $Method.apiDictList();
161
175
  },
162
-
163
- // 分页改变
164
176
  onPageChange({ currentPage }) {
165
177
  $Data.pagerConfig.currentPage = currentPage;
166
178
  $Method.apiDictList();
167
179
  },
168
-
169
- // 每页条数改变
170
180
  handleSizeChange({ pageSize }) {
171
181
  $Data.pagerConfig.limit = pageSize;
172
182
  $Data.pagerConfig.currentPage = 1;
173
183
  $Method.apiDictList();
174
184
  },
175
-
176
- // 高亮行变化
177
185
  onActiveChange(value, context) {
178
- // 禁止取消高亮:如果新值为空,保持当前选中
179
186
  if (value.length === 0 && $Data.activeRowKeys.length > 0) {
180
187
  return;
181
188
  }
182
189
  $Data.activeRowKeys = value;
183
- // 更新当前高亮的行数据
184
- if (context.activeRowList && context.activeRowList.length > 0) {
185
- $Data.currentRow = context.activeRowList[0].row;
186
- }
190
+ $Data.currentRow = context.currentRowData;
187
191
  },
188
-
189
- // 操作菜单点击
190
- onAction(command, rowData) {
191
- $Data.actionType = command;
192
- $Data.rowData = rowData;
193
- if (command === 'add' || command === 'upd') {
192
+ onAction(type, row) {
193
+ if (type === 'add') {
194
+ $Data.actionType = 'add';
195
+ $Data.rowData = {};
194
196
  $Data.editVisible = true;
195
- } else if (command === 'del') {
196
- $Method.apiDictDel(rowData);
197
+ } else if (type === 'upd') {
198
+ $Data.actionType = 'upd';
199
+ $Data.rowData = { ...row };
200
+ $Data.editVisible = true;
201
+ } else if (type === 'del') {
202
+ $Method.apiDictDel(row);
197
203
  }
198
204
  }
199
205
  };
200
206
 
201
- $Method.initData();
207
+ onMounted(() => {
208
+ $Method.initData();
209
+ });
202
210
  </script>
203
211
 
204
212
  <style scoped lang="scss">
205
- // 样式继承自全局 page-table
213
+ .page-dict {
214
+ .main-tool .right {
215
+ display: flex;
216
+ gap: 8px;
217
+ align-items: center;
218
+
219
+ .t-select {
220
+ width: 200px;
221
+ }
222
+
223
+ .t-input {
224
+ width: 240px;
225
+ }
226
+ }
227
+ }
206
228
  </style>
@@ -1,4 +1,4 @@
1
1
  {
2
- "name": "字典配置",
2
+ "name": "字典列表",
3
3
  "order": 1
4
4
  }
@@ -0,0 +1,106 @@
1
+ <template>
2
+ <TDialog v-model:visible="visible" :header="actionType === 'add' ? '添加字典类型' : '编辑字典类型'" width="600px" @confirm="$Method.handleSubmit" @close="$Method.handleClose">
3
+ <TForm ref="formRef" :data="$Data.formData" :rules="$Data.rules" label-width="100px">
4
+ <TFormItem label="类型代码" name="code">
5
+ <TInput v-model="$Data.formData.code" placeholder="请输入类型代码(英文/数字/下划线)" :disabled="actionType === 'upd'" />
6
+ </TFormItem>
7
+ <TFormItem label="类型名称" name="name">
8
+ <TInput v-model="$Data.formData.name" placeholder="请输入类型名称" />
9
+ </TFormItem>
10
+ <TFormItem label="描述" name="description">
11
+ <TTextarea v-model="$Data.formData.description" placeholder="请输入描述信息" :autosize="{ minRows: 3, maxRows: 6 }" />
12
+ </TFormItem>
13
+ <TFormItem label="排序" name="sort">
14
+ <TInputNumber v-model="$Data.formData.sort" :min="0" placeholder="请输入排序值" />
15
+ </TFormItem>
16
+ </TForm>
17
+ </TDialog>
18
+ </template>
19
+
20
+ <script setup>
21
+ import { Dialog as TDialog, Form as TForm, FormItem as TFormItem, Input as TInput, Textarea as TTextarea, InputNumber as TInputNumber, MessagePlugin } from 'tdesign-vue-next';
22
+ import { $Http } from '@/plugins/http';
23
+
24
+ const props = defineProps({
25
+ modelValue: Boolean,
26
+ actionType: String,
27
+ rowData: Object
28
+ });
29
+
30
+ const emit = defineEmits(['update:modelValue', 'success']);
31
+
32
+ const visible = computed({
33
+ get: () => props.modelValue,
34
+ set: (val) => emit('update:modelValue', val)
35
+ });
36
+
37
+ const formRef = $ref(null);
38
+
39
+ const $Data = $ref({
40
+ formData: {
41
+ code: '',
42
+ name: '',
43
+ description: '',
44
+ sort: 0
45
+ },
46
+ rules: {
47
+ code: [{ required: true, message: '请输入类型代码' }],
48
+ name: [{ required: true, message: '请输入类型名称' }]
49
+ }
50
+ });
51
+
52
+ const $Method = {
53
+ async handleSubmit() {
54
+ const valid = await formRef.validate();
55
+ if (!valid) return;
56
+
57
+ try {
58
+ const apiUrl = props.actionType === 'add' ? '/addon/admin/dictType/ins' : '/addon/admin/dictType/upd';
59
+ const params = {
60
+ code: $Data.formData.code,
61
+ name: $Data.formData.name,
62
+ description: $Data.formData.description,
63
+ sort: $Data.formData.sort
64
+ };
65
+ if (props.actionType === 'upd') {
66
+ params.id = props.rowData.id;
67
+ }
68
+
69
+ const res = await $Http(apiUrl, params);
70
+ if (res.code === 0) {
71
+ MessagePlugin.success(props.actionType === 'add' ? '添加成功' : '更新成功');
72
+ visible.value = false;
73
+ emit('success');
74
+ } else {
75
+ MessagePlugin.error(res.msg || '操作失败');
76
+ }
77
+ } catch (error) {
78
+ console.error('提交失败:', error);
79
+ MessagePlugin.error('操作失败');
80
+ }
81
+ },
82
+ handleClose() {
83
+ visible.value = false;
84
+ }
85
+ };
86
+
87
+ watch(
88
+ () => props.modelValue,
89
+ (val) => {
90
+ if (val) {
91
+ if (props.actionType === 'upd' && props.rowData) {
92
+ $Data.formData.code = props.rowData.code || '';
93
+ $Data.formData.name = props.rowData.name || '';
94
+ $Data.formData.description = props.rowData.description || '';
95
+ $Data.formData.sort = props.rowData.sort || 0;
96
+ } else {
97
+ $Data.formData.code = '';
98
+ $Data.formData.name = '';
99
+ $Data.formData.description = '';
100
+ $Data.formData.sort = 0;
101
+ }
102
+ }
103
+ },
104
+ { immediate: true }
105
+ );
106
+ </script>