aldehyde 0.2.134 → 0.2.136

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 (44) hide show
  1. package/lib/controls/action/index.d.ts +8 -3
  2. package/lib/controls/action/index.d.ts.map +1 -1
  3. package/lib/controls/action/index.js +36 -12
  4. package/lib/controls/action/index.js.map +1 -1
  5. package/lib/detail/edit/fields-edit-card.d.ts +3 -3
  6. package/lib/detail/edit/fields-edit-card.d.ts.map +1 -1
  7. package/lib/detail/edit/fields-edit-card.js +5 -6
  8. package/lib/detail/edit/fields-edit-card.js.map +1 -1
  9. package/lib/form/fields-form.d.ts +1 -1
  10. package/lib/form/fields-form.d.ts.map +1 -1
  11. package/lib/form/fields-form.js.map +1 -1
  12. package/lib/login/login.d.ts +4 -0
  13. package/lib/login/login.d.ts.map +1 -1
  14. package/lib/login/login.js +32 -25
  15. package/lib/login/login.js.map +1 -1
  16. package/lib/login/vertify/index.css +144 -0
  17. package/lib/login/vertify/index.d.ts +78 -0
  18. package/lib/login/vertify/index.d.ts.map +1 -0
  19. package/lib/login/vertify/index.js +210 -0
  20. package/lib/login/vertify/index.js.map +1 -0
  21. package/lib/login/vertify/tool.d.ts +5 -0
  22. package/lib/login/vertify/tool.d.ts.map +1 -0
  23. package/lib/login/vertify/tool.js +11 -0
  24. package/lib/login/vertify/tool.js.map +1 -0
  25. package/lib/module/block-menu-tree-drawer.js +1 -1
  26. package/lib/module/block-menu-tree-drawer.js.map +1 -1
  27. package/lib/tmpl/interface.d.ts +25 -25
  28. package/lib/tmpl/interface.d.ts.map +1 -1
  29. package/lib/units/index.d.ts.map +1 -1
  30. package/lib/units/index.js.map +1 -1
  31. package/lib/welcome/HCWelcome.js +1 -17
  32. package/lib/welcome/HCWelcome.js.map +1 -1
  33. package/package.json +1 -1
  34. package/src/aldehyde/controls/action/index.tsx +50 -14
  35. package/src/aldehyde/detail/edit/fields-edit-card.tsx +9 -8
  36. package/src/aldehyde/form/fields-form.tsx +2 -2
  37. package/src/aldehyde/login/login.tsx +115 -79
  38. package/src/aldehyde/login/vertify/index.css +144 -0
  39. package/src/aldehyde/login/vertify/index.tsx +360 -0
  40. package/src/aldehyde/login/vertify/tool.ts +13 -0
  41. package/src/aldehyde/module/block-menu-tree-drawer.tsx +1 -1
  42. package/src/aldehyde/tmpl/interface.tsx +25 -25
  43. package/src/aldehyde/units/index.tsx +1 -0
  44. package/src/aldehyde/welcome/HCWelcome.js +20 -20
