WebApp【公共组件库】@前端(For Git Submodule)
Tevin
2023-10-18 8ee8b95561e2103bbebeab295c32379814610a57
Merge branch 'master' of ssh://dev.zhiheiot.com:29418/mob-components
5 files added
8 files modified
360 ■■■■ changed files
forms/chinaArea/ChinaLocations.js 14 ●●●● patch | view | raw | blame | history
forms/chinaArea/SmartAddress.js 17 ●●●●● patch | view | raw | blame | history
forms/input/CInput.vue 4 ●●●● patch | view | raw | blame | history
forms/input/CInputScanCode.scss 4 ●●●● patch | view | raw | blame | history
forms/switch/cSwitch.scss 4 ●●●● patch | view | raw | blame | history
plugins/filter/CFilter.vue 19 ●●●●● patch | view | raw | blame | history
plugins/filter/CFilterInput.vue 51 ●●●●● patch | view | raw | blame | history
plugins/filter/CFilterRadio.vue 60 ●●●●● patch | view | raw | blame | history
plugins/filter/CFilterSelect.vue 1 ●●●● patch | view | raw | blame | history
plugins/filter/cFilter.scss 56 ●●●●● patch | view | raw | blame | history
plugins/filter/cFilterInput.scss 25 ●●●●● patch | view | raw | blame | history
plugins/filter/cFilterRadio.scss 45 ●●●●● patch | view | raw | blame | history
plugins/filter/cFilterSelect.scss 60 ●●●●● patch | view | raw | blame | history
forms/chinaArea/ChinaLocations.js
@@ -27,7 +27,7 @@
    success: response => {
        locationRes = response.data;
        readyCallbacks.forEach(callback => callback());
    }
    },
});
export class ChinaLocations {
@@ -213,8 +213,16 @@
            if (typeof regions === 'string') {
                regions = regions.split(',');
            }
            if (!regions || regions.length === 0 || !regions[0]) {
            if (!regions || regions.length === 0 || !regions[0] || !regions[1]) {
                callback('');
                return;
            }
            // 中文转编码
            if (!/^\d+$/.test(regions[0])) {
                this.getRegionCodes(regions, regionsCode => {
                    this.getRegionsArea(regionsCode, callback);
                });
                return;
            }
            let area = '';
            // 省
@@ -238,6 +246,6 @@
            callback(area);
        });
    }
};
}
export const $locations = new ChinaLocations();
forms/chinaArea/SmartAddress.js
@@ -158,7 +158,7 @@
                    }
                }
            }
        })
        });
    }
    _isAddress(tree, content) {
@@ -175,7 +175,8 @@
    _parseAddress(chinaTree, content) {
        content = content.replace('中国', '');
        // 省份处理 ---
        const provinceTailReg = /特别行政区|自治区|省|市$/;
        const provinceTail = '特别行政区|壮族自治区|回族自治区|维吾尔自治区|自治区|省|市';
        const provinceTailReg = new RegExp(provinceTail + '$');
        for (let province of chinaTree) {
            const provinceStr = province.label.replace(provinceTailReg, '');
            // 省份匹配
@@ -184,10 +185,11 @@
                this.wordData.province = province.label;
                this.wordData.provinceCode = province.value;
                // 移除省份
                const provinceNameReg = new RegExp('^' + provinceStr + '(特别行政区|自治区|省|市)?');
                const provinceNameReg = new RegExp('^' + provinceStr + '(' + provinceTail + ')?');
                content = content.replace(provinceNameReg, '');
                // 市级处理 ---
                const cityTailReg = /市|区|县|自治县|自治州|地区$/;
                const cityTail = '市|区|县|自治县|自治州|地区';
                const cityTailReg = new RegExp(cityTail + '$');
                for (let city of province.children) {
                    const cityStr = city.label.replace(cityTailReg, '');
                    // 市级匹配
@@ -196,10 +198,11 @@
                        this.wordData.city = city.label;
                        this.wordData.cityCode = city.value;
                        // 移除市级
                        const cityNameReg = new RegExp('^' + cityStr + '(市|区|县|自治县|自治州|地区)?');
                        const cityNameReg = new RegExp('^' + cityStr + '(' + cityTail + ')?');
                        content = content.replace(cityNameReg, '');
                        // 区级处理 ---
                        const distTailReg = /市|区|县|镇|乡|自治县|开发区|新区|矿区|旗|自治旗$/;
                        const distTail = '市|区|县|镇|乡|自治县|开发区|新区|矿区|旗|自治旗';
                        const distTailReg = new RegExp(distTail + '$');
                        for (let dist of city.children) {
                            const distStr = dist.label.replace(distTailReg, '');
                            // 区级匹配
@@ -208,7 +211,7 @@
                                this.wordData.dist = dist.label;
                                this.wordData.distCode = dist.value;
                                // 移除区级
                                const distNameReg = new RegExp('^' + distStr + '(市|区|县|镇|乡|自治县|开发区|新区|矿区|旗|自治旗)?');
                                const distNameReg = new RegExp('^' + distStr + '(' + distTail + ')?');
                                content = content.replace(distNameReg, '');
                            }
                        }
forms/input/CInput.vue
@@ -17,7 +17,7 @@
            :error="itemRes.error"
            :cursorSpacing="0"
            :value="value"
            :onChange="evt => hanldeChange(evt)"
            :onChange="evt => handleChange(evt)"
        >
            <slot v-if="!unit" />
            <text
@@ -61,7 +61,7 @@
        },
    },
    methods: {
        hanldeChange(evt) {
        handleChange(evt) {
            // 去除首尾空格,小程序中还可以粘贴换行符进来
            const changeValue = ((evt || '') + '')
                .replace(/^\s+|\s+$/g, '')
forms/input/CInputScanCode.scss
@@ -21,6 +21,10 @@
            animation: atRotate 1s linear infinite;
            transform-origin: 50% 48%;
        }
        .at-button__text text {
            color: #fff;
            padding: 0;
        }
    }
    .at-input__icon {
        display: none;
forms/switch/cSwitch.scss
@@ -56,7 +56,7 @@
        }
        .c-switch-radio-item {
            display: inline-block;
            padding-left: 18px;
            padding-left: 24px;
        }
        .c-switch-radio-icon {
            @include flexbox(inline, center center);
@@ -90,7 +90,7 @@
            padding-right: 0;
            .c-switch-radio-item {
                padding-left: 0;
                padding-right: 22px;
                padding-right: 24px;
            }
        }
    }
plugins/filter/CFilter.vue
@@ -67,6 +67,21 @@
                        :value="filterRes[item.name]"
                        :onChange="evt=>handleItemChange(item.name, evt)"
                    />
                    <CFilterRadio
                        v-if="item.type==='radio'"
                        type="item"
                        :label="item.label"
                        :options="selectOptions[item.name] || []"
                        :value="filterRes[item.name]"
                        :onChange="evt=>handleItemChange(item.name, evt)"
                    />
                    <CFilterInput
                        v-if="item.type==='input'"
                        type="item"
                        :label="item.label"
                        :value="filterRes[item.name]"
                        :onChange="evt=>handleItemChange(item.name, evt)"
                    />
                </view>
            </scroll-view>
            <view class="c-filter-drawer-btn">
@@ -92,6 +107,8 @@
import { CDrawer } from '@components/layout/drawer';
import CFilterSelect from './CFilterSelect';
import CFilterDateRange from './CFilterDateRange';
import CFilterRadio from './CFilterRadio';
import CFilterInput from './CFilterInput';
import './cFilter.scss';
export default {
@@ -101,6 +118,8 @@
        AtButton,
        CFilterSelect,
        CFilterDateRange,
        CFilterRadio,
        CFilterInput,
        CDrawer,
    },
    props: {
plugins/filter/CFilterInput.vue
New file
@@ -0,0 +1,51 @@
/**
 * CFilterInput - 筛选项目,单选
 * @author Tevin
 */
<template>
    <view
        class="c-filter-input"
        :class="'type-'+type"
    >
        <view class="label">{{label}}</view>
        <AtInput
            type="text"
            :placeholder="'请输入' + label"
            :value="value"
            :onChange="evt => handleChange(evt)"
        />
    </view>
</template>
<script>
import Taro from '@tarojs/taro';
import { AtInput } from 'taro-ui-vue';
import './cFilterInput.scss';
export default {
    name: 'CFilterInput',
    components: {
        AtInput,
    },
    props: {
        type: String,
        label: String,
        value: String,
        onChange: Function,
    },
    data() {
        return {};
    },
    methods: {
        handleChange(value) {
            if (value) {
                this.onChange(value);
            } else {
                this.onChange(undefined);
            }
        },
    },
    mounted() {},
};
</script>
plugins/filter/CFilterRadio.vue
New file
@@ -0,0 +1,60 @@
/**
 * CFilterRadio - 筛选项目,单选
 * @author Tevin
 */
<template>
    <view
        class="c-filter-radio"
        :class="'type-'+type"
    >
        <view
            class="label"
            v-if="type==='item'"
        >{{label}}</view>
        <view class="content">
            <view
                class="c-filter-radio-item"
                v-for="item of options"
                :key="item.value"
                @tap="evt => handleChange(item.value)"
            >
                <view
                    class="c-filter-radio-icon"
                    :class="value === item.value ? 'checked' : ''"
                >
                    <AtIcon value="check" />
                </view>
                <view class="c-filter-radio-label">{{item.label || item.name}}</view>
            </view>
        </view>
    </view>
</template>
<script>
import Taro from '@tarojs/taro';
import { AtIcon } from 'taro-ui-vue';
import './cFilterRadio.scss';
export default {
    name: 'CFilterRadio',
    components: {
        AtIcon,
    },
    props: {
        type: String,
        label: String,
        options: Array,
        value: [String, Number],
        onChange: Function,
    },
    data() {
        return {};
    },
    methods: {
        handleChange(value) {
            this.onChange(value);
        },
    },
};
</script>
plugins/filter/CFilterSelect.vue
@@ -35,6 +35,7 @@
<script>
import Taro from '@tarojs/taro';
import './cFilterSelect.scss';
export default {
    name: 'CFilterSelect',
plugins/filter/cFilter.scss
@@ -44,7 +44,7 @@
                width: 12px;
                height: 12px;
                content: " ";
                background-color: #36a0e7;
                background-color: $colorDanger;
                border-radius: 50%;
            }
        }
@@ -83,60 +83,6 @@
                    color: #36a0e7;
                    background-color: #d4f1f7;
                }
            }
        }
    }
}
.c-filter-select {
    .content {
        @include flexbox(flex, flex-start center);
        white-space: nowrap;
        .empty,
        .value {
            display: inline-block;
            vertical-align: middle;
            @include ellipsis();
        }
        .empty {
            color: #ccc;
        }
        .filled {
            color: #6190e8;
        }
        .at-icon {
            text-align: center;
            color: #666;
        }
    }
    &.type-bar {
        .content {
            height: 86px;
            .label {
                padding-right: 12px;
                color: #666;
            }
            .filled {
                letter-spacing: -2px;
            }
            .at-icon {
                padding-left: 4px;
                vertical-align: middle;
            }
        }
    }
    &.type-item {
        .label {
            color: #666;
            line-height: 40px;
        }
        .content {
            .empty,
            .filled {
                flex: 6;
            }
            .at-icon {
                flex: 1;
            }
        }
    }
plugins/filter/cFilterInput.scss
New file
@@ -0,0 +1,25 @@
/**
 * CFilterInput
 * @author Tevin
 */
@import "../../common/sassMixin";
.c-filter-input {
    .label {
        line-height: 40px;
    }
    .at-input {
        height: 90px;
        padding: 0;
        margin: 0;
        background-color: transparent;
        &::after {
            display: none;
        }
        input {
            height: 90px;
            line-height: 90px;
        }
    }
}
plugins/filter/cFilterRadio.scss
New file
@@ -0,0 +1,45 @@
/**
 * CFilterSwitchRadio
 * @author Tevin
 */
@import "../../common/sassMixin";
.c-filter-radio {
    .label {
        color: #666;
        line-height: 40px;
    }
    .content {
        .c-filter-radio-item {
            display: inline-block;
            padding-right: 24px;
        }
        .c-filter-radio-icon {
            @include flexbox(inline, center center);
            width: 48px;
            min-width: 48px;
            height: 48px;
            vertical-align: middle;
            color: transparent;
            font-size: 32px;
            line-height: 1;
            border: 1PX solid #c9c9c9;
            border-radius: 50%;
            background-color: #fff;
            box-sizing: border-box;
            transition: all .2s;
            &.checked {
                color: #fff;
                border: none;
                background-color: #2093df;
            }
        }
        .c-filter-radio-label {
            display: inline-block;
            vertical-align: middle;
            padding-left: 6px;
        }
    }
    &.type-item {}
}
plugins/filter/cFilterSelect.scss
New file
@@ -0,0 +1,60 @@
/**
 * filter select
 * @author Tevin
 */
@import "../../common/sassMixin";
.c-filter-select {
    .content {
        @include flexbox(flex, flex-start center);
        white-space: nowrap;
        .empty,
        .value {
            display: inline-block;
            vertical-align: middle;
            @include ellipsis();
        }
        .empty {
            color: #ccc;
        }
        .filled {
            color: #6190e8;
        }
        .at-icon {
            text-align: center;
            color: #666;
        }
    }
    &.type-bar {
        .content {
            height: 86px;
            .label {
                padding-right: 12px;
                color: #666;
            }
            .filled {
                letter-spacing: -2px;
            }
            .at-icon {
                padding-left: 4px;
                vertical-align: middle;
            }
        }
    }
    &.type-item {
        .label {
            color: #666;
            line-height: 40px;
        }
        .content {
            .empty,
            .filled {
                flex: 6;
            }
            .at-icon {
                flex: 1;
            }
        }
    }
}