p-pc-ui 1.2.2 → 1.2.3

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.
@@ -277,16 +277,13 @@ const getFormData = async (options: { no_check?: Boolean } = {}) => {
277
277
  // 上传到oss
278
278
  else if (renderItem.type == "uploadOss") {
279
279
  const fileData = toRaw(formData[key]);
280
- console.log("asdasdasd", fileData);
281
280
  const keys = fileData.map((val)=>{return val?.response?.key || val.key});
282
281
  returnFormData[key] = renderItem?.fieldType == "string" ? keys[0] : keys;
283
282
  }
284
283
  // 获取file对象
285
284
  else if (renderItem.type == "upload") {
286
- console.log("上传数据", formState[key]);
287
285
  const formatData = formState[key].map((val) => ({ base64: val.thumbUrl, file: val.originFileObj }));
288
286
  returnFormData[key] = formatData;
289
- console.log(formatData);
290
287
  }
291
288
 
292
289
  // 处理富文本字段
@@ -341,8 +338,6 @@ const uploadChange = (e, renderItem) => {
341
338
  // }
342
339
  // }
343
340
 
344
- console.log(fileList);
345
-
346
341
  formState[renderItem.key] = fileList;
347
342
  };
348
343
 
@@ -375,7 +370,6 @@ const uploadRequest = async (options, renderItem: FormDataItem) => {
375
370
  const config: any = await renderItem.getOssToken({ file_name: file.name });
376
371
 
377
372
  const key = await uploadOss(file, config);
378
- console.log("上传结果",key)
379
373
 
380
374
  options.onSuccess({ key }, file);
381
375
  } else {
@@ -383,7 +377,6 @@ const uploadRequest = async (options, renderItem: FormDataItem) => {
383
377
  options.onProgress({ percent: 100 });
384
378
  // 成功回调,必须包含 URL 或其他必要字段
385
379
  const fakeUrl = URL.createObjectURL(options.file);
386
- console.log(fakeUrl);
387
380
  options.onSuccess({}, "阿斯加德卡拉胶漏打卡");
388
381
  }, 100);
389
382
  }
