linwe
2024-07-11 23a1e5b3a79d4aafb1abf5d6824b51f75eb98c6d
代码优化
19 files modified
2 files deleted
24 files added
6009 ■■■■■ changed files
api/system/region.js 2 ●●● patch | view | raw | blame | history
common/setting.js 4 ●●●● patch | view | raw | blame | history
components/btn/footerBtn.vue 16 ●●●●● patch | view | raw | blame | history
mixin/uploadMixin.js 1 ●●●● patch | view | raw | blame | history
pages.json 6 ●●●● patch | view | raw | blame | history
pages/circle/index.vue 13 ●●●●● patch | view | raw | blame | history
pages/home/index.vue 2 ●●● patch | view | raw | blame | history
pages/user/center.vue 6 ●●●●● patch | view | raw | blame | history
static/img/center-bg-2.png patch | view | raw | blame | history
static/img/center-bg.png patch | view | raw | blame | history
subPackage/house/components/householdLabel.vue 494 ●●●●● patch | view | raw | blame | history
subPackage/house/components/userInfo.vue 130 ●●●● patch | view | raw | blame | history
subPackage/house/houseNumber/siteInspect.vue 58 ●●●● patch | view | raw | blame | history
subPackage/house/member/add.vue 5 ●●●●● patch | view | raw | blame | history
subPackage/house/member/householdLabel.vue 6 ●●●● patch | view | raw | blame | history
subPackage/school/clockIn.vue 8 ●●●● patch | view | raw | blame | history
subPackage/school/troubleDetail.vue 194 ●●●● patch | view | raw | blame | history
subPackage/task/index.vue 21 ●●●● patch | view | raw | blame | history
subPackage/workbench/components/actionBtn.vue 98 ●●●● patch | view | raw | blame | history
subPackage/workbench/views/labelReportDetail.vue 30 ●●●●● patch | view | raw | blame | history
subPackage/workbench/views/reportAudit.vue 4 ●●●● patch | view | raw | blame | history
uni_modules/uni-data-picker/changelog.md 77 ●●●●● patch | view | raw | blame | history
uni_modules/uni-data-picker/components/uni-data-picker/keypress.js 45 ●●●●● patch | view | raw | blame | history
uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.uvue 380 ●●●●● patch | view | raw | blame | history
uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue 551 ●●●●● patch | view | raw | blame | history
uni_modules/uni-data-picker/components/uni-data-pickerview/loading.uts 1 ●●●● patch | view | raw | blame | history
uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js 622 ●●●●● patch | view | raw | blame | history
uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.uts 693 ●●●●● patch | view | raw | blame | history
uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.css 76 ●●●●● patch | view | raw | blame | history
uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.uvue 69 ●●●●● patch | view | raw | blame | history
uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue 323 ●●●●● patch | view | raw | blame | history
uni_modules/uni-data-picker/package.json 91 ●●●●● patch | view | raw | blame | history
uni_modules/uni-data-picker/readme.md 22 ●●●●● patch | view | raw | blame | history
uni_modules/uni-icons/components/uni-icons/uni-icons.uvue 91 ●●●●● patch | view | raw | blame | history
uni_modules/uni-icons/components/uni-icons/uniicons_file.ts 664 ●●●●● patch | view | raw | blame | history
uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js 649 ●●●●● patch | view | raw | blame | history
uni_modules/uni-load-more/changelog.md 19 ●●●●● patch | view | raw | blame | history
uni_modules/uni-load-more/components/uni-load-more/i18n/en.json 5 ●●●●● patch | view | raw | blame | history
uni_modules/uni-load-more/components/uni-load-more/i18n/index.js 8 ●●●●● patch | view | raw | blame | history
uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hans.json 5 ●●●●● patch | view | raw | blame | history
uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hant.json 5 ●●●●● patch | view | raw | blame | history
uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue 399 ●●●●● patch | view | raw | blame | history
uni_modules/uni-load-more/package.json 86 ●●●●● patch | view | raw | blame | history
uni_modules/uni-load-more/readme.md 14 ●●●●● patch | view | raw | blame | history
vue.config.js 16 ●●●●● patch | view | raw | blame | history
api/system/region.js
@@ -12,7 +12,7 @@
export const lazyTree = (parentCode) => {
    return http.request({
        url: '/api/blade-system/region/lazy-tree',
        url: '/blade-system/region/lazy-tree',
        method: 'GET',
        params: {
            parentCode
common/setting.js
@@ -10,8 +10,8 @@
    version: '2.0.0',
    // 开发环境接口Url
    // devUrl: 'http://z4042833u6.wicp.vip',
    // devUrl: 'http://localhost:9528',
    devUrl: 'https://srgdjczzxtpt.com:2080/api',
    devUrl: 'http://localhost:9528',
    // devUrl: 'https://srgdjczzxtpt.com:2080/api',
    // devUrl: 'https://kt39592615.goho.co',
    minioBaseUrl: "https://srgdjczzxtpt.com:2080/gminio/jczz/",
    // minioBaseUrl: "http://192.168.0.101:9528/",
components/btn/footerBtn.vue
@@ -1,6 +1,7 @@
<template>
    <view class="footer">
        <button class="footer-btn" @click="handel">{{text}}</button>
        <!-- <button class="footer-btn" @click="handel">{{text}}</button> -->
        <button class="footer-btn" @tap="$u.throttle(handel, 1000)">{{text}}</button>
    </view>
</template>
@@ -15,7 +16,20 @@
        },
        methods: {
            handel() {
                uni.showLoading({})
                this.$emit("click")
                // 定义 setTimeout 返回值
                let timerID = 0;
                // 启动 setTimeout 并更新 timerID
                timerID = setTimeout(() => {
                    // 执行一次
                    uni.hideLoading()
                }, 1000)
                // 取消
                // clearTimeout(timerID)
            }
        }
    }
mixin/uploadMixin.js
@@ -72,7 +72,6 @@
            var that = this;
            // 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
            let lists = [].concat(event.file)
            let fileListLen = this.form[key].length
            lists.map((item) => {
                this.form[key].push({
pages.json
@@ -1319,7 +1319,7 @@
                {
                    "path": "securityRecord",
                    "style": {
                        "navigationBarTitleText": "校园安全检查记录",
                        "navigationBarTitleText": "校园安保检查",
                        "navigationBarBackgroundColor": "#fff",
                        "navigationBarTextStyle": "black",
                        "enablePullDownRefresh": false
@@ -1346,7 +1346,7 @@
                {
                    "path": "troubleTaskList",
                    "style": {
                        "navigationBarTitleText": "校园任务",
                        "navigationBarTitleText": "问题处理与反馈",
                        "navigationBarBackgroundColor": "#fff",
                        "navigationBarTextStyle": "black",
                        "enablePullDownRefresh": false
@@ -1411,4 +1411,4 @@
            }
        ]
    }
}
}
pages/circle/index.vue
@@ -179,6 +179,7 @@
            this.$refs.paging.reload();
        },
        // onPullDownRefresh() {
        //     this.getCircleList();
        //     setTimeout(() => {
@@ -332,6 +333,18 @@
                        url: `/subPackage/ecall/detail?id=${item.eventId}&types=circle`
                    })
                }
                if (item.evenType == 4) {
                    // subPackage/school/troubleDetail?id=1811233007500054530
                    uni.navigateTo({
                        url: `/subPackage/school/troubleDetail?id=${item.eventId}&disable=true`
                    })
                }
                if (item.evenType == 5) {
                    // subPackage/workbench/views/labelReportDetail?id=1805127669027196929
                    uni.navigateTo({
                        url: `/subPackage/workbench/views/labelReportDetail?id=${item.eventId}&disable=true`
                    })
                }
pages/home/index.vue
@@ -1656,4 +1656,4 @@
<style lang="scss">
    @import "./index.scss";
</style>
</style>
pages/user/center.vue
@@ -1,8 +1,10 @@
<template>
    <view class="container">
        <view class="head">
            <image src="/static/img/center-bg.png" class="head-bg" v-if="roleType == 1" />
            <image src="/static/img/center-bg-2.png" class="head-bg" v-if="roleType == 2" />
            <image src="https://srgdjczzxtpt.com:2080/gminio/jczz/upload/20240706/d14541c0a8eba34a1a7fe441b63c4ed7.png"
                class="head-bg" v-if="roleType == 1" />
            <image src="https://srgdjczzxtpt.com:2080/gminio/jczz/upload/20240706/303714c1ca993b520414ddeb864dc647.png"
                class="head-bg" v-if="roleType == 2" />
            <!-- 用户信息 -->
            <view class="user-box">
                <view class="left">
static/img/center-bg-2.png
Binary files differ
static/img/center-bg.png
Binary files differ
subPackage/house/components/householdLabel.vue
New file
@@ -0,0 +1,494 @@
<template>
    <view class="container">
        <view class="main">
            <view class="base b-c-w" v-if="id">
                <u-icon name="/static/icon/map.png" width="15" height="18"></u-icon>
                <view>{{ houseAddress}}</view>
            </view>
            <view class="content">
                <view class="l flex-1 flex" v-if="id">
                    <view class="flex_base">
                        <view class="head-img flex_base">
                            <u--image shape="circle" :showLoading="true" src="/static/icon/user-01.png" width="120rpx"
                                height="120rpx"></u--image>
                        </view>
                    </view>
                    <view class="info">
                        <view>姓名:{{householdInfo.name}}</view>
                        <view class="flex">
                            手机:{{householdInfo.phoneNumber || ""}} <u-icon v-if="householdInfo.phoneNumber"
                                name="phone-fill" color="#4586FE"></u-icon>
                        </view>
                    </view>
                </view>
                <view v-for="(item, index) in labelBtnList" :key="index" class="label-crad">
                    <newBoxTitle :title="item.name"></newBoxTitle>
                    <block v-if="item.children[0].children.length">
                        <u-collapse accordion :border="false">
                            <u-collapse-item :title="c.name" v-for="(c, k) in item.children" :key="k">
                                <view class="label-btn-box">
                                    <view v-for="(i, f) in c.children" :key="f">
                                        <u-button size="mini" type="primary" :color="$setLabelColor(i.color)"
                                            :style="{color: $setLabelColor(i.color) && '#fff'}" :text="i.name"
                                            @click="showLabelPopup(i,index,f,true)"></u-button>
                                    </view>
                                </view>
                            </u-collapse-item>
                        </u-collapse>
                    </block>
                    <view class="label-btn-box" v-else>
                        <view v-for="(item, k) in item.children" :key="k">
                            <u-button size="mini" type="primary" :color="$setLabelColor(item.color)"
                                :style="{color: $setLabelColor(item.color) && '#fff'}" :text="item.name"
                                @click="showLabelPopup(item,index,k,false)"></u-button>
                        </view>
                    </view>
                </view>
            </view>
            <!-- <button @click="commit" type="primary">确认</button> -->
        </view>
        <u-modal style="flex: none;" :show="popupShow" :closeOnClickOverlay="true" showCancelButton
            @cancel="popupShow = false" @confirm="popupConfirm">
            <view class="slot-content">
                <view class="flex_base">
                    {{ labelModelInfo.title }}
                </view>
                <u-radio-group class="mt-40" v-model="labelValue" placement="row">
                    <u-radio :customStyle="{marginBottom: '8px'}" v-for="(item, index) in labelList" :key="index"
                        :label="item.name" :labelColor="item.showColor" :style="{color: item.showColor && '#fff'}"
                        :name="item.name" :activeColor="item.showColor" @change="radioChange(item)">
                    </u-radio>
                </u-radio-group>
                <u--textarea class="mt-40" v-model="remark" placeholder="请输入内容"></u--textarea>
            </view>
        </u-modal>
    </view>
</template>
<script>
    import uploadMixin from "@/mixin/uploadMixin";
    import newBoxTitle from '@/subPackage/house/components/boxTitle/index2.vue'
    import {
        getLabelListByParentId
    } from "@/api/label/label.js";
    import {
        getDetail
    } from "@/api/doorplateAddress/doorplateAddress.js";
    import {
        saveOrUpdateHouseholdLabel,
        removeHouseholdLabel
    } from "@/api/house/householdLabel.js"
    import {
        getHouseholdDetail
    } from "@/api/house/household.js"
    export default {
        mixins: [uploadMixin],
        components: {
            newBoxTitle
        },
        data() {
            return {
                householdLabelList: [],
                showType: false,
                houseAddress: "",
                houseInfo: {},
                householdInfo: {},
                houseCode: "",
                popupShow: false,
                labelBtnList: [],
                // 安置房弹框中
                labelList: [{
                        name: '撤销',
                        disabled: false,
                        // color: '#EBEDF0'
                        showColor: '#999',
                        color: '#999'
                    },
                    {
                        name: '绿',
                        disabled: false,
                        showColor: '#30D17C',
                        color: 'green'
                    },
                    {
                        name: '黄',
                        disabled: false,
                        showColor: '#FFB42B',
                        color: 'yellow'
                    }, {
                        name: '红',
                        disabled: false,
                        showColor: '#EA1F1F',
                        color: 'red'
                    }
                ],
                currentLabelInfo: {},
                currentColorInfo: {},
                labelModelInfo: {
                    title: '',
                    selectedColor: ''
                },
                labelValue: '',
                remark: '',
                // 标记
                number: 0,
                id: "",
                from: "",
                fIndex: "",
                cIndex: ""
            }
        },
        mounted() {
            console.log("option*****************1************==>");
            this.getLabelList()
        },
        onLoad(option) {
            console.log("option*****************2************==>");
            // console.log("option==>", option);
            // const data = JSON.parse(option.data);
            // this.householdInfo = data;
            // this.houseCode = data.houseCode
            // if (data.id) {
            //     this.id = data.id;
            //     this.getDoorPlateAddressDetail()
            // }
            // if (option.from) {
            //     this.from = option.from;
            // }
            // this.getDoorPlateAddressDetail()
        },
        onShow() {
            console.log("option*****************************==>");
            this.getLabelList()
        },
        methods: {
            // 提交
            commit() {
                // this.$emit('getLableCallback', this.householdLabelList);
            },
            init(from) {
                this.from = from
            },
            // 获取房屋详情
            async getDoorPlateAddressDetail() {
                const param = {
                    addressCode: this.houseCode
                }
                const res = await getDetail(param)
                this.houseInfo = res.data
                const aoiName = (this.houseInfo.aoiName || this.houseInfo.subAoi)
                const unitName = this.houseInfo.unitName == null ? "" : this.houseInfo.unitName
                this.houseAddress = aoiName +
                    this.houseInfo.buildingName + unitName + this.houseInfo.houseName + "室"
            },
            // 获取房屋标签信息
            async getLabelList() {
                if (this.from) {
                    this.from.householdLabelList = this.householdLabelList
                }
                // 房屋标签处理
                const labelParam = {
                    parentId: 1000
                }
                const resLabel = await getLabelListByParentId(labelParam)
                this.labelBtnList = resLabel.data
                const labelChildAll = []
                // 将细类放到一起
                this.labelBtnList.forEach(e => {
                    e.children.forEach(f => {
                        if (f.children.length) {
                            f.children.forEach(k => {
                                labelChildAll.push(k)
                            })
                        } else {
                            labelChildAll.push(f)
                        }
                    })
                })
                if (this.householdLabelList.length > 0) {
                    labelChildAll.forEach(e => {
                        this.householdLabelList.forEach(household => {
                            if (Number(e.id) == household.labelId) {
                                e['color'] = household.color
                                e['remark'] = household.remark
                            }
                        })
                    })
                }
                console.log("ces ", this.labelBtnList)
            },
            // 房屋弹窗
            showLabelPopup(item, fIndex, cIndex, type) {
                // 先清空
                this.number = 0
                this.labelValue = ""
                this.remark = ""
                this.popupShow = true
                this.showType = type
                this.labelModelInfo.title = item.name
                this.currentLabelInfo = item;
                this.fIndex = fIndex;
                this.cIndex = cIndex;
                // 遍历标签集合
                this.labelList.forEach(e => {
                    if (e.color == item.color) {
                        this.labelValue = e.name
                        this.remark = item.remark
                        this.number = 1
                    }
                })
            },
            // popupConfirm() {
            //     this.popupShow = false
            // },
            radioChange(item) {
                this.currentColorInfo = item
            },
            // 更新房屋标签
            async popupConfirm() {
                const {
                    id
                } = this.currentLabelInfo
                const {
                    color,
                    name
                } = this.currentColorInfo
                let res = null
                if (name === '撤销') {
                    if (this.number == 1) {
                        // this.removeLabel(id)
                        let lableList = this.householdLabelList
                        this.householdLabelList = lableList.filter(item => item.labelId !== id);
                        this.getLabelList()
                    } else {
                        uni.showToast({
                            title: "无可撤销项",
                            icon: "error",
                            duration: 1500
                        })
                        return
                    }
                } else {
                    if (!color) return;
                    this.addLabel(id, color)
                }
                // 刷新页面
                // if (!this.from) {
                //     this.getLabelList()
                // }
                this.popupShow = false
            },
            removeLabel(id) {
                // if (this.from) {
                //     let item = this.labelBtnList[this.fIndex];
                //     item.children[this.cIndex].color = "";
                //     this.$set(this.labelBtnList, this.fIndex, item);
                //     this.updatePrePageData()
                // } else
                {
                    const data = {
                        labelId: id,
                        householdId: this.householdInfo.id
                    }
                    removeHouseholdLabel(data).then(res => {
                        if (res.code != 200) {
                            uni.showToast({
                                title: "操作失败",
                                icon: "error",
                                duration: 1200
                            })
                        } else {
                            this.getLabelList()
                        }
                    })
                }
            },
            addLabel(id, color) {
                let pamars = {
                    labelId: id,
                    labelName: this.labelModelInfo.title,
                    remark: this.remark,
                    lableType: 1,
                    color: color,
                    houseCode: this.from.houseCode
                }
                this.householdLabelList.push(pamars)
                this.getLabelList()
                // if (this.from) {
                //     let item = this.labelBtnList[this.fIndex];
                //     console.log("**********" + color)
                //     if (this.showType) {
                //         item.children[this.fIndex].children[this.cIndex].color = color;
                //         item.children[this.fIndex].children[this.cIndex].remark = this.remark;
                //         this.$set(this.labelBtnList, this.fIndex, item);
                //     } else {
                //         item.children[this.cIndex].color = color;
                //         item.children[this.cIndex].remark = this.remark;
                //         this.$set(this.labelBtnList, this.fIndex, item);
                //     }
                //     this.updatePrePageData()
                // } else
                // {
                //     saveOrUpdateHouseholdLabel({
                //         householdId: this.householdInfo.id,
                //         labelId: id,
                //         labelName: this.labelModelInfo.title,
                //         remark: this.remark,
                //         lableType: 1,
                //         color,
                //         houseCode: this.houseCode,
                //         userId: this.householdInfo.associatedUserId
                //     }).then(res => {
                //         if (res.code != 200) {
                //             uni.showToast({
                //                 title: "操作失败",
                //                 icon: "error",
                //                 duration: 1200
                //             })
                //         } else {
                //             this.getLabelList()
                //         }
                //     })
                // }
            },
            //更新上个页面标签数据
            updatePrePageData() {
                let pages = getCurrentPages();
                let prePage = pages[pages.length - 2];
                let arr = []
                for (let i = 0, ii = this.labelBtnList.length; i < ii; i++) {
                    for (let k = 0, kk = this.labelBtnList[i].children.length; k < kk; k++) {
                        if (this.labelBtnList[i].children[k].color) {
                            arr.push({
                                color: this.labelBtnList[i].children[k].color,
                                labelId: this.labelBtnList[i].children[k].id,
                                labelName: this.labelBtnList[i].children[k].name,
                                lableType: 1,
                                houseCode: prePage.$vm.houseCode
                            })
                        }
                    }
                }
                this.$set(prePage.$vm.form, "householdLabelList", arr);
            }
        }
    }
</script>
<style>
    page {
        background-color: #fff;
    }
</style>
<style scoped lang="scss">
    .container {
        width: 100%;
        height: 100%;
        display: flex;
        flex-direction: column;
        background: #f6f6f6;
        .main {
            // position: relative;
            // height: 0;
            // flex: 1;
            // display: flex;
            // flex-direction: column;
            .base {
                padding: 20rpx 18rpx;
                display: flex;
                color: #333333;
                background: #fff;
                min-height: 38rpx;
                font-size: 30rpx;
                view {
                    margin-left: 15rpx;
                }
            }
            .content {
                // height: 0;
                // flex: 1;
                overflow-y: auto;
                margin: 20rpx 30rpx;
                .l {
                    background-color: #ffffff;
                    align-items: center;
                    padding: 30rpx 30rpx;
                    border-radius: 8rpx;
                    .head-img {
                        width: 124rpx;
                        height: 124rpx;
                        border-radius: 50%;
                    }
                    .info {
                        margin-left: 20rpx;
                        font-size: 24rpx;
                        &>view {
                            height: 56rpx;
                            line-height: 56rpx;
                        }
                    }
                }
                .basic-info {
                    .form-item {
                        background-color: #ffffff;
                        padding: 5rpx 20rpx;
                    }
                }
                .pic {
                    background-color: #ffffff;
                    padding: 40rpx 30rpx;
                }
                .label-crad {
                    background-color: #fff;
                    margin-top: 20rpx;
                    padding: 30rpx;
                    border-radius: 8rpx;
                    .label-btn-box {
                        display: flex;
                        flex-direction: row;
                        flex-wrap: wrap;
                        &>view {
                            margin: 0 20rpx 20rpx 0;
                            /deep/ .u-button {
                                padding: 6rpx 8rpx;
                                border-width: 0 !important;
                                background-color: #F5F5F5;
                                color: #999999;
                            }
                        }
                    }
                }
            }
        }
    }
</style>
subPackage/house/components/userInfo.vue
@@ -10,8 +10,8 @@
                        </u-form-item>
                        <u-form-item @click="showSelectBus('性别','gender')" class="form-item" labelWidth="110" label="性别"
                            prop="gender">
                            <u--input border="none" v-model="selectDefaultName.genderValue" disabled
                                disabledColor="#ffffff" placeholder="请选择性别">
                            <u--input border="none" v-model="selectDefaultName.gender" disabled disabledColor="#ffffff"
                                placeholder="请选择性别">
                            </u--input>
                            <u-icon slot="right" name="arrow-right"></u-icon>
                        </u-form-item>
@@ -36,18 +36,24 @@
                            <u--input border="none" type="number" v-model="form.phoneNumber" placeholder="请输入手机号码">
                            </u--input>
                        </u-form-item>
                        <u-form-item class="form-item" labelWidth="110" label="户籍地区" prop="residentAdcode">
                            <view class="region">
                                <picker mode="region" :value="residentadDefault" @change="changeHouseholdRegion">
                                <uni-data-picker :border="false" v-model="residentadDefault"
                                    :map="{text:'name',value:'id'}" :localdata="cityList" popup-title="请选择户籍地区"
                                    @change="onchange" @nodeclick="onnodeclick"></uni-data-picker>
                                <!-- <picker mode="region" custom-item="children" :range="cityList" range-key="name"
                                    :value="residentadDefault" @change="changeHouseholdRegion">
                                    <view class="region-picker c-c0" v-if="!residentad">
                                        请选择户籍地区
                                    </view>
                                    <view class="region-picker c-30" v-if="residentad">
                                        {{residentad}}
                                    </view>
                                </picker>
                                </picker> -->
                            </view>
                            <u-icon slot="right" name="arrow-right"></u-icon>
                            <!-- <u-icon slot="right" name="arrow-right"></u-icon> -->
                        </u-form-item>
                        <u-form-item @click="showSelectBus('与业主关系','relationship')" class="form-item" labelWidth="120"
@@ -81,7 +87,7 @@
                        <u-form-item @click="showSelectBus('民族','ethnicity')" class="form-item" labelWidth="110"
                            label="民族" prop="ethnicity">
                            <u--input border="none" v-model="selectDefaultName.ethnicityValue" disabled
                            <u--input border="none" v-model="selectDefaultName.ethnicity" disabled
                                disabledColor="#ffffff" placeholder="请选择民族">
                            </u--input>
                            <u-icon slot="right" name="arrow-right"></u-icon>
@@ -183,16 +189,20 @@
                        </u-form-item> -->
                        <u-form-item class="form-item" labelWidth="110" label="籍贯地区" prop="nativePlaceAdcode">
                            <view class="region">
                                <picker mode="region" :value="navtivePlaceDefault" @change="changeNativeRegion">
                                <uni-data-picker :border="false" v-model="navtivePlaceDefault"
                                    :map="{text:'name',value:'id'}" :localdata="cityList" popup-title="请选择户籍地区"
                                    @change="changeNativeRegion" @nodeclick="onnodeclick"></uni-data-picker>
                                <!-- <picker :range="cityList" range-key="name" :value="navtivePlaceDefault"
                                    @change="changeNativeRegion">
                                    <view class="region-picker c-c0" v-if="!nativePlace">
                                        请选择籍贯地区
                                    </view>
                                    <view class="region-picker c-30" v-if="nativePlace">
                                        {{nativePlace}}
                                    </view>
                                </picker>
                                </picker> -->
                            </view>
                            <u-icon slot="right" name="arrow-right"></u-icon>
                            <!-- <u-icon slot="right" name="arrow-right"></u-icon> -->
                        </u-form-item>
                        <u-form-item @click="showSelectBus('户籍类型','residentType')" class="form-item" labelWidth="110"
@@ -289,11 +299,11 @@
            :show="typeShow" :columns="[selectBusList]" @close="typeShow = false" @cancel="typeShow = false"
            keyName="name" @confirm="typeSelect"></u-picker>
        <u-datetime-picker :show="showSelectDate" v-model="currentTime" mode="date" :formatter="formatter"
            @confirm="confirmDate" @cancel="showSelectDate = false" :minDate="goOutMinDate"></u-datetime-picker>
        <u-datetime-picker :show="showSelectDate" v-model="currentTime" mode="date" @confirm="confirmDate"
            @cancel="showSelectDate = false"></u-datetime-picker>
        <u-datetime-picker :show="showSelectBirthday" v-model="currentTime" mode="date" @confirm="confirmBirthday"
            @cancel="showSelectBirthday = false" :minDate="minDate"></u-datetime-picker>
            @cancel="showSelectBirthday = false"></u-datetime-picker>
        <u-picker :defaultIndex="[homeIndex]" :closeOnClickOverlay="true" :show="showRegion" :columns="[regionList]"
            @close="showRegion = false" @cancel="showRegion = false" keyName="name" @confirm="regionSelect"></u-picker>
@@ -302,7 +312,7 @@
            :columns="[volunteerOrgTypeList]" @close="showRegion = false" @cancel="showVolunteerOrg = false"
            @confirm="confirmVolunteerOrg"></u-picker>
        <u-popup :show="isShowPopup" mode="bottom" :round="12" closeable="true" @close="isShowPopup = false">
        <u-popup :show="isShowPopup" mode="bottom" :round="12" :closeable="true" @close="isShowPopup = false">
            <view class="popup-content">
                <z-paging ref="paging" v-model="houseList" @query="queryHouseList" @onRefresh="refreshList"
                    :fixed="false">
@@ -326,6 +336,13 @@
            </view>
        </u-popup>
        <u-popup :show="isShowPopupLabel" mode="center" :round="12" :closeable="true" @close="isShowPopupLabel = false">
            <view class="popup-lable">
                <householdLabel id="formLable" ref="formLable" @getLableCallback="handleData"></householdLabel>
            </view>
        </u-popup>
    </view>
</template>
@@ -356,11 +373,13 @@
        getHouseList
    } from "@/api/house/house.js"
    import boxTitle from '../components/boxTitle/index2.vue'
    // import boxTitle from '../components/boxTitle/index2.vue'
    import householdLabel from './householdLabel.vue'
    export default {
        components: {
            selectBus,
            boxTitle
            // boxTitle,
            householdLabel
        },
        mixins: [uploadMixin],
        data() {
@@ -368,6 +387,7 @@
                addOrUpdateTitle: "添加",
                houseCode: "",
                form: {},
                formatter: 'yyyy-MM-dd',
                rules: {
                    'selectDefaultName.relationship': {
                        required: true,
@@ -493,6 +513,7 @@
                },
                showSelectDate: false,
                regionList: [],
                cityList: [],
                nativePlace: "", //籍贯
                residentad: "", //户籍
                homeRegion: "", //居住地    
@@ -509,6 +530,7 @@
                minDate: "",
                goOutMinDate: "",
                isShowPopup: false,
                isShowPopupLabel: false,
                addressName: "",
                houseList: [],
                volunteerOrgTypeList: ["信州义警", "蓝天救援", "其他"],
@@ -523,6 +545,9 @@
            this.getHeader()
            this.getAllBizDict()
            this.setCardTypeDefault()
            this.getRegionList()
            this.getRegionTree()
        },
        onReady() {
@@ -531,8 +556,9 @@
        async onShow(option) {
            this.minDate = Number(new Date('1900-01-01')); //设置出生日期选择器最小值
            this.goOutMinDate = Number(new Date('1970-01-01')); //设置外出时间选择器最小值
            await this.getRegionList()
            await this.getAllBizDict()
            await this.getRegionList()
            this.homeRegion = uni.getStorageSync("curStreet")
            this.form.homeAdcode = this.getHouseRegion(uni.getStorageSync("curStreet")).code;
            this.homeIndex = this.getHouseRegion(uni.getStorageSync("curStreet")).index;
@@ -554,6 +580,12 @@
        // },
        methods: {
            handleData(res) {
                console.log("getback", res)
                this.isShowPopupLabel = false
                // householdLabelList
            },
            getHouseDetail(code, type) {
                getQrCodeDetail({
@@ -632,29 +664,44 @@
            //选择籍贯
            changeNativeRegion(e) {
                this.navtivePlaceDefault = e.detail.value
                let {
                    code,
                    value
                } = e.detail;
                this.nativePlace = `${value[0]}-${value[1]}-${value[2]}`
                this.form.nativePlaceAdcode = code[2];
                this.form.nativePlaceAdcode = value[2].value;
            },
            //选择户籍
            changeHouseholdRegion(e) {
            onchange(e) {
                // console.log("***1****" + JSON.stringify(e))
                this.residentadDefault = e.detail.value
                let {
                    code,
                    value
                } = e.detail;
                this.residentad = `${value[0]}-${value[1]}-${value[2]}`
                this.form.residentAdcode = code[2];
                this.form.residentAdcode = value[2].value;
            },
            onnodeclick(node) {
                // console.log("****2***" + JSON.stringify(node))
            },
            //选择户籍
            // changeHouseholdRegion(e) {
            //     let {
            //         code,
            //         value
            //     } = e.detail;
            //     this.residentad = `${value[0]}-${value[1]}-${value[2]}`
            //     this.form.residentAdcode = code[2];
            // },
            getRegionList() {
                select(361102).then(res => {
                    console.log(res);
                    // console.log(res);
                    if (res.code == 200) {
                        this.regionList = res.data;
                    }
@@ -662,10 +709,12 @@
                })
            },
            getRegionTree(callback) {
            getRegionTree() {
                regionTree().then(res => {
                    console.log("region ==>", res.data)
                    callback(res.data);
                    // console.log("region ==>", res.data)
                    // callback(res.data);
                    // 城市
                    this.cityList = res.data
                })
            },
@@ -817,9 +866,10 @@
            // 显示选择弹框
            showSelectBus(title, key) {
                // console.log("************" + JSON.stringify(this.dataList))
                // console.log("************" + key)
                this.selectBusList = this.dataList[key]
                // console.log("************" + JSON.stringify(this.selectBusList))
                // console.log("*******1*****" + JSON.stringify(this.dataList[key]))
                // console.log("******2******" + JSON.stringify(this.selectBusList))
                this.selectBusTitle = title
                // this.selectBusModel = model
                this.selectBusKey = key
@@ -828,6 +878,7 @@
            },
            //类型选择确认
            typeSelect(item) {
                console.log("****1******" + JSON.stringify(item))
                const [result] = item.value
                // this[this.selectBusModel] = result.name
                this.form[this.selectBusKey] = result.value
@@ -956,16 +1007,22 @@
            },
            navTo() {
                let data = JSON.parse(JSON.stringify(this.form));
                // let data = JSON.parse(JSON.stringify(this.form));
                console.log("form", this.form)
                // this.$u.func.globalNavigator(
                //     `householdLabel?data=${JSON.stringify(data)}&from=add`)
                if (!this.isEdit) {
                    this.$u.func.globalNavigator(
                        `householdLabel?data=${JSON.stringify(data)}&from=add`)
                } else {
                    this.$u.func.globalNavigator(
                        `householdLabel?data=${JSON.stringify(data)}`)
                }
                // if (!this.isEdit) {
                //     this.$u.func.globalNavigator(
                //         `householdLabel?data=${JSON.stringify(data)}&from=add`)
                // } else {
                //     this.$u.func.globalNavigator(
                //         `householdLabel?data=${JSON.stringify(data)}`)
                // }
                let that = this
                that.$refs.form.validate().then(res => {
                    that.selectComponent('#formLable').$vm.init(this.form)
                })
                that.isShowPopupLabel = true
            },
            delAction() {
@@ -1272,6 +1329,11 @@
        }
    }
    .popup-lable {
        max-height: 80vh;
        /* 或者其他适合的高度 */
        overflow-y: auto;
    }
    .popup-content {
        width: 100%;
subPackage/house/houseNumber/siteInspect.vue
@@ -1,6 +1,12 @@
<template>
    <view class="wrap">
        <view class="top info flex j-c-s-b a-i-c" @click="onScan()" v-if="!currentId">
            <view class="flex a-i-c">
                <u-icon name="/static/icon/nav-05.png" width="90rpx" height="90rpx"></u-icon>
                <text class="f-28 ml-10">扫码获取信息</text>
            </view>
            <u-icon name="arrow-right" size="20"></u-icon>
        </view>
        <view class="info mt-20 bgc-ff" v-if="from == 'home'">
            <view class="info-row flex j-c-s-b a-i-c" @click="isShowPopup = true">
@@ -26,19 +32,19 @@
                </view>
                <view class="info-row flex j-c-s-b a-i-c">
                    <text class="f-28">场所负责人</text>
                    <text>{{selectedPlace.principal}}</text>
                    <text>{{selectedPlace.principal||''}}</text>
                </view>
                <view class="info-row flex j-c-s-b a-i-c">
                    <text class="f-28">手机号</text>
                    <text>{{selectedPlace.principalPhone}}</text>
                    <text>{{selectedPlace.principalPhone||''}}</text>
                </view>
                <view class="info-row flex j-c-s-b a-i-c">
                    <text class="f-28">身份证号</text>
                    <text>{{selectedPlace.principalIdCard}}</text>
                    <text>{{selectedPlace.principalIdCard||''}}</text>
                </view>
                <view class="info-row flex j-c-s-b a-i-c">
                    <text class="f-28">标准地址</text>
                    <text class="info-row-right">{{selectedPlace.location}}</text>
                    <text class="info-row-right">{{selectedPlace.location||''}}</text>
                </view>
            </block>
@@ -170,7 +176,7 @@
        <u-popup :show="isShowPopup" mode="bottom" :round="10" closeable="true" @close="isShowPopup = false">
        <u-popup :show="isShowPopup" mode="bottom" :round="10" :closeable="true" @close="isShowPopup = false">
            <view class="popup-content">
                <view class="popup-title f-30">选择场所</view>
                <u-search placeholder="请输入场所名称" :showAction="true" actionText="搜索" :animation="true" v-model="placeName"
@@ -181,10 +187,6 @@
                            <text class="f-28 fw mr-20">{{i.placeName}}</text>
                            <text class="f-26" v-if="i.phoneNumber">{{i.phoneNumber}}</text>
                        </view>
                        <!--
                        <view class="f-28">
                            {{i.townStreetName}}{{i.neiName}}{{i.aoiName}}{{i.address || ""}}
                        </view> -->
                        <view class="check-icon" v-if="i.houseCode == info.houseCode">
                            <u-icon name="checkbox-mark" color="#017BFC" size="30"></u-icon>
                        </view>
@@ -209,6 +211,9 @@
        bizDictionary,
        bizDictionaryTree
    } from '@/api/system/dict.js'
    // import {
    //     getQrCodeDetail
    // } from "@/api/system/index"
    export default {
        mixins: [uploadMixin],
        data() {
@@ -286,6 +291,37 @@
        },
        methods: {
            onScan() {
                uni.scanCode({
                    success: (res) => {
                        let obj = this.getUrlParams(res.result);
                        this.getHouseType(obj.stdId);
                    }
                })
            },
            getUrlParams(url) {
                let urlStr = url.split('?')[1]
                let obj = {};
                let paramsArr = urlStr.split('&')
                for (let i = 0, len = paramsArr.length; i < len; i++) {
                    let arr = paramsArr[i].split('=')
                    obj[arr[0]] = arr[1];
                }
                return obj
            },
            getHouseType(code) {
                getPlaceDetail({
                    roleName: uni.getStorageSync("activeRole").roleName,
                    houseCode: code
                }).then(res => {
                    if (res.data) {
                        this.selectPlace(res.data)
                    }
                })
            },
            getNineTypeList(callback) {
                bizDictionaryTree({
@@ -590,7 +626,7 @@
    .top {
        display: flex;
        justify-content: flex-end;
        // justify-content: flex-end;
        padding: 20rpx;
    }
subPackage/house/member/add.vue
@@ -65,7 +65,7 @@
                    </view>
                </view>
                <view class="add-person" style="padding:20rpx 30rpx;" v-if="!currentId">
                <view class="add-person" style="padding:20rpx 30rpx;">
                    <u-button type="success" plain @click="addPerson">再加一人</u-button>
                </view>
            </view>
@@ -77,7 +77,7 @@
        <u-popup :show="isShowPopup" mode="bottom" :round="12" closeable="true" @close="isShowPopup = false">
        <u-popup :show="isShowPopup" mode="bottom" :round="12" :closeable="true" @close="isShowPopup = false">
            <view class="popup-content">
                <z-paging ref="paging" v-model="houseList" @query="queryHouseList" @onRefresh="refreshList"
                    :fixed="false">
@@ -646,7 +646,6 @@
            //表单提交
            submit() {
                let that = this
                // that.$refs.formRef.checks()
                that.$refs.form.validate().then(res => {
                    that.selectComponent('#formRef').$vm.checks()
                })
subPackage/house/member/householdLabel.vue
@@ -248,9 +248,9 @@
                    }
                })
            },
            popupConfirm() {
                this.popupShow = false
            },
            // popupConfirm() {
            //     this.popupShow = false
            // },
            radioChange(item) {
                this.currentColorInfo = item
            },
subPackage/school/clockIn.vue
@@ -109,8 +109,8 @@
                    phone: "",
                    location: "",
                    gradeAndClass: "",
                    lat: "",
                    lng: "",
                    latitude: "",
                    longitude: "",
                    houseCode: ""
                },
                rules: {
@@ -192,8 +192,8 @@
                uni.chooseLocation({
                    success: (res) => {
                        this.$set(this.info, "location", res.address);
                        this.$set(this.info, "lat", res.latitude);
                        this.$set(this.info, "lng", res.longitude)
                        this.$set(this.info, "latitude", res.latitude);
                        this.$set(this.info, "longitude", res.longitude)
                    }
                })
            },
subPackage/school/troubleDetail.vue
@@ -64,7 +64,29 @@
            </view>
        </view>
        <block v-if="roleTypeName == 'mj'">
        <block v-if="roleTypeName == 'mj' && disable">
            <view class="image-wrap bgc-ff">
                <view class="mb-20">
                    <text style="color: red;">* </text> 处理意见
                </view>
                <view class="flex flex-wrap">
                    <u-textarea v-model="confirmNotion" placeholder="请输入处理意见" :disabled="true"></u-textarea>
                </view>
            </view>
            <view class="image-wrap bgc-ff">
                <view class="mb-20">
                    <text style="color: red;">* </text> 工作照片
                </view>
                <view class="flex-wrap">
                    <view class="mr-20" v-for="i in workImage">
                        <u-image :src="i" width="140rpx" height="140rpx" @click="previewImage(workImage,i)"></u-image>
                    </view>
                </view>
            </view>
        </block>
        <block v-if="roleTypeName == 'mj' && !disable">
            <view class="image-wrap bgc-ff">
                <view class="mb-20">
                    <text style="color: red;">* </text> 处理意见
@@ -92,7 +114,6 @@
                    </view>
                </u-upload>
            </view>
        </block>
@@ -118,14 +139,6 @@
                <u-form-item label="处理备注:" labelWidth="100" prop="isHandle" v-if="form.isProblem == 1">
                    <u--textarea v-model="form.handleRemark" placeholder="请输入内容"></u--textarea>
                </u-form-item>
                <!-- <u-form-item label="是否上报:" labelWidth="100" prop="isReporting" v-if="form.isHandle == 2">
                    <u-radio-group v-model="form.isReporting">
                        <u-radio :customStyle="{marginBottom: '8px'}" v-for="(item, index) in statusList" :key="index"
                            :label="item.name" :name="item.id">
                        </u-radio>
                    </u-radio-group>
                </u-form-item> -->
            </u-form>
        </view>
@@ -135,8 +148,43 @@
            v-if="roleType == 2 && info.confirmFlag == 1 && roleTypeName == 'mj' "></audit-action> -->
        <!-- <footer-btn v-if="roleType == 1  && info.confirmFlag == 3" text="编辑" @click="navToEdit" /> -->
        <footer-btn v-if="roleTypeName == 'xyzt' && info.confirmFlag == 4 " @click="submitInfo" />
        <footer-btn v-if="roleType == 2 && info.confirmFlag == 1 && roleTypeName == 'mj'" text="确定"
            @click="submitInfo" />
        <!-- <footer-btn v-if="roleType == 2 && info.confirmFlag == 1 && roleTypeName == 'mj'" text="确定"
            @click="submitInfo" /> -->
        <view class="footer flex a-i-c j-c-s-b"
            v-if="roleType == 2 && info.confirmFlag == 1 && roleTypeName == 'mj' && !disable">
            <button class="footer-btn" @click="submitInfo">处置</button>
            <button class="footer-btn" @click="submit(2)">共享</button>
        </view>
        <u-picker :defaultIndex="[defaultColums]" :closeOnClickOverlay="true" @close="isPickerShow = false"
            :show="isPickerShow" ref="uPicker" :columns="columns" keyName="name" @cancel="isPickerShow = false"
            @confirm="handleConfirm"></u-picker>
        <u-picker :defaultIndex="peopleIndex" :closeOnClickOverlay="true" @close="isShowPeoplePicker = false"
            :show="isShowPeoplePicker" ref="pPicker" :columns="peopleList" keyName="name"
            @cancel="isShowPeoplePicker = false" @confirm="handlePeopleConfirm" @change="changePeople"></u-picker>
        <u-popup :show="show" mode="bottom" @close="close" :round="10" :closeable="true">
            <view class="popup-title">
                共享
            </view>
            <view style="margin-top: 20rpx 0rpx;" class="popup-content">
                <u-radio-group v-model="radiovalue1" @change="groupChange" iconPlacement="right" placement="column">
                    <view v-for="(item, index) in radiolist1" style="padding:10rpx 0;">
                        <u-radio :customStyle="{marginBottom: '8px'}" :key="index" :label="item.name" :name="item.id"
                            @change="radioChange">
                        </u-radio>
                    </view>
                </u-radio-group>
                <view class="popup-btn flex a-i-c j-c-s-b">
                    <button class="popup-btn-item" @click="pushCircle">确认</button>
                </view>
            </view>
        </u-popup>
    </view>
</template>
@@ -144,6 +192,9 @@
<script>
    import uploadMixin from "@/mixin/uploadMixin";
    import auditAction from '@/components/btn/actionBtn.vue'
    import {
        handlePublish
    } from '@/api/circle/circle.js'
    import {
        getTroubleReportDetail,
        auditTroubleReport
@@ -158,6 +209,8 @@
        mixins: [uploadMixin],
        data() {
            return {
                disable: false,
                show: false,
                info: {},
                roleType: 1,
                id: "",
@@ -173,6 +226,18 @@
                    {
                        name: "否",
                        id: 2
                    }
                ],
                // 基本案列数据
                radiolist1: [{
                        name: '邻里圈',
                        disabled: false,
                        id: 0
                    },
                    {
                        name: '协同圈',
                        disabled: false,
                        id: 1
                    }
                ],
                roleTypeName: "",
@@ -194,6 +259,9 @@
                this.roleType == 1;
            }
            this.id = option.id;
            if (option.disable) {
                this.disable = option.disable
            }
        },
        onShow() {
@@ -201,6 +269,32 @@
        },
        methods: {
            pushCircle() {
                handlePublish({
                    houseCode: this.info.houseCode,
                    eventId: this.info.id,
                    // 校园
                    evenType: 4,
                    circleType: this.radiovalue1,
                    circleText: this.info.remark,
                    circleImages: this.info.images
                }).then(res => {
                    this.$showTips("操作成功", "success")
                    this.close()
                    // this.$set(this.peopleList, 1, res.data);
                })
            },
            close() {
                this.show = false
            },
            groupChange(n) {
                console.log('groupChange', n);
            },
            radioChange(n) {
                console.log('radioChange', n);
            },
            getDangerTypeList(callback) {
                bizDictionary({
                    code: "hiddenDangerType"
@@ -261,21 +355,7 @@
            },
            submit(val) {
                let data = {
                    id: this.info.id,
                    confirmFlag: val.type == 2 ? 2 : 3,
                }
                if (val.type == 3) {
                    data.confirmNotion = val.remark;
                }
                auditTroubleReport(data).then(res => {
                    if (res.code == 200) {
                        this.$showTips("操作成功", "success");
                        setTimeout(() => {
                            uni.navigateBack();
                        }, 300)
                    }
                })
                this.show = true
            },
            submitInfo() {
@@ -318,7 +398,7 @@
                    } else {
                        this.$showTips("请上传工作照片")
                        return;
                        // return;
                    }
                    data.confirmFlag = 2;
                    data.confirmNotion = this.confirmNotion
@@ -391,4 +471,62 @@
        width: 100%;
        height: 200rpx;
    }
    .popup-title {
        padding: 20rpx 0;
        text-align: center;
    }
    .popup-content {
        padding: 20rpx;
    }
    .popup-btn {
        padding: 20rpx;
        .popup-btn-item {
            width: 100%;
            height: 78rpx;
            line-height: 78rpx;
            border-radius: 36rpx;
            color: #fff;
            background: linear-gradient(163deg, #01BDFC 0%, #017BFC 100%);
            font-size: 28rpx;
        }
        .popup-btn-item:after {
            border: none;
        }
    }
    .footer {
        width: 100%;
        padding: 20rpx 30rpx;
        box-sizing: border-box;
        position: fixed;
        bottom: 0;
        left: 0;
        background-color: #fff;
        z-index: 10;
        padding-bottom: calc(env(safe-area-inset-bottom) + 20rpx);
        z-index: 999;
        background-color: #fff;
        box-shadow: 0rpx 0rpx 10rpx 1rpx rgba(0, 0, 0, 0.1);
        .footer-btn {
            width: 150rpx;
            height: 78rpx;
            border-radius: 8rpx;
            font-size: 32rpx;
            color: #fff;
            border: none;
            background: linear-gradient(163deg, #01BDFC 0%, #017BFC 100%);
        }
        .footer-btn:after {
            border: none;
        }
    }
</style>
subPackage/task/index.vue
@@ -135,15 +135,23 @@
                    </block>
                    <u-icon name="arrow-right" color="#999"></u-icon>
                </view>
                <!-- <view class="flex">
                    <block v-if="bailCount > 0">
            </view>
        </view>
        <view class="nav bgc-ff mb-20 mt-20" v-if="schoolList.length">
            <view class="nav-item flex j-c-s-b a-i-c" @click="navTo(`${i.path}&from=task`)" v-for="i in schoolList">
                <text class="f-28">{{i.name}}</text>
                <view class="flex">
                    <block v-if="i.count > 0">
                        <text class="f-28 c-99">待处理</text>
                        <view class="dot bgc-main">{{bailCount}}</view>
                        <view class="dot bgc-main">{{i.count}}</view>
                    </block>
                    <u-icon name="arrow-right" color="#999"></u-icon>
                </view> -->
                </view>
            </view>
        </view>
    </view>
</template>
@@ -163,6 +171,7 @@
                }],
                repairsCount: 0,
                countInfo: {},
                schoolList: [],
                securityList: [],
                comprehensive: [],
                bailCount: 0
@@ -187,8 +196,10 @@
                        if (i.remark == '1') {
                            if (i.name == "报事报修") {}
                            this.comprehensive.push(i)
                        } else {
                        } else if (i.remark == '2') {
                            this.securityList.push(i)
                        } else if (i.remark == '3') {
                            this.schoolList.push(i)
                        }
                    }
                }
subPackage/workbench/components/actionBtn.vue
@@ -4,8 +4,9 @@
            <button v-if="dataItem.type === 1" class="footer-btn" @click="submit(2)">通过</button>
            <button v-if="dataItem.type === 2" class="footer-btn" @click="submitTwo(2)">通过</button>
            <button class="footer-btn" @click="open()">驳回</button>
            <button class="footer-btn" @click="show = true">共享</button>
        </view>
        <u-modal :show="isShowModal" title="备注" :showConfirmButton="false">
        <u-modal :show="isShowModal" title="备注" :showConfirmButton="false" :closeOnClickOverlay="true" @click="close">
            <view class="modal-content">
                <u-textarea v-model="remark" placeholder="请输入驳回原因"></u-textarea>
                <view class="modal-btn flex j-c-s-b a-i-c" slot="confirmButton">
@@ -15,17 +16,29 @@
            </view>
        </u-modal>
        <u-popup :show="show" mode="bottom" @close="close" :round="10" :closeable="true">
            <view class="popup-title">
                共享
            </view>
            <view style="margin-top: 20rpx 0rpx;" class="popup-content">
                <u-radio-group v-model="radiovalue1" @change="groupChange" iconPlacement="right" placement="column">
                    <view v-for="(item, index) in radiolist1" style="padding:10rpx 0;">
                        <u-radio :customStyle="{marginBottom: '8px'}" :key="index" :label="item.name" :name="item.id"
                            @change="radioChange">
                        </u-radio>
                    </view>
                </u-radio-group>
                <view class="popup-btn flex a-i-c j-c-s-b">
                    <button class="popup-btn-item" @click="pushCircle">确认</button>
                </view>
            </view>
        </u-popup>
        <u-modal :show="isShowModalTwo" title="备注" :showConfirmButton="false">
            <view class="modal-content">
                <u-search placeholder="请输入场所名称" :clearabled="true" @blur="searchPlace()" v-model="placeName"></u-search>
                <!-- <u-search placeholder="请输入需要查询信息的姓名" v-model="placeName" :clearabled="true" :showAction="true"
                    :animation="true" @search="searchPlace"></u-search> -->
                <!-- <view v-for="(item,index) in placeList" :key="index">
                    <view :class="item.isSelect ? '':''" @click="selectChang(item)">
                        {{item.placeName +'----场所地址:'+item.location}}
                    </view>
                </view> -->
                <u-radio-group v-model="houseCode" placement="column" @change="groupChange">
                    <u-radio :customStyle="{marginBottom: '8px'}" v-for="(item, index) in placeList" :key="index"
@@ -47,6 +60,9 @@
    import {
        getLocationRecord
    } from "@/api/place/place";
    import {
        handlePublish
    } from '@/api/circle/circle.js'
    export default {
        name: "auditAction",
@@ -54,16 +70,45 @@
            return {
                isShowModal: false,
                isShowModalTwo: false,
                show: false,
                remark: "",
                placeName: '',
                houseCode: '',
                dataItem: {},
                placeList: []
                placeList: [],
                // 基本案列数据
                radiolist1: [{
                        name: '邻里圈',
                        disabled: false,
                        id: 0
                    },
                    {
                        name: '协同圈',
                        disabled: false,
                        id: 1
                    }
                ],
            }
        },
        props: ['dataItem'],
        methods: {
            pushCircle() {
                handlePublish({
                    houseCode: this.dataItem.houseCode,
                    eventId: this.dataItem.id,
                    // 二手交易
                    evenType: 5,
                    circleType: this.radiovalue1,
                    circleText: this.dataItem.labelName + ' ' + this.dataItem.transactionObject,
                    circleImages: this.dataItem.images
                }).then(res => {
                    this.$showTips("操作成功", "success")
                    this.close()
                    // this.$set(this.peopleList, 1, res.data);
                })
            },
            groupChange(n) {
                this.houseCode = n
@@ -76,6 +121,7 @@
                this.isShowModal = true;
            },
            close() {
                this.show = false
                this.isShowModal = false;
            },
@@ -144,7 +190,7 @@
        box-shadow: 0rpx 0rpx 10rpx 1rpx rgba(0, 0, 0, 0.1);
        .footer-btn {
            width: 300rpx;
            width: 200rpx;
            height: 78rpx;
            border-radius: 8rpx;
            font-size: 32rpx;
@@ -158,6 +204,7 @@
        }
    }
    .modal-content {
        width: 100%;
@@ -184,6 +231,35 @@
        }
    }
    .popup-title {
        padding: 20rpx 0;
        text-align: center;
    }
    .popup-content {
        padding: 20rpx;
    }
    .popup-btn {
        padding: 20rpx;
        .popup-btn-item {
            width: 100%;
            height: 78rpx;
            line-height: 78rpx;
            border-radius: 36rpx;
            color: #fff;
            background: linear-gradient(163deg, #01BDFC 0%, #017BFC 100%);
            font-size: 28rpx;
        }
        .popup-btn-item:after {
            border: none;
        }
    }
    /deep/ .u-modal__content {
        padding-bottom: 20rpx !important;
    }
subPackage/workbench/views/labelReportDetail.vue
@@ -34,23 +34,12 @@
                <text class="row-right">{{remark}}</text>
            </view>
            <!-- <view class="info">
                <u-form labelWidth="70" :model="form" ref="form" class="form">
                    <u-form-item label="审核状态" @click="showPicker()" class="form-item" :border-bottom="true">
                        <u--input v-model="form.confirmFlag" disabled disabledColor="#ffffff" placeholder="请选择审核状态"
                            :border="false"></u--input>
                        <u-icon slot="right" name="arrow-right"></u-icon>
                    </u-form-item>
                    <u-form-item label="备注" class="form-item" v-if="selectStatus == 3">
                        <u--input type="textarea" v-model="remark"></u--input>
                    </u-form-item>
                </u-form>
            </view> -->
        </view>
        <!-- <view class="bottom-btn" v-if="(roleType == 1 && status == 1) || (roleType == 2 && status == 2)">
            <u-button type="primary" @click="submit">提交审核</u-button>
        </view> -->
        <footer-btn v-if="roleType ==2 && status == 3" text="重新编辑" @click="navToEdit"></footer-btn>
        <audit-action :dataItem="info" @handle="submit" v-if="roleType == 1 && status == 1"></audit-action>
        <u-picker :defaultIndex="defaultIndex" :closeOnClickOverlay="true" @close="isPickerShow = false"
@@ -78,7 +67,7 @@
        data() {
            return {
                info: {
                    type: 1
                    type: 1,
                },
                basicData: [{
                        label: '物品名称',
@@ -205,8 +194,6 @@
                            title: `${data.labelName}详情`
                        })
                    }
                    this.id = data.id;
                    this.status = data.confirmFlag;
                    this.remark = data.confirmNotion;
@@ -214,8 +201,11 @@
                    this.basicData.forEach(item => {
                        item.value = data[item.name] || "未完善"
                    })
                    // this.imageUrls = this.setImages(data.imageUrls);
                    // this.goodsImageUrls = this.setImages(data.goodsImageUrls);
                    this.info.labelName = data.labelName
                    this.info.transactionObject = data.transactionObject
                    this.info.id = this.taskId
                    this.info.houseCode = data.houseCode
                    console.log("********0", this.info)
                    this.imageUrls = this.$setImageUrl(data.imageUrls);
                    this.goodsImageUrls = this.$setImageUrl(data.goodsImageUrls)
                })
subPackage/workbench/views/reportAudit.vue
@@ -306,10 +306,6 @@
            this.setDefaultValue()
        },
        methods: {
            pushCircle() {
                handlePublish({
                    houseCode: this.defaultData.addressCode,
uni_modules/uni-data-picker/changelog.md
New file
@@ -0,0 +1,77 @@
## 2.0.0(2023-12-14)
- 新增 支持 uni-app-x
## 1.1.2(2023-04-11)
- 修复 更改 modelValue 报错的 bug
- 修复 v-for 未使用 key 值控制台 warning
## 1.1.1(2023-02-21)
- 修复代码合并时引发 value 属性为空时不渲染数据的问题
## 1.1.0(2023-02-15)
- 修复 localdata 不支持动态更新的bug
## 1.0.9(2023-02-15)
- 修复 localdata 不支持动态更新的bug
## 1.0.8(2022-09-16)
- 可以使用 uni-scss 控制主题色
## 1.0.7(2022-07-06)
- 优化 pc端图标位置不正确的问题
## 1.0.6(2022-07-05)
- 优化 显示样式
## 1.0.5(2022-07-04)
- 修复 uni-data-picker 在 uni-forms-item 中宽度不正确的bug
## 1.0.4(2022-04-19)
- 修复 字节小程序 本地数据无法选择下一级的Bug
## 1.0.3(2022-02-25)
- 修复 nvue 不支持的 v-show 的 bug
## 1.0.2(2022-02-25)
- 修复 条件编译 nvue 不支持的 css 样式
## 1.0.1(2021-11-23)
- 修复 由上个版本引发的map、v-model等属性不生效的bug
## 1.0.0(2021-11-19)
- 优化 组件 UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-data-picker](https://uniapp.dcloud.io/component/uniui/uni-data-picker)
## 0.4.9(2021-10-28)
- 修复 VUE2 v-model 概率无效的 bug
## 0.4.8(2021-10-27)
- 修复 v-model 概率无效的 bug
## 0.4.7(2021-10-25)
- 新增 属性 spaceInfo 服务空间配置 HBuilderX 3.2.11+
- 修复 树型 uniCloud 数据类型为 int 时报错的 bug
## 0.4.6(2021-10-19)
- 修复 非 VUE3 v-model 为 0 时无法选中的 bug
## 0.4.5(2021-09-26)
- 新增 清除已选项的功能(通过 clearIcon 属性配置是否显示按钮),同时提供 clear 方法以供调用,二者等效
- 修复 readonly 为 true 时报错的 bug
## 0.4.4(2021-09-26)
- 修复 上一版本造成的 map 属性失效的 bug
- 新增 ellipsis 属性,支持配置 tab 选项长度过长时是否自动省略
## 0.4.3(2021-09-24)
- 修复 某些情况下级联未触发的 bug
## 0.4.2(2021-09-23)
- 新增 提供 show 和 hide 方法,开发者可以通过 ref 调用
- 新增 选项内容过长自动添加省略号
## 0.4.1(2021-09-15)
- 新增 map 属性 字段映射,将 text/value 映射到数据中的其他字段
## 0.4.0(2021-07-13)
- 组件兼容 vue3,如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 0.3.5(2021-06-04)
- 修复 无法加载云端数据的问题
## 0.3.4(2021-05-28)
- 修复 v-model 无效问题
- 修复 loaddata 为空数据组时加载时间过长问题
- 修复 上个版本引出的本地数据无法选择带有 children 的 2 级节点
## 0.3.3(2021-05-12)
- 新增 组件示例地址
## 0.3.2(2021-04-22)
- 修复 非树形数据有 where 属性查询报错的问题
## 0.3.1(2021-04-15)
- 修复 本地数据概率无法回显时问题
## 0.3.0(2021-04-07)
- 新增 支持云端非树形表结构数据
- 修复 根节点 parent_field 字段等于 null 时选择界面错乱问题
## 0.2.0(2021-03-15)
- 修复 nodeclick、popupopened、popupclosed 事件无法触发的问题
## 0.1.9(2021-03-09)
- 修复 微信小程序某些情况下无法选择的问题
## 0.1.8(2021-02-05)
- 优化 部分样式在 nvue 上的兼容表现
## 0.1.7(2021-02-05)
- 调整为 uni_modules 目录规范
uni_modules/uni-data-picker/components/uni-data-picker/keypress.js
New file
@@ -0,0 +1,45 @@
// #ifdef H5
export default {
  name: 'Keypress',
  props: {
    disable: {
      type: Boolean,
      default: false
    }
  },
  mounted () {
    const keyNames = {
      esc: ['Esc', 'Escape'],
      tab: 'Tab',
      enter: 'Enter',
      space: [' ', 'Spacebar'],
      up: ['Up', 'ArrowUp'],
      left: ['Left', 'ArrowLeft'],
      right: ['Right', 'ArrowRight'],
      down: ['Down', 'ArrowDown'],
      delete: ['Backspace', 'Delete', 'Del']
    }
    const listener = ($event) => {
      if (this.disable) {
        return
      }
      const keyName = Object.keys(keyNames).find(key => {
        const keyName = $event.key
        const value = keyNames[key]
        return value === keyName || (Array.isArray(value) && value.includes(keyName))
      })
      if (keyName) {
        // 避免和其他按键事件冲突
        setTimeout(() => {
          this.$emit(keyName, {})
        }, 0)
      }
    }
    document.addEventListener('keyup', listener)
    this.$once('hook:beforeDestroy', () => {
      document.removeEventListener('keyup', listener)
    })
  },
    render: () => {}
}
// #endif
uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.uvue
New file
@@ -0,0 +1,380 @@
<template>
  <view class="uni-data-tree">
    <view class="uni-data-tree-input" @click="handleInput">
      <slot :data="selectedPaths" :error="error">
        <view class="input-value" :class="{'input-value-border': border}">
          <text v-if="error!=null" class="error-text">{{error!.errMsg}}</text>
          <scroll-view v-if="selectedPaths.length" class="selected-path" scroll-x="true">
            <view class="selected-list">
              <template v-for="(item, index) in selectedPaths">
                <text class="text-color">{{item[mappingTextName]}}</text>
                <text v-if="index<selectedPaths.length-1" class="input-split-line">{{split}}</text>
              </template>
            </view>
          </scroll-view>
          <text v-else-if="error==null&&!loading" class="placeholder">{{placeholder}}</text>
          <view v-if="!readonly" class="arrow-area">
            <view class="input-arrow"></view>
          </view>
        </view>
      </slot>
      <view v-if="loading && !isOpened" class="selected-loading">
        <slot name="picker-loading" :loading="loading"></slot>
      </view>
    </view>
    <view class="uni-data-tree-cover" v-if="isOpened" @click="handleClose"></view>
    <view class="uni-data-tree-dialog" v-if="isOpened">
      <view class="uni-popper__arrow"></view>
      <view class="dialog-caption">
        <view class="dialog-title-view">
          <text class="dialog-title">{{popupTitle}}</text>
        </view>
        <view class="dialog-close" @click="handleClose">
          <view class="dialog-close-plus" data-id="close"></view>
          <view class="dialog-close-plus dialog-close-rotate" data-id="close"></view>
        </view>
      </view>
      <view ref="pickerView" class="uni-data-pickerview">
        <view v-if="error!=null" class="error">
          <text class="error-text">{{error!.errMsg}}</text>
        </view>
        <scroll-view v-if="!isCloudDataList" :scroll-x="true">
          <view class="selected-node-list">
            <template v-for="(item, index) in selectedNodes">
              <text class="selected-node-item" :class="{'selected-node-item-active':index==selectedIndex}"
                @click="onTabSelect(index)">
                {{item[mappingTextName]}}
              </text>
            </template>
          </view>
        </scroll-view>
        <list-view class="list-view" :scroll-y="true">
          <list-item class="list-item" v-for="(item, _) in currentDataList" @click="onNodeClick(item)">
            <text class="item-text" :class="{'item-text-disabled': item['disable']}">{{item[mappingTextName]}}</text>
            <text class="check" v-if="item[mappingValueName] == selectedNodes[selectedIndex][mappingValueName]"></text>
          </list-item>
        </list-view>
        <view class="loading-cover" v-if="loading">
          <slot name="pickerview-loading" :loading="loading"></slot>
        </view>
      </view>
    </view>
  </view>
</template>
<script>
  import { dataPicker } from "../uni-data-pickerview/uni-data-picker.uts"
  /**
   * DataPicker 级联选择
   * @description 支持单列、和多列级联选择。列数没有限制,如果屏幕显示不全,顶部tab区域会左右滚动。
   * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
   * @property {String} popup-title 弹出窗口标题
   * @property {Array} localdata 本地数据,参考
   * @property {Boolean} border = [true|false] 是否有边框
   * @property {Boolean} readonly = [true|false] 是否仅读
   * @property {Boolean} preload = [true|false] 是否预加载数据
   * @value true 开启预加载数据,点击弹出窗口后显示已加载数据
   * @value false 关闭预加载数据,点击弹出窗口后开始加载数据
   * @property {Boolean} step-searh = [true|false] 是否分布查询
   * @value true 启用分布查询,仅查询当前选中节点
   * @value false 关闭分布查询,一次查询出所有数据
   * @property {String|DBFieldString} self-field 分布查询当前字段名称
   * @property {String|DBFieldString} parent-field 分布查询父字段名称
   * @property {String|DBCollectionString} collection 表名
   * @property {String|DBFieldString} field 查询字段,多个字段用 `,` 分割
   * @property {String} orderby 排序字段及正序倒叙设置
   * @property {String|JQLString} where 查询条件
   * @event {Function} popupshow 弹出的选择窗口打开时触发此事件
   * @event {Function} popuphide 弹出的选择窗口关闭时触发此事件
   */
  export default {
    name: 'UniDataPicker',
    emits: ['popupopened', 'popupclosed', 'nodeclick', 'change', 'input', 'update:modelValue', 'inputclick'],
    mixins: [dataPicker],
    props: {
      popupTitle: {
        type: String,
        default: '请选择'
      },
      placeholder: {
        type: String,
        default: '请选择'
      },
      heightMobile: {
        type: String,
        default: ''
      },
      readonly: {
        type: Boolean,
        default: false
      },
      clearIcon: {
        type: Boolean,
        default: true
      },
      border: {
        type: Boolean,
        default: true
      },
      split: {
        type: String,
        default: '/'
      },
      ellipsis: {
        type: Boolean,
        default: true
      }
    },
    data() {
      return {
        isOpened: false
      }
    },
    computed: {
      isShowClearIcon() : boolean {
        if (this.readonly) {
          return false
        }
        if (this.clearIcon && this.selectedPaths.length > 0) {
          return true
        }
        return false
      }
    },
    created() {
      this.load()
    },
    methods: {
      clear() {
      },
      load() {
        if (this.isLocalData) {
          this.loadLocalData()
        } else if (this.isCloudDataList || this.isCloudDataTree) {
          this.loadCloudDataPath()
        }
      },
      show() {
        this.isOpened = true
        this.$emit('popupopened')
        if (!this.hasCloudTreeData) {
          this.loadData()
        }
      },
      hide() {
        this.isOpened = false
        this.$emit('popupclosed')
      },
      handleInput() {
        if (this.readonly) {
          this.$emit('inputclick')
        } else {
          this.show()
        }
      },
      handleClose() {
        this.hide()
      },
      onFinish() {
        this.selectedPaths = this.getChangeNodes()
        this.$emit('change', this.selectedPaths)
        this.hide()
      }
    }
  }
</script>
<style>
  @import url("../uni-data-pickerview/uni-data-pickerview.css");
  .uni-data-tree {
    position: relative;
  }
  .uni-data-tree-input {
    position: relative;
  }
  .selected-loading {
    display: flex;
    justify-content: center;
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
  }
  .error-text {
    flex: 1;
    font-size: 12px;
    color: #DD524D;
  }
  .input-value {
    flex-direction: row;
    align-items: center;
    flex-wrap: nowrap;
    padding: 5px 5px;
    padding-right: 5px;
    overflow: hidden;
    min-height: 28px;
  }
  .input-value-border {
    border: 1px solid #e5e5e5;
    border-radius: 5px;
  }
  .selected-path {
    flex: 1;
    flex-direction: row;
    overflow: hidden;
  }
  .load-more {
    width: 40px;
  }
  .selected-list {
    flex-direction: row;
    flex-wrap: nowrap;
  }
  .selected-item {
    flex-direction: row;
    flex-wrap: nowrap;
  }
  .text-color {
    font-size: 14px;
    color: #333;
  }
  .placeholder {
    color: grey;
    font-size: 14px;
  }
  .input-split-line {
    opacity: .5;
    margin-left: 1px;
    margin-right: 1px;
  }
  .arrow-area {
    position: relative;
    padding: 0 12px;
    margin-left: auto;
    justify-content: center;
    transform: rotate(-45deg);
    transform-origin: center;
  }
  .input-arrow {
    width: 8px;
    height: 8px;
    border-left: 2px solid #999;
    border-bottom: 2px solid #999;
  }
  .uni-data-tree-cover {
    position: fixed;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, .4);
    flex-direction: column;
    z-index: 100;
  }
  .uni-data-tree-dialog {
    position: fixed;
    left: 0;
    top: 20%;
    right: 0;
    bottom: 0;
    background-color: #FFFFFF;
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
    flex-direction: column;
    z-index: 102;
    overflow: hidden;
  }
  .dialog-caption {
    position: relative;
    flex-direction: row;
  }
  .dialog-title-view {
    flex: 1;
  }
  .dialog-title {
    align-self: center;
    padding: 0 10px;
    line-height: 44px;
  }
  .dialog-close {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    flex-direction: row;
    align-items: center;
    padding: 0 15px;
  }
  .dialog-close-plus {
    width: 16px;
    height: 2px;
    background-color: #666;
    border-radius: 2px;
    transform: rotate(45deg);
  }
  .dialog-close-rotate {
    position: absolute;
    transform: rotate(-45deg);
  }
  .uni-data-pickerview {
    flex: 1;
  }
  .icon-clear {
    display: flex;
    align-items: center;
  }
  /* #ifdef H5 */
  @media all and (min-width: 768px) {
    .uni-data-tree-cover {
      background-color: transparent;
    }
    .uni-data-tree-dialog {
      position: absolute;
      top: 55px;
      height: auto;
      min-height: 400px;
      max-height: 50vh;
      background-color: #fff;
      border: 1px solid #EBEEF5;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
      border-radius: 4px;
      overflow: unset;
    }
    .dialog-caption {
      display: none;
    }
  }
  /* #endif */
</style>
uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue
New file
@@ -0,0 +1,551 @@
<template>
  <view class="uni-data-tree">
    <view class="uni-data-tree-input" @click="handleInput">
      <slot :options="options" :data="inputSelected" :error="errorMessage">
        <view class="input-value" :class="{'input-value-border': border}">
          <text v-if="errorMessage" class="selected-area error-text">{{errorMessage}}</text>
          <view v-else-if="loading && !isOpened" class="selected-area">
            <uni-load-more class="load-more" :contentText="loadMore" status="loading"></uni-load-more>
          </view>
          <scroll-view v-else-if="inputSelected.length" class="selected-area" scroll-x="true">
            <view class="selected-list">
              <view class="selected-item" v-for="(item,index) in inputSelected" :key="index">
                <text class="text-color">{{item.text}}</text><text v-if="index<inputSelected.length-1"
                  class="input-split-line">{{split}}</text>
              </view>
            </view>
          </scroll-view>
          <text v-else class="selected-area placeholder">{{placeholder}}</text>
          <view v-if="clearIcon && !readonly && inputSelected.length" class="icon-clear" @click.stop="clear">
            <uni-icons type="clear" color="#c0c4cc" size="24"></uni-icons>
          </view>
          <view class="arrow-area" v-if="(!clearIcon || !inputSelected.length) && !readonly ">
            <view class="input-arrow"></view>
          </view>
        </view>
      </slot>
    </view>
    <view class="uni-data-tree-cover" v-if="isOpened" @click="handleClose"></view>
    <view class="uni-data-tree-dialog" v-if="isOpened">
      <view class="uni-popper__arrow"></view>
      <view class="dialog-caption">
        <view class="title-area">
          <text class="dialog-title">{{popupTitle}}</text>
        </view>
        <view class="dialog-close" @click="handleClose">
          <view class="dialog-close-plus" data-id="close"></view>
          <view class="dialog-close-plus dialog-close-rotate" data-id="close"></view>
        </view>
      </view>
      <data-picker-view class="picker-view" ref="pickerView" v-model="dataValue" :localdata="localdata"
        :preload="preload" :collection="collection" :field="field" :orderby="orderby" :where="where"
        :step-searh="stepSearh" :self-field="selfField" :parent-field="parentField" :managed-mode="true" :map="map"
        :ellipsis="ellipsis" @change="onchange" @datachange="ondatachange" @nodeclick="onnodeclick">
      </data-picker-view>
    </view>
  </view>
</template>
<script>
  import dataPicker from "../uni-data-pickerview/uni-data-picker.js"
  import DataPickerView from "../uni-data-pickerview/uni-data-pickerview.vue"
  /**
   * DataPicker 级联选择
   * @description 支持单列、和多列级联选择。列数没有限制,如果屏幕显示不全,顶部tab区域会左右滚动。
   * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
   * @property {String} popup-title 弹出窗口标题
   * @property {Array} localdata 本地数据,参考
   * @property {Boolean} border = [true|false] 是否有边框
   * @property {Boolean} readonly = [true|false] 是否仅读
   * @property {Boolean} preload = [true|false] 是否预加载数据
   * @value true 开启预加载数据,点击弹出窗口后显示已加载数据
   * @value false 关闭预加载数据,点击弹出窗口后开始加载数据
   * @property {Boolean} step-searh = [true|false] 是否分布查询
   * @value true 启用分布查询,仅查询当前选中节点
   * @value false 关闭分布查询,一次查询出所有数据
   * @property {String|DBFieldString} self-field 分布查询当前字段名称
   * @property {String|DBFieldString} parent-field 分布查询父字段名称
   * @property {String|DBCollectionString} collection 表名
   * @property {String|DBFieldString} field 查询字段,多个字段用 `,` 分割
   * @property {String} orderby 排序字段及正序倒叙设置
   * @property {String|JQLString} where 查询条件
   * @event {Function} popupshow 弹出的选择窗口打开时触发此事件
   * @event {Function} popuphide 弹出的选择窗口关闭时触发此事件
   */
  export default {
    name: 'UniDataPicker',
    emits: ['popupopened', 'popupclosed', 'nodeclick', 'input', 'change', 'update:modelValue','inputclick'],
    mixins: [dataPicker],
    components: {
      DataPickerView
    },
    props: {
      options: {
        type: [Object, Array],
        default () {
          return {}
        }
      },
      popupTitle: {
        type: String,
        default: '请选择'
      },
      placeholder: {
        type: String,
        default: '请选择'
      },
      heightMobile: {
        type: String,
        default: ''
      },
      readonly: {
        type: Boolean,
        default: false
      },
      clearIcon: {
        type: Boolean,
        default: true
      },
      border: {
        type: Boolean,
        default: true
      },
      split: {
        type: String,
        default: '/'
      },
      ellipsis: {
        type: Boolean,
        default: true
      }
    },
    data() {
      return {
        isOpened: false,
        inputSelected: []
      }
    },
    created() {
      this.$nextTick(() => {
        this.load();
      })
    },
    watch: {
            localdata: {
                handler() {
                    this.load()
                },
        deep: true
            },
    },
    methods: {
      clear() {
        this._dispatchEvent([]);
      },
      onPropsChange() {
        this._treeData = [];
        this.selectedIndex = 0;
        this.load();
      },
      load() {
        if (this.readonly) {
          this._processReadonly(this.localdata, this.dataValue);
          return;
        }
        // 回显本地数据
        if (this.isLocalData) {
          this.loadData();
          this.inputSelected = this.selected.slice(0);
        } else if (this.isCloudDataList || this.isCloudDataTree) { // 回显 Cloud 数据
          this.loading = true;
          this.getCloudDataValue().then((res) => {
            this.loading = false;
            this.inputSelected = res;
          }).catch((err) => {
            this.loading = false;
            this.errorMessage = err;
          })
        }
      },
      show() {
        this.isOpened = true
        setTimeout(() => {
          this.$refs.pickerView.updateData({
            treeData: this._treeData,
            selected: this.selected,
            selectedIndex: this.selectedIndex
          })
        }, 200)
        this.$emit('popupopened')
      },
      hide() {
        this.isOpened = false
        this.$emit('popupclosed')
      },
      handleInput() {
        if (this.readonly) {
                    this.$emit('inputclick')
          return
        }
        this.show()
      },
      handleClose(e) {
        this.hide()
      },
      onnodeclick(e) {
        this.$emit('nodeclick', e)
      },
      ondatachange(e) {
        this._treeData = this.$refs.pickerView._treeData
      },
      onchange(e) {
        this.hide()
        this.$nextTick(() => {
          this.inputSelected = e;
        })
        this._dispatchEvent(e)
      },
      _processReadonly(dataList, value) {
        var isTree = dataList.findIndex((item) => {
          return item.children
        })
        if (isTree > -1) {
          let inputValue
          if (Array.isArray(value)) {
            inputValue = value[value.length - 1]
            if (typeof inputValue === 'object' && inputValue.value) {
              inputValue = inputValue.value
            }
          } else {
            inputValue = value
          }
          this.inputSelected = this._findNodePath(inputValue, this.localdata)
          return
        }
        if (!this.hasValue) {
          this.inputSelected = []
          return
        }
        let result = []
        for (let i = 0; i < value.length; i++) {
          var val = value[i]
          var item = dataList.find((v) => {
            return v.value == val
          })
          if (item) {
            result.push(item)
          }
        }
        if (result.length) {
          this.inputSelected = result
        }
      },
      _filterForArray(data, valueArray) {
        var result = []
        for (let i = 0; i < valueArray.length; i++) {
          var value = valueArray[i]
          var found = data.find((item) => {
            return item.value == value
          })
          if (found) {
            result.push(found)
          }
        }
        return result
      },
      _dispatchEvent(selected) {
        let item = {}
        if (selected.length) {
          var value = new Array(selected.length)
          for (var i = 0; i < selected.length; i++) {
            value[i] = selected[i].value
          }
          item = selected[selected.length - 1]
        } else {
          item.value = ''
        }
        if (this.formItem) {
          this.formItem.setValue(item.value)
        }
        this.$emit('input', item.value)
        this.$emit('update:modelValue', item.value)
        this.$emit('change', {
          detail: {
            value: selected
          }
        })
      }
    }
  }
</script>
<style>
  .uni-data-tree {
    flex: 1;
    position: relative;
    font-size: 14px;
  }
  .error-text {
    color: #DD524D;
  }
  .input-value {
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex-direction: row;
    align-items: center;
    flex-wrap: nowrap;
    font-size: 14px;
    /* line-height: 35px; */
    padding: 0 10px;
    padding-right: 5px;
    overflow: hidden;
    height: 35px;
    /* #ifndef APP-NVUE */
    box-sizing: border-box;
    /* #endif */
  }
  .input-value-border {
    border: 1px solid #e5e5e5;
    border-radius: 5px;
  }
  .selected-area {
    flex: 1;
    overflow: hidden;
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex-direction: row;
  }
  .load-more {
    /* #ifndef APP-NVUE */
    margin-right: auto;
    /* #endif */
    /* #ifdef APP-NVUE */
    width: 40px;
    /* #endif */
  }
  .selected-list {
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex-direction: row;
    flex-wrap: nowrap;
    /* padding: 0 5px; */
  }
  .selected-item {
    flex-direction: row;
    /* padding: 0 1px; */
    /* #ifndef APP-NVUE */
    white-space: nowrap;
    /* #endif */
  }
  .text-color {
    color: #333;
  }
  .placeholder {
    color: grey;
    font-size: 12px;
  }
  .input-split-line {
    opacity: .5;
  }
  .arrow-area {
    position: relative;
    width: 20px;
    /* #ifndef APP-NVUE */
    margin-bottom: 5px;
    margin-left: auto;
    display: flex;
    /* #endif */
    justify-content: center;
    transform: rotate(-45deg);
    transform-origin: center;
  }
  .input-arrow {
    width: 7px;
    height: 7px;
    border-left: 1px solid #999;
    border-bottom: 1px solid #999;
  }
  .uni-data-tree-cover {
    position: fixed;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, .4);
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex-direction: column;
    z-index: 100;
  }
  .uni-data-tree-dialog {
    position: fixed;
    left: 0;
    /* #ifndef APP-NVUE */
    top: 20%;
    /* #endif */
    /* #ifdef APP-NVUE */
    top: 200px;
    /* #endif */
    right: 0;
    bottom: 0;
    background-color: #FFFFFF;
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex-direction: column;
    z-index: 102;
    overflow: hidden;
    /* #ifdef APP-NVUE */
    width: 750rpx;
    /* #endif */
  }
  .dialog-caption {
    position: relative;
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex-direction: row;
    /* border-bottom: 1px solid #f0f0f0; */
  }
  .title-area {
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    align-items: center;
    /* #ifndef APP-NVUE */
    margin: auto;
    /* #endif */
    padding: 0 10px;
  }
  .dialog-title {
    /* font-weight: bold; */
    line-height: 44px;
  }
  .dialog-close {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex-direction: row;
    align-items: center;
    padding: 0 15px;
  }
  .dialog-close-plus {
    width: 16px;
    height: 2px;
    background-color: #666;
    border-radius: 2px;
    transform: rotate(45deg);
  }
  .dialog-close-rotate {
    position: absolute;
    transform: rotate(-45deg);
  }
  .picker-view {
    flex: 1;
    overflow: hidden;
  }
  .icon-clear {
    display: flex;
    align-items: center;
  }
  /* #ifdef H5 */
  @media all and (min-width: 768px) {
    .uni-data-tree-cover {
      background-color: transparent;
    }
    .uni-data-tree-dialog {
      position: absolute;
      top: 55px;
      height: auto;
      min-height: 400px;
      max-height: 50vh;
      background-color: #fff;
      border: 1px solid #EBEEF5;
      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
      border-radius: 4px;
      overflow: unset;
    }
    .dialog-caption {
      display: none;
    }
    .icon-clear {
      /* margin-right: 5px; */
    }
  }
  /* #endif */
  /* picker 弹出层通用的指示小三角, todo:扩展至上下左右方向定位 */
  /* #ifndef APP-NVUE */
  .uni-popper__arrow,
  .uni-popper__arrow::after {
    position: absolute;
    display: block;
    width: 0;
    height: 0;
    border-color: transparent;
    border-style: solid;
    border-width: 6px;
  }
  .uni-popper__arrow {
    filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
    top: -6px;
    left: 10%;
    margin-right: 3px;
    border-top-width: 0;
    border-bottom-color: #EBEEF5;
  }
  .uni-popper__arrow::after {
    content: " ";
    top: 1px;
    margin-left: -6px;
    border-top-width: 0;
    border-bottom-color: #fff;
  }
  /* #endif */
</style>
uni_modules/uni-data-picker/components/uni-data-pickerview/loading.uts
New file
@@ -0,0 +1 @@
export const imgbase : string = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QzlBMzU3OTlEOUM0MTFFOUI0NTZDNERBQURBQzI4RkUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QzlBMzU3OUFEOUM0MTFFOUI0NTZDNERBQURBQzI4RkUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDOUEzNTc5N0Q5QzQxMUU5QjQ1NkM0REFBREFDMjhGRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpDOUEzNTc5OEQ5QzQxMUU5QjQ1NkM0REFBREFDMjhGRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pt+ALSwAAA6CSURBVHja1FsLkFZV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'
uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js
New file
@@ -0,0 +1,622 @@
export default {
  props: {
    localdata: {
      type: [Array, Object],
      default () {
        return []
      }
    },
    spaceInfo: {
      type: Object,
      default () {
        return {}
      }
    },
    collection: {
      type: String,
      default: ''
    },
    action: {
      type: String,
      default: ''
    },
    field: {
      type: String,
      default: ''
    },
    orderby: {
      type: String,
      default: ''
    },
    where: {
      type: [String, Object],
      default: ''
    },
    pageData: {
      type: String,
      default: 'add'
    },
    pageCurrent: {
      type: Number,
      default: 1
    },
    pageSize: {
      type: Number,
      default: 500
    },
    getcount: {
      type: [Boolean, String],
      default: false
    },
    getone: {
      type: [Boolean, String],
      default: false
    },
    gettree: {
      type: [Boolean, String],
      default: false
    },
    manual: {
      type: Boolean,
      default: false
    },
    value: {
      type: [Array, String, Number],
      default () {
        return []
      }
    },
    modelValue: {
      type: [Array, String, Number],
      default () {
        return []
      }
    },
    preload: {
      type: Boolean,
      default: false
    },
    stepSearh: {
      type: Boolean,
      default: true
    },
    selfField: {
      type: String,
      default: ''
    },
    parentField: {
      type: String,
      default: ''
    },
    multiple: {
      type: Boolean,
      default: false
    },
    map: {
      type: Object,
      default () {
        return {
          text: "text",
          value: "value"
        }
      }
    }
  },
  data() {
    return {
      loading: false,
      errorMessage: '',
      loadMore: {
        contentdown: '',
        contentrefresh: '',
        contentnomore: ''
      },
      dataList: [],
      selected: [],
      selectedIndex: 0,
      page: {
        current: this.pageCurrent,
        size: this.pageSize,
        count: 0
      }
    }
  },
  computed: {
    isLocalData() {
      return !this.collection.length;
    },
    isCloudData() {
      return this.collection.length > 0;
    },
    isCloudDataList() {
      return (this.isCloudData && (!this.parentField && !this.selfField));
    },
    isCloudDataTree() {
      return (this.isCloudData && this.parentField && this.selfField);
    },
    dataValue() {
      let isModelValue = Array.isArray(this.modelValue) ? (this.modelValue.length > 0) : (this.modelValue !== null ||
        this.modelValue !== undefined);
      return isModelValue ? this.modelValue : this.value;
    },
    hasValue() {
      if (typeof this.dataValue === 'number') {
        return true
      }
      return (this.dataValue != null) && (this.dataValue.length > 0)
    }
  },
  created() {
    this.$watch(() => {
      var al = [];
      ['pageCurrent',
        'pageSize',
        'spaceInfo',
        'value',
        'modelValue',
        'localdata',
        'collection',
        'action',
        'field',
        'orderby',
        'where',
        'getont',
        'getcount',
        'gettree'
      ].forEach(key => {
        al.push(this[key])
      });
      return al
    }, (newValue, oldValue) => {
      let needReset = false
      for (let i = 2; i < newValue.length; i++) {
        if (newValue[i] != oldValue[i]) {
          needReset = true
          break
        }
      }
      if (newValue[0] != oldValue[0]) {
        this.page.current = this.pageCurrent
      }
      this.page.size = this.pageSize
      this.onPropsChange()
    })
    this._treeData = []
  },
  methods: {
    onPropsChange() {
      this._treeData = [];
    },
    // 填充 pickview 数据
    async loadData() {
      if (this.isLocalData) {
        this.loadLocalData();
      } else if (this.isCloudDataList) {
        this.loadCloudDataList();
      } else if (this.isCloudDataTree) {
        this.loadCloudDataTree();
      }
    },
    // 加载本地数据
    async loadLocalData() {
      this._treeData = [];
      this._extractTree(this.localdata, this._treeData);
      let inputValue = this.dataValue;
      if (inputValue === undefined) {
        return;
      }
      if (Array.isArray(inputValue)) {
        inputValue = inputValue[inputValue.length - 1];
        if (typeof inputValue === 'object' && inputValue[this.map.value]) {
          inputValue = inputValue[this.map.value];
        }
      }
      this.selected = this._findNodePath(inputValue, this.localdata);
    },
    // 加载 Cloud 数据 (单列)
    async loadCloudDataList() {
      if (this.loading) {
        return;
      }
      this.loading = true;
      try {
        let response = await this.getCommand();
        let responseData = response.result.data;
        this._treeData = responseData;
        this._updateBindData();
        this._updateSelected();
        this.onDataChange();
      } catch (e) {
        this.errorMessage = e;
      } finally {
        this.loading = false;
      }
    },
    // 加载 Cloud 数据 (树形)
    async loadCloudDataTree() {
      if (this.loading) {
        return;
      }
      this.loading = true;
      try {
        let commandOptions = {
          field: this._cloudDataPostField(),
          where: this._cloudDataTreeWhere()
        };
        if (this.gettree) {
          commandOptions.startwith = `${this.selfField}=='${this.dataValue}'`;
        }
        let response = await this.getCommand(commandOptions);
        let responseData = response.result.data;
        this._treeData = responseData;
        this._updateBindData();
        this._updateSelected();
        this.onDataChange();
      } catch (e) {
        this.errorMessage = e;
      } finally {
        this.loading = false;
      }
    },
    // 加载 Cloud 数据 (节点)
    async loadCloudDataNode(callback) {
      if (this.loading) {
        return;
      }
      this.loading = true;
      try {
        let commandOptions = {
          field: this._cloudDataPostField(),
          where: this._cloudDataNodeWhere()
        };
        let response = await this.getCommand(commandOptions);
        let responseData = response.result.data;
        callback(responseData);
      } catch (e) {
        this.errorMessage = e;
      } finally {
        this.loading = false;
      }
    },
    // 回显 Cloud 数据
    getCloudDataValue() {
      if (this.isCloudDataList) {
        return this.getCloudDataListValue();
      }
      if (this.isCloudDataTree) {
        return this.getCloudDataTreeValue();
      }
    },
    // 回显 Cloud 数据 (单列)
    getCloudDataListValue() {
      // 根据 field's as value标识匹配 where 条件
      let where = [];
      let whereField = this._getForeignKeyByField();
      if (whereField) {
        where.push(`${whereField} == '${this.dataValue}'`)
      }
      where = where.join(' || ');
      if (this.where) {
        where = `(${this.where}) && (${where})`
      }
      return this.getCommand({
        field: this._cloudDataPostField(),
        where
      }).then((res) => {
        this.selected = res.result.data;
        return res.result.data;
      });
    },
    // 回显 Cloud 数据 (树形)
    getCloudDataTreeValue() {
      return this.getCommand({
        field: this._cloudDataPostField(),
        getTreePath: {
          startWith: `${this.selfField}=='${this.dataValue}'`
        }
      }).then((res) => {
        let treePath = [];
        this._extractTreePath(res.result.data, treePath);
        this.selected = treePath;
        return treePath;
      });
    },
    getCommand(options = {}) {
      /* eslint-disable no-undef */
      let db = uniCloud.database(this.spaceInfo)
      const action = options.action || this.action
      if (action) {
        db = db.action(action)
      }
      const collection = options.collection || this.collection
      db = db.collection(collection)
      const where = options.where || this.where
      if (!(!where || !Object.keys(where).length)) {
        db = db.where(where)
      }
      const field = options.field || this.field
      if (field) {
        db = db.field(field)
      }
      const orderby = options.orderby || this.orderby
      if (orderby) {
        db = db.orderBy(orderby)
      }
      const current = options.pageCurrent !== undefined ? options.pageCurrent : this.page.current
      const size = options.pageSize !== undefined ? options.pageSize : this.page.size
      const getCount = options.getcount !== undefined ? options.getcount : this.getcount
      const getTree = options.gettree !== undefined ? options.gettree : this.gettree
      const getOptions = {
        getCount,
        getTree
      }
      if (options.getTreePath) {
        getOptions.getTreePath = options.getTreePath
      }
      db = db.skip(size * (current - 1)).limit(size).get(getOptions)
      return db
    },
    _cloudDataPostField() {
      let fields = [this.field];
      if (this.parentField) {
        fields.push(`${this.parentField} as parent_value`);
      }
      return fields.join(',');
    },
    _cloudDataTreeWhere() {
      let result = []
      let selected = this.selected
      let parentField = this.parentField
      if (parentField) {
        result.push(`${parentField} == null || ${parentField} == ""`)
      }
      if (selected.length) {
        for (var i = 0; i < selected.length - 1; i++) {
          result.push(`${parentField} == '${selected[i].value}'`)
        }
      }
      let where = []
      if (this.where) {
        where.push(`(${this.where})`)
      }
      if (result.length) {
        where.push(`(${result.join(' || ')})`)
      }
      return where.join(' && ')
    },
    _cloudDataNodeWhere() {
      let where = []
      let selected = this.selected;
      if (selected.length) {
        where.push(`${this.parentField} == '${selected[selected.length - 1].value}'`);
      }
      where = where.join(' || ');
      if (this.where) {
        return `(${this.where}) && (${where})`
      }
      return where
    },
    _getWhereByForeignKey() {
      let result = []
      let whereField = this._getForeignKeyByField();
      if (whereField) {
        result.push(`${whereField} == '${this.dataValue}'`)
      }
      if (this.where) {
        return `(${this.where}) && (${result.join(' || ')})`
      }
      return result.join(' || ')
    },
    _getForeignKeyByField() {
      let fields = this.field.split(',');
      let whereField = null;
      for (let i = 0; i < fields.length; i++) {
        const items = fields[i].split('as');
        if (items.length < 2) {
          continue;
        }
        if (items[1].trim() === 'value') {
          whereField = items[0].trim();
          break;
        }
      }
      return whereField;
    },
    _updateBindData(node) {
      const {
        dataList,
        hasNodes
      } = this._filterData(this._treeData, this.selected)
      let isleaf = this._stepSearh === false && !hasNodes
      if (node) {
        node.isleaf = isleaf
      }
      this.dataList = dataList
      this.selectedIndex = dataList.length - 1
      if (!isleaf && this.selected.length < dataList.length) {
        this.selected.push({
          value: null,
          text: "请选择"
        })
      }
      return {
        isleaf,
        hasNodes
      }
    },
    _updateSelected() {
      let dl = this.dataList
      let sl = this.selected
      let textField = this.map.text
      let valueField = this.map.value
      for (let i = 0; i < sl.length; i++) {
        let value = sl[i].value
        let dl2 = dl[i]
        for (let j = 0; j < dl2.length; j++) {
          let item2 = dl2[j]
          if (item2[valueField] === value) {
            sl[i].text = item2[textField]
            break
          }
        }
      }
    },
    _filterData(data, paths) {
      let dataList = []
      let hasNodes = true
      dataList.push(data.filter((item) => {
        return (item.parent_value === null || item.parent_value === undefined || item.parent_value === '')
      }))
      for (let i = 0; i < paths.length; i++) {
        let value = paths[i].value
        let nodes = data.filter((item) => {
          return item.parent_value === value
        })
        if (nodes.length) {
          dataList.push(nodes)
        } else {
          hasNodes = false
        }
      }
      return {
        dataList,
        hasNodes
      }
    },
    _extractTree(nodes, result, parent_value) {
      let list = result || []
      let valueField = this.map.value
      for (let i = 0; i < nodes.length; i++) {
        let node = nodes[i]
        let child = {}
        for (let key in node) {
          if (key !== 'children') {
            child[key] = node[key]
          }
        }
        if (parent_value !== null && parent_value !== undefined && parent_value !== '') {
          child.parent_value = parent_value
        }
        result.push(child)
        let children = node.children
        if (children) {
          this._extractTree(children, result, node[valueField])
        }
      }
    },
    _extractTreePath(nodes, result) {
      let list = result || []
      for (let i = 0; i < nodes.length; i++) {
        let node = nodes[i]
        let child = {}
        for (let key in node) {
          if (key !== 'children') {
            child[key] = node[key]
          }
        }
        result.push(child)
        let children = node.children
        if (children) {
          this._extractTreePath(children, result)
        }
      }
    },
    _findNodePath(key, nodes, path = []) {
      let textField = this.map.text
      let valueField = this.map.value
      for (let i = 0; i < nodes.length; i++) {
        let node = nodes[i]
        let children = node.children
        let text = node[textField]
        let value = node[valueField]
        path.push({
          value,
          text
        })
        if (value === key) {
          return path
        }
        if (children) {
          const p = this._findNodePath(key, children, path)
          if (p.length) {
            return p
          }
        }
        path.pop()
      }
      return []
    }
  }
}
uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.uts
New file
@@ -0,0 +1,693 @@
export type PaginationType = {
  current : number,
  size : number,
  count : number
}
export type LoadMoreType = {
  contentdown : string,
  contentrefresh : string,
  contentnomore : string
}
export type SelectedItemType = {
  name : string,
  value : string,
}
export type GetCommandOptions = {
  collection ?: UTSJSONObject,
  field ?: string,
  orderby ?: string,
  where ?: any,
  pageData ?: string,
  pageCurrent ?: number,
  pageSize ?: number,
  getCount ?: boolean,
  getTree ?: any,
  getTreePath ?: UTSJSONObject,
  startwith ?: string,
  limitlevel ?: number,
  groupby ?: string,
  groupField ?: string,
  distinct ?: boolean,
  pageIndistinct ?: boolean,
  foreignKey ?: string,
  loadtime ?: string,
  manual ?: boolean
}
const DefaultSelectedNode = {
  text: '请选择',
  value: ''
}
export const dataPicker = defineMixin({
  props: {
    localdata: {
      type: Array as PropType<Array<UTSJSONObject>>,
      default: [] as Array<UTSJSONObject>
    },
    collection: {
      type: Object,
      default: ''
    },
    field: {
      type: String,
      default: ''
    },
    orderby: {
      type: String,
      default: ''
    },
    where: {
      type: Object,
      default: ''
    },
    pageData: {
      type: String,
      default: 'add'
    },
    pageCurrent: {
      type: Number,
      default: 1
    },
    pageSize: {
      type: Number,
      default: 20
    },
    getcount: {
      type: Boolean,
      default: false
    },
    gettree: {
      type: Object,
      default: ''
    },
    gettreepath: {
      type: Object,
      default: ''
    },
    startwith: {
      type: String,
      default: ''
    },
    limitlevel: {
      type: Number,
      default: 10
    },
    groupby: {
      type: String,
      default: ''
    },
    groupField: {
      type: String,
      default: ''
    },
    distinct: {
      type: Boolean,
      default: false
    },
    pageIndistinct: {
      type: Boolean,
      default: false
    },
    foreignKey: {
      type: String,
      default: ''
    },
    loadtime: {
      type: String,
      default: 'auto'
    },
    manual: {
      type: Boolean,
      default: false
    },
    preload: {
      type: Boolean,
      default: false
    },
    stepSearh: {
      type: Boolean,
      default: true
    },
    selfField: {
      type: String,
      default: ''
    },
    parentField: {
      type: String,
      default: ''
    },
    multiple: {
      type: Boolean,
      default: false
    },
    value: {
      type: Object,
      default: ''
    },
    modelValue: {
      type: Object,
      default: ''
    },
    defaultProps: {
      type: Object as PropType<UTSJSONObject>,
    }
  },
  data() {
    return {
      loading: false,
      error: null as UniCloudError | null,
      treeData: [] as Array<UTSJSONObject>,
      selectedIndex: 0,
      selectedNodes: [] as Array<UTSJSONObject>,
      selectedPages: [] as Array<UTSJSONObject>[],
      selectedValue: '',
      selectedPaths: [] as Array<UTSJSONObject>,
      pagination: {
        current: 1,
        size: 20,
        count: 0
      } as PaginationType
    }
  },
  computed: {
    mappingTextName() : string {
      // TODO
      return (this.defaultProps != null) ? this.defaultProps!.getString('text', 'text') : 'text'
    },
    mappingValueName() : string {
      // TODO
      return (this.defaultProps != null) ? this.defaultProps!.getString('value', 'value') : 'value'
    },
    currentDataList() : Array<UTSJSONObject> {
      if (this.selectedIndex > this.selectedPages.length - 1) {
        return [] as Array<UTSJSONObject>
      }
      return this.selectedPages[this.selectedIndex]
    },
    isLocalData() : boolean {
      return this.localdata.length > 0
    },
    isCloudData() : boolean {
      return this._checkIsNotNull(this.collection)
    },
    isCloudDataList() : boolean {
      return (this.isCloudData && (this.parentField.length == 0 && this.selfField.length == 0))
    },
    isCloudDataTree() : boolean {
      return (this.isCloudData && this.parentField.length > 0 && this.selfField.length > 0)
    },
    dataValue() : any {
      return this.hasModelValue ? this.modelValue : this.value
    },
    hasCloudTreeData() : boolean {
      return this.treeData.length > 0
    },
    hasModelValue() : boolean {
      if (typeof this.modelValue == 'string') {
        const valueString = this.modelValue as string
        return (valueString.length > 0)
      } else if (Array.isArray(this.modelValue)) {
        const valueArray = this.modelValue as Array<string>
        return (valueArray.length > 0)
      }
      return false
    },
    hasCloudDataValue() : boolean {
      if (typeof this.dataValue == 'string') {
        const valueString = this.dataValue as string
        return (valueString.length > 0)
      }
      return false
    }
  },
  created() {
    this.pagination.current = this.pageCurrent
    this.pagination.size = this.pageSize
    this.$watch(
      () : any => [
        this.pageCurrent,
        this.pageSize,
        this.localdata,
        this.value,
        this.collection,
        this.field,
        this.getcount,
        this.orderby,
        this.where,
        this.groupby,
        this.groupField,
        this.distinct
      ],
      (newValue : Array<any>, oldValue : Array<any>) => {
        this.pagination.size = this.pageSize
        if (newValue[0] !== oldValue[0]) {
          this.pagination.current = this.pageCurrent
        }
        this.onPropsChange()
      }
    )
  },
  methods: {
    onPropsChange() {
      this.selectedIndex = 0
      this.treeData.length = 0
      this.selectedNodes.length = 0
      this.selectedPages.length = 0
      this.selectedPaths.length = 0
      // 加载数据
      this.$nextTick(() => {
        this.loadData()
      })
    },
    onTabSelect(index : number) {
      this.selectedIndex = index
    },
    onNodeClick(nodeData : UTSJSONObject) {
      if (nodeData.getBoolean('disable', false)) {
        return
      }
      const isLeaf = this._checkIsLeafNode(nodeData)
      this._trimSelectedNodes(nodeData)
      this.$emit('nodeclick', nodeData)
      if (this.isLocalData) {
        if (isLeaf || !this._checkHasChildren(nodeData)) {
          this.onFinish()
        }
      } else if (this.isCloudDataList) {
        this.onFinish()
      } else if (this.isCloudDataTree) {
        if (isLeaf) {
          this.onFinish()
        } else if (!this._checkHasChildren(nodeData)) {
          // 尝试请求一次,如果没有返回数据标记为叶子节点
          this.loadCloudDataNode(nodeData)
        }
      }
    },
    getChangeNodes(): Array<UTSJSONObject> {
      const nodes: Array<UTSJSONObject> = []
      this.selectedNodes.forEach((node : UTSJSONObject) => {
        const newNode: UTSJSONObject = {}
        newNode[this.mappingTextName] = node.getString(this.mappingTextName)
        newNode[this.mappingValueName] = node.getString(this.mappingValueName)
        nodes.push(newNode)
      })
      return nodes
    },
    onFinish() { },
    // 加载数据(自动判定环境)
    loadData() {
      if (this.isLocalData) {
        this.loadLocalData()
      } else if (this.isCloudDataList) {
        this.loadCloudDataList()
      } else if (this.isCloudDataTree) {
        this.loadCloudDataTree()
      }
    },
    // 加载本地数据
    loadLocalData() {
      this.treeData = this.localdata
      if (Array.isArray(this.dataValue)) {
        const value = this.dataValue as Array<UTSJSONObject>
        this.selectedPaths = value.slice(0)
        this._pushSelectedTreeNodes(value, this.localdata)
      } else {
        this._pushSelectedNodes(this.localdata)
      }
    },
    // 加载 Cloud 数据 (单列)
    loadCloudDataList() {
      this._loadCloudData(null, (data : Array<UTSJSONObject>) => {
        this.treeData = data
        this._pushSelectedNodes(data)
      })
    },
    // 加载 Cloud 数据 (树形)
    loadCloudDataTree() {
      let commandOptions = {
        field: this._cloudDataPostField(),
        where: this._cloudDataTreeWhere(),
        getTree: true
      } as GetCommandOptions
      if (this._checkIsNotNull(this.gettree)) {
        commandOptions.startwith = `${this.selfField}=='${this.dataValue as string}'`
      }
      this._loadCloudData(commandOptions, (data : Array<UTSJSONObject>) => {
        this.treeData = data
        if (this.selectedPaths.length > 0) {
          this._pushSelectedTreeNodes(this.selectedPaths, data)
        } else {
          this._pushSelectedNodes(data)
        }
      })
    },
    // 加载 Cloud 数据 (节点)
    loadCloudDataNode(nodeData : UTSJSONObject) {
      const commandOptions = {
        field: this._cloudDataPostField(),
        where: this._cloudDataNodeWhere()
      } as GetCommandOptions
      this._loadCloudData(commandOptions, (data : Array<UTSJSONObject>) => {
        nodeData['children'] = data
        if (data.length == 0) {
          nodeData['isleaf'] = true
          this.onFinish()
        } else {
          this._pushSelectedNodes(data)
        }
      })
    },
    // 回显 Cloud Tree Path
    loadCloudDataPath() {
      if (!this.hasCloudDataValue) {
        return
      }
      const command : GetCommandOptions = {}
      // 单列
      if (this.isCloudDataList) {
        // 根据 field's as value标识匹配 where 条件
        let where : Array<string> = [];
        let whereField = this._getForeignKeyByField();
        if (whereField.length > 0) {
          where.push(`${whereField} == '${this.dataValue as string}'`)
        }
        let whereString = where.join(' || ')
        if (this._checkIsNotNull(this.where)) {
          whereString = `(${this.where}) && (${whereString})`
        }
        command.field = this._cloudDataPostField()
        command.where = whereString
      }
      // 树形
      if (this.isCloudDataTree) {
        command.field = this._cloudDataPostField()
        command.getTreePath = {
          startWith: `${this.selfField}=='${this.dataValue as string}'`
        }
      }
      this._loadCloudData(command, (data : Array<UTSJSONObject>) => {
        this._extractTreePath(data, this.selectedPaths)
      })
    },
    _loadCloudData(options ?: GetCommandOptions, callback ?: ((data : Array<UTSJSONObject>) => void)) {
      if (this.loading) {
        return
      }
      this.loading = true
      this.error = null
      this._getCommand(options).then((response : UniCloudDBGetResult) => {
        callback?.(response.data)
      }).catch((err : any | null) => {
        this.error = err as UniCloudError
      }).finally(() => {
        this.loading = false
      })
    },
    _cloudDataPostField() : string {
      let fields = [this.field];
      if (this.parentField.length > 0) {
        fields.push(`${this.parentField} as parent_value`)
      }
      return fields.join(',')
    },
    _cloudDataTreeWhere() : string {
      let result : Array<string> = []
      let selectedNodes = this.selectedNodes.length > 0 ? this.selectedNodes : this.selectedPaths
      let parentField = this.parentField
      if (parentField.length > 0) {
        result.push(`${parentField} == null || ${parentField} == ""`)
      }
      if (selectedNodes.length > 0) {
        for (var i = 0; i < selectedNodes.length - 1; i++) {
          const parentFieldValue = selectedNodes[i].getString('value', '')
          result.push(`${parentField} == '${parentFieldValue}'`)
        }
      }
      let where : Array<string> = []
      if (this._checkIsNotNull(this.where)) {
        where.push(`(${this.where as string})`)
      }
      if (result.length > 0) {
        where.push(`(${result.join(' || ')})`)
      }
      return where.join(' && ')
    },
    _cloudDataNodeWhere() : string {
      const where : Array<string> = []
      if (this.selectedNodes.length > 0) {
        const value = this.selectedNodes[this.selectedNodes.length - 1].getString('value', '')
        where.push(`${this.parentField} == '${value}'`)
      }
      let whereString = where.join(' || ')
      if (this._checkIsNotNull(this.where)) {
        return `(${this.where as string}) && (${whereString})`
      }
      return whereString
    },
    _getWhereByForeignKey() : string {
      let result : Array<string> = []
      let whereField = this._getForeignKeyByField();
      if (whereField.length > 0) {
        result.push(`${whereField} == '${this.dataValue as string}'`)
      }
      if (this._checkIsNotNull(this.where)) {
        return `(${this.where}) && (${result.join(' || ')})`
      }
      return result.join(' || ')
    },
    _getForeignKeyByField() : string {
      const fields = this.field.split(',')
      let whereField = ''
      for (let i = 0; i < fields.length; i++) {
        const items = fields[i].split('as')
        if (items.length < 2) {
          continue
        }
        if (items[1].trim() === 'value') {
          whereField = items[0].trim()
          break
        }
      }
      return whereField
    },
    _getCommand(options ?: GetCommandOptions) : Promise<UniCloudDBGetResult> {
      let db = uniCloud.databaseForJQL()
      let collection = Array.isArray(this.collection) ? db.collection(...(this.collection as Array<any>)) : db.collection(this.collection)
      let filter : UniCloudDBFilter | null = null
      if (this.foreignKey.length > 0) {
        filter = collection.foreignKey(this.foreignKey)
      }
      const where : any = options?.where ?? this.where
      if (typeof where == 'string') {
        const whereString = where as string
        if (whereString.length > 0) {
          filter = (filter != null) ? filter.where(where) : collection.where(where)
        }
      } else {
        filter = (filter != null) ? filter.where(where) : collection.where(where)
      }
      let query : UniCloudDBQuery | null = null
      if (this.field.length > 0) {
        query = (filter != null) ? filter.field(this.field) : collection.field(this.field)
      }
      if (this.groupby.length > 0) {
        if (query != null) {
          query = query.groupBy(this.groupby)
        } else if (filter != null) {
          query = filter.groupBy(this.groupby)
        }
      }
      if (this.groupField.length > 0) {
        if (query != null) {
          query = query.groupField(this.groupField)
        } else if (filter != null) {
          query = filter.groupField(this.groupField)
        }
      }
      if (this.distinct == true) {
        if (query != null) {
          query = query.distinct(this.field)
        } else if (filter != null) {
          query = filter.distinct(this.field)
        }
      }
      if (this.orderby.length > 0) {
        if (query != null) {
          query = query.orderBy(this.orderby)
        } else if (filter != null) {
          query = filter.orderBy(this.orderby)
        }
      }
      const size = this.pagination.size
      const current = this.pagination.current
      if (query != null) {
        query = query.skip(size * (current - 1)).limit(size)
      } else if (filter != null) {
        query = filter.skip(size * (current - 1)).limit(size)
      } else {
        query = collection.skip(size * (current - 1)).limit(size)
      }
      const getOptions = {}
      const treeOptions = {
        limitLevel: this.limitlevel,
        startWith: this.startwith
      }
      if (this.getcount == true) {
        getOptions['getCount'] = this.getcount
      }
      const getTree : any = options?.getTree ?? this.gettree
      if (typeof getTree == 'string') {
        const getTreeString = getTree as string
        if (getTreeString.length > 0) {
          getOptions['getTree'] = treeOptions
        }
      } else if (typeof getTree == 'object') {
        getOptions['getTree'] = treeOptions
      } else {
        getOptions['getTree'] = getTree
      }
      const getTreePath = options?.getTreePath ?? this.gettreepath
      if (typeof getTreePath == 'string') {
        const getTreePathString = getTreePath as string
        if (getTreePathString.length > 0) {
          getOptions['getTreePath'] = getTreePath
        }
      } else {
        getOptions['getTreePath'] = getTreePath
      }
      return query.get(getOptions)
    },
    _checkIsNotNull(value : any) : boolean {
      if (typeof value == 'string') {
        const valueString = value as string
        return (valueString.length > 0)
      } else if (value instanceof UTSJSONObject) {
        return true
      }
      return false
    },
    _checkIsLeafNode(nodeData : UTSJSONObject) : boolean {
      if (this.selectedIndex >= this.limitlevel) {
        return true
      }
      if (nodeData.getBoolean('isleaf', false)) {
        return true
      }
      return false
    },
    _checkHasChildren(nodeData : UTSJSONObject) : boolean {
      const children = nodeData.getArray('children') ?? ([] as Array<any>)
      return children.length > 0
    },
    _pushSelectedNodes(nodes : Array<UTSJSONObject>) {
      this.selectedNodes.push(DefaultSelectedNode)
      this.selectedPages.push(nodes)
      this.selectedIndex = this.selectedPages.length - 1
    },
    _trimSelectedNodes(nodeData : UTSJSONObject) {
      this.selectedNodes.splice(this.selectedIndex)
      this.selectedNodes.push(nodeData)
      if (this.selectedPages.length > 0) {
        this.selectedPages.splice(this.selectedIndex + 1)
      }
      const children = nodeData.getArray<UTSJSONObject>('children') ?? ([] as Array<UTSJSONObject>)
      if (children.length > 0) {
        this.selectedNodes.push(DefaultSelectedNode)
        this.selectedPages.push(children)
      }
      this.selectedIndex = this.selectedPages.length - 1
    },
    _pushSelectedTreeNodes(paths : Array<UTSJSONObject>, nodes : Array<UTSJSONObject>) {
      let children : Array<UTSJSONObject> = nodes
      paths.forEach((node : UTSJSONObject) => {
        const findNode = children.find((item : UTSJSONObject) : boolean => {
          return (item.getString(this.mappingValueName) == node.getString(this.mappingValueName))
        })
        if (findNode != null) {
          this.selectedPages.push(children)
          this.selectedNodes.push(node)
          children = findNode.getArray<UTSJSONObject>('children') ?? ([] as Array<UTSJSONObject>)
        }
      })
      this.selectedIndex = this.selectedPages.length - 1
    },
    _extractTreePath(nodes : Array<UTSJSONObject>, result : Array<UTSJSONObject>) {
      if (nodes.length == 0) {
        return
      }
      const node = nodes[0]
      result.push(node)
      const children = node.getArray<UTSJSONObject>('children')
      if (Array.isArray(children) && children!.length > 0) {
        this._extractTreePath(children, result)
      }
    }
  }
})
uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.css
New file
@@ -0,0 +1,76 @@
.uni-data-pickerview {
  position: relative;
  flex-direction: column;
  overflow: hidden;
}
.loading-cover {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  align-items: center;
  justify-content: center;
  background-color: rgba(150, 150, 150, .1);
}
.error {
  background-color: #fff;
  padding: 15px;
}
.error-text {
  color: #DD524D;
}
.selected-node-list {
  flex-direction: row;
  flex-wrap: nowrap;
}
.selected-node-item {
  margin-left: 10px;
  margin-right: 10px;
  padding: 8px 10px 8px 10px;
  border-bottom: 2px solid transparent;
}
.selected-node-item-active {
  color: #007aff;
  border-bottom-color: #007aff;
}
.list-view {
  flex: 1;
}
.list-item {
  flex-direction: row;
  justify-content: space-between;
  padding: 12px 15px;
  border-bottom: 1px solid #f0f0f0;
}
.item-text {
  color: #333333;
}
.item-text-disabled {
  opacity: .5;
}
.item-text-overflow {
  overflow: hidden;
}
.check {
  margin-right: 5px;
  border: 2px solid #007aff;
  border-left: 0;
  border-top: 0;
  height: 12px;
  width: 6px;
  transform-origin: center;
  transform: rotate(45deg);
}
uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.uvue
New file
@@ -0,0 +1,69 @@
<template>
  <view class="uni-data-pickerview">
    <view v-if="error!=null" class="error">
      <text class="error-text">{{error!.errMsg}}</text>
    </view>
    <scroll-view v-if="!isCloudDataList" :scroll-x="true">
      <view class="selected-node-list">
        <template v-for="(item, index) in selectedNodes">
          <text class="selected-node-item" :class="{'selected-node-item-active':index==selectedIndex}"
            @click="onTabSelect(index)">
            {{item[mappingTextName]}}
          </text>
        </template>
      </view>
    </scroll-view>
    <list-view class="list-view" :scroll-y="true">
      <list-item class="list-item" v-for="(item, _) in currentDataList" @click="onNodeClick(item)">
        <text class="item-text" :class="{'item-text-disabled': item['disable']}">{{item[mappingTextName]}}</text>
        <text class="check" v-if="item[mappingValueName] == selectedNodes[selectedIndex][mappingValueName]"></text>
      </list-item>
    </list-view>
    <view class="loading-cover" v-if="loading">
      <slot name="pickerview-loading" :loading="loading"></slot>
    </view>
  </view>
</template>
<script>
  import { dataPicker } from "./uni-data-picker.uts"
  /**
   * DataPickerview
   * @description uni-data-pickerview
   * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
   * @property {Array} localdata 本地数据,参考
   * @property {Boolean} step-searh = [true|false] 是否分布查询
   * @value true 启用分布查询,仅查询当前选中节点
   * @value false 关闭分布查询,一次查询出所有数据
   * @property {String|DBFieldString} self-field 分布查询当前字段名称
   * @property {String|DBFieldString} parent-field 分布查询父字段名称
   * @property {String|DBCollectionString} collection 表名
   * @property {String|DBFieldString} field 查询字段,多个字段用 `,` 分割
   * @property {String} orderby 排序字段及正序倒叙设置
   * @property {String|JQLString} where 查询条件
   */
  export default {
    name: 'UniDataPickerView',
    emits: ['nodeclick', 'change', 'update:modelValue'],
    mixins: [dataPicker],
    props: {
      ellipsis: {
        type: Boolean,
        default: true
      }
    },
    created() {
      this.loadData()
    },
    methods: {
      onFinish() {
        this.$emit('change', this.getChangeNodes())
      }
    }
  }
</script>
<style>
  @import url("uni-data-pickerview.css");
</style>
uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue
New file
@@ -0,0 +1,323 @@
<template>
  <view class="uni-data-pickerview">
    <scroll-view v-if="!isCloudDataList" class="selected-area" scroll-x="true">
      <view class="selected-list">
          <view
            class="selected-item"
            v-for="(item,index) in selected"
            :key="index"
            :class="{
              'selected-item-active':index == selectedIndex
            }"
            @click="handleSelect(index)"
          >
            <text>{{item.text || ''}}</text>
          </view>
      </view>
    </scroll-view>
    <view class="tab-c">
      <scroll-view class="list" :scroll-y="true">
        <view class="item" :class="{'is-disabled': !!item.disable}" v-for="(item, j) in dataList[selectedIndex]" :key="j"
          @click="handleNodeClick(item, selectedIndex, j)">
          <text class="item-text">{{item[map.text]}}</text>
          <view class="check" v-if="selected.length > selectedIndex && item[map.value] == selected[selectedIndex].value"></view>
        </view>
      </scroll-view>
      <view class="loading-cover" v-if="loading">
        <uni-load-more class="load-more" :contentText="loadMore" status="loading"></uni-load-more>
      </view>
      <view class="error-message" v-if="errorMessage">
        <text class="error-text">{{errorMessage}}</text>
      </view>
    </view>
  </view>
</template>
<script>
  import dataPicker from "./uni-data-picker.js"
  /**
   * DataPickerview
   * @description uni-data-pickerview
   * @tutorial https://ext.dcloud.net.cn/plugin?id=3796
   * @property {Array} localdata 本地数据,参考
   * @property {Boolean} step-searh = [true|false] 是否分布查询
   * @value true 启用分布查询,仅查询当前选中节点
   * @value false 关闭分布查询,一次查询出所有数据
   * @property {String|DBFieldString} self-field 分布查询当前字段名称
   * @property {String|DBFieldString} parent-field 分布查询父字段名称
   * @property {String|DBCollectionString} collection 表名
   * @property {String|DBFieldString} field 查询字段,多个字段用 `,` 分割
   * @property {String} orderby 排序字段及正序倒叙设置
   * @property {String|JQLString} where 查询条件
   */
  export default {
    name: 'UniDataPickerView',
    emits: ['nodeclick', 'change', 'datachange', 'update:modelValue'],
    mixins: [dataPicker],
    props: {
      managedMode: {
        type: Boolean,
        default: false
      },
      ellipsis: {
        type: Boolean,
        default: true
      }
    },
    created() {
      if (!this.managedMode) {
        this.$nextTick(() => {
          this.loadData();
        })
      }
    },
    methods: {
      onPropsChange() {
        this._treeData = [];
        this.selectedIndex = 0;
        this.$nextTick(() => {
          this.loadData();
        })
      },
      handleSelect(index) {
        this.selectedIndex = index;
      },
      handleNodeClick(item, i, j) {
        if (item.disable) {
          return;
        }
        const node = this.dataList[i][j];
        const text = node[this.map.text];
        const value = node[this.map.value];
        if (i < this.selected.length - 1) {
          this.selected.splice(i, this.selected.length - i)
          this.selected.push({
            text,
            value
          })
        } else if (i === this.selected.length - 1) {
          this.selected.splice(i, 1, {
            text,
            value
          })
        }
        if (node.isleaf) {
          this.onSelectedChange(node, node.isleaf)
          return
        }
        const {
          isleaf,
          hasNodes
        } = this._updateBindData()
        // 本地数据
        if (this.isLocalData) {
          this.onSelectedChange(node, (!hasNodes || isleaf))
        } else if (this.isCloudDataList) { // Cloud 数据 (单列)
          this.onSelectedChange(node, true)
        } else if (this.isCloudDataTree) { // Cloud 数据 (树形)
          if (isleaf) {
            this.onSelectedChange(node, node.isleaf)
          } else if (!hasNodes) { // 请求一次服务器以确定是否为叶子节点
            this.loadCloudDataNode((data) => {
              if (!data.length) {
                node.isleaf = true
              } else {
                this._treeData.push(...data)
                this._updateBindData(node)
              }
              this.onSelectedChange(node, node.isleaf)
            })
          }
        }
      },
      updateData(data) {
        this._treeData = data.treeData
        this.selected = data.selected
        if (!this._treeData.length) {
          this.loadData()
        } else {
          //this.selected = data.selected
          this._updateBindData()
        }
      },
      onDataChange() {
        this.$emit('datachange');
      },
      onSelectedChange(node, isleaf) {
        if (isleaf) {
          this._dispatchEvent()
        }
        if (node) {
          this.$emit('nodeclick', node)
        }
      },
      _dispatchEvent() {
        this.$emit('change', this.selected.slice(0))
      }
    }
  }
</script>
<style lang="scss">
    $uni-primary: #007aff !default;
    .uni-data-pickerview {
        flex: 1;
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        flex-direction: column;
        overflow: hidden;
        height: 100%;
    }
  .error-text {
    color: #DD524D;
  }
  .loading-cover {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(255, 255, 255, .5);
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex-direction: column;
    align-items: center;
    z-index: 1001;
  }
  .load-more {
    /* #ifndef APP-NVUE */
    margin: auto;
    /* #endif */
  }
  .error-message {
    background-color: #fff;
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    padding: 15px;
    opacity: .9;
    z-index: 102;
  }
  /* #ifdef APP-NVUE */
  .selected-area {
    width: 750rpx;
  }
  /* #endif */
  .selected-list {
    /* #ifndef APP-NVUE */
    display: flex;
    flex-wrap: nowrap;
    /* #endif */
    flex-direction: row;
    padding: 0 5px;
    border-bottom: 1px solid #f8f8f8;
  }
  .selected-item {
    margin-left: 10px;
    margin-right: 10px;
    padding: 12px 0;
    text-align: center;
    /* #ifndef APP-NVUE */
    white-space: nowrap;
    /* #endif */
  }
  .selected-item-text-overflow {
    width: 168px;
    /* fix nvue */
    overflow: hidden;
    /* #ifndef APP-NVUE */
    width: 6em;
    white-space: nowrap;
    text-overflow: ellipsis;
    -o-text-overflow: ellipsis;
    /* #endif */
  }
    .selected-item-active {
        border-bottom: 2px solid $uni-primary;
    }
    .selected-item-text {
        color: $uni-primary;
    }
  .tab-c {
    position: relative;
    flex: 1;
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex-direction: row;
    overflow: hidden;
  }
  .list {
    flex: 1;
  }
  .item {
    padding: 12px 15px;
    /* border-bottom: 1px solid #f0f0f0; */
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex-direction: row;
    justify-content: space-between;
  }
  .is-disabled {
    opacity: .5;
  }
  .item-text {
    /* flex: 1; */
    color: #333333;
  }
  .item-text-overflow {
    width: 280px;
    /* fix nvue */
    overflow: hidden;
    /* #ifndef APP-NVUE */
    width: 20em;
    white-space: nowrap;
    text-overflow: ellipsis;
    -o-text-overflow: ellipsis;
    /* #endif */
  }
    .check {
        margin-right: 5px;
        border: 2px solid $uni-primary;
        border-left: 0;
        border-top: 0;
        height: 12px;
        width: 6px;
        transform-origin: center;
        /* #ifndef APP-NVUE */
        transition: all 0.3s;
        /* #endif */
        transform: rotate(45deg);
    }
</style>
uni_modules/uni-data-picker/package.json
New file
@@ -0,0 +1,91 @@
{
  "id": "uni-data-picker",
  "displayName": "uni-data-picker 数据驱动的picker选择器",
  "version": "2.0.0",
  "description": "单列、多列级联选择器,常用于省市区城市选择、公司部门选择、多级分类等场景",
  "keywords": [
    "uni-ui",
    "uniui",
    "picker",
    "级联",
    "省市区",
    ""
],
  "repository": "https://github.com/dcloudio/uni-ui",
  "engines": {
    "HBuilderX": ""
  },
  "directories": {
    "example": "../../temps/example_temps"
  },
"dcloudext": {
    "sale": {
      "regular": {
        "price": "0.00"
      },
      "sourcecode": {
        "price": "0.00"
      }
    },
    "contact": {
      "qq": ""
    },
    "declaration": {
      "ads": "无",
      "data": "无",
      "permissions": "无"
    },
    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
    "type": "component-vue"
  },
  "uni_modules": {
    "dependencies": [
      "uni-load-more",
            "uni-icons",
            "uni-scss"
    ],
    "encrypt": [],
    "platforms": {
      "cloud": {
        "tcb": "y",
        "aliyun": "y"
      },
      "client": {
        "App": {
          "app-vue": "y",
          "app-nvue": "y",
          "app-uvue": "y"
        },
        "H5-mobile": {
          "Safari": "y",
          "Android Browser": "y",
          "微信浏览器(Android)": "y",
          "QQ浏览器(Android)": "y"
        },
        "H5-pc": {
          "Chrome": "y",
          "IE": "y",
          "Edge": "y",
          "Firefox": "y",
          "Safari": "y"
        },
        "小程序": {
          "微信": "y",
          "阿里": "y",
          "百度": "y",
          "字节跳动": "y",
        "QQ": "y",
        "京东": "u"
        },
        "快应用": {
          "华为": "u",
          "联盟": "u"
        },
        "Vue": {
            "vue2": "y",
            "vue3": "y"
        }
      }
    }
  }
}
uni_modules/uni-data-picker/readme.md
New file
@@ -0,0 +1,22 @@
## DataPicker 级联选择
> **组件名:uni-data-picker**
> 代码块: `uDataPicker`
> 关联组件:`uni-data-pickerview`、`uni-load-more`。
`<uni-data-picker>` 是一个选择类[datacom组件](https://uniapp.dcloud.net.cn/component/datacom)。
支持单列、和多列级联选择。列数没有限制,如果屏幕显示不全,顶部tab区域会左右滚动。
候选数据支持一次性加载完毕,也支持懒加载,比如示例图中,选择了“北京”后,动态加载北京的区县数据。
`<uni-data-picker>` 组件尤其适用于地址选择、分类选择等选择类。
`<uni-data-picker>` 支持本地数据、云端静态数据(json),uniCloud云数据库数据。
`<uni-data-picker>` 可以通过JQL直连uniCloud云数据库,配套[DB Schema](https://uniapp.dcloud.net.cn/uniCloud/schema),可在schema2code中自动生成前端页面,还支持服务器端校验。
在uniCloud数据表中新建表“uni-id-address”和“opendb-city-china”,这2个表的schema自带foreignKey关联。在“uni-id-address”表的表结构页面使用schema2code生成前端页面,会自动生成地址管理的维护页面,自动从“opendb-city-china”表包含的中国所有省市区信息里选择地址。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-picker)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
uni_modules/uni-icons/components/uni-icons/uni-icons.uvue
New file
@@ -0,0 +1,91 @@
<template>
  <text class="uni-icons" :style="styleObj">
    <slot>{{unicode}}</slot>
  </text>
</template>
<script>
  import { fontData, IconsDataItem } from './uniicons_file'
  /**
   * Icons 图标
   * @description 用于展示 icon 图标
   * @tutorial https://ext.dcloud.net.cn/plugin?id=28
   * @property {Number,String} size 图标大小
   * @property {String} type 图标图案,参考示例
   * @property {String} color 图标颜色
   * @property {String} customPrefix 自定义图标
   * @event {Function} click 点击 Icon 触发事件
   */
  export default {
    name: "uni-icons",
    props: {
      type: {
        type: String,
        default: ''
      },
      color: {
        type: String,
        default: '#333333'
      },
      size: {
        type: [Number, String],
        default: 16
      },
      fontFamily: {
        type: String,
        default: ''
      }
    },
    data() {
      return {};
    },
    computed: {
      unicode() : string {
        let codes = fontData.find((item : IconsDataItem) : boolean => { return item.font_class == this.type })
        if (codes !== null) {
          return codes.unicode
        }
        return ''
      },
      iconSize() : string {
        const size = this.size
        if (typeof size == 'string') {
          const reg = /^[0-9]*$/g
          return reg.test(size as string) ? '' + size + 'px' : '' + size;
          // return '' + this.size
        }
        return this.getFontSize(size as number)
      },
      styleObj() : UTSJSONObject {
        if (this.fontFamily !== '') {
          return { color: this.color, fontSize: this.iconSize, fontFamily: this.fontFamily }
        }
        return { color: this.color, fontSize: this.iconSize }
      }
    },
    created() { },
    methods: {
      /**
       * 字体大小
       */
      getFontSize(size : number) : string {
        return size + 'px';
      },
    },
  }
</script>
<style scoped>
  @font-face {
    font-family: UniIconsFontFamily;
    src: url('./uniicons.ttf');
  }
  .uni-icons {
    font-family: UniIconsFontFamily;
    font-size: 18px;
    font-style: normal;
    color: #333;
  }
</style>
uni_modules/uni-icons/components/uni-icons/uniicons_file.ts
New file
@@ -0,0 +1,664 @@
export type IconsData = {
    id : string
    name : string
    font_family : string
    css_prefix_text : string
    description : string
    glyphs : Array<IconsDataItem>
}
export type IconsDataItem = {
    font_class : string
    unicode : string
}
export const fontData = [
  {
    "font_class": "arrow-down",
    "unicode": "\ue6be"
  },
  {
    "font_class": "arrow-left",
    "unicode": "\ue6bc"
  },
  {
    "font_class": "arrow-right",
    "unicode": "\ue6bb"
  },
  {
    "font_class": "arrow-up",
    "unicode": "\ue6bd"
  },
  {
    "font_class": "auth",
    "unicode": "\ue6ab"
  },
  {
    "font_class": "auth-filled",
    "unicode": "\ue6cc"
  },
  {
    "font_class": "back",
    "unicode": "\ue6b9"
  },
  {
    "font_class": "bars",
    "unicode": "\ue627"
  },
  {
    "font_class": "calendar",
    "unicode": "\ue6a0"
  },
  {
    "font_class": "calendar-filled",
    "unicode": "\ue6c0"
  },
  {
    "font_class": "camera",
    "unicode": "\ue65a"
  },
  {
    "font_class": "camera-filled",
    "unicode": "\ue658"
  },
  {
    "font_class": "cart",
    "unicode": "\ue631"
  },
  {
    "font_class": "cart-filled",
    "unicode": "\ue6d0"
  },
  {
    "font_class": "chat",
    "unicode": "\ue65d"
  },
  {
    "font_class": "chat-filled",
    "unicode": "\ue659"
  },
  {
    "font_class": "chatboxes",
    "unicode": "\ue696"
  },
  {
    "font_class": "chatboxes-filled",
    "unicode": "\ue692"
  },
  {
    "font_class": "chatbubble",
    "unicode": "\ue697"
  },
  {
    "font_class": "chatbubble-filled",
    "unicode": "\ue694"
  },
  {
    "font_class": "checkbox",
    "unicode": "\ue62b"
  },
  {
    "font_class": "checkbox-filled",
    "unicode": "\ue62c"
  },
  {
    "font_class": "checkmarkempty",
    "unicode": "\ue65c"
  },
  {
    "font_class": "circle",
    "unicode": "\ue65b"
  },
  {
    "font_class": "circle-filled",
    "unicode": "\ue65e"
  },
  {
    "font_class": "clear",
    "unicode": "\ue66d"
  },
  {
    "font_class": "close",
    "unicode": "\ue673"
  },
  {
    "font_class": "closeempty",
    "unicode": "\ue66c"
  },
  {
    "font_class": "cloud-download",
    "unicode": "\ue647"
  },
  {
    "font_class": "cloud-download-filled",
    "unicode": "\ue646"
  },
  {
    "font_class": "cloud-upload",
    "unicode": "\ue645"
  },
  {
    "font_class": "cloud-upload-filled",
    "unicode": "\ue648"
  },
  {
    "font_class": "color",
    "unicode": "\ue6cf"
  },
  {
    "font_class": "color-filled",
    "unicode": "\ue6c9"
  },
  {
    "font_class": "compose",
    "unicode": "\ue67f"
  },
  {
    "font_class": "contact",
    "unicode": "\ue693"
  },
  {
    "font_class": "contact-filled",
    "unicode": "\ue695"
  },
  {
    "font_class": "down",
    "unicode": "\ue6b8"
  },
    {
      "font_class": "bottom",
      "unicode": "\ue6b8"
    },
  {
    "font_class": "download",
    "unicode": "\ue68d"
  },
  {
    "font_class": "download-filled",
    "unicode": "\ue681"
  },
  {
    "font_class": "email",
    "unicode": "\ue69e"
  },
  {
    "font_class": "email-filled",
    "unicode": "\ue69a"
  },
  {
    "font_class": "eye",
    "unicode": "\ue651"
  },
  {
    "font_class": "eye-filled",
    "unicode": "\ue66a"
  },
  {
    "font_class": "eye-slash",
    "unicode": "\ue6b3"
  },
  {
    "font_class": "eye-slash-filled",
    "unicode": "\ue6b4"
  },
  {
    "font_class": "fire",
    "unicode": "\ue6a1"
  },
  {
    "font_class": "fire-filled",
    "unicode": "\ue6c5"
  },
  {
    "font_class": "flag",
    "unicode": "\ue65f"
  },
  {
    "font_class": "flag-filled",
    "unicode": "\ue660"
  },
  {
    "font_class": "folder-add",
    "unicode": "\ue6a9"
  },
  {
    "font_class": "folder-add-filled",
    "unicode": "\ue6c8"
  },
  {
    "font_class": "font",
    "unicode": "\ue6a3"
  },
  {
    "font_class": "forward",
    "unicode": "\ue6ba"
  },
  {
    "font_class": "gear",
    "unicode": "\ue664"
  },
  {
    "font_class": "gear-filled",
    "unicode": "\ue661"
  },
  {
    "font_class": "gift",
    "unicode": "\ue6a4"
  },
  {
    "font_class": "gift-filled",
    "unicode": "\ue6c4"
  },
  {
    "font_class": "hand-down",
    "unicode": "\ue63d"
  },
  {
    "font_class": "hand-down-filled",
    "unicode": "\ue63c"
  },
  {
    "font_class": "hand-up",
    "unicode": "\ue63f"
  },
  {
    "font_class": "hand-up-filled",
    "unicode": "\ue63e"
  },
  {
    "font_class": "headphones",
    "unicode": "\ue630"
  },
  {
    "font_class": "heart",
    "unicode": "\ue639"
  },
  {
    "font_class": "heart-filled",
    "unicode": "\ue641"
  },
  {
    "font_class": "help",
    "unicode": "\ue679"
  },
  {
    "font_class": "help-filled",
    "unicode": "\ue674"
  },
  {
    "font_class": "home",
    "unicode": "\ue662"
  },
  {
    "font_class": "home-filled",
    "unicode": "\ue663"
  },
  {
    "font_class": "image",
    "unicode": "\ue670"
  },
  {
    "font_class": "image-filled",
    "unicode": "\ue678"
  },
  {
    "font_class": "images",
    "unicode": "\ue650"
  },
  {
    "font_class": "images-filled",
    "unicode": "\ue64b"
  },
  {
    "font_class": "info",
    "unicode": "\ue669"
  },
  {
    "font_class": "info-filled",
    "unicode": "\ue649"
  },
  {
    "font_class": "left",
    "unicode": "\ue6b7"
  },
  {
    "font_class": "link",
    "unicode": "\ue6a5"
  },
  {
    "font_class": "list",
    "unicode": "\ue644"
  },
  {
    "font_class": "location",
    "unicode": "\ue6ae"
  },
  {
    "font_class": "location-filled",
    "unicode": "\ue6af"
  },
  {
    "font_class": "locked",
    "unicode": "\ue66b"
  },
  {
    "font_class": "locked-filled",
    "unicode": "\ue668"
  },
  {
    "font_class": "loop",
    "unicode": "\ue633"
  },
  {
    "font_class": "mail-open",
    "unicode": "\ue643"
  },
  {
    "font_class": "mail-open-filled",
    "unicode": "\ue63a"
  },
  {
    "font_class": "map",
    "unicode": "\ue667"
  },
  {
    "font_class": "map-filled",
    "unicode": "\ue666"
  },
  {
    "font_class": "map-pin",
    "unicode": "\ue6ad"
  },
  {
    "font_class": "map-pin-ellipse",
    "unicode": "\ue6ac"
  },
  {
    "font_class": "medal",
    "unicode": "\ue6a2"
  },
  {
    "font_class": "medal-filled",
    "unicode": "\ue6c3"
  },
  {
    "font_class": "mic",
    "unicode": "\ue671"
  },
  {
    "font_class": "mic-filled",
    "unicode": "\ue677"
  },
  {
    "font_class": "micoff",
    "unicode": "\ue67e"
  },
  {
    "font_class": "micoff-filled",
    "unicode": "\ue6b0"
  },
  {
    "font_class": "minus",
    "unicode": "\ue66f"
  },
  {
    "font_class": "minus-filled",
    "unicode": "\ue67d"
  },
  {
    "font_class": "more",
    "unicode": "\ue64d"
  },
  {
    "font_class": "more-filled",
    "unicode": "\ue64e"
  },
  {
    "font_class": "navigate",
    "unicode": "\ue66e"
  },
  {
    "font_class": "navigate-filled",
    "unicode": "\ue67a"
  },
  {
    "font_class": "notification",
    "unicode": "\ue6a6"
  },
  {
    "font_class": "notification-filled",
    "unicode": "\ue6c1"
  },
  {
    "font_class": "paperclip",
    "unicode": "\ue652"
  },
  {
    "font_class": "paperplane",
    "unicode": "\ue672"
  },
  {
    "font_class": "paperplane-filled",
    "unicode": "\ue675"
  },
  {
    "font_class": "person",
    "unicode": "\ue699"
  },
  {
    "font_class": "person-filled",
    "unicode": "\ue69d"
  },
  {
    "font_class": "personadd",
    "unicode": "\ue69f"
  },
  {
    "font_class": "personadd-filled",
    "unicode": "\ue698"
  },
  {
    "font_class": "personadd-filled-copy",
    "unicode": "\ue6d1"
  },
  {
    "font_class": "phone",
    "unicode": "\ue69c"
  },
  {
    "font_class": "phone-filled",
    "unicode": "\ue69b"
  },
  {
    "font_class": "plus",
    "unicode": "\ue676"
  },
  {
    "font_class": "plus-filled",
    "unicode": "\ue6c7"
  },
  {
    "font_class": "plusempty",
    "unicode": "\ue67b"
  },
  {
    "font_class": "pulldown",
    "unicode": "\ue632"
  },
  {
    "font_class": "pyq",
    "unicode": "\ue682"
  },
  {
    "font_class": "qq",
    "unicode": "\ue680"
  },
  {
    "font_class": "redo",
    "unicode": "\ue64a"
  },
  {
    "font_class": "redo-filled",
    "unicode": "\ue655"
  },
  {
    "font_class": "refresh",
    "unicode": "\ue657"
  },
  {
    "font_class": "refresh-filled",
    "unicode": "\ue656"
  },
  {
    "font_class": "refreshempty",
    "unicode": "\ue6bf"
  },
  {
    "font_class": "reload",
    "unicode": "\ue6b2"
  },
  {
    "font_class": "right",
    "unicode": "\ue6b5"
  },
  {
    "font_class": "scan",
    "unicode": "\ue62a"
  },
  {
    "font_class": "search",
    "unicode": "\ue654"
  },
  {
    "font_class": "settings",
    "unicode": "\ue653"
  },
  {
    "font_class": "settings-filled",
    "unicode": "\ue6ce"
  },
  {
    "font_class": "shop",
    "unicode": "\ue62f"
  },
  {
    "font_class": "shop-filled",
    "unicode": "\ue6cd"
  },
  {
    "font_class": "smallcircle",
    "unicode": "\ue67c"
  },
  {
    "font_class": "smallcircle-filled",
    "unicode": "\ue665"
  },
  {
    "font_class": "sound",
    "unicode": "\ue684"
  },
  {
    "font_class": "sound-filled",
    "unicode": "\ue686"
  },
  {
    "font_class": "spinner-cycle",
    "unicode": "\ue68a"
  },
  {
    "font_class": "staff",
    "unicode": "\ue6a7"
  },
  {
    "font_class": "staff-filled",
    "unicode": "\ue6cb"
  },
  {
    "font_class": "star",
    "unicode": "\ue688"
  },
  {
    "font_class": "star-filled",
    "unicode": "\ue68f"
  },
  {
    "font_class": "starhalf",
    "unicode": "\ue683"
  },
  {
    "font_class": "trash",
    "unicode": "\ue687"
  },
  {
    "font_class": "trash-filled",
    "unicode": "\ue685"
  },
  {
    "font_class": "tune",
    "unicode": "\ue6aa"
  },
  {
    "font_class": "tune-filled",
    "unicode": "\ue6ca"
  },
  {
    "font_class": "undo",
    "unicode": "\ue64f"
  },
  {
    "font_class": "undo-filled",
    "unicode": "\ue64c"
  },
  {
    "font_class": "up",
    "unicode": "\ue6b6"
  },
    {
      "font_class": "top",
      "unicode": "\ue6b6"
    },
  {
    "font_class": "upload",
    "unicode": "\ue690"
  },
  {
    "font_class": "upload-filled",
    "unicode": "\ue68e"
  },
  {
    "font_class": "videocam",
    "unicode": "\ue68c"
  },
  {
    "font_class": "videocam-filled",
    "unicode": "\ue689"
  },
  {
    "font_class": "vip",
    "unicode": "\ue6a8"
  },
  {
    "font_class": "vip-filled",
    "unicode": "\ue6c6"
  },
  {
    "font_class": "wallet",
    "unicode": "\ue6b1"
  },
  {
    "font_class": "wallet-filled",
    "unicode": "\ue6c2"
  },
  {
    "font_class": "weibo",
    "unicode": "\ue68b"
  },
  {
    "font_class": "weixin",
    "unicode": "\ue691"
  }
] as IconsDataItem[]
// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)
uni_modules/uni-icons/components/uni-icons/uniicons_file_vue.js
New file
@@ -0,0 +1,649 @@
export const fontData = [
  {
    "font_class": "arrow-down",
    "unicode": "\ue6be"
  },
  {
    "font_class": "arrow-left",
    "unicode": "\ue6bc"
  },
  {
    "font_class": "arrow-right",
    "unicode": "\ue6bb"
  },
  {
    "font_class": "arrow-up",
    "unicode": "\ue6bd"
  },
  {
    "font_class": "auth",
    "unicode": "\ue6ab"
  },
  {
    "font_class": "auth-filled",
    "unicode": "\ue6cc"
  },
  {
    "font_class": "back",
    "unicode": "\ue6b9"
  },
  {
    "font_class": "bars",
    "unicode": "\ue627"
  },
  {
    "font_class": "calendar",
    "unicode": "\ue6a0"
  },
  {
    "font_class": "calendar-filled",
    "unicode": "\ue6c0"
  },
  {
    "font_class": "camera",
    "unicode": "\ue65a"
  },
  {
    "font_class": "camera-filled",
    "unicode": "\ue658"
  },
  {
    "font_class": "cart",
    "unicode": "\ue631"
  },
  {
    "font_class": "cart-filled",
    "unicode": "\ue6d0"
  },
  {
    "font_class": "chat",
    "unicode": "\ue65d"
  },
  {
    "font_class": "chat-filled",
    "unicode": "\ue659"
  },
  {
    "font_class": "chatboxes",
    "unicode": "\ue696"
  },
  {
    "font_class": "chatboxes-filled",
    "unicode": "\ue692"
  },
  {
    "font_class": "chatbubble",
    "unicode": "\ue697"
  },
  {
    "font_class": "chatbubble-filled",
    "unicode": "\ue694"
  },
  {
    "font_class": "checkbox",
    "unicode": "\ue62b"
  },
  {
    "font_class": "checkbox-filled",
    "unicode": "\ue62c"
  },
  {
    "font_class": "checkmarkempty",
    "unicode": "\ue65c"
  },
  {
    "font_class": "circle",
    "unicode": "\ue65b"
  },
  {
    "font_class": "circle-filled",
    "unicode": "\ue65e"
  },
  {
    "font_class": "clear",
    "unicode": "\ue66d"
  },
  {
    "font_class": "close",
    "unicode": "\ue673"
  },
  {
    "font_class": "closeempty",
    "unicode": "\ue66c"
  },
  {
    "font_class": "cloud-download",
    "unicode": "\ue647"
  },
  {
    "font_class": "cloud-download-filled",
    "unicode": "\ue646"
  },
  {
    "font_class": "cloud-upload",
    "unicode": "\ue645"
  },
  {
    "font_class": "cloud-upload-filled",
    "unicode": "\ue648"
  },
  {
    "font_class": "color",
    "unicode": "\ue6cf"
  },
  {
    "font_class": "color-filled",
    "unicode": "\ue6c9"
  },
  {
    "font_class": "compose",
    "unicode": "\ue67f"
  },
  {
    "font_class": "contact",
    "unicode": "\ue693"
  },
  {
    "font_class": "contact-filled",
    "unicode": "\ue695"
  },
  {
    "font_class": "down",
    "unicode": "\ue6b8"
  },
    {
      "font_class": "bottom",
      "unicode": "\ue6b8"
    },
  {
    "font_class": "download",
    "unicode": "\ue68d"
  },
  {
    "font_class": "download-filled",
    "unicode": "\ue681"
  },
  {
    "font_class": "email",
    "unicode": "\ue69e"
  },
  {
    "font_class": "email-filled",
    "unicode": "\ue69a"
  },
  {
    "font_class": "eye",
    "unicode": "\ue651"
  },
  {
    "font_class": "eye-filled",
    "unicode": "\ue66a"
  },
  {
    "font_class": "eye-slash",
    "unicode": "\ue6b3"
  },
  {
    "font_class": "eye-slash-filled",
    "unicode": "\ue6b4"
  },
  {
    "font_class": "fire",
    "unicode": "\ue6a1"
  },
  {
    "font_class": "fire-filled",
    "unicode": "\ue6c5"
  },
  {
    "font_class": "flag",
    "unicode": "\ue65f"
  },
  {
    "font_class": "flag-filled",
    "unicode": "\ue660"
  },
  {
    "font_class": "folder-add",
    "unicode": "\ue6a9"
  },
  {
    "font_class": "folder-add-filled",
    "unicode": "\ue6c8"
  },
  {
    "font_class": "font",
    "unicode": "\ue6a3"
  },
  {
    "font_class": "forward",
    "unicode": "\ue6ba"
  },
  {
    "font_class": "gear",
    "unicode": "\ue664"
  },
  {
    "font_class": "gear-filled",
    "unicode": "\ue661"
  },
  {
    "font_class": "gift",
    "unicode": "\ue6a4"
  },
  {
    "font_class": "gift-filled",
    "unicode": "\ue6c4"
  },
  {
    "font_class": "hand-down",
    "unicode": "\ue63d"
  },
  {
    "font_class": "hand-down-filled",
    "unicode": "\ue63c"
  },
  {
    "font_class": "hand-up",
    "unicode": "\ue63f"
  },
  {
    "font_class": "hand-up-filled",
    "unicode": "\ue63e"
  },
  {
    "font_class": "headphones",
    "unicode": "\ue630"
  },
  {
    "font_class": "heart",
    "unicode": "\ue639"
  },
  {
    "font_class": "heart-filled",
    "unicode": "\ue641"
  },
  {
    "font_class": "help",
    "unicode": "\ue679"
  },
  {
    "font_class": "help-filled",
    "unicode": "\ue674"
  },
  {
    "font_class": "home",
    "unicode": "\ue662"
  },
  {
    "font_class": "home-filled",
    "unicode": "\ue663"
  },
  {
    "font_class": "image",
    "unicode": "\ue670"
  },
  {
    "font_class": "image-filled",
    "unicode": "\ue678"
  },
  {
    "font_class": "images",
    "unicode": "\ue650"
  },
  {
    "font_class": "images-filled",
    "unicode": "\ue64b"
  },
  {
    "font_class": "info",
    "unicode": "\ue669"
  },
  {
    "font_class": "info-filled",
    "unicode": "\ue649"
  },
  {
    "font_class": "left",
    "unicode": "\ue6b7"
  },
  {
    "font_class": "link",
    "unicode": "\ue6a5"
  },
  {
    "font_class": "list",
    "unicode": "\ue644"
  },
  {
    "font_class": "location",
    "unicode": "\ue6ae"
  },
  {
    "font_class": "location-filled",
    "unicode": "\ue6af"
  },
  {
    "font_class": "locked",
    "unicode": "\ue66b"
  },
  {
    "font_class": "locked-filled",
    "unicode": "\ue668"
  },
  {
    "font_class": "loop",
    "unicode": "\ue633"
  },
  {
    "font_class": "mail-open",
    "unicode": "\ue643"
  },
  {
    "font_class": "mail-open-filled",
    "unicode": "\ue63a"
  },
  {
    "font_class": "map",
    "unicode": "\ue667"
  },
  {
    "font_class": "map-filled",
    "unicode": "\ue666"
  },
  {
    "font_class": "map-pin",
    "unicode": "\ue6ad"
  },
  {
    "font_class": "map-pin-ellipse",
    "unicode": "\ue6ac"
  },
  {
    "font_class": "medal",
    "unicode": "\ue6a2"
  },
  {
    "font_class": "medal-filled",
    "unicode": "\ue6c3"
  },
  {
    "font_class": "mic",
    "unicode": "\ue671"
  },
  {
    "font_class": "mic-filled",
    "unicode": "\ue677"
  },
  {
    "font_class": "micoff",
    "unicode": "\ue67e"
  },
  {
    "font_class": "micoff-filled",
    "unicode": "\ue6b0"
  },
  {
    "font_class": "minus",
    "unicode": "\ue66f"
  },
  {
    "font_class": "minus-filled",
    "unicode": "\ue67d"
  },
  {
    "font_class": "more",
    "unicode": "\ue64d"
  },
  {
    "font_class": "more-filled",
    "unicode": "\ue64e"
  },
  {
    "font_class": "navigate",
    "unicode": "\ue66e"
  },
  {
    "font_class": "navigate-filled",
    "unicode": "\ue67a"
  },
  {
    "font_class": "notification",
    "unicode": "\ue6a6"
  },
  {
    "font_class": "notification-filled",
    "unicode": "\ue6c1"
  },
  {
    "font_class": "paperclip",
    "unicode": "\ue652"
  },
  {
    "font_class": "paperplane",
    "unicode": "\ue672"
  },
  {
    "font_class": "paperplane-filled",
    "unicode": "\ue675"
  },
  {
    "font_class": "person",
    "unicode": "\ue699"
  },
  {
    "font_class": "person-filled",
    "unicode": "\ue69d"
  },
  {
    "font_class": "personadd",
    "unicode": "\ue69f"
  },
  {
    "font_class": "personadd-filled",
    "unicode": "\ue698"
  },
  {
    "font_class": "personadd-filled-copy",
    "unicode": "\ue6d1"
  },
  {
    "font_class": "phone",
    "unicode": "\ue69c"
  },
  {
    "font_class": "phone-filled",
    "unicode": "\ue69b"
  },
  {
    "font_class": "plus",
    "unicode": "\ue676"
  },
  {
    "font_class": "plus-filled",
    "unicode": "\ue6c7"
  },
  {
    "font_class": "plusempty",
    "unicode": "\ue67b"
  },
  {
    "font_class": "pulldown",
    "unicode": "\ue632"
  },
  {
    "font_class": "pyq",
    "unicode": "\ue682"
  },
  {
    "font_class": "qq",
    "unicode": "\ue680"
  },
  {
    "font_class": "redo",
    "unicode": "\ue64a"
  },
  {
    "font_class": "redo-filled",
    "unicode": "\ue655"
  },
  {
    "font_class": "refresh",
    "unicode": "\ue657"
  },
  {
    "font_class": "refresh-filled",
    "unicode": "\ue656"
  },
  {
    "font_class": "refreshempty",
    "unicode": "\ue6bf"
  },
  {
    "font_class": "reload",
    "unicode": "\ue6b2"
  },
  {
    "font_class": "right",
    "unicode": "\ue6b5"
  },
  {
    "font_class": "scan",
    "unicode": "\ue62a"
  },
  {
    "font_class": "search",
    "unicode": "\ue654"
  },
  {
    "font_class": "settings",
    "unicode": "\ue653"
  },
  {
    "font_class": "settings-filled",
    "unicode": "\ue6ce"
  },
  {
    "font_class": "shop",
    "unicode": "\ue62f"
  },
  {
    "font_class": "shop-filled",
    "unicode": "\ue6cd"
  },
  {
    "font_class": "smallcircle",
    "unicode": "\ue67c"
  },
  {
    "font_class": "smallcircle-filled",
    "unicode": "\ue665"
  },
  {
    "font_class": "sound",
    "unicode": "\ue684"
  },
  {
    "font_class": "sound-filled",
    "unicode": "\ue686"
  },
  {
    "font_class": "spinner-cycle",
    "unicode": "\ue68a"
  },
  {
    "font_class": "staff",
    "unicode": "\ue6a7"
  },
  {
    "font_class": "staff-filled",
    "unicode": "\ue6cb"
  },
  {
    "font_class": "star",
    "unicode": "\ue688"
  },
  {
    "font_class": "star-filled",
    "unicode": "\ue68f"
  },
  {
    "font_class": "starhalf",
    "unicode": "\ue683"
  },
  {
    "font_class": "trash",
    "unicode": "\ue687"
  },
  {
    "font_class": "trash-filled",
    "unicode": "\ue685"
  },
  {
    "font_class": "tune",
    "unicode": "\ue6aa"
  },
  {
    "font_class": "tune-filled",
    "unicode": "\ue6ca"
  },
  {
    "font_class": "undo",
    "unicode": "\ue64f"
  },
  {
    "font_class": "undo-filled",
    "unicode": "\ue64c"
  },
  {
    "font_class": "up",
    "unicode": "\ue6b6"
  },
    {
      "font_class": "top",
      "unicode": "\ue6b6"
    },
  {
    "font_class": "upload",
    "unicode": "\ue690"
  },
  {
    "font_class": "upload-filled",
    "unicode": "\ue68e"
  },
  {
    "font_class": "videocam",
    "unicode": "\ue68c"
  },
  {
    "font_class": "videocam-filled",
    "unicode": "\ue689"
  },
  {
    "font_class": "vip",
    "unicode": "\ue6a8"
  },
  {
    "font_class": "vip-filled",
    "unicode": "\ue6c6"
  },
  {
    "font_class": "wallet",
    "unicode": "\ue6b1"
  },
  {
    "font_class": "wallet-filled",
    "unicode": "\ue6c2"
  },
  {
    "font_class": "weibo",
    "unicode": "\ue68b"
  },
  {
    "font_class": "weixin",
    "unicode": "\ue691"
  }
]
// export const fontData = JSON.parse<IconsDataItem>(fontDataJson)
uni_modules/uni-load-more/changelog.md
New file
@@ -0,0 +1,19 @@
## 1.3.3(2022-01-20)
- 新增 showText属性 ,是否显示文本
## 1.3.2(2022-01-19)
- 修复 nvue 平台下不显示文本的bug
## 1.3.1(2022-01-19)
- 修复 微信小程序平台样式选择器报警告的问题
## 1.3.0(2021-11-19)
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-load-more](https://uniapp.dcloud.io/component/uniui/uni-load-more)
## 1.2.1(2021-08-24)
- 新增 支持国际化
## 1.2.0(2021-07-30)
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.1.8(2021-05-12)
- 新增 组件示例地址
## 1.1.7(2021-03-30)
- 修复 uni-load-more 在首页使用时,h5 平台报 'uni is not defined' 的 bug
## 1.1.6(2021-02-05)
- 调整为uni_modules目录规范
uni_modules/uni-load-more/components/uni-load-more/i18n/en.json
New file
@@ -0,0 +1,5 @@
{
    "uni-load-more.contentdown": "Pull up to show more",
    "uni-load-more.contentrefresh": "loading...",
    "uni-load-more.contentnomore": "No more data"
}
uni_modules/uni-load-more/components/uni-load-more/i18n/index.js
New file
@@ -0,0 +1,8 @@
import en from './en.json'
import zhHans from './zh-Hans.json'
import zhHant from './zh-Hant.json'
export default {
    en,
    'zh-Hans': zhHans,
    'zh-Hant': zhHant
}
uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hans.json
New file
@@ -0,0 +1,5 @@
{
    "uni-load-more.contentdown": "上拉显示更多",
    "uni-load-more.contentrefresh": "正在加载...",
    "uni-load-more.contentnomore": "没有更多数据了"
}
uni_modules/uni-load-more/components/uni-load-more/i18n/zh-Hant.json
New file
@@ -0,0 +1,5 @@
{
    "uni-load-more.contentdown": "上拉顯示更多",
    "uni-load-more.contentrefresh": "正在加載...",
    "uni-load-more.contentnomore": "沒有更多數據了"
}
uni_modules/uni-load-more/components/uni-load-more/uni-load-more.vue
New file
@@ -0,0 +1,399 @@
<template>
    <view class="uni-load-more" @click="onClick">
        <!-- #ifdef APP-NVUE -->
        <loading-indicator v-if="!webviewHide && status === 'loading' && showIcon"
            :style="{color: color,width:iconSize+'px',height:iconSize+'px'}" :animating="true"
            class="uni-load-more__img uni-load-more__img--nvue"></loading-indicator>
        <!-- #endif -->
        <!-- #ifdef H5 -->
        <svg width="24" height="24" viewBox="25 25 50 50"
            v-if="!webviewHide && (iconType==='circle' || iconType==='auto' && platform === 'android') && status === 'loading' && showIcon"
            :style="{width:iconSize+'px',height:iconSize+'px'}"
            class="uni-load-more__img uni-load-more__img--android-H5">
            <circle cx="50" cy="50" r="20" fill="none" :style="{color:color}" :stroke-width="3"></circle>
        </svg>
        <!-- #endif -->
        <!-- #ifndef APP-NVUE || H5 -->
        <view
            v-if="!webviewHide && (iconType==='circle' || iconType==='auto' && platform === 'android') && status === 'loading' && showIcon"
            :style="{width:iconSize+'px',height:iconSize+'px'}"
            class="uni-load-more__img uni-load-more__img--android-MP">
            <view class="uni-load-more__img-icon" :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view>
            <view class="uni-load-more__img-icon" :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view>
            <view class="uni-load-more__img-icon" :style="{borderTopColor:color,borderTopWidth:iconSize/12}"></view>
        </view>
        <!-- #endif -->
        <!-- #ifndef APP-NVUE -->
        <view v-else-if="!webviewHide && status === 'loading' && showIcon"
            :style="{width:iconSize+'px',height:iconSize+'px'}" class="uni-load-more__img uni-load-more__img--ios-H5">
            <image :src="imgBase64" mode="widthFix"></image>
        </view>
        <!-- #endif -->
        <text v-if="showText" class="uni-load-more__text"
            :style="{color: color}">{{ status === 'more' ? contentdownText : status === 'loading' ? contentrefreshText : contentnomoreText }}</text>
    </view>
</template>
<script>
    let platform
    setTimeout(() => {
        platform = uni.getSystemInfoSync().platform
    }, 16)
    import {
        initVueI18n
    } from '@dcloudio/uni-i18n'
    import messages from './i18n/index.js'
    const {
        t
    } = initVueI18n(messages)
    /**
     * LoadMore 加载更多
     * @description 用于列表中,做滚动加载使用,展示 loading 的各种状态
     * @tutorial https://ext.dcloud.net.cn/plugin?id=29
     * @property {String} status = [more|loading|noMore] loading 的状态
     *     @value more loading前
     *     @value loading loading中
     *     @value noMore 没有更多了
     * @property {Number} iconSize 指定图标大小
     * @property {Boolean} iconSize = [true|false] 是否显示 loading 图标
     * @property {String} iconType = [snow|circle|auto] 指定图标样式
     *     @value snow ios雪花加载样式
     *     @value circle 安卓唤醒加载样式
     *     @value auto 根据平台自动选择加载样式
     * @property {String} color 图标和文字颜色
     * @property {Object} contentText 各状态文字说明,值为:{contentdown: "上拉显示更多",contentrefresh: "正在加载...",contentnomore: "没有更多数据了"}
     * @event {Function} clickLoadMore 点击加载更多时触发
     */
    export default {
        name: 'UniLoadMore',
        emits: ['clickLoadMore'],
        props: {
            status: {
                // 上拉的状态:more-loading前;loading-loading中;noMore-没有更多了
                type: String,
                default: 'more'
            },
            showIcon: {
                type: Boolean,
                default: true
            },
            iconType: {
                type: String,
                default: 'auto'
            },
            iconSize: {
                type: Number,
                default: 24
            },
            color: {
                type: String,
                default: '#777777'
            },
            contentText: {
                type: Object,
                default () {
                    return {
                        contentdown: '',
                        contentrefresh: '',
                        contentnomore: ''
                    }
                }
            },
            showText: {
                type: Boolean,
                default: true
            }
        },
        data() {
            return {
                webviewHide: false,
                platform: platform,
                imgBase64: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6QzlBMzU3OTlEOUM0MTFFOUI0NTZDNERBQURBQzI4RkUiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6QzlBMzU3OUFEOUM0MTFFOUI0NTZDNERBQURBQzI4RkUiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDpDOUEzNTc5N0Q5QzQxMUU5QjQ1NkM0REFBREFDMjhGRSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDpDOUEzNTc5OEQ5QzQxMUU5QjQ1NkM0REFBREFDMjhGRSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/Pt+ALSwAAA6CSURBVHja1FsLkFZV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'
            }
        },
        computed: {
            iconSnowWidth() {
                return (Math.floor(this.iconSize / 24) || 1) * 2
            },
            contentdownText() {
                return this.contentText.contentdown || t("uni-load-more.contentdown")
            },
            contentrefreshText() {
                return this.contentText.contentrefresh || t("uni-load-more.contentrefresh")
            },
            contentnomoreText() {
                return this.contentText.contentnomore || t("uni-load-more.contentnomore")
            }
        },
        mounted() {
            // #ifdef APP-PLUS
            var pages = getCurrentPages();
            var page = pages[pages.length - 1];
            var currentWebview = page.$getAppWebview();
            currentWebview.addEventListener('hide', () => {
                this.webviewHide = true
            })
            currentWebview.addEventListener('show', () => {
                this.webviewHide = false
            })
            // #endif
        },
        methods: {
            onClick() {
                this.$emit('clickLoadMore', {
                    detail: {
                        status: this.status,
                    }
                })
            }
        }
    }
</script>
<style lang="scss" >
    .uni-load-more {
        /* #ifndef APP-NVUE */
        display: flex;
        /* #endif */
        flex-direction: row;
        height: 40px;
        align-items: center;
        justify-content: center;
    }
    .uni-load-more__text {
        font-size: 14px;
        margin-left: 8px;
    }
    .uni-load-more__img {
        width: 24px;
        height: 24px;
        // margin-right: 8px;
    }
    .uni-load-more__img--nvue {
        color: #666666;
    }
    .uni-load-more__img--android,
    .uni-load-more__img--ios {
        width: 24px;
        height: 24px;
        transform: rotate(0deg);
    }
    /* #ifndef APP-NVUE */
    .uni-load-more__img--android {
        animation: loading-ios 1s 0s linear infinite;
    }
    @keyframes loading-android {
        0% {
            transform: rotate(0deg);
        }
        100% {
            transform: rotate(360deg);
        }
    }
    .uni-load-more__img--ios-H5 {
        position: relative;
        animation: loading-ios-H5 1s 0s step-end infinite;
    }
    .uni-load-more__img--ios-H5 image {
        position: absolute;
        width: 100%;
        height: 100%;
        left: 0;
        top: 0;
    }
    @keyframes loading-ios-H5 {
        0% {
            transform: rotate(0deg);
        }
        8% {
            transform: rotate(30deg);
        }
        16% {
            transform: rotate(60deg);
        }
        24% {
            transform: rotate(90deg);
        }
        32% {
            transform: rotate(120deg);
        }
        40% {
            transform: rotate(150deg);
        }
        48% {
            transform: rotate(180deg);
        }
        56% {
            transform: rotate(210deg);
        }
        64% {
            transform: rotate(240deg);
        }
        73% {
            transform: rotate(270deg);
        }
        82% {
            transform: rotate(300deg);
        }
        91% {
            transform: rotate(330deg);
        }
        100% {
            transform: rotate(360deg);
        }
    }
    /* #endif */
    /* #ifdef H5 */
    .uni-load-more__img--android-H5 {
        animation: loading-android-H5-rotate 2s linear infinite;
        transform-origin: center center;
    }
    .uni-load-more__img--android-H5 circle {
        display: inline-block;
        animation: loading-android-H5-dash 1.5s ease-in-out infinite;
        stroke: currentColor;
        stroke-linecap: round;
    }
    @keyframes loading-android-H5-rotate {
        0% {
            transform: rotate(0deg);
        }
        100% {
            transform: rotate(360deg);
        }
    }
    @keyframes loading-android-H5-dash {
        0% {
            stroke-dasharray: 1, 200;
            stroke-dashoffset: 0;
        }
        50% {
            stroke-dasharray: 90, 150;
            stroke-dashoffset: -40;
        }
        100% {
            stroke-dasharray: 90, 150;
            stroke-dashoffset: -120;
        }
    }
    /* #endif */
    /* #ifndef APP-NVUE || H5 */
    .uni-load-more__img--android-MP {
        position: relative;
        width: 24px;
        height: 24px;
        transform: rotate(0deg);
        animation: loading-ios 1s 0s ease infinite;
    }
    .uni-load-more__img--android-MP .uni-load-more__img-icon {
        position: absolute;
        box-sizing: border-box;
        width: 100%;
        height: 100%;
        border-radius: 50%;
        border: solid 2px transparent;
        border-top: solid 2px #777777;
        transform-origin: center;
    }
    .uni-load-more__img--android-MP .uni-load-more__img-icon:nth-child(1) {
        animation: loading-android-MP-1 1s 0s linear infinite;
    }
    .uni-load-more__img--android-MP .uni-load-more__img-icon:nth-child(2) {
        animation: loading-android-MP-2 1s 0s linear infinite;
    }
    .uni-load-more__img--android-MP .uni-load-more__img-icon:nth-child(3) {
        animation: loading-android-MP-3 1s 0s linear infinite;
    }
    @keyframes loading-android {
        0% {
            transform: rotate(0deg);
        }
        100% {
            transform: rotate(360deg);
        }
    }
    @keyframes loading-android-MP-1 {
        0% {
            transform: rotate(0deg);
        }
        50% {
            transform: rotate(90deg);
        }
        100% {
            transform: rotate(360deg);
        }
    }
    @keyframes loading-android-MP-2 {
        0% {
            transform: rotate(0deg);
        }
        50% {
            transform: rotate(180deg);
        }
        100% {
            transform: rotate(360deg);
        }
    }
    @keyframes loading-android-MP-3 {
        0% {
            transform: rotate(0deg);
        }
        50% {
            transform: rotate(270deg);
        }
        100% {
            transform: rotate(360deg);
        }
    }
    /* #endif */
</style>
uni_modules/uni-load-more/package.json
New file
@@ -0,0 +1,86 @@
{
  "id": "uni-load-more",
  "displayName": "uni-load-more 加载更多",
  "version": "1.3.3",
  "description": "LoadMore 组件,常用在列表里面,做滚动加载使用。",
  "keywords": [
    "uni-ui",
    "uniui",
    "加载更多",
    "load-more"
],
  "repository": "https://github.com/dcloudio/uni-ui",
  "engines": {
    "HBuilderX": ""
  },
  "directories": {
    "example": "../../temps/example_temps"
  },
  "dcloudext": {
    "category": [
      "前端组件",
      "通用组件"
    ],
    "sale": {
      "regular": {
        "price": "0.00"
      },
      "sourcecode": {
        "price": "0.00"
      }
    },
    "contact": {
      "qq": ""
    },
    "declaration": {
      "ads": "无",
      "data": "无",
      "permissions": "无"
    },
    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
  },
  "uni_modules": {
    "dependencies": ["uni-scss"],
    "encrypt": [],
    "platforms": {
      "cloud": {
        "tcb": "y",
        "aliyun": "y"
      },
      "client": {
        "App": {
          "app-vue": "y",
          "app-nvue": "y"
        },
        "H5-mobile": {
          "Safari": "y",
          "Android Browser": "y",
          "微信浏览器(Android)": "y",
          "QQ浏览器(Android)": "y"
        },
        "H5-pc": {
          "Chrome": "y",
          "IE": "y",
          "Edge": "y",
          "Firefox": "y",
          "Safari": "y"
        },
        "小程序": {
          "微信": "y",
          "阿里": "y",
          "百度": "y",
          "字节跳动": "y",
          "QQ": "y"
        },
        "快应用": {
          "华为": "u",
          "联盟": "u"
        },
        "Vue": {
            "vue2": "y",
            "vue3": "y"
        }
      }
    }
  }
}
uni_modules/uni-load-more/readme.md
New file
@@ -0,0 +1,14 @@
### LoadMore 加载更多
> **组件名:uni-load-more**
> 代码块: `uLoadMore`
用于列表中,做滚动加载使用,展示 loading 的各种状态。
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-load-more)
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
vue.config.js
@@ -11,6 +11,22 @@
    devServer: {
        proxy: {
            "/api/blade-resource/oss": {
                //本地服务接口地址
                // target: "http://localhost:9528",
                target: "https://srgdjczzxtpt.com:2080/api",
                // target: "https://kt39592615.goho.co",
                // target: "http://z4042833u6.wicp.vip",
                // target: "http://localhost:9528",
                // target: "http://192.168.2.109:9528",
                //远程演示服务地址,可用于直接启动项目
                //target: 'https://saber.bladex.cn/api',
                changeOrigin: true,
                ws: true,
                pathRewrite: {
                    "^/api": "/",
                },
            },
            // 业务平台接口
            "/api": {
                target: "http://172.16.13.129:9528",