@@ -0,0 +1,360 @@
1
+ import React, { useRef, useState, useEffect, ReactNode, memo } from "react";
2
+ import { getRandomNumberByRange, sum, square } from "./tool";
3
+ import "./index.css";
4
+ import { useLocale } from "../../locale/useLocale";
5
+
6
+ interface VertifyType {
7
+ spliced: boolean;
8
+ verified: boolean; // 简单验证拖动轨迹,为零时表示Y轴上下没有波动,可能非人为操作
9
+ left: number; // 滑块的移动位置
10
+ destX: number; // 滑块的目标位置
11
+ }
12
+
13
+ interface IVertifyProp {
14
+ /**
15
+ * @description canvas宽度
16
+ * @default 320
17
+ */
18
+ width?: number;
19
+ /**
20
+ * @description canvas高度
21
+ * @default 160
22
+ */
23
+ height?: number;
24
+ /**
25
+ * @description 滑块边长
26
+ * @default 42
27
+ */
28
+ l?: number;
29
+ /**
30
+ * @description 滑块半径
31
+ * @default 9
32
+ */
33
+ r?: number;
34
+ /**
35
+ * @description 是否可见
36
+ * @default true
37
+ */
38
+ visible?: boolean;
39
+ /**
40
+ * @description 滑块文本
41
+ * @default 向右滑动填充拼图
42
+ */
43
+ text?: string | ReactNode;
44
+ /**
45
+ * @description 刷新按钮icon, 为icon的url地址
46
+ * @default -
47
+ */
48
+ refreshIcon?: string;
49
+ /**
50
+ * @description 用于获取随机图片的url地址
51
+ * @default https://picsum.photos/${id}/${width}/${height}, 具体参考https://picsum.photos/, 只需要实现类似接口即可
52
+ */
53
+ imgUrl?: string;
54
+ /**
55
+ * @description 拖拽滑块时的回调, 参数为当前滑块拖拽的距离
56
+ * @default (l: number):void => {}
57
+ */
58
+ onDraw?: (l: number) => {};
59
+ /**
60
+ * @description 用户的自定义验证逻辑
61
+ * @default (arg: VertifyType) => VertifyType
62
+ */
63
+ onCustomVertify?: (arg: VertifyType) => VertifyType;
64
+ /**
65
+ * @description 验证成功回调
66
+ * @default ():void => {}
67
+ */
68
+ onSuccess?: VoidFunction;
69
+ /**
70
+ * @description 验证失败回调
71
+ * @default ():void => {}
72
+ */
73
+ onFail?: VoidFunction;
74
+ /**
75
+ * @description 刷新时回调
76
+ * @default ():void => {}
77
+ */
78
+ onRefresh?: VoidFunction;
79
+ }
80
+
81
+ export default memo(
82
+ ({
83
+ width = 320,
84
+ height = 160,
85
+ l = 42,
86
+ r = 9,
87
+ imgUrl,
88
+ text,
89
+ refreshIcon = "http://cdn.dooring.cn/dr/icon12.png",
90
+ visible = true,
91
+ onDraw,
92
+ onCustomVertify,
93
+ onSuccess,
94
+ onFail,
95
+ onRefresh,
96
+ }: IVertifyProp) => {
97
+ const { translate } = useLocale();
98
+
99
+ const [isLoading, setLoading] = useState(false);
100
+ const [sliderLeft, setSliderLeft] = useState(0);
101
+ const [sliderClass, setSliderClass] = useState("sliderContainer");
102
+ const [textTip, setTextTip] = useState(text);
103
+ const canvasRef = useRef<any>(null);
104
+ const blockRef = useRef<any>(null);
105
+ const imgRef = useRef<any>(null);
106
+ const isMouseDownRef = useRef<boolean>(false);
107
+ const trailRef = useRef<number[]>([]);
108
+ const originXRef = useRef<number>(0);
109
+ const originYRef = useRef<number>(0);
110
+ const xRef = useRef<number>(0);
111
+ const yRef = useRef<number>(0);
112
+ const PI = Math.PI;
113
+ const L = l + r * 2 + 3; // 滑块实际边长
114
+
115
+ const drawPath = (
116
+ ctx: any,
117
+ x: number,
118
+ y: number,
119
+ operation: "fill" | "clip"
120
+ ) => {
121
+ ctx.beginPath();
122
+ ctx.moveTo(x, y);
123
+ ctx.arc(x + l / 2, y - r + 2, r, 0.72 * PI, 2.26 * PI);
124
+ ctx.lineTo(x + l, y);
125
+ ctx.arc(x + l + r - 2, y + l / 2, r, 1.21 * PI, 2.78 * PI);
126
+ ctx.lineTo(x + l, y + l);
127
+ ctx.lineTo(x, y + l);
128
+ ctx.arc(x + r - 2, y + l / 2, r + 0.4, 2.76 * PI, 1.24 * PI, true);
129
+ ctx.lineTo(x, y);
130
+ ctx.lineWidth = 2;
131
+ ctx.fillStyle = "rgba(255, 255, 255, 0.7)";
132
+ ctx.strokeStyle = "rgba(255, 255, 255, 0.7)";
133
+ ctx.stroke();
134
+ ctx.globalCompositeOperation = "destination-over";
135
+ operation === "fill" ? ctx.fill() : ctx.clip();
136
+ };
137
+
138
+ const getRandomImgSrc = () => {
139
+ return (
140
+ imgUrl ||
141
+ `https://picsum.photos/id/${getRandomNumberByRange(
142
+ 0,
143
+ 1084
144
+ )}/${width}/${height}`
145
+ );
146
+ };
147
+
148
+ const createImg = (onload: VoidFunction) => {
149
+ const img = new Image();
150
+ img.crossOrigin = "Anonymous";
151
+ img.onload = onload;
152
+ img.onerror = () => {
153
+ (img as any).setSrc(getRandomImgSrc()); // 图片加载失败的时候重新加载其他图片
154
+ };
155
+
156
+ (img as any).setSrc = (src: string) => {
157
+ const isIE = window.navigator.userAgent.indexOf("Trident") > -1;
158
+ if (isIE) {
159
+ // IE浏览器无法通过img.crossOrigin跨域,使用ajax获取图片blob然后转为dataURL显示
160
+ const xhr = new XMLHttpRequest();
161
+ xhr.onloadend = function(e: any) {
162
+ const file = new FileReader(); // FileReader仅支持IE10+
163
+ file.readAsDataURL(e.target.response);
164
+ file.onloadend = function(e) {
165
+ img.src = e?.target?.result as string;
166
+ };
167
+ };
168
+ xhr.open("GET", src);
169
+ xhr.responseType = "blob";
170
+ xhr.send();
171
+ } else img.src = src;
172
+ };
173
+
174
+ (img as any).setSrc(getRandomImgSrc());
175
+ return img;
176
+ };
177
+
178
+ const draw = (img: HTMLImageElement) => {
179
+ const canvasCtx = canvasRef.current.getContext("2d");
180
+ const blockCtx = blockRef.current.getContext("2d");
181
+ // 随机位置创建拼图形状
182
+ xRef.current = getRandomNumberByRange(L + 10, width - (L + 10));
183
+ yRef.current = getRandomNumberByRange(10 + r * 2, height - (L + 10));
184
+ drawPath(canvasCtx, xRef.current, yRef.current, "fill");
185
+ drawPath(blockCtx, xRef.current, yRef.current, "clip");
186
+
187
+ // 画入图片
188
+ canvasCtx.drawImage(img, 0, 0, width, height);
189
+ blockCtx.drawImage(img, 0, 0, width, height);
190
+
191
+ // 提取滑块并放到最左边
192
+ const y1 = yRef.current - r * 2 - 1;
193
+ const ImageData = blockCtx.getImageData(xRef.current - 3, y1, L, L);
194
+ blockRef.current.width = L;
195
+ blockCtx.putImageData(ImageData, 0, y1);
196
+ };
197
+
198
+ const initImg = () => {
199
+ setLoading(true);
200
+ const img = createImg(() => {
201
+ setLoading(false);
202
+ draw(img);
203
+ });
204
+ imgRef.current = img;
205
+ };
206
+
207
+ const reset = () => {
208
+ const canvasCtx = canvasRef.current.getContext("2d");
209
+ const blockCtx = blockRef.current.getContext("2d");
210
+ // 重置样式
211
+ setSliderLeft(0);
212
+ setSliderClass("sliderContainer");
213
+ blockRef.current.width = width;
214
+ blockRef.current.style.left = 0 + "px";
215
+
216
+ // 清空画布
217
+ canvasCtx.clearRect(0, 0, width, height);
218
+ blockCtx.clearRect(0, 0, width, height);
219
+
220
+ // 重新加载图片
221
+ setLoading(true);
222
+ imgRef.current.setSrc(getRandomImgSrc());
223
+ };
224
+
225
+ const handleRefresh = () => {
226
+ reset();
227
+ typeof onRefresh === "function" && onRefresh();
228
+ };
229
+
230
+ const verify = () => {
231
+ const arr = trailRef.current; // 拖动时y轴的移动距离
232
+ const average = arr.reduce(sum) / arr.length;
233
+ const deviations = arr.map((x) => x - average);
234
+ const stddev = Math.sqrt(deviations.map(square).reduce(sum) / arr.length);
235
+ const left = parseInt(blockRef.current.style.left);
236
+ return {
237
+ spliced: Math.abs(left - xRef.current) < 10,
238
+ verified: stddev !== 0, // 简单验证拖动轨迹,为零时表示Y轴上下没有波动,可能非人为操作
239
+ left,
240
+ destX: xRef.current,
241
+ };
242
+ };
243
+
244
+ const handleDragStart = function(e: any) {
245
+ originXRef.current = e.clientX || e.touches[0].clientX;
246
+ originYRef.current = e.clientY || e.touches[0].clientY;
247
+ isMouseDownRef.current = true;
248
+ };
249
+
250
+ const handleDragMove = (e: any) => {
251
+ if (!isMouseDownRef.current) return false;
252
+ e.preventDefault();
253
+ const eventX = e.clientX || e.touches[0].clientX;
254
+ const eventY = e.clientY || e.touches[0].clientY;
255
+ const moveX = eventX - originXRef.current;
256
+ const moveY = eventY - originYRef.current;
257
+ if (moveX < 0 || moveX + 38 >= width) return false;
258
+ setSliderLeft(moveX);
259
+ const blockLeft = ((width - 40 - 20) / (width - 40)) * moveX;
260
+ blockRef.current.style.left = blockLeft + "px";
261
+
262
+ setSliderClass("sliderContainer sliderContainer_active");
263
+ trailRef.current.push(moveY);
264
+ onDraw && onDraw(blockLeft);
265
+ };
266
+
267
+ const handleDragEnd = (e: any) => {
268
+ if (!isMouseDownRef.current) return false;
269
+ isMouseDownRef.current = false;
270
+ const eventX = e.clientX || e.changedTouches[0].clientX;
271
+ if (eventX === originXRef.current) return false;
272
+ setSliderClass("sliderContainer");
273
+ const { spliced, verified } = onCustomVertify
274
+ ? onCustomVertify(verify())
275
+ : verify();
276
+ if (spliced) {
277
+ if (verified) {
278
+ setSliderClass("sliderContainer sliderContainer_success");
279
+ typeof onSuccess === "function" && onSuccess();
280
+ } else {
281
+ setSliderClass("sliderContainer sliderContainer_fail");
282
+ setTextTip(translate("${请再试一次}"));
283
+ reset();
284
+ }
285
+ } else {
286
+ setSliderClass("sliderContainer sliderContainer_fail");
287
+ typeof onFail === "function" && onFail();
288
+ setTimeout(reset.bind(this), 1000);
289
+ }
290
+ };
291
+
292
+ useEffect(() => {
293
+ if (visible) {
294
+ imgRef.current ? reset() : initImg();
295
+ }
296
+ }, [visible]);
297
+
298
+ return (
299
+ <div
300
+ className="vertifyWrap"
301
+ style={{
302
+ width: width + "px",
303
+ margin: "0 auto",
304
+ display: visible ? "" : "none",
305
+ background: "white",
306
+ }}
307
+ onMouseMove={handleDragMove}
308
+ onMouseUp={handleDragEnd}
309
+ onTouchMove={handleDragMove}
310
+ onTouchEnd={handleDragEnd}
311
+ >
312
+ <div className="canvasArea">
313
+ <canvas ref={canvasRef} width={width} height={height}></canvas>
314
+ <canvas
315
+ ref={blockRef}
316
+ className="block"
317
+ width={width}
318
+ height={height}
319
+ onMouseDown={handleDragStart}
320
+ onTouchStart={handleDragStart}
321
+ ></canvas>
322
+ </div>
323
+ <div
324
+ className={sliderClass}
325
+ style={{
326
+ pointerEvents: isLoading ? "none" : "auto",
327
+ width: width + "px",
328
+ }}
329
+ >
330
+ <div className="sliderMask" style={{ width: sliderLeft + "px" }}>
331
+ <div
332
+ className="slider"
333
+ style={{ left: sliderLeft + "px" }}
334
+ onMouseDown={handleDragStart}
335
+ onTouchStart={handleDragStart}
336
+ >
337
+ <div className="sliderIcon">&rarr;</div>
338
+ </div>
339
+ </div>
340
+ <div className="sliderText">{textTip}</div>
341
+ </div>
342
+ <div
343
+ className="refreshIcon"
344
+ onClick={handleRefresh}
345
+ style={{ backgroundImage: `url(${refreshIcon})` }}
346
+ ></div>
347
+ <div
348
+ className="loadingContainer"
349
+ style={{
350
+ width: width + "px",
351
+ height: height + "px",
352
+ display: isLoading ? "" : "none",
353
+ }}
354
+ >
355
+ <div className="loadingIcon"></div>
356
+ </div>
357
+ </div>
358
+ );
359
+ }
360
+ );
@@ -0,0 +1,13 @@
1
+ function getRandomNumberByRange(start: number, end: number) {
2
+ return Math.round(Math.random() * (end - start) + start);
3
+ }
4
+
5
+ function sum(x: number, y: number) {
6
+ return x + y;
7
+ }
8
+
9
+ function square(x: number) {
10
+ return x * x;
11
+ }
12
+
13
+ export { getRandomNumberByRange, sum, square };
@@ -46,7 +46,7 @@ export default class BlockMenuTreeDrawer extends React.PureComponent<BlockMenuTr
46
46
  const {roleCode:preRoleCode}=preProps