@@ -395,10 +388,13 @@ const uploadRequest = async (options, renderItem: FormDataItem) => {
395
388
  const editorUpload = async (renderItem, file, insertFn) => {
396
389
  const config: any = await renderItem.getOssToken({ type: renderItem.ossKey, file_name: file.name });
397
390
  const key = await uploadOss(file, config);
398
- console.log(insertFn, key);
399
391
  insertFn(renderItem.baseOssUrl + key);
400
392
  };
401
393
 
394
+
395
+ /**
396
+ * 发送验证码
397
+ */
402
398
  const sendNoticeClick = async (renderItem) => {
403
399
  if (renderItem.sendStatus == "sending") return;
404
400
  const res = await renderItem.sendNoticeFunc();
@@ -0,0 +1,54 @@
1
+ import { createApp, h, ref } from "vue";
2
+ import PModalForm from './p-form-modal.vue'
3
+ import type { FormDataItem } from "../p-form/index.d";
4
+
5
+ interface Options {
6
+ title: string;
7
+ renderFormData: FormDataItem[];
8
+ renderKeys?: string[];
9
+ width?: number;
10
+ initFormData?: { [key: string]: any };
11
+ }
12
+
13
+
14
+ export const PFormModal = (options: Options) => {
15
+ return new Promise((resolve, reject) => {
16
+ const container = document.createElement('div')
17
+ document.body.append(container)
18
+ const visible = ref(true)
19
+
20
+ const app = createApp({
21
+ render() {
22
+ return h(PModalForm, {
23
+ visible: visible.value,
24
+ ...options,
25
+ onConfirm: (formData) => {
26
+ resolve(formData)
27
+ visible.value = false
28
+ cleanup()
29
+ },
30
+ "onUpdate:visible": () => {
31
+ resolve(null)
32
+ visible.value = false
33
+ cleanup()
34
+ }
35
+ })
36
+ }
37
+ })
38
+
39
+
40
+
41
+ const cleanup = () => {
42
+ setTimeout(() => {
43
+ app.unmount()
44
+ if (container.parentNode) {
45
+ container.parentNode.removeChild(container)
46
+ }
47
+ }, 1000)
48
+ }
49
+
50
+
51
+ app.mount(container)
52
+
53
+ })
54
+ }
@@ -0,0 +1,79 @@
1
+ <template>
2
+ <Modal v-model:visible="visible" :title="title" :width="modalWidth" okText="确定" cancel-text="取消" @ok="ok"
3
+ @cancel="cancel">
4
+ <div style="max-height: 600px; overflow-y: auto; padding-right: 80px">
5
+ <p-form v-if="formRenderData.length > 0" ref="PFormRef" :render-data="formRenderData"
6
+ :init-form="initFormValue"></p-form>
7
+ </div>
8
+ </Modal>
9
+ </template>
10
+
11
+ <script lang="ts" setup>
12
+ import { ref, reactive, onMounted } from "vue";
13
+ import { message, Modal } from "ant-design-vue";
14
+ import * as _ from "../../utils/dataUtils";
15
+ import PForm from "../p-form/p-form.vue";
16
+ import type { FormDataItem } from "../p-form/index.d";
17
+
18
+ interface Props {
19
+ title: string;
20
+ renderFormData: FormDataItem[];
21
+ renderKeys?: string[];
22
+ width?: number;
23
+ initFormData?: { [key: string]: any };
24
+ }
25
+
26
+ const props = defineProps<Props>();
27
+
28
+ const visible = defineModel<boolean>('visible', { required: true })
29
+
30
+
31
+ const emits = defineEmits(['confirm'])
32
+
33
+ const modalWidth = ref(600);
34
+
35
+ const PFormRef = ref();
36
+
37
+
38
+ let formRenderData = ref([]);
39
+ let initFormValue: any = reactive({});
40
+
41
+
42
+ onMounted(() => {
43
+ const { initFormData, renderFormData, renderKeys, width } = props;
44
+ // 设置modal的宽度
45
+ modalWidth.value = width || 600;
46
+
47
+ if (!_.isEmpty(initFormData)) {
48
+ initFormValue = initFormData;
49
+ } else {
50
+ initFormValue = {};
51
+ }
52
+
53
+ const filterRenderData: any = [];
54
+ for (const renderKey of renderKeys || renderFormData.map((val) => val.key)) {
55
+ const renderItem = _.cloneDeep(renderFormData).find((val) => val.key == renderKey);
56
+ if (!_.isEmpty(renderItem)) {
57
+ filterRenderData.push(renderItem);
58
+ }
59
+ }
60
+
61
+ formRenderData.value = filterRenderData;
62
+ console.log(formRenderData)
63
+ })
64
+
65
+
66
+ const ok = async () => {
67
+ let formData = await PFormRef.value.getFormData();
68
+ emits('confirm', formData)
69
+ }
70
+
71
+
72
+ const cancel = () => {
73
+ visible.value = false;
74
+ };
75
+
76
+
77
+ </script>
78
+
79
+ <style scoped></style>
@@ -24,7 +24,7 @@ interface TableLink extends TableBase {
24
24
 
25
25
  interface TableCommon extends TableBase {
26
26
  key: string;
27
- type: 'common';
27
+ type?: 'common'
28
28
  }
29
29
 
30
30
  interface TableDate extends TableBase {
@@ -34,6 +34,7 @@ interface TableDate extends TableBase {
34
34
  }
35
35
 
36
36
  interface TableOperate extends TableBase {
37
+ key?: 'operate',
37
38
  type: 'operate',
38
39
  operateButtons: { label: string; click: Function; visibleFunc?: Function }[];
39
40
 
@@ -2,27 +2,33 @@
2
2
  // import "viewerjs/dist/viewer.css";
3
3
  import { api as viewerApi } from "v-viewer";
4
4
  import PForm from "../p-form/p-form.vue";
5
- import { h, ref, reactive, onMounted, toRaw } from "vue";
5
+ import { h, ref, reactive, onMounted, toRaw,defineExpose } from "vue";
6
6
  import * as _ from "../../utils/dataUtils";
7
7
  import dayjs from "dayjs";
8
- import { Table as ATable, Button as AButton } from "ant-design-vue";
8
+ import { Table as ATable, Button as AButton,Textarea as ATextarea } from "ant-design-vue";
9
9
  import type { FormDataItem } from "../p-form/index.d";
10
10
  import type { TableColumn } from "./index.d";
11
+ import { useSlots } from "vue";
11
12
  const SearchFormRef = ref();
12
13
 
13
- interface Props {
14
+ const uSlots = useSlots()
15
+
16
+
17
+ interface Props{
14
18
  tableColumns: TableColumn[];
15
- getData: null | ((query: object) => Promise<{ data: any[]; count: number; pages: { total: number; now: number } }>);
19
+ height?: number;
20
+ editColumns?:string[]
21
+ getData?: ((query: object) => Promise<{ data: any[]; count: number; pages: { total: number; now: number } }>);
16
22
  searchRenderData?: FormDataItem[];
17
23
  initSearchFormData?: any;
18
- height?: number;
24
+ data?:any[]
19
25
  }
20
26
 
21
- const props = withDefaults(defineProps<Props>(), {
22
- getData: null,
23
- height: 1000,
24
- searchRenderData: [] as any,
25
- });
27
+
28
+
29
+ const {getData =null,data= [],height=1000,searchRenderData = [],editColumns = [],tableColumns = [],initSearchFormData =[]} = defineProps<Props>()
30
+
31
+
26
32
 
27
33
  const pageQuery = reactive({
28
34
  p: 1,
@@ -47,35 +53,44 @@ const rowSelection = {
47
53
  },
48
54
  };
49
55
 
56
+ const editableData = reactive({});
57
+
58
+
50
59
  const loading = ref(false);
51
60
 
52
61
  let searchQuery = {};
53
62
 
54
63
  const renderTableColumns = (tableColumns: TableColumn[]) => {
55
64
  const returnColumns: any = [];
56
- for (const renderItem of tableColumns) {
65
+ for (const [index,renderItem] of tableColumns.entries()) {
57
66
  if (renderItem.type == "operate") {
58
- renderItem.customRender = ({ text, record }) => {
59
- const buttons: any = [];
60
- for (const buttonItem of renderItem.operateButtons) {
61
- if (buttonItem.visibleFunc && !buttonItem.visibleFunc(record)) continue;
62
- buttons.push(
63
- h(
64
- "a",
65
- {
66
- onClick: () => {
67
- buttonItem.click(record);
68
- },
69
- },
70
- buttonItem.label
71
- )
72
- );
73
- }
74
- return h("div", { style: { display: "flex", justifyContent: "space-around" } }, buttons);
75
- };
76
-
77
- renderItem.width = renderItem.operateButtons.length * 65;
67
+ // renderItem.customRender = ({ text, record }) => {
68
+ // const buttons: any = [];
69
+ // for (const buttonItem of renderItem.operateButtons) {
70
+ // if (buttonItem.visibleFunc && !buttonItem.visibleFunc(record)) continue;
71
+ // buttons.push(
72
+ // h(
73
+ // "a",
74
+ // {
75
+ // onClick: () => {
76
+ // buttonItem.click(record);
77
+ // },
78
+ // },
79
+ // buttonItem.label
80
+ // )
81
+ // );
82
+ // }
83
+ // return h("div", { style: { display: "flex", justifyContent: "space-around" } }, buttons);
84
+ // };
85
+
86
+
87
+ renderItem.width = renderItem.operateButtons.length * 55;
88
+
89
+ if(editColumns.length > 0){
90
+ renderItem.width +=110
91
+ }
78
92
  renderItem.align = "center";
93
+
79
94
  }
80
95
 
81
96
  // 处理默认字段
@@ -144,22 +159,37 @@ const renderTableColumns = (tableColumns: TableColumn[]) => {
144
159
 
145
160
  renderItem["dataIndex"] = renderItem["key"];
146
161
  returnColumns.push(renderItem);
162
+
147
163
  }
148
164
 
165
+
166
+
167
+
149
168
  return returnColumns;
150
169
  };
151
170
 
152
- const columns = renderTableColumns(props.tableColumns);
171
+ const columns = renderTableColumns(tableColumns);
153
172
 
154
173
  const renderTableData = async () => {
155
174
  loading.value = true;
156
- const _searchInitFormData = props.initSearchFormData ? JSON.parse(JSON.stringify(props.initSearchFormData)) : {};
157
- const _pageQuery = JSON.parse(JSON.stringify(pageQuery));
158
- if (!props.getData) return;
159
- const _tableData = await props.getData({ ..._searchInitFormData, ..._pageQuery, ..._.cloneDeep(searchQuery) });
160
- tableData.data = _tableData.data;
161
- tableData.count = _tableData.count;
162
- tableData.pages = _tableData.pages;
175
+ if(getData){
176
+ const _searchInitFormData = initSearchFormData ? JSON.parse(JSON.stringify(initSearchFormData)) : {};
177
+ const _pageQuery = JSON.parse(JSON.stringify(pageQuery));
178
+ const _tableData = await getData({ ..._searchInitFormData, ..._pageQuery, ..._.cloneDeep(searchQuery) });
179
+ tableData.data = _tableData.data;
180
+ tableData.count = _tableData.count;
181
+ tableData.pages = _tableData.pages;
182
+ }
183
+
184
+ else if(data){
185
+ tableData.data = data
186
+ }
187
+
188
+
189
+ tableData.data.forEach((item,index)=>{
190
+ item["index"] = index
191
+ })
192
+
163
193
  loading.value = false;
164
194
  };
165
195
 
@@ -218,6 +248,22 @@ const getTableData = () => {
218
248
  return toRaw(tableData)["data"];
219
249
  };
220
250
 
251
+
252
+
253
+ const edit = (index: string) => {
254
+ editableData[index] = _.cloneDeep(tableData.data[index]);
255
+
256
+
257
+ };
258
+ const save = (key: string) => {
259
+ Object.assign(tableData.data.filter(item => key === item.key)[0], editableData[key]);
260
+ delete editableData[key];
261
+ };
262
+
263
+ const cancel = (key: string) => {
264
+ delete editableData[key];
265
+ };
266
+
221
267
  onMounted(() => {
222
268
  renderTableData();
223
269
  });
@@ -245,7 +291,7 @@ defineExpose({
245
291
  </PForm>
246
292
  </div>
247
293
 
248
- <div style="display: flex; justify-content: flex-end; margin-bottom: 10px; margin-top: 10px; padding: 20px">
294
+ <div v-if="uSlots.button" style="display: flex; justify-content: flex-end; margin-bottom: 10px; margin-top: 10px; padding: 20px">
249
295
  <slot name="button"></slot>
250
296
  </div>
251
297
 
@@ -258,7 +304,7 @@ defineExpose({
258
304
  :scroll="{
259
305
  y: height,
260
306
  }"
261
- :pagination="{
307
+ :pagination="data.length >0? false :{
262
308
  current: pageQuery.p,
263
309
  defaultPageSize: pageQuery.pc,
264
310
  showSizeChanger: true,
@@ -270,8 +316,32 @@ defineExpose({
270
316
  bordered
271
317
  @change="onchange"
272
318
  >
273
- <template #bodyCell="slotProps">
274
- <slot name="bodyCell" v-bind="slotProps" />
319
+ <template #bodyCell="{ column, text, record,index }">
320
+ <template v-if="editColumns.includes(column.key as string)">
321
+ <div>
322
+ <a-textarea
323
+ v-if="editableData[record.index]"
324
+ v-model:value="editableData[record.index][column.key]"
325
+ style="margin: -5px 0"
326
+ :auto-size="true"
327
+ />
328
+ <template v-else>
329
+ {{text}}
330
+ </template>
331
+ </div>
332
+ </template>
333
+
334
+ <template v-else-if="column['type'] === 'operate'">
335
+
336
+ <div style="display:flex;gap:10px;justify-content: center;">
337
+ <a class="operate-a" v-for="item in column['operateButtons']" @click="item.click(record)"> {{ item.label}}</a>
338
+ <a class="operate-a" v-if="editableData[record.index]" @click="save(record.index)">保存</a>
339
+ <a class="operate-a" v-if="editableData[record.index]" @click="cancel(record.index)">退出</a>
340
+ <a class="operate-a" @click="edit(record.index)">编辑</a>
341
+ </div>
342
+ </template>
343
+
344
+ <slot name="bodyCell" v-bind="{column, text, record,index}" />
275
345
  </template>
276
346
  </a-table>
277
347
  </template>
@@ -296,4 +366,9 @@ defineExpose({
296
366
  padding-top: 25px;
297
367
  border-bottom: 10px solid #f5f5f5;
298
368
  }
369
+
370
+
371
+ .operate-a{
372
+ color: #126cff;
373
+ }
299
374
  </style>
package/dist/index.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  import PTable from './components/p-table/p-table.vue'
2
2
  import PForm from './components/p-form/p-form.vue'
3
- import PModalForm from './components/p-modal-form/p-modal-form.vue'
4
-
5
- export { PTable, PModalForm, PForm }
3
+ import { PFormModal } from './components/p-modal-form/p-form-modal'
4
+ export { PTable, PFormModal, PForm }
6
5
  export type { FormDataItem } from './components/p-form/index.d'
7
6
  export type { TableColumn } from './components/p-table/index.d'
8
7
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "p-pc-ui",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "type": "module",
5
5
  "module": "dist/index.ts",
6
6
  "main": "dist/index.ts",
@@ -1,113 +0,0 @@
1
- <template>
2
- <Modal
3
- v-model:open="visible"
4
- :title="titleText"
5
- :width="modalWidth"
6
- okText="确定"
7
- cancel-text="取消"
8
- @ok="ok"
9
- @cancel="cancel"
10
- >
11
- <div style="max-height: 600px; overflow-y: auto; padding-right: 80px">
12
- <p-form v-if="visible" ref="PFormRef" :render-data="formRenderData" :init-form="initFormValue"></p-form>
13
- </div>
14
- </Modal>
15
- </template>
16
-
17
- <script lang="ts" setup>
18
- import PForm from "../p-form/p-form.vue";
19
- import { ref, reactive } from "vue";
20
- import { message, Modal } from "ant-design-vue";
21
- import * as _ from "../../utils/dataUtils";
22
- import type { FormDataItem } from "../p-form/index.d";
23
-
24
- interface Props {}
25
- const props = defineProps<Props>();
26
-
27
- const modalWidth = ref(600);
28
-
29
- const visible = ref(false);
30
- const titleText = ref("");
31
- const PFormRef = ref();
32
-
33
- let formRenderData = reactive([]);
34
- let initFormValue: any = reactive({});
35
-
36
- interface ModalFormConfig {
37
- operateType: "add" | "detail" | "edit";
38
- renderFormData: FormDataItem[];
39
- onOk: Function;
40
- title?: string;
41
- renderKeys?: string[];
42
- width?: number;
43
- rowId?: string;
44
- extraFormData?: { [key: string]: any };
45
- initFormData?: { [key: string]: any };
46
- }
47
-
48
- let modalConfig: ModalFormConfig;
49
-
50
- const open = async (config: ModalFormConfig) => {
51
- const { operateType, rowId, initFormData, onOk, renderFormData, renderKeys, extraFormData, title, width } = config;
52
- if (!["add", "edit", "detail"].includes(operateType)) return message.error("操作类型错误");
53
- if (["edit", "detail"].includes(operateType) && _.isEmpty(rowId)) return message.error("请传入主键ID");
54
-
55
- // 设置modal的宽度
56
- modalWidth.value = width || 600;
57
-
58
- if (!_.isEmpty(initFormData)) {
59
- initFormValue = initFormData;
60
- } else {
61
- initFormValue = {};
62
- }
63
-
64
- if (title) {
65
- titleText.value = title;
66
- } else {
67
- const typeMap = {
68
- add: "新增",
69
- edit: "编辑",
70
- detail: "查看",
71
- };
72
- titleText.value = typeMap[operateType];
73
- }
74
-
75
- const filterRenderData: any = [];
76
- for (const renderKey of renderKeys || renderFormData.map((val) => val.key)) {
77
- const renderItem = _.cloneDeep(renderFormData).find((val) => val.key == renderKey);
78
- if (!_.isEmpty(renderItem)) {
79
- filterRenderData.push(renderItem);
80
- }
81
- }
82
-
83
- modalConfig = config;
84
- formRenderData = filterRenderData;
85
- visible.value = true;
86
- };
87
-
88
- const ok = async () => {
89
- let formData = await PFormRef.value.getFormData();
90
- if (_.isEmpty(formData)) return;
91
- if (!_.isEmpty(modalConfig.extraFormData)) {
92
- formData = { ...formData, ...modalConfig.extraFormData };
93
- }
94
- let callbackRes = null;
95
- if (modalConfig.operateType == "edit") {
96
- callbackRes = await modalConfig.onOk(modalConfig.rowId, formData);
97
- } else {
98
- callbackRes = await modalConfig.onOk(formData);
99
- }
100
- if (callbackRes === false) return;
101
- visible.value = false;
102
- };
103
-
104
- const cancel = () => {
105
- visible.value = false;
106
- };
107
-
108
- defineExpose({
109
- open,
110
- });
111
- </script>
112
-
113
- <style scoped></style>