From d02a55091f739068f185a0107dd4f3372ba082e6 Mon Sep 17 00:00:00 2001 From: dengxiongfei Date: Tue, 11 Jan 2022 11:28:34 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0websocket=E3=80=81=E6=96=B0?= =?UTF-8?q?=E5=A2=9Eqn-form-item=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apis/clientCreditApi.js | 10 + apis/commonApi.js | 8 + apis/mineApi.js | 14 + components/qn-footer/qn-footer.vue | 1 + components/qn-form-item/qn-form-item.vue | 87 ++ enums/index.js | 25 + env/index.js | 3 + main.js | 9 +- pages.json | 95 +- pages/client-credit/index.vue | 118 ++- pages/enterprise-info/index.vue | 296 +++--- pages/{client-signing => fs-credit}/index.vue | 0 pages/guarantee-agreement/index.vue | 203 ++++ pages/login/index.vue | 2 +- pages/mine/index.vue | 259 ++++- pages/month-credit/index.vue | 181 ++++ pages/page-view/index.vue | 59 ++ pages/search/index.vue | 2 +- pages/toggle-supplier/index.vue | 9 + static/imgs/mine/contract-icon.png | Bin 0 -> 8810 bytes static/imgs/mine/credit-icon.png | Bin 0 -> 5996 bytes static/imgs/mine/default-avatar.png | Bin 0 -> 17577 bytes static/imgs/mine/finance-icon.png | Bin 0 -> 8572 bytes static/imgs/mine/money-icon.png | Bin 0 -> 1662 bytes static/imgs/mine/order-icon.png | Bin 0 -> 5275 bytes static/imgs/mine/user-avatar.png | Bin 1522 -> 5263 bytes uni_modules/uni-data-picker/changelog.md | 52 - .../components/uni-data-picker/keypress.js | 45 - .../uni-data-picker/uni-data-picker.vue | 537 ---------- .../uni-data-pickerview/uni-data-picker.js | 563 ---------- .../uni-data-pickerview.vue | 333 ------ uni_modules/uni-data-picker/package.json | 92 -- uni_modules/uni-data-picker/readme.md | 22 - uni_modules/uni-datetime-picker/changelog.md | 85 -- .../uni-datetime-picker/calendar-item.vue | 185 ---- .../uni-datetime-picker/calendar.vue | 898 ---------------- .../uni-datetime-picker/i18n/en.json | 19 - .../uni-datetime-picker/i18n/index.js | 8 - .../uni-datetime-picker/i18n/zh-Hans.json | 19 - .../uni-datetime-picker/i18n/zh-Hant.json | 19 - .../uni-datetime-picker/keypress.js | 45 - .../uni-datetime-picker/time-picker.vue | 927 ----------------- .../uni-datetime-picker.vue | 981 ------------------ .../components/uni-datetime-picker/util.js | 410 -------- uni_modules/uni-datetime-picker/package.json | 90 -- uni_modules/uni-datetime-picker/readme.md | 21 - utils/index.js | 109 ++ 47 files changed, 1241 insertions(+), 5600 deletions(-) create mode 100644 apis/mineApi.js create mode 100644 components/qn-form-item/qn-form-item.vue rename pages/{client-signing => fs-credit}/index.vue (100%) create mode 100644 pages/guarantee-agreement/index.vue create mode 100644 pages/month-credit/index.vue create mode 100644 pages/page-view/index.vue create mode 100644 pages/toggle-supplier/index.vue create mode 100644 static/imgs/mine/contract-icon.png create mode 100644 static/imgs/mine/credit-icon.png create mode 100644 static/imgs/mine/default-avatar.png create mode 100644 static/imgs/mine/finance-icon.png create mode 100644 static/imgs/mine/money-icon.png create mode 100644 static/imgs/mine/order-icon.png delete mode 100644 uni_modules/uni-data-picker/changelog.md delete mode 100644 uni_modules/uni-data-picker/components/uni-data-picker/keypress.js delete mode 100644 uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue delete mode 100644 uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js delete mode 100644 uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue delete mode 100644 uni_modules/uni-data-picker/package.json delete mode 100644 uni_modules/uni-data-picker/readme.md delete mode 100644 uni_modules/uni-datetime-picker/changelog.md delete mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue delete mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue delete mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json delete mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js delete mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json delete mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json delete mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/keypress.js delete mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue delete mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue delete mode 100644 uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js delete mode 100644 uni_modules/uni-datetime-picker/package.json delete mode 100644 uni_modules/uni-datetime-picker/readme.md create mode 100644 utils/index.js diff --git a/apis/clientCreditApi.js b/apis/clientCreditApi.js index 625c189..bfd177e 100644 --- a/apis/clientCreditApi.js +++ b/apis/clientCreditApi.js @@ -19,3 +19,13 @@ export function getCustomerCreditInfo(data) { data }) } +/** + * 创建月结授信 + * @param {*} data + */ +export function makeMonthlyCreditInfo(data) { + return http.post({ + url: '/yyt-uec/supplier/create/customer/credit', + data + }) +} diff --git a/apis/commonApi.js b/apis/commonApi.js index 1a07f27..1dc3bd6 100644 --- a/apis/commonApi.js +++ b/apis/commonApi.js @@ -44,3 +44,11 @@ export function getBaseInfo(data = {}, refresh = false) { } }) } + +/** + * 获取当前账号的企业实名认证地址 + * @param {object} data 参数 enterpriseId + */ +export function getVerifyUrl(data = {}) { + return http.post({ url: '/yyt-uec/get/fdd-enterprise-verify-url', data }) +} diff --git a/apis/mineApi.js b/apis/mineApi.js new file mode 100644 index 0000000..f76e9bc --- /dev/null +++ b/apis/mineApi.js @@ -0,0 +1,14 @@ +import http from '../utils/http/index.js' + +/** + * 纸掌柜获取纸盘商订单统计 + * @param {object} data + * @returns 订单统计 + * swagger:http://api-ops-uec-test.qniao.cn/uec/swagger-ui/index.html?urls.primaryName=CustomerApi#/%E7%99%BB%E5%BD%95%E8%AE%A4%E8%AF%81/authorizeByCaptchaUsingPOST + */ +export const getOrderStatistics = (data) => { + return http.get({ + url: '/base-paper-trading/get/supplier/order-volume-statistics', + data + }) +} diff --git a/components/qn-footer/qn-footer.vue b/components/qn-footer/qn-footer.vue index c9362ef..991d0a8 100644 --- a/components/qn-footer/qn-footer.vue +++ b/components/qn-footer/qn-footer.vue @@ -42,6 +42,7 @@ export default { background-color: #fff; overflow: hidden; padding: 16rpx 0; + margin-top: 24rpx; } .qn-footer--fixed { position: fixed; diff --git a/components/qn-form-item/qn-form-item.vue b/components/qn-form-item/qn-form-item.vue new file mode 100644 index 0000000..4b0febf --- /dev/null +++ b/components/qn-form-item/qn-form-item.vue @@ -0,0 +1,87 @@ + + + + + diff --git a/enums/index.js b/enums/index.js index 0f0b3ec..259f546 100644 --- a/enums/index.js +++ b/enums/index.js @@ -46,3 +46,28 @@ export const uploadUrl = { image: `https://api-ops-yyt${urlEnv}.qniao.cn/yyt-uec/file-uploading/upload/image`, file: `https://api-ops-yyt${urlEnv}.qniao.cn/yyt-uec/file-uploading/upload/file` } +/** + * 结算周期:1:月结30(飞算1期),2:月结45,3:月结60(飞算2期),4:月结75,5:月结90(飞算3期) + */ +export const settlementPeriodEnum = [ + { + value: 1, + label: '月结30' + }, + { + value: 2, + label: '月结45' + }, + { + value: 3, + label: '月结60' + }, + { + value: 4, + label: '月结75' + }, + { + value: 5, + label: '月结90' + } +] diff --git a/env/index.js b/env/index.js index 751d7ca..a0bfcb1 100644 --- a/env/index.js +++ b/env/index.js @@ -1,3 +1,6 @@ +/** + * @description 唯一环境变量 + */ const env = 'test' // const env = 'dev' // const env = 'production' diff --git a/main.js b/main.js index 86cf81d..98dab6a 100644 --- a/main.js +++ b/main.js @@ -1,11 +1,12 @@ import App from './App' -import pubFn from './common/js/publicFn.js' -import store from "./store"; +import store from './store' import Vue from 'vue' + Vue.config.productionTip = false -Vue.prototype.$store = store; +// Vue.prototype.$store = store App.mpType = 'app' const app = new Vue({ - ...App + ...App, + store }) app.$mount() diff --git a/pages.json b/pages.json index 0e96a30..a6aa9ed 100644 --- a/pages.json +++ b/pages.json @@ -66,6 +66,14 @@ "navigationStyle": "custom" } }, + { + "path": "pages/toggle-supplier/index", + "style": { + "navigationBarTitleText": "切换供应商", + "enablePullDownRefresh": false, + "navigationStyle": "custom" + } + }, { "path": "pages/message/index", "style": { @@ -104,9 +112,25 @@ } }, { - "path": "pages/client-signing/index", + "path": "pages/month-credit/index", "style": { - "navigationBarTitleText": "客户签约", + "navigationBarTitleText": "月结授信", + "navigationStyle": "custom", + "enablePullDownRefresh": false + } + }, + { + "path": "pages/fs-credit/index", + "style": { + "navigationBarTitleText": "飞算授信", + "navigationStyle": "custom", + "enablePullDownRefresh": false + } + }, + { + "path": "pages/guarantee-agreement/index", + "style": { + "navigationBarTitleText": "担保协议", "navigationStyle": "custom", "enablePullDownRefresh": false } @@ -130,8 +154,8 @@ { "path": "pages/my-offer/index", "style": { - "navigationBarTitleText": "我的报价", - "navigationStyle": "custom", + "navigationBarTitleText": "我的报价", + "navigationStyle": "custom", "enablePullDownRefresh": false } }, @@ -142,38 +166,39 @@ "navigationStyle": "custom", "enablePullDownRefresh": false } + }, + { + "path": "pages/quotation-details/index", + "style": { + "navigationBarTitleText": "报价详情", + "navigationStyle": "custom", + "enablePullDownRefresh": false + } + }, + { + "path": "pages/switching-mall/index", + "style": { + "navigationBarTitleText": "切换商城", + "navigationStyle": "custom", + "enablePullDownRefresh": false + } + }, + { + "path": "pages/add-paper/index", + "style": { + "navigationBarTitleText": "添加纸品", + "navigationStyle": "custom", + "enablePullDownRefresh": false + } + }, + { + "path": "pages/page-view/index", + "style": { + "navigationBarTitleText": "统一第三方页面", + "enablePullDownRefresh": false + } } - ,{ - "path" : "pages/quotation-details/index", - "style" : - { - "navigationBarTitleText": "报价详情", - "navigationStyle": "custom", - "enablePullDownRefresh": false - } - - } - ,{ - "path" : "pages/switching-mall/index", - "style" : - { - "navigationBarTitleText": "切换商城", - "navigationStyle": "custom", - "enablePullDownRefresh": false - } - - } - ,{ - "path" : "pages/add-paper/index", - "style" : - { - "navigationBarTitleText": "添加纸品", - "navigationStyle": "custom", - "enablePullDownRefresh": false - } - - } - ], + ], "globalStyle": { "navigationBarTextStyle": "black", "navigationBarTitleText": "uni-app", diff --git a/pages/client-credit/index.vue b/pages/client-credit/index.vue index 528807a..ba4ea52 100644 --- a/pages/client-credit/index.vue +++ b/pages/client-credit/index.vue @@ -1,23 +1,32 @@ @@ -64,29 +132,115 @@ import { exit, go2 } from '@/utils/hook.js' import { fddEnterpriseStatus } from '@/enums/index.js' import { getBaseInfo } from '@/apis/commonApi.js' +import qnDataPicker from '@/components/qn-data-picker/qn-data-picker.vue' +import { dateTimeFormat } from '@/utils/index.js' +import { getOrderStatistics } from '@/apis/mineApi.js' +// 获取本月第一天和最后一天 +const currentMonth = (() => { + let endDate = new Date() + let beginDate = new Date(endDate.getFullYear(), endDate.getMonth(), 1) + return [dateTimeFormat(beginDate, 'yyyy-mm-dd'), dateTimeFormat(endDate, 'yyyy-mm-dd')] +})() + +// 获取上月第一天和最后一天 +const lastMonth = (() => { + let now = new Date() + let endDate = new Date(now.getFullYear(), now.getMonth(), 0) + let beginDate = new Date(now.getFullYear(), now.getMonth() - 1, 1) + return [dateTimeFormat(beginDate, 'yyyy-mm-dd'), dateTimeFormat(endDate, 'yyyy-mm-dd')] +})() export default { + components: { qnDataPicker }, data() { return { userInfo: { - avatar: this.$store.state.userInfo.avatar, - name: this.$store.state.userInfo.name, - supplierName: this.$store.state.supplierInfo.name, - fddEnterpriseStatus: this.$store.state.supplierInfo.fddEnterpriseStatus + avatar: this.$store.state.userInfo.avatar || '', + name: this.$store.state.userInfo.name || '', + supplierName: this.$store.state.supplierInfo.name || '', + fddEnterpriseStatus: this.$store.state.supplierInfo.fddEnterpriseStatus || 1 }, fddStatus: Object.freeze(fddEnterpriseStatus), messageNum: 0, - companyNum: 0 + companyNum: 0, + tradeRange: [ + { + text: '本月', + value: currentMonth.join('~') + }, + { + text: '上月', + value: lastMonth.join('~') + }, + { + text: '总计', + value: '' + } + ], + tradeDate: currentMonth.join('~'), + tradeData: { + tradingVolume: 0, + volumeOfBusiness: 0, + orderQuantity: 0 + } } }, methods: { logout() { exit() }, - go2 + go2, + // 获取纸盘商订单统计 + getStatistics() { + if (!this.hasLogin) { + return + } + let beginDate = this.tradeDate.split('~')[0] || '' + let endDate = this.tradeDate.split('~')[1] || '' + // 供应商id + let currentSupplier = this.$store.state.supplierInfo.supplierId + getOrderStatistics({ + beginDate, + endDate, + currentSupplier + }).then((res) => { + console.log('res', res) + if (res) { + this.tradeData = res + } + }) + } + }, + watch: { + tradeDate(val) { + console.log('val:', val) + }, + '$store.state.supplierInfo.supplierId': { + handler(val) { + console.log('切换了供应商:', val) + if (val) { + this.getStatistics() + } + }, + immediate: true + }, + tradeDate() { + this.getStatistics() + } }, computed: { hasLogin() { + console.log('token:', this.$store.state.qnToken) return this.$store.state.qnToken != '' + }, + curAvatar() { + if (!this.hasLogin) { + return '/static/imgs/mine/user-avatar.png' + } + if (this.userInfo.avatar) { + return this.userInfo.avatar + } else { + return '/static/imgs/mine/default-avatar.png' + } } }, onShow() { @@ -95,6 +249,9 @@ export default { this.companyNum = res.enterpriseList.length } }) + }, + created() { + this.getStatistics() } } @@ -150,7 +307,6 @@ export default { flex-grow: 0; flex-shrink: 0; overflow: hidden; - background-color: #fff; margin-right: 16rpx; } .user__name { @@ -279,4 +435,89 @@ export default { } } } +.card-area { + width: 686rpx; + margin: 20rpx 32rpx 0; + background-color: #fff; + box-shadow: 0 2rpx 14rpx 0 rgba(220, 220, 220, 0.5); + border-radius: 10px; + .header { + padding: 20rpx 24rpx 14rpx; + border-bottom: 2rpx solid #f8f8f8; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + .item { + display: flex; + flex-direction: row; + align-items: center; + .icon { + flex-grow: 0; + flex-shrink: 0; + margin-right: 10rpx; + } + .text { + font-size: 30rpx; + color: rgba(0, 0, 0, 0.85); + letter-spacing: 1.5rpx; + font-weight: 500; + } + } + } +} +.order-area { + padding: 20rpx 20rpx 30rpx; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + .order-item { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + .value { + font-size: 36rpx; + color: rgba(0, 0, 0, 0.85); + font-weight: 500; + } + .label { + font-size: 26rpx; + color: #666666; + margin-top: 10rpx; + } + } +} +.icon-area { + padding: 40rpx 32rpx; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + flex-wrap: wrap; + .icon-item { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + .icon { + width: 68rpx; + height: 68rpx; + flex-grow: 0; + flex-shrink: 0; + } + .label { + font-size: 26rpx; + color: #666666; + margin-top: 10rpx; + } + } +} +.time-range { + display: flex; + flex-direction: row; + align-items: center; + justify-content: flex-end; +} diff --git a/pages/month-credit/index.vue b/pages/month-credit/index.vue new file mode 100644 index 0000000..26839d8 --- /dev/null +++ b/pages/month-credit/index.vue @@ -0,0 +1,181 @@ + + + + + diff --git a/pages/page-view/index.vue b/pages/page-view/index.vue new file mode 100644 index 0000000..767a9a6 --- /dev/null +++ b/pages/page-view/index.vue @@ -0,0 +1,59 @@ + + + + + diff --git a/pages/search/index.vue b/pages/search/index.vue index 1e49d1d..eca9d44 100644 --- a/pages/search/index.vue +++ b/pages/search/index.vue @@ -106,7 +106,7 @@ export default { }, computed: { historyList() { - return this.$store.state.searchHistory + return this.$store.state.searchHistory || [] } } } diff --git a/pages/toggle-supplier/index.vue b/pages/toggle-supplier/index.vue new file mode 100644 index 0000000..9cb29d9 --- /dev/null +++ b/pages/toggle-supplier/index.vue @@ -0,0 +1,9 @@ + + + + + diff --git a/static/imgs/mine/contract-icon.png b/static/imgs/mine/contract-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..13dc629589d0cb63255a924f5d96999460ec407d GIT binary patch literal 8810 zcmV-wB9+~VP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91N}vM(1ONa40RR91N&o-=06xuyNB{sK)Ja4^RCodHoLQ`9*Ok}z8NTnk zQ@JLW=OHm}C$TXmYQ)e)iV=f)0$PMl3kjhX4+xNW03m@Qk!mX-cC+bm;0^-q zR$zT(pq4>Wf<}N&0g&Jv2bhgVQg(hPW$W{lU0$T@fq}!z)eTj=_k*}T3K^hTMwifayNyO&b8Lp(i_+ATo) zv3H3Fz?81rfpy0~-3p`&7gDYS3DEAflph74`EJU~B9-NzKmSZIZ6D0bbi8ZZJck*~ z{vFeBD>O0BUCYBf>$;{bt`%)|_S$PlU%2|6)$PeFwbRwqUfv=Gu=NY6J#{LzO4rY7 zzm|;tvSi&ckt0y5+bBtbbnR5i@7_vzyON4a*HUrn+4t_BeQNQQtVo}mOs3_eC|9#A zU+dxNU`G;+4-xhkAFB>rbhMSxmazexQk$}QTi4g;i`|OB`N90+){irc@gQFAzjBGOYN;BYv|$-L@pJ%9Z1EcROG9v$R??{`!ApU`C_g6(p?)TjssG! z6eDxd-p!ofd?$n>+dY{*1bv>>$ENm}$VdTBGB%89V?y25>H4)RmlpH(e{OyK{=Z$n zm*(k6YWQu^L#e@Rgk&v)HAH_5u|CJ%6qv+OO}>2M=)HHB z#iZz3Mwe@hBMtpy9K3Kp#tPY(Hty4aL|T3I8q?!*+m7_mkM3NbXW5L=E7OsUQzzDs z9QnzkUpV_Kvtwx`ZKWd3kbJa3jnKxbA){+Eg7cw)T9zh#qx%8r-Ftd<(;f-Zu`ite zOOy5d=Qq}lAKPO>1_{AjpX?2Zc^H%fFA7J#aio{xWl#nn`?AYzwL`ncT$UrAO;%S| z*N!~7@r83=)piQjTWErV?Vu0jMKtpJp@AA3IZZGbZjQ6BBSvc7uk zSV#p7884?}ln-Fkwq<4vGH%!dF~G9S2-uJwfF8?6CF?19LmX*IF^_mwuCA7|^4Zm& zy7WiVG!+i=0^9m+27Q#Os6709D4<4k6-%W_Kgk)++09Xzm#IAYXD
13T*ElX{q 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 literal 0 HcmV?d00001 diff --git a/static/imgs/mine/credit-icon.png b/static/imgs/mine/credit-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..fa4b43cc29641e739299b6a96261a6b5ddc3eaf7 GIT binary patch literal 5996 zcmV-y7nA6TP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91M4$rz1ONa40RR91NdN!<060kp4gdfa)=5M`RCodHTwRPM$5lR6eShZX z&g{%)XD4=cKtk?0f>&+}PJ2Q9Y{&jcpeW$DX*6n-m%&u`{Kcsg1 zR`sbnRX;~`bW&u@qs ztD!oL?UndzRGQ+G(?lkeGow4TVlxtQ0! zx0OHom4E49Zocz)K1pWbIYIKU+Xj%T-~?cFmYD>`5C}2aTKjX_I`jg0UZg(@Pe=g3 z-gTSxPM93tmbS%awr=k_*8RfQZY=)QGuzFJzjkWxBOiPBwa5PO((Lcm>|$>F;%slr zH3fzw@SN*t>E%@&V+PystYlR($m;dBY%a%5ot*f`pNAB#M+RtU@ng6Z5 zB9fUu`u^P4KYQ2CW4$zK47%++u`M`F-O&&`3vl`XqqFU`T$Q{bCch5P0I;ycWZkyS z)5JEc`>D@8pFa*p^Ud$eEBCFMosYghx#REtT`u=~ZAZCD??m3)z2R)fxq59mr$@@c zrX&lqZoVyf2jGkVvr$wV12X~$v*{VzX#LIoO8|WhK!~Lm4AO?p=avg)^F0{9Y_b#} zn0=EwW3j%oZqTtw-z*I>(}y2L{atL@Od4k3^2|ssY2vKe&&|GbrU_7*%i5ZGuWj5e z#Q0CUO7>>8YUe4Hr(p?4@4@QlrUv3vbB+npEN>1-#ze75~S&AJcUWM|f) zPAAq_dxP>|jWgn)DD=mjNsL|CchEntmC7S``LPe|eun%8CTvCjIJXgD)-`!Y`=)!UFOHU=sP9dC!W4Mc;%1puRq!wwEtAL7evxc6mg_*$ekFc z6RB^Us9*#{5Qk)tXcL!#mP^B=$wFfGcU}G1N={p8^YTf!AOf){y9{R)jKZdyZrXvY z*nED`W(R_f&Tg3$o`6(Q#}vy84=q^Y--$rR3^$pEVG}u3tDsYe$?1{7;KIPcF6){k znP1EYsaV+RI@eb6?Y5ZPR|-%{Kv;llj5IeU?O__lIEG%&VG43Eu`&!hh~D1R55bsP zE>=F4R&8RR=cv^bP~zg%G|M44&RVbu-9Jk)uBS65*L79IuYhoNX`>(YU&FlL!`N*1 zY;G28-tS`R1#UGdRz6O9X@OMr28)cmm^q?)k4TQRljj9U7%Xu!3U2^t3Wmdqz<`pp zDNkl>=Jss1Z%sdi?Wc7++Ppk;A0-`n}q3Q`!TPRj)D$|JQ!*41wDz|0X;5j9MT?V$Ku!*+K zvf-B1=9f>b%4yH1fPA+s1TYTJ3Tey8OxFqqp29;WwM=YiDWHO4@vQ;ogb_j*WEEL!Mb!XkICFGuHa@-Rfi|> z#5OThJ!&G;A;ggukLuujdJ6$g0^6EczV2JsO-;Uc%%s^RBPZ8X$`FukEVY|(tCeFw z?!d@aFOfP5qssut3FAVnMWkThtO5||aj{!T`E#D$K0}*mo7;zt??6mV0ZIs^xO_e_ITmJ4+ITXnJh{leQsii z$U3zKCZJKZGh~g$mBIREkyN{*vc;4P>8v=SNA-0E`68Ag*336B-E^$m!PbJb3~di= z3P=~LR1&ajV+4=ilFj1j69`_V3 zF~wqAYk=k105;~BO&1H>6@&L

r8u+`$battD~$T}-=pI7ym#OoCIn!2}cWh|Qom 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%0Dc;jzZYc+qwT@NT@ zEOoD??0bnJt&jQ*aBi-YdDuE#?6cgXS6J}WR=dBJJ8eb50bB&5`{oWFB!%dxw~gFJ zS%f8clqUU4LgiRXbzDAkA+YjC+&7X92`wA}JlnQS?P&IH}s8I-Ymvp>)M&f)x-SD`F;^!XiCyAQV9qHe;n zeP$DI`@oXGm{lOufhP7_53n#r`?>SGyI%ZJ4!r9a)5;*CVC+c4{tN!DwV|m)+oZ4W z(4uG*xhzs%Fpx4iV5?!uC!U_u-rDhN*|nW8=%nMc;=Vk#?o>I#oTzru3e&PzLbO<1 z@#G1bXPr2Z$~}BqNV_}+Ag|)MCMxOu_Syz*qVlR;Gr{Opj&ff$U0GLbdgT3>{SP=A zuz;haRPY%yzPj}D<;TvtUIT^Ev6LQNXyfJ`=HTm#tPv(%FbiJ>zxO0-^cZuO97|-W zd`C6WxOS7NU%yePlb>FhS(VDB&(jG-h>QHzuUc>FR;}HpdB5v7Jox^*#noaJJR*de zzS{$;OAXB?1-I&#v+o*RAV+t`$h)F-j2QY_&~FAEZ3hnq%t_E!X#_`?V@=D0-W)hT z08P8P{`xiR0#?Xc;l<`_xFF+M6k1<6as1_lbH`5F_|OOL8pvQHAJMZDCAWR?_%EN# zXnpx}8F!2-G*!aSrxhojvLjOa!8+6~f#-Bj+SVK$-hd?~wNpz8nV`4nrfZbxd20;~ zCt|8sQWm2MOx3HGXWy~n`lDJSzBzy%^oi+cs`4w~F_5@VUG0LC?=>Hl;Cz+vG~XY- zUH_>CGcF+y;nLMAi`|<8?JTa$qHHZW(_qI@kqLwy4NW};O2XnoalIeC_!;x?K<8%R ziutetoSOlspdZrjhfcn?Yj$V5xmd#Tg{q9GXMJx9= zZruD&Efst$r=s|Q>bp-4+T1qHDd>~nk4V7zOAgh_yYFtB)s>ZVntCpdQ^Zm5M5%=<54YnY?XTYmxdRZH;J zvc(<(rJU|||8~Nm%ac<#QztNK4o%nH$9CPXmhEVDUV*88_LCX%=kN~we`(fl#4+t! QiU0rr07*qoM6N<$g2POq6#xJL literal 0 HcmV?d00001 diff --git a/static/imgs/mine/finance-icon.png b/static/imgs/mine/finance-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b26f8f167ec3173efa7837dad39fa0118912fa06 GIT binary patch literal 8572 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 IM6N<$f{u#w%>V!Z literal 0 HcmV?d00001 diff --git a/static/imgs/mine/order-icon.png b/static/imgs/mine/order-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..27b06a667dededf201e22f36ea4a706efeaae164 GIT binary patch literal 5275 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 literal 0 HcmV?d00001 diff --git a/static/imgs/mine/user-avatar.png b/static/imgs/mine/user-avatar.png index c6c94fba68a96b737071e3e57e9986a1652a9cf8..4df69c8790436afea6a865ac41dd4e330f0b47e8 100644 GIT binary patch delta 5240 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 Y6uTzy*OxxQpa1{>07*qoM6N<$f+xq!ga7~l diff --git a/uni_modules/uni-data-picker/changelog.md b/uni_modules/uni-data-picker/changelog.md deleted file mode 100644 index d1998de..0000000 --- a/uni_modules/uni-data-picker/changelog.md +++ /dev/null @@ -1,52 +0,0 @@ -## 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 目录规范 diff --git a/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js b/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js deleted file mode 100644 index 6ef26a2..0000000 --- a/uni_modules/uni-data-picker/components/uni-data-picker/keypress.js +++ /dev/null @@ -1,45 +0,0 @@ -// #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 diff --git a/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue b/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue deleted file mode 100644 index ce51b16..0000000 --- a/uni_modules/uni-data-picker/components/uni-data-picker/uni-data-picker.vue +++ /dev/null @@ -1,537 +0,0 @@ - - - - - diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js deleted file mode 100644 index c12fd54..0000000 --- a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-picker.js +++ /dev/null @@ -1,563 +0,0 @@ -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: 20 - }, - 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 - }, - postField() { - let fields = [this.field]; - if (this.parentField) { - fields.push(`${this.parentField} as parent_value`); - } - return fields.join(','); - }, - 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 = [] - }, - 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 - }, - getNodeData(callback) { - if (this.loading) { - return - } - this.loading = true - this.getCommand({ - field: this.postField, - where: this._pathWhere() - }).then((res) => { - this.loading = false - this.selected = res.result.data - callback && callback() - }).catch((err) => { - this.loading = false - this.errorMessage = err - }) - }, - getTreePath(callback) { - if (this.loading) { - return - } - this.loading = true - - this.getCommand({ - field: this.postField, - getTreePath: { - startWith: `${this.selfField}=='${this.dataValue}'` - } - }).then((res) => { - this.loading = false - let treePath = [] - this._extractTreePath(res.result.data, treePath) - this.selected = treePath - callback && callback() - }).catch((err) => { - this.loading = false - this.errorMessage = err - }) - }, - loadData() { - if (this.isLocaldata) { - this._processLocalData() - return - } - - if (this.dataValue != null) { - this._loadNodeData((data) => { - this._treeData = data - this._updateBindData() - this._updateSelected() - }) - return - } - - if (this.stepSearh) { - this._loadNodeData((data) => { - this._treeData = data - this._updateBindData() - }) - } else { - this._loadAllData((data) => { - this._treeData = [] - this._extractTree(data, this._treeData, null) - this._updateBindData() - }) - } - }, - _loadAllData(callback) { - if (this.loading) { - return - } - this.loading = true - - this.getCommand({ - field: this.postField, - gettree: true, - startwith: `${this.selfField}=='${this.dataValue}'` - }).then((res) => { - this.loading = false - callback(res.result.data) - this.onDataChange() - }).catch((err) => { - this.loading = false - this.errorMessage = err - }) - }, - _loadNodeData(callback, pw) { - if (this.loading) { - return - } - this.loading = true - - this.getCommand({ - field: this.postField, - where: pw || this._postWhere(), - pageSize: 500 - }).then((res) => { - this.loading = false - callback(res.result.data) - this.onDataChange() - }).catch((err) => { - this.loading = false - this.errorMessage = err - }) - }, - _pathWhere() { - let result = [] - let where_field = this._getParentNameByField(); - if (where_field) { - result.push(`${where_field} == '${this.dataValue}'`) - } - - if (this.where) { - return `(${this.where}) && (${result.join(' || ')})` - } - - return result.join(' || ') - }, - _postWhere() { - 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(' && ') - }, - _nodeWhere() { - let result = [] - let selected = this.selected - if (selected.length) { - result.push(`${this.parentField} == '${selected[selected.length - 1].value}'`) - } - - if (this.where) { - return `(${this.where}) && (${result.join(' || ')})` - } - - return result.join(' || ') - }, - _getParentNameByField() { - const fields = this.field.split(','); - let where_field = 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') { - where_field = items[0].trim(); - break; - } - } - return where_field - }, - _isTreeView() { - return (this.parentField && this.selfField) - }, - _updateSelected() { - var dl = this.dataList - var sl = this.selected - let textField = this.map.text - let valueField = this.map.value - for (var i = 0; i < sl.length; i++) { - var value = sl[i].value - var dl2 = dl[i] - for (var j = 0; j < dl2.length; j++) { - var item2 = dl2[j] - if (item2[valueField] === value) { - sl[i].text = item2[textField] - break - } - } - } - }, - _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 - } - }, - _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++) { - var value = paths[i].value - var 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 [] - }, - _processLocalData() { - this._treeData = [] - this._extractTree(this.localdata, this._treeData) - - var 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) - } - } -} diff --git a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue b/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue deleted file mode 100644 index 56cb09c..0000000 --- a/uni_modules/uni-data-picker/components/uni-data-pickerview/uni-data-pickerview.vue +++ /dev/null @@ -1,333 +0,0 @@ - - - - diff --git a/uni_modules/uni-data-picker/package.json b/uni_modules/uni-data-picker/package.json deleted file mode 100644 index 188ea73..0000000 --- a/uni_modules/uni-data-picker/package.json +++ /dev/null @@ -1,92 +0,0 @@ -{ - "id": "uni-data-picker", - "displayName": "uni-data-picker 数据驱动的picker选择器", - "version": "1.0.1", - "description": "单列、多列级联选择器,常用于省市区城市选择、公司部门选择、多级分类等场景", - "keywords": [ - "uni-ui", - "uniui", - "picker", - "级联", - "省市区", - "" -], - "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-load-more", - "uni-icons", - "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" - } - } - } - } -} \ No newline at end of file diff --git a/uni_modules/uni-data-picker/readme.md b/uni_modules/uni-data-picker/readme.md deleted file mode 100644 index 6cda224..0000000 --- a/uni_modules/uni-data-picker/readme.md +++ /dev/null @@ -1,22 +0,0 @@ -## DataPicker 级联选择 -> **组件名:uni-data-picker** -> 代码块: `uDataPicker` -> 关联组件:`uni-data-pickerview`、`uni-load-more`。 - - -`` 是一个选择类[datacom组件](https://uniapp.dcloud.net.cn/component/datacom)。 - -支持单列、和多列级联选择。列数没有限制,如果屏幕显示不全,顶部tab区域会左右滚动。 - -候选数据支持一次性加载完毕,也支持懒加载,比如示例图中,选择了“北京”后,动态加载北京的区县数据。 - -`` 组件尤其适用于地址选择、分类选择等选择类。 - -`` 支持本地数据、云端静态数据(json),uniCloud云数据库数据。 - -`` 可以通过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 \ No newline at end of file diff --git a/uni_modules/uni-datetime-picker/changelog.md b/uni_modules/uni-datetime-picker/changelog.md deleted file mode 100644 index 381c9a8..0000000 --- a/uni_modules/uni-datetime-picker/changelog.md +++ /dev/null @@ -1,85 +0,0 @@ -## 2.2.2(2021-12-10) -- 修复 clear-icon 属性在小程序平台不生效的 bug -## 2.2.1(2021-12-10) -- 修复 日期范围选在小程序平台,必须多点击一次才能取消选中状态的 bug -## 2.2.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-datetime-picker](https://uniapp.dcloud.io/component/uniui/uni-datetime-picker) -## 2.1.5(2021-11-09) -- 新增 提供组件设计资源,组件样式调整 -## 2.1.4(2021-09-10) -- 修复 hide-second 在移动端的 bug -- 修复 单选赋默认值时,赋值日期未高亮的 bug -- 修复 赋默认值时,移动端未正确显示时间的 bug -## 2.1.3(2021-09-09) -- 新增 hide-second 属性,支持只使用时分,隐藏秒 -## 2.1.2(2021-09-03) -- 优化 取消选中时(范围选)直接开始下一次选择, 避免多点一次 -- 优化 移动端支持清除按钮,同时支持通过 ref 调用组件的 clear 方法 -- 优化 调整字号大小,美化日历界面 -- 修复 因国际化导致的 placeholder 失效的 bug -## 2.1.1(2021-08-24) -- 新增 支持国际化 -- 优化 范围选择器在 pc 端过宽的问题 -## 2.1.0(2021-08-09) -- 新增 适配 vue3 -## 2.0.19(2021-08-09) -- 新增 支持作为 uni-forms 子组件相关功能 -- 修复 在 uni-forms 中使用时,选择时间报 NAN 错误的 bug -## 2.0.18(2021-08-05) -- 修复 type 属性动态赋值无效的 bug -- 修复 ‘确认’按钮被 tabbar 遮盖 bug -- 修复 组件未赋值时范围选左、右日历相同的 bug -## 2.0.17(2021-08-04) -- 修复 范围选未正确显示当前值的 bug -- 修复 h5 平台(移动端)报错 'cale' of undefined 的 bug -## 2.0.16(2021-07-21) -- 新增 return-type 属性支持返回 date 日期对象 -## 2.0.15(2021-07-14) -- 修复 单选日期类型,初始赋值后不在当前日历的 bug -- 新增 clearIcon 属性,显示框的清空按钮可配置显示隐藏(仅 pc 有效) -- 优化 移动端移除显示框的清空按钮,无实际用途 -## 2.0.14(2021-07-14) -- 修复 组件赋值为空,界面未更新的 bug -- 修复 start 和 end 不能动态赋值的 bug -- 修复 范围选类型,用户选择后再次选择右侧日历(结束日期)显示不正确的 bug -## 2.0.13(2021-07-08) -- 修复 范围选择不能动态赋值的 bug -## 2.0.12(2021-07-08) -- 修复 范围选择的初始时间在一个月内时,造成无法选择的bug -## 2.0.11(2021-07-08) -- 优化 弹出层在超出视窗边缘定位不准确的问题 -## 2.0.10(2021-07-08) -- 修复 范围起始点样式的背景色与今日样式的字体前景色融合,导致日期字体看不清的 bug -- 优化 弹出层在超出视窗边缘被遮盖的问题 -## 2.0.9(2021-07-07) -- 新增 maskClick 事件 -- 修复 特殊情况日历 rpx 布局错误的 bug,rpx -> px -- 修复 范围选择时清空返回值不合理的bug,['', ''] -> [] -## 2.0.8(2021-07-07) -- 新增 日期时间显示框支持插槽 -## 2.0.7(2021-07-01) -- 优化 添加 uni-icons 依赖 -## 2.0.6(2021-05-22) -- 修复 图标在小程序上不显示的 bug -- 优化 重命名引用组件,避免潜在组件命名冲突 -## 2.0.5(2021-05-20) -- 优化 代码目录扁平化 -## 2.0.4(2021-05-12) -- 新增 组件示例地址 -## 2.0.3(2021-05-10) -- 修复 ios 下不识别 '-' 日期格式的 bug -- 优化 pc 下弹出层添加边框和阴影 -## 2.0.2(2021-05-08) -- 修复 在 admin 中获取弹出层定位错误的bug -## 2.0.1(2021-05-08) -- 修复 type 属性向下兼容,默认值从 date 变更为 datetime -## 2.0.0(2021-04-30) -- 支持日历形式的日期+时间的范围选择 - > 注意:此版本不向后兼容,不再支持单独时间选择(type=time)及相关的 hide-second 属性(时间选可使用内置组件 picker) -## 1.0.6(2021-03-18) -- 新增 hide-second 属性,时间支持仅选择时、分 -- 修复 选择跟显示的日期不一样的 bug -- 修复 chang事件触发2次的 bug -- 修复 分、秒 end 范围错误的 bug -- 优化 更好的 nvue 适配 diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue deleted file mode 100644 index b57610f..0000000 --- a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar-item.vue +++ /dev/null @@ -1,185 +0,0 @@ - - - - - diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue deleted file mode 100644 index c48a096..0000000 --- a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/calendar.vue +++ /dev/null @@ -1,898 +0,0 @@ - - - - - diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json deleted file mode 100644 index cc76311..0000000 --- a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/en.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "uni-datetime-picker.selectDate": "select date", - "uni-datetime-picker.selectTime": "select time", - "uni-datetime-picker.selectDateTime": "select datetime", - "uni-datetime-picker.startDate": "start date", - "uni-datetime-picker.endDate": "end date", - "uni-datetime-picker.startTime": "start time", - "uni-datetime-picker.endTime": "end time", - "uni-datetime-picker.ok": "ok", - "uni-datetime-picker.clear": "clear", - "uni-datetime-picker.cancel": "cancel", - "uni-calender.MON": "MON", - "uni-calender.TUE": "TUE", - "uni-calender.WED": "WED", - "uni-calender.THU": "THU", - "uni-calender.FRI": "FRI", - "uni-calender.SAT": "SAT", - "uni-calender.SUN": "SUN" -} diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js deleted file mode 100644 index de7509c..0000000 --- a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/index.js +++ /dev/null @@ -1,8 +0,0 @@ -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 -} diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json deleted file mode 100644 index 7bc7405..0000000 --- a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hans.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "uni-datetime-picker.selectDate": "选择日期", - "uni-datetime-picker.selectTime": "选择时间", - "uni-datetime-picker.selectDateTime": "选择日期时间", - "uni-datetime-picker.startDate": "开始日期", - "uni-datetime-picker.endDate": "结束日期", - "uni-datetime-picker.startTime": "开始时间", - "uni-datetime-picker.endTime": "结束时间", - "uni-datetime-picker.ok": "确定", - "uni-datetime-picker.clear": "清除", - "uni-datetime-picker.cancel": "取消", - "uni-calender.SUN": "日", - "uni-calender.MON": "一", - "uni-calender.TUE": "二", - "uni-calender.WED": "三", - "uni-calender.THU": "四", - "uni-calender.FRI": "五", - "uni-calender.SAT": "六" -} diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json deleted file mode 100644 index 7d37043..0000000 --- a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/i18n/zh-Hant.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "uni-datetime-picker.selectDate": "選擇日期", - "uni-datetime-picker.selectTime": "選擇時間", - "uni-datetime-picker.selectDateTime": "選擇日期時間", - "uni-datetime-picker.startDate": "開始日期", - "uni-datetime-picker.endDate": "結束日期", - "uni-datetime-picker.startTime": "開始时间", - "uni-datetime-picker.endTime": "結束时间", - "uni-datetime-picker.ok": "確定", - "uni-datetime-picker.clear": "清除", - "uni-datetime-picker.cancel": "取消", - "uni-calender.SUN": "日", - "uni-calender.MON": "一", - "uni-calender.TUE": "二", - "uni-calender.WED": "三", - "uni-calender.THU": "四", - "uni-calender.FRI": "五", - "uni-calender.SAT": "六" -} diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/keypress.js b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/keypress.js deleted file mode 100644 index 9601aba..0000000 --- a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/keypress.js +++ /dev/null @@ -1,45 +0,0 @@ -// #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 \ No newline at end of file diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue deleted file mode 100644 index 699aa63..0000000 --- a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/time-picker.vue +++ /dev/null @@ -1,927 +0,0 @@ - - - - - diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue deleted file mode 100644 index e844331..0000000 --- a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue +++ /dev/null @@ -1,981 +0,0 @@ - - - - diff --git a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js b/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js deleted file mode 100644 index efa5773..0000000 --- a/uni_modules/uni-datetime-picker/components/uni-datetime-picker/util.js +++ /dev/null @@ -1,410 +0,0 @@ -class Calendar { - constructor({ - date, - selected, - startDate, - endDate, - range, - // multipleStatus - } = {}) { - // 当前日期 - this.date = this.getDate(new Date()) // 当前初入日期 - // 打点信息 - this.selected = selected || []; - // 范围开始 - this.startDate = startDate - // 范围结束 - this.endDate = endDate - this.range = range - // 多选状态 - this.cleanMultipleStatus() - // 每周日期 - this.weeks = {} - // this._getWeek(this.date.fullDate) - // this.multipleStatus = multipleStatus - this.lastHover = false - } - /** - * 设置日期 - * @param {Object} date - */ - setDate(date) { - this.selectDate = this.getDate(date) - this._getWeek(this.selectDate.fullDate) - } - - /** - * 清理多选状态 - */ - cleanMultipleStatus() { - this.multipleStatus = { - before: '', - after: '', - data: [] - } - } - - /** - * 重置开始日期 - */ - resetSatrtDate(startDate) { - // 范围开始 - this.startDate = startDate - - } - - /** - * 重置结束日期 - */ - resetEndDate(endDate) { - // 范围结束 - this.endDate = endDate - } - - /** - * 获取任意时间 - */ - getDate(date, AddDayCount = 0, str = 'day') { - if (!date) { - date = new Date() - } - if (typeof date !== 'object') { - date = date.replace(/-/g, '/') - } - const dd = new Date(date) - switch (str) { - case 'day': - dd.setDate(dd.getDate() + AddDayCount) // 获取AddDayCount天后的日期 - break - case 'month': - if (dd.getDate() === 31) { - dd.setDate(dd.getDate() + AddDayCount) - } else { - dd.setMonth(dd.getMonth() + AddDayCount) // 获取AddDayCount天后的日期 - } - break - case 'year': - dd.setFullYear(dd.getFullYear() + AddDayCount) // 获取AddDayCount天后的日期 - break - } - const y = dd.getFullYear() - const m = dd.getMonth() + 1 < 10 ? '0' + (dd.getMonth() + 1) : dd.getMonth() + 1 // 获取当前月份的日期,不足10补0 - const d = dd.getDate() < 10 ? '0' + dd.getDate() : dd.getDate() // 获取当前几号,不足10补0 - return { - fullDate: y + '-' + m + '-' + d, - year: y, - month: m, - date: d, - day: dd.getDay() - } - } - - - /** - * 获取上月剩余天数 - */ - _getLastMonthDays(firstDay, full) { - let dateArr = [] - for (let i = firstDay; i > 0; i--) { - const beforeDate = new Date(full.year, full.month - 1, -i + 1).getDate() - dateArr.push({ - date: beforeDate, - month: full.month - 1, - disable: true - }) - } - return dateArr - } - /** - * 获取本月天数 - */ - _currentMonthDys(dateData, full) { - let dateArr = [] - let fullDate = this.date.fullDate - for (let i = 1; i <= dateData; i++) { - let isinfo = false - let nowDate = full.year + '-' + (full.month < 10 ? - full.month : full.month) + '-' + (i < 10 ? - '0' + i : i) - // 是否今天 - let isDay = fullDate === nowDate - // 获取打点信息 - let info = this.selected && this.selected.find((item) => { - if (this.dateEqual(nowDate, item.date)) { - return item - } - }) - - // 日期禁用 - let disableBefore = true - let disableAfter = true - if (this.startDate) { - // let dateCompBefore = this.dateCompare(this.startDate, fullDate) - // disableBefore = this.dateCompare(dateCompBefore ? this.startDate : fullDate, nowDate) - disableBefore = this.dateCompare(this.startDate, nowDate) - } - - if (this.endDate) { - // let dateCompAfter = this.dateCompare(fullDate, this.endDate) - // disableAfter = this.dateCompare(nowDate, dateCompAfter ? this.endDate : fullDate) - disableAfter = this.dateCompare(nowDate, this.endDate) - } - let multiples = this.multipleStatus.data - let checked = false - let multiplesStatus = -1 - if (this.range) { - if (multiples) { - multiplesStatus = multiples.findIndex((item) => { - return this.dateEqual(item, nowDate) - }) - } - if (multiplesStatus !== -1) { - checked = true - } - } - let data = { - fullDate: nowDate, - year: full.year, - date: i, - multiple: this.range ? checked : false, - beforeMultiple: this.isLogicBefore(nowDate, this.multipleStatus.before, this.multipleStatus.after), - afterMultiple: this.isLogicAfter(nowDate, this.multipleStatus.before, this.multipleStatus.after), - month: full.month, - disable: !(disableBefore && disableAfter), - isDay, - userChecked: false - } - if (info) { - data.extraInfo = info - } - - dateArr.push(data) - } - return dateArr - } - /** - * 获取下月天数 - */ - _getNextMonthDays(surplus, full) { - let dateArr = [] - for (let i = 1; i < surplus + 1; i++) { - dateArr.push({ - date: i, - month: Number(full.month) + 1, - disable: true - }) - } - return dateArr - } - - /** - * 获取当前日期详情 - * @param {Object} date - */ - getInfo(date) { - if (!date) { - date = new Date() - } - const dateInfo = this.canlender.find(item => item.fullDate === this.getDate(date).fullDate) - return dateInfo - } - - /** - * 比较时间大小 - */ - dateCompare(startDate, endDate) { - // 计算截止时间 - startDate = new Date(startDate.replace('-', '/').replace('-', '/')) - // 计算详细项的截止时间 - endDate = new Date(endDate.replace('-', '/').replace('-', '/')) - if (startDate <= endDate) { - return true - } else { - return false - } - } - - /** - * 比较时间是否相等 - */ - dateEqual(before, after) { - // 计算截止时间 - before = new Date(before.replace('-', '/').replace('-', '/')) - // 计算详细项的截止时间 - after = new Date(after.replace('-', '/').replace('-', '/')) - if (before.getTime() - after.getTime() === 0) { - return true - } else { - return false - } - } - - /** - * 比较真实起始日期 - */ - - isLogicBefore(currentDay, before, after) { - let logicBefore = before - if (before && after) { - logicBefore = this.dateCompare(before, after) ? before : after - } - return this.dateEqual(logicBefore, currentDay) - } - - isLogicAfter(currentDay, before, after) { - let logicAfter = after - if (before && after) { - logicAfter = this.dateCompare(before, after) ? after : before - } - return this.dateEqual(logicAfter, currentDay) - } - - /** - * 获取日期范围内所有日期 - * @param {Object} begin - * @param {Object} end - */ - geDateAll(begin, end) { - var arr = [] - var ab = begin.split('-') - var ae = end.split('-') - var db = new Date() - db.setFullYear(ab[0], ab[1] - 1, ab[2]) - var de = new Date() - de.setFullYear(ae[0], ae[1] - 1, ae[2]) - var unixDb = db.getTime() - 24 * 60 * 60 * 1000 - var unixDe = de.getTime() - 24 * 60 * 60 * 1000 - for (var k = unixDb; k <= unixDe;) { - k = k + 24 * 60 * 60 * 1000 - arr.push(this.getDate(new Date(parseInt(k))).fullDate) - } - return arr - } - - /** - * 获取多选状态 - */ - setMultiple(fullDate) { - let { - before, - after - } = this.multipleStatus - if (!this.range) return - if (before && after) { - if (!this.lastHover) { - this.lastHover = true - return - } - this.multipleStatus.before = fullDate - this.multipleStatus.after = '' - this.multipleStatus.data = [] - this.multipleStatus.fulldate = '' - this.lastHover = false - } else { - if (!before) { - this.multipleStatus.before = fullDate - this.lastHover = false - } else { - this.multipleStatus.after = fullDate - if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) { - this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus - .after); - } else { - this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus - .before); - } - this.lastHover = true - } - } - this._getWeek(fullDate) - } - - /** - * 鼠标 hover 更新多选状态 - */ - setHoverMultiple(fullDate) { - let { - before, - after - } = this.multipleStatus - - if (!this.range) return - if (this.lastHover) return - - if (!before) { - this.multipleStatus.before = fullDate - } else { - this.multipleStatus.after = fullDate - if (this.dateCompare(this.multipleStatus.before, this.multipleStatus.after)) { - this.multipleStatus.data = this.geDateAll(this.multipleStatus.before, this.multipleStatus.after); - } else { - this.multipleStatus.data = this.geDateAll(this.multipleStatus.after, this.multipleStatus.before); - } - } - this._getWeek(fullDate) - } - - /** - * 更新默认值多选状态 - */ - setDefaultMultiple(before, after) { - this.multipleStatus.before = before - this.multipleStatus.after = after - if (before && after) { - if (this.dateCompare(before, after)) { - this.multipleStatus.data = this.geDateAll(before, after); - this._getWeek(after) - } else { - this.multipleStatus.data = this.geDateAll(after, before); - this._getWeek(before) - } - } - } - - /** - * 获取每周数据 - * @param {Object} dateData - */ - _getWeek(dateData) { - const { - fullDate, - year, - month, - date, - day - } = this.getDate(dateData) - let firstDay = new Date(year, month - 1, 1).getDay() - let currentDay = new Date(year, month, 0).getDate() - let dates = { - lastMonthDays: this._getLastMonthDays(firstDay, this.getDate(dateData)), // 上个月末尾几天 - currentMonthDys: this._currentMonthDys(currentDay, this.getDate(dateData)), // 本月天数 - nextMonthDays: [], // 下个月开始几天 - weeks: [] - } - let canlender = [] - const surplus = 42 - (dates.lastMonthDays.length + dates.currentMonthDys.length) - dates.nextMonthDays = this._getNextMonthDays(surplus, this.getDate(dateData)) - canlender = canlender.concat(dates.lastMonthDays, dates.currentMonthDys, dates.nextMonthDays) - let weeks = {} - // 拼接数组 上个月开始几天 + 本月天数+ 下个月开始几天 - for (let i = 0; i < canlender.length; i++) { - if (i % 7 === 0) { - weeks[parseInt(i / 7)] = new Array(7) - } - weeks[parseInt(i / 7)][i % 7] = canlender[i] - } - this.canlender = canlender - this.weeks = weeks - } - - //静态方法 - // static init(date) { - // if (!this.instance) { - // this.instance = new Calendar(date); - // } - // return this.instance; - // } -} - - -export default Calendar diff --git a/uni_modules/uni-datetime-picker/package.json b/uni_modules/uni-datetime-picker/package.json deleted file mode 100644 index 5e0ff11..0000000 --- a/uni_modules/uni-datetime-picker/package.json +++ /dev/null @@ -1,90 +0,0 @@ -{ - "id": "uni-datetime-picker", - "displayName": "uni-datetime-picker 日期选择器", - "version": "2.2.2", - "description": "uni-datetime-picker 日期时间选择器,支持日历,支持范围选择", - "keywords": [ - "uni-datetime-picker", - "uni-ui", - "uniui", - "日期时间选择器", - "日期时间" -], - "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", - "uni-icons" - ], - "encrypt": [], - "platforms": { - "cloud": { - "tcb": "y", - "aliyun": "y" - }, - "client": { - "App": { - "app-vue": "y", - "app-nvue": "n" - }, - "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" - } - } - } - } -} diff --git a/uni_modules/uni-datetime-picker/readme.md b/uni_modules/uni-datetime-picker/readme.md deleted file mode 100644 index 162fbef..0000000 --- a/uni_modules/uni-datetime-picker/readme.md +++ /dev/null @@ -1,21 +0,0 @@ - - -> `重要通知:组件升级更新 2.0.0 后,支持日期+时间范围选择,组件 ui 将使用日历选择日期,ui 变化较大,同时支持 PC 和 移动端。此版本不向后兼容,不再支持单独的时间选择(type=time)及相关的 hide-second 属性(时间选可使用内置组件 picker)。若仍需使用旧版本,可在插件市场下载*非uni_modules版本*,旧版本将不再维护` - -## DatetimePicker 时间选择器 - -> **组件名:uni-datetime-picker** -> 代码块: `uDatetimePicker` - - -该组件的优势是,支持**时间戳**输入和输出(起始时间、终止时间也支持时间戳),可**同时选择**日期和时间。 - -若只是需要单独选择日期和时间,不需要时间戳输入和输出,可使用原生的 picker 组件。 - -**_点击 picker 默认值规则:_** - -- 若设置初始值 value, 会显示在 picker 显示框中 -- 若无初始值 value,则初始值 value 为当前本地时间 Date.now(), 但不会显示在 picker 显示框中 - -### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-datetime-picker) -#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 \ No newline at end of file diff --git a/utils/index.js b/utils/index.js new file mode 100644 index 0000000..47671e3 --- /dev/null +++ b/utils/index.js @@ -0,0 +1,109 @@ +import env from '@/env/index.js' +import store from '@/store/index.js' +/** + * 日期格式化,样例 yyyy-mm-dd hh:MM:ss + * @param date Date 需要转换的日期 + * @param fmt string 转化的格式 + */ +export const dateTimeFormat = (date, fmt) => { + if (!date) { + throw new Error('日期不正确') + } + let ret + const opt = { + 'y+': date.getFullYear().toString(), // 年 + 'm+': (date.getMonth() + 1).toString(), // 月 + 'd+': date.getDate().toString(), // 日 + 'h+': date.getHours().toString(), // 时 + 'M+': date.getMinutes().toString(), // 分 + 's+': date.getSeconds().toString() // 秒 + } + for (let k in opt) { + ret = new RegExp('(' + k + ')').exec(fmt) + if (ret) { + fmt = fmt.replace(ret[1], ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, '0')) + } + } + return fmt +} + +/** + * 创建websocket + * @param {*} data + * @value {string} pageInfo 页面信息 + * @value {true} retry 是否重连,默认false + * @returns 一个websocket实例 + */ +export const makeSocket = async ({ pageInfo = '', retry = false }) => { + const socket = { + sockTask: null, + close: function () { + this.sockTask.close({ code: 1000 }) + closeFlag = true + }, + onMessage: function () {} + } + + let limitedNum = 0 + let closeFlag = false + let timer = null + + async function createSocket() { + let url = '' + if (env == 'production') { + url = 'wss://api-client-yyt.qniao.cn/qn-websocket-service/wechatwebsock?token=' + } else if (env == 'test') { + url = 'wss://api-client-yyt-test.qniao.cn/qn-websocket-service/wechatwebsock?token=' + } + const token = store.state.qnToken + const socketTask = await uni.connectSocket({ + url: `${url}${token}`, + header: { + 'content-type': 'application/json' + }, + success: () => { + console.log('websocket连接成功') + }, + fail: () => { + console.log('websocket连接失败') + } + }) + socketTask.onOpen(() => { + console.log(pageInfo + ' onOpen') + timer = setInterval(() => { + socketTask.send({ data: 'ping' }) + }, 10000) + }) + socketTask.onClose(() => { + console.log(pageInfo + ' onClose') + clearInterval(timer) + timer = null + if (!closeFlag && retry && limitedNum < 20) { + limitedNum++ + console.log('重连次数:' + limitedNum) + createSocket() + } + }) + + socketTask.onError(() => { + console.log(pageInfo + ' error') + }) + + socket.sockTask = socketTask + } + + await createSocket() + if (socket) { + socket.onMessage = (fn) => { + socket.sockTask.onMessage((res) => { + let data = JSON.parse(res.data) + console.log(pageInfo + '接收到消息:', data) + if (data.type != 'heartbeat') { + fn(data) + } + }) + } + } + + return socket +}