47
47
 
48
48
  if(!preRoleCode || preRoleCode!=roleCode){
49
- debugger
49
+ //debugger
50
50
  await this.loadData();
51
51
  }
52
52
  }
@@ -17,8 +17,8 @@ export type ActTableViewModel = "table" | "verticalList" | "horizontalList";
17
17
  export type ControlHolderType = "table" | "descriptions";
18
18
  export type PageType = "modal" | "drawer" | "card";
19
19
  export interface TmplBase {
20
- id: string;
21
- title: string;
20
+ id?: string;
21
+ title?: string;
22
22
  tip?: string;
23
23
  }
24
24
 
@@ -182,23 +182,23 @@ export type GroupDisplayConfig =
182
182
  | "tableview";
183
183
  export interface FieldGroupConfig extends OrderableTmplBase {
184
184
  serverKey?: string;
185
- type: FieldGroupType;
186
- buttons: ButtonName[];
187
- min: number;
188
- max: number;
185
+ type?: FieldGroupType;
186
+ buttons?: ButtonName[];
187
+ min?: number;
188
+ max?: number;
189
189
  showRowNum?: boolean;
190
190
  relationNames?: string[];
191
191
  showRelationName?: boolean;
192
192
  fields: FieldConfig[];
193
- rowActions: ActionConfig[];
194
- displayConfig: GroupDisplayConfig;
193
+ rowActions?: ActionConfig[];
194
+ displayConfig?: GroupDisplayConfig;
195
195
  mainCode?: string;
196
196
  disabled?: boolean;
197
197
  readOnly?: boolean;
198
198
  embedType?: "列表" | "详情" | "编辑" | "编辑或添加";
199
- pageSourceFieldMstrucId: string;
200
- codeSourceFieldMstrucId: string;
201
- pointSourceId: string;
199
+ pageSourceFieldMstrucId?: string;
200
+ codeSourceFieldMstrucId?: string;
201
+ pointSourceId?: string;
202
202
  classifiedAddConfigs?: ClassifiedAddConfig[];
203
203
  }
204
204
 
@@ -207,23 +207,23 @@ export type SaveJumpType = "list" | "add" | "edit";
207
207
  export interface DtmplConfig extends TmplBase {
208
208
  autoSaveInterval?: number;
209
209
  //exportExcel fusionMode history dtmplSave refresh
210
- buttons: ButtonName[];
210
+ buttons?: ButtonName[];
211
211
  // list add edit
212
- saveJumpTo: SaveJumpType[];
213
- cQuerys: CQueryConfig[];
214
- editAction: ActionConfig;
215
- actions: ActionConfig[];
216
- premises: FieldConfig[];
217
- groups: FieldGroupConfig[];
218
- buttonPosition: ButtonPosition;
219
- buildInFuncFields: FieldConfig[];
220
- onValuesChange: (
212
+ saveJumpTo?: SaveJumpType[];
213
+ cQuerys?: CQueryConfig[];
214
+ editAction?: ActionConfig;
215
+ actions?: ActionConfig[];
216
+ premises?: FieldConfig[];
217
+ groups?: FieldGroupConfig[];
218
+ buttonPosition?: ButtonPosition;
219
+ buildInFuncFields?: FieldConfig[];
220
+ onValuesChange?: (
221
221
  changedValues,
222
222
  allValues: DtmplData,
223
223
  formInstance: FormInstance
224
224
  ) => void;
225
- entity: DtmplData;
226
- dynamic: boolean;
225
+ entity?: DtmplData;
226
+ dynamic?: boolean;
227
227
  hiddenFields?: FieldConfig[];
228
228
  }
229
229
 
@@ -351,11 +351,11 @@ export interface EnumItem {
351
351
  export type EditStatus = "new" | "changed" | "persisted";
352
352
 
353
353
  export interface DtmplData {
354
- code: string;
354
+ code?: string;
355
355
  editStatus?: EditStatus;
356
356
  title?: string;
357
357
  relationLabel?: string;
358
- fieldMap: object;
358
+ fieldMap?: object;
359
359
  arrayMap?: object; //Map<number,DtmplData[]>
360
360
  }
361
361
 
@@ -33,6 +33,7 @@ export default {
33
33
  },
34
34
 
35
35
  getAppDtmplConfig(dtmplConfig: DtmplConfig, dtmplData: DtmplData,props:DtmplFormProps) {
36
+
36
37
  if (dtmplConfig){
37
38
  if( AppDtmplConfigFuncMap[dtmplConfig.id]) {
38
39
  return AppDtmplConfigFuncMap[dtmplConfig.id](dtmplConfig, dtmplData, props);
@@ -230,27 +230,27 @@ class HCWelcome extends React.Component {
230
230
  {/* </Col>*/}
231
231
  {/*</Row>*/}
232
232
 
233
- <Row>
234
- <Col>
235
- <Button onClick={()=>{
236
- this.setState({
237
- openDrawer:!this.state.openDrawer
238
- })
239
- }
233
+ {/*<Row>*/}
234
+ {/* <Col>*/}
235
+ {/* <Button onClick={()=>{*/}
236
+ {/* this.setState({*/}
237
+ {/* openDrawer:!this.state.openDrawer*/}
238
+ {/* })*/}
239
+ {/* }*/}
240
240
 
241
- } >打开权限</Button>
242
- {/*<BlockMenuAuthTree />*/}
243
- </Col>
244
- </Row>
245
- <BlockMenuAuthTreeDrawer onCancel={ ()=>{
246
- this.setState({
247
- openDrawer:false
248
- })
249
- }} onOk={ ()=>{
250
- this.setState({
251
- openDrawer:false
252
- })
253
- }} open={openDrawer} roleCode={'374901611447492611'}></BlockMenuAuthTreeDrawer>
241
+ {/* } >打开权限</Button>*/}
242
+ {/* /!*<BlockMenuAuthTree />*!/*/}
243
+ {/* </Col>*/}
244
+ {/*</Row>*/}
245
+ {/*<BlockMenuAuthTreeDrawer onCancel={ ()=>{*/}
246
+ {/* this.setState({*/}
247
+ {/* openDrawer:false*/}
248
+ {/* })*/}
249
+ {/*}} onOk={ ()=>{*/}
250
+ {/* this.setState({*/}
251
+ {/* openDrawer:false*/}
252
+ {/* })*/}
253
+ {/*}} open={openDrawer} roleCode={'374901611447492611'}></BlockMenuAuthTreeDrawer>*/}
254
254
 
255
255
  </>
256
256
  }