0%

如果第三方接口获取到的数据,返回为csv文档时,可以先把csv文档保存到本地某路径,再通过fs的createReadStream读取数据,保存到本地数据库。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
const processConversations = async (dateObj) => {
const username = '你的帐户名';
const password = '密码';

const year = dateObj.format('YYYY');
const month = dateObj.format('MM');
const day = dateObj.format('DD');
const hour = dateObj.format('HH');
const dateStr = `${year}-${month}-${day}-${hour}`;
const fileName = `路径后半部份`;
const url = `https://api/${fileName}`;
const outputPath = `/tmp/conversations`;
const tableName = 'test';


try {
// 下载 CSV
const response = await axios.get(url, {
responseType: 'stream',
headers: {
Authorization: `Basic ${Buffer.from(`${username}:${password}`).toString('base64')}`
}
});

const writer = fs.createWriteStream(outputPath);
response.data.pipe(writer);
await new Promise((resolve, reject) => {
writer.on('finish', resolve);
writer.on('error', reject);
});

console.log(' CSV 文件下载成功:', fileName);



const rows = [];

await new Promise((resolve, reject) => {
fs.createReadStream(outputPath)
.pipe(csv())
.on('data', (row) => {
rows.push([
row['DATE_TIME'] ? dayjs(row['DATE_TIME']).format('YYYY-MM-DD HH:mm:ss') : null,
row['CLID'] || null,
row['CLID_SOURCE'] || null
]);
})
.on('end', resolve)
.on('error', reject);
});

if (rows.length === 0) {
console.warn(`CSV 中没有数据: ${fileName}`);
return;
}

const insertSQL = `
INSERT INTO \`${tableName}\` (
date_time, clid, clid_source
) VALUES ?
`;




await query(insertSQL, [rows]);
console.log(`成功插入 ${rows.length} 条记录: ${fileName}`);
} catch (error) {
console.error(`报错 (${fileName}):`, error.message);
}
};

索引的作用

当想要快速查找到自己想要的数据时,可以用索引。通过索引,可以在检索数据时直接定位到,省去时间,就好比一本书前面的目录,能让你快速找到自己想看的内容。如果索引包含多列,那么按照从左到右的顺序,即最左前缀列来进行。

索引的类型

  1. 唯一索引:
    对某些列(比如身份证)添加唯一约束,不能出现两条身份证相同的记录,通过 UNIQUE 关键字我们就添加了一个唯一索引。
1
ADD UNIQUE INDEX uni_sf (sf);

也可以给列添加唯一约束,而不创建唯一索引,列具有唯一性。

1
ADD CONSTRAINT uni_name UNIQUE (name);
  1. 主键索引:
    主键一旦创建,就会自动带上索引。这也是为什么主键搜索数据会更快的原因。一个表只能有一个主键,一个主键可以包含多列,即联合主键。
1
ALTER TABLE table_name ADD PRIMARY KEY (column);
  1. 普通索引:
    任何一列都可以创建索引,建议只在自己经常想要检索的列上加索引,不要全部加,会耗性能。
1
ALTER TABLE table_name ADD INDEX index_name (column);

测试、UI要求的会比较高,比如滑动图标改成自定义图片等,所以传统的@react-native-community/slider已经不能满足所需,所以采取自定义形式,在网上找了很久才发现的一个宝藏依赖:https://github.com/miblanchard/react-native-slider

组件代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
import React, { PureComponent } from 'react';
import {
Animated,
Easing,
I18nManager,
Image,
ImageSourcePropType,
LayoutChangeEvent,
PanResponder,
PanResponderInstance,
View,
ViewStyle,
} from 'react-native';
// styles
import { defaultStyles as styles } from './styles';
import type { Dimensions, SliderProps, SliderState } from './types';

type RectReturn = {
containsPoint: (nativeX: number, nativeY: number) => boolean;
height: number;
trackDistanceToPoint: (nativeX: number) => number;
width: number;
x: number;
y: number;
};

const Rect = ({
height,
width,
x,
y,
}: {
height: number;
width: number;
x: number;
y: number;
}) => ({
containsPoint: (nativeX: number, nativeY: number) =>
nativeX >= x &&
nativeY >= y &&
nativeX <= x + width &&
nativeY <= y + height,
height,
trackDistanceToPoint: (nativeX: number) => {
if (nativeX < x) {
return x - nativeX;
}

if (nativeX > x + width) {
return nativeX - (x + width);
}

return 0;
},
width,
x,
y,
});

const DEFAULT_ANIMATION_CONFIGS = {
spring: {
friction: 7,
tension: 100,
},
timing: {
duration: 150,
easing: Easing.inOut(Easing.ease),
delay: 0,
},
};

const normalizeValue = (
props: SliderProps,
value?: number | Array<number>,
): Array<number> => {
if (!value || (Array.isArray(value) && value.length === 0)) {
return [0];
}

const {maximumValue, minimumValue} = props;

const getBetweenValue = (inputValue: number) =>
Math.max(Math.min(inputValue, maximumValue), minimumValue);

if (!Array.isArray(value)) {
return [getBetweenValue(value)];
}

return value.map(getBetweenValue).sort((a, b) => a - b);
};

const updateValues = ({
values,
newValues = values,
}: {
values: number | Array<number> | Animated.Value | Array<Animated.Value>;
newValues?: number | Array<number> | Animated.Value | Array<Animated.Value>;
}): Animated.Value[] => {
if (
Array.isArray(newValues) &&
Array.isArray(values) &&
newValues.length !== values.length
) {
return updateValues({values: newValues});
}

if (Array.isArray(values) && Array.isArray(newValues)) {
return values?.map((value: number | Animated.Value, index: number) => {
let valueToSet = newValues[index];
if (value instanceof Animated.Value) {
if (valueToSet instanceof Animated.Value) {
valueToSet = valueToSet.__getValue();
}
value.setValue(valueToSet);
return value;
}

if (valueToSet instanceof Animated.Value) {
return valueToSet;
}

return new Animated.Value(valueToSet);
});
}

return [new Animated.Value(0)];
};

const indexOfLowest = (values: Array<number>): number => {
let lowestIndex = 0;
values.forEach((value, index, array) => {
if (value < array[lowestIndex]) {
lowestIndex = index;
}
});
return lowestIndex;
};

export class Slider extends PureComponent<SliderProps, SliderState> {
constructor(props: SliderProps) {
super(props);
this._panResponder = PanResponder.create({
onStartShouldSetPanResponder:
this._handleStartShouldSetPanResponder,
onMoveShouldSetPanResponder: this._handleMoveShouldSetPanResponder,
onPanResponderGrant: this._handlePanResponderGrant,
onPanResponderMove: this._handlePanResponderMove,
onPanResponderRelease: this._handlePanResponderEnd,
onPanResponderTerminationRequest:
this._handlePanResponderRequestEnd,
onPanResponderTerminate: this._handlePanResponderEnd,
});
this.state = {
allMeasured: false,
containerSize: {
width: 0,
height: 0,
},
thumbSize: {
width: 0,
height: 0,
},
trackMarksValues: updateValues({
values: normalizeValue(this.props, this.props.trackMarks),
}),
values: updateValues({
values: normalizeValue(
this.props,
this.props.value instanceof Animated.Value
? this.props.value.__getValue()
: this.props.value,
),
}),
};
}

static defaultProps = {
animationType: 'timing',
debugTouchArea: false,
trackMarks: [],
maximumTrackTintColor: '#b3b3b3',
maximumValue: 1,
minimumTrackTintColor: '#3f3f3f',
minimumValue: 0,
step: 0,
thumbTintColor: '#343434',
trackClickable: true,
value: 0,
vertical: false,
};

static getDerivedStateFromProps(props: SliderProps, state: SliderState) {
if (
props.trackMarks &&
!!state.trackMarksValues &&
state.trackMarksValues.length > 0
) {
const newTrackMarkValues = normalizeValue(props, props.trackMarks);
const statePatch = {} as SliderState;

if (
state.trackMarksValues
) {
statePatch.trackMarksValues = updateValues({
values: state.trackMarksValues,
newValues: newTrackMarkValues,
});
}

return statePatch;
}
}

componentDidUpdate() {
const newValues = normalizeValue(
this.props,
this.props.value instanceof Animated.Value
? this.props.value.__getValue()
: this.props.value,
);
newValues.forEach((value, i) => {
if (!this.state.values[i]) {
this._setCurrentValue(value, i);
} else if (value !== this.state.values[i].__getValue()) {
if (this.props.animateTransitions) {
this._setCurrentValueAnimated(value, i);
} else {
this._setCurrentValue(value, i);
}
}
});
}

_getRawValues(
values: Array<Animated.Value> | Array<Animated.AnimatedInterpolation>,
) {
return values.map((value) => value.__getValue());
}

_handleStartShouldSetPanResponder = (
e: any,
): /* gestureState: GestureState */
boolean => this._thumbHitTest(e); // Should we become active when the user presses down on the thumb?

_handleMoveShouldSetPanResponder(): /* e, gestureState: GestureState */
boolean {
// Should we become active when the user moves a touch over the thumb?
return false;
}

_handlePanResponderGrant = (e: {nativeEvent: any}) => {
const {thumbSize} = this.state;
const {nativeEvent} = e;
this._previousLeft = this.props.trackClickable
? nativeEvent.locationX - thumbSize.width
: this._getThumbLeft(this._getCurrentValue(this._activeThumbIndex));

this.props?.onSlidingStart?.(this._getRawValues(this.state.values));
};

_handlePanResponderMove = (_e: any, gestureState: any) => {
if (this.props.disabled) {
return;
}

this._setCurrentValue(
this._getValue(gestureState),
this._activeThumbIndex,
() => {
this.props?.onValueChange?.(
this._getRawValues(this.state.values),
);
},
);
};

_handlePanResponderRequestEnd = () =>
/* e, gestureState: GestureState */
{
// Should we allow another component to take over this pan?
return false;
};

_handlePanResponderEnd = (_e: any, gestureState: any) => {
if (this.props.disabled) {
return;
}

this._setCurrentValue(
this._getValue(gestureState),
this._activeThumbIndex,
() => {
if (this.props.trackClickable) {
this.props?.onValueChange?.(
this._getRawValues(this.state.values),
);
}

this.props?.onSlidingComplete?.(
this._getRawValues(this.state.values),
);
},
);

this._activeThumbIndex = 0;
};

_measureContainer = (e: LayoutChangeEvent) => {
this._handleMeasure('_containerSize', e);
};

_measureTrack = (e: LayoutChangeEvent) => {
this._handleMeasure('_trackSize', e);
};

_measureThumb = (e: LayoutChangeEvent) => {
this._handleMeasure('_thumbSize', e);
};

_handleMeasure = (
name: '_containerSize' | '_trackSize' | '_thumbSize',
e: LayoutChangeEvent,
) => {
const {width, height} = e.nativeEvent.layout;
const size = {
width,
height,
};

const currentSize = this[name];

if (
currentSize &&
width === currentSize.width &&
height === currentSize.height
) {
return;
}

this[name] = size;

if (this._containerSize && this._thumbSize) {
this.setState({
containerSize: this._containerSize,
thumbSize: this._thumbSize,
allMeasured: true,
});
}
};
_getRatio = (value: number) => {
const {maximumValue, minimumValue} = this.props;
return (value - minimumValue) / (maximumValue - minimumValue);
};
_getThumbLeft = (value: number) => {
const {containerSize, thumbSize} = this.state;
const {vertical} = this.props;

const standardRatio = this._getRatio(value);

const ratio = I18nManager.isRTL ? 1 - standardRatio : standardRatio;
return ratio * ((vertical ? containerSize.height : containerSize.width) - thumbSize.width);
};
_getValue = (gestureState: {dx: number, dy: number}) => {
const {containerSize, thumbSize, values} = this.state;
const {maximumValue, minimumValue, step, vertical} = this.props;
const length = containerSize.width - thumbSize.width;
const thumbLeft = vertical ? this._previousLeft + (gestureState.dy * -1) : this._previousLeft + gestureState.dx;
const nonRtlRatio = thumbLeft / length;
const ratio = I18nManager.isRTL ? 1 - nonRtlRatio : nonRtlRatio;
let minValue = minimumValue;
let maxValue = maximumValue;

const rawValues = this._getRawValues(values);

const buffer = step ? step : 0.1;

if (values.length === 2) {
if (this._activeThumbIndex === 1) {
minValue = rawValues[0] + buffer;
} else {
maxValue = rawValues[1] - buffer;
}
}

if (step) {
return Math.max(
minValue,
Math.min(
maxValue,
minimumValue +
Math.round(
(ratio * (maximumValue - minimumValue)) / step,
) *
step,
),
);
}

return Math.max(
minValue,
Math.min(
maxValue,
ratio * (maximumValue - minimumValue) + minimumValue,
),
);
};
_getCurrentValue = (thumbIndex: number = 0) =>
this.state.values[thumbIndex].__getValue();

_setCurrentValue = (
value: number,
thumbIndex: number | null | undefined,
callback?: () => void,
) => {
const safeIndex = thumbIndex ?? 0;
const animatedValue = this.state.values[safeIndex];

if (animatedValue) {
animatedValue.setValue(value);

if (callback) {
callback();
}
} else {
this.setState((prevState: SliderState) => {
const newValues = [...prevState.values];
newValues[safeIndex] = new Animated.Value(value);
return {
values: newValues,
};
}, callback);
}
};

_setCurrentValueAnimated = (value: number, thumbIndex: number = 0) => {
const {animationType} = this.props;
const animationConfig = {
...DEFAULT_ANIMATION_CONFIGS[animationType],
...this.props.animationConfig,
toValue: value,
useNativeDriver: false,
};
Animated[animationType](
this.state.values[thumbIndex],
animationConfig,
).start();
};

_getTouchOverflowSize = (): {
width: number;
height: number;
} => {
const {allMeasured, containerSize, thumbSize} = this.state;
const {thumbTouchSize} = this.props;
const size = {
width: 40,
height: 40,
};

if (allMeasured) {
size.width = Math.max(
0,
thumbTouchSize?.width || 0 - thumbSize.width,
);
size.height = Math.max(
0,
thumbTouchSize?.height || 0 - containerSize.height,
);
}

return size;
};

_getTouchOverflowStyle = () => {
const {width, height} = this._getTouchOverflowSize();

const touchOverflowStyle = {} as ViewStyle;

if (width !== undefined && height !== undefined) {
const verticalMargin = -height / 2;
touchOverflowStyle.marginTop = verticalMargin;
touchOverflowStyle.marginBottom = verticalMargin;
const horizontalMargin = -width / 2;
touchOverflowStyle.marginLeft = horizontalMargin;
touchOverflowStyle.marginRight = horizontalMargin;
}

if (this.props.debugTouchArea === true) {
touchOverflowStyle.backgroundColor = 'orange';
touchOverflowStyle.opacity = 0.5;
}

return touchOverflowStyle;
};
_thumbHitTest = (e: {nativeEvent: any}) => {
const {nativeEvent} = e;
const {trackClickable} = this.props;
const {values} = this.state;
const hitThumb = values.find((_, i) => {
const thumbTouchRect = this._getThumbTouchRect(i);

const containsPoint = thumbTouchRect.containsPoint(
nativeEvent.locationX,
nativeEvent.locationY,
);

if (containsPoint) {
this._activeThumbIndex = i;
}

return containsPoint;
});

if (hitThumb) {
return true;
}

if (trackClickable) {
// set the active thumb index
if (values.length === 1) {
this._activeThumbIndex = 0;
} else {
// we will find the closest thumb and that will be the active thumb
const thumbDistances = values.map((_value, index) => {
const thumbTouchRect = this._getThumbTouchRect(index);

return thumbTouchRect.trackDistanceToPoint(
nativeEvent.locationX,
);
});
this._activeThumbIndex = indexOfLowest(thumbDistances);
}

return true;
}

return false;
};

_getThumbTouchRect = (thumbIndex: number = 0): RectReturn => {
const {containerSize, thumbSize} = this.state;
const {thumbTouchSize} = this.props;
const {height, width} = thumbTouchSize || {height: 40, width: 40};

const touchOverflowSize = this._getTouchOverflowSize();

return Rect({
height,
width,
x:
touchOverflowSize.width / 2 +
this._getThumbLeft(this._getCurrentValue(thumbIndex)) +
(thumbSize.width - width) / 2,
y:
touchOverflowSize.height / 2 +
(containerSize.height - height) / 2,
});
};

_activeThumbIndex: number = 0;
_containerSize: Dimensions | null | undefined;
_panResponder: PanResponderInstance;
_previousLeft: number = 0;
_thumbSize: Dimensions | null | undefined;
_trackSize: Dimensions | null | undefined;

_renderDebugThumbTouchRect = (
thumbLeft: Animated.AnimatedInterpolation,
index: number,
) => {
const {height, y, width} = this._getThumbTouchRect() || {};
const positionStyle = {
height,
left: thumbLeft,
top: y,
width,
};
return (
<Animated.View
key={`debug-thumb-${index}`}
pointerEvents="none"
style={[styles.debugThumbTouchArea, positionStyle]}
/>
);
};

_renderThumbImage = (thumbIndex: number = 0) => {
const {thumbImage} = this.props;

if (!thumbImage) {
return null;
}

return (
<Image
source={
(Array.isArray(thumbImage)
? thumbImage[thumbIndex]
: thumbImage) as ImageSourcePropType
}
/>
);
};

render() {
const {
containerStyle,
debugTouchArea,
maximumTrackTintColor,
maximumValue,
minimumTrackTintColor,
minimumValue,
renderAboveThumbComponent,
renderTrackMarkComponent,
renderThumbComponent,
thumbStyle,
thumbTintColor,
trackStyle,
vertical,
...other
} = this.props;
const {
allMeasured,
containerSize,
thumbSize,
trackMarksValues,
values,
} = this.state;
const interpolatedThumbValues = values.map((value) =>
value.interpolate({
inputRange: [minimumValue, maximumValue],
outputRange: I18nManager.isRTL
? [0, -(containerSize.width - thumbSize.width)]
: [0, containerSize.width - thumbSize.width],
}),
);
const interpolatedTrackValues = values.map((value) =>
value.interpolate({
inputRange: [minimumValue, maximumValue],
outputRange: [0, containerSize.width - thumbSize.width],
}),
);
const interpolatedTrackMarksValues =
trackMarksValues &&
trackMarksValues.map((v) =>
v.interpolate({
inputRange: [minimumValue, maximumValue],
outputRange: I18nManager.isRTL
? [0, -(containerSize.width - thumbSize.width)]
: [0, containerSize.width - thumbSize.width],
}),
);
const valueVisibleStyle = {} as ViewStyle;

if (!allMeasured) {
valueVisibleStyle.opacity = 0;
}

const interpolatedRawValues = this._getRawValues(
interpolatedTrackValues,
);

const minThumbValue = new Animated.Value(
Math.min(...interpolatedRawValues),
);
const maxThumbValue = new Animated.Value(
Math.max(...interpolatedRawValues),
);
const minimumTrackStyle = {
position: 'absolute',
left:
interpolatedTrackValues.length === 1
? new Animated.Value(0)
: Animated.add(minThumbValue, thumbSize.width / 2),
width:
interpolatedTrackValues.length === 1
? Animated.add(
interpolatedTrackValues[0],
thumbSize.width / 2,
)
: Animated.add(
Animated.multiply(minThumbValue, -1),
maxThumbValue,
),
backgroundColor: minimumTrackTintColor,
...valueVisibleStyle,
} as ViewStyle;

const touchOverflowStyle = this._getTouchOverflowStyle();

return (
<>
{renderAboveThumbComponent && (
<View style={styles.aboveThumbComponentsContainer}>
{interpolatedThumbValues.map((value, i) => (
<Animated.View
key={`slider-above-thumb-${i}`}
style={[
styles.renderThumbComponent, // eslint-disable-next-line react-native/no-inline-styles
{
bottom: 0,
transform: [
{
translateX: value,
},
{
translateY: 0,
},
],
...valueVisibleStyle,
},
]}>
{renderAboveThumbComponent(i)}
</Animated.View>
))}
</View>
)}
<View
{...other}
style={[styles.container, vertical ? {transform: [{rotate: '-90deg' }]} : {}, containerStyle]}
onLayout={this._measureContainer}>
<View
renderToHardwareTextureAndroid
style={[
styles.track,
{
backgroundColor: maximumTrackTintColor,
},
trackStyle,
]}
onLayout={this._measureTrack}
/>
<Animated.View
renderToHardwareTextureAndroid
style={[styles.track, trackStyle, minimumTrackStyle]}
/>
{renderTrackMarkComponent &&
interpolatedTrackMarksValues &&
interpolatedTrackMarksValues.map((value, i) => (
<Animated.View
key={`track-mark-${i}`}
style={[
styles.renderThumbComponent,
{
transform: [
{
translateX: value,
},
{
translateY: 0,
},
],
...valueVisibleStyle,
},
]}>
{renderTrackMarkComponent(i)}
</Animated.View>
))}
{interpolatedThumbValues.map((value, i) => (
<Animated.View
key={`slider-thumb-${i}`}
style={[
renderThumbComponent
? styles.renderThumbComponent
: styles.thumb,
renderThumbComponent
? {}
: {
backgroundColor: thumbTintColor,
...thumbStyle,
},
{
transform: [
{
translateX: value,
},
{
translateY: 0,
},
],
...valueVisibleStyle,
},
]}
onLayout={this._measureThumb}>
{renderThumbComponent
? renderThumbComponent()
: this._renderThumbImage(i)}
</Animated.View>
))}
<View
style={[styles.touchArea, touchOverflowStyle]}
{...this._panResponder.panHandlers}>
{!!debugTouchArea &&
interpolatedThumbValues.map((value, i) =>
this._renderDebugThumbTouchRect(value, i),
)}
</View>
</View>
</>
);
}
}

导入部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { Slider } from '所放的上述组件路径'

<Slider
minimumValue={1}
maximumValue={7} //可滑动范围为1到7
minimumTrackTintColor="#0A79C3"
maximumTrackTintColor="#F3F3F3"
step={1} //步长
value={targetDay} //默认值,例如4
onValueChange={targetDays => dispatch({
type: 'SetupWeekTarget/updateState',
payload: { targetDay: targetDays }
})} //滑动触发的事件
trackStyle={{ height: 10, borderRadius: 12 }}
containerStyle={{ width: SCREEN_WIDTH - 90 }}
thumbTintColor="transparent"
thumbImage={require('图片路径')}
/>

详细参数可参考链接:

https://github.com/miblanchard/react-native-slider

最开始我想的是有多少个输入框,就放多少个input,做完会发现有各种bug。比如键盘突然消失、没聚焦下个输入框、操作不丝滑等。
正确思路是一个输入框就够了,然后通过改变样式(间隔、高亮)来实现,就是表面看起来是六个输入框,本质上只有一个input

正确解法:

1
2
3
<view class="w-80 h-100 rad-10 b-a-9 tc f-50" v-for="(item,index)  in 6">
<input class="w-80 h-100 " maxlength="1" type="text" @input="inputListener(index)" :focus="focus && (focusIndex == index)"/>
</view>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
data(){
return{
focus: true,
code:['','','','','',''],// 需要获取焦点的序号
focusIndex: 0
}
}
method:{
// 输入时事件
inputListener(e) {
if (this.focusIndex != e)this.focusIndex=e
if (e < 6) {
this.focus=true,
this.focusIndex=e + 1
}else {
this.focus=false
}
},
}

完整版可参考链接:

https://blog.csdn.net/u011423258/article/details/106683068?spm=1001.2014.3001.5506

什么是序列化

在 TCP 通道里传输的数据只能是二进制形式的,所以将数据结构或对象转化成二进制的形式就叫序列化。反过来就叫反序列化,他们之间的规则就叫协议。

RPC是什么

全称是Remote Procedure Call, 中文名字叫远程过程调用。大部份的 RPC 是基于TCP的。具体实现流程如下:

1、前端通过 Proxy 代理调用相应的接口, Proxy 将 RPC 的服务名,方法名,参数等信息转换成 RPC Request 对象,交给 RPC 框架
2、RPC 框架通过 RPC 协议将 RPC Request 对象序列化成二进制形式
3、RPC 通过 TCP 通道把二进制数据传递给后端
4、后端将二进制数据反序列化成 RPC Request 对象
5、后端将反序列化后的数据对应到自己写的方法内,传入参数,获取数据,将获取后的数据进行封装,封装成 RPC Response 交给 RPC 框架
6、RPC 框架通过 RPC 协议将 RPC Response 对象序列化成二进制形式, 通过 TCP 通道传递给前端
6、前端将收到的二进制数据反序列化成 RPC response 对象,将结果通过 Proxy 返回给业务代码

The intonation.(语调)
Express the different feelings of the speaker.
We often use the falling tone when we read a statement, a special question, an exclamatory or imperative sentence(祈使句、感叹句). We often use rising tone when we ask a Yes/No question. We often use rising-falling tone to read an alternative question and a coordinate clause(选择疑问句、并列句). There are two parts in a tag question(反义疑问句). The first part is often in a falling tone and for second part, there are two cases. If we are not sure about the question, we often use a rising tone. If we are sure about that, we offen use a falling tone.
We choose different intonations to express different feelings and moods.

The word stress(单词重音)
Read words more exactly
When we say a word with more than one syllable, some of the syllables need to be stressed.
When we read two-syllable words, normally we stress the first syllable for nouns, and stress the second syllable for verbs. As for the multi-syllable words, we stress the third from the bottom.

The sentence stress(句子重读)
Draw attention to certain information.
We usually stress the lexical words such as nouns, verbs, adjectives, adverbs and numbers. We don’t stress the function words such as a, the, is, of and so on. Besides, you can stress some information you want to emphasis.
We should change it according to the situation and feelings of the speaker.

The liaison/ˈlēəˌzän,lēˈāˌzän//Word linking.(连读)
Speak English more fluently and naturally.
In one sense group, we can read the two words together if the former word ends with a consonant/ˈkänsənənt/, a vowel or “r” sound, and the following word begins with a vowel. If the two words finish and start with the same consonant, we only read one of the consonants.
The two words must be in one sense group.

incomplete plosion/‘pləʊʒ(ə)n/(不完全爆破)
Speak English more fluently and naturally.
There are six plosive sounds /t/ /d/ /p/ /b/ /k/ /g/ in English.When two consonants of them are next to each other, we read the former sound silently.
The two words must be in one sense group.

Weak form(弱读)
speak English more fluently and naturally.
Some words often appear in a weak form such as function words, articles, auxiliary verbs and modal verbs.
there are mainly three ways to change function words to weak forms. They are shortening, elision[ i’liʒən ] and vowel changed to schwa  [ʃwɑ:] sound.

Assimilation(同化)
We use it to speak English more fluently and naturally.
As we can see, Two different sounds affect each other and become more alike.
/s+ j/ -> /F/this year,/d+j/ -> /d3/ would you

Sense group(意群)
We use it to make our expression more easily to understand.
As we can see, a sentence may consists of several groups according to meaning or structure. Each group is called a sense group. It can be a word, a phrase, a clause. After a sense group, there should be a short pause.
We should remind that we should change it according to the situation and feelings of the speaker.

The pause(停顿)
We use to speak English more fluently and naturally.
As we can see, in a long sentence, we should pause several times according to the sense group. Normally, we pause based on meaning and grammatical structure.
We should remind that there should be no pause in a sense group. Where to pause also depends on the situation and the feelings of the speaker.

开场问候

Dear Judges, Now I’ll start the lesson. Good morning, Boys and girls. How are you today? Good? Fine? I’m fine, too. Before the class, Let’s sing a song together. If you can sing, sing along with me . “You are my sunshine, my only sunshine, you make me happy.” Do you feel better? Great, let’s start the lesson.
At the beginning, I’ll show you a video, and you should try to answer the question: What can you see in the video? Who would like to try? Blair, please. You saw the girl had much fun. She had dinner and went shopping with friends. Thank you, Blair, you set a good example for us. You know so much about this topic. Do you want to learn more? Today, let’s learn a new lesson — How was your day off.

导入

OK, everyone, here is a passage. I’ll read it for you. You should listen carefully and tell me the main idea, OK? Here we go! …….OK, Please share your ideas. Jenny, you please. It talks about the Bermuda Triangle, where a number of planes and ships disappeared.Do you agree? I totally agree with her.

Pre

Boys and girls, since we already know the content of the letter, Let’s look at the structure of the letter.There are 4 parts of it, right?
The first one is to whom. We call it salutation/ˌsalyəˈtāSH(ə)n/, such as Hi Henry, Dear Lucy and so on. The second part is body part. You can write whatever you want. The third part, we often add complementary close/wishes, such as ‘yours’, ‘sincerely’. The last part is from whom, we call it signature. Am I clear? So when we write a letter, we can imitate it. Brilliant!

the first part is introduction. It’s a fun day last Saturday. The second part is main body, it’s about what they did in the morning, afternoon and so on. The third part is conclusion. So if we want to write out our everyday life, we can imitate this structure, OK?

写前

Before writing, let’s have a brainstorm. As Tom, what information can you write to reply to Nick’s letter? You can have a discussion in groups. 3 minutes for you. Stop! Who can try, this boy? You will write some activities during camping. Your ideas are wonderful. Bravo! Thank you.
OK,I can see you all have many ideas. How about writing down your ideas with the structure we just learned. You have 2 minutes to design your outline.OK, time is up. Finished? I see all of you nod your heads. Very good!
It’s time to finish the whole letter. While writing, you should pay attention to the grammar.We should use simple past tense to talk about the experience in the past.And for the signature, you should write”Tom”. If you have any problems, just raise your hands, and I will help you. Are you ready? Let’s do it.

写后

Have you finished your writing? Show me your hands. Well done. Next, go over your writing one more time and then exchange it with your group members.Try to check and correct the mistakes, got it? You have 2 minutes.
Stop here.Who wants to share your writing? Cindy, please. Wow, good pronunciation. You state the story vividly. The logic is clear! OK, anyone else? Tony. Please. Oh, you want to present Tina’s article.Can you read it? Very good. Thank you, Tony. Guys, Let’s look at Tina’s work together. “Tom” went to a mountain for camping. I think her article is perfect. We can learn a lot from it. Boys and girls, you all did a good job!

总结

How time files! The class is almost over. Before ending our class, let’s have a summary. Who can summarize what we have learned this class? Fiona please. Very good. I hope you can apply what we have learned in your daily life so that we can improve our reading and speaking ability, right?
Our homework is as follows: You should finish the exercise book and search for more information about ask your parents about their day off. Next class, we will share them together.

Class is over, see you next time.

Grammer

开场问候

Dear Judges, Now I’ll start the lesson. Good morning, Boys and girls. How are you today? Good? Fine? I’m fine, too. Before the class, Let’s sing a song together. If you can sing, sing along with me . “You are my sunshine, my only sunshine, you make me happy.” Do you feel better? Great, let’s start the lesson.

导入

基本跟上一篇一样,只是换了问题,根据材料的主题来问问题。比如:little prince and harry porter. Today, we’re going to learn a new grammar about it , the present perfect tense.

Pre

Now boys and girls, let’s have a prediction according to the title and the conversation on your book. I will read for you.When you listen, think about this question: What’s the material mainly about? Try to think out as many answers as you can.(let’s begin,…..)OK, who wants to have a try?Justin, you please. The passage is about some books they have read. Nice try! Do you agree? OK, maybe you are right. You got the correct answer.

While

Now boys and girls, let’s have a prediction according to the title and the pictures on your book. Take a guess:What’s the passage mainly about? Try to think out as many answers as you can. OK, who wants to have a try?Justin, you please. The passage is about a cartoon Mickey Mouse. Nice try! Do you agree? OK, maybe you are right.Next, Let’s find out the truth in this passage.

语法教学

All right guys, it’s time to learn something new. Here are some sentences. (板书)Let’s look at the first one. Can you read it together? Yes,1……2…
3…. Wonderful! It’s not difficult for you, right?
Now, boys and girls, please try to find the similarity among these sentences? You can work in groups and share your ideas with each other. Here we go.
So, did you find something in common? OK, who would like to try? Amanda, please. You have sharp eyes.Yes, they have the word “have/has” and these are “yes/no” questions.Yes, exactly!
Now, let’s put all your views/points together. Boys and girls, This is what we will learn today, the present perfect tense.
We use it to talk about things that happened in the past but have a connection to the present in some way.
As we can see, the main structure of this grammar is “has/have done”, right? We often use “yet” in this grammar. But we should remind that normally the rules of past participle form are the same as the past form, such as live/lived. However, there are some irregular verbs, such as, put/put/put, read/read/read. We make the negative sentences like this:”has/have not done”.Clear? You are so smart!

巩固

practice makes perfect, so let’s do some exercises. Let’s “Fill in the blanks”. Now look at the Power Point. Please finish it as quickly as you can and we will check the answers later. Here we go.
Have you finished? What’s your answer, Cindy? Have you found your pen yet?-No, I haven’t. Do you agree with Cindy? Good, next one? Mike? He has turned off the light! All right, I think you have mastered it.

总结

How time files! The class is almost over. Before ending our class, let’s have a summary. Who can summarize what we have learned this class? Fiona please. Very good. I hope you can apply what we have learned in your daily life so that we can improve our reading and speaking ability, right?
Our homework is as follows: You should finish the exercise book and search for more information about famous cartoons on the Internet. Next class, we will share them together.

Class is over, see you next time.

其他语法模版

The simple present tense(一般现在时)
the things or actions that happen regularly.
“Verb to be” has three forms: am/is/are. “Verb to do” has two forms: do/does.
If the subject(主语) is first person or plural form, we should use do, if not, we use does.For the third singular form, normally we add s to the end, such as help/helps. The second type is to add es, such as guess/guesses. And the last type is to change y to i and add es, such as study/studies.

the simple past tense.(一般过去时)
We use it to talk about the past events. (When)
As we can see, “verb to be” has two forms:was/were, and we have to the change the
“verb to do” into past form, right? (Details)
We should remind that normally we add ed/d to the end, such as look/looked,
live/lived. The second type is to double write the last letter and add ed, such as
stop/stopped. And the last type is to change y to i and add ed, such as study/studied.
There are also some irregular verbs, such as, put/put, catch/caught.

the simple future tense.(一般将来时中的will/shall + do)
We use it to talk about our intentions or make predictions. (When)
As we can see, the main structure of this grammar is “will+do” , right?(Details)
We should remind that We should use the original form of the verbs. We make the
negative sentence like this: “will not do”. If the subject is the first person, we can
also use ‘shall’ instead of ‘will’.

the simple future tense.(一般将来时中的be going to + do)
We use it to talk about things that happen in the future. (When)
As we can see, the main structure of this grammar is “be going to do” , right?(Details)
We should remind that We should use the original form of the verbs. We make the
negative sentence like this: “be not going to do”.

the present progressive tense(现在进行时)
We use it to talk about what people are doing or what’s going on. (When)
As we can see, the main structure of this grammar is “be doing” , right? (Details)
We should remind that “verb to be” has three forms: am/is/are.We make the negative
sentences like this: “be not doing”.And we should change the verbs into ‘-ing’ form.
Normally we add -ing to the end, such as look/looking. The second type is to remove e
and add -ing, such as write/writing. And the last type is to double write the last letter
and add -ing, such as get/getting.

the past progressive tense.(过去进行时)
We use it to talk about the past events in certain time. (When)
As we can see, the main structure of this grammar is “was/were doing”, right? (Details)
We should remind that we should change the verbs into -ing form. Normally we add
ing to the end, such as look/looking. The second type is to remove ‘e’ and add “ing” ,
such as write/writing. And the last type is to double write the last letter and add ing,
such as get/getting. We make the negative sentences like this: “was/were not doing”.

the present perfect tense.(现在完成时)
We use it to talk about things that happened in the past but have a connection to the present in some way.
As we can see, the main structure of this grammar is “has/have done”, right? We often use “yet” in this grammar. But we should remind that normally the rules of past participle form are the same as the past form, such as live/lived. However, there are some irregular verbs, such as, put/put/put, read/read/read. We make the negative sentences like this:”has/have not done”.

the present passive voice.(一般现在时的被动语态)
We use it to talk about the passive relationships between the subject and the object.(When)
As we can see, the main structure of this grammar is “be+done”, right? (Details)
We should remind that “verb to be” has three forms: am/is/are. We should use the
past participle form of transitive verbs. And there are some irregular verbs, such as,
put/put/put, catch/caught/caught.We make the negative sentences like this: “be not
done”.

the past passive voice.(一般过去时的被动语态)
We use it to talk about the passive relationships between the subject and the object.(When)
As we can see, the main structure of this grammar is “was/were+done”, right? (Details)
We should remind that we should use the past participle form of transitive verbs. And
there are some irregular verbs, such as, put/put/put, catch/caught/caught.We make the
negative sentences like this: “w as/were not done”.

the attributive clause. (定语从句-名词之后出现)
Describe the nouns more exactly.
the relative pronouns(代词) should be used to link the main clause and the clause.They are ‘that/which/who/whom/whose’.
’that/which/who’ can be used as subject(主语) or object(宾语) of a clause, ‘whom’ can be as object, whose can be as attributive(定语). ’That’ can be used to refer to the things or people, ‘which’ for things, ‘who/whom’ for people.

the objective clause.(宾语从句-谓语动词后面出现)
express our thoughts more exactly.
There are three kinds of objective clauses. The first one is with ‘that’, the second one is with ‘if/whether’, the last one is with ‘wh-words’.
The order of words in the objective clauses should be written in statements and the tense should be changed according to the main clause.

The first conditional if.
Talk about the things happen in certain condition.
The main structure of this grammar is “First conditional if+will”(板书例句)
The main clause is in the future tense. The clause is in the present tense.(主将从现) And the first conditional if can be put before or after the main clause.

the imperative sentence.(祈使句)
Ask for permission, order or warn sb (not) to do sth.
The imperatives begin with the original form of the verb
The subject of the imperative is ‘you’ which is omitted. We make the negative sentences like this. “Don’t do sth”.

There be sentences.
we use it to Describe things or people.
As we can see, The main structure of this grammar is There be something/somebody in someplace/sometime, right?
But we should remind that “verb to be” has two forms: is/are. We should change it according to the nouns after it. We make the negative sentences like this: “There is/ are not.”

the nouns.(名词)
Describe things or people.
There are countable nouns and uncountable nouns, right?
Countable nouns have two forms: the singular and the plural. Normally, we add s to the end, such as book/books. The second type is to add es, such as class/classes. And the last type is to change y to i and add es, such as family/families. There are also some irregular nouns, such as man/men, sheep/sheep, child/children.

the comparatives.(比较级)
Compare different objects or people.
We usually add ‘er/r’ to the end of adjectives or adverbs, such as tall/taller, slow/slower, late/later. And add ‘more’ before the multi-syllable words, such as ‘more beautiful’.
There are some irregular changes, such as good/better, bad/worse.

The superlatives.(最高级)
Compare different objects or people.
We usually add est/st to the end of the adjectives or adverbs, such as tall/tallest, slow/slowest, late/latest.And add ‘most’ before the words, such as most beautiful.
There are some irregular changes, such as good/best, bad/worst. And we should add ‘the’ before the superlatives.

Adverbs of frequency.(频率副词)
Talk about how often we do things.
There are always, usually, often, sometimes, hardly ever(seldom), never.
If we put them in order, it will be like that always>usually>often>sometimes>hardly ever(seldom)>never.

The indefinite pronouns some and any.(普通不定代词)
Refer to people or things.
Normally some is used in statements(肯定句), any is used in negative statements or questions, right? They can both replace or modify the plural nouns and uncountable nouns.(可数名词复数以及不可数名词)
If we want the answer to the question is yes, we can also use some in questions. For example, would you like some tea?

The indefinite pronouns many and much.
Refer to people or things.
Many can replace or modify plural nouns, and much can replace or modify the uncountable nouns, right?
We use “How many…” questions to ask about the plural nouns, and “How much…” question to ask about the uncountable nouns.

the compound indefinite pronouns something, anything, nothing(复合不定代词)
Refer to people or things.
If the subject is something, anything… it is seen as singular(单数形式), right?
We should put the adjectives after the indefinite pronouns. For example, something important.

the modal verbs.(情态动词)
Make inferences.(作出推断)
The main structure of this grammar is “modal verbs + be”, right?
Some modal verbs can be used for making inferences. They are must, can’t, could, may, might. We use must to show that we think something is probably true. And use may, might and could to show that we think something is possibly true. Use can’t to show that you are almost sure something is not true.

Reading/Listening

开场问候

Dear Judges, Now I’ll start the lesson. Good morning, Boys and girls. How are you today? Good? Fine? I’m fine, too. Before the class, Let’s sing a song together. If you can sing, sing along with me . “You are my sunshine, my only sunshine, you make me happy.” Do you feel better? Great, let’s start the lesson.

导入

At the beginning, I’ll show you a video, and you should try to answer the question: What can you see in the video? Who would like to try? Blair, please. You see different cartoons, such as Snow White and Tom and Jerry.Thank you, Blair, you set a good example for us. You know so much about cartoons.Do you want to learn more? Today, let’s learn a new lesson — Cartoon.

读前

Before reading, To help you understand the passage better, let’s learn some words. Now, Look at the first one. Smart.Form example, Zhu Geliang is very smart and he can solve many problems. Can you understand now? Great! The next one cute. Look at the picture. What’s that? A cat. So cats are very cute and it’s very lovely. So cute means lovely. You are so cute. Cats are so cute. Birds are so cute, okay, wonderful How about the last one? Ivory. Here is a picture about ivory. It forms long teeth of elephants. Read after me, ivory, ivory. Well done! All of you did a good job.

读中

Now boys and girls, let’s have a prediction according to the title and the pictures on your book. Take a guess:What’s the passage mainly about? Try to think out as many answers as you can. OK, who wants to have a try?Justin, you please. The passage is about a cartoon Mickey Mouse. Nice try! Do you agree? OK, maybe you are right.Next, Let’s find out the truth in this passage.

读后

Let’s read it together.When you read, think about this question:What’s the passage mainly about? You should read quickly and check your prediction.Let’s begin.
OK, guys, are you right? Wow, I heard John said he had the correct prediction.The passage tells us some information about Mickey Mouse. Oh, most of you are right! I am so proud of you.
For the second time, you should read it carefully and catch some detail informations. After that, you should answer some true or false question. Okay? Let’s start. Time is up. The first one, It’s easy, right? Answer me together. It’s true. Then the second question. Lily, what’s your answer? It ’s false. Can you correct it ? Great. Thank you. The last one, boys come on. Eric please. It’s true.perfect.

巩固

We have done so many exercises.It’s time for fun. Let’s have a group discussion. Think about the topic: Introducing your favorite cartoon characters to group members. Work in group of 4 and discuss with your partners. Then show your work on the stage. You have 5 minutes to prepare.Are you ready? Go! Time is up. Which group goes first? Christina and your partners, please. Wow, your ideas are very creative and Your pronunciation is perfect.Let’s give them a big hand.

总结

How time files! The class is almost over. Before ending our class, let’s have a summary. Who can summarize what we have learned this class? Fiona please. Very good. I hope you can apply what we have learned in your daily life so that we can improve our reading and speaking ability, right?
Our homework is as follows: You should finish the exercise book and search for more information about famous cartoons on the Internet. Next class, we will share them together.

Class is over, see you next time.

Dps.config.js 中文说明文档

本配置文件用以生成 Vue 应用的骨架屏。


基本配置字段说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  const dpsConfig = {
url: 'file:///Users/myname/Desktop/project/pro/scaleTips/dist/index.html#/',
// 待生成骨架屏页面的地址,用百度(https://baidu.com)试试也可以
output: {
filepath: '/Users/myname/Desktop/project/pro',
// 生成骨架屏的存放页面,一般为项目的入口页面
injectSelector: '#app'
// 生成的骨架屏插入页面的节点
},
// header: {
// height: 40,
// background: '#1b9af4'
// },
// background: '#eee',
// animation: 'opacity 1s linear infinite;',
//用于定制或排除某些节点的绘制行为
includeElement: function(node, draw) {
// 定制某个节点画出来的样子,带上return false
if(node.id == 'ui-alert') {
//跳过该节点及其子节点
return false;
}
if(node.tagName.toLowerCase() === 'img') {
// 对该图片生成宽100%,高8%,颜色为红色的色块
draw({
width: 100,
height: 8,
left: 0,
top: 0,
zIndex: 99999999,
background: 'red'
});
return false;
}
},
// writePageStructure: function(html) {
// 自己处理生成的骨架屏
// fs.writeFileSync(filepath, html);
// console.log(html)
// },
init: function() {
// 生成骨架屏之前的操作,比如删除干扰节点
}
}

module.exports = dpsConfig;