commit 89db955ec1d2ebfdeebceb9dda6d548782e1706e Author: YeMingfei666 <1619116647@qq.com> Date: Wed Apr 2 10:35:17 2025 +0800 first diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..54f54aa --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +unpackage/cache +unpackage/dist +unpackage/res +unpackage/resources +node_modules/ +/node_modules/ +" " +" " diff --git a/.hbuilderx/launch.json b/.hbuilderx/launch.json new file mode 100644 index 0000000..179fe2d --- /dev/null +++ b/.hbuilderx/launch.json @@ -0,0 +1,23 @@ +{ + // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/ + // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数 + "version" : "0.0", + "configurations" : [ + { + "app-plus" : { + "launchtype" : "local" + }, + "default" : { + "launchtype" : "local" + }, + "mp-weixin" : { + "launchtype" : "local" + }, + "type" : "uniCloud" + }, + { + "playground" : "custom", + "type" : "uni-app:app-android" + } + ] +} diff --git a/App.vue b/App.vue new file mode 100644 index 0000000..b13a8f6 --- /dev/null +++ b/App.vue @@ -0,0 +1,166 @@ + + + \ No newline at end of file diff --git a/androidPrivacy.json b/androidPrivacy.json new file mode 100644 index 0000000..b58f517 --- /dev/null +++ b/androidPrivacy.json @@ -0,0 +1,27 @@ +{ + "version" : "1", + "prompt" : "template", + "title" : "服务协议和隐私政策", + "message" : "  请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。
  你可阅读《服务协议》《隐私政策》了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。", + "buttonAccept" : "同意并接受", + "buttonRefuse" : "暂不同意", + "second" : { + "title" : "确认提示", + "message" : "  进入应用前,你需先同意《服务协议》《隐私政策》,否则将退出应用。", + "buttonAccept" : "同意并继续", + "buttonRefuse" : "退出应用" + }, + "styles" : { + "backgroundColor" : "#FFFFFF", + "borderRadius" : "5px", + "title" : { + "color" : "#262626" + }, + "buttonAccept" : { + "color" : "#3981FF" + }, + "buttonRefuse" : { + "color" : "#A6A6A6" + } + } +} diff --git a/commons/$data.js b/commons/$data.js new file mode 100644 index 0000000..a5f997a --- /dev/null +++ b/commons/$data.js @@ -0,0 +1,8 @@ +let statusHeight=44 +// #ifdef H5 +statusHeight=0 +// #endif +// #ifndef H5 +statusHeight=22 +// #endif +export const customNavHeight=statusHeight \ No newline at end of file diff --git a/commons/JSON/mccAli.json b/commons/JSON/mccAli.json new file mode 100644 index 0000000..3b4fed6 --- /dev/null +++ b/commons/JSON/mccAli.json @@ -0,0 +1 @@ +[{"children":[{"msg":"","text":"火锅","value":"B0199"},{"msg":"","text":"中式正餐","value":"B0001"},{"msg":"","text":"西式正餐","value":"B0002"},{"msg":"","text":"日韩/东南亚菜","value":"B0003"},{"msg":"","text":"中式快餐","value":"B0004"},{"msg":"","text":"西式快餐","value":"B0005"},{"msg":"","text":"小吃/熟食","value":"B0006"},{"msg":"申请成为该行业商家,请提交:1. 商户与企业团餐合作协议或者2. 合作资质证明扫描件","text":"校园团餐","value":"B0007"},{"msg":"申请成为该行业商家,请提交:1. 商户与企业团餐合作协议或者2. 合作资质证明扫描件","text":"综合团餐","value":"B0008"},{"msg":"","text":"饮品/甜品","value":"B0009"},{"msg":"","text":"烘焙糕点","value":"B0010"},{"msg":"","text":"酒吧/清吧","value":"B0011"},{"msg":"","text":"咖啡馆/茶馆","value":"B0012"},{"msg":"","text":"宴会提供商","value":"B0200"},{"msg":"","text":"订餐服务平台","value":"B0117"}],"text":"餐饮","value":"A0001"},{"children":[{"msg":"","text":"小型商店","value":"B0013"},{"msg":"","text":"连锁便利店","value":"B0014"},{"msg":"","text":"大型超市","value":"B0015"},{"msg":"","text":"大卖场","value":"B0016"},{"msg":"","text":"百货商场","value":"B0017"},{"msg":"","text":"购物中心","value":"B0018"},{"msg":"","text":"奥特莱斯","value":"B0019"},{"msg":"","text":"商业街","value":"B0020"},{"msg":"","text":"水果店","value":"B0021"},{"msg":"","text":"食品零售","value":"B0201"},{"msg":"","text":"蔬菜/肉蛋/水产","value":"B0202"},{"msg":"","text":"茶叶","value":"B0022"},{"msg":"申请成为该行业商家,请提交:1. 《酒类经营许可证》或者2. 《酒类销售许可证》","text":"酒类","value":"B0023"},{"msg":"申请成为该行业商家,请提交:1. 《烟草专卖零售许可证》或者2. 《烟草专卖批发企业许可证》或者3. 《烟草专卖生产企业许可证》","text":"烟草/雪茄","value":"B0024"},{"msg":"","text":"营养品/保健品","value":"B0025"},{"msg":"","text":"服饰鞋包","value":"B0026"},{"msg":"","text":"美妆个护","value":"B0027"},{"msg":"","text":"黄金珠宝/钟表饰品","value":"B0028"},{"msg":"","text":"眼镜店","value":"B0029"},{"msg":"","text":"3C数码/家用电器","value":"B0030"},{"msg":"","text":"办公用品","value":"B0203"},{"msg":"","text":"图文音像/工美乐器","value":"B0031"},{"msg":"申请成为该行业商家,请提交:1. 《营业执照》","text":"母婴用品/儿童玩具","value":"B0032"},{"msg":"","text":"宠物/宠物用品","value":"B0033"},{"msg":"","text":"户外运动器材","value":"B0034"},{"msg":"","text":"五金建材","value":"B0035"},{"msg":"","text":"家居家纺","value":"B0216"},{"msg":"","text":"鲜花/绿植","value":"B0036"},{"msg":"申请成为该行业商家,请提交:1. 《文物复制品销售许可证》或者2. 《文物复制许可证》或者3. 《文物经营许可证》","text":"文物经营/文物复制品","value":"B0037"},{"msg":"","text":"计生用品","value":"B0038"},{"msg":"申请成为该行业商家,请提交:1. 《烟花爆竹安全生产许可证》或者2. 《烟花爆竹经营(零售)许可证》或者3. 《烟花爆竹经营(批发)许可证》或者4. 《烟花爆竹经营批发(含进出口)许可证》","text":"烟花爆竹","value":"B0039"},{"msg":"申请成为该行业商家,请提交:1. 《危险化学品经营许可证》","text":"危险化工产品","value":"B0040"},{"msg":"申请成为该行业商家,请提交:1. 《成品油零售经营批准证书》或者2. 营业执照经营范围包含销售/批发汽油、煤油、柴油、天然气、成品油、加油卡、加油服务","text":"石油及石油产品","value":"B0041"},{"msg":"","text":"工业产品","value":"B0042"},{"msg":"","text":"其他专业零售店","value":"B0043"},{"msg":"","text":"互联网综合电商平台","value":"B0114"},{"msg":"","text":"互联网垂直电商平台","value":"B0115"},{"msg":"","text":"社区团购服务平台","value":"B0118"}],"text":"零售批发","value":"A0002"},{"children":[{"msg":"","text":"美发/美容/美甲服务","value":"B0044"},{"msg":"","text":"洗浴/保健养生服务","value":"B0045"},{"msg":"","text":"家政/清洁服务","value":"B0046"},{"msg":"","text":"电器/家具/其他维修","value":"B0047"},{"msg":"","text":"建筑装饰/装修服务","value":"B0048"},{"msg":"","text":"地产/房屋中介代理","value":"B0049"},{"msg":"","text":"宠物医院/其他宠物服务","value":"B0050"},{"msg":"","text":"数码/娱乐设备租赁","value":"B0051"},{"msg":"","text":"无人值守自助服务","value":"B0052"},{"msg":"","text":"共享充电宝及其他共享租赁","value":"B0212"},{"msg":"","text":"无人值守自助零售","value":"B0213"},{"msg":"","text":"无人值守自助娱乐","value":"B0214"},{"msg":"","text":"婚介/婚庆/摄影服务","value":"B0053"},{"msg":"","text":"广告/会展/图文印刷","value":"B0054"},{"msg":"申请成为该行业商家,请提交:1. 《律师事务所执业许可证》","text":"法律咨询/律师事务所","value":"B0055"},{"msg":"","text":"会计/金融咨询服务","value":"B0056"},{"msg":"申请成为该行业商家,请提交:1. 营业执照经营范围包含企业征信业务和人民银行官网关于公司获取企业征信相关资质公示截图","text":"征信和信用报告咨询服务","value":"B0057"},{"msg":"","text":"人才招聘服务","value":"B0058"},{"msg":"申请成为该行业商家,请提交:1. 《殡葬服务经营许可证》","text":"丧葬服务","value":"B0059"},{"msg":"申请成为该行业商家,请提交:1. 《拍卖经营批准证书》或者2. 营业执照经营范围包含销售/批发汽油、煤油、柴油、天然气、成品油、加油卡、加油服务","text":"拍卖/收藏","value":"B0060"},{"msg":"","text":"其他商业及生活服务","value":"B0061"},{"msg":"","text":"默认行业","value":"B0223"},{"msg":"","text":"生活服务平台","value":"B0116"},{"msg":"","text":"在线工具","value":"B0112"},{"msg":"","text":"物业管理","value":"B0165"}],"text":"商业生活服务","value":"A0003"},{"children":[{"msg":"","text":"歌舞厅/休闲会所/KTV","value":"B0062"},{"msg":"","text":"棋牌桌游/电玩网吧","value":"B0063"},{"msg":"","text":"健身房/瑜伽/舞蹈","value":"B0064"},{"msg":"","text":"院线影城/演出赛事","value":"B0065"},{"msg":"","text":"游乐园/嘉年华","value":"B0066"},{"msg":"","text":"文化场馆","value":"B0067"},{"msg":"","text":"体育场馆","value":"B0068"},{"msg":"申请成为该行业商家,请提交:1. 《彩票销售许可证》","text":"彩票","value":"B0069"},{"msg":"","text":"其他文体娱乐","value":"B0070"},{"msg":"","text":"网络社交","value":"B0108"},{"msg":"申请成为该行业商家,请提交:1. 《网络文化经营许可证》且 营业执照经营范围明确包含相关内容或者2. 《互联网出版许可证》且 营业执照经营范围明确包含相关内容","text":"网络图书/视频/音乐","value":"B0109"},{"msg":"申请成为该行业商家,请提交:1. 《网络文化经营许可证》或者2. 营业执照经营范围包含网络游戏制作、经营、销售、系统服务、技术、计算机、通讯设备、电子产品、互联网、网络技术、网络工程等任意一项业务","text":"游戏","value":"B0110"},{"msg":"申请成为该行业商家,请提交:1. 《网络文化经营许可证》","text":"游戏周边服务/交易平台","value":"B0205"},{"msg":"申请成为该行业商家,请提交:1. 《网络文化经营许可证》且 营业执照经营范围明确包含相关内容","text":"网络直播","value":"B0111"}],"text":"休闲娱乐","value":"A0004"},{"children":[{"msg":"","text":"车辆零配件/用品精品","value":"B0071"},{"msg":"","text":"汽车洗美/维修养护","value":"B0072"},{"msg":"","text":"车辆销售","value":"B0073"},{"msg":"","text":"二手车销售","value":"B0074"},{"msg":"","text":"停车服务","value":"B0075"},{"msg":"","text":"代驾服务","value":"B0076"},{"msg":"申请成为该行业商家,请提交:1. 营业执照经营范围包含:电瓶车充电,电动车充电相关关键字","text":"电动汽车充换电","value":"B0077"},{"msg":"申请成为该行业商家,请提交:1. 营业执照经营范围包含:电瓶车充电,电动车充电相关关键字","text":"两轮电瓶车充换电","value":"B0078"},{"msg":"","text":"汽车租赁","value":"B0079"},{"msg":"申请成为该行业商家,请提交:1. 营业执照经营范围包含公路的投资、建设、收费、养护、管理、高速公路开发经营及服务","text":"ETC不停车自动缴费","value":"B0080"},{"msg":"申请成为该行业商家,请提交:1. 营业执照经营范围包含公路的投资、建设、收费、养护、管理、高速公路开发经营及服务","text":"MTC半自动车道收费","value":"B0081"},{"msg":"","text":"高速服务区","value":"B0082"},{"msg":"","text":"道路救援","value":"B0083"}],"text":"车主生活","value":"A0005"},{"children":[{"msg":"","text":"公路客运","value":"B0084"},{"msg":"申请成为该行业商家,请提交:1. 《道路运输经营许可证》或者2. 《出租车营运证》","text":"出租车客运","value":"B0085"},{"msg":"","text":"网约车客运","value":"B0086"},{"msg":"申请成为该行业商家,请提交:1. 营业执照经营范围包含地铁、轻轨、轨道交通服务 ","text":"地铁","value":"B0087"},{"msg":"申请成为该行业商家,请提交:1. 营业执照经营范围包含公共汽车、客运、公交服务","text":"公共交通","value":"B0088"},{"msg":"","text":"共享两轮车服务","value":"B0089"},{"msg":"申请成为该行业商家,请提交:1. 《成品油零售经营批准证书》或者2. 《燃气经营许可证》或者3. 营业执照经营范围包含销售/批发汽油、煤油、柴油、天然气、成品油、加油卡、加油服务","text":"加油卡、加油服务","value":"B0090"},{"msg":"申请成为该行业商家,请提交:1. 《成品油零售经营批准证书》或者2. 《燃气经营许可证》","text":"加油站、加气站","value":"B0091"},{"msg":"申请成为该行业商家,请提交:1. 《公共航空运输企业经营许可证》","text":"航空公司","value":"B0097"},{"msg":"","text":"机场","value":"B0098"},{"msg":"申请成为该行业商家,请提交:1. 《中国民用航空运输销售代理业务资格认可证书》或2、经营范围包含代售机票业务","text":"机票代理人","value":"B0099"},{"msg":"","text":"航空系统商","value":"B0100"},{"msg":"申请成为该行业商家,请提交:1. 营业执照经营范围包含铁路运输服务","text":"铁路旅客运输","value":"B0101"},{"msg":"","text":"游轮及巡游航线服务","value":"B0102"}],"text":"交通出行","value":"A0006"},{"children":[{"msg":"申请成为该行业商家,请提交:1. 营业执照经营范围包含物流、货运、仓储、集装箱等相关业务或者2. 《道路运输经营许可证》或者3. 《IATA航空货代资质》或者4. 《无船承运业务经营资格登记证》","text":"物流/快递","value":"B0092"},{"msg":"","text":"快递服务(个人商户)","value":"B0093"},{"msg":"","text":"物流平台","value":"B0217"},{"msg":"","text":"同城即时配送","value":"B0218"},{"msg":"申请成为该行业商家,请提交:1. 关键字匹配,商户名称包含:***邮政管理局(非快递公司,中国邮政不属于国家邮政) ","text":"邮政基本服务","value":"B0094"},{"msg":"","text":"驿站/自提柜","value":"B0095"},{"msg":"申请成为该行业商家,请提交:1. 营业执照经营范围包含物流、货运、仓储、集装箱等相关业务","text":"仓储","value":"B0096"},{"msg":"申请成为该行业商家,请提交:1. 营业执照经营范围包含铁路运输服务","text":"铁路货物运输","value":"B0103"},{"msg":"申请成为该行业商家,请提交:1. 《水路运输许可证》或者2. 营业执照内包含水运、船舶、海运的经营范围或客运船票的相关资质","text":"船舶、海运服务提供商","value":"B0104"},{"msg":"","text":"货品停放交易(国际专用)","value":"B0105"},{"msg":"","text":"国际货运代理和报关行","value":"B0106"},{"msg":"","text":"其他运输代理业","value":"B0107"}],"text":"物流运输","value":"A0015"},{"children":[{"msg":"","text":"信息检索服务/网络论坛","value":"B0113"},{"msg":"","text":"互联网数据服务","value":"B0120"},{"msg":"","text":"软件开发服务","value":"B0121"},{"msg":"","text":"数字类产品-游戏(国际专用)","value":"B0122"},{"msg":"","text":"数字类产品-软件提供商(国际专用)","value":"B0123"},{"msg":"","text":"数字类产品-其他(国际专用)","value":"B0124"},{"msg":"","text":"其他在线应用或综合类服务","value":"B0125"},{"msg":"","text":"网络推广/网络广告","value":"B0126"},{"msg":"申请成为该行业商家,请提交:1. 《电信业务经营许可证》或者2. 与运营商的合作协议","text":"电信运营商","value":"B0127"},{"msg":"申请成为该行业商家,请提交:1. 《信息网络传播视听节目许可证》","text":"付费电视","value":"B0128"},{"msg":"","text":"网络电话、传真服务","value":"B0129"}],"text":"网络通讯","value":"A0007"},{"children":[{"msg":"申请成为该行业商家,请提交:1. 教育行政部门出具的审批设立证明或者2. 《事业单位法人证书》","text":"儿童保育服务(公立,含学前教育)","value":"B0130"},{"msg":"申请成为该行业商家,请提交:1. 《民办学校办学许可证》","text":"儿童保育服务(民办,含学前教育)","value":"B0131"},{"msg":"申请成为该行业商家,请提交:1. 教育行政部门出具的审批设立证明或者2. 《事业单位法人证书》","text":"中小学校(公立)","value":"B0132"},{"msg":"申请成为该行业商家,请提交:1. 《民办学校办学许可证》","text":"中小学校(民办)","value":"B0133"},{"msg":"申请成为该行业商家,请提交:1. 教育行政部门出具的审批设立证明或者2. 《事业单位法人证书》","text":"大学与学院(公立)","value":"B0134"},{"msg":"申请成为该行业商家,请提交:1. 《民办学校办学许可证》","text":"大学与学院(民办)","value":"B0135"},{"msg":"申请成为该行业商家,请提交:1. 《事业单位法人证书》或者2. 《民办学校办学许可证》","text":"其他学校/公立培训机构","value":"B0136"},{"msg":"","text":"教育管理机构","value":"B0215"},{"msg":"申请成为该行业商家,请提交:1. 营业执照经营范围包含:培训、辅导、教育、咨询、活动策划、体育赛事组织策划、健康管理等业务","text":"教育培训机构","value":"B0137"},{"msg":"申请成为该行业商家,请提交:1. 《事业单位法人证书》或者2. 《民办非企业单位登记证书》","text":"少年宫及青少年发展中心","value":"B0138"},{"msg":"","text":"其他教育/培训","value":"B0139"}],"text":"教育培训","value":"A0008"},{"children":[{"msg":"申请成为该行业商家,请提交:1. 《药品经营许可证》或者2. 《互联网药品交易服务证》","text":"医药销售","value":"B0140"},{"msg":"申请成为该行业商家,请提交:1. 营业执照经营范围包含一类医疗器械或者2. 《第二类医疗器械经营备案凭证》或者3. 《医疗器械经营企业许可证》","text":"医疗器械销售","value":"B0141"},{"msg":"申请成为该行业商家,请提交:1. 营业执照经营范围包含一类医疗器械或者2. 《第二类医疗器械经营备案凭证》或者3. 《医疗器械经营企业许可证》或者4. 《互联网药品交易服务证》","text":"保健辅助治疗器材","value":"B0142"},{"msg":"申请成为该行业商家,请提交:1. 《医疗机构执业许可证》和《事业单位法人证书》","text":"公立医院","value":"B0143"},{"msg":"申请成为该行业商家,请提交:1. 《医疗机构执业许可证》","text":"社区卫生服务中心","value":"B0144"},{"msg":"申请成为该行业商家,请提交:1. 《医疗机构执业许可证》或者2. 《事业单位法人证书》中业务范围包含公共卫生","text":"专业公共卫生机构","value":"B0145"},{"msg":"申请成为该行业商家,请提交:1. 《医疗机构执业许可证》","text":"民营医院","value":"B0146"},{"msg":"申请成为该行业商家,请提交:1. 《医疗机构执业许可证》或者2. 《中医诊所备案证》","text":"诊所","value":"B0147"},{"msg":"申请成为该行业商家,请提交:1. 《执业医师资格证》","text":"个体医生","value":"B0148"},{"msg":"申请成为该行业商家,请提交:1. 《医疗机构执业许可证》","text":"医疗美容","value":"B0149"},{"msg":"申请成为该行业商家,请提交:1. 《医疗机构执业许可证》","text":"眼科医疗服务","value":"B0150"},{"msg":"申请成为该行业商家,请提交:1. 《医疗机构执业许可证》","text":"口腔医疗服务","value":"B0151"},{"msg":"申请成为该行业商家,请提交:1. 《医疗机构执业许可证》","text":"医学实验室及诊断中心","value":"B0152"},{"msg":"申请成为该行业商家,请提交:1. 银监会关于同意开展消费金融业务的批复或者2. 该协议医院的《医疗机构执业许可证》","text":"线上医疗服务","value":"B0153"},{"msg":"","text":"护理机构服务","value":"B0154"},{"msg":"申请成为该行业商家,请提交:1. 《医疗机构执业许可证》或者2. 营业执照经营范围包含“健康咨询”","text":"体检/健康咨询","value":"B0155"},{"msg":"申请成为该行业商家,请提交:1. 《医疗机构执业许可证》","text":"其他医疗保健服务","value":"B0156"}],"text":"医疗卫生","value":"A0009"},{"children":[{"msg":"","text":"酒店/旅馆/民宿","value":"B0157"},{"msg":"申请成为该行业商家,请提交:1. 营业执照经营范围包含:旅游","text":"景区","value":"B0158"},{"msg":"申请成为该行业商家,请提交:1. 《旅行社业务经营许可证》或者2. 《旅行社分社备案登记证明》或者3. 《旅行社业务经营许可证》经营范围中须包含出境旅游业务","text":"旅行社和旅游服务","value":"B0159"},{"msg":"申请成为该行业商家,请提交:1. 旅游相关:直销商户授权书、直销员资质或业务代理资质","text":"旅游相关服务直销","value":"B0160"},{"msg":"","text":"风景区系统商","value":"B0219"},{"msg":"","text":"观光车","value":"B0220"},{"msg":"","text":"游船码头","value":"B0221"},{"msg":"","text":"旅游服务平台(OTA)","value":"B0119"}],"text":"酒旅景区","value":"A0010"},{"children":[{"msg":"申请成为该行业商家,请提交:1. 营业执照经营范围包含公共事业的水、电、煤(燃)气等经营和收费相关业务或者2. 非实际水、电、煤等机构来签约,则需要提供水电煤服务提供商授权资质","text":"公共事业(电、气、水)","value":"B0161"},{"msg":"申请成为该行业商家,请提交:1. 营业执照经营范围包含公共事业的电力经营和收费相关业务或者2. 非实际电力机构来签约,则需要提供电力服务提供商授权资质","text":"公共事业-电力缴费","value":"B0204"},{"msg":"申请成为该行业商家,请提交:1. 营业执照经营范围包含公共事业的煤(燃)气经营和收费相关业务或者2. 非实际煤(燃)气经营机构来签约,则需要提供煤(燃)气服务提供商授权资质","text":"公共事业-煤气缴费","value":"B0211"},{"msg":"申请成为该行业商家,请提交:1. 营业执照经营范围包含公共事业的自来水经营和收费相关业务或者2. 非实际自来水经营机构来签约,则需要提供自来水服务提供商授权资质","text":"公共事业-自来水缴费","value":"B0206"},{"msg":"申请成为该行业商家,请提交:1. 营业执照范围包含广播电视节目策划、制作、经营、有线电视相关业务","text":"公共事业-有线电视缴费","value":"B0162"},{"msg":"","text":"公共事业-清洁服务缴费","value":"B0207"},{"msg":"","text":"公共事业-其他缴费","value":"B0163"},{"msg":"","text":"话费充值与缴费","value":"B0164"}],"text":"生活缴费","value":"A0011"},{"children":[{"msg":"申请成为该行业商家,请提交:1. 《金融许可证》或者2. 银监会关于同意开展个人贷款业务的批复或者3. 银监会关于同意开展信用卡业务的批复或者4. 银监会关于同意贵司的开业批复","text":"金融机构","value":"B0166"},{"msg":"申请成为该行业商家,请提交:1. 《金融许可证》或者2. 银监会关于同意开展对应业务的批复或开业批复或者3. 金融办关于同意开展对应业务的批复或开业批复或者4. 银行资质存管协议或与持牌金融机构的合作协议","text":"金融机构-其他服务","value":"B0167"},{"msg":"申请成为该行业商家,请提交:1. 《金融许可证》或者2. 《经营保险业务许可证》或者3. 《经营外汇业务许可证》或者4. 《个人本外币兑换特许业务经营许可证》","text":"外币汇兑","value":"B0168"},{"msg":"申请成为该行业商家,请提交:1. 《经营证券期货业务许可证》或者2. 证监会关于同意开展证券经营业务的批复、证监会及其派出机构颁布的基金类业务相关资格证书","text":"股票基金服务","value":"B0169"},{"msg":"申请成为该行业商家,请提交:1. 《小额贷款公司经营许可证》或者2. 金融办关于同意该公司(名称中带“小额贷款”字样)开业的批复","text":"小贷公司","value":"B0170"},{"msg":"申请成为该行业商家,请提交:1. 与持牌的消费金融公司、小贷公司、银行等持牌机构的业务合作协议,且协议内容需要体现平台用户的放款由对应合作机构发放。注:若最终资金端未体现直接合作,则需补充提交与合作方最终资金端的合作协议。","text":"借贷消费平台","value":"B0171"},{"msg":"申请成为该行业商家,请提交:1. 《金融许可证》或者2. 银监会关于同意开展融资租赁业务的批复","text":"融资租赁公司","value":"B0172"},{"msg":"申请成为该行业商家,请提交:1. 《金融许可证》或者2. 银监会关于同意开展金融租赁业务的批复","text":"金融租赁公司","value":"B0173"},{"msg":"申请成为该行业商家,请提交:1. 《金融许可证》或者2. 银监会关于同意开展汽车金融业务的批复","text":"汽车金融公司","value":"B0174"},{"msg":"申请成为该行业商家,请提交:1. 《金融许可证》或者2. 银监会关于同意开展消费金融业务的批复","text":"消费金融公司","value":"B0175"},{"msg":"申请成为该行业商家,请提交:1. 《金融许可证》或者2. 银监会关于同意开展信托业务的批复","text":"信托公司","value":"B0176"},{"msg":"申请成为该行业商家,请提交:1. 《支付业务许可证》(中国人民银行颁发)","text":"支付机构","value":"B0177"},{"msg":"申请成为该行业商家,请提交:1. 《融资性担保机构经营许可证》或者2. 金融办关于同意该公司(名称含有“融资担保”字样)开业的批复","text":"融资担保公司","value":"B0178"},{"msg":"","text":"其他金融服务","value":"B0179"},{"msg":"申请成为该行业商家,请提交:1. 《保险公司法人许可证》或者2. 《经营保险业务许可证》或者3. 《保险营销服务许可证》或者4. 《经营保险代理业务许可证》或者5. 《经营保险经纪业务许可证》或者6. 《经营保险公估业务许可证》或者7. 《保险兼业代理业务许可证》或者8. 保险资产管理:直销商户授权书、直销员资质或业务代理资质","text":"保险业务/保险代理","value":"B0180"},{"msg":"申请成为该行业商家,请提交:1. 《典当经营许可证》","text":"典当","value":"B0181"}],"text":"金融理财","value":"A0012"},{"children":[{"msg":"申请成为该行业商家,请提交:1. 关键字匹配,商户名称包含:***财政局(厅)/公安局(厅)/行政执法队/警察总队/人民政府(办公厅、室)/***人力资源和社会保障****中心(局、办公室)/***公积金管理中心/***医保局/**医疗保障局","text":"政府机构","value":"B0182"},{"msg":"申请成为该行业商家,请提交:1. 关键字匹配,商户名称包含:***财政局(厅)/公安局(厅)/行政执法队/警察总队","text":"行政费用和罚款(非税)","value":"B0183"},{"msg":"申请成为该行业商家,请提交:1. 关键字匹配,商户名称包含:***财政局(厅)/公安局(厅)/行政执法队/警察总队/人民政府(办公厅、室)/***人力资源和社会保障****中心(局、办公室)/***公积金管理中心","text":"公积金","value":"B0184"},{"msg":"申请成为该行业商家,请提交:1. 关键字匹配,商户名称包含:公安局(厅)/行政执法队/警察总队","text":"公安交管","value":"B0185"},{"msg":"申请成为该行业商家,请提交:1. 关键字匹配,商户名称包含:***医保局/**医疗保障局","text":"医保","value":"B0186"},{"msg":"申请成为该行业商家,请提交:1. 关键字匹配,商户名称包含:社会保障,常见名称为:***人力资源和社会保障****中心/局/办公室","text":"社会保障服务","value":"B0187"},{"msg":"申请成为该行业商家,请提交:1. 关键字匹配,商户名称包含:***财政局(厅)/公安局(厅)/行政执法队/警察总队/人民政府(办公厅、室)/***人力资源和社会保障****中心(局、办公室)/***公积金管理中心","text":"政府采购","value":"B0188"},{"msg":"","text":"文体机构","value":"B0222"},{"msg":"","text":"政府贷款","value":"B0189"},{"msg":"申请成为该行业商家,请提交:1. 关键字匹配,商户名称包含:***法院","text":"法庭费用","value":"B0190"},{"msg":"申请成为该行业商家,请提交:1. 关键字匹配,商户名称包含:***公安局(厅)","text":"保释金","value":"B0191"},{"msg":"申请成为该行业商家,请提交:1. 关键字匹配,商户名称包含:***税务局","text":"税务","value":"B0192"},{"msg":"申请成为该行业商家,请提交:1. 《社会团体法人证书》或者2. 《民办非企业单位登记证书》且业务范围包含公益/慈善/捐赠/捐款/志愿服务/扶贫/社会工作","text":"慈善和社会公益服务","value":"B0193"},{"msg":"申请成为该行业商家,请提交:1. 关键字匹配,商户名称包含:*****驻华大使馆","text":"使领馆","value":"B0194"},{"msg":"申请成为该行业商家,请提交:1. 《社会团体法人证书》","text":"行业协会和专业社团","value":"B0195"},{"msg":"","text":"汽车协会","value":"B0196"},{"msg":"申请成为该行业商家,请提交:1. 《宗教活动场所登记证》","text":"宗教组织","value":"B0197"},{"msg":"","text":"其他会员组织","value":"B0198"},{"msg":"","text":"中国共产党机关","value":"B0208"}],"text":"公共管理和社会组织","value":"A0013"},{"children":[{"msg":"","text":"集团行业","value":"B0209"}],"text":"集团类目","value":"A0014"}] \ No newline at end of file diff --git a/commons/class/list.js b/commons/class/list.js new file mode 100644 index 0000000..ee1e210 --- /dev/null +++ b/commons/class/list.js @@ -0,0 +1,48 @@ +import { + reactive, ref +} from 'vue'; +function isSameType(a, b) { + return a instanceof b === true || b instanceof a === true; +} +class LIST{ + constructor(data) { + this.data=reactive({ + page:0, + totalPage:0, + total:0, + list:[], + hasAjax:false, + status:'',//loading fail success + query:{ + + } + }) + Object.assign(this.data, data) + } + add(item){ + this.data.list.push(item) + } + del(index){ + this.data.list.splice(index,1) + } + update(index,item){ + this.data.list[index]=item + } + get(index){ + return this.data.list[index] + } + getVal(key){ + return this.data[key] + } + setQuery(key,val){ + this.data.query[key]=val + } + setVal(key,val){ + this.data[key]=val + if(key=='page'){ + this.data['page']=val + } + } +} + +export default LIST \ No newline at end of file diff --git a/commons/color.js b/commons/color.js new file mode 100644 index 0000000..5987b9e --- /dev/null +++ b/commons/color.js @@ -0,0 +1,7 @@ +export const ColorMain= '#318AFE'; +export const ColorRed= '#F02C45'; + + +export default{ + ColorMain,ColorRed +} diff --git a/commons/goodsData.js b/commons/goodsData.js new file mode 100644 index 0000000..3fa480a --- /dev/null +++ b/commons/goodsData.js @@ -0,0 +1,74 @@ +import dayjs from "dayjs"; +export const $types = [{ + title: "计量商品", + desc: '单价购买', + value: 'normal' + }, + { + title: "多规格", + desc: '多种不同规格', + value: 'sku' + }, + { + title: "套餐组合", + desc: '选择多种组合', + value: 'group' + }, + { + title: "称重商品", + desc: '按重量售卖', + value: 'weight' + }, + { + title: "时价商品", + desc: '收银端可更改价格', + value: 'currentPrice' + } +] + +// 商品默认sku +export const $defaultSku = { + salePrice: '', + memberPrice: '', + costPrice: '', + originPrice: '', + // stockNumber: '', + firstShared: '', + suit: 1, + barCode: `${uni.getStorageSync("shopId")}${dayjs().valueOf()}`, +} + + +// 库存记录筛选类型 +export const $invoicingType = [{ + text: '全部', + value: '' + }, + { + text: '供应商入库', + value: 'purveyor' + }, + { + text: '供应商退货', + value: 'reject' + }, + { + text: '其他入库', + value: 'purchase' + }, + { + text: '其他出库', + value: 'other-out' + } +] + +// 页面常用数据 +export const $pageData = { + query: { + page: 0, + size: 10 + }, + totalElements: 0, + list: [], + hasAjax: false, +} \ No newline at end of file diff --git a/commons/orderEnum.js b/commons/orderEnum.js new file mode 100644 index 0000000..c472261 --- /dev/null +++ b/commons/orderEnum.js @@ -0,0 +1,84 @@ +export default { + status: [ + { + key: 'unpaid', + label: '待支付' + }, + { + key: 'unsend', + label: '待发货' + }, + { + key: 'closed', + label: '订单完成' + }, + { + key: 'send', + label: '已发' + }, + { + key: 'refunding', + label: '申请退单' + }, + { + key: 'refund', + label: '退单' + }, + { + key: 'cancelled', + label: '取消订单' + }, + { + key: 'merge', + label: '合台' + }, + { + key: 'pending', + label: '挂单' + }, + { + key: 'activate', + label: '激活' + }, + { + key: 'paying', + label: '支付中' + } + ], + sendType: [ + { + key: 'post', + label: '快递' + }, + { + key: 'takeaway', + label: '外卖' + }, + { + key: 'takeself', + label: '自提' + }, + { + key: 'table', + label: '堂食' + } + ], + orderType: [ + { + key: 'cash', + label: '收银' + }, + { + key: 'miniapp', + label: '小程序' + }, + { + key: 'offline', + label: '线下' + }, + { + key: 'return', + label: '退单' + } + ] +} \ No newline at end of file diff --git a/commons/readme.txt b/commons/readme.txt new file mode 100644 index 0000000..592624a --- /dev/null +++ b/commons/readme.txt @@ -0,0 +1,14 @@ +该文件夹内放置: 项目自建资源, 比如 公共样式文件, 和 工具包等文件。 + + +目录结构: +commons + style + utils + +知识点: 样式文件不应该放置到 static文件夹内(css、less/scss 等资源不要放在 static 目录下,建议这些公用的资源放在自建的 common 目录下。), 详见: +https://uniapp.dcloud.net.cn/tutorial/project.html + + + + diff --git a/commons/style/common.scss b/commons/style/common.scss new file mode 100644 index 0000000..b6b3ec8 --- /dev/null +++ b/commons/style/common.scss @@ -0,0 +1,406 @@ +.u-relative, +.u-rela { + position: relative; +} + +.u-absolute, +.u-abso { + position: absolute; +} +.u-fixed,.u-fix{ + position: fixed; +} +.left-top{ + left: 0; + top: 0; +} +.u-overflow-hide{ + overflow: hidden; +} + +// nvue不能用标签命名样式,不能放在微信组件中,否则微信开发工具会报警告,无法使用标签名当做选择器 +/* #ifndef APP-NVUE */ +image { + display: inline-block; +} + +// 在weex,也即nvue中,所有元素默认为border-box +view, +text { + box-sizing: border-box; +} +/* #endif */ + +.u-font-xs { + font-size: 22rpx; +} + +.u-font-sm { + font-size: 26rpx; +} + +.u-font-md { + font-size: 28rpx; +} + +.u-font-lg { + font-size: 30rpx; +} + +.u-font-xl { + font-size: 34rpx; +} + +.u-flex { + /* #ifndef APP-NVUE */ + display: flex; + /* #endif */ + flex-direction: row; + align-items: center; +} + +.u-flex-wrap { + flex-wrap: wrap; +} + +.u-flex-nowrap { + flex-wrap: nowrap; +} + +.u-col-center { + align-items: center; +} + +.u-col-top { + align-items: flex-start; +} + +.u-col-bottom { + align-items: flex-end; +} + +.u-row-center { + justify-content: center; +} + +.u-row-left { + justify-content: flex-start; +} + +.u-row-right { + justify-content: flex-end; +} + +.u-row-between { + justify-content: space-between; +} + +.u-row-around { + justify-content: space-around; +} + +.u-text-left { + text-align: left; +} + +.u-text-center { + text-align: center; +} + +.u-text-right { + text-align: right; +} + +.u-flex-col { + /* #ifndef APP-NVUE */ + display: flex!important; + /* #endif */ + flex-direction: column!important; +} + +// 定义flex等分 +@for $i from 0 through 12 { + .u-flex-#{$i} { + flex: $i; + } +} + +// 定义字体(px)单位,小于20都为px单位字体 +@for $i from 9 to 20 { + .u-font-#{$i} { + font-size: $i + px; + } +} + +// 定义字体(rpx)单位,大于或等于20的都为rpx单位字体 +@for $i from 20 through 40 { + .u-font-#{$i} { + font-size: $i + rpx; + } +} + +// 定义内外边距,历遍1-80 +@for $i from 0 through 80 { + // 只要双数和能被5除尽的数 + @if $i % 2 == 0 or $i % 5 == 0 { + // 得出:u-margin-30或者u-m-30 + .u-margin-#{$i}, .u-m-#{$i} { + margin: $i + rpx!important; + } + + // 得出:u-padding-30或者u-p-30 + .u-padding-#{$i}, .u-p-#{$i} { + padding: $i + rpx!important; + } + + @each $short, $long in l left, t top, r right, b bottom { + // 缩写版,结果如: u-m-l-30 + // 定义外边距 + .u-m-#{$short}-#{$i} { + margin-#{$long}: $i + rpx!important; + } + + // 定义内边距 + .u-p-#{$short}-#{$i} { + padding-#{$long}: $i + rpx!important; + } + + // 完整版,结果如:u-margin-left-30 + // 定义外边距 + .u-margin-#{$long}-#{$i} { + margin-#{$long}: $i + rpx!important; + } + + // 定义内边距 + .u-padding-#{$long}-#{$i} { + padding-#{$long}: $i + rpx!important; + } + } + } +} + +// 重置nvue的默认关于flex的样式 +.u-reset-nvue { + flex-direction: row; + align-items: center; +} + +/* start--文本行数限制--start */ +.u-line-1 { + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.u-line-2 { + -webkit-line-clamp: 2; +} + +.u-line-3 { + -webkit-line-clamp: 3; +} + +.u-line-4 { + -webkit-line-clamp: 4; +} + +.u-line-5 { + -webkit-line-clamp: 5; +} + +.u-line-2, .u-line-3, .u-line-4, .u-line-5 { + overflow: hidden; + word-break: break-all; + text-overflow: ellipsis; + display: -webkit-box; // 弹性伸缩盒 + -webkit-box-orient: vertical; // 设置伸缩盒子元素排列方式 +} + +/* end--文本行数限制--end */ + + +/* start--不同颜色文字--start */ +.color-333{ + color: #333; +} +.color-666{ + color: #666; +} +.color-999{ + color: #999; +} +.color-red{ + color: $my-red-color; +} +.color-main{ + color:$my-main-color +} + +/* end--不同颜色文字--end */ + + +.tranistion{ + transition: all .3s ease-in-out; +} +.tranistion-1{ + transition: all .1s ease-in-out; +} +.tranistion-2{ + transition: all .2s ease-in-out; +} +.font-bold{ + font-weight: 700; +} + + +/* start--不同颜色背景--start */ +.my-bg-main{ + background-color:$my-main-color +} + +/* end--不同颜色背景--end */ + +.safe-page{ + padding-bottom: 60rpx!important; +} +::v-deep .uni-switch-input.uni-switch-input-checked{ + border-color: $my-main-color; + background-color: $my-main-color; +} +.min-page{ + /* #ifdef H5 */ + min-height: calc(100vh - 44px); + /* #endif */ + /* #ifndef H5 */ + min-height: 100vh; + /* #endif */ +} +.w-full{ + width: 100%; +} +.gap-20{ + gap: 20rpx; +} +.color-000{ + color: #000; +} +.color-fff{ + color: #fff; +} +.bg-fff{ + background-color: #fff; +} +.bg-gray{ + background-color: #F9F9F9; +} +.overflow-hide{ + /* #ifdef H5 */ + height: calc(100vh - 44px); + /* #endif */ + /* #ifndef H5 */ + height: 100vh; + /* #endif */ + overflow: hidden; +} +.no-wrap{ + white-space: nowrap; +} +.border-r-12{ + border-radius: 12rpx; +} +.border-r-18{ + border-radius: 18rpx; +} +.border-top{ + border-top: 1px solid #E5E5E5; +} +.border-bottom{ + border-bottom: 1px solid #E5E5E5; +} +.scale7{ + transform: scale(0.7); +} +.page-gray { + min-height: calc(100vh); + /* #ifdef H5 */ + min-height: calc(100vh - var(--window-top)); + /* #endif */ + display: flex; + flex-direction: column; + background: #F9F9F9; +} +.box-shadow{ + box-shadow: 0 0 5px #eee; +} +.safe-bottom{ + padding-bottom: env(safe-area-inset-bottom); + /* #ifdef H5 */ + padding-bottom: 28rpx; + /* #endif */ +} +.position-all{ + left: 0; + right: 0; + top: 0; + bottom: 0; +} +.fixed-top{ + position: fixed; + /* #ifdef H5 */ + top: 44px; + /* #endif */ + /* #ifndef H5 */ + top: 0; + /* #endif */ + left: 0; + right: 0; +} +.lh30 { + line-height: 30px; +} +.default-box-padding{ + padding: 32rpx 28rpx; +} +.icon-arrow-down-fill { + width: 16rpx; + height: 10rpx; +} +.zIndex-999{ + z-index: 999; +} +.icon-default-size{ + width: 28rpx; + height: 28rpx; +} +::v-deep.uni-easyinput__placeholder-class{ + font-size: 28rpx!important; +} +.filter-gray{ + filter: grayscale(1); +} +// .u-font-20{ +// font-size: 10px; +// } +// .u-font-24{ +// font-size: 12px; +// } +// .u-font-28{ +// font-size: 14px; +// } +// .u-font-32{ +// font-size: 16px; +// } +.line-th{ + text-decoration: line-through; +} +//覆盖u-view-plus 颜色 +.u-primary-light { + color: $my-main-color; +} +::v-deep .u-border{ + border-width: 1px!important; +} + +::v-deep .u-m-t-16 .u-textarea{ + border-width: 1px!important; +} \ No newline at end of file diff --git a/commons/style/global.scss b/commons/style/global.scss new file mode 100644 index 0000000..a3e94e8 --- /dev/null +++ b/commons/style/global.scss @@ -0,0 +1,230 @@ +/** + * 系统级别: 全局样式 + * + * @site https://www.jeequan.com + * @date 2022/11/22 07:29 + */ + +/** 已整理 **/ + + +// 通用 列表页样式 +.page-wrapper { + min-height: calc(100vh - 70rpx); /** 最小高度 **/ + padding-bottom: 70rpx; /** 安全距离(防止home条遮挡文字) **/ + background-color: $v-color-bgrey; /** 全局背景灰 **/ +} + +// 底部 固定的按钮, 比如: 创建门店, 创建员工等按钮。 +.list-footer{ + height: 100rpx; + background: transparent; + .button-wrapper { + border-top: 1rpx solid rgba(0,0,0, 0.07); + background-color: rgba(252, 252, 252, 0.85); + backdrop-filter: blur(20rpx); + position: fixed; + left: 0; + right: 0; + bottom: 0; + padding: 30rpx; + } +} + + +/** 详情页 覆写:list-item */ +.list-item-by-detail { + padding: 60rpx 60rpx 10rpx 60rpx !important; + background-color: transparent !important; /** 背景透明 **/ + .list-title{ + color: #fff !important; + } + .list-subtitle{ + color: rgba(251,252,253,0.7) !important; + } + .list-info { + image { + margin-right: 0 !important; + } + } +} + +/**列表条目渲染, 比如: 头像、 主标题, **/ +.list-item { + display: flex; + align-items: center; + padding: 0 40rpx; + height: 170rpx; + background-color: #FFF; /** 背景 白色 **/ + image { + flex-shrink: 0; + flex-grow: 0; + width: 100rpx; + height: 100rpx; + margin-right: 30rpx; + } + .list-info { + flex: 1; + .list-title { + display: flex; + justify-content: space-between; + align-items: center; + height: 40rpx; + color: rgba(77,77,77,1); + .list-name { + width: auto; + flex: 1; + display: flex; + align-items: center; + font-size: 30rpx; + font-weight: 400; + } + } + .list-subtitle { + color: rgba(153, 153, 153, 1); + margin-top: 25rpx; + font-size: 26rpx; + font-weight: 400; + width: 430rpx; + } + } +} + + +/** 状态小圆点 **/ +.state-dot { + display: flex; + align-items: center; + font-size: 30rpx; + font-weight: 400; + &::after { + content: ''; + display: block; + margin-left: 20rpx; + width: 20rpx; + height: 20rpx; + border-radius: 50%; + } +} + +/** 状态小圆点 **/ +.state-dot-enable { + &::after { + background-color: #168FFF; + } + +} + +/** 状态小圆点 **/ +.state-dot-disable { + &::after { + background-color: #D9D9D9; + } +} + +/** 状态小圆点 **/ +.state-dot-error { + &::after { + background-color: red; + } +} + + +/** + * 描述预览图, 参考: app详情 + * 第一个最后一个距离上下 40rpx, 中间间距20rpx + */ +.desc-view { + .desc-view-item { + display: flex; + justify-content: space-between; + padding: 20rpx 40rpx; + font-size: 30rpx; + font-weight: 400; + + .title { + color: #808080; + } + .desc { + color: #000; + } + + &:first-child { + margin-top: 20rpx; + } + &:last-child { + margin-bottom: 20rpx; + } + } +} + +/** 已整理 **/ + + + + +//容器内部元素上下左右居中 +.flex-center { + display: flex; + justify-content: center; + align-items: center; +} +// 触摸反馈样式 +.touch-hover { + background-color: #f7f8fa !important ; +} +.touch-button { + opacity: 0.5; +} +/* 单行文本超出省略号 */ +.single-text-beyond { + overflow: hidden; /*超出部分隐藏*/ + white-space: nowrap; /*禁止换行*/ + text-overflow: ellipsis; /*省略号*/ +} +// 按钮背景样式 +.footer-button-style { + border-top: 1rpx solid #fcfcfc; + background-color: rgba(252, 252, 252, 0.85); + backdrop-filter: blur(20rpx); +} +// 搜素框 提示语样式 +.input-placeholder { + font-size: 32rpx; + color: rgba(0, 0, 0, 0.35); +} + + +// 表单分割线 +.line { + height: 20rpx; + background-color: $v-color-bgrey; +} + + + +/** + * jeepay-btn 通用btn样式。 + * 用法: + */ +.jeepay-btn { + display: flex; + justify-content: center; + align-items: center; + height: 110rpx; + font-size: 33rpx; + font-weight: 500; + color: $J-color-tff; + border-radius: 20rpx; + background: linear-gradient(270deg, rgba(35,143,252,1) 0%, rgba(26,102,255,1) 100%); + box-shadow: 0 20rpx 60rpx -20rpx rgba(0,84,210,0.5); + &.hover-button { + opacity: 0.5; + } +} + +/** 输入框icon **/ +.input-icon{ + width: 36rpx; + height: 36rpx; +} diff --git a/commons/style/ipad.scss b/commons/style/ipad.scss new file mode 100644 index 0000000..0070a1c --- /dev/null +++ b/commons/style/ipad.scss @@ -0,0 +1,4 @@ +.login-wrapper{ + .login-bottom{ + } +} \ No newline at end of file diff --git a/commons/style/reset-uni-form.scss b/commons/style/reset-uni-form.scss new file mode 100644 index 0000000..a78d604 --- /dev/null +++ b/commons/style/reset-uni-form.scss @@ -0,0 +1,6 @@ +::v-deep .uni-easyinput__content-input{ +height: initial; +} +::v-deep .uni-forms-item{ + min-height: initial; +} diff --git a/commons/style/uni-overwrite.scss b/commons/style/uni-overwrite.scss new file mode 100644 index 0000000..94b7fb7 --- /dev/null +++ b/commons/style/uni-overwrite.scss @@ -0,0 +1,181 @@ +/** + * 系统级别:覆写 uni样式 + * + * @site https://www.jeequan.com + * @date 2022/11/22 07:29 + */ + + + + +/* 去除开关右侧边距 */ +.uni-switch-input { + margin-right: 0 !important; +} + +/* .uni-navbar { + position: relative; + z-index: 10; +} */ +.uni-popup{ + z-index: 998 !important; +} +// 表单组件样式 覆写 +.uni-forms-item { + display: flex; + align-items: center; + min-height: 120rpx; + background-color: $J-bg-ff; + font-size: 32rpx; + font-weight: 400; +} +.uni-forms-item ::v-deep .uni-forms-item__label { + font-size: 32rpx !important; + font-weight: 400; + text-indent: 40rpx; + color: #4d4d4d; + height: auto !important; +} + +// uni-form-item 表单校验, 如果校验不通过, 显示的文字占位, 并且添加下边距。 +.uni-forms-item__error.msg--active{ + position: relative !important; + margin-bottom: 30rpx; +} + + +.is-input-error-border .uni-easyinput__placeholder-class{ + color: #f56c6c !important +} + + +// 去掉按钮边框 +button:after { + border: none !important; +} + +// 去点导航栏组件center&right +::v-deep.uni-navbar__header { + .uni-navbar__header-container, + .uni-navbar__header-btns-right { + display: none !important; + } +} + +// 修改 uuni-easyinput +// form 外层必须包裹一个 view class="jeepay-form" +.jeepay-form { + .uni-easyinput { + .uni-easyinput__content { + border: 2px solid transparent !important; + height: 110rpx; + padding: 0 30rpx; + margin-bottom: 50rpx; + box-sizing: border-box !important; + border-radius: 20rpx !important; + background-color: rgba(247, 247, 247, 1) !important; + } + + .uni-easyinput__content-input { + color: rgba(0, 0, 0, 1); + font-size: 32rpx !important; + font-weight: 400; + } + + .is-foucs { + border: 2px solid #1d79fd !important; + background-color: white !important; + } + + .uni-input-placeholder + /* #ifdef MP-WEIXIN */ + ,.uni-easyinput__placeholder-class + /* #endif */ { + font-size: 32rpx !important; + color: #B3B3B3 !important; + } + } +} + +.jeepay-edit-form .uni-easyinput__content-input { + padding-left: 0 !important; + .uni-input-placeholder { + font-size: 32rpx !important; + } +} + +// 设置新密码覆盖form默认样式 +.new-password { + .uni-forms-item.is-direction-left { + padding: 0 40rpx; + .uni-forms-item__label { + width: 190rpx !important; + font-size: 32rpx !important; + font-weight: 400; + white-space: nowrap; + color: rgba(102, 102, 102, 1); + text-indent: 0 !important; + } + .uni-easyinput__placeholder-class { + font-size: 32rpx !important; + font-weight: 400 !important; + } + } +} + +// 搜索栏覆盖默认样式 +/* #ifdef MP-WEIXIN */ +.input-main { + button { + font-size: 32rpx; + color: rgba(29,121,253,1); + background: rgba(255,255,255,1); + } + .uni-easyinput { + .uni-easyinput__content { + background-color: $J-bg-f5 !important; + border-radius: $J-b-r12; + .uni-easyinput__content-input { + padding-left: 0 !important; + .uni-input-input { + border-radius: $J-b-r12 !important; + overflow: hidden !important; + } + } + .uni-input-placeholder { + font-size: 27rpx; + } + .uni-icons { + color: rgba(230,230,230,1) !important; + } + } + } +} +/* #endif */ + +// 搜索栏覆盖默认样式 +/* #ifdef MP-WEIXIN */ +button[is="components/Button/Button"] { + padding: 0; + background-color: transparent !important; +} +/* #endif */ + +// 修改时间选择器按钮颜色 +.xp-button--confirm { + background: $jeepay-bg-primary; +} +.xp-button--cancel { + color: rgba(0, 0, 0, 0.5) !important; +} +// label 样式 +.f-label{ + width: 280rpx; + align-self: start; + padding-top: 40rpx; + font-size: 32rpx ; + font-weight: 400; + text-indent: 40rpx; + color: #4d4d4d; +} + diff --git a/commons/style/vars.scss b/commons/style/vars.scss new file mode 100644 index 0000000..65ad362 --- /dev/null +++ b/commons/style/vars.scss @@ -0,0 +1,77 @@ +/** + * 系统级别: 自定义变量 + * + * @site https://www.jeequan.com + * @date 2022/11/22 07:29 + */ + +// $v : 表示: variables简写。 uni的默认都有特殊开头, 一般不会重复。 +$v-color-t21: #217dfe; + +// 全局通用: 背景灰 background grey +$v-color-bgrey: #F7F7F7; + +// 背景色 +$J-bg-f7: #f7f7f7; //页面背景色 +$J-bg-ff: #fff; +$J-bg-f5: #f5f5f5; //输入框背景色 + +// 文字颜色 +$J-color-t80: #808080; //常用于 未选中文字颜色 +$J-color-t21: #217dfe; //卡片文字选中 统计报表 +$J-color-tff: #fff; +$J-color-tSff: rgba(255, 255, 255, 0.7); +$J-color-t29: #2980fd; //选中 文字颜色 搜索 +$J-color-ta6: #a6a6a6; +$J-color-t4d: #4d4d4d; //标题颜色 +$J-color-t99: #999; +$J-color-t8c: #8c8c8c; // 卡片列表 标题文字颜色 +//圆角相关变量 +$J-b-r32: 32rpx; +$J-b-r12: 12rpx; +$J-b-r10: 10rpx; +$v-b-r20: 20rpx; + +// 文字大小 +$J-f-size30: 30rpx; + +// 常用边框颜色 +$v-b-color-ed: #ededed; + +//common.scss 分包页面以及组件里所用的颜色 +$my-main-color:#318AFE; +$my-red-color:#F02C45; + +//my-components +$u-main-color: #303133; +$u-content-color: #606266; +$u-tips-color: #909193; +$u-light-color: #c0c4cc; +$u-border-color: #dadbde; +$u-bg-color: #f3f4f6; +$u-disabled-color: #c8c9cc; + +$u-primary: #3c9cff; +$u-primary-dark: #398ade; +$u-primary-disabled: #9acafc; +$u-primary-light: #ecf5ff; + +$u-warning: #f9ae3d; +$u-warning-dark: #f1a532; +$u-warning-disabled: #f9d39b; +$u-warning-light: #fdf6ec; + +$u-success: #5ac725; +$u-success-dark: #53c21d; +$u-success-disabled: #a9e08f; +$u-success-light: #f5fff0; + +$u-error: #f56c6c; +$u-error-dark: #e45656; +$u-error-disabled: #f7b2b2; +$u-error-light: #fef0f0; + +$u-info: #909399; +$u-info-dark: #767a82; +$u-info-disabled: #c4c6c9; +$u-info-light: #f4f4f5; \ No newline at end of file diff --git a/commons/table-status.js b/commons/table-status.js new file mode 100644 index 0000000..4d53960 --- /dev/null +++ b/commons/table-status.js @@ -0,0 +1,38 @@ +export const $status = { + pending: { + label: "挂单中", + type: "#E6A23C", + }, + using: { + label: "开台中", + type: "#fa5555", + }, + paying: { + label: "结算中", + type: "#E6A23C", + }, + idle: { + label: "空闲", + type: "#3F9EFF", + }, + subscribe: { + label: "预定", + type: "rgb(34, 191, 100)", + }, + closed: { + label: "关台", + type: "rgb(221,221,221)", + }, + // opening: { + // label: "开台中", + // type: "#67C23A", + // }, + cleaning: { + label: "待清台", + type: "#FAAD14", + }, + unbind: { + label: "未绑定", + type: "rgb(221,221,221)", + } +} \ No newline at end of file diff --git a/commons/utils/.keep b/commons/utils/.keep new file mode 100644 index 0000000..e69de29 diff --git a/commons/utils/ak.js b/commons/utils/ak.js new file mode 100644 index 0000000..5a0a244 --- /dev/null +++ b/commons/utils/ak.js @@ -0,0 +1,28 @@ +/** + * 统一工具类 (all utils x ) aux ( 谐音 ) [ window 无法创建此命名的文件 放弃。 = = ] + * 统一使用: all Kit 简称 ak. + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2022/12/12 18:38 + */ + +import go from './go.js' +import emit from './emit.js' +import ent from './ent.js' +import cal from './cal.js' +import dataKit from './dataKit.js' +import timer from './timer.js' +import infoBox from './infoBox.js' + +const ak = { + go: go, + emit: emit, + ent: ent, + cal: cal, + timer: timer, + infoBox: infoBox, +} + +export default ak + diff --git a/commons/utils/cal.js b/commons/utils/cal.js new file mode 100644 index 0000000..b160920 --- /dev/null +++ b/commons/utils/cal.js @@ -0,0 +1,37 @@ +/** + * 数字, 计算相关函数 + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2022/11/22 10:38 + */ + +/** + * 保留小数n位,不进行四舍五入 + * num你传递过来的数字, + * decimal你保留的几位,默认保留小数后两位 + */ +const formatDecimal = function(num, decimal = 2) { + num = num.toString() + const index = num.indexOf('.') + if (index !== -1) { + num = num.substring(0, decimal + index + 1) + } else { + num = num.substring(0) + } + //截取后保留两位小数 + return parseFloat(num).toFixed(decimal) +} + +const model = { + // 分转元 + // amount - 金额 parseFloat - 是否转换为数字格式, 默认String + cert2Dollar(amount, needParseFloat = false) { + if (needParseFloat) { // parseFlot + return formatDecimal(amount / 100) + } + return formatDecimal(amount / 100) + } +} + +export default model \ No newline at end of file diff --git a/commons/utils/dataKit.js b/commons/utils/dataKit.js new file mode 100644 index 0000000..8dd0691 --- /dev/null +++ b/commons/utils/dataKit.js @@ -0,0 +1,38 @@ +/** + * 数据 工具类 + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2022/11/30 14:18 + */ + +const model = { + + // 递归遍历树状结构数据 matchFunc 匹配结果, true表示匹配成功, 否则继续匹配。 + // pnode 可不传入 + // 返回结构: [当前数据, 上级数据 ] + recursionTreeData: (treeData, matchFunc, childrenName = 'children', pnode = null ) => { + + for (let i = 0; i < treeData.length; i++) { + + const item = treeData[i] + + // 匹配成功 + if(matchFunc(item)){ + return [item, pnode] + } + + if (item[childrenName] && item[childrenName].length > 0) { + let res = model.recursionTreeData(item[childrenName], matchFunc, childrenName, item) + if(res){ + return res + } + } + } + + } + +} + +export default model + diff --git a/commons/utils/datamap.js b/commons/utils/datamap.js new file mode 100644 index 0000000..a48d464 --- /dev/null +++ b/commons/utils/datamap.js @@ -0,0 +1,164 @@ +/** + * datamap , 数据字典, 存放常用的配置常量信息。 如订单类型的判断, 用户类型的判断。 + * + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2022/11/28 16:16 + */ + +const payOrderStateMap = { + 0: { + text: '订单生成', + color: '#2980FD' + }, + 1: { + text: '支付中', + color: '#FFAA33' + }, + 2: { + text: '支付成功', + color: '#09BB07' + }, + 3: { + text: '支付失败', + color: '#CB2972' + }, + 4: { + text: '已撤销', + color: '#808080' + }, + 5: { + text: '已退款', + color: '#FF5B4C' + }, + 6: { + text: '订单关闭', + color: '#D9D9D9' + }, +} +// 订单 图片 和背景颜色 +const payOrderImageMap = { + WECHAT: { + title: '微信', + imgUrl: '/static/orderImg/wechat.svg', //微信支付 + bgColor: '#09BB07', + }, + ALIPAY: { + title: '支付宝', + imgUrl: '/static/orderImg/zfb.svg', //支付宝支付 + bgColor: '#458FFF', + }, + YSFPAY: { + title: '云闪付', + imgUrl: '/static/orderImg/ysf.svg', // 云闪付支付 + bgColor: '#FF5B4C', + }, + UNIONPAY: { + title: '银联', + imgUrl: '/static/orderImg/union-pay.svg', //银联支付 + bgColor: '#0D131A', + }, + OTHER: { + title: '其他', + imgUrl: '/static/orderImg/default-pay.svg', //其他支付 + bgColor: '#5F36C4', + }, +} + +// 1-超级管理员 2-普通用户 3-拓展员, 11-店长, 12-店员 +const userTypeMap = { + 1: { + text: '超管', + bgColor: 'linear-gradient(270deg, rgba(35,161,252,1) 0%, rgba(26,102,255,1) 100%)', + type: 'blue' + }, + 2: { + text: '普通用户', + bgColor: 'linear-gradient(270deg, rgba(35,161,252,1) 0%, rgba(26,102,255,1) 100%)' + }, + 3: { + text: '拓展员', + bgColor: 'linear-gradient(270deg, rgba(35,161,252,1) 0%, rgba(26,102,255,1) 100%)' + }, + 11: { + text: '店长', + bgColor: 'linear-gradient(270deg, rgba(220,61,138,1) 0%, rgba(187,23,92,1) 100%)', + type: 'purple' + }, + 12: { + text: '店员', + bgColor: ' linear-gradient(270deg, rgba(61,220,68,1) 0%, rgba(23,187,118,1) 100%)', + type: 'green' + }, +} +// 设备厂商 +const devProvider = { + zgwl: '智谷物联', + bsj: '博实结', + fe: '飞鹅', + ps: '品生', + clj: '财来聚', + wsy: '微收银', + xjl: '小精灵', + lmspay: '立码收', + lkls: '拉卡拉', + zw: '智网' +} + +const rechargeStateMap = { + 0: { + text: '初始化', + color: '#2980FD' + }, + 1: { + text: '充值中', + color: '#FFAA33' + }, + 2: { + text: '充值成功', + color: '#09BB07' + }, + 3: { + text: '充值失败', + color: '#CB2972' + } +} + +const model = { + // 订单状态文本和color + payOrderState: (state) => { + // 避免循环判断,影响性能。 + if (payOrderStateMap[state]) { + return payOrderStateMap[state] + } + + return { + text: '未知', + color: '#D9D9D9' + } + }, + + // 订单图片 和图片背景颜色 + payOrderImage: (state) => { + // 取值 找到 返回当前值 未找到返回空对象 + return payOrderImageMap[state] || {} + }, + + // 用户类型的判断 + userType: (userTypeVal) => { + return userTypeMap[userTypeVal] || {} + }, + // 查找设备厂商 找到就返回 找不到据返回空 + provider: (state) => { + return devProvider[state] || '未知' + }, + + // 会员充值订单图片 和图片背景颜色 + rechargeRecordImage: (state) => { + // 取值 找到 返回当前值 未找到返回空对象 + return rechargeStateMap[state] || {} + }, +} + +export default model \ No newline at end of file diff --git a/commons/utils/dayjs-time.js b/commons/utils/dayjs-time.js new file mode 100644 index 0000000..cd8a29d --- /dev/null +++ b/commons/utils/dayjs-time.js @@ -0,0 +1,30 @@ +import dayjs from 'dayjs'; + +// 获取今天的开始和结束时间 +export function getTodayTimestamps() { + const start = dayjs().startOf('day').format('YYYY-MM-DD HH:mm:ss'); + const end = dayjs().endOf('day').format('YYYY-MM-DD HH:mm:ss'); + return { start, end ,label:'今日'}; +} + +// 获取昨天的开始和结束时间 +export function getYesterdayTimestamps() { + const start = dayjs().subtract(1, 'day').startOf('day').format('YYYY-MM-DD HH:mm:ss'); + const end = dayjs().subtract(1, 'day').endOf('day').format('YYYY-MM-DD HH:mm:ss'); + return { start, end ,label:'昨日'}; +} + +// 获取本周的开始和结束时间 +export function getThisWeekTimestamps() { + const start = dayjs().startOf('week').format('YYYY-MM-DD HH:mm:ss'); + const end = dayjs().endOf('week').format('YYYY-MM-DD HH:mm:ss'); + return { start, end,label:'本周' }; +} + +// 获取本月的开始和结束时间 +export function getThisMonthTimestamps() { + const start = dayjs().startOf('month').format('YYYY-MM-DD HH:mm:ss'); + const end = dayjs().endOf('month').format('YYYY-MM-DD HH:mm:ss'); + return { start, end ,label:'本月'}; +} + \ No newline at end of file diff --git a/commons/utils/emit.js b/commons/utils/emit.js new file mode 100644 index 0000000..293c63d --- /dev/null +++ b/commons/utils/emit.js @@ -0,0 +1,138 @@ +/** + * 页面通讯工具类(uni.emit)的封装 + * + * @author terrfly + * @site https://www.jeequan.com + * @date 2022/11/24 15:54 + */ + +const model = { + + // 定义监听器的名字, 应该是一个页面一个, 不可两个页面公共一个, 否则会导致: 一个页面onUnload 移除时影响另一个页面的正常接收。 + // 业务页面 监听, onUnload应该移除掉。 + + // 通用搜索页 + ENAME_REF_SEARCH_PAGE : 'ENAME_REF_SEARCH_PAGE', + + // 应用列表页的刷新 + ENAME_REF_TABLE_MCH_APP : 'ENAME_REF_TABLE_MCH_APP', + // 应用详情 + ENAME_REF_TABLE_MCH_APP_DETAILS : 'ENAME_REF_TABLE_MCH_APP_DETAILS', + + // 调起扫一扫 + ENAME_E_PAY_SCAN : 'ENAME_E_PAY_SCAN', + // 重置 金额 + ENAME_RESET_PAY_AMOUNT: 'ENAME_RESET_PAY_AMOUNT', + // 更新支付订单信息 + ENAME_REF_PAY_ORDER : 'ENAME_REF_PAY_ORDER', + + // 更新 门店列表 + ENAME_REF_STORE_LIST : 'ENAME_REF_STORE_LIST', + + // 更新 门店详情 + ENAME_REF_STORE_DETAIL : 'ENAME_REF_STORE_DETAIL', + + // 更新 员工列表 + ENAME_REF_SYS_USER_LIST : 'ENAME_REF_SYS_USER_LIST', + + // 更新 员工详情 + ENAME_REF_SYS_USER_DETAIL : 'ENAME_REF_SYS_USER_DETAIL', + + // 更新 通道列表 + ENAME_REF_PAY_PASSAGE_LIST : 'ENAME_REF_PAY_PASSAGE_LIST', + + // 更新 辅助终端信息 + ENAME_REF_TERMINAL_LIST : 'ENAME_REF_TERMINAL_LIST', + + // 更新 辅助终端 详情页 + ENAME_REF_TERMINAL_DETAIL : 'ENAME_REF_TERMINAL_DETAIL', + + // 更新 智能pos 信息 + ENAME_REF_AUTOPOS_LIST : 'ENAME_REF_AUTOPOS_LIST', + + // 更新 智能pos 详情页 + ENAME_REF_AUTOPOS_DETAIL : 'ENAME_REF_AUTOPOS_DETAIL', + + // 更新 扫码pos 信息 + ENAME_REF_SCANPOS_LIST : 'ENAME_REF_SCANPOS_LIST', + + // 更新 扫码pos 详情页 + ENAME_REF_SCANPOS_DETAIL : 'ENAME_REF_SCANPOS_DETAIL', + // 码牌列表 + ENAME_REF_QRC_LIST : 'ENAME_REF_QRC_LIST', + + // 码牌详情 + ENAME_REF_QRC_DETAIL : 'ENAME_REF_QRC_DETAIL', + // 更新 打印机 信息 + ENAME_REF_PRINTER_LIST : 'ENAME_REF_PRINTER_LIST', + + // 更新 打印机 详情页 + ENAME_REF_PRINTER_DETAIL : 'ENAME_REF_PRINTER_DETAIL', + + // 云喇叭列表 + ENAME_REF_SPEAKER_LIST : 'ENAME_REF_SPEAKER_LIST', + + // 云喇叭详情 + ENAME_REF_SPEAKER_DETAIL : 'ENAME_REF_SPEAKER_DETAIL', + + + // 进件列表 + ENAME_REF_APPLYMENT_LIST : 'ENAME_REF_APPLYMENT_LIST', + + // 刷脸设备列表 + ENAME_REF_FACE_LIST : 'ENAME_REF_FACE_LIST', + // 刷脸设备详情 + ENAME_REF_FACE_DETAIL : 'ENAME_REF_FACE_DETAIL', + + // 刷脸广告列表 + ENAME_REF_AD_LIST : 'ENAME_REF_AD_LIST', + + // 刷脸广告 详情 + ENAME_REF_AD_DETAILS : 'ENAME_REF_AD_DETAILS', + + // 更新 会员列表 + ENAME_REF_MEMBER_LIST : 'ENAME_REF_MEMBER_LIST', + + // 更新 会员详情 + ENAME_REF_MEMBER_DETAIL : 'ENAME_REF_MEMBER_DETAIL', + + // 更新 会员账户流水列表 + ENAME_REF_MEMBER_ACCOUNT_HISTORY_LIST : 'ENAME_REF_MEMBER_ACCOUNT_HISTORY_LIST', + + // 更新 会员账户流水详情 + ENAME_REF_MEMBER_ACCOUNT_HISTORY_DETAIL : 'ENAME_REF_MEMBER_ACCOUNT_HISTORY_DETAIL', + + // 更新 会员充值记录列表 + ENAME_REF_MEMBER_RECHARGE_RECORD_LIST : 'ENAME_REF_MEMBER_RECHARGE_RECORD_LIST', + + // 更新 会员充值记录详情 + ENAME_REF_MEMBER_RECHARGE_RECORD_DETAIL : 'ENAME_REF_MEMBER_RECHARGE_RECORD_DETAIL', + + // 更新 充值规则列表 + ENAME_REF_RECHARGE_RULE_LIST : 'ENAME_REF_RECHARGE_RULE_LIST', + + // 刷新页面的 发射事件 , 更新页面 && 更新搜索页面 + refPageAndSearchEmit: (refEmitEventName, data = {} ) => { + model.pageEmit(refEmitEventName, data) + model.pageEmit(model.ENAME_REF_SEARCH_PAGE, data) + }, + + // 自定义 + pageEmit: (refEmitEventName, data) => { + uni.$emit(refEmitEventName, data ) + }, + + + + // 废弃该函数。 ( 因为: 页面只监听一次, 使用该函数则无法再次监听, 需要再每个页面写入: uni.$on 保证正常接收。 ) + // 监听页面刷新函数 + on: (refEmitEventName) => { + return new Promise( (resolve) => { + uni.$on(refEmitEventName, function(data){ + resolve( data ) + }) + }) + } +} + +export default model \ No newline at end of file diff --git a/commons/utils/encryptUtil.js b/commons/utils/encryptUtil.js new file mode 100644 index 0000000..95881ce --- /dev/null +++ b/commons/utils/encryptUtil.js @@ -0,0 +1,72 @@ +/** + * 加解密工具包 + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2021/5/16 17:35 + */ +import { SM4 } from 'gm-crypto' +import appConfig from '@/config/appConfig.js' + +let HEX_KEY = null + +// 字符串转16进制 +function str2hex(str) { + var val = '' + for (var i = 0; i < str.length; i++) { + if (val == '') + val = str.charCodeAt(i).toString(16) + else + val += str.charCodeAt(i).toString(16) + } + val += '' + return val +} + +// 获取hex秘钥 +function getHexKey(){ + + if(!HEX_KEY){ + + HEX_KEY = str2hex(appConfig.encryptKey) + + } + return HEX_KEY +} + + +// 解密 (http响应数据, 做通用处理) +export function sm4DecryptByResData(data){ + + if(!data){ + return data + } + + let res = SM4.decrypt(data, getHexKey(), { + inputEncoding: 'base64', + outputEncoding: 'utf8' + }) + + if(!res){ + return res + } + + return JSON.parse(res)['originData'] +} + +// 加密 (http响应数据, 做通用处理) +export function sm4EncryptByReqData(data){ + + if(!data){ + return data + } + + // 加密处理 + let encryptData = SM4.encrypt(JSON.stringify(data), getHexKey(), { + inputEncoding: 'utf8', + outputEncoding: 'base64' + }) + + return {encryptData : encryptData} +} + diff --git a/commons/utils/ent.js b/commons/utils/ent.js new file mode 100644 index 0000000..6b2bcf5 --- /dev/null +++ b/commons/utils/ent.js @@ -0,0 +1,21 @@ +/** + * 权限判断 + * + * @author terrfly + * @site https://www.jeequan.com + * @date 2022/11/22 14:29 + */ +import storageManage from '@/commons/utils/storageManage.js' +const model = { + + // 判断是否包含该权限 + has(entId){ + let userInfo = storageManage.userInfo() + if(userInfo && userInfo.entIdList && userInfo.entIdList.indexOf(entId) >= 0){ + return true; + } + return false; + } +} + +export default model \ No newline at end of file diff --git a/commons/utils/formUtil.js b/commons/utils/formUtil.js new file mode 100644 index 0000000..8d51bf8 --- /dev/null +++ b/commons/utils/formUtil.js @@ -0,0 +1,101 @@ +/** + * form 验证 工具类 + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2022/11/25 10:58 + */ + +import infoBox from '@/commons/utils/infoBox.js' + +const model = { + + + // 正则表达式 + regexp: { + + // 手机号验证规则 + mobile: /^1\d{10}$/, + + // 登录用户名: 字母开头 6 -18位。 + loginUsername: /^[a-zA-Z][a-zA-Z0-9]{5,17}$/, + + }, + + + // 验证规则: + rules: { + + // showText 为空, 说明是 input的placeHoloder 直接飘红, + // showText 有值: 在文本框下方提示。 + // 只有input 才有这种特殊判断。 + requiredInput: (showText, type = 'string') => { + return {format: type, required: true, errorMessage: showText ? ('请输入' + showText) : ' ' } + }, + + requiredSelect: (showText, type = 'string') => { + return {format: type, required: true, errorMessage: '请选择' + showText } + }, + + requiredUpload: (showText, type = 'string') => { + return {format: type, required: true, errorMessage: '请上传' + showText } + }, + + // 正则验证 , 请注意: 该规则需要在required后面, 此处不可包含required + patternRule: (showText, p) => { + return {pattern: p, errorMessage: '请输入正确的' + showText } + }, + + requiredInputShowToast: (showText, type = 'string') => { + return {format: type, required: true, errorMessage:' ', toastErrorMessage: '请输入' + showText } + }, + + requiredSelectShowToast: (showText, type = 'string') => { + return {format: type, required: true, errorMessage:' ', toastErrorMessage: '请选择' + showText } + }, + + requiredUploadShowToast: (showText, type = 'string') => { + return {format: type, required: true, errorMessage:' ', toastErrorMessage: '请上传' + showText } + }, + + patternRuleShowToast: (showText, p) => { + return {pattern: p, errorMessage:' ', toastErrorMessage: '请输入正确的' + showText } + }, + + }, + + + // 支持 提示信息 + // 类型如下: + // { + // required: true, + // toastErrorMessage: "请输入去去去去群", + // errorMessage: ' ', // 不会显示在下部, 需要空格占位 + // } + validate: (form) => { + + return form.validate().catch(e => { + + if(!e || e.length <= 0){ + return Promise.reject() + } + + for(let i = 0; i < e.length; i++){ + let k = e[i].key + let rules = form.rules[k].rules + for(let j = 0; j < rules.length; j++){ + if(rules[j].toastErrorMessage && rules[j].required){ + infoBox.showToast(rules[j].toastErrorMessage) // 仅提示一次即可 + return Promise.reject(e) + } + } + } + return Promise.reject(e) + }) + + }, + +} + +export default model + diff --git a/commons/utils/format.js b/commons/utils/format.js new file mode 100644 index 0000000..f3d5d0a --- /dev/null +++ b/commons/utils/format.js @@ -0,0 +1,55 @@ +/** + * 格式化价格函数,将价格限定在指定的最小值和最大值范围内,并保留两位小数。 + * + * @param {number} price - 需要格式化的价格。 + * @param {number} min - 价格的最小值。 + * @param {number} max - 价格的最大值,默认为100000000。 + * @param {Boolean} returnIsArea - 是否返回值符合范围区间,默认为false。 + * @returns {number} - 返回格式化后的价格,如果超出范围则返回最小值或最大值。 + */ +export const formatPrice = (price,min=-Infinity, max = 100000000,returnIsArea=false,isRerturnNullString=false) => { + + if(price === undefined || price === null||price===''){ + return isRerturnNullString?'':0 + } + // 将价格转换为浮点数并保留两位小数 + const newval = parseFloat((Math.floor(price * 100) / 100).toFixed(2)) + // 如果价格大于最大值,返回最大值 + if (newval > max) { + return returnIsArea?{value:max,error:true}:max + } + // 如果价格小于最小值,返回最小值 + if (newval < min) { + return returnIsArea?{value:min,error:true}:min + } + // 如果价格小于最小值,返回最小值 + if (newval < min) { + return min + } + // 返回格式化后的价格 + return newval +} +export function returnReverseVal(val, isReturnString = true) { + const isBol = typeof val === "boolean"; + const isString = typeof val === "string"; + let reverseNewval = ""; + if (isBol) { + reverseNewval = !val; + } + if (isString) { + reverseNewval = val === "true" ? "false" : "true"; + } + return reverseNewval; +} +export function returnBoolean(val) { + const isBol = typeof val === "boolean"; + const isString = typeof val === "string"; + let newval = ""; + if (isBol) { + newval = val; + } + if (isString) { + newval = val === "true" ? true : false; + } + return newval; +} \ No newline at end of file diff --git a/commons/utils/getDateArea.js b/commons/utils/getDateArea.js new file mode 100644 index 0000000..50583c6 --- /dev/null +++ b/commons/utils/getDateArea.js @@ -0,0 +1,32 @@ +function getDayArea(date = new Date(), type) { + const now = date + if (type === 'start') { + const startOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate()); + return startOfDay + } + if (type === 'end') { + const endOfDay = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 23, 59, 59, 999); + return endOfDay; + } + return `${startOfDay}-${endOfDay}` +} +function getMonthArea(date = new Date(), type) { + let now = date + let currentMonthStart = new Date(now.getFullYear(), now.getMonth(), 1); + let currentMonthEnd = new Date(now.getFullYear(), now.getMonth() + 1, 0 , 23, 59, 59, 999); + if (type === 'start') { + return currentMonthStart + } + if (type === 'end') { + return currentMonthEnd; + } + return { + start: currentMonthStart, + end: currentMonthEnd + }; +} + + +export default { + getDayArea, getMonthArea +} \ No newline at end of file diff --git a/commons/utils/getQueryString.js b/commons/utils/getQueryString.js new file mode 100644 index 0000000..ed310c7 --- /dev/null +++ b/commons/utils/getQueryString.js @@ -0,0 +1,13 @@ +/** + * 获取url链接参数 + * @param {Object} url + * @param {Object} name + */ +export function getQueryString(url, name) { + var reg = new RegExp('(^|&|/?)' + name + '=([^&|/?]*)(&|/?|$)', 'i') + var r = url.substr(1).match(reg) + if (r != null) { + return r[2] + } + return null; +} \ No newline at end of file diff --git a/commons/utils/go.js b/commons/utils/go.js new file mode 100644 index 0000000..c044e60 --- /dev/null +++ b/commons/utils/go.js @@ -0,0 +1,109 @@ +/** + * 页面跳转工具类 + * + * @author terrfly + * @site https://www.jeequan.com + * @date 2022/11/14 17:12 + */ + +// 引入 pages用于解析 pageId 变量 , 注意 需要在 pages.json 定义pageId 参数。 +// 使用方法: go.to(""), 优点: 扩展分包可任意路径,业务调用不再传入固定URL, 传入的是pageId变量。 +import pagesJSON from '@/pages.json' +import emit from './emit.js' + +// 获取到全部的页面路径 和 ID +const ALL_PAGES = { } + +// 添加到 ALL_PAGES +function addPages(pagesRoot){ + let rootUrl = pagesRoot.root ? `/${pagesRoot.root}/` : '/' + pagesRoot.pages.forEach(r => { + if(r.pageId){ + ALL_PAGES[r.pageId] = rootUrl + r.path + } + }) +} + +// 1. 添加 主目录 +addPages(pagesJSON) + +// 2. 添加分包文件 目录 +if(pagesJSON.subPackages){ + pagesJSON.subPackages.forEach(r => addPages(r)) +} + +const model = { + + // 跳转类型 + GO_TYPE_TO: 'navigateTo', + GO_TYPE_REDIRECT: 'redirect', + GO_TYPE_RELAUNCH: 'reLaunch', + GO_TYPE_SWITCHTAB: 'switchTab', + + + // 对象转换url参数 + object2param: (obj) => { + + if(!obj || Object.keys(obj).length <= 0){ + return "" + } + + let result = "?" + Object.keys(obj).forEach(k => { + + let val = obj[k] + // H5需要转码, 其他平台不需要 + // #ifdef H5 + val = encodeURIComponent(val) + // #endif + + result += `${k}=${val}&` + }) + return result.substr(0, (result.length - 1)); + }, + + + // uni.navigateTo函数的封装: 保留当前页面,跳转到应用内的某个页面,使用uni.navigateBack可以返回到原页面。 + // 参数: pagesIdOrUrl(路径或者pageId), 页面参数, 扩展参数 + to: (pagesIdOrUrl, params = {}, type = model.GO_TYPE_TO, extObject = {}) => { + + // 使用ID作为标识 + if(pagesIdOrUrl.indexOf('PAGES_') == 0){ + pagesIdOrUrl = ALL_PAGES[pagesIdOrUrl] + } + pagesIdOrUrl += model.object2param(params) + if(type == model.GO_TYPE_TO){ + uni.navigateTo(Object.assign({ url: pagesIdOrUrl }, extObject)) + } + + if(type == model.GO_TYPE_REDIRECT){ + uni.redirectTo(Object.assign({ url: pagesIdOrUrl }, extObject)) + } + + if(type == model.GO_TYPE_RELAUNCH){ + uni.reLaunch(Object.assign({ url: pagesIdOrUrl }, extObject)) + } + + if(type == model.GO_TYPE_SWITCHTAB){ + uni.switchTab(Object.assign({ url: pagesIdOrUrl }, extObject)) + } + }, + + // 跳转到通用搜索页面 + toSearchPage: (pageType, extObject = {}) => { + model.to("PAGES_LIST_SEARCH", Object.assign({type: pageType}, extObject)) + }, + + // delta 返回到第几页, refEmitEventName: 触发全局更新函数 (更新 list and search ) + back: (delta = 1, refEmitEventName) => { + + if(refEmitEventName){ + emit.refPageAndSearchEmit(refEmitEventName) + } + uni.navigateBack(delta) + } + + +} + +export default model \ No newline at end of file diff --git a/commons/utils/goodsUtil.js b/commons/utils/goodsUtil.js new file mode 100644 index 0000000..9ff70de --- /dev/null +++ b/commons/utils/goodsUtil.js @@ -0,0 +1,37 @@ +export function canComputedPackFee(v) { + return v.pack && v.status != 'return' && v.status != 'refund' && v.status != 'refunding' +} +export function returnCanComputedGoodsArr(arr) { + return arr.filter(v => canComputedPackFee(v)) +} +export function returnPackFee(arr) { + return arr.reduce((prve, cur) => { + return prve + cur.packAmount + }, 0).toFixed(2) +} + +export function canTuicai(orderInfo, item) { + if (orderInfo.status == 'unpaid' && orderInfo.isPostpaid !== null && orderInfo.isPostpaid == 0) { + return false + } + return orderInfo.status == 'unpaid' && orderInfo.useType != 'dine-in-before' && item.status != 'return' +} +export function canTuiKuan(orderInfo, item) { + return orderInfo.status == 'closed' && item.status != 'return' && item.status != 'refund' && item.status != + 'refunding' +} +export function isTuiCai(item) { + return item.status == 'return' +} +export function isTui(item) { + return item.status == 'return' || item.status == 'refund' || item.status == 'refunding' +} +export function isGift(item) { + return !isTui(item) && item.gift +} +export function numSum(arr) { + const sum = arr.reduce((a, b) => { + return a + b * 100 + }, 0) + return (sum / 100).toFixed(2) +} \ No newline at end of file diff --git a/commons/utils/hasPermission.js b/commons/utils/hasPermission.js new file mode 100644 index 0000000..960feaa --- /dev/null +++ b/commons/utils/hasPermission.js @@ -0,0 +1,163 @@ +import { + $hasPermission +} from '@/http/yskApi/shop.js' +import infoBox from '@/commons/utils/infoBox.js' + +const $PermissionObj = { + data: [{ + key: 'yun_xu_cha_kan_jing_ying_shu_ju', + text: '允许查看经营数据' + }, + { + key: 'yun_xu_cha_kan_suo_you_jiao_ban_ji_lu', + text: '允许查看所有交班记录' + } + ], + default: [{ + key: 'yun_xu_xia_dan', + text: '允许下单' + }, + { + key: 'yun_xu_shou_kuan', + text: '允许收款' + }, + { + key: 'yun_xu_tui_kuan', + text: '允许退款' + }, + { + key: 'yun_xu_jiao_ban', + text: '允许交班' + } + ], + goods: [{ + key: 'yun_xu_xiu_gai_shang_pin', + text: '允许修改商品' + }, + { + key: 'yun_xu_shang_xia_jia_shang_pin', + text: '允许上下架商品' + }, + { + key: 'yun_xu_xiu_gai_fen_lei', + text: '允许修改分类' + }, + { + key: 'yun_xu_xiu_gai_fen_zu', + text: '允许修改分组' + } + ], + discount:[ + { + key: 'yun_xu_da_zhe', + text: '允许打折' + } + ], + vip:[ + { + text: '允许管理会员信息', + key: 'yun_xu_guan_li_hui_yuan_xin_xi' + }, + { + key: 'yun_xu_xiu_gai_hui_yuan_yu_e', + text: '允许修改会员余额' + } + ], + stock:[ + { + text: '允许提交报损', + key: 'yun_xu_ti_jiao_bao_sun' + }, + { + text: '允许沽清', + key: 'yun_xu_gu_qing' + }, + { + text: '允许售罄商品', + key: 'yun_xu_shou_qing_shang_pin' + }, + { + text:'允许修改商品库存', + key:'yun_xu_xiu_gai_shang_pin_ku_cun' + }, + { + text: '允许耗材入库', + key: 'yun_xu_hao_cai_ru_ku' + }, + { + text: '允许耗材出库', + key: 'yun_xu_hao_cai_chu_ku' + }, + { + text: '允许耗材盘点', + key: 'yun_xu_hao_cai_pan_dian' + } + ] +} + +function isChinese(str) { + for (var i = 0; i < str.length; i++) { + if (str.charCodeAt(i) >= 0x4E00 && str.charCodeAt(i) <= 0x9FFF) { + return true; // 是中文 + } + } + return false; // 不是中文,全是英文或其他 +} + +function isObjectButNotArray(value) { + return typeof value === 'object' && Array.isArray(value) === false; +} + +function findPermissionObj(str) { + for (let i in $PermissionObj) { + const obj = $PermissionObj[i].find(v => v.key == str || v.text == str) + if (obj) { + return obj + break + } + } + console.error('未找到相关权限配置,请检查权限配置文件commons/utils/hasPermission.js文件进行修改或增加') + return false +} + +function returnFormatParams(params) { + if (typeof params === 'string') { + return findPermissionObj(params) + } else { + if (isObjectButNotArray(params)) { + const obj=findPermissionObj(params.key || params.text) + return {...params,...obj} + } else { + console.error('参数只能是字符串或者对象,不能是数组') + } + } +} + +/** + * 判断是否有某权限 + * @param {Object|String} params + */ +export async function hasPermission(params) { + //如果是商户默认拥有全部权限 + const loginType=uni.getStorageSync('loginType') + if(loginType=='merchant'){ + return true + } + params = returnFormatParams(params) + if (!params) { + return infoBox.showToast('未找到相关权限,请检查代码或在权限配置文件commons/utils/hasPermission.js文件进行修改或增加') + } + const option = Object.assign({ + tips: true, + key: '', + text: '' + }, params) + const res = await $hasPermission({ + code: params.key + }) + if (!res && option.tips) { + infoBox.showToast('您没有' + params.text + '权限!') + } + return res +} + diff --git a/commons/utils/infoBox.js b/commons/utils/infoBox.js new file mode 100644 index 0000000..6b57f3f --- /dev/null +++ b/commons/utils/infoBox.js @@ -0,0 +1,62 @@ +/** + * 提示信息公共文件 + * + * @author terrfly + * @site https://www.jeequan.com + * @date 2022/11/14 15:29 + */ + +const model = { + + // uni.showToast的封装 + // 参数: 标题、 显示时长(单位: 秒), 扩展参数 + // 返回: promise对象, 当提示消失后调用 resolve() + showToast: (title, duration = 1.5, extObject) => { + return new Promise((resolve, reject) => { + uni.showToast(Object.assign({ title: title, icon: 'none', mask: false, duration: (duration * 1000) }, extObject)) + setTimeout(resolve, (duration * 1000)); + }) + }, + + // success类型的提示 + showSuccessToast: (title, duration) => { + return model.showToast(title, duration, {icon: 'success'}) + }, + + // error类型的提示 + showErrorToast: (title, duration) => { + return model.showToast(title, duration, {icon: 'error'}) + }, + + showLoading: (title = '请稍后' ) => { + return uni.showLoading({ title: title, mask: true }) + }, + + hideLoading: () => { + return uni.hideLoading() + }, + + // 返回 Promise 点击确定和取消 + // APP安卓原生提示(比较丑), APP 不推荐使用该函数 。 + showModal: (title, confirmText = '确定', cancalText = '取消', extObject) => { + return new Promise((resolve, reject) => { + uni.showModal( Object.assign({ + title: title, + confirmText: confirmText, + showCancel: cancalText ? true : false, + cancelText: cancalText, + success: function(r) { + if (r.confirm) { + resolve() + }else if (r.cancel) { + reject() + } + } + }, extObject )); + }); + }, + + +} + +export default model \ No newline at end of file diff --git a/commons/utils/prveImg.js b/commons/utils/prveImg.js new file mode 100644 index 0000000..1bc8fdb --- /dev/null +++ b/commons/utils/prveImg.js @@ -0,0 +1,14 @@ +export function prveImg(arr, current) { + uni.previewImage({ + urls: arr,current, + longPressActions: { + itemList: ['发送给朋友', '保存图片', '收藏'], + success: function(data) { + console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片'); + }, + fail: function(err) { + console.log(err.errMsg); + } + } + }); +} \ No newline at end of file diff --git a/commons/utils/pushmsg/QS-baiduyy.js b/commons/utils/pushmsg/QS-baiduyy.js new file mode 100644 index 0000000..9341b2d --- /dev/null +++ b/commons/utils/pushmsg/QS-baiduyy.js @@ -0,0 +1,143 @@ +import { $getBaiduToken } from '@/http/apiManager.js'; +const audioTeam = []; +let audioStartSwitch = false; +const getAudioUrl = 'https://tsn.baidu.com/text2audio'; + +export default function openVoice(objs) { // 传入需转为语音的文本内容 + let lineUp = false; + let returnAudio = false; + if (typeof(objs) !== 'string') { + if (objs && objs.lineUp === true) { + lineUp = true; + } + if (objs && objs.returnAudio === true) { + returnAudio = true; + } + } + if(returnAudio) { + return new Promise((resolve, reject)=>{ + openVoiceFc(objs, returnAudio).then(res=>{ + resolve(res); + }).catch(err=>{ + reject(err) + }); + }) + } + + if (!audioStartSwitch || lineUp) { + audioStartSwitch = true; + openVoiceFc(objs); + } else { + audioTeam.push(objs); + } +} + +function openVoiceFc(objs, returnAudio) { + if(returnAudio) { + return new Promise((resolve, reject)=>{ + $getBaiduToken().then(({bizData}) => { + if (bizData) { + resolve(tts(objs, bizData, returnAudio)); + } else { + reject('获取语音tok接口为空'); + } + }) + }) + }else{ + $getBaiduToken().then(({bizData}) => { + if (bizData) { + tts(objs, bizData); + } else { + } + }) + } +} + +function tts(objs, tok, returnAudio) { + if(typeof(objs)=='string') + objs = {voiceSet: {tex: objs}}; + const data = { + tok, + cuid: tok, + ctp: 1, + lan: 'zh', + ...objs.voiceSet + } + if(returnAudio) + return btts( data, objs.audioSet, objs.audioCallback, objs.lineUp, returnAudio); + btts( data, objs.audioSet, objs.audioCallback, objs.lineUp, returnAudio); +} + +function setAudioSet(options, audio) { + if (options) { + audio.volume = options.volume || 1; + audio.startTime = options.startTime || 0; + audio.loop = options.loop || false; + audio.obeyMuteSwitch = options.obeyMuteSwitch && typeof(options.obeyMuteSwitch) == 'boolean' ? options.obeyMuteSwitch : + true; //支持微信小程序、百度小程序、头条小程序 + } +} + +function btts(param, options, audioCallback, lineUp, returnAudio) { + let audio = uni.createInnerAudioContext(); + setAudioSet(options, audio); + // 序列化参数列表 + let fd = []; + for (let k in param) { + fd.push(k + '=' + encodeURIComponent(encodeURIComponent(param[k]))); + } + audio.src = `${getAudioUrl}?${fd.join('&')}`; + + if(returnAudio) { + audio.onEnded(() => { + audio.destroy(); //销毁音频实例 + audio = null; + }) + audio.onError((e)=>{ + if (audioCallback && audioCallback.onError && typeof(audioCallback.onError) == 'function') audioCallback.onError(e); + audio.destroy(); //销毁音频实例 + audio = null; + }) + return audio; + } + audio.onPlay(() => { + if (audioCallback && audioCallback.onPlay && typeof(audioCallback.onPlay) == 'function') audioCallback.onPlay(); + }) + audio.onPause(()=>{ + if (audioCallback && audioCallback.onPause && typeof(audioCallback.onPause) == 'function') audioCallback.onPause(); + }) + audio.onWaiting(()=>{ + if (audioCallback && audioCallback.onWaiting && typeof(audioCallback.onWaiting) == 'function') audioCallback.onWaiting(); + }) + audio.onStop(()=>{ + if (audioCallback && audioCallback.onStop && typeof(audioCallback.onStop) == 'function') audioCallback.onStop(); + }) + audio.onTimeUpdate(()=>{ + if (audioCallback && audioCallback.onTimeUpdate && typeof(audioCallback.onTimeUpdate) == 'function') audioCallback.onTimeUpdate(); + }) + audio.onSeeking(()=>{ + if (audioCallback && audioCallback.onSeeking && typeof(audioCallback.onSeeking) == 'function') audioCallback.onSeeking(); + }) + audio.onSeeked(()=>{ + if (audioCallback && audioCallback.onSeeked && typeof(audioCallback.onSeeked) == 'function') audioCallback.onSeeked(); + }) + audio.onEnded(() => { + audio.destroy(); //销毁音频实例 + audio = null; + if (audioCallback && audioCallback.onEnded && typeof(audioCallback.onEnded) == 'function') audioCallback.onEnded(); + if (lineUp !== false) { + if (audioTeam.length > 0) { + openVoiceFc(audioTeam[0]); + audioTeam.splice(0, 1); + } else { + audioStartSwitch = false; + } + } + }) + audio.onError((e)=>{ + if (audioCallback && audioCallback.onError && typeof(audioCallback.onError) == 'function') audioCallback.onError(e); + audio.destroy(); //销毁音频实例 + audio = null; + }) + audio.play(); +} diff --git a/commons/utils/pushmsg/pushMsgManage.js b/commons/utils/pushmsg/pushMsgManage.js new file mode 100644 index 0000000..10385dc --- /dev/null +++ b/commons/utils/pushmsg/pushMsgManage.js @@ -0,0 +1,71 @@ +import storageManage from '@/commons/utils/storageManage.js' +import dayjs from 'dayjs' +import baiduyy from './QS-baiduyy.js'; // 百度语音合成 + +// #ifdef MP-WEIXIN +import wxTextToSpeach from './wxTextToSpeach.js'; // 微信小程序插件语音合成 +// #endif + + +const model = { + // 监听推送通知 + addPushMsgEventListener: function(){ + + console.log("监听推送") + + // #ifdef APP-PLUS + // unipush1.0监听消息 + if(plus && plus.push) { + plus.push.addEventListener('receive', model.handlePush) + } + // #endif + // unipush2.0监听消息 + model.uniPushListener2() + }, + + + // uniPush2.0 接收推送消息 + uniPushListener2: function() { + uni.onPushMessage((res) => { + console.log("uniPush2.0 收到推送消息:", res.data) //监听推送消息 + model.handlePush(res.data) + }) + }, + + // 语音播报 + handlePush: function(message) { + + // 没有token信息 + if(!storageManage.token()){ + return false; + } + + // 信息不存在 + if(!message || !message.content) { + return false; + } + + const content = JSON.parse(message.content) + console.log("消息内容:", content) + + // 支付成功 + if (content && content.type == 'paySuccess') { + // 在过期时间之内, 则调起语音播报。 + if( dayjs(content.expiredTime).isAfter(dayjs()) ){ + console.log('执行消息播报'); + // #ifdef MP-WEIXIN + wxTextToSpeach(content.msg) + // #endif + + // #ifndef MP-WEIXIN + baiduyy(content.msg) + // #endif + uni.vibrateLong({}); + } + } + } + +} + + +export default model \ No newline at end of file diff --git a/commons/utils/pushmsg/registerPush.js b/commons/utils/pushmsg/registerPush.js new file mode 100644 index 0000000..1d8c813 --- /dev/null +++ b/commons/utils/pushmsg/registerPush.js @@ -0,0 +1,50 @@ +import { + $pushInfoRegister +} from '@/http/apiManager.js' +import storageManage from '@/commons/utils/storageManage.js' +// 默认导出 方法 注册 push连接 +export default async function() { + let cid1 = undefined // unipush1.0 客户端CID + let cid2 = undefined // unipush2.0 客户端CID + let orgCid = undefined // 原始cid如果获取的cid和新的cid不相同赋值原始cid后端会根据原始cid更新 + let cidType = undefined //传递类型 是 app 还是 微信 + // #ifdef APP-PLUS + cidType = 'app_plus' + // #endif + + // #ifdef MP-WEIXIN + cidType = 'mp_weixin' + // #endif + + // #ifdef APP-PLUS + if (!plus) { + cid1 = plus.push.getClientInfo().clientid + } + // #endif + const data = await uni.getPushClientId() + console.log('客户端推送标识:', data.cid) + cid2 = data.cid + // 如果不存 cid 本地存储 写入 cid + if (!storageManage.uniPush2Cid()) { + storageManage.uniPush2Cid(data.cid) + } else if (cid2 !== storageManage.uniPush2Cid()) { // 否则进行 cid 对比 判断 是否相等 不相等 赋值 orgCid + orgCid = storageManage.uniPush2Cid() //赋值原始cid + storageManage.uniPush2Cid(data.cid) //重新写入 cid + } + if (cid1) { + pushInfoRegister(cid1) + } else { + pushInfoRegister(cid1, cid2, orgCid, cidType) + } + + function pushInfoRegister(cid1 = '', cid2 = '', org = '', cidType = '') { + $pushInfoRegister({ + cid1, + cid2, + orgCid: org, + cidType + }).then(res => { + orgCid = '' //重置 数据 + }) + } +} diff --git a/commons/utils/pushmsg/wxTextToSpeach.js b/commons/utils/pushmsg/wxTextToSpeach.js new file mode 100644 index 0000000..bfd523d --- /dev/null +++ b/commons/utils/pushmsg/wxTextToSpeach.js @@ -0,0 +1,87 @@ +import { $mchConfig } from "@/http/apiManager" +import storageManage from '@/commons/utils/storageManage.js' +let num = 0 //计算错误此时 超过5次错误 不在出触发 +const plugin = requirePlugin("WechatSI") +const pushMsgArr = [] //维护一个消息队列 +let backgroundAudioManager = undefined //获取背景音频实例 +let audioMp3 = '' +console.log('执行创建 语音播报逻辑'); +// 获取配置项 判断是否 开启 小程序 语音推送 +export function getPushStatus () { + if (!storageManage.token()) return //未登录 不播放 + $mchConfig('orderConfig').then(({ bizData = [] }) => { + const weChat = bizData.find(v => v.configKey == "weChatVoice") + if (weChat && weChat?.configVal == 1) { + createBgMusice() + } + }) +} +// getPushStatus() +// 创建 背景音乐 +function createBgMusice (file) { + backgroundAudioManager = wx.getBackgroundAudioManager() + backgroundAudioManager.title = '订单通知' + if (!audioMp3) { + createFile() + } else { + backgroundAudioManager.src = audioMp3 + } + + // 监听 音频播放失败事件 + backgroundAudioManager.onError(function (res) { + console.log('音频播放失败', res, num); + if (num >= 5) return + createFile() + num++ + }) + // 监听 音频播放结束事件 + onBgMusiceEnd() +} +// 监听bei背景音乐播放状态 +export function onBgMusiceEnd () { + backgroundAudioManager.onEnded(() => { + if (pushMsgArr.length > 0) return broadcast(pushMsgArr.pop()) //如果有消息 则继续播放 + backgroundAudioManager.src = audioMp3 //否则播放默认背景音乐 + }) +} +export function startOrEndMusice (flag) { + if (!flag && !!backgroundAudioManager) return backgroundAudioManager.stop() //关闭背景音乐 地址指向空即可 + if (!backgroundAudioManager) return createBgMusice() // 如果一开始是关闭状态 则创建背景音乐实例 + backgroundAudioManager.src = audioMp3 // 否则重新赋值背景音地址即可 +} +export default function (message) { + if (!backgroundAudioManager) return + pushMsgArr.unshift(message) //将消息添加到消息队列头部 背景音乐播放结束后 会对消息队列 进行校验 如果消息队列有消息 会进行播放 否则继续循环背景音乐 +} +// 播放订单 +function broadcast (msg) { + plugin.textToSpeech({ + lang: "zh_CN", + tts: true, + content: msg, + success: function (res) { + backgroundAudioManager.src = res.filename; + onBgMusiceEnd() + }, + fail: function (res) { + console.log("fail tts", res) + } + }) +} + +// 创建文件 +export function createFile (file) { + const fs = wx.getFileSystemManager() + fs.copyFile({ + srcPath: `static/noiseless.mp3`, + destPath: `${wx.env.USER_DATA_PATH}/noiseless.mp3`, + success (res) { + console.log(res, `${wx.env.USER_DATA_PATH}/noiseless.mp3`) + audioMp3 = `${wx.env.USER_DATA_PATH}/noiseless.mp3` + backgroundAudioManager.src = audioMp3 + }, + fail (res) { + console.error(res) + } + }) +} \ No newline at end of file diff --git a/commons/utils/pushmsg/推送和播报相关.txt b/commons/utils/pushmsg/推送和播报相关.txt new file mode 100644 index 0000000..11b6a55 --- /dev/null +++ b/commons/utils/pushmsg/推送和播报相关.txt @@ -0,0 +1,10 @@ +创建 云空间 上传云函数 云函数 url化 运营平台 配置云函数地址 + +打包时 勾选云push 2.0 push1.0 仅支持 app 推送 + +注意配置 百度语音相关参数 + +使用push2.0 请将 static\noiseless.mp3 文件 配置到运营平台 系统 配置 通知配置 push2.0 uniPush语音播报音频文件(小程序播报必填) 下 + +注意:扩展库依赖3张opendb表:opendb-tempdata,opendb-device,uni-id-device。公测版uniCloud,执行扩展库会自动创建。如果你使用的是uniCloud正式版需要自己创建这3张表。 + \ No newline at end of file diff --git a/commons/utils/qrCode.js b/commons/utils/qrCode.js new file mode 100644 index 0000000..41c1be4 --- /dev/null +++ b/commons/utils/qrCode.js @@ -0,0 +1,1625 @@ +//--------------------------------------------------------------------- +// +// QR Code Generator for JavaScript +// +// Copyright (c) 2009 Kazuhiko Arase +// +// URL: http://www.d-project.com/ +// +// Licensed under the MIT license: +// http://www.opensource.org/licenses/mit-license.php +// +// The word 'QR Code' is registered trademark of +// DENSO WAVE INCORPORATED +// http://www.denso-wave.com/qrcode/faqpatent-e.html +// +//--------------------------------------------------------------------- + +//---------------微信小程序基于base64生成二维码插件修改------------------- +/* + * @Modified: Pudon + * @demoURL: https://github.com/Pudon/weapp-qrcode + * @Date: 2018-09-11 14:00:05 + * @Last Modified by: Pudon + * @Last Modified time: 2018-09-12 16:33:19 + */ +//--------------------------------------------------------------------- + +/** + * qrcode + * @param typeNumber 1 to 40 + * @param errorCorrectLevel 'L','M','Q','H' + */ +var qrcode = function(typeNumber, errorCorrectLevel) { + + var PAD0 = 0xEC; + var PAD1 = 0x11; + + var _typeNumber = typeNumber; + var _errorCorrectLevel = QRErrorCorrectLevel[errorCorrectLevel]; + var _modules = null; + var _moduleCount = 0; + var _dataCache = null; + var _dataList = new Array(); + + var _this = {}; + + var makeImpl = function(test, maskPattern) { + + _moduleCount = _typeNumber * 4 + 17; + _modules = function(moduleCount) { + var modules = new Array(moduleCount); + for (var row = 0; row < moduleCount; row += 1) { + modules[row] = new Array(moduleCount); + for (var col = 0; col < moduleCount; col += 1) { + modules[row][col] = null; + } + } + return modules; + }(_moduleCount); + + setupPositionProbePattern(0, 0); + setupPositionProbePattern(_moduleCount - 7, 0); + setupPositionProbePattern(0, _moduleCount - 7); + setupPositionAdjustPattern(); + setupTimingPattern(); + setupTypeInfo(test, maskPattern); + + if (_typeNumber >= 7) { + setupTypeNumber(test); + } + + if (_dataCache == null) { + _dataCache = createData(_typeNumber, _errorCorrectLevel, _dataList); + } + + mapData(_dataCache, maskPattern); + }; + + var setupPositionProbePattern = function(row, col) { + + for (var r = -1; r <= 7; r += 1) { + + if (row + r <= -1 || _moduleCount <= row + r) continue; + + for (var c = -1; c <= 7; c += 1) { + + if (col + c <= -1 || _moduleCount <= col + c) continue; + + if ( (0 <= r && r <= 6 && (c == 0 || c == 6) ) + || (0 <= c && c <= 6 && (r == 0 || r == 6) ) + || (2 <= r && r <= 4 && 2 <= c && c <= 4) ) { + _modules[row + r][col + c] = true; + } else { + _modules[row + r][col + c] = false; + } + } + } + }; + + var getBestMaskPattern = function() { + + var minLostPoint = 0; + var pattern = 0; + + for (var i = 0; i < 8; i += 1) { + + makeImpl(true, i); + + var lostPoint = QRUtil.getLostPoint(_this); + + if (i == 0 || minLostPoint > lostPoint) { + minLostPoint = lostPoint; + pattern = i; + } + } + + return pattern; + }; + + var setupTimingPattern = function() { + + for (var r = 8; r < _moduleCount - 8; r += 1) { + if (_modules[r][6] != null) { + continue; + } + _modules[r][6] = (r % 2 == 0); + } + + for (var c = 8; c < _moduleCount - 8; c += 1) { + if (_modules[6][c] != null) { + continue; + } + _modules[6][c] = (c % 2 == 0); + } + }; + + var setupPositionAdjustPattern = function() { + + var pos = QRUtil.getPatternPosition(_typeNumber); + + for (var i = 0; i < pos.length; i += 1) { + + for (var j = 0; j < pos.length; j += 1) { + + var row = pos[i]; + var col = pos[j]; + + if (_modules[row][col] != null) { + continue; + } + + for (var r = -2; r <= 2; r += 1) { + + for (var c = -2; c <= 2; c += 1) { + + if (r == -2 || r == 2 || c == -2 || c == 2 + || (r == 0 && c == 0) ) { + _modules[row + r][col + c] = true; + } else { + _modules[row + r][col + c] = false; + } + } + } + } + } + }; + + var setupTypeNumber = function(test) { + + var bits = QRUtil.getBCHTypeNumber(_typeNumber); + + for (var i = 0; i < 18; i += 1) { + var mod = (!test && ( (bits >> i) & 1) == 1); + _modules[Math.floor(i / 3)][i % 3 + _moduleCount - 8 - 3] = mod; + } + + for (var i = 0; i < 18; i += 1) { + var mod = (!test && ( (bits >> i) & 1) == 1); + _modules[i % 3 + _moduleCount - 8 - 3][Math.floor(i / 3)] = mod; + } + }; + + var setupTypeInfo = function(test, maskPattern) { + + var data = (_errorCorrectLevel << 3) | maskPattern; + var bits = QRUtil.getBCHTypeInfo(data); + + // vertical + for (var i = 0; i < 15; i += 1) { + + var mod = (!test && ( (bits >> i) & 1) == 1); + + if (i < 6) { + _modules[i][8] = mod; + } else if (i < 8) { + _modules[i + 1][8] = mod; + } else { + _modules[_moduleCount - 15 + i][8] = mod; + } + } + + // horizontal + for (var i = 0; i < 15; i += 1) { + + var mod = (!test && ( (bits >> i) & 1) == 1); + + if (i < 8) { + _modules[8][_moduleCount - i - 1] = mod; + } else if (i < 9) { + _modules[8][15 - i - 1 + 1] = mod; + } else { + _modules[8][15 - i - 1] = mod; + } + } + + // fixed module + _modules[_moduleCount - 8][8] = (!test); + }; + + var mapData = function(data, maskPattern) { + + var inc = -1; + var row = _moduleCount - 1; + var bitIndex = 7; + var byteIndex = 0; + var maskFunc = QRUtil.getMaskFunction(maskPattern); + + for (var col = _moduleCount - 1; col > 0; col -= 2) { + + if (col == 6) col -= 1; + + while (true) { + + for (var c = 0; c < 2; c += 1) { + + if (_modules[row][col - c] == null) { + + var dark = false; + + if (byteIndex < data.length) { + dark = ( ( (data[byteIndex] >>> bitIndex) & 1) == 1); + } + + var mask = maskFunc(row, col - c); + + if (mask) { + dark = !dark; + } + + _modules[row][col - c] = dark; + bitIndex -= 1; + + if (bitIndex == -1) { + byteIndex += 1; + bitIndex = 7; + } + } + } + + row += inc; + + if (row < 0 || _moduleCount <= row) { + row -= inc; + inc = -inc; + break; + } + } + } + }; + + var createBytes = function(buffer, rsBlocks) { + + var offset = 0; + + var maxDcCount = 0; + var maxEcCount = 0; + + var dcdata = new Array(rsBlocks.length); + var ecdata = new Array(rsBlocks.length); + + for (var r = 0; r < rsBlocks.length; r += 1) { + + var dcCount = rsBlocks[r].dataCount; + var ecCount = rsBlocks[r].totalCount - dcCount; + + maxDcCount = Math.max(maxDcCount, dcCount); + maxEcCount = Math.max(maxEcCount, ecCount); + + dcdata[r] = new Array(dcCount); + + for (var i = 0; i < dcdata[r].length; i += 1) { + dcdata[r][i] = 0xff & buffer.getBuffer()[i + offset]; + } + offset += dcCount; + + var rsPoly = QRUtil.getErrorCorrectPolynomial(ecCount); + var rawPoly = qrPolynomial(dcdata[r], rsPoly.getLength() - 1); + + var modPoly = rawPoly.mod(rsPoly); + ecdata[r] = new Array(rsPoly.getLength() - 1); + for (var i = 0; i < ecdata[r].length; i += 1) { + var modIndex = i + modPoly.getLength() - ecdata[r].length; + ecdata[r][i] = (modIndex >= 0)? modPoly.getAt(modIndex) : 0; + } + } + + var totalCodeCount = 0; + for (var i = 0; i < rsBlocks.length; i += 1) { + totalCodeCount += rsBlocks[i].totalCount; + } + + var data = new Array(totalCodeCount); + var index = 0; + + for (var i = 0; i < maxDcCount; i += 1) { + for (var r = 0; r < rsBlocks.length; r += 1) { + if (i < dcdata[r].length) { + data[index] = dcdata[r][i]; + index += 1; + } + } + } + + for (var i = 0; i < maxEcCount; i += 1) { + for (var r = 0; r < rsBlocks.length; r += 1) { + if (i < ecdata[r].length) { + data[index] = ecdata[r][i]; + index += 1; + } + } + } + + return data; + }; + + var createData = function(typeNumber, errorCorrectLevel, dataList) { + + var rsBlocks = QRRSBlock.getRSBlocks(typeNumber, errorCorrectLevel); + + var buffer = qrBitBuffer(); + + for (var i = 0; i < dataList.length; i += 1) { + var data = dataList[i]; + buffer.put(data.getMode(), 4); + buffer.put(data.getLength(), QRUtil.getLengthInBits(data.getMode(), typeNumber) ); + data.write(buffer); + } + + // calc num max data. + var totalDataCount = 0; + for (var i = 0; i < rsBlocks.length; i += 1) { + totalDataCount += rsBlocks[i].dataCount; + } + + if (buffer.getLengthInBits() > totalDataCount * 8) { + throw new Error('code length overflow. (' + + buffer.getLengthInBits() + + '>' + + totalDataCount * 8 + + ')'); + } + + // end code + if (buffer.getLengthInBits() + 4 <= totalDataCount * 8) { + buffer.put(0, 4); + } + + // padding + while (buffer.getLengthInBits() % 8 != 0) { + buffer.putBit(false); + } + + // padding + while (true) { + + if (buffer.getLengthInBits() >= totalDataCount * 8) { + break; + } + buffer.put(PAD0, 8); + + if (buffer.getLengthInBits() >= totalDataCount * 8) { + break; + } + buffer.put(PAD1, 8); + } + + return createBytes(buffer, rsBlocks); + }; + + _this.addData = function(data) { + var newData = qr8BitByte(data); + _dataList.push(newData); + _dataCache = null; + }; + + _this.isDark = function(row, col) { + if (row < 0 || _moduleCount <= row || col < 0 || _moduleCount <= col) { + throw new Error(row + ',' + col); + } + return _modules[row][col]; + }; + + _this.getModuleCount = function() { + return _moduleCount; + }; + + _this.make = function() { + makeImpl(false, getBestMaskPattern() ); + }; + + _this.createTableTag = function(cellSize, margin) { + + cellSize = cellSize || 2; + margin = (typeof margin == 'undefined')? cellSize * 4 : margin; + + var qrHtml = ''; + + qrHtml += ''; + qrHtml += ''; + + for (var r = 0; r < _this.getModuleCount(); r += 1) { + + qrHtml += ''; + + for (var c = 0; c < _this.getModuleCount(); c += 1) { + qrHtml += ''; + } + + qrHtml += ''; + qrHtml += '
'; + } + + qrHtml += '
'; + + return qrHtml; + }; + + _this.createImgTag = function(cellSize, margin, size) { + + cellSize = cellSize || 2; + margin = (typeof margin == 'undefined')? cellSize * 4 : margin; + + var min = margin; + var max = _this.getModuleCount() * cellSize + margin; + + return createImgTag(size, size, function(x, y) { + if (min <= x && x < max && min <= y && y < max) { + var c = Math.floor( (x - min) / cellSize); + var r = Math.floor( (y - min) / cellSize); + return _this.isDark(r, c)? 0 : 1; + } else { + return 1; + } + } ); + }; + + return _this; +}; + +//--------------------------------------------------------------------- +// qrcode.stringToBytes +//--------------------------------------------------------------------- + +qrcode.stringToBytes = function(s) { + var bytes = new Array(); + for (var i = 0; i < s.length; i += 1) { + var c = s.charCodeAt(i); + bytes.push(c & 0xff); + } + return bytes; +}; + +//--------------------------------------------------------------------- +// qrcode.createStringToBytes +//--------------------------------------------------------------------- + +/** + * @param unicodeData base64 string of byte array. + * [16bit Unicode],[16bit Bytes], ... + * @param numChars + */ +qrcode.createStringToBytes = function(unicodeData, numChars) { + + // create conversion map. + + var unicodeMap = function() { + + var bin = base64DecodeInputStream(unicodeData); + var read = function() { + var b = bin.read(); + if (b == -1) throw new Error(); + return b; + }; + + var count = 0; + var unicodeMap = {}; + while (true) { + var b0 = bin.read(); + if (b0 == -1) break; + var b1 = read(); + var b2 = read(); + var b3 = read(); + var k = String.fromCharCode( (b0 << 8) | b1); + var v = (b2 << 8) | b3; + unicodeMap[k] = v; + count += 1; + } + if (count != numChars) { + throw new Error(count + ' != ' + numChars); + } + + return unicodeMap; + }(); + + var unknownChar = '?'.charCodeAt(0); + + return function(s) { + var bytes = new Array(); + for (var i = 0; i < s.length; i += 1) { + var c = s.charCodeAt(i); + if (c < 128) { + bytes.push(c); + } else { + var b = unicodeMap[s.charAt(i)]; + if (typeof b == 'number') { + if ( (b & 0xff) == b) { + // 1byte + bytes.push(b); + } else { + // 2bytes + bytes.push(b >>> 8); + bytes.push(b & 0xff); + } + } else { + bytes.push(unknownChar); + } + } + } + return bytes; + }; +}; + +//--------------------------------------------------------------------- +// QRMode +//--------------------------------------------------------------------- + +var QRMode = { + MODE_NUMBER : 1 << 0, + MODE_ALPHA_NUM : 1 << 1, + MODE_8BIT_BYTE : 1 << 2, + MODE_KANJI : 1 << 3 +}; + +//--------------------------------------------------------------------- +// QRErrorCorrectLevel +//--------------------------------------------------------------------- + +var QRErrorCorrectLevel = { + L : 1, + M : 0, + Q : 3, + H : 2 +}; + +//--------------------------------------------------------------------- +// QRMaskPattern +//--------------------------------------------------------------------- + +var QRMaskPattern = { + PATTERN000 : 0, + PATTERN001 : 1, + PATTERN010 : 2, + PATTERN011 : 3, + PATTERN100 : 4, + PATTERN101 : 5, + PATTERN110 : 6, + PATTERN111 : 7 +}; + +//--------------------------------------------------------------------- +// QRUtil +//--------------------------------------------------------------------- + +var QRUtil = function() { + + var PATTERN_POSITION_TABLE = [ + [], + [6, 18], + [6, 22], + [6, 26], + [6, 30], + [6, 34], + [6, 22, 38], + [6, 24, 42], + [6, 26, 46], + [6, 28, 50], + [6, 30, 54], + [6, 32, 58], + [6, 34, 62], + [6, 26, 46, 66], + [6, 26, 48, 70], + [6, 26, 50, 74], + [6, 30, 54, 78], + [6, 30, 56, 82], + [6, 30, 58, 86], + [6, 34, 62, 90], + [6, 28, 50, 72, 94], + [6, 26, 50, 74, 98], + [6, 30, 54, 78, 102], + [6, 28, 54, 80, 106], + [6, 32, 58, 84, 110], + [6, 30, 58, 86, 114], + [6, 34, 62, 90, 118], + [6, 26, 50, 74, 98, 122], + [6, 30, 54, 78, 102, 126], + [6, 26, 52, 78, 104, 130], + [6, 30, 56, 82, 108, 134], + [6, 34, 60, 86, 112, 138], + [6, 30, 58, 86, 114, 142], + [6, 34, 62, 90, 118, 146], + [6, 30, 54, 78, 102, 126, 150], + [6, 24, 50, 76, 102, 128, 154], + [6, 28, 54, 80, 106, 132, 158], + [6, 32, 58, 84, 110, 136, 162], + [6, 26, 54, 82, 110, 138, 166], + [6, 30, 58, 86, 114, 142, 170] + ]; + var G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0); + var G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0); + var G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1); + + var _this = {}; + + var getBCHDigit = function(data) { + var digit = 0; + while (data != 0) { + digit += 1; + data >>>= 1; + } + return digit; + }; + + _this.getBCHTypeInfo = function(data) { + var d = data << 10; + while (getBCHDigit(d) - getBCHDigit(G15) >= 0) { + d ^= (G15 << (getBCHDigit(d) - getBCHDigit(G15) ) ); + } + return ( (data << 10) | d) ^ G15_MASK; + }; + + _this.getBCHTypeNumber = function(data) { + var d = data << 12; + while (getBCHDigit(d) - getBCHDigit(G18) >= 0) { + d ^= (G18 << (getBCHDigit(d) - getBCHDigit(G18) ) ); + } + return (data << 12) | d; + }; + + _this.getPatternPosition = function(typeNumber) { + return PATTERN_POSITION_TABLE[typeNumber - 1]; + }; + + _this.getMaskFunction = function(maskPattern) { + + switch (maskPattern) { + + case QRMaskPattern.PATTERN000 : + return function(i, j) { return (i + j) % 2 == 0; }; + case QRMaskPattern.PATTERN001 : + return function(i, j) { return i % 2 == 0; }; + case QRMaskPattern.PATTERN010 : + return function(i, j) { return j % 3 == 0; }; + case QRMaskPattern.PATTERN011 : + return function(i, j) { return (i + j) % 3 == 0; }; + case QRMaskPattern.PATTERN100 : + return function(i, j) { return (Math.floor(i / 2) + Math.floor(j / 3) ) % 2 == 0; }; + case QRMaskPattern.PATTERN101 : + return function(i, j) { return (i * j) % 2 + (i * j) % 3 == 0; }; + case QRMaskPattern.PATTERN110 : + return function(i, j) { return ( (i * j) % 2 + (i * j) % 3) % 2 == 0; }; + case QRMaskPattern.PATTERN111 : + return function(i, j) { return ( (i * j) % 3 + (i + j) % 2) % 2 == 0; }; + + default : + throw new Error('bad maskPattern:' + maskPattern); + } + }; + + _this.getErrorCorrectPolynomial = function(errorCorrectLength) { + var a = qrPolynomial([1], 0); + for (var i = 0; i < errorCorrectLength; i += 1) { + a = a.multiply(qrPolynomial([1, QRMath.gexp(i)], 0) ); + } + return a; + }; + + _this.getLengthInBits = function(mode, type) { + + if (1 <= type && type < 10) { + + // 1 - 9 + + switch(mode) { + case QRMode.MODE_NUMBER : return 10; + case QRMode.MODE_ALPHA_NUM : return 9; + case QRMode.MODE_8BIT_BYTE : return 8; + case QRMode.MODE_KANJI : return 8; + default : + throw new Error('mode:' + mode); + } + + } else if (type < 27) { + + // 10 - 26 + + switch(mode) { + case QRMode.MODE_NUMBER : return 12; + case QRMode.MODE_ALPHA_NUM : return 11; + case QRMode.MODE_8BIT_BYTE : return 16; + case QRMode.MODE_KANJI : return 10; + default : + throw new Error('mode:' + mode); + } + + } else if (type < 41) { + + // 27 - 40 + + switch(mode) { + case QRMode.MODE_NUMBER : return 14; + case QRMode.MODE_ALPHA_NUM : return 13; + case QRMode.MODE_8BIT_BYTE : return 16; + case QRMode.MODE_KANJI : return 12; + default : + throw new Error('mode:' + mode); + } + + } else { + throw new Error('type:' + type); + } + }; + + _this.getLostPoint = function(qrcode) { + + var moduleCount = qrcode.getModuleCount(); + + var lostPoint = 0; + + // LEVEL1 + + for (var row = 0; row < moduleCount; row += 1) { + for (var col = 0; col < moduleCount; col += 1) { + + var sameCount = 0; + var dark = qrcode.isDark(row, col); + + for (var r = -1; r <= 1; r += 1) { + + if (row + r < 0 || moduleCount <= row + r) { + continue; + } + + for (var c = -1; c <= 1; c += 1) { + + if (col + c < 0 || moduleCount <= col + c) { + continue; + } + + if (r == 0 && c == 0) { + continue; + } + + if (dark == qrcode.isDark(row + r, col + c) ) { + sameCount += 1; + } + } + } + + if (sameCount > 5) { + lostPoint += (3 + sameCount - 5); + } + } + }; + + // LEVEL2 + + for (var row = 0; row < moduleCount - 1; row += 1) { + for (var col = 0; col < moduleCount - 1; col += 1) { + var count = 0; + if (qrcode.isDark(row, col) ) count += 1; + if (qrcode.isDark(row + 1, col) ) count += 1; + if (qrcode.isDark(row, col + 1) ) count += 1; + if (qrcode.isDark(row + 1, col + 1) ) count += 1; + if (count == 0 || count == 4) { + lostPoint += 3; + } + } + } + + // LEVEL3 + + for (var row = 0; row < moduleCount; row += 1) { + for (var col = 0; col < moduleCount - 6; col += 1) { + if (qrcode.isDark(row, col) + && !qrcode.isDark(row, col + 1) + && qrcode.isDark(row, col + 2) + && qrcode.isDark(row, col + 3) + && qrcode.isDark(row, col + 4) + && !qrcode.isDark(row, col + 5) + && qrcode.isDark(row, col + 6) ) { + lostPoint += 40; + } + } + } + + for (var col = 0; col < moduleCount; col += 1) { + for (var row = 0; row < moduleCount - 6; row += 1) { + if (qrcode.isDark(row, col) + && !qrcode.isDark(row + 1, col) + && qrcode.isDark(row + 2, col) + && qrcode.isDark(row + 3, col) + && qrcode.isDark(row + 4, col) + && !qrcode.isDark(row + 5, col) + && qrcode.isDark(row + 6, col) ) { + lostPoint += 40; + } + } + } + + // LEVEL4 + + var darkCount = 0; + + for (var col = 0; col < moduleCount; col += 1) { + for (var row = 0; row < moduleCount; row += 1) { + if (qrcode.isDark(row, col) ) { + darkCount += 1; + } + } + } + + var ratio = Math.abs(100 * darkCount / moduleCount / moduleCount - 50) / 5; + lostPoint += ratio * 10; + + return lostPoint; + }; + + return _this; +}(); + +//--------------------------------------------------------------------- +// QRMath +//--------------------------------------------------------------------- + +var QRMath = function() { + + var EXP_TABLE = new Array(256); + var LOG_TABLE = new Array(256); + + // initialize tables + for (var i = 0; i < 8; i += 1) { + EXP_TABLE[i] = 1 << i; + } + for (var i = 8; i < 256; i += 1) { + EXP_TABLE[i] = EXP_TABLE[i - 4] + ^ EXP_TABLE[i - 5] + ^ EXP_TABLE[i - 6] + ^ EXP_TABLE[i - 8]; + } + for (var i = 0; i < 255; i += 1) { + LOG_TABLE[EXP_TABLE[i] ] = i; + } + + var _this = {}; + + _this.glog = function(n) { + + if (n < 1) { + throw new Error('glog(' + n + ')'); + } + + return LOG_TABLE[n]; + }; + + _this.gexp = function(n) { + + while (n < 0) { + n += 255; + } + + while (n >= 256) { + n -= 255; + } + + return EXP_TABLE[n]; + }; + + return _this; +}(); + +//--------------------------------------------------------------------- +// qrPolynomial +//--------------------------------------------------------------------- + +function qrPolynomial(num, shift) { + + if (typeof num.length == 'undefined') { + throw new Error(num.length + '/' + shift); + } + + var _num = function() { + var offset = 0; + while (offset < num.length && num[offset] == 0) { + offset += 1; + } + var _num = new Array(num.length - offset + shift); + for (var i = 0; i < num.length - offset; i += 1) { + _num[i] = num[i + offset]; + } + return _num; + }(); + + var _this = {}; + + _this.getAt = function(index) { + return _num[index]; + }; + + _this.getLength = function() { + return _num.length; + }; + + _this.multiply = function(e) { + + var num = new Array(_this.getLength() + e.getLength() - 1); + + for (var i = 0; i < _this.getLength(); i += 1) { + for (var j = 0; j < e.getLength(); j += 1) { + num[i + j] ^= QRMath.gexp(QRMath.glog(_this.getAt(i) ) + QRMath.glog(e.getAt(j) ) ); + } + } + + return qrPolynomial(num, 0); + }; + + _this.mod = function(e) { + + if (_this.getLength() - e.getLength() < 0) { + return _this; + } + + var ratio = QRMath.glog(_this.getAt(0) ) - QRMath.glog(e.getAt(0) ); + + var num = new Array(_this.getLength() ); + for (var i = 0; i < _this.getLength(); i += 1) { + num[i] = _this.getAt(i); + } + + for (var i = 0; i < e.getLength(); i += 1) { + num[i] ^= QRMath.gexp(QRMath.glog(e.getAt(i) ) + ratio); + } + + // recursive call + return qrPolynomial(num, 0).mod(e); + }; + + return _this; +}; + +//--------------------------------------------------------------------- +// QRRSBlock +//--------------------------------------------------------------------- + +var QRRSBlock = function() { + + + // [1: [L, M, Q, H], ..] + var RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]]; + + var qrRSBlock = function(totalCount, dataCount) { + var _this = {}; + _this.totalCount = totalCount; + _this.dataCount = dataCount; + return _this; + }; + + var _this = {}; + + var getRsBlockTable = function(typeNumber, errorCorrectLevel) { + + switch(errorCorrectLevel) { + case QRErrorCorrectLevel.L : + return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 0]; + case QRErrorCorrectLevel.M : + return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 1]; + case QRErrorCorrectLevel.Q : + return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 2]; + case QRErrorCorrectLevel.H : + return RS_BLOCK_TABLE[(typeNumber - 1) * 4 + 3]; + default : + return undefined; + } + }; + + _this.getRSBlocks = function(typeNumber, errorCorrectLevel) { + + var rsBlock = getRsBlockTable(typeNumber, errorCorrectLevel); + + if (typeof rsBlock == 'undefined') { + throw new Error('bad rs block @ typeNumber:' + typeNumber + + '/errorCorrectLevel:' + errorCorrectLevel); + } + + var length = rsBlock.length / 3; + + var list = new Array(); + + for (var i = 0; i < length; i += 1) { + + var count = rsBlock[i * 3 + 0]; + var totalCount = rsBlock[i * 3 + 1]; + var dataCount = rsBlock[i * 3 + 2]; + + for (var j = 0; j < count; j += 1) { + list.push(qrRSBlock(totalCount, dataCount) ); + } + } + + return list; + }; + + return _this; +}(); + +//--------------------------------------------------------------------- +// qrBitBuffer +//--------------------------------------------------------------------- + +var qrBitBuffer = function() { + + var _buffer = new Array(); + var _length = 0; + + var _this = {}; + + _this.getBuffer = function() { + return _buffer; + }; + + _this.getAt = function(index) { + var bufIndex = Math.floor(index / 8); + return ( (_buffer[bufIndex] >>> (7 - index % 8) ) & 1) == 1; + }; + + _this.put = function(num, length) { + for (var i = 0; i < length; i += 1) { + _this.putBit( ( (num >>> (length - i - 1) ) & 1) == 1); + } + }; + + _this.getLengthInBits = function() { + return _length; + }; + + _this.putBit = function(bit) { + + var bufIndex = Math.floor(_length / 8); + if (_buffer.length <= bufIndex) { + _buffer.push(0); + } + + if (bit) { + _buffer[bufIndex] |= (0x80 >>> (_length % 8) ); + } + + _length += 1; + }; + + return _this; +}; + +//--------------------------------------------------------------------- +// qr8BitByte +//--------------------------------------------------------------------- + +var qr8BitByte = function(data) { + + var _mode = QRMode.MODE_8BIT_BYTE; + var _data = data; + var _parsedData = []; + + var _this = {}; + + + // Added to support UTF-8 Characters + for (var i = 0, l = _data.length; i < l; i++) { + var byteArray = []; + var code = _data.charCodeAt(i); + + if (code > 0x10000) { + byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18); + byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12); + byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6); + byteArray[3] = 0x80 | (code & 0x3F); + } else if (code > 0x800) { + byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12); + byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6); + byteArray[2] = 0x80 | (code & 0x3F); + } else if (code > 0x80) { + byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6); + byteArray[1] = 0x80 | (code & 0x3F); + } else { + byteArray[0] = code; + } + + // Fix Unicode corruption bug + _parsedData.push(byteArray); + } + + _parsedData = Array.prototype.concat.apply([], _parsedData); + + if (_parsedData.length != _data.length) { + _parsedData.unshift(191); + _parsedData.unshift(187); + _parsedData.unshift(239); + } + + var _bytes = _parsedData; + + _this.getMode = function() { + return _mode; + }; + + _this.getLength = function(buffer) { + return _bytes.length; + }; + + _this.write = function(buffer) { + for (var i = 0; i < _bytes.length; i += 1) { + buffer.put(_bytes[i], 8); + } + }; + + return _this; +}; + +//===================================================================== +// GIF Support etc. +// + +//--------------------------------------------------------------------- +// byteArrayOutputStream +//--------------------------------------------------------------------- + +var byteArrayOutputStream = function() { + + var _bytes = new Array(); + + var _this = {}; + + _this.writeByte = function(b) { + _bytes.push(b & 0xff); + }; + + _this.writeShort = function(i) { + _this.writeByte(i); + _this.writeByte(i >>> 8); + }; + + _this.writeBytes = function(b, off, len) { + off = off || 0; + len = len || b.length; + for (var i = 0; i < len; i += 1) { + _this.writeByte(b[i + off]); + } + }; + + _this.writeString = function(s) { + for (var i = 0; i < s.length; i += 1) { + _this.writeByte(s.charCodeAt(i) ); + } + }; + + _this.toByteArray = function() { + return _bytes; + }; + + _this.toString = function() { + var s = ''; + s += '['; + for (var i = 0; i < _bytes.length; i += 1) { + if (i > 0) { + s += ','; + } + s += _bytes[i]; + } + s += ']'; + return s; + }; + + return _this; +}; + +//--------------------------------------------------------------------- +// base64EncodeOutputStream +//--------------------------------------------------------------------- + +var base64EncodeOutputStream = function() { + + var _buffer = 0; + var _buflen = 0; + var _length = 0; + var _base64 = ''; + + var _this = {}; + + var writeEncoded = function(b) { + _base64 += String.fromCharCode(encode(b & 0x3f) ); + }; + + var encode = function(n) { + if (n < 0) { + // error. + } else if (n < 26) { + return 0x41 + n; + } else if (n < 52) { + return 0x61 + (n - 26); + } else if (n < 62) { + return 0x30 + (n - 52); + } else if (n == 62) { + return 0x2b; + } else if (n == 63) { + return 0x2f; + } + throw new Error('n:' + n); + }; + + _this.writeByte = function(n) { + + _buffer = (_buffer << 8) | (n & 0xff); + _buflen += 8; + _length += 1; + + while (_buflen >= 6) { + writeEncoded(_buffer >>> (_buflen - 6) ); + _buflen -= 6; + } + }; + + _this.flush = function() { + + if (_buflen > 0) { + writeEncoded(_buffer << (6 - _buflen) ); + _buffer = 0; + _buflen = 0; + } + + if (_length % 3 != 0) { + // padding + var padlen = 3 - _length % 3; + for (var i = 0; i < padlen; i += 1) { + _base64 += '='; + } + } + }; + + _this.toString = function() { + return _base64; + }; + + return _this; +}; + +//--------------------------------------------------------------------- +// base64DecodeInputStream +//--------------------------------------------------------------------- + +var base64DecodeInputStream = function(str) { + + var _str = str; + var _pos = 0; + var _buffer = 0; + var _buflen = 0; + + var _this = {}; + + _this.read = function() { + + while (_buflen < 8) { + + if (_pos >= _str.length) { + if (_buflen == 0) { + return -1; + } + throw new Error('unexpected end of file./' + _buflen); + } + + var c = _str.charAt(_pos); + _pos += 1; + + if (c == '=') { + _buflen = 0; + return -1; + } else if (c.match(/^\s$/) ) { + // ignore if whitespace. + continue; + } + + _buffer = (_buffer << 6) | decode(c.charCodeAt(0) ); + _buflen += 6; + } + + var n = (_buffer >>> (_buflen - 8) ) & 0xff; + _buflen -= 8; + return n; + }; + + var decode = function(c) { + if (0x41 <= c && c <= 0x5a) { + return c - 0x41; + } else if (0x61 <= c && c <= 0x7a) { + return c - 0x61 + 26; + } else if (0x30 <= c && c <= 0x39) { + return c - 0x30 + 52; + } else if (c == 0x2b) { + return 62; + } else if (c == 0x2f) { + return 63; + } else { + throw new Error('c:' + c); + } + }; + + return _this; +}; + +//--------------------------------------------------------------------- +// gifImage (B/W) +//--------------------------------------------------------------------- + +var gifImage = function(width, height) { + + var _width = width; + var _height = height; + var _data = new Array(width * height); + + var _this = {}; + + _this.setPixel = function(x, y, pixel) { + _data[y * _width + x] = pixel; + }; + + _this.write = function(out) { + + //--------------------------------- + // GIF Signature + + out.writeString('GIF87a'); + + //--------------------------------- + // Screen Descriptor + + out.writeShort(_width); + out.writeShort(_height); + + out.writeByte(0x80); // 2bit + out.writeByte(0); + out.writeByte(0); + + //--------------------------------- + // Global Color Map + + // black + out.writeByte(0x00); + out.writeByte(0x00); + out.writeByte(0x00); + + // white + out.writeByte(0xff); + out.writeByte(0xff); + out.writeByte(0xff); + + //--------------------------------- + // Image Descriptor + + out.writeString(','); + out.writeShort(0); + out.writeShort(0); + out.writeShort(_width); + out.writeShort(_height); + out.writeByte(0); + + //--------------------------------- + // Local Color Map + + //--------------------------------- + // Raster Data + + var lzwMinCodeSize = 2; + var raster = getLZWRaster(lzwMinCodeSize); + + out.writeByte(lzwMinCodeSize); + + var offset = 0; + + while (raster.length - offset > 255) { + out.writeByte(255); + out.writeBytes(raster, offset, 255); + offset += 255; + } + + out.writeByte(raster.length - offset); + out.writeBytes(raster, offset, raster.length - offset); + out.writeByte(0x00); + + //--------------------------------- + // GIF Terminator + out.writeString(';'); + }; + + var bitOutputStream = function(out) { + + var _out = out; + var _bitLength = 0; + var _bitBuffer = 0; + + var _this = {}; + + _this.write = function(data, length) { + + if ( (data >>> length) != 0) { + throw new Error('length over'); + } + + while (_bitLength + length >= 8) { + _out.writeByte(0xff & ( (data << _bitLength) | _bitBuffer) ); + length -= (8 - _bitLength); + data >>>= (8 - _bitLength); + _bitBuffer = 0; + _bitLength = 0; + } + + _bitBuffer = (data << _bitLength) | _bitBuffer; + _bitLength = _bitLength + length; + }; + + _this.flush = function() { + if (_bitLength > 0) { + _out.writeByte(_bitBuffer); + } + }; + + return _this; + }; + + var getLZWRaster = function(lzwMinCodeSize) { + + var clearCode = 1 << lzwMinCodeSize; + var endCode = (1 << lzwMinCodeSize) + 1; + var bitLength = lzwMinCodeSize + 1; + + // Setup LZWTable + var table = lzwTable(); + + for (var i = 0; i < clearCode; i += 1) { + table.add(String.fromCharCode(i) ); + } + table.add(String.fromCharCode(clearCode) ); + table.add(String.fromCharCode(endCode) ); + + var byteOut = byteArrayOutputStream(); + var bitOut = bitOutputStream(byteOut); + + // clear code + bitOut.write(clearCode, bitLength); + + var dataIndex = 0; + + var s = String.fromCharCode(_data[dataIndex]); + dataIndex += 1; + + while (dataIndex < _data.length) { + + var c = String.fromCharCode(_data[dataIndex]); + dataIndex += 1; + + if (table.contains(s + c) ) { + + s = s + c; + + } else { + + bitOut.write(table.indexOf(s), bitLength); + + if (table.size() < 0xfff) { + + if (table.size() == (1 << bitLength) ) { + bitLength += 1; + } + + table.add(s + c); + } + + s = c; + } + } + + bitOut.write(table.indexOf(s), bitLength); + + // end code + bitOut.write(endCode, bitLength); + + bitOut.flush(); + + return byteOut.toByteArray(); + }; + + var lzwTable = function() { + + var _map = {}; + var _size = 0; + + var _this = {}; + + _this.add = function(key) { + if (_this.contains(key) ) { + throw new Error('dup key:' + key); + } + _map[key] = _size; + _size += 1; + }; + + _this.size = function() { + return _size; + }; + + _this.indexOf = function(key) { + return _map[key]; + }; + + _this.contains = function(key) { + return typeof _map[key] != 'undefined'; + }; + + return _this; + }; + + return _this; +}; + +var createImgTag = function(width, height, getPixel, alt) { + + var gif = gifImage(width, height); + for (var y = 0; y < height; y += 1) { + for (var x = 0; x < width; x += 1) { + gif.setPixel(x, y, getPixel(x, y) ); + } + } + + var b = byteArrayOutputStream(); + gif.write(b); + + var base64 = base64EncodeOutputStream(); + var bytes = b.toByteArray(); + for (var i = 0; i < bytes.length; i += 1) { + base64.writeByte(bytes[i]); + } + base64.flush(); + + var img = ''; + img += 'data:image/gif;base64,'; + img += base64; + + return img; +}; + +//--------------------------------------------------------------------- +// returns qrcode function. + +var drawImg = function(text, options) { + options = options || {}; + var typeNumber = options.typeNumber || 4; + var errorCorrectLevel = options.errorCorrectLevel || 'M'; + var size = options.size || 500; + + var qr; + + try { + qr = qrcode(typeNumber, errorCorrectLevel || 'M'); + qr.addData(text); + qr.make(); + } catch (e) { + if(typeNumber >= 40) { + throw new Error('Text too long to encode'); + } else { + return drawImg(text, { + size: size, + errorCorrectLevel: errorCorrectLevel, + typeNumber: typeNumber + 1 + }); + } + } + + // calc cellsize and margin + var cellsize = parseInt(size / qr.getModuleCount()); + var margin = parseInt((size - qr.getModuleCount() * cellsize) / 2); + + return qr.createImgTag(cellsize, margin, size); +}; +export default { + drawImg: drawImg +}; \ No newline at end of file diff --git a/commons/utils/returrn-data.js b/commons/utils/returrn-data.js new file mode 100644 index 0000000..3619e8e --- /dev/null +++ b/commons/utils/returrn-data.js @@ -0,0 +1,7 @@ +export const objToArrary = (obj,keyNewName) => { + return Object.entries(obj).map(([key, value]) => ({ + key, + [keyNewName]:key, + ...value, + })) +} \ No newline at end of file diff --git a/commons/utils/rsaEncrypt.js b/commons/utils/rsaEncrypt.js new file mode 100644 index 0000000..1948ddd --- /dev/null +++ b/commons/utils/rsaEncrypt.js @@ -0,0 +1,14 @@ +import JSEncrypt from 'jsencrypt/bin/jsencrypt.min' + +// 密钥对生成 http://web.chacuo.net/netrsakeypair + +const publicKey = 'MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANL378k3RiZHWx5AfJqdH9xRNBmD9wGD\n' + + '2iRe41HdTNF8RUhNnHit5NpMNtGL0NPTSSpPjjI1kJfVorRvaQerUgkCAwEAAQ==' + +// 加密 +export function encrypt(txt) { + const encryptor = new JSEncrypt() + encryptor.setPublicKey(publicKey) // 设置公钥 + return encryptor.encrypt(txt) // 对需要加密的数据进行加密 +} + diff --git a/commons/utils/safe-bottom.js b/commons/utils/safe-bottom.js new file mode 100644 index 0000000..9cfddc1 --- /dev/null +++ b/commons/utils/safe-bottom.js @@ -0,0 +1,35 @@ +import { + getCurrentInstance, +} from 'vue'; +export async function getElRect(elClass, instance,option) { + instance = instance ? instance : getCurrentInstance(); + const query = uni.createSelectorQuery().in(instance.proxy); + try{ + const res= await getEle(query,elClass,option) + return res + }catch(e){ + console.log(e); + } +} +async function getEle(query,elClass,option){ + return new Promise((resolve, reject)=>{ + query.select('.' + elClass).fields({ + size: true, + ...option + }, res => { + // 如果节点尚未生成,res值为null,循环调用执行 + if (!res) { + return setTimeout(() => { + getEle(query,elClass,option); + }, 10); + } + resolve(res); + }).exec(); + }) + +} + +export async function getSafeBottomHeight(className, height = 16) { + const bottomEle = await getElRect(className) + return bottomEle.height + height +} \ No newline at end of file diff --git a/commons/utils/saveImg.js b/commons/utils/saveImg.js new file mode 100644 index 0000000..98533ad --- /dev/null +++ b/commons/utils/saveImg.js @@ -0,0 +1,38 @@ +// 保存图片 +export function saveHeadImgFile(base64, quality) { + const bitmap = new plus.nativeObj.Bitmap("test"); + return new Promise((resolve, reject) => { + // 从本地加载Bitmap图片 + bitmap.loadBase64Data(base64, function() { + const url = "_doc/" + getTimeStamps() + ".png"; // url为时间戳命名方式 + + bitmap.save(url, { + overwrite: true, // 是否覆盖 + quality: quality // 图片清晰度 + }, (i) => { + console.log(url) + uni.saveImageToPhotosAlbum({ + filePath: url, + success: function() { + resolve({ + code: 0, + msg: '保存成功', + filePath: url + }); + }, + fail:function(){ + msg:'保存失败' + } + }); + }, (e) => { + reject('保存图片失败:' + JSON.stringify(e)); + }); + }, (e) => { + reject('加载图片失败:' + JSON.stringify(e)); + }); + }) +} + +function getTimeStamps (){ + return (new Date()).valueOf() +} \ No newline at end of file diff --git a/commons/utils/storageManage.js b/commons/utils/storageManage.js new file mode 100644 index 0000000..27c5fdd --- /dev/null +++ b/commons/utils/storageManage.js @@ -0,0 +1,290 @@ +/** + * 存储管理对象 + * 目标:将现有系统的所有需要存储的数据,统一管理 + * + * @author terrfly + * @site https://www.jeequan.com + * @date 2022/04/13 07:18 + */ + +import appConfig from "@/config/appConfig.js" + +// 应用级(vue级别)缓存, 当存在时则读取此值, 否则读取storage中的值。( vue线程内的缓存,不必要每次读取应用数据,影响性能) +const appCache = { + tokenVal: null, // token取值 + currentUser: null, // 当前商户信息 +} + +const model = { + + setLogin(res){ + const user=res.user.user + uni.setStorageSync('logoutHandle',false) + uni.setStorageSync('shopId', res.shopId) + uni.setStorageSync('shopName',res.shopName) + uni.setStorageSync('logo',res.logo) + uni.setStorageSync('loginType',res.loginType) + uni.setStorageSync('shopUserId',user.id) + if(res.loginType=='staff'){ + uni.setStorageSync('merchantName',user.createBy||user.updateBy) + } + }, + // 退出清空所有的缓存数据。 (不包含 环境相关) + cleanByLogout: () => { + // 1. 清空app级别缓存。 + Object.keys(appCache).forEach(k => appCache[k] = null) + const merchantName=uni.getStorageSync('merchantName') + const MerchantId=uni.getStorageSync('MerchantId') + let envName = model.env() // 获取到当前的环境变量 + uni.clearStorageSync() // 清除所有的缓存信息 + uni.setStorageSync('merchantName',merchantName) + uni.setStorageSync('MerchantId',MerchantId) + model.env(envName) // 重置env + }, + + // 获取和放置token + token: (val, isDelete = false) => { + if (isDelete) { + appCache.tokenVal = "" + return uni.removeStorageSync(appConfig.tokenKey) + } + + if (val) { + // 有值,为放置 + appCache.tokenVal = val + uni.setStorageSync(appConfig.tokenKey, val) + } else { + // 否则为获取 + + if (!appCache.tokenVal) { + //缓存取不到,获取应用本地信息 + appCache.tokenVal = uni.getStorageSync(appConfig.tokenKey) + } + return appCache.tokenVal + } + }, + // 获取和放置shopId + shopId: (val, isDelete = false) => { + if (isDelete) { + appCache.shopId = "" + return uni.removeStorageSync('shopId') + } + + if (val) { + // 有值,为放置 + appCache.shopId = val + uni.setStorageSync('shopId', val) + } else { + // 否则为获取 + + if (!appCache.shopId) { + //缓存取不到,获取应用本地信息 + appCache.shopId = uni.getStorageSync('shopId') + } + return appCache.shopId + } + }, + // 获取和放置店铺员工id + shopUserId: (val, isDelete = false) => { + if (isDelete) { + appCache.shopUserId = "" + return uni.removeStorageSync('shopUserId') + } + + if (val) { + // 有值,为放置 + appCache.shopUserId = val + uni.setStorageSync('shopUserId', val) + } else { + // 否则为获取 + + if (!appCache.shopUserId) { + //缓存取不到,获取应用本地信息 + appCache.shopUserId = uni.getStorageSync('shopUserId') + } + return appCache.shopUserId + } + }, + // 获取和放置useType就餐类型 + useType: (val, isDelete = false) => { + if (isDelete) { + appCache.useType = "" + return uni.removeStorageSync('useType') + } + + if (val) { + // 有值,为放置 + appCache.useType = val + uni.setStorageSync('useType', val) + } else { + // 否则为获取 + + if (!appCache.useType) { + //缓存取不到,获取应用本地信息 + appCache.useType = uni.getStorageSync('useType') + } + return appCache.useType + } + }, + // 缓存代客下单商品 + cacheGoods: (val, isDelete = false) => { + if (isDelete) { + appCache.cacheGoods = "" + return uni.removeStorageSync('cacheGoods') + } + + if (val) { + // 有值,为放置 + appCache.cacheGoods = val + uni.setStorageSync('cacheGoods', val) + } else { + // 否则为获取 + + if (!appCache.cacheGoods) { + //缓存取不到,获取应用本地信息 + appCache.cacheGoods = uni.getStorageSync('cacheGoods') + } + return appCache.cacheGoods + } + }, + // 缓存代客下单商品节点信息缓存 + cacheGoodsNode: (val, isDelete = false) => { + if (isDelete) { + appCache.cacheGoodsNode = "" + return uni.removeStorageSync('cacheGoodsNode') + } + + if (val) { + // 有值,为放置 + appCache.cacheGoodsNode = val + uni.setStorageSync('cacheGoodsNode', val) + } else { + // 否则为获取 + + if (!appCache.cacheGoodsNode) { + //缓存取不到,获取应用本地信息 + appCache.cacheGoodsNode = uni.getStorageSync('cacheGoodsNode') + } + return appCache.cacheGoodsNode + } + }, + // 已经登录的用户记录 + loggedInUser: (addUserName = null, removeUserName = null) => { + let key = "loggedInUserList" + + // 删除 + if (removeUserName) { + let nameList = uni.getStorageSync(key) || [] + if (nameList.length <= 0) { + //不存在数据 + return false + } + + let hasUserIndex = nameList.indexOf(removeUserName) + if (hasUserIndex >= 0) { + nameList.splice(hasUserIndex, 1) //删除 + uni.setStorageSync(key, nameList) + } + + return false + } + + // 有新插入的记录 + if (addUserName) { + let nameList = uni.getStorageSync(key) || [] + + let hasUser = false + for (let i = 0; i < nameList.length; i++) { + if (nameList[i] == addUserName) { + hasUser = true + } + } + + // 包含记录 + if (hasUser) { + return false + } + + // 最多存储 5 个 + if (nameList.length >= 5) { + nameList.splice(0, 1) //删除第一个 + } + nameList.push(addUserName) + uni.setStorageSync(key, nameList) + + //获取 + } else { + return uni.getStorageSync(key) || [] //默认空数组 + } + }, + + // 用户信息 + userInfo: (currentUserInfo) => { + if (currentUserInfo) { + // 仅保存基础数据 + let saveUser = { + + sysUserId: currentUserInfo.sysUserId, // 用户ID + realname: currentUserInfo.realname, // 用户姓名 + avatarUrl: currentUserInfo.avatarUrl, // 头像 + telphone: currentUserInfo.telphone, // 手机号 + userType: currentUserInfo.userType, // 用户类型 + + mchNo: currentUserInfo.userNo, // 商户No + mchShortName: currentUserInfo.shortName, // 商户简称 + mchType: currentUserInfo.mchType, // 商户类型 + mchLevel: currentUserInfo.mchLevel, // 商户级别 + isHasMemberEnt:currentUserInfo.isHasMemberEnt,// 是否购买会员模块 + entIdList: currentUserInfo.entIdList, // 权限集合List + + } + uni.setStorageSync("currentUserInfo", saveUser) // 改变存储 + appCache.currentUser = null + } + + if(!appCache.currentUser){ // 获取缓存数据 + appCache.currentUser = uni.getStorageSync("currentUserInfo") + } + + return appCache.currentUser + }, + + // 项目环境变量:(测试、 生产的切换) + env: (envMode) => { + if (envMode) { + uni.setStorageSync(appConfig.storeEnvEnumKey, envMode) // 改变存储 + } + return uni.getStorageSync(appConfig.storeEnvEnumKey) + }, + + // push 状态是否开启 + pushIsOpen: (pushFlag) => { + if (pushFlag) { + uni.setStorageSync('pushFlag', pushFlag) // 改变存储 + } + return uni.getStorageSync('pushFlag') + }, + // 网站信息 + siteInfos: (siteInfos) => { + if (siteInfos) { + uni.setStorageSync("siteInfos", siteInfos) // 改变存储 + } + return uni.getStorageSync("siteInfos") + }, + + // unipush2 cid + uniPush2Cid: (uniPush2Cid) => { + if (uniPush2Cid) { + uni.setStorageSync("uniPush2Cid", uniPush2Cid) // 改变存储 + } + return uni.getStorageSync("uniPush2Cid") + }, + uploadImgSize: (uploadImgSize) => { + if (uploadImgSize) { + uni.setStorageSync("uploadImgSize", uploadImgSize) // 存储 上传 图片大小限制 + } + return uni.getStorageSync("uploadImgSize") + }, +} + +export default model diff --git a/commons/utils/timeInspect.js b/commons/utils/timeInspect.js new file mode 100644 index 0000000..5097766 --- /dev/null +++ b/commons/utils/timeInspect.js @@ -0,0 +1,14 @@ +import dayjs from 'dayjs' //时间格式库 +import infoBox from '@/commons/utils/infoBox.js' +// 时间校验 用于筛选 开始 时间不能大于结束 开始结束时间必选 时间 返回值 true 和 false +export const startAndEndTime = (start, end) => { + if (!start || !end) { + infoBox.showToast('请选择开始或结束时间') + return false + } + if (dayjs(start).isAfter(end)) { + infoBox.showToast('开始时间不能大于结束时间') + return false + } + return true +} diff --git a/commons/utils/timer.js b/commons/utils/timer.js new file mode 100644 index 0000000..546fa94 --- /dev/null +++ b/commons/utils/timer.js @@ -0,0 +1,54 @@ +/** + * 任务执行器 + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2022/11/15 16:30 + */ +const model = { + + + // 任务启动工具, 每 xxs调用一次, 知道多次x次为止。 + // 注意: 启动后将立马调用一次, 而不是1s后再调用。 + + // 参数: + // allCount: 全部的次数 (支持promise 并不一定是 秒) + // stepSecond : 步伐(单位: 秒) + // callbackFunc 回调函数, 支持返回 boolean 或者 promise , + // 注意: boolean类型: true 进入下一次循环, false: 停止任务。 + // promise类型: then 进入下一次循环, catch: 停止任务。 + startTimeoutTask: (stepSecond, allCount, callbackFunc) => { + + // 不存在回调函数 + if(!callbackFunc){ + return false; + } + + let callbackResult = callbackFunc(allCount) + + // 明确返回false, 说明不再循环 + if(callbackResult === false){ + return false + } + + // 不包含剩余次数了。 + if(allCount <= 0){ + return false + } + + // promise + if(typeof callbackResult == 'object'){ + + callbackResult.then(() => { + setTimeout(() => model.startTimeoutTask(stepSecond, --allCount, callbackFunc), (stepSecond * 1000) ) + }) + + }else{ // 其他boolean类型, 或返回不明确, 继续下一次任务。 + + setTimeout(() => model.startTimeoutTask(stepSecond, --allCount, callbackFunc), (stepSecond * 1000) ) + } + } +} + +export default model + diff --git a/commons/utils/unionScan.js b/commons/utils/unionScan.js new file mode 100644 index 0000000..cf04a1e --- /dev/null +++ b/commons/utils/unionScan.js @@ -0,0 +1,62 @@ +/** + * 统一扫码, 支持登录、 码牌绑定、 打印机、 等 + * + * @author terrfly + * @site https://www.jeepay.vip + * @date 2022/11/22 10:38 + */ + +import { $parseQrCodeUrl } from '@/http/apiManager.js' + +const model = { + + // 扫码结果类型 + QR_TYPE_LOGIN: 'QR_TYPE_LOGIN', // 登录 + QR_TYPE_QRC: 'QR_TYPE_QRC', // 码牌 + QR_TYPE_PRINTER: 'QR_TYPE_PRINTER', // 打印机 + QR_TYPE_OTHER: 'QR_TYPE_OTHER', // 其他 + + + returnFunc: (type, bizValue, originQrVal) => { + return { type: type, bizValue: bizValue, originQrVal: originQrVal} + }, + + // 解析 码牌 + parseQrc: (originQrVal) => { + return $parseQrCodeUrl(originQrVal).then( ({bizData}) => { + return model.returnFunc(model.QR_TYPE_QRC, bizData, originQrVal) + }) + }, + + + // 返回 类型 和 扫码的值 + // 参数: 是否解析qrc , 默认不解析 + scan: (isParseQRC = false) => { + + return uni.scanCode().then(({ result }) => { + + // 登录类型 + if(result.startsWith("JEEPAY_LOGIN_QR_")){ + return model.returnFunc(model.QR_TYPE_LOGIN, result.substring(16), result) + } + + + if(isParseQRC){ + return model.parseQrc(result).then( (res) => { + return res; + }).catch(() => { + return model.returnFunc(model.QR_TYPE_OTHER, result, result) + }) + }else{ + + return model.returnFunc(model.QR_TYPE_OTHER, result, result) + + } + + }) + } + +} + +export default model + diff --git a/commons/utils/useStroage.js b/commons/utils/useStroage.js new file mode 100644 index 0000000..da32ab5 --- /dev/null +++ b/commons/utils/useStroage.js @@ -0,0 +1,14 @@ +export default { + get(key) { + return uni.getStorageSync(key) + }, + set(key, value) { + uni.setStorageSync(key, value) + }, + del(key) { + uni.removeStorageSync(key) + }, + clear() { + uni.clearStorageSync() + } +} \ No newline at end of file diff --git a/commons/utils/versionManage.js b/commons/utils/versionManage.js new file mode 100644 index 0000000..0f98233 --- /dev/null +++ b/commons/utils/versionManage.js @@ -0,0 +1,121 @@ +import { $versionDetection } from '@/http/apiManager.js'; +import appConfig from '@/config/appConfig.js' + +// app更新 +function appPlusUpdate(sign){ + + // 获取版本号 + plus.runtime.getProperty(plus.runtime.appid, function(inf) { + + // 调起接口查询 + $versionDetection({versionNumber: inf.versionCode}) + .then(({ bizData }) => { + + //返回data为空或者版本号一致 + if (!bizData || Object.keys(bizData).length == 0 || !bizData.versionSerialNumber || bizData.versionSerialNumber == inf.versionCode) { + if(sign === 'checked') { + uni.showToast({ + title: '已是最新版本' + }) + } + return false; + } + // 是否强制更新 + let isForceUpdate = bizData.forceUpdate == 1 + uni.showModal({ + title: '发现新版本:' + bizData.versionName, + showCancel: !isForceUpdate , + content: bizData.versionDesc, + confirmText: '立即更新', + confirmColor: '#108EE9', + success: function(r) { + if (r.confirm) { + downLoad(bizData.downloadUrl); + }else{ + // 强制更新也需要更新 + if(isForceUpdate){ + downLoad(bizData.downloadUrl); + } + } + } + }); + }); + }); +} + +//下载更新包 +function downLoad(url) { + + if (!url) { + uni.showToast({icon: 'none',title: '下载地址错误'}); + return false; + } + // 下载文件 + uni.showLoading({title: '更新中'}); + uni.downloadFile({ + url: url, + success: res => { + uni.hideLoading(); + if (res.statusCode === 200) { + uni.showToast({title: '下载成功'}); + plus.runtime.install(res.tempFilePath); + } + }, + fail: res => { + uni.hideLoading(); + } + }); +} + + +// 获取当前版本 & 检查 +export function getCurrentVersionPromise() { + let isApp = false + +// #ifdef APP-PLUS + isApp = true +// #endif + + if(!isApp){ + return Promise.reject() + } + +// 获取版本号 + return new Promise((resolve, reject) => { + plus.runtime.getProperty(plus.runtime.appid, function(inf) { + resolve(inf) + }) + }) + +} + +// 获取当前版本 & 检查 +export function checkCurrVersion(sign) { +// #ifdef APP-PLUS + switch(uni.getSystemInfoSync().platform){ + case 'android': + appPlusUpdate(sign) //仅安卓更新 + break; + case 'ios': + break; + default: + break; + } +// #endif +} + + +//同步取出ext.json对象 +export function getExtStoreId(){ + try{ + const extConfig = uni.getExtConfigSync() + if(extConfig.domain){ + appConfig.env.JEEPAY_BASE_URL = extConfig.domain + } + // uni.showToast({title: JSON.stringify(extConfig),icon:"none",duration:3000}); + console.log(extConfig,'extJson对象'); + return extConfig; + }catch(err){ + console.log(err,'getExtStoreId__error') + } +} \ No newline at end of file diff --git a/commons/week.js b/commons/week.js new file mode 100644 index 0000000..b7b85da --- /dev/null +++ b/commons/week.js @@ -0,0 +1 @@ +export const $weeks=['周一','周二','周三','周四','周五','周六','周日']; \ No newline at end of file diff --git a/components/Button/Button.vue b/components/Button/Button.vue new file mode 100644 index 0000000..3bed10f --- /dev/null +++ b/components/Button/Button.vue @@ -0,0 +1,37 @@ + + + + + + + \ No newline at end of file diff --git a/components/my-components/edit-discount.vue b/components/my-components/edit-discount.vue new file mode 100644 index 0000000..dfabe73 --- /dev/null +++ b/components/my-components/edit-discount.vue @@ -0,0 +1,208 @@ + + + + + \ No newline at end of file diff --git a/components/my-components/my-action-sheet.vue b/components/my-components/my-action-sheet.vue new file mode 100644 index 0000000..dd9e208 --- /dev/null +++ b/components/my-components/my-action-sheet.vue @@ -0,0 +1,107 @@ + + + + + \ No newline at end of file diff --git a/components/my-components/my-button.vue b/components/my-components/my-button.vue new file mode 100644 index 0000000..95364a3 --- /dev/null +++ b/components/my-components/my-button.vue @@ -0,0 +1,158 @@ + + + + + \ No newline at end of file diff --git a/components/my-components/my-date-pickerview.vue b/components/my-components/my-date-pickerview.vue new file mode 100644 index 0000000..7507b74 --- /dev/null +++ b/components/my-components/my-date-pickerview.vue @@ -0,0 +1,601 @@ + + + + + \ No newline at end of file diff --git a/components/my-components/my-empty.vue b/components/my-components/my-empty.vue new file mode 100644 index 0000000..9fbf231 --- /dev/null +++ b/components/my-components/my-empty.vue @@ -0,0 +1,38 @@ + + + + + \ No newline at end of file diff --git a/components/my-components/my-icons.vue b/components/my-components/my-icons.vue new file mode 100644 index 0000000..1a5872e --- /dev/null +++ b/components/my-components/my-icons.vue @@ -0,0 +1,71 @@ + + + + + \ No newline at end of file diff --git a/components/my-components/my-img-empty.vue b/components/my-components/my-img-empty.vue new file mode 100644 index 0000000..938aa44 --- /dev/null +++ b/components/my-components/my-img-empty.vue @@ -0,0 +1,32 @@ + + + + + \ No newline at end of file diff --git a/components/my-components/my-login.vue b/components/my-components/my-login.vue new file mode 100644 index 0000000..3ea5aad --- /dev/null +++ b/components/my-components/my-login.vue @@ -0,0 +1,326 @@ + + + + \ No newline at end of file diff --git a/components/my-components/my-mask.vue b/components/my-components/my-mask.vue new file mode 100644 index 0000000..ec036d4 --- /dev/null +++ b/components/my-components/my-mask.vue @@ -0,0 +1,79 @@ + + + + + \ No newline at end of file diff --git a/components/my-components/my-model.vue b/components/my-components/my-model.vue new file mode 100644 index 0000000..b8ae871 --- /dev/null +++ b/components/my-components/my-model.vue @@ -0,0 +1,232 @@ + + + + + \ No newline at end of file diff --git a/components/my-components/my-pagination.vue b/components/my-components/my-pagination.vue new file mode 100644 index 0000000..0dbf76c --- /dev/null +++ b/components/my-components/my-pagination.vue @@ -0,0 +1,150 @@ + + + + + \ No newline at end of file diff --git a/components/my-components/my-pickerview.vue b/components/my-components/my-pickerview.vue new file mode 100644 index 0000000..8dab2bc --- /dev/null +++ b/components/my-components/my-pickerview.vue @@ -0,0 +1,344 @@ + + + + + \ No newline at end of file diff --git a/components/my-components/my-radio.vue b/components/my-components/my-radio.vue new file mode 100644 index 0000000..e6a6836 --- /dev/null +++ b/components/my-components/my-radio.vue @@ -0,0 +1,96 @@ + + + + \ No newline at end of file diff --git a/components/my-components/my-reportDamage.vue b/components/my-components/my-reportDamage.vue new file mode 100644 index 0000000..c2cbd4f --- /dev/null +++ b/components/my-components/my-reportDamage.vue @@ -0,0 +1,345 @@ + + + + + \ No newline at end of file diff --git a/components/my-components/my-search.vue b/components/my-components/my-search.vue new file mode 100644 index 0000000..ee4fe43 --- /dev/null +++ b/components/my-components/my-search.vue @@ -0,0 +1,59 @@ + + + + + \ No newline at end of file diff --git a/components/my-components/my-step.vue b/components/my-components/my-step.vue new file mode 100644 index 0000000..9474c6b --- /dev/null +++ b/components/my-components/my-step.vue @@ -0,0 +1,95 @@ + + + + + \ No newline at end of file diff --git a/components/my-components/my-switch.vue b/components/my-components/my-switch.vue new file mode 100644 index 0000000..1184b4d --- /dev/null +++ b/components/my-components/my-switch.vue @@ -0,0 +1,163 @@ + + + + + \ No newline at end of file diff --git a/components/my-components/my-tabs.vue b/components/my-components/my-tabs.vue new file mode 100644 index 0000000..b17befe --- /dev/null +++ b/components/my-components/my-tabs.vue @@ -0,0 +1,144 @@ + + + + + \ No newline at end of file diff --git a/components/my-components/my-tag.vue b/components/my-components/my-tag.vue new file mode 100644 index 0000000..40b174c --- /dev/null +++ b/components/my-components/my-tag.vue @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/components/my-components/my-time-area-pickerview.vue b/components/my-components/my-time-area-pickerview.vue new file mode 100644 index 0000000..9686372 --- /dev/null +++ b/components/my-components/my-time-area-pickerview.vue @@ -0,0 +1,49 @@ + + + + + \ No newline at end of file diff --git a/components/my-components/my-up-upload.vue b/components/my-components/my-up-upload.vue new file mode 100644 index 0000000..bfbba13 --- /dev/null +++ b/components/my-components/my-up-upload.vue @@ -0,0 +1,118 @@ + + + + + \ No newline at end of file diff --git a/components/my-components/my-upload-file.vue b/components/my-components/my-upload-file.vue new file mode 100644 index 0000000..5d187ca --- /dev/null +++ b/components/my-components/my-upload-file.vue @@ -0,0 +1,116 @@ + + + + + \ No newline at end of file diff --git a/config/appConfig.js b/config/appConfig.js new file mode 100644 index 0000000..8e2a36a --- /dev/null +++ b/config/appConfig.js @@ -0,0 +1,27 @@ +const appConfig = { + + // 项目名称 + appName: '银收客', + + // token取值key + tokenKey: 'iToken', + // tokenKey: 'satoken', + + // 环境变量相关 + env: {}, + + // 环境变量常量 + ENV_ENUM: { + DEVELOPMENT: 'development', // 本地调试地址 + TEST: 'test', // 测试地址 + DEMO: 'demo', // 演示环境 + PRODUCTION: 'production' // 生产环境 + }, + + storeEnvEnumKey: 'currentEnvEnum', // 本地存储的envkey的值 + + encryptKey: '1234567890123456' // http数据加解密的key + +} + +export default appConfig; \ No newline at end of file diff --git a/env/config.js b/env/config.js new file mode 100644 index 0000000..55856a5 --- /dev/null +++ b/env/config.js @@ -0,0 +1,45 @@ +/** + * ENV 的封装 + * 由于uniapp 无法设置.env等打包属性,实现线上,线下多版本配置属性的无缝切换。 + * process.env.NODE_ENV 将在打包环境通过编译器进行替换, 线上打包后无法获取到 process对象。 所以将配置属性统一封装到appConfig中。 + * + * 环境地址环境枚举详见: appConfig.js + * + * @author terrfly + * @site https://www.jeequan.com + * @date 2021/12/16 17:57 + */ +import appConfig from '@/config/appConfig.js'; + +// uni-app 暂时不支持动态import(导包app报错), 需要将所有的env全部导入 = = 、 +import development from './env.development.js'; +import test from './env.test.js'; +import demo from './env.demo.js'; +import production from './env.production.js'; + +const allEnvMap = { + development: development, + test: test, + demo: demo, + production: production +} + +// 获取当前环境变量 +const processEnv = process.env.NODE_ENV + +// 改变env环境 +function changeEnv(envMode){ + + appConfig.env = allEnvMap[envMode || processEnv] + + // // 动态导包的方式:设置全局env配置项目 : 当参数不存在, 那么获取node环境 + // import(`./env.${envMode || processEnv}.js`).then(module => { + // appConfig.env = module.default + // }).catch(() => { + // appConfig.env = production //当出现错误, 比如本地没有复制dev文件时, 默认使用生产环境 + // }) +} + +export default { changeEnv: changeEnv } + + diff --git a/env/env.demo.js b/env/env.demo.js new file mode 100644 index 0000000..ebfe46d --- /dev/null +++ b/env/env.demo.js @@ -0,0 +1,6 @@ +export default { + 'JEEPAY_BASE_URL': 'https://b.rscygroup.com', // 请求URL(生产环境) + 'JEEPAY_BASE_URL_H5': 'https://b.rscygroup.com' + // 'JEEPAY_BASE_URL': 'http://192.168.1.8:9218' // 请求URL(测试环境) + // 'JEEPAY_BASE_URL': 'https://b.qilinshuzi.com' //支付网关URL +} \ No newline at end of file diff --git a/env/env.development.js b/env/env.development.js new file mode 100644 index 0000000..ebfe46d --- /dev/null +++ b/env/env.development.js @@ -0,0 +1,6 @@ +export default { + 'JEEPAY_BASE_URL': 'https://b.rscygroup.com', // 请求URL(生产环境) + 'JEEPAY_BASE_URL_H5': 'https://b.rscygroup.com' + // 'JEEPAY_BASE_URL': 'http://192.168.1.8:9218' // 请求URL(测试环境) + // 'JEEPAY_BASE_URL': 'https://b.qilinshuzi.com' //支付网关URL +} \ No newline at end of file diff --git a/env/env.production.js b/env/env.production.js new file mode 100644 index 0000000..ebfe46d --- /dev/null +++ b/env/env.production.js @@ -0,0 +1,6 @@ +export default { + 'JEEPAY_BASE_URL': 'https://b.rscygroup.com', // 请求URL(生产环境) + 'JEEPAY_BASE_URL_H5': 'https://b.rscygroup.com' + // 'JEEPAY_BASE_URL': 'http://192.168.1.8:9218' // 请求URL(测试环境) + // 'JEEPAY_BASE_URL': 'https://b.qilinshuzi.com' //支付网关URL +} \ No newline at end of file diff --git a/env/env.test.js b/env/env.test.js new file mode 100644 index 0000000..5ba49d6 --- /dev/null +++ b/env/env.test.js @@ -0,0 +1,5 @@ +export default { + // 'JEEPAY_BASE_URL': 'https://b.shouyinbei.com' // 请求URL(测试地址) + 'JEEPAY_BASE_URL_H5': 'https://b.rscygroup.com', + 'JEEPAY_BASE_URL': 'https://b.rscygroup.com' //支付网关URL +} \ No newline at end of file diff --git a/ext.json b/ext.json new file mode 100644 index 0000000..7a8f6b6 --- /dev/null +++ b/ext.json @@ -0,0 +1,8 @@ +{ + "extEnable": true, + "extAppid":"wx9b4f8ff05754599f", + "directCommit": false, + "ext": { + "name": "wechat" + } +} \ No newline at end of file diff --git a/http/apiManager.js b/http/apiManager.js new file mode 100644 index 0000000..c5e8c7a --- /dev/null +++ b/http/apiManager.js @@ -0,0 +1,624 @@ +/** + * api接口管理, 全部以$开头 + * @author terrfly + * @site https://www.jeequan.com + * @date 2021/12/17 09:57 + */ + +import http from './http.js' +import appConfig from '@/config/appConfig.js' +import { + Base64 +} from 'js-base64' +import infoBox from '@/commons/utils/infoBox.js' + +export const req = { + list: (uri, params) => { + return http.req(uri, params, 'GET', false) + }, + + add: (uri, data) => { + return http.req(uri, data, 'POST', false) + }, + + getById: (uri, bizId) => { + return http.req(`${uri}/${bizId}`, {}, 'GET', false) + }, + + updateById: (uri, bizId, data) => { + return http.req(`${uri}/${bizId}`, data, 'PUT', false) + }, + + delById: (uri, bizId) => { + return http.req(`${uri}/${bizId}`, {}, 'DELETE', false) + }, +} + +export const reqLoad = { + list: (uri, params) => { + return http.req(uri, params, 'GET') + }, + + add: (uri, data) => { + return http.req(uri, data, 'POST') + }, + + getById: (uri, bizId) => { + return http.req(`${uri}/${bizId}`, {}, 'GET') + }, + + updateById: (uri, bizId, data) => { + return http.req(`${uri}/${bizId}`, data, 'PUT') + }, + + delById: (uri, bizId) => { + return http.req(`${uri}/${bizId}`, {}, 'DELETE') + }, + + // 通用 新增 or 更新 + addOrUpdate: (bizId, url, data, showMessage = true) => { + //包含bizId 请求的是修改接口 + if (bizId) { + return reqLoad.updateById(url, bizId, data).then((res) => { + if (showMessage) { + return infoBox.showSuccessToast('更新成功').then(() => res) + } + return Promise.resolve(res) + }) + } else { + return reqLoad.add(url, data).then((res) => { + if (showMessage) { + return infoBox.showSuccessToast('新增成功').then(() => res) + } + return Promise.resolve(res) + }) + } + } +} + +/** 上传文件 url **/ +export const API_URL_SINGLE_FILE_UPLOAD = '/api/ossFiles/singleFile' + +/** 公告 **/ +export const API_URL_SYS_ARTICLES = '/api/sysArticles' + +/** 支付订单列表 */ +export const API_URL_PAY_ORDER_LIST = '/api/payOrder' + +/** 退款订单列表 */ +export const API_URL_REFUND_LIST = '/api/refundOrder' + +/** 商户应用 */ +export const API_URL_MCH_APP_LIST = '/api/mchApps' + +/** 门店列表 */ +export const API_URL_MCH_STORE_LIST = '/api/mchStore' + +/** 通知接收人列表 */ +export const API_URL_WXMP_USER_LIST = '/api/wxmp' + +/** 进件管理 */ +export const API_URL_MCH_APPLYMENT_LIST = '/api/mchApplyments' + +/** 员工管理 */ +export const API_URL_SYS_USER_LIST = '/api/sysUsers' + +/** 码牌管理 */ +export const API_URL_SYS_CODE_LIST = '/api/mchQrCodes' + +/** 通用设备管理 deviceType 1-喇叭 2-打印机 3-扫码POS 4-智能POS 6-刷脸设备*/ +export const API_URL_SYS_DEVICE_LIST = '/api/store/device' + +/** 辅助终端管理*/ +export const API_URL_SYS_TERMINALS = '/api/mchTerminals' + +/** 用户绑定门店列表 */ +export const API_URL_USER_BIND_STORE_LIST = '/api/mchStore/userStoreRelas' + +/** 商户支付通道列表 */ +export const API_URL_PAY_PASSAGE_LIST = '/api/mch/payPassages' +/** 广告列表 */ +export const API_URI_PAY_AD_LIST = '/api/advert' +/** 如意门店操作 */ +export const API_URI_DEV_RUYI = '/api/alipayShop' + +/** 会员管理 */ +export const API_URL_MEMBERS = '/api/member' + +/** 会员充值记录 */ +export const API_URL_MEMBER_RECHARGE_RECORDS = '/api/member/rechargeRecord' + +/** 会员充值规则管理 */ +export const API_URL_MEMBER_RECHARGE_RULES = '/api/member/rechargeRule' + +/** 会员账户流水 */ +export const API_URL_MEMBER_ACCOUNT_HISTORY = '/api/member/accountHistory' + +//营销红包开始 + +//红包规则 +export const API_URL_MCH_REF_PACKET_RULE_LIST = '/api/redPacketRule' +//新增红包规则 +export const API_URL_MCH_REF_PACKET_RULE_ADD = '/api/redPacketRule' + +//顾客统计 +export const API_URL_MCH_REF_PACKET_RULE_COUNT = '/api/redPacketUser/count' +//顾客列表 +export const API_URL_MCH_REF_PACKET_USER_LIST = '/api/redPacketUser' +//顾客红包 +export const API_URL_MCH_REF_PACKET_INFO_LIST = '/api/redPacketInfo' +//红包查询规则详情 +export const API_URL_MCH_REF_PACKET_RULE_QUERY = '/api/redPacketRule' +//红包修改规则 +export const API_URL_MCH_REF_PACKET_RULE_EDIT = '/api/redPacketRule/edit' +//红包余额变动明细列表 +export const API_URL_MCH_REF_PACKET_CHANGE = '/api/redPacketChange' +//渠道列表 +export const API_URL_MCH_ISV_LIST = '/api/isvInfo/isvInfoList' + + + +/* 密码登录 */ +export function $loginByPwd(username, pwd, safetyCode) { + // 登录类型 + let lt = '' + // #ifdef APP-PLUS + lt = Base64.encode('APP') + // #endif + // #ifdef H5 || MP-WEIXIN + lt = Base64.encode('LITE') + // #endif + + let data = { + ia: Base64.encode(username), + ip: Base64.encode(pwd), + mc: safetyCode ? Base64.encode(safetyCode) : null, + lt: lt, + } + return http.req('/api/anon/auth/validate', data, 'POST') +} + +/* 验证码登录 */ +export function $phoneCodeLogin(phone, code) { + // 登录类型 + let lt = '' + // #ifdef APP-PLUS + lt = Base64.encode('APP') + // #endif + // #ifdef H5 || MP-WEIXIN + lt = Base64.encode('LITE') + // #endif + + let data = { + phone: Base64.encode(phone), + code: Base64.encode(code), + lt: lt, + } + + return http.req('/api/anon/auth/phoneCode', data, 'POST') +} + +// 找回密码 +export function $retrieve({ + phone, + code, + newPwd +}) { + let data = { + phone: Base64.encode(phone), + code: Base64.encode(code), + newPwd: newPwd ? Base64.encode(newPwd) : '' + } + return http.req('/api/anon/cipher/retrieve', data, 'POST') +} + +/* 修改密码 */ +export function $modifyPwd({ + originalPwd, + confirmPwd +}) { + let data = { + originalPwd: Base64.encode(originalPwd), + confirmPwd: Base64.encode(confirmPwd) + } + return http.req("/api/current/modifyPwd", data, "PUT") +} + +/* 注册新商户 */ +export function $mchRegister({ + mchName, + confirmPwd, + inviteCode, + phone, + code +}) { + let data = { + mchName: mchName, // 用户名称 + confirmPwd: Base64.encode(confirmPwd), // 确认密码 + inviteCode, // 邀请码 + phone: Base64.encode(phone), // 手机号 + code: Base64.encode(code), // 短信验证码 + } + return http.req('/api/anon/register/mchRegister', data, 'POST') +} + +/* 发送短信验证码 */ +export function $sendSms(data, smsType) { + return http.req('/api/anon/sms/code', { + phone: data.phone, + vercode: data.vercode, + vercodeToken: data.vercodeToken, + smsType: smsType + }, 'POST') +} + +/* 获取个人信息 */ +export function $userInfo(cid1, cid2) { + return http.req('/api/current/user', { + cid1, + cid2 + }, 'GET') +} + +/* 获取公司信息 */ +export function $getSiteInfos() { + return http.req('/api/anon/siteInfos', {}, 'GET') +} + +// 隐私政策与服务协议 +export function $getTreaty() { + return http.req('/api/anon/treaty', {}, 'GET') +} + +/* 快捷收银 */ +export function $appPay(storeId, amount, sellerRemark, wayCode, authCode) { + let data = { + storeId, + amount, + sellerRemark, + wayCode, + authCode + } + + // 二维码, 返回结果为 图片地址 + if (wayCode == 'QR_CASHIER') { + data.payDataType = 'codeImgUrl' + } + + return http.req('/api/pay/app', data, 'POST') +} + +/* 当前商户信息 */ +export function $getMchInfo() { + return http.req('/api/mainChart', {}, 'GET') +} + +/* 订单打印 */ +export function $payOrderPrint(orderId) { + return http.req('/api/payOrder/print/' + orderId, {}, 'GET') +} + +/* 订单退款 */ +export function $payOrderRefund(orderId, refundAmount, refundReason, refundPassword) { + return http.req( + '/api/payOrder/refunds/' + orderId, { + refundAmount: refundAmount, + refundReason: refundReason, + refundPassword: Base64.encode(refundPassword), + refundModel: 1 + }, + 'POST' + ) +} +// // 首页统计信息 +// export function $indexStatistics (queryDateRange) { +// return http.req('/api/mainChart/payDayCount', { queryDateRange }, 'GET') +// } + +// 首页统计信息 +export function $indexStatistics(queryDateRange) { + return http.req('/api/payOrder/count?queryDateRange', { + queryDateRange + }, 'GET') +} + +// 统计报表 +export function $getStatInfo(data) { + return http.req('/api/statistic/total', data, 'GET', false) +} +// 统计报表设备 门店 支付方式统计 +export function $getStatistic(data) { + return http.req('/api/statistic', data, 'GET') +} + +/* 经纬度转换为areacode */ +export function $location2areacode(location) { + return http.req('/api/mchStore/location2areacode/', { + location: location + }, 'GET') +} + + +/* 获取上传form信息 */ +export function $ossFilesForm(bizType, file) { + let postData = { + bizType: bizType, + sourceFileName: file.name || file.path, // 如果没有name 则使用pach替换 + sourceFileSize: file.size, + } + + return http.req('/api/ossFiles/form', postData, 'POST') +} + +/* 系统设置 */ +// 获取语音播报开关信息 +export function $mchConfig(groupKey) { + return http.req('/api/mchConfig', { + groupKey: groupKey + }, 'GET') +} +// 修改语音播报开关信息 +export function $orderConfig(configData, mchNo) { + console.log('mchNo', mchNo); + return http.req('/api/mchConfig/orderConfig', { + configData: configData, + mchNo: mchNo + }, 'PUT') +} + +/* 修改个人信息 */ +export function $modifyUser({ + realname, + avatarUrl +}) { + return http.req("/api/current/user", { + realname, + avatarUrl + }, "PUT") +} + +/* 获取密码规则 */ +export function $getPasswordRules() { + return http.req("/api/anon/cipher/pwdRulesRegexp", "GET") +} + +// 验证是否有密码 +export function $isSipw() { + return http.req("/api/mchConfig/hasSipwValidate", "GET") +} + +// 验证原支付密码是否正确 +export function $isMchSipw(originalPwd) { + return http.req("/api/mchConfig/mchSipwValidate", { + originalPwd: Base64.encode(originalPwd) + }, "POST") +} + +/* 更新支付密码 */ +export function $updateMchSipw({ + originalPwd, + confirmPwd +}) { + let data = { + originalPwd: Base64.encode(originalPwd), + confirmPwd: Base64.encode(confirmPwd) + } + return http.req("/api/mchConfig/mchSipw", data, "PUT") +} + +/* 版本检测 */ +export function $versionDetection({ + versionNumber +}) { + return http.req("/api/anon/clientVersion/versionInfo", { + versionNumber: versionNumber + }, "GET") +} + +/* 查询用户权限 */ +export function $getUserEntRoles(sysUserId) { + return http.req("/api/sysUsers/userEntRoles/" + sysUserId, {}, "GET") +} + +/* 更新用户权限 */ +export function $updateUserEntRoles(sysUserId, ruleName, state) { + return http.req("/api/sysUsers/userEntRoles/" + sysUserId, { + ruleName, + state + }, "PUT") +} + + +/* 根据支付方式查询可配置的支付接口 */ +export function $getAvailablePayInterface(appId, wayCode) { + return http.req(`/api/mch/payPassages/availablePayInterface/${appId}/${wayCode}`, "GET") +} + +/* 支付方式配置支付接口 */ +export function $wayCodeConfigIfCode(appId, wayCode, ifCode) { + + let reqData = { + appId: appId, + wayCode: wayCode, + ifCode: ifCode, + state: 1 + } + return http.req(`/api/mch/payPassages/mchPassage`, reqData, "POST") +} +/*码牌扫码 二维码解析*/ +export function $parseQrCodeUrl(qrUrl) { + return http.req('/api/mchQrCodes/parseQrCodeUrl', { + qrUrl + }, 'GET') +} +/*码牌绑定*/ +export function $bindEmptyQR(qrcInfo) { + return http.req('/api/mchQrCodes/bindEmptyQR', qrcInfo, 'POST') +} +/*解绑码牌*/ +export function $unBindQrc(qrcId) { + return http.req('/api/mchQrCodes/unbind/' + qrcId, {}, 'POST') +} +/*码牌查询受支持的云喇叭设备*/ +export function $getHornList(qrcId) { + return http.req('/api/mchQrCodes/bindDevice/' + qrcId, 'GET') +} +/* 更新默认 */ +export function $updateTrmDefault(trmId, defaultFlag) { + return http.req('/api/mchTerminals/trmDefaults', { + trmId, + defaultFlag + }, 'PUT') +} + +/* 设备解绑 */ +export function $deviceUnbind(deviceId) { + return http.req('/api/store/device/unbind/' + deviceId, {}, 'POST') +} + + +/* 渠道报备列表 */ +export function $terminalChannelBindList(trmId) { + return http.req('/api/mchTerminals/channelBindInfos/' + trmId, {}, 'GET') +} + +/* 渠道报备 */ +export function $terminalChannelBindSend(trmId, ifCode) { + return http.req('/api/mchTerminals/channelSendup/' + trmId, { + ifCode: ifCode, + state: 1 + }, 'POST') +} + + +// 扫码登录 +export function $scanCodeLogin(qrcodeNo, qrcodeStatus) { + return http.req("/api/current/qrcode/login", { + qrcodeNo, + qrcodeStatus + }, "POST") +} + +// 云喇叭 播报测试 +export function $speakTest(devId, amount) { + return http.req("/api/store/device/speak/" + devId, amount, "POST") +} + +// 云打印 打印测试 +export function $printTest(devId, amount) { + return http.req(`/api/store/device/print/${devId}`, { + amount + }, "POST") +} + +/* 获取百度语音播报token */ +export function $getBaiduToken() { + return http.req("/api/pushinfo/getBaiduToken", {}, "GET") +} +// 获取通知接收人二维码图片 +export function $getWxMpInfo() { + return http.req("/api/wxmp/getWxmpInfo", {}, "GET") +} + +/* 获取进件通道列表 */ +export function $getAllAllowApplymentIfCodeList() { + return http.req("/api/payConfig/ifCodes", { + infoId: 'CURRENT', + configMode: 'mchApplyment' + }, "GET") +} +/* 查询店长可以绑定的门店 */ +export function $getBindStoreList(params) { + return http.req('/api/mchStore/bindStoreList', params, "GET") +} + +/* 提交unipush cid */ +export function $pushInfoRegister(data) { + console.log('push cid', data); + return http.req("/api/pushinfo/register", data, "POST") +} +/* 获取广告接口*/ +export function $adList(params) { + return http.req('/api/advert/appAdvert', params, 'GET') +} +/** 如意Lite 绑定解绑接口 */ +export function $BindLite(data) { + return http.req('/api/alipayIot/bind/' + data.deviceId, data, "POST") +} + +// 获取支付宝扫码授权 +export function $aliPayQrCodeOrApply(account = '', type = 'queryResult') { + return http.req(`/api/alipaySpOperation/${type}`, { + alipayAccount: account + }, type == 'apply' ? 'POST' : 'GET') +} +// 获取支付宝授权信息 +export function $aliAccountInfo() { + return http.req('/api/alipaySpOperation/authInfo', {}, 'GET') +} + +// 查询蚂蚁店铺状态 +export function $queryAliStore(storeId) { + return req.getById('/api/alipayShop/createResult', storeId) +} + + +// 获取上传图片 大小 +export function $getUploadImgSize() { + return http.req('/api/defaultConfig', {}, "GET") +} + +// 会员调账 +export function $memberManual(params) { + return http.req('/api/member/manual/' + params.memberId, params, "POST") +} + +//查询或修改会员配置信息 +export function $findOrEditMemberConfig(data, mode = 'GET', uri = '') { + return http.req('/api/mchConfig' + uri, data, mode) +} +/* 会员数据统计 */ +export function $memberInfoCount(params) { + return http.req('/api/member/count', params, 'GET') +} + +/* 查询商户支付应用 费率参数是否配置 */ +export function $getMchPayPassage(appId, ifCode) { + return http.req(`/api/payConfig/existPayParams/${appId}/${ifCode}`, {}, 'GET') +} + +/* 获取进件渠道列表 */ +export function $getAllIsvInfoList(ifCode, range = 0) { + return http.req("/api/isvInfo/isvInfoList", { + pageNumber: "-1", + range: range, + ifCode: ifCode + }, "GET") +} + + +// 请求验证码 +export function $isCode() { + return http.req("/api/anon/auth/vercode", "GET") +} + +export function $pmdfb(data) { + return http.req("/api/store/device/setMarqueeInfo", data, "POST") +} + +export function $getImgWH(params) { + return http.req(`/api/store/device/getMarketPoint/${params}`, "GET") +} + +export function $initializeImg(params) { + return http.req(`/api/store/device/getMarketPic/${params}`, "GET") +} + +export function $uploadImg(data) { + return http.req(`/api/store/device/setMarketPic`, data, "POST") +} + +/* 获取上传form信息 */ +export function $NewOssFilesForm(data) { + return http.req("/api/ossFiles/form", data, "POST") +} diff --git a/http/businessApiManger.js b/http/businessApiManger.js new file mode 100644 index 0000000..0503c48 --- /dev/null +++ b/http/businessApiManger.js @@ -0,0 +1,47 @@ +import request from './businessHttp.js' +import useStorage from '@/commons/utils/useStroage.js' + +/** + * 登录 + * @param {Object} data + */ +export function login(data) { + return request('/login/wx/merchant/login', data, 'post') +} + +/** + * 桌台列表 + * @param {Object} areaId + */ +export function tableList(areaId) { + return request('/table/list', { + shopId: useStorage.get('userInfo').shopId, + areaId: areaId + }, 'post') +} + +/** + * 区域列表 + * @param {Object} data + */ +export function areaList(data) { + return request('/table/area', { + shopId: useStorage.get('userInfo').shopId + }) +} + +/** + * 绑定桌码 + * @param {Object} data + */ +export function tableBinding(data) { + return request('/table/binding', data, 'post') +} + +/** + * 登录获取openid + * @param {Object} data + */ +export function wxlogin(data) { + return request('/login/wx/business/login', data) +} \ No newline at end of file diff --git a/http/businessHttp.js b/http/businessHttp.js new file mode 100644 index 0000000..2938964 --- /dev/null +++ b/http/businessHttp.js @@ -0,0 +1,52 @@ +/** + * 因为两个小程序接口不一致,餐饮商超商家端的接口使用该http + */ +import useStorage from '@/commons/utils/useStroage.js' +import go from '@/commons/utils/go.js'; +// const baseURL = 'http://192.168.2.128:9000/cashierService' +// const baseURL = 'http://192.168.2.41:9888/cashierService' +let baseURL = 'https://wxcashiertest.sxczgkj.cn/cashierService' +// #ifdef H5 +baseURL = '/ysk' +// #endif +// const baseURL = 'https://cashier.sxczgkj.cn/cashierService' +export default function(api = '', data = {}, method = 'GET') { + return new Promise((resolve, reject) => { + uni.request({ + url: `${baseURL}${api}`, + method: method, + data: data, + header: { + 'environment': 'wx', + 'type': 'ios', + 'version': '1.0.0', + 'token': useStorage.get('iToken'), + 'Authorization': useStorage.get('iToken'), + 'Content-Type': 'application/json' + }, + success: res => { + if (res.data.code == 0) { + resolve(res.data) + } else { + uni.showToast({ + icon: 'none', + "title": res.data.msg + }) + if(res.data.code==-4){ + setTimeout(()=>{ + go.to('PAGES_LOGIN', {}, 'redirect') + },2000) + } + reject(res.data.msg) + } + }, + fail: err => { + uni.showToast({ + icon: 'none', + "title": err.errMsg + }) + reject(err) + } + }) + }) +} \ No newline at end of file diff --git a/http/classApi.js b/http/classApi.js new file mode 100644 index 0000000..6ed1954 --- /dev/null +++ b/http/classApi.js @@ -0,0 +1,22 @@ + class API { + constructor(url,req) { + const map={ + add:'POST', + del:'DELETE', + update:'PUT', + get:'GET' + } + this.url=url + for(let key in map){ + this[key]=function(data){ + data=Array.isArray(data)?data:{...data,shopId:uni.getStorageSync('shopId')} + if(key==='del'){ + delete data.shopId + } + return req(url, data,map[key]) + } + } + } +} + +export default API \ No newline at end of file diff --git a/http/http.js b/http/http.js new file mode 100644 index 0000000..14122b6 --- /dev/null +++ b/http/http.js @@ -0,0 +1,161 @@ +/** + * HTTP的封装, 基于uni.request + * 包括: 通用响应结果的处理 和 业务的增删改查函数 + * + * @author terrfly + * @site https://www.jeequan.com + * @date 2021/12/16 18:35 + */ + +// 导入全局属性 +import appConfig from '@/config/appConfig.js' +import storageManage from '@/commons/utils/storageManage.js' +import { sm4DecryptByResData } from '@/commons/utils/encryptUtil.js' +import infoBox from "@/commons/utils/infoBox.js" +import go from '@/commons/utils/go.js'; +let baseUrl = 'http://101.37.12.135:8080' +// #ifdef H5 +baseUrl = '/server3/mch' +// #endif +// #ifndef H5 +baseUrl = 'http://101.37.12.135:8080/mch' +// #endif + +// 多少 ms 以内, 不提示loading +const loadingShowTime = 200 + +// 通用处理逻辑 +function commonsProcess(showLoading, httpReqCallback){ + + // 判断是否请求完成(用作 是否loading ) + // 包括: 'ing', 'ingLoading', 'finish' + let reqState = 'ing' + + // 是否已经提示的错误信息 + let isShowErrorToast = false + + + // 请求完成, 需要处理的动作 + let reqFinishFunc = () => { + + if(reqState == 'ingLoading'){ // 关闭loading弹层 + infoBox.hideLoading() + } + reqState = 'finish' // 请求完毕 + } + + // 明确显示loading + if(showLoading){ + // xx ms内响应完成,不提示loading + setTimeout(() => { + if(reqState == 'ing'){ + reqState = 'ingLoading' + infoBox.showLoading() + } + }, loadingShowTime) + } + + return httpReqCallback().then((httpData) => { + + reqFinishFunc(); // 请求完毕的动作 + + // 从http响应数据中解构响应数据 [ 响应码、 bodyData ] + let { statusCode, data } = httpData + // 避免混淆重新命名 + let bodyData = data + if(statusCode == 401){ + + // 清楚 token + storageManage.token(null, true) + + // 提示信息 + isShowErrorToast = true + // infoBox.showErrorToast('请登录').then(() => { + // go.to("PAGES_LOGIN", {}, go.GO_TYPE_RELAUNCH) + // }) + return Promise.reject(bodyData) // 跳转到catch函数 + } + // http响应码不正确 + if(statusCode != 200){ + isShowErrorToast = true + infoBox.showToast('服务器异常') + return Promise.reject(bodyData) // 跳转到catch函数 + } + + // 业务响应异常 + if(bodyData.code != 0){ + isShowErrorToast = true + infoBox.showToast(bodyData.msg) + if(bodyData.code == 5005){ // 密码已过期, 直接跳转到更改密码页面 + uni.reLaunch({url: '/pageUser/setting/updatePwd'}) + } + if(bodyData.code == 500){ // 密码已过期, 直接跳转到更改密码页面 + uni.redirectTo({url: '/pages/login/index'}) + } + return Promise.reject(bodyData) + } + + // 加密数据 + if(!bodyData.data && bodyData.encryptData){ + + return Promise.resolve({ bizData: sm4DecryptByResData(bodyData.encryptData), code: bodyData.code }) + } + + // 构造请求成功的响应数据 + return Promise.resolve({ bizData: bodyData.data, code: bodyData.code }) + + }).catch( res => { + reqFinishFunc(); // 请求完毕的动作 + // 如果没有提示错误, 那么此处提示 异常。 + if(!isShowErrorToast){ + infoBox.showToast(`请求网络异常`) + } + return Promise.reject(res) + + }).finally(() => { // finally 是 then结束后再执行, 此处不适用。 需要在请求完成后立马调用: reqFinishFunc() + + }); + +} + + +// 默认 显示loading(控制 xxs 内 不提示loading ) +function req(uri, data, method = "GET", showLoading = true, extParams = {}){ + + // 放置token + let headerObject = {} + headerObject[appConfig.tokenKey] = storageManage.token() + headerObject["satoken"] = storageManage.token() + + return commonsProcess(showLoading, () => { + return uni.request( + Object.assign({url: baseUrl + uri, data: data, method: method, header: headerObject}, extParams ) + ) + } + ) +} + + +// 上传 +function upload(uri, data, file, showLoading = true, extParams = {}){ + + // 放置token + let headerObject = {} + headerObject[appConfig.tokenKey] = storageManage.token() + + return commonsProcess(showLoading, () => { + return uni.uploadFile( + Object.assign({url: baseUrl + uri, formData: data, name: "file", filePath: file.path, header: headerObject}, extParams ) + ).then((httpData) => { + // uni.upload 返回bodyData 的是 string类型。 需要解析。 + httpData.data = JSON.parse(httpData.data) + return Promise.resolve(httpData) + }) + } + ) +} + +export default { + req : req, + upload : upload +} diff --git a/http/newApi/http.js b/http/newApi/http.js new file mode 100644 index 0000000..da81844 --- /dev/null +++ b/http/newApi/http.js @@ -0,0 +1,182 @@ +/** + * HTTP的封装, 基于uni.request + * 包括: 通用响应结果的处理 和 业务的增删改查函数 + * + * @author terrfly + * @site https://www.jeequan.com + * @date 2021/12/16 18:35 + */ + +// 导入全局属性 +import appConfig from '@/config/appConfig.js' +import storageManage from '@/commons/utils/storageManage.js' +import { + sm4DecryptByResData +} from '@/commons/utils/encryptUtil.js' +import infoBox from "@/commons/utils/infoBox.js" +import go from '@/commons/utils/go.js'; +let baseUrl = 'http://101.37.12.135:8080' +// #ifdef H5 +baseUrl = '/server3' +// #endif +// 多少 ms 以内, 不提示loading +const loadingShowTime = 200 + +// 通用处理逻辑 +function commonsProcess(showLoading, httpReqCallback) { + + // 判断是否请求完成(用作 是否loading ) + // 包括: 'ing', 'ingLoading', 'finish' + let reqState = 'ing' + + // 是否已经提示的错误信息 + let isShowErrorToast = false + + + // 请求完成, 需要处理的动作 + let reqFinishFunc = () => { + + if (reqState == 'ingLoading') { // 关闭loading弹层 + infoBox.hideLoading() + } + reqState = 'finish' // 请求完毕 + } + + // 明确显示loading + if (showLoading) { + // xx ms内响应完成,不提示loading + setTimeout(() => { + if (reqState == 'ing') { + reqState = 'ingLoading' + infoBox.showLoading() + } + }, loadingShowTime) + } + + return httpReqCallback().then((httpData) => { + console.log(httpData); + reqFinishFunc(); // 请求完毕的动作 + + // 从http响应数据中解构响应数据 [ 响应码、 bodyData ] + let { + statusCode, + data + } = httpData + + // 避免混淆重新命名 + let bodyData = data + if (statusCode == 401) { + + // 清楚 token + storageManage.token(null, true) + + // 提示信息 + isShowErrorToast = true + infoBox.showErrorToast('请登录').then(() => { + go.to("PAGES_LOGIN", {}, go.GO_TYPE_RELAUNCH) + }) + return Promise.reject(bodyData) // 跳转到catch函数 + } + // http响应码不正确 + if (statusCode != 200) { + isShowErrorToast = true + infoBox.showErrorToast('服务器异常') + return Promise.reject(bodyData) // 跳转到catch函数 + } + + // 业务响应异常 + if (bodyData.code != 200) { + isShowErrorToast = true + infoBox.showToast(bodyData.msg) + if (bodyData.code == 5005) { // 密码已过期, 直接跳转到更改密码页面 + uni.reLaunch({ + url: '/pageUser/setting/updatePwd' + }) + } + if(bodyData.code == 500){ // 密码已过期, 直接跳转到更改密码页面 + uni.redirectTo({url: '/pages/login/index'}) + } + return Promise.reject(bodyData) + } + + // 加密数据 + if (!bodyData.data && bodyData.encryptData) { + + return Promise.resolve({ + bizData: sm4DecryptByResData(bodyData.encryptData), + code: bodyData.code + }) + } + + // 构造请求成功的响应数据 + return Promise.resolve({ + bizData: bodyData.data, + code: bodyData.code + }) + + }).catch(res => { + reqFinishFunc(); // 请求完毕的动作 + + // 如果没有提示错误, 那么此处提示 异常。 + if (!isShowErrorToast) { + infoBox.showErrorToast(`请求网络异常`) + } + + return Promise.reject(res) + + }).finally(() => { // finally 是 then结束后再执行, 此处不适用。 需要在请求完成后立马调用: reqFinishFunc() + + }); + +} + + +// 默认 显示loading(控制 xxs 内 不提示loading ) +function req(uri, data, method = "GET", showLoading = true, extParams = {}) { + let headerObject = {} + // headerObject[appConfig.tokenKey] = storageManage.token() + headerObject["satoken"] = storageManage.token() + headerObject["content-type"] = 'application/json' + + return commonsProcess(showLoading, () => { + return uni.request( + Object.assign({ + url: baseUrl + uri, + data: data, + method: method, + header: headerObject + }, extParams) + ) + }) +} + + +// 上传 +function upload(uri, data, file, showLoading = true, extParams = {}) { + + // 放置token + let headerObject = {} + // headerObject[appConfig.tokenKey] = storageManage.token() + headerObject["satoken"] = storageManage.token() + + return commonsProcess(showLoading, () => { + return uni.uploadFile( + Object.assign({ + url: appConfig.env.JEEPAY_BASE_URL + uri, + formData: data, + name: "file", + filePath: file.path, + header: headerObject + }, extParams) + ).then((httpData) => { + // uni.upload 返回bodyData 的是 string类型。 需要解析。 + httpData.data = JSON.parse(httpData.data) + return Promise.resolve(httpData) + }) + }) +} + +export default { + req: req, + upload: upload +} \ No newline at end of file diff --git a/http/newApi/login.js b/http/newApi/login.js new file mode 100644 index 0000000..5674ba3 --- /dev/null +++ b/http/newApi/login.js @@ -0,0 +1,11 @@ +import http from './http.js' +import appConfig from '@/config/appConfig.js' +import { + Base64 +} from 'js-base64' +import infoBox from '@/commons/utils/infoBox.js' +/* 登录 */ +export function $login(postData) { + // return http.req('/login', params, 'GET') + return http.req('/login', postData, 'POST') +} diff --git a/http/yskApi/Instead.js b/http/yskApi/Instead.js new file mode 100644 index 0000000..d964201 --- /dev/null +++ b/http/yskApi/Instead.js @@ -0,0 +1,392 @@ +// 代课下单 +import http from './http.js' +import $API from '@/http/classApi.js' +import appConfig from '@/config/appConfig.js' +import { + Base64 +} from 'js-base64' +import infoBox from '@/commons/utils/infoBox.js' + +const request = http.request + + +//就餐形式,默认堂食后付费 +const useType = 'dine-in-after' + +function getUseType() { + const type = uni.getStorageSync("useType") + return type ? type : useType +} + + +/** + * 获取当前台桌订单信息 + * @returns + */ +export function getCart(params) { + return request({ + url: `/api/place/cart`, + method: "get", + params:{ + shopId: uni.getStorageSync("shopId"), + useType: getUseType(), + ...params + } + }); +} +/** + * 已上架商品列表 + * @returns + */ +export function getGoodsLists(params,showLoading=true) { + return request({ + url: `/api/place/activate`, + method: "get", + params:{ + shopId: uni.getStorageSync("shopId"), + ...params + }, + showLoading + }); +} + +/** + * 点单 + * @returns + */ +export function addCart(data) { + return request({ + url: `/api/place/addCart`, + method: "post", + data:{ + shopId: uni.getStorageSync("shopId"), + useType: getUseType(), + ...data + } + }); +} + +/** + * 清空购物车/支付订单 + * @returns + */ +export function $clearCart(data) { + return request({ + url: `/api/place/clearCart`, + method: "delete", + data:{ + shopId: uni.getStorageSync("shopId"), + useType: getUseType(), + ...data + } + }); +} + +/** + * 删除购物车某个商品 + * @returns + */ +export function $removeCart(data) { + return request({ + url: `/api/place/removeCart`, + method: "delete", + data:{ + shopId: uni.getStorageSync("shopId"), + useType: getUseType(), + ...data + } + }); +} +/** + * 更新规格 + * @returns + */ +export function $updateCart(data) { + return request({ + url: `/api/place/updateCart`, + method: "put", + data:{ + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} +/** + * 批量打包 + * @returns + */ +export function $allPack(data) { + return request({ + url: `/api/place/pack`, + method: "put", + data:{ + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} +/** + * 获取取餐号 + * @returns + */ +export function $getMasterId(data) { + return request({ + url: `/api/place/masterId`, + method: "get", + params:{ + shopId: uni.getStorageSync("shopId"), + useType: getUseType(), + ...data + } + }); +} +/** + * 支付方式获取 + * @returns + */ +export function $getPayType(data) { + return request({ + url: `/api/place/payType`, + method: "get", + params:{ + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} +/** + * 创建订单 + * @returns + */ +export function $createOrder(data) { + return request({ + url: `/api/place/order`, + method: "post", + data:{ + shopId: uni.getStorageSync("shopId"), + useType: getUseType(), + ...data + } + }); +} + + +/** + * 挂起订单 + * @returns + */ +export function $cacheOrder(data) { + return request({ + url: `/api/place/pending`, + method: "post", + data:{ + shopId: uni.getStorageSync("shopId"), + useType: getUseType(), + ...data + } + }); +} + +/** + * 获取已挂起订单 + * @returns + */ +export function $getCacheOrder(data) { + return request({ + url: `/api/place/pending/cart`, + method: "get", + params:{ + shopId: uni.getStorageSync("shopId"), + useType: getUseType(), + ...data + } + }); +} + +// 会员点单/取消会员点单 +export function $setUser(data) { + return request({ + url: `/api/place/updateVip`, + method: "put", + data:{ + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} +// 删除订单 +export function $delOrder(data) { + return request({ + url: `/api/place/order`, + method: "delete", + data:{ + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} +// 支付订单 +export function $payOrder(data) { + return request({ + url: '/api/place/pay', + method: "put", + data:{ + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} +//退单 + +export function $returnCart(data) { + return request({ + url: '/api/place/returnCart', + method: "put", + data:{ + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} +// 选择台桌 +export function $choseTable(data) { + return request({ + url: '/api/place/choseTable', + method: "put", + data:{ + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} +// 用餐人数 + +export function $choseCount(data) { + return request({ + url: '/api/place/choseCount', + method: "put", + data:{ + shopId: uni.getStorageSync("shopId"), + useType: getUseType(), + ...data + } + }); +} + +// 批量生成台桌 +export function $fastCreateTable(data) { + return request({ + url: '/api/tbShopTable/generate', + method: "post", + data:{ + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} + +//打印当前台桌订单 +export function $printOrder(data) { + return request({ + url: '/api/place/printOrder', + method: "post", + data:{ + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} +//打印当前台桌菜品 + +export function $printDishes(data) { + return request({ + url: '/api/place/printDishes', + method: "post", + data:{ + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} + +// 就餐模式切换 +export function $changeUseType(data) { + return request({ + url: '/api/place/choseModel', + method: "put", + data:{ + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} + +// 退款 +export function $returnOrder(data) { + return request({ + url: '/api/place/returnOrder', + method: "post", + data:{ + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} + +//获取订单可用优惠券 +export function $activateByOrderId(data) { + return request({ + url: '/api/tbShopCoupon/activateByOrderId', + method: "get", + params:{ + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} + +//会员积分列表 +export function $returnMemberPointsList(data) { + return request({ + url: '/api/points/member-points/page', + method: "get", + params:{ + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} + +// 会员积分账户信息 +export function $returnMemberPoints(memberId) { + return request({ + url: '/api/points/member-points/'+memberId, + method: "get", + params:{ + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} +//002-获取订单可用积分及抵扣金额(支付页面使用) +export function $calcUsablePoints(data) { + return request({ + url: '/api/points/member-points/calc-usable-points', + method: "get", + params:{ + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} +// 003-根据积分计算可抵扣金额 +export function $calcDeDuctionPoints(data) { + return request({ + url: '/api/points/member-points/calc-deduction-amount', + method: "get", + params:{ + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} \ No newline at end of file diff --git a/http/yskApi/breakage.js b/http/yskApi/breakage.js new file mode 100644 index 0000000..a3c6f2e --- /dev/null +++ b/http/yskApi/breakage.js @@ -0,0 +1,33 @@ +import http from './http.js' +const request=http.request + + +/** + * 商品报损 + * @returns + */ +export function productBreakage(data) { + return request({ + url: `/api/tbProductStockDetail/frmLoss`, + method: 'post', + data:{ + shopId: uni.getStorageSync('shopId'), + ...data + } + }) +} + +/** + * 耗材报损 + * @returns + */ +export function consumableBreakage(data) { + return request({ + url: `/api/tbConsInfoFlow/frmLoss`, + method: 'post', + data:{ + shopId: uni.getStorageSync('shopId'), + ...data + } + }) +} diff --git a/http/yskApi/bwc.js b/http/yskApi/bwc.js new file mode 100644 index 0000000..6899f16 --- /dev/null +++ b/http/yskApi/bwc.js @@ -0,0 +1,33 @@ +import http from './http.js' +const request = http.request + + +/** + * 商品报损 + * @returns + */ +export function get(params) { + return request({ + url: `/freeDine`, + method: 'get', + params: { + shopId: uni.getStorageSync('shopId'), + ...params + } + }) +} + +/** + * 耗材报损 + * @returns + */ +export function edit(data) { + return request({ + url: `/freeDine`, + method: 'put', + params: { + shopId: uni.getStorageSync('shopId'), + ...data + } + }) +} \ No newline at end of file diff --git a/http/yskApi/consumable.js b/http/yskApi/consumable.js new file mode 100644 index 0000000..ac31a33 --- /dev/null +++ b/http/yskApi/consumable.js @@ -0,0 +1,232 @@ +import http from './http.js' +const request = http.request + + +/** + * 查询耗材类型 + * @returns + */ +export function gettbConsType(params) { + return request({ + url: '/api/tbConsType', + method: "get", + params + }); +} + +/** + * 新增耗材类型 + * @returns + */ +export function posttbConsType(data) { + return request({ + url: '/api/tbConsType', + method: "post", + data + }); +} +/** + * 修改耗材类型 + * @returns + */ +export function puttbConsType(data) { + return request({ + url: '/api/tbConsType', + method: "put", + data + }); +} +/** + * 查询耗材信息 + * @returns + */ +export function gettbConsInfo(params) { + // return request({ + // url: '/api/tbConsInfo', + // method: "get", + // params + // }); + return request({ + url: "/api/tbConsInfo", + method: "get", + params: { + ...params, + shopId: uni.getStorageSync("shopId"), + } + }); +} + + +/** + * 耗材入库 + * @returns + */ +export function posttbConsInfostockIn(data) { + return request({ + url: '/api/tbConsInfo/stockIn', + method: "post", + data + }); +} +/** + * 修改单位耗材值耗材 + * @returns + */ +export function postapitbConsInfo(data) { + return request({ + url: '/api/tbConsInfo', + method: "put", + data + }); +} +/** + * 新增耗材信息 + * @returns + */ +export function posttbConsInfo(data) { + return request({ + url: '/api/tbConsInfo', + method: "post", + data + }); +} + +/** + * 查询查询耗材规格信息 + * @returns + */ +export function getviewConSku(params) { + return request({ + url: '/api/viewConSku', + method: "get", + params + }); +} +/** + * 查询查询商品规格 + * @returns + */ +export function gettbProductSpec(params) { + return request({ + url: '/api/viewProductSkuShop', + method: "get", + params + }); +} +/** + * 新增商品规格耗材信息 + * @returns + */ +export function posttbProskuCon(data) { + return request({ + url: '/api/tbProskuCon', + method: "post", + data + }); +} +/** + * 新增商品规格耗材信息-修改后 + * @returns + */ +export function posttbProskuCons(data) { + return request({ + url: '/api/tbProskuCon', + method: "post", + data + }); +} +/** + * 修改商品规格耗材信息状态 + * @returns + */ +export function puttbProskuCon(data) { + return request({ + url: '/api/tbProskuCon', + method: "put", + data + }); +} +// 编辑单位耗材值 +// export function puttbProskuCon(data) { +// return request({ +// url: '/api/tbProskuCon', +// method: "put", +// data +// }); +// } +/** + * 删除商品规格耗材信息状态 + * @returns + */ +export function deletetbProskuCon(data) { + return request({ + url: '/api/tbProskuCon', + method: "delete", + data + }); +} +/** + * 查询耗材流水信息 + * @returns + */ +export function gettbConsInfoFlow(params) { + return request({ + url: '/api/tbConsInfoFlow', + method: "get", + params + }); +} +/** + * 分组查询获取耗材流水信息 + */ +// export function viewConInfoFlow(data) { +// return request({ +// url: "/api/viewConInfoFlow", +// method: "get", +// params: { +// shopId: uni.getStorageSync("shopId"), +// ...data +// } +// }); +// } + +/** + * 查询耗材单位列表 + */ +export function queryTbConUnitInfo(data) { + return request({ + url: "/api/tbConUnit/queryTbConUnitInfo", + method: "get", + params: { + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} + +/** + * 新增耗材单位 + */ +export function addtbConUnit(data) { + return request({ + url: '/api/tbConUnit', + method: "post", + data: { + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} +/** + * 修改耗材单位 + */ +export function edittbConUnit(data) { + return request({ + url: '/api/tbConUnit', + method: "put", + data: { + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} \ No newline at end of file diff --git a/http/yskApi/coupon.js b/http/yskApi/coupon.js new file mode 100644 index 0000000..ae4d4fc --- /dev/null +++ b/http/yskApi/coupon.js @@ -0,0 +1,58 @@ +import http from './http.js' +const request=http.request + + +/** + * 获取优惠券列表 + * @returns + */ +export function getTbShopCoupon(data) { + return request({ + url: `/api/tbShopCoupon`, + method: 'get', + params: { + shopId: uni.getStorageSync('shopId'), + ...data + } + }) +} + +/** + * 获取优惠券详情 + * @returns + */ +export function getTbShopCouponInfo(id) { + return request({ + url: `/api/tbShopCoupon/${id}`, + method: 'get', + params: { + } + }) +} + +/** + * 增加优惠券 + * @returns + */ +export function addTbShopCoupon(data) { + return request({ + url: `/api/tbShopCoupon`, + method: 'post', + params: { + shopId: uni.getStorageSync('shopId'), + ...data + } + }) +} + +/** + * 删除优惠券 + * @returns + */ +export function delTbShopCoupon(data) { + return request({ + url: `/api/tbShopCoupon`, + method: 'delete', + params: data + }) +} diff --git a/http/yskApi/couponCategory.js b/http/yskApi/couponCategory.js new file mode 100644 index 0000000..8f6c451 --- /dev/null +++ b/http/yskApi/couponCategory.js @@ -0,0 +1,30 @@ +import http from './http.js' +import appConfig from '@/config/appConfig.js' +import { + Base64 +} from 'js-base64' +import infoBox from '@/commons/utils/infoBox.js' + +/* 查询团购卷分类 */ +export function $tbCouponCategory(data, mehtod = 'GET') { + return http.req('/api/tbCouponCategory', { + ...data, + shopId: uni.getStorageSync('shopId') + }, 'GET') +} + + +export default { + add: function(data) { + return $tbCouponCategory(data, 'POST') + }, + del: function(data) { + return $tbCouponCategory(data, 'DELETE') + }, + update: function(data) { + return $tbCouponCategory(data, 'PUT') + }, + get: function(data) { + return $tbCouponCategory(data) + } +} \ No newline at end of file diff --git a/http/yskApi/devices.js b/http/yskApi/devices.js new file mode 100644 index 0000000..82b1c57 --- /dev/null +++ b/http/yskApi/devices.js @@ -0,0 +1,66 @@ +import http from './http.js' +const request = http.request + +/** + * 增加打印机 + * @returns + */ +export function tbPrintMachine(data, method = 'post') { + return request({ + url: '/api/shop-config/printer', + method: method, + data: { + shopId: uni.getStorageSync('shopId'), + ...data + } + }) +} + +/** + * 打印机列表 + * @returns + */ +export function tbPrintMachineGet(params) { + return request({ + url: '/api/shop-config/printer/list', + method: 'get', + params: { + shopId: uni.getStorageSync('shopId'), + sort: '', + ...params + } + }) +} + +// 打印机部分 +export function tbShopCategoryget(params) { + return request({ + url: '/api/tbShopCategory', + method: 'get', + params + }) +} +// 修改打印机状态 +export function shopConfigprinter(data) { + return request({ + url: '/api/shop-config/printer/update-status', + method: 'post', + data + }) +} + +// * 打印机详情 +export function printerd(id) { + return request({ + url: '/api/shop-config/printer/' + id, + method: 'get', + + }) +} +// 删除 +export function delTableHandle(id) { + return request({ + url: '/api/shop-config/printer/' + id, + method: 'DELETE', + }) +} \ No newline at end of file diff --git a/http/yskApi/file.js b/http/yskApi/file.js new file mode 100644 index 0000000..8065fcc --- /dev/null +++ b/http/yskApi/file.js @@ -0,0 +1,11 @@ +import http from './http.js' +import appConfig from '@/config/appConfig.js' +import { + Base64 +} from 'js-base64' +import infoBox from '@/commons/utils/infoBox.js' + +/* 上传图片 */ +export function $uploadFile(file,data) { + return http.upload('/api/qiNiuContent', data,file) +} diff --git a/http/yskApi/goods.js b/http/yskApi/goods.js new file mode 100644 index 0000000..18e1587 --- /dev/null +++ b/http/yskApi/goods.js @@ -0,0 +1,140 @@ +import http from './http.js' +import $API from '@/http/classApi.js' +import appConfig from '@/config/appConfig.js' +import { + Base64 +} from 'js-base64' +import infoBox from '@/commons/utils/infoBox.js' +function objectToUrlParams(obj) { + let params = []; + for (let key in obj) { + if (obj.hasOwnProperty(key)) { + let value = obj[key]; + let param = encodeURIComponent(key) + '=' + encodeURIComponent(value); + params.push(param); + } + } + return params.join('&'); +} +/* 商品列表 */ +export function $tbProduct(data) { + return http.req('/api/tbProduct', {...data,shopId:uni.getStorageSync('shopId')}, 'GET') +} + +/* 添加商品 */ +export function $addProduct(data) { + return http.req('/api/tbProduct', {...data,shopId:uni.getStorageSync('shopId')}, 'POST') +} + +/* 删除商品 */ +export function $delProduct(ids) { + return http.req('/api/tbProduct', ids, 'DELETE') +} + + +/* 更新商品相关 */ +export function $updateProduct(data) { + return http.req('/api/tbProduct', {...data,shopId:uni.getStorageSync('shopId')}, 'PUT') +} +/* 修改商品排序 */ +export function $upProSort(data) { + return http.req('/api/tbProduct/upProSort', {...data,shopId:uni.getStorageSync('shopId')}, 'POST') +} +/* 商品详情(单个商品) */ +export function $getProductDetail(product,showLoading=true) { + return http.req('/api/tbProduct/'+product, {shopId:uni.getStorageSync('shopId')}, 'GET',showLoading) +} + +/* 设置热销商品 */ +export function $goodsIsHot(data) { + return http.req('/api/tbProduct/isHot', {...data,shopId:uni.getStorageSync('shopId')}, 'GET') +} + + + +/** + * 商品分类列表 + */ +export function $tbShopCategory(data) { + return http.req('/api/tbShopCategory', {...data,shopId:uni.getStorageSync('shopId')}, 'GET') +} +/** + * 商品分类 + */ +export const $productCategory=new $API('/api/tbShopCategory',http.req) + + +/** + * 更新商品库存状态 + */ +export function $updateProductStatus(data){ + return http.req('/api/stock/productStatus', {...data,shopId:uni.getStorageSync('shopId')}, 'PUT') +} + +/** + * 库存记录列表 + */ +export function $getProductStockDetail(data){ + return http.req('/api/tbProductStockDetail/stock', {...data,shopId:uni.getStorageSync('shopId')}, 'POST') +} + +/** + * 库存记录变动数量 + */ +export function $getProductStockDetailSum(data){ + return http.req('/api/tbProductStockDetail/sum', {...data,shopId:uni.getStorageSync('shopId')}, 'GET') +} +/** + * 新增盘点 + */ +export function $addStocktakin(data){ + return http.req('/api/tbProductStocktakin', {...data,shopId:uni.getStorageSync('shopId')}, 'POST') +} +/** + * 盘点记录查询 + */ +export function $getStocktakin(data){ + return http.req('/api/tbProductStocktakin', {...data,shopId:uni.getStorageSync('shopId')}, 'GET') +} + + +/** + * 上下架商品 + */ +export function $updateGrounding(data){ + const ajaxData={...data,shopId:uni.getStorageSync('shopId')} + return http.req('/api/stock/grounding'+`?${objectToUrlParams(ajaxData)}`, ajaxData, 'PUT') +} + + + +/* 商品单位列表 */ +export function $tbShopUnit(data) { + return http.req('/api/tbShopUnit', {...data,shopId:uni.getStorageSync('shopId')}, 'GET') +} + +/* 商品规格 */ +export const $productSpec=new $API('/api/tbProductSpec',http.req) + + + +// v2 api start + +/* 商品列表 V2 */ +export function $tbProductV2(data) { + return http.req('/api/tbProduct/list/v2', {...data,shopId:uni.getStorageSync('shopId')}, 'post') +} +/* 耗材与商品绑定关系 */ +export function $tbProskuConV2(data) { + return http.req('/api/tbProskuCon/V2', data, 'POST') +} + +/* 修改商品相关(快捷接口) */ +export function $updateProductData(data) { + return http.req('/api/stock/updateProductData', data, 'POST') +} +/* 商品报损 */ +export function $frmLoss(data) { + return http.req('/api/tbProductStockDetail/frmLoss', {...data,shopId:uni.getStorageSync('shopId')}, 'POST') +} +// v2 api end \ No newline at end of file diff --git a/http/yskApi/http.js b/http/yskApi/http.js new file mode 100644 index 0000000..67aef22 --- /dev/null +++ b/http/yskApi/http.js @@ -0,0 +1,241 @@ +/** + * HTTP的封装, 基于uni.request + * 包括: 通用响应结果的处理 和 业务的增删改查函数 + * + * @author terrfly + * @site https://www.jeequan.com + * @date 2021/12/16 18:35 + */ + +// 导入全局属性 +import appConfig from '@/config/appConfig.js' +import storageManage from '@/commons/utils/storageManage.js' +import { + sm4DecryptByResData +} from '@/commons/utils/encryptUtil.js' +import infoBox from "@/commons/utils/infoBox.js" +import go from '@/commons/utils/go.js'; +import { reject } from 'lodash'; +// 测试服 +let baseUrl = 'https://admintestpapi.sxczgkj.cn' + +//预发布 +// let baseUrl = 'https://pre-cashieradmin.sxczgkj.cn' + +//正式 +// let baseUrl = 'https://cashieradmin.sxczgkj.cn' + +// 王伟本地测 +// let baseUrl = '/ww' +// let baseUrl = 'http://192.168.1.15:8000' + // 巩 + // let baseUrl = 'http://192.168.1.9:8000' +// 多少 ms 以内, 不提示loading +const loadingShowTime = 200 + + +function getHeader(){ + const headerObject={} + headerObject["Authorization"] = storageManage.token() + return headerObject +} + +// 通用处理逻辑 +function commonsProcess(showLoading, httpReqCallback) { + + // 判断是否请求完成(用作 是否loading ) + // 包括: 'ing', 'ingLoading', 'finish' + let reqState = 'ing' + + // 是否已经提示的错误信息 + let isShowErrorToast = false + + + // 请求完成, 需要处理的动作 + let reqFinishFunc = () => { + + if (reqState == 'ingLoading') { // 关闭loading弹层 + infoBox.hideLoading() + } + reqState = 'finish' // 请求完毕 + } + + // 明确显示loading + if (showLoading) { + // xx ms内响应完成,不提示loading + setTimeout(() => { + if (reqState == 'ing') { + reqState = 'ingLoading' + infoBox.showLoading() + } + }, loadingShowTime) + } + + return httpReqCallback().then((httpData) => { + reqFinishFunc(); // 请求完毕的动作 + // 从http响应数据中解构响应数据 [ 响应码、 bodyData ] + let { + statusCode, + data + } = httpData + // 避免混淆重新命名 + let bodyData = data + if (statusCode == 500) { + isShowErrorToast = true + return Promise.reject(bodyData) // 跳转到catch函数 + } + if (statusCode == 401) { + // storageManage.token(null, true) + // 提示信息 + isShowErrorToast = true + // infoBox.showErrorToast('请登录').then(() => { + // go.to("PAGES_LOGIN", {}, go.GO_TYPE_RELAUNCH) + // }) + return Promise.reject(bodyData) // 跳转到catch函数 + } + // http响应码不正确 + if (statusCode != 200 && statusCode != 204 && statusCode != 201) { + isShowErrorToast = true + data.message=data.message=='Bad credentials'?'用户名或密码错误':data.message + infoBox.showToast(data.message || '服务器异常') + return Promise.reject(bodyData) // 跳转到catch函数 + } + + // // 业务响应异常 + // if (bodyData.hasOwnProperty('code') && bodyData.code != 200) { + // isShowErrorToast = true + // infoBox.showToast(bodyData.msg) + // if (bodyData.code == 5005) { // 密码已过期, 直接跳转到更改密码页面 + // uni.reLaunch({ + // url: '/pageUser/setting/updatePwd' + // }) + // } + // // if(bodyData.code == 500){ // 密码已过期, 直接跳转到更改密码页面 + // // uni.redirectTo({url: '/pages/login/index'}) + // // } + // return bodyData + // // return Promise.reject(bodyData) + // } + + // 加密数据 + if (!bodyData.data && bodyData.encryptData) { + + return Promise.resolve({ + bizData: sm4DecryptByResData(bodyData.encryptData), + code: bodyData.code + }) + } + + // 构造请求成功的响应数据 + return Promise.resolve(bodyData) + + }).catch(res => { + if(res.status==401){ + storageManage.token(null, true) + infoBox.showErrorToast(res.message||'请登录').then(() => { + uni.redirectTo({url: '/pages/login/index'}) + reject() + }) + } + // if(res.status==400){ + // storageManage.token(null, true) + // infoBox.showErrorToast('').then(() => { + // go.to("PAGES_LOGIN", {}, go.GO_TYPE_RELAUNCH) + // }) + // } + if(res.status==500){ + infoBox.showErrorToast(res.message||'服务器异常').then(() => { + }) + } + // if(res&&res.msg){ + // infoBox.showErrorToast(res.msg) + // } + reqFinishFunc(); // 请求完毕的动作 + + // 如果没有提示错误, 那么此处提示 异常。 + if (!isShowErrorToast) { + infoBox.showErrorToast(`请求网络异常`) + } + + return Promise.reject(res) + + }).finally(() => { // finally 是 then结束后再执行, 此处不适用。 需要在请求完成后立马调用: reqFinishFunc() + + }); + +} + + +// 默认 显示loading(控制 xxs 内 不提示loading ) +function req(uri, data, method = "GET", showLoading = true, extParams = {}) { + // headerObject[appConfig.tokenKey] = storageManage.token() + return commonsProcess(showLoading, () => { + return uni.request( + Object.assign({ + url: baseUrl + uri, + data: data, + method: method, + header: getHeader() + }, extParams) + ) + }) +} + + +// 默认 显示loading(控制 xxs 内 不提示loading ) +function request(args) { + const { + url, + data, + params, + method = "GET", + showLoading = true, + extParams = {} + } = args + let headerObject = {} + // headerObject[appConfig.tokenKey] = storageManage.token() + return commonsProcess(showLoading, () => { + return uni.request( + Object.assign({ + url: baseUrl + url, + data: params||data, + method: method, + header: getHeader() + }, extParams) + ) + }) +} + + + +// 上传 +function upload(uri, data, file, showLoading = true, extParams = {}) { + // 放置token + let headerObject = {} + // headerObject[appConfig.tokenKey] = storageManage.token() + + return commonsProcess(showLoading, () => { + return uni.uploadFile( + Object.assign({ + url: baseUrl + uri, + formData: data, + name: "file", + filePath: file.path||file.url, + header: getHeader() + }, extParams) + ).then((httpData) => { + // uni.upload 返回bodyData 的是 string类型。 需要解析。 + httpData.data = JSON.parse(httpData.data) + return Promise.resolve(httpData) + }).catch(err=>{ + uni.hideLoading() + infoBox.showErrorToast(`上传失败`) + }) + }) +} + +export default { + req: req, + request, + upload: upload +} \ No newline at end of file diff --git a/http/yskApi/invoicing.js b/http/yskApi/invoicing.js new file mode 100644 index 0000000..314a3a4 --- /dev/null +++ b/http/yskApi/invoicing.js @@ -0,0 +1,13 @@ +import http from './http.js' +import $API from '@/http/classApi.js' +import appConfig from '@/config/appConfig.js' +import { + Base64 +} from 'js-base64' +import infoBox from '@/commons/utils/infoBox.js' + +/* 操作记录 */ +export function $getStockOperate(data) { + return http.req('/api/tbProductStockOperate/list', {...data,shopId:uni.getStorageSync('shopId')}, 'POST') +} + diff --git a/http/yskApi/login.js b/http/yskApi/login.js new file mode 100644 index 0000000..0791b7a --- /dev/null +++ b/http/yskApi/login.js @@ -0,0 +1,44 @@ +import http from './http.js' +const request=http.request + +export function login(data) { + return request({ + url: "/auth/login", + method: "post", + data + }); +} + +export function getInfo() { + return request({ + url: "/auth/info", + method: "get" + }); +} + +export function getCodeImg(header) { + return request({ + url: "/auth/code", + method: "get" + }); +} + +export function logout() { + return request({ + url: "/auth/logout", + method: "delete" + }); +} + +/** + * 个人中心 修改密码 + * @param {*} data + * @returns + */ +export function updatePass(data) { + return request({ + url: "/api/users/updatePass", + method: "post", + data + }); +} diff --git a/http/yskApi/order.js b/http/yskApi/order.js new file mode 100644 index 0000000..764344e --- /dev/null +++ b/http/yskApi/order.js @@ -0,0 +1,108 @@ +import http from './http.js' +const request = http.request + +/** + * 查询订单 + * @param {*} data + * @returns + */ +export function tbOrderInfoData(data) { + return request({ + url: "/api/tbOrderInfo/date", + method: "post", + data: { + shopId: uni.getStorageSync('shopId'), + ...data + } + }); +} + +/** + * 导出数据 + * @param {*} data + * @returns + */ +export function tbOrderInfoDownload(data) { + return request({ + url: "/api/tbOrderInfo/download", + method: "post", + data: { + shopId: uni.getStorageSync('shopId'), + ...data + }, + responseType: "blob" + }); +} + +/** + * 通过Id查询订单 + * @param {*} id + * @returns + */ +export function tbOrderInfoDetail(id) { + return request({ + url: `/api/tbOrderInfo/${id}`, + method: "get" + }); +} + +/** + * 通过Id查询订单 + * @param {*} createdAt + * @returns + */ +export function payCount(createdAt) { + console.log(createdAt); + return request({ + url: `/api/tbOrderInfo/payCount`, + method: "post", + data: { + shopId: uni.getStorageSync('shopId'), + createdAt: createdAt + } + }); +} + +/** + * 订单列表 + * @param {*} createdAt + * @returns + */ +export function tbGroupOrderInfo(params) { + return request({ + url: `/api/tbGroupOrderInfo`, + method: "post", + data: { + shopId: uni.getStorageSync('shopId'), + ...params + } + }); +} + +/** + * 退单 + * @param {*} data + * @returns + */ +export function returnGpOrder(data) { + return request({ + url: `/api/tbGroupOrderInfo/returnGpOrder`, + method: "post", + data + }); +} + + +/** + * 店铺订单支付获取链接 + */ +export function $getOrderPayUrl(data) { + return request({ + url: `/api/shopPayApi/getOrderPayUrl`, + method: "get", + data: { + shopId: uni.getStorageSync('shopId'), + ...data + } + }); +} \ No newline at end of file diff --git a/http/yskApi/pad.js b/http/yskApi/pad.js new file mode 100644 index 0000000..cea7721 --- /dev/null +++ b/http/yskApi/pad.js @@ -0,0 +1,40 @@ +import http from './http.js' +const request=http.request + +// Pad商品版式布局列表 +export function $layout(params) { + return request({ + url: '/api/pad/layout/list', + method: "get", + params:{ + userId: uni.getStorageSync("shopUserId"), + shopId: uni.getStorageSync("shopId"), + ...params + } + }); +} + +// Pad点餐列表 +export function $layoutpage(params) { + return request({ + url: '/api/pad/productCategory/page', + method: "get", + params:{ + userId: uni.getStorageSync("shopUserId"), + shopId: uni.getStorageSync("shopId"), + ...params + } + }); +} +//获取详情 + +export function $productCategory(id) { + return request({ + url: '/api/pad/productCategory/'+id, + method: "get", + params:{ + userId: uni.getStorageSync("shopUserId"), + shopId: uni.getStorageSync("shopId"), + } + }); +} diff --git a/http/yskApi/pageNotification.js b/http/yskApi/pageNotification.js new file mode 100644 index 0000000..9597344 --- /dev/null +++ b/http/yskApi/pageNotification.js @@ -0,0 +1,17 @@ +import http from './http.js' +const request=http.request + + +/** + * 获取订阅二维码 + * @returns + */ +export function getSubQrCode(params) { + return request({ + url: `/api/msg/subQrCode`, + method: 'get', + params: { + shopId: uni.getStorageSync('shopId'), + } + }) +} diff --git a/http/yskApi/pageWorkControl.js b/http/yskApi/pageWorkControl.js new file mode 100644 index 0000000..6f4d115 --- /dev/null +++ b/http/yskApi/pageWorkControl.js @@ -0,0 +1,29 @@ +import http from './http.js' +const request = http.request + +/** + * 查询交班记录 + * @returns + */ +export function tbHandover(data) { + return request({ + url: '/api/tbHandover?' + data, + method: 'get' + }) +} + + +/** + * 提交交班 + * @returns + */ +export function handoverData(data) { + return request({ + url: '/api/tbHandover/handoverData', + method: 'post', + data: { + shopId: uni.getStorageSync('shopId'), + ...data + } + }) +} \ No newline at end of file diff --git a/http/yskApi/requestAll.js b/http/yskApi/requestAll.js new file mode 100644 index 0000000..049300b --- /dev/null +++ b/http/yskApi/requestAll.js @@ -0,0 +1,315 @@ +import http from './http.js' +const request = http.request +// 销售总会list +export function summaryTrade(data) { + return request({ + url: '/api/summary/trade', + method: 'post', + data: { + ...data + } + }) +} +export function tbConsInfoFlowcount(data) { + return request({ + url: '/api/tbConsInfoFlow/count', + method: 'post', + data + }) +} +// 供应商列表 +export function tbShopPurveyorTransact(params) { + return request({ + url: '/api/tbShopPurveyorTransact', + method: 'get', + params + }) +} +// 添加供应商 +export function tbShopPurveyorpost(data) { + return request({ + url: `/api/tbShopPurveyor`, + method: "post", + data + }); +} +// 编辑供应商 +export function tbShopPurveyorput(data) { + return request({ + url: `/api/tbShopPurveyor`, + method: "put", + data + }); +} +// 结款记录列表 +export function tbShopPurveyorTransactinfo(data) { + return request({ + url: '/api/tbShopPurveyorTransact/info', + method: "post", + data + }) +} +// 付款 +export function tbShopPurveyorpayTransact(data) { + return request({ + url: '/api/tbShopPurveyorTransact/payTransact', + method: "post", + data + }) +} +// 账单付款记录 +export function tbShopPurveyorTransacttransactPayInfos(params) { + return request({ + url: '/api/tbShopPurveyorTransact/transactPayInfos', + method: 'get', + params + }) +} +// 删除供应商列表 +export function tbShopPurveyordelete(data) { + return request({ + url: `/api/tbShopPurveyor`, + method: "delete", + data + }); +} +// 耗材报损 +export function tbConsInfoFlowfrmLoss(data) { + return request({ + url: '/api/tbConsInfoFlow/frmLoss', + method: 'post', + data + }) +} +// 销售排行榜 +export function dateProduct(params) { + return request({ + url: '/api/summary/productSaleDate', + method: 'get', + params + }) +} +// 是否开启 +export function updateStatus(data) { + return request({ + url: `/api/tbPlussShopStaff/updateStatus`, + method: "put", + data + }); +} +// 编辑 +export function tbPlussShopStaffDetail(id) { + return request({ + url: `/api/tbPlussShopStaff/${id}`, + method: "get" + }); +} +// 新增耗材类型 +export function tbConsType(data) { + return request({ + url: '/api/tbConsType ', + method: 'post', + data + }) +} +// 编辑耗材类型 +export function tbConsTypeput(data) { + return request({ + url: '/api/tbConsInfo ', + method: "put", + data + }); +} + +// 获取耗材类型列表 +export function tbConsTypeList(params) { + return request({ + url: '/api/tbConsType', + method: 'get', + params + }) +} +// 修改耗材类型 +export function edittbConsTypeput(data) { + return request({ + url: '/api/tbConsType ', + method: "put", + data + }); +} +// 添加耗材列表 +export function tbConsInfoAddlist(data) { + return request({ + url: '/api/tbConsInfo ', + method: 'post', + data + }) +} +// 操作耗材入库 +export function tbConsInfostockInOut(data) { + return request({ + url: '/api/tbConsInfo/stockInOut ', + method: 'post', + data + }) +} +// 获取耗材列表 +export function tbConsInfoList(params) { + return request({ + url: '/api/tbConsInfo', + method: 'get', + params + }) +} +// 耗材盘点 +export function tbConsInfotbConCheck(data) { + return request({ + url: '/api/tbConCheck ', + method: 'post', + data + }) +} +// 获取供应商列表 +export function tbShopPurveyor(params) { + return request({ + url: '/api/tbShopPurveyor', + method: 'get', + params + }) +} +// 桌型列表 +export function callTable(params) { + return request({ + url: '/callTable', + method: 'get', + params + }) +} +// 排队列表 +export function callTablequeue(params) { + return request({ + url: '/callTable/queue', + method: 'get', + params + }) +} +// 取号 +export function callTabletakeNumber(data) { + return request({ + url: '/callTable/takeNumber', + method: 'post', + data: { + ...data + } + }) +} +// 增减余额 +export function midfiyAccount(data) { + return request({ + url: '/api/tbShopUser/midfiyAccount', + method: 'post', + data: { + ...data + } + }) +} +// 新增会员 +export function member(data) { + return request({ + url: '/api/member', + method: 'post', + data: { + ...data + } + }) +} +// 修改会员 +export function tbShopUser(data) { + return request({ + url: `/api/tbShopUser`, + method: "put", + data + }); +} +export function callTablecallRecord(params) { + return request({ + url: '/callTable/callRecord', + method: 'get', + params + }) +} +export function callTableput(data) { + return request({ + url: `/callTable/updateState`, + method: "put", + data + }); +} +// 叫号 +export function callTablecall(data) { + return request({ + url: `/callTable/call`, + method: 'post', + data + }); +} +// 获取员工列表 +export function rolesGet(params) { + return request({ + url: `/api/tbPlussShopStaff`, + method: "get", + params + }); +} +// 删除员工 +export function shopStaffDelete(data) { + return request({ + url: `/api/tbPlussShopStaff`, + method: "delete", + data + }); +} +// 新增员工获取权限 +export function tbShopPermissionList() { + return request({ + url: `/api/tbShopPermission/list`, + method: "get" + }); +} + +// 获取角色权限 +export function getroles() { + return request({ + url: `/api/roles`, + method: "get" + }); +} +export function tbConsTypes() { + return request({ + url: `/api/tbConsType`, + method: "get" + }); +} +export function tbPlussShopStaff(data) { + return request({ + url: `/api/tbPlussShopStaff`, + method: data.id ? "put" : "post", + data + }); +} +// 耗材列表 +export function viewConInfoFlowget(data) { + return request({ + url: `/api/tbConsInfo/allAndPro`, + method: 'post', + data + }); +} +// 耗材记录 +export function tbConsInfoFlowstock(data) { + return request({ + url: `/api/tbConsInfoFlow/stock`, + method: 'post', + data + }); +} \ No newline at end of file diff --git a/http/yskApi/shop-user.js b/http/yskApi/shop-user.js new file mode 100644 index 0000000..4434d93 --- /dev/null +++ b/http/yskApi/shop-user.js @@ -0,0 +1,48 @@ +// 用户管理 +import http from './http.js' +import $API from '@/http/classApi.js' +import appConfig from '@/config/appConfig.js' +import { + Base64 +} from 'js-base64' +import infoBox from '@/commons/utils/infoBox.js' + +const request=http.request + +// 获取店铺会员二维码 +export function getwxacode(data) { + return request({ + url: `/shop/storage/getwxacode`, + method: "post", + data + }); +} +/** + * 商家用户列表 + * @returns + */ +export function queryAllShopUser(params) { + return request({ + url: `/api/tbShopUser/queryAllShopUser`, + method: "get", + params: { + shopId: uni.getStorageSync('shopId'), + ...params + } + }); +} +/** + * 查询商家用户概述信息 + * @returns + */ +export function queryAllShopInfo(params) { + return request({ + url: `/api/tbShopUser/summary`, + method: "get", + params: { + shopId: uni.getStorageSync('shopId'), + isVip:1, + ...params + } + }); +} diff --git a/http/yskApi/shop.js b/http/yskApi/shop.js new file mode 100644 index 0000000..9422701 --- /dev/null +++ b/http/yskApi/shop.js @@ -0,0 +1,735 @@ +import http from './http.js' +const request=http.request + + +/** + * 获取店铺列表 + * @returns + */ +export function getShopList(params) { + return request({ + url: `/api/tbShopInfo`, + method: 'get', + params: { + + } + }) +} + +/** + * 获取店铺数据 + * @returns + */ +export function getShopInfo(params) { + return request({ + url: `/api/tbShopInfo/${params}`, + method: 'get', + params: { + + } + }) +} + +/** + * 更改店铺信息 + * @returns + */ +export function editShopInfo(data) { + return request({ + url: `/api/tbShopInfo`, + method: 'put', + data:{ + // shopId: uni.getStorageSync('shopId'), + ...data + } + }) +} + + +/** + * 获取店铺图片 + * @returns + */ +export function getShopExtend(params) { + return request({ + url: `/tbShopExtend`, + method: 'get', + params:{ + shopId: uni.getStorageSync('shopId'), + } + }) +} + +/** + * 获取店铺图片 + * @returns + */ +export function editShopExtend(data) { + return request({ + url: `/tbShopExtend`, + method: 'put', + data:{ + shopId: uni.getStorageSync('shopId'), + ...data + } + }) +} +/** + * 商品列表 + * @returns + */ +export function tbProduct(params) { + return request({ + url: "/api/tbProduct", + method: "get", + params + }); +} + +/** + * 删除商品 + * @returns + */ +export function tbProductDelete(data) { + return request({ + url: "/api/tbProduct", + method: "delete", + data + }); +} + +/** + * 商品单位列表 + * @returns + */ +export function tbShopUnit(params) { + return request({ + url: "/api/tbShopUnit", + method: "get", + params + }); +} + +/** + * 店铺基本配置 + * @returns + */ +export function tbShopCurrency(shopId) { + return request({ + url: `/api/tbShopCurrency/${shopId}`, + method: "get" + }); +} + +/** + * 修改店铺信息 + * @returns + */ +export function tbShopCurrencyPut(data) { + return request({ + url: `/api/tbShopCurrency`, + method: "put", + data + }); +} + +/** + * 新增单位 + * @returns + */ +export function tbShopUnitPost(data) { + return request({ + url: `/api/tbShopUnit`, + method: "post", + data + }); +} + +/** + * 更改单位 + * @returns + */ +export function tbShopUnitPut(data) { + return request({ + url: `/api/tbShopUnit`, + method: "put", + data + }); +} + +/** + * 删除单位 + * @returns + */ +export function tbShopUnitDelete(data) { + return request({ + url: `/api/tbShopUnit`, + method: "delete", + data + }); +} + +/** + * 店铺基本配置 + * @returns + */ +export function tbShopCurrencyGet(params) { + return request({ + url: `/api/tbShopUnit`, + method: "get", + params:{ + sort:'id', + shopId: uni.getStorageSync("shopId"), + ...params, + } + }); +} + +/** + * 商品分类列表 + * @returns + */ +export function tbShopCategoryGet(params) { + return request({ + url: `/api/tbShopCategory`, + method: "get", + params + }); +} + +/** + * 新增、编辑分类/新增、编辑子分类 + * @returns + */ +export function tbShopCategoryPost(data, method = "post") { + return request({ + url: `/api/tbShopCategory`, + method: method, + data + }); +} + +/** + * 删除商品分类 + * @returns + */ +export function tbShopCategoryDelete(data) { + return request({ + url: `/api/tbShopCategory`, + method: "delete", + data + }); +} + +/** + * 规格增加 + * @returns + */ +export function tbProductSpecPost(data) { + return request({ + url: `/api/tbProductSpec`, + method: "post", + data + }); +} + +/** + * 规格列表 + * @returns + */ +export function tbProductSpecGet(params) { + return request({ + url: `/api/tbProductSpec`, + method: "get", + params + }); +} + +/** + * 规格更改 + * @returns + */ +export function tbProductSpecPut(data) { + return request({ + url: `/api/tbProductSpec`, + method: "put", + data + }); +} + +/** + * 删除规格 + * @returns + */ +export function tbProductSpecDelete(data) { + return request({ + url: `/api/tbProductSpec`, + method: "DELETE", + data + }); +} + +/** + * 新增分组 + * @returns + */ +export function tbProductGroupPost(data) { + return request({ + url: `/api/tbProductGroup`, + method: "post", + data + }); +} + +/** + * 更改分组 + * @returns + */ +export function tbProductGroupPut(data) { + return request({ + url: `/api/tbProductGroup`, + method: "PUT", + data + }); +} + +/** + * 商品分组列表 + * @returns + */ +export function tbProductGroupGet(params) { + return request({ + url: `/api/tbProductGroup`, + method: "get", + params + }); +} + +/** + * 商品列表(根据分组中的商品id) + * @returns + */ +export function productListGet(productGroup) { + return request({ + url: `/api/tbProductGroup/${productGroup}`, + method: "get" + }); +} + +/** + * 删除分组 + * @returns + */ +export function tbProductGroupDelete(data) { + return request({ + url: `/api/tbProductGroup`, + method: "DELETE", + data + }); +} + +/** + * 添加商品 + * @returns + */ +export function tbProductPost(data) { + return request({ + url: `/api/tbProduct`, + method: "post", + data + }); +} + +/** + * 添加商品 + * @returns + */ +export function tbProductPut(data) { + return request({ + url: `/api/tbProduct`, + method: "put", + data + }); +} + +/** + * 商品详情(单个商品) + * product 商品id + * @returns + */ +export function tbProductGetDetail(product) { + return request({ + url: `/api/tbProduct/${product}`, + method: "get" + }); +} + +/** + * 店铺列表 + * @returns + */ +export function tbShopInfo(params) { + return request({ + url: `/api/tbShopInfo`, + method: "get", + params + }); +} + +/** + * 增加激活码 + * @returns + */ +export function tbMerchantRegisterPost(data) { + return request({ + url: `/api/tbMerchantRegister`, + method: "post", + data + }); +} + +/** + * 激活码列表 + * @returns + */ +export function tbMerchantRegisterList(data) { + return request({ + url: `/api/tbMerchantRegister/list`, + method: "post", + data + }); +} + +/** + * 增加/编辑店铺 + * @returns + */ +export function tbShopInfoPost(data, method = "post") { + return request({ + url: `/api/tbShopInfo`, + method: method, + data + }); +} + +/** + * 详情(配置三方支付) + * @returns + */ +export function tbMerchantThirdApply(shopId) { + return request({ + url: `/api/tbMerchantThirdApply/${shopId}`, + method: "get" + }); +} + +/** + * 修改第三方配置 + * @returns + */ +export function tbMerchantThirdApplyPut(data) { + return request({ + url: `/api/tbMerchantThirdApply`, + method: "put", + data + }); +} + +/** + * 设置热销商品 + * @returns + */ +export function tbProductIsHot(params) { + return request({ + url: `/api/tbProduct/isHot`, + method: "get", + params + }); +} + +/** + * 增加/编辑优惠券 + * @returns + */ +export function tbMerchantCoupon(data, method = "post") { + return request({ + url: `/api/tbMerchantCoupon`, + method: method, + data + }); +} + +/** + * 设置热销商品 + * @returns + */ +export function tbMerchantCouponGet(params) { + return request({ + url: `/api/tbMerchantCoupon`, + method: "get", + params + }); +} + +/** + * 设置热销商品 + * @returns + */ +export function geocode(params) { + return request({ + url: `/api/geocode`, + method: "get", + params + }); +} + +/** + * 新增、修改活动 + * @returns + */ +export function modityActivate(data) { + return request({ + url: `/shop/storage/modityActivate`, + method: "post", + data + }); +} + +/** + * 活动列表 + * @returns + */ +export function findActivate(params) { + return request({ + url: `/shop/storage/findActivate`, + method: "get", + params + }); +} +// 获取店铺会员二维码 +export function getwxacode(data) { + return request({ + url: `/shop/storage/getwxacode`, + method: "post", + data + }); +} +/** + * 商家用户列表 + * @returns + */ +export function queryAllShopUser(params) { + return request({ + url: `/api/tbShopUser/queryAllShopUser`, + method: "get", + params: { + shopId: uni.getStorageSync("shopId"), + ...params + } + }); +} +/** + * 查询商家用户概述信息 + * @returns + */ +export function queryAllShopInfo(params) { + return request({ + url: `/api/tbShopUser/summary`, + method: "get", + params: { + shopId: uni.getStorageSync("shopId"), + ...params + } + }); +} + +/** + * 修改商品排序 + * @returns + */ +export function upProSort(data) { + return request({ + url: `/api/tbProduct/upProSort`, + method: "post", + data + }); +} + +/** + * 修改分组排序 + * @returns + */ +export function upGroupSort(data) { + return request({ + url: `/api/tbProductGroup/upGroupSort`, + method: "post", + data + }); +} + +/** + * 修改分类排序 + * @returns + */ +export function upCategorySort(data) { + return request({ + url: `/api/tbShopCategory/upCategorySort`, + method: "post", + data + }); +} + +/** + * 查询店铺充值记录 + * @returns + */ +export function tbShopUserRecharge(params) { + return request({ + url: `/api/tbShopUser/recharge`, + method: "get", + params: { + shopId: uni.getStorageSync("shopId"), + ...params + } + }); +} + +/** + * 导出充值记录 + * @returns + */ +export function downloadTableRecharge(data) { + return request({ + url: `/api/tbShopUser/recharge/download`, + method: "post", + data: { + shopId: uni.getStorageSync("shopId"), + ...data + }, + responseType: "blob" + }); +} + +/** + * 员工列表 + * @returns + */ +export function tbPlussShopStaffGet(params) { + return request({ + url: `/api/tbPlussShopStaff`, + method: "get", + params: { + shopId: uni.getStorageSync("shopId"), + ...params + } + }); +} + +/** + * 角色列表 + * @returns + */ +export function rolesGet() { + return request({ + url: `/api/roles`, + method: "get" + }); +} + +/** + * 增加员工 + * @returns + */ +export function tbPlussShopStaff(data) { + return request({ + url: `/api/tbPlussShopStaff`, + method: data.id ? "put" : "post", + data: { + shopId: uni.getStorageSync("shopId"), + ...data + } + }); +} + +/** + * 通过id获取员工信息 + * @returns + */ +export function tbPlussShopStaffDetail(id) { + return request({ + url: `/api/tbPlussShopStaff/${id}`, + method: "get" + }); +} + +/** + * 更改员工状态 + * @returns + */ +export function updateStatus(data) { + return request({ + url: `/api/tbPlussShopStaff/updateStatus`, + method: "put", + data + }); +} + +/** + * 员工删除 + * @returns + */ +export function shopStaffDelete(data) { + return request({ + url: `/api/tbPlussShopStaff`, + method: "delete", + data + }); +} + +//增减余额 +export function midfiyAccount(data) { + return request({ + url: `/api/tbShopUser/midfiyAccount`, + method: "post", + data + }); +} +// 编辑用户 +export function tbShopUseredit(data) { + return request({ + url: `/api/tbShopUser`, + method: "put", + data + }); +} +// 通过活动id获取赠送商品列表 +export function activate(id) { + return request({ + url: `shop/storage/activate/${id}`, + method: "get" + }); +} + +// 通过活动id获取赠送商品列表 +export function queryShopUserFlow(params) { + return request({ + url: `/api/tbShopUser/queryShopUserFlow`, + method: "get", + params + }); +} + +//新增 + +// 查询员工是否拥有权限 +export function $hasPermission(params) { + return request({ + url: '/api/tbShopPermission/hasPermission', + method: "get", + params:{ + userId: uni.getStorageSync("shopUserId"), + ...params + } + }); +} + diff --git a/http/yskApi/sku.js b/http/yskApi/sku.js new file mode 100644 index 0000000..d65e86f --- /dev/null +++ b/http/yskApi/sku.js @@ -0,0 +1,13 @@ +import http from './http.js' +import $API from '@/http/classApi.js' +import appConfig from '@/config/appConfig.js' +import { + Base64 +} from 'js-base64' +import infoBox from '@/commons/utils/infoBox.js' + +/* 查询库存 */ +export function $getProductSku(productId) { + return http.req('/api/stock/sku', {productId,shopId:uni.getStorageSync('shopId')}, 'GET') +} + diff --git a/http/yskApi/table.js b/http/yskApi/table.js new file mode 100644 index 0000000..796f756 --- /dev/null +++ b/http/yskApi/table.js @@ -0,0 +1,50 @@ +// 桌台管理 +import http from './http.js' +const request = http.request +import $API from '@/http/classApi.js' +import appConfig from '@/config/appConfig.js' +import { + Base64 +} from 'js-base64' +import infoBox from '@/commons/utils/infoBox.js' + +/* 台桌区域 */ +export const $tableArea = new $API('/api/tbShopArea', http.req) +/* 台桌 */ +export const $table = new $API('/api/tbShopTable', http.req) +/* 绑定 */ +// export const $bind=new $API('/api/tbShopTable/bind',http.req) +export function $bind(data) { + return request({ + url: "/api/tbShopTable/bind", + method: "post", + data: { + shopId: uni.getStorageSync('shopId'), + ...data + } + }); +} +//获取台桌详情状态 +export function $returnTableDetail(data) { + return request({ + url: '/api/tbShopTable/state', + method: "get", + params: { + shopId: uni.getStorageSync('shopId'), + ...data + } + }); +} + + +// 选择台桌 +export function $choseTable(data) { + return request({ + url: '/api/place/choseTable', + method: "put", + data: { + shopId: uni.getStorageSync('shopId'), + ...data + } + }); +} \ No newline at end of file diff --git a/http/yskApi/user.js b/http/yskApi/user.js new file mode 100644 index 0000000..1b46450 --- /dev/null +++ b/http/yskApi/user.js @@ -0,0 +1,25 @@ +import http from './http.js' +const request=http.request +/** + * 用户详情 + * @returns + */ +export function tbShopInfo(shopId) { + const _shopId=uni.getStorageSync('shopId') + return request({ + url: `/api/tbShopInfo/${shopId||_shopId}`, + method: 'get' + }) +} + +/** + * 修改店铺信息 + * @returns + */ +export function tbShopInfoPut(data) { + return request({ + url: `/api/tbShopInfo`, + method: 'put', + data + }) +} \ No newline at end of file diff --git a/http/yskApi/version.js b/http/yskApi/version.js new file mode 100644 index 0000000..9929361 --- /dev/null +++ b/http/yskApi/version.js @@ -0,0 +1,15 @@ +import http from './http.js' +const request=http.request + + +/** + * 查询所属渠道升级版本 + * @returns + */ +export function getFindBySource(params) { + return request({ + url: `/api/tbVersion/findBySource`, + method: 'get', + params + }) +} diff --git a/index.html b/index.html new file mode 100644 index 0000000..c3ff205 --- /dev/null +++ b/index.html @@ -0,0 +1,20 @@ + + + + + + + + + + +
+ + + diff --git a/js_sdk/js-base64/.attic/test-moment/dankogai.js b/js_sdk/js-base64/.attic/test-moment/dankogai.js new file mode 100644 index 0000000..b631414 --- /dev/null +++ b/js_sdk/js-base64/.attic/test-moment/dankogai.js @@ -0,0 +1,44 @@ +/* + * $Id: dankogai.js,v 0.4 2012/08/24 05:23:18 dankogai Exp dankogai $ + * + * use mocha to test me + * http://visionmedia.github.com/mocha/ + */ +var assert = assert || require("assert"); +var Base64 = Base64 || require('../base64.js').Base64; +var is = function (a, e, m) { + return function () { + assert.equal(a, e, m) + } +}; + +describe('basic', function () { + it('d', is(Base64.encode('d'), 'ZA==')); + it('da', is(Base64.encode('da'), 'ZGE=')); + it('dan', is(Base64.encode('dan'), 'ZGFu')); + it('ZA==', is(Base64.decode('ZA=='), 'd' )); + it('ZGE=', is(Base64.decode('ZGE='), 'da' )); + it('ZGFu', is(Base64.decode('ZGFu'), 'dan' )); +}); + +describe('whitespace', function () { + it('Z A==', is(Base64.decode('ZA =='), 'd' )); + it('ZG E=', is(Base64.decode('ZG E='), 'da' )); + it('ZGF u', is(Base64.decode('ZGF u'), 'dan' )); +}); + +describe('null', function () { + it('\\0', is(Base64.encode('\0'), 'AA==')); + it('\\0\\0', is(Base64.encode('\0\0'), 'AAA=')); + it('\\0\\0\\0', is(Base64.encode('\0\0\0'), 'AAAA')); + it('AA==', is(Base64.decode('AA=='), '\0' )); + it('AAA=', is(Base64.decode('AAA='), '\0\0' )); + it('AAAA', is(Base64.decode('AAAA'), '\0\0\0')); +}); + +describe('Base64', function () { + it('.encode', is(Base64.encode('小飼弾'), '5bCP6aO85by+')); + it('.encodeURI', is(Base64.encodeURI('小飼弾'), '5bCP6aO85by-')); + it('.decode', is(Base64.decode('5bCP6aO85by+'), '小飼弾')); + it('.decode', is(Base64.decode('5bCP6aO85by-'), '小飼弾')); +}); diff --git a/js_sdk/js-base64/.attic/test-moment/es5.js b/js_sdk/js-base64/.attic/test-moment/es5.js new file mode 100644 index 0000000..ef134f6 --- /dev/null +++ b/js_sdk/js-base64/.attic/test-moment/es5.js @@ -0,0 +1,24 @@ +/* + * $Id: es5.js,v 0.1 2012/08/23 19:43:17 dankogai Exp dankogai $ + * + * use mocha to test me + * http://visionmedia.github.com/mocha/ + */ +var assert = assert || require("assert"); +var Base64 = Base64 || require('../base64.js').Base64; +var is = function (a, e, m) { + return function () { + assert.equal(a, e, m) + } +}; + +if ('extendString' in Base64){ + Base64.extendString(); + describe('String', function () { + it('.toBase64', is('小飼弾'.toBase64(), '5bCP6aO85by+')); + it('.toBase64', is('小飼弾'.toBase64(true), '5bCP6aO85by-')); + it('.toBase64URI', is('小飼弾'.toBase64URI(), '5bCP6aO85by-')); + it('.fromBase64', is('5bCP6aO85by+'.fromBase64(), '小飼弾')); + it('.fromBase64', is('5bCP6aO85by-'.fromBase64(), '小飼弾')); + }); +} diff --git a/js_sdk/js-base64/.attic/test-moment/es6.js b/js_sdk/js-base64/.attic/test-moment/es6.js new file mode 100644 index 0000000..7dbe475 --- /dev/null +++ b/js_sdk/js-base64/.attic/test-moment/es6.js @@ -0,0 +1,25 @@ +/* + * $Id: es6.js,v 0.1 2017/11/29 21:43:17 ufolux Exp ufolux $ + * + * use mocha to test me + * http://visionmedia.github.com/mocha/ + */ +import {Base64} from '../base64' + +var assert = assert || require("assert"); +var is = function (a, e, m) { + return function () { + assert.equal(a, e, m) + } +}; + +if ('extendString' in Base64){ + Base64.extendString(); + describe('String', function () { + it('.toBase64', is('小飼弾'.toBase64(), '5bCP6aO85by+')); + it('.toBase64', is('小飼弾'.toBase64(true), '5bCP6aO85by-')); + it('.toBase64URI', is('小飼弾'.toBase64URI(), '5bCP6aO85by-')); + it('.fromBase64', is('5bCP6aO85by+'.fromBase64(), '小飼弾')); + it('.fromBase64', is('5bCP6aO85by-'.fromBase64(), '小飼弾')); + }); +} diff --git a/js_sdk/js-base64/.attic/test-moment/index.html b/js_sdk/js-base64/.attic/test-moment/index.html new file mode 100644 index 0000000..13136c9 --- /dev/null +++ b/js_sdk/js-base64/.attic/test-moment/index.html @@ -0,0 +1,40 @@ + + + + Mocha Tests + + + +
+ + + + + + + + + + + + + + + + $Id: index.html,v 0.3 2017/09/11 08:43:43 dankogai Exp dankogai $ +
+ + diff --git a/js_sdk/js-base64/.attic/test-moment/large.js b/js_sdk/js-base64/.attic/test-moment/large.js new file mode 100644 index 0000000..20d7842 --- /dev/null +++ b/js_sdk/js-base64/.attic/test-moment/large.js @@ -0,0 +1,25 @@ +/* + * $Id: large.js,v 0.3 2012/08/23 19:14:37 dankogai Exp dankogai $ + * + * use mocha to test me + * http://visionmedia.github.com/mocha/ + */ +var assert = assert || require("assert"); +var Base64 = Base64 || require('../base64.js').Base64; +var is = function (a, e, m) { + return function () { + assert.equal(a, e, m) + } +}; +var seed = function () { + var a, i; + for (a = [], i = 0; i < 256; i++) { + a.push(String.fromCharCode(i)); + } + return a.join(''); +}(); +describe('Base64', function () { + for (var i = 0, str = seed; i < 16; str += str, i++) { + it(''+str.length, is(Base64.decode(Base64.encode(str)), str)); + } +}); diff --git a/js_sdk/js-base64/.attic/test-moment/moment.js b/js_sdk/js-base64/.attic/test-moment/moment.js new file mode 100644 index 0000000..71b15f9 --- /dev/null +++ b/js_sdk/js-base64/.attic/test-moment/moment.js @@ -0,0 +1,4535 @@ +//! moment.js +//! version : 2.20.1 +//! authors : Tim Wood, Iskren Chernev, Moment.js contributors +//! license : MIT +//! momentjs.com + +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + global.moment = factory() +}(this, (function () { 'use strict'; + +var hookCallback; + +function hooks () { + return hookCallback.apply(null, arguments); +} + +// This is done to register the method called with moment() +// without creating circular dependencies. +function setHookCallback (callback) { + hookCallback = callback; +} + +function isArray(input) { + return input instanceof Array || Object.prototype.toString.call(input) === '[object Array]'; +} + +function isObject(input) { + // IE8 will treat undefined and null as object if it wasn't for + // input != null + return input != null && Object.prototype.toString.call(input) === '[object Object]'; +} + +function isObjectEmpty(obj) { + if (Object.getOwnPropertyNames) { + return (Object.getOwnPropertyNames(obj).length === 0); + } else { + var k; + for (k in obj) { + if (obj.hasOwnProperty(k)) { + return false; + } + } + return true; + } +} + +function isUndefined(input) { + return input === void 0; +} + +function isNumber(input) { + return typeof input === 'number' || Object.prototype.toString.call(input) === '[object Number]'; +} + +function isDate(input) { + return input instanceof Date || Object.prototype.toString.call(input) === '[object Date]'; +} + +function map(arr, fn) { + var res = [], i; + for (i = 0; i < arr.length; ++i) { + res.push(fn(arr[i], i)); + } + return res; +} + +function hasOwnProp(a, b) { + return Object.prototype.hasOwnProperty.call(a, b); +} + +function extend(a, b) { + for (var i in b) { + if (hasOwnProp(b, i)) { + a[i] = b[i]; + } + } + + if (hasOwnProp(b, 'toString')) { + a.toString = b.toString; + } + + if (hasOwnProp(b, 'valueOf')) { + a.valueOf = b.valueOf; + } + + return a; +} + +function createUTC (input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, true).utc(); +} + +function defaultParsingFlags() { + // We need to deep clone this object. + return { + empty : false, + unusedTokens : [], + unusedInput : [], + overflow : -2, + charsLeftOver : 0, + nullInput : false, + invalidMonth : null, + invalidFormat : false, + userInvalidated : false, + iso : false, + parsedDateParts : [], + meridiem : null, + rfc2822 : false, + weekdayMismatch : false + }; +} + +function getParsingFlags(m) { + if (m._pf == null) { + m._pf = defaultParsingFlags(); + } + return m._pf; +} + +var some; +if (Array.prototype.some) { + some = Array.prototype.some; +} else { + some = function (fun) { + var t = Object(this); + var len = t.length >>> 0; + + for (var i = 0; i < len; i++) { + if (i in t && fun.call(this, t[i], i, t)) { + return true; + } + } + + return false; + }; +} + +function isValid(m) { + if (m._isValid == null) { + var flags = getParsingFlags(m); + var parsedParts = some.call(flags.parsedDateParts, function (i) { + return i != null; + }); + var isNowValid = !isNaN(m._d.getTime()) && + flags.overflow < 0 && + !flags.empty && + !flags.invalidMonth && + !flags.invalidWeekday && + !flags.weekdayMismatch && + !flags.nullInput && + !flags.invalidFormat && + !flags.userInvalidated && + (!flags.meridiem || (flags.meridiem && parsedParts)); + + if (m._strict) { + isNowValid = isNowValid && + flags.charsLeftOver === 0 && + flags.unusedTokens.length === 0 && + flags.bigHour === undefined; + } + + if (Object.isFrozen == null || !Object.isFrozen(m)) { + m._isValid = isNowValid; + } + else { + return isNowValid; + } + } + return m._isValid; +} + +function createInvalid (flags) { + var m = createUTC(NaN); + if (flags != null) { + extend(getParsingFlags(m), flags); + } + else { + getParsingFlags(m).userInvalidated = true; + } + + return m; +} + +// Plugins that add properties should also add the key here (null value), +// so we can properly clone ourselves. +var momentProperties = hooks.momentProperties = []; + +function copyConfig(to, from) { + var i, prop, val; + + if (!isUndefined(from._isAMomentObject)) { + to._isAMomentObject = from._isAMomentObject; + } + if (!isUndefined(from._i)) { + to._i = from._i; + } + if (!isUndefined(from._f)) { + to._f = from._f; + } + if (!isUndefined(from._l)) { + to._l = from._l; + } + if (!isUndefined(from._strict)) { + to._strict = from._strict; + } + if (!isUndefined(from._tzm)) { + to._tzm = from._tzm; + } + if (!isUndefined(from._isUTC)) { + to._isUTC = from._isUTC; + } + if (!isUndefined(from._offset)) { + to._offset = from._offset; + } + if (!isUndefined(from._pf)) { + to._pf = getParsingFlags(from); + } + if (!isUndefined(from._locale)) { + to._locale = from._locale; + } + + if (momentProperties.length > 0) { + for (i = 0; i < momentProperties.length; i++) { + prop = momentProperties[i]; + val = from[prop]; + if (!isUndefined(val)) { + to[prop] = val; + } + } + } + + return to; +} + +var updateInProgress = false; + +// Moment prototype object +function Moment(config) { + copyConfig(this, config); + this._d = new Date(config._d != null ? config._d.getTime() : NaN); + if (!this.isValid()) { + this._d = new Date(NaN); + } + // Prevent infinite loop in case updateOffset creates new moment + // objects. + if (updateInProgress === false) { + updateInProgress = true; + hooks.updateOffset(this); + updateInProgress = false; + } +} + +function isMoment (obj) { + return obj instanceof Moment || (obj != null && obj._isAMomentObject != null); +} + +function absFloor (number) { + if (number < 0) { + // -0 -> 0 + return Math.ceil(number) || 0; + } else { + return Math.floor(number); + } +} + +function toInt(argumentForCoercion) { + var coercedNumber = +argumentForCoercion, + value = 0; + + if (coercedNumber !== 0 && isFinite(coercedNumber)) { + value = absFloor(coercedNumber); + } + + return value; +} + +// compare two arrays, return the number of differences +function compareArrays(array1, array2, dontConvert) { + var len = Math.min(array1.length, array2.length), + lengthDiff = Math.abs(array1.length - array2.length), + diffs = 0, + i; + for (i = 0; i < len; i++) { + if ((dontConvert && array1[i] !== array2[i]) || + (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) { + diffs++; + } + } + return diffs + lengthDiff; +} + +function warn(msg) { + if (hooks.suppressDeprecationWarnings === false && + (typeof console !== 'undefined') && console.warn) { + console.warn('Deprecation warning: ' + msg); + } +} + +function deprecate(msg, fn) { + var firstTime = true; + + return extend(function () { + if (hooks.deprecationHandler != null) { + hooks.deprecationHandler(null, msg); + } + if (firstTime) { + var args = []; + var arg; + for (var i = 0; i < arguments.length; i++) { + arg = ''; + if (typeof arguments[i] === 'object') { + arg += '\n[' + i + '] '; + for (var key in arguments[0]) { + arg += key + ': ' + arguments[0][key] + ', '; + } + arg = arg.slice(0, -2); // Remove trailing comma and space + } else { + arg = arguments[i]; + } + args.push(arg); + } + warn(msg + '\nArguments: ' + Array.prototype.slice.call(args).join('') + '\n' + (new Error()).stack); + firstTime = false; + } + return fn.apply(this, arguments); + }, fn); +} + +var deprecations = {}; + +function deprecateSimple(name, msg) { + if (hooks.deprecationHandler != null) { + hooks.deprecationHandler(name, msg); + } + if (!deprecations[name]) { + warn(msg); + deprecations[name] = true; + } +} + +hooks.suppressDeprecationWarnings = false; +hooks.deprecationHandler = null; + +function isFunction(input) { + return input instanceof Function || Object.prototype.toString.call(input) === '[object Function]'; +} + +function set (config) { + var prop, i; + for (i in config) { + prop = config[i]; + if (isFunction(prop)) { + this[i] = prop; + } else { + this['_' + i] = prop; + } + } + this._config = config; + // Lenient ordinal parsing accepts just a number in addition to + // number + (possibly) stuff coming from _dayOfMonthOrdinalParse. + // TODO: Remove "ordinalParse" fallback in next major release. + this._dayOfMonthOrdinalParseLenient = new RegExp( + (this._dayOfMonthOrdinalParse.source || this._ordinalParse.source) + + '|' + (/\d{1,2}/).source); +} + +function mergeConfigs(parentConfig, childConfig) { + var res = extend({}, parentConfig), prop; + for (prop in childConfig) { + if (hasOwnProp(childConfig, prop)) { + if (isObject(parentConfig[prop]) && isObject(childConfig[prop])) { + res[prop] = {}; + extend(res[prop], parentConfig[prop]); + extend(res[prop], childConfig[prop]); + } else if (childConfig[prop] != null) { + res[prop] = childConfig[prop]; + } else { + delete res[prop]; + } + } + } + for (prop in parentConfig) { + if (hasOwnProp(parentConfig, prop) && + !hasOwnProp(childConfig, prop) && + isObject(parentConfig[prop])) { + // make sure changes to properties don't modify parent config + res[prop] = extend({}, res[prop]); + } + } + return res; +} + +function Locale(config) { + if (config != null) { + this.set(config); + } +} + +var keys; + +if (Object.keys) { + keys = Object.keys; +} else { + keys = function (obj) { + var i, res = []; + for (i in obj) { + if (hasOwnProp(obj, i)) { + res.push(i); + } + } + return res; + }; +} + +var defaultCalendar = { + sameDay : '[Today at] LT', + nextDay : '[Tomorrow at] LT', + nextWeek : 'dddd [at] LT', + lastDay : '[Yesterday at] LT', + lastWeek : '[Last] dddd [at] LT', + sameElse : 'L' +}; + +function calendar (key, mom, now) { + var output = this._calendar[key] || this._calendar['sameElse']; + return isFunction(output) ? output.call(mom, now) : output; +} + +var defaultLongDateFormat = { + LTS : 'h:mm:ss A', + LT : 'h:mm A', + L : 'MM/DD/YYYY', + LL : 'MMMM D, YYYY', + LLL : 'MMMM D, YYYY h:mm A', + LLLL : 'dddd, MMMM D, YYYY h:mm A' +}; + +function longDateFormat (key) { + var format = this._longDateFormat[key], + formatUpper = this._longDateFormat[key.toUpperCase()]; + + if (format || !formatUpper) { + return format; + } + + this._longDateFormat[key] = formatUpper.replace(/MMMM|MM|DD|dddd/g, function (val) { + return val.slice(1); + }); + + return this._longDateFormat[key]; +} + +var defaultInvalidDate = 'Invalid date'; + +function invalidDate () { + return this._invalidDate; +} + +var defaultOrdinal = '%d'; +var defaultDayOfMonthOrdinalParse = /\d{1,2}/; + +function ordinal (number) { + return this._ordinal.replace('%d', number); +} + +var defaultRelativeTime = { + future : 'in %s', + past : '%s ago', + s : 'a few seconds', + ss : '%d seconds', + m : 'a minute', + mm : '%d minutes', + h : 'an hour', + hh : '%d hours', + d : 'a day', + dd : '%d days', + M : 'a month', + MM : '%d months', + y : 'a year', + yy : '%d years' +}; + +function relativeTime (number, withoutSuffix, string, isFuture) { + var output = this._relativeTime[string]; + return (isFunction(output)) ? + output(number, withoutSuffix, string, isFuture) : + output.replace(/%d/i, number); +} + +function pastFuture (diff, output) { + var format = this._relativeTime[diff > 0 ? 'future' : 'past']; + return isFunction(format) ? format(output) : format.replace(/%s/i, output); +} + +var aliases = {}; + +function addUnitAlias (unit, shorthand) { + var lowerCase = unit.toLowerCase(); + aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit; +} + +function normalizeUnits(units) { + return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined; +} + +function normalizeObjectUnits(inputObject) { + var normalizedInput = {}, + normalizedProp, + prop; + + for (prop in inputObject) { + if (hasOwnProp(inputObject, prop)) { + normalizedProp = normalizeUnits(prop); + if (normalizedProp) { + normalizedInput[normalizedProp] = inputObject[prop]; + } + } + } + + return normalizedInput; +} + +var priorities = {}; + +function addUnitPriority(unit, priority) { + priorities[unit] = priority; +} + +function getPrioritizedUnits(unitsObj) { + var units = []; + for (var u in unitsObj) { + units.push({unit: u, priority: priorities[u]}); + } + units.sort(function (a, b) { + return a.priority - b.priority; + }); + return units; +} + +function zeroFill(number, targetLength, forceSign) { + var absNumber = '' + Math.abs(number), + zerosToFill = targetLength - absNumber.length, + sign = number >= 0; + return (sign ? (forceSign ? '+' : '') : '-') + + Math.pow(10, Math.max(0, zerosToFill)).toString().substr(1) + absNumber; +} + +var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g; + +var localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g; + +var formatFunctions = {}; + +var formatTokenFunctions = {}; + +// token: 'M' +// padded: ['MM', 2] +// ordinal: 'Mo' +// callback: function () { this.month() + 1 } +function addFormatToken (token, padded, ordinal, callback) { + var func = callback; + if (typeof callback === 'string') { + func = function () { + return this[callback](); + }; + } + if (token) { + formatTokenFunctions[token] = func; + } + if (padded) { + formatTokenFunctions[padded[0]] = function () { + return zeroFill(func.apply(this, arguments), padded[1], padded[2]); + }; + } + if (ordinal) { + formatTokenFunctions[ordinal] = function () { + return this.localeData().ordinal(func.apply(this, arguments), token); + }; + } +} + +function removeFormattingTokens(input) { + if (input.match(/\[[\s\S]/)) { + return input.replace(/^\[|\]$/g, ''); + } + return input.replace(/\\/g, ''); +} + +function makeFormatFunction(format) { + var array = format.match(formattingTokens), i, length; + + for (i = 0, length = array.length; i < length; i++) { + if (formatTokenFunctions[array[i]]) { + array[i] = formatTokenFunctions[array[i]]; + } else { + array[i] = removeFormattingTokens(array[i]); + } + } + + return function (mom) { + var output = '', i; + for (i = 0; i < length; i++) { + output += isFunction(array[i]) ? array[i].call(mom, format) : array[i]; + } + return output; + }; +} + +// format date using native date object +function formatMoment(m, format) { + if (!m.isValid()) { + return m.localeData().invalidDate(); + } + + format = expandFormat(format, m.localeData()); + formatFunctions[format] = formatFunctions[format] || makeFormatFunction(format); + + return formatFunctions[format](m); +} + +function expandFormat(format, locale) { + var i = 5; + + function replaceLongDateFormatTokens(input) { + return locale.longDateFormat(input) || input; + } + + localFormattingTokens.lastIndex = 0; + while (i >= 0 && localFormattingTokens.test(format)) { + format = format.replace(localFormattingTokens, replaceLongDateFormatTokens); + localFormattingTokens.lastIndex = 0; + i -= 1; + } + + return format; +} + +var match1 = /\d/; // 0 - 9 +var match2 = /\d\d/; // 00 - 99 +var match3 = /\d{3}/; // 000 - 999 +var match4 = /\d{4}/; // 0000 - 9999 +var match6 = /[+-]?\d{6}/; // -999999 - 999999 +var match1to2 = /\d\d?/; // 0 - 99 +var match3to4 = /\d\d\d\d?/; // 999 - 9999 +var match5to6 = /\d\d\d\d\d\d?/; // 99999 - 999999 +var match1to3 = /\d{1,3}/; // 0 - 999 +var match1to4 = /\d{1,4}/; // 0 - 9999 +var match1to6 = /[+-]?\d{1,6}/; // -999999 - 999999 + +var matchUnsigned = /\d+/; // 0 - inf +var matchSigned = /[+-]?\d+/; // -inf - inf + +var matchOffset = /Z|[+-]\d\d:?\d\d/gi; // +00:00 -00:00 +0000 -0000 or Z +var matchShortOffset = /Z|[+-]\d\d(?::?\d\d)?/gi; // +00 -00 +00:00 -00:00 +0000 -0000 or Z + +var matchTimestamp = /[+-]?\d+(\.\d{1,3})?/; // 12.4.8789 123456789.123 + +// any word (or two) characters or numbers including two/three word month in arabic. +// includes scottish gaelic two word and hyphenated months +var matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i; + + +var regexes = {}; + +function addRegexToken (token, regex, strictRegex) { + regexes[token] = isFunction(regex) ? regex : function (isStrict, localeData) { + return (isStrict && strictRegex) ? strictRegex : regex; + }; +} + +function getParseRegexForToken (token, config) { + if (!hasOwnProp(regexes, token)) { + return new RegExp(unescapeFormat(token)); + } + + return regexes[token](config._strict, config._locale); +} + +// Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript +function unescapeFormat(s) { + return regexEscape(s.replace('\\', '').replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function (matched, p1, p2, p3, p4) { + return p1 || p2 || p3 || p4; + })); +} + +function regexEscape(s) { + return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); +} + +var tokens = {}; + +function addParseToken (token, callback) { + var i, func = callback; + if (typeof token === 'string') { + token = [token]; + } + if (isNumber(callback)) { + func = function (input, array) { + array[callback] = toInt(input); + }; + } + for (i = 0; i < token.length; i++) { + tokens[token[i]] = func; + } +} + +function addWeekParseToken (token, callback) { + addParseToken(token, function (input, array, config, token) { + config._w = config._w || {}; + callback(input, config._w, config, token); + }); +} + +function addTimeToArrayFromToken(token, input, config) { + if (input != null && hasOwnProp(tokens, token)) { + tokens[token](input, config._a, config, token); + } +} + +var YEAR = 0; +var MONTH = 1; +var DATE = 2; +var HOUR = 3; +var MINUTE = 4; +var SECOND = 5; +var MILLISECOND = 6; +var WEEK = 7; +var WEEKDAY = 8; + +// FORMATTING + +addFormatToken('Y', 0, 0, function () { + var y = this.year(); + return y <= 9999 ? '' + y : '+' + y; +}); + +addFormatToken(0, ['YY', 2], 0, function () { + return this.year() % 100; +}); + +addFormatToken(0, ['YYYY', 4], 0, 'year'); +addFormatToken(0, ['YYYYY', 5], 0, 'year'); +addFormatToken(0, ['YYYYYY', 6, true], 0, 'year'); + +// ALIASES + +addUnitAlias('year', 'y'); + +// PRIORITIES + +addUnitPriority('year', 1); + +// PARSING + +addRegexToken('Y', matchSigned); +addRegexToken('YY', match1to2, match2); +addRegexToken('YYYY', match1to4, match4); +addRegexToken('YYYYY', match1to6, match6); +addRegexToken('YYYYYY', match1to6, match6); + +addParseToken(['YYYYY', 'YYYYYY'], YEAR); +addParseToken('YYYY', function (input, array) { + array[YEAR] = input.length === 2 ? hooks.parseTwoDigitYear(input) : toInt(input); +}); +addParseToken('YY', function (input, array) { + array[YEAR] = hooks.parseTwoDigitYear(input); +}); +addParseToken('Y', function (input, array) { + array[YEAR] = parseInt(input, 10); +}); + +// HELPERS + +function daysInYear(year) { + return isLeapYear(year) ? 366 : 365; +} + +function isLeapYear(year) { + return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; +} + +// HOOKS + +hooks.parseTwoDigitYear = function (input) { + return toInt(input) + (toInt(input) > 68 ? 1900 : 2000); +}; + +// MOMENTS + +var getSetYear = makeGetSet('FullYear', true); + +function getIsLeapYear () { + return isLeapYear(this.year()); +} + +function makeGetSet (unit, keepTime) { + return function (value) { + if (value != null) { + set$1(this, unit, value); + hooks.updateOffset(this, keepTime); + return this; + } else { + return get(this, unit); + } + }; +} + +function get (mom, unit) { + return mom.isValid() ? + mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]() : NaN; +} + +function set$1 (mom, unit, value) { + if (mom.isValid() && !isNaN(value)) { + if (unit === 'FullYear' && isLeapYear(mom.year()) && mom.month() === 1 && mom.date() === 29) { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value, mom.month(), daysInMonth(value, mom.month())); + } + else { + mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value); + } + } +} + +// MOMENTS + +function stringGet (units) { + units = normalizeUnits(units); + if (isFunction(this[units])) { + return this[units](); + } + return this; +} + + +function stringSet (units, value) { + if (typeof units === 'object') { + units = normalizeObjectUnits(units); + var prioritized = getPrioritizedUnits(units); + for (var i = 0; i < prioritized.length; i++) { + this[prioritized[i].unit](units[prioritized[i].unit]); + } + } else { + units = normalizeUnits(units); + if (isFunction(this[units])) { + return this[units](value); + } + } + return this; +} + +function mod(n, x) { + return ((n % x) + x) % x; +} + +var indexOf; + +if (Array.prototype.indexOf) { + indexOf = Array.prototype.indexOf; +} else { + indexOf = function (o) { + // I know + var i; + for (i = 0; i < this.length; ++i) { + if (this[i] === o) { + return i; + } + } + return -1; + }; +} + +function daysInMonth(year, month) { + if (isNaN(year) || isNaN(month)) { + return NaN; + } + var modMonth = mod(month, 12); + year += (month - modMonth) / 12; + return modMonth === 1 ? (isLeapYear(year) ? 29 : 28) : (31 - modMonth % 7 % 2); +} + +// FORMATTING + +addFormatToken('M', ['MM', 2], 'Mo', function () { + return this.month() + 1; +}); + +addFormatToken('MMM', 0, 0, function (format) { + return this.localeData().monthsShort(this, format); +}); + +addFormatToken('MMMM', 0, 0, function (format) { + return this.localeData().months(this, format); +}); + +// ALIASES + +addUnitAlias('month', 'M'); + +// PRIORITY + +addUnitPriority('month', 8); + +// PARSING + +addRegexToken('M', match1to2); +addRegexToken('MM', match1to2, match2); +addRegexToken('MMM', function (isStrict, locale) { + return locale.monthsShortRegex(isStrict); +}); +addRegexToken('MMMM', function (isStrict, locale) { + return locale.monthsRegex(isStrict); +}); + +addParseToken(['M', 'MM'], function (input, array) { + array[MONTH] = toInt(input) - 1; +}); + +addParseToken(['MMM', 'MMMM'], function (input, array, config, token) { + var month = config._locale.monthsParse(input, token, config._strict); + // if we didn't find a month name, mark the date as invalid. + if (month != null) { + array[MONTH] = month; + } else { + getParsingFlags(config).invalidMonth = input; + } +}); + +// LOCALES + +var MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/; +var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'); +function localeMonths (m, format) { + if (!m) { + return isArray(this._months) ? this._months : + this._months['standalone']; + } + return isArray(this._months) ? this._months[m.month()] : + this._months[(this._months.isFormat || MONTHS_IN_FORMAT).test(format) ? 'format' : 'standalone'][m.month()]; +} + +var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'); +function localeMonthsShort (m, format) { + if (!m) { + return isArray(this._monthsShort) ? this._monthsShort : + this._monthsShort['standalone']; + } + return isArray(this._monthsShort) ? this._monthsShort[m.month()] : + this._monthsShort[MONTHS_IN_FORMAT.test(format) ? 'format' : 'standalone'][m.month()]; +} + +function handleStrictParse(monthName, format, strict) { + var i, ii, mom, llc = monthName.toLocaleLowerCase(); + if (!this._monthsParse) { + // this is not used + this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; + for (i = 0; i < 12; ++i) { + mom = createUTC([2000, i]); + this._shortMonthsParse[i] = this.monthsShort(mom, '').toLocaleLowerCase(); + this._longMonthsParse[i] = this.months(mom, '').toLocaleLowerCase(); + } + } + + if (strict) { + if (format === 'MMM') { + ii = indexOf.call(this._shortMonthsParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._longMonthsParse, llc); + return ii !== -1 ? ii : null; + } + } else { + if (format === 'MMM') { + ii = indexOf.call(this._shortMonthsParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._longMonthsParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._longMonthsParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortMonthsParse, llc); + return ii !== -1 ? ii : null; + } + } +} + +function localeMonthsParse (monthName, format, strict) { + var i, mom, regex; + + if (this._monthsParseExact) { + return handleStrictParse.call(this, monthName, format, strict); + } + + if (!this._monthsParse) { + this._monthsParse = []; + this._longMonthsParse = []; + this._shortMonthsParse = []; + } + + // TODO: add sorting + // Sorting makes sure if one month (or abbr) is a prefix of another + // see sorting in computeMonthsParse + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, i]); + if (strict && !this._longMonthsParse[i]) { + this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i'); + this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i'); + } + if (!strict && !this._monthsParse[i]) { + regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, ''); + this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) { + return i; + } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) { + return i; + } else if (!strict && this._monthsParse[i].test(monthName)) { + return i; + } + } +} + +// MOMENTS + +function setMonth (mom, value) { + var dayOfMonth; + + if (!mom.isValid()) { + // No op + return mom; + } + + if (typeof value === 'string') { + if (/^\d+$/.test(value)) { + value = toInt(value); + } else { + value = mom.localeData().monthsParse(value); + // TODO: Another silent failure? + if (!isNumber(value)) { + return mom; + } + } + } + + dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value)); + mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth); + return mom; +} + +function getSetMonth (value) { + if (value != null) { + setMonth(this, value); + hooks.updateOffset(this, true); + return this; + } else { + return get(this, 'Month'); + } +} + +function getDaysInMonth () { + return daysInMonth(this.year(), this.month()); +} + +var defaultMonthsShortRegex = matchWord; +function monthsShortRegex (isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + if (isStrict) { + return this._monthsShortStrictRegex; + } else { + return this._monthsShortRegex; + } + } else { + if (!hasOwnProp(this, '_monthsShortRegex')) { + this._monthsShortRegex = defaultMonthsShortRegex; + } + return this._monthsShortStrictRegex && isStrict ? + this._monthsShortStrictRegex : this._monthsShortRegex; + } +} + +var defaultMonthsRegex = matchWord; +function monthsRegex (isStrict) { + if (this._monthsParseExact) { + if (!hasOwnProp(this, '_monthsRegex')) { + computeMonthsParse.call(this); + } + if (isStrict) { + return this._monthsStrictRegex; + } else { + return this._monthsRegex; + } + } else { + if (!hasOwnProp(this, '_monthsRegex')) { + this._monthsRegex = defaultMonthsRegex; + } + return this._monthsStrictRegex && isStrict ? + this._monthsStrictRegex : this._monthsRegex; + } +} + +function computeMonthsParse () { + function cmpLenRev(a, b) { + return b.length - a.length; + } + + var shortPieces = [], longPieces = [], mixedPieces = [], + i, mom; + for (i = 0; i < 12; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, i]); + shortPieces.push(this.monthsShort(mom, '')); + longPieces.push(this.months(mom, '')); + mixedPieces.push(this.months(mom, '')); + mixedPieces.push(this.monthsShort(mom, '')); + } + // Sorting makes sure if one month (or abbr) is a prefix of another it + // will match the longer piece. + shortPieces.sort(cmpLenRev); + longPieces.sort(cmpLenRev); + mixedPieces.sort(cmpLenRev); + for (i = 0; i < 12; i++) { + shortPieces[i] = regexEscape(shortPieces[i]); + longPieces[i] = regexEscape(longPieces[i]); + } + for (i = 0; i < 24; i++) { + mixedPieces[i] = regexEscape(mixedPieces[i]); + } + + this._monthsRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._monthsShortRegex = this._monthsRegex; + this._monthsStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); + this._monthsShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); +} + +function createDate (y, m, d, h, M, s, ms) { + // can't just apply() to create a date: + // https://stackoverflow.com/q/181348 + var date = new Date(y, m, d, h, M, s, ms); + + // the date constructor remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0 && isFinite(date.getFullYear())) { + date.setFullYear(y); + } + return date; +} + +function createUTCDate (y) { + var date = new Date(Date.UTC.apply(null, arguments)); + + // the Date.UTC function remaps years 0-99 to 1900-1999 + if (y < 100 && y >= 0 && isFinite(date.getUTCFullYear())) { + date.setUTCFullYear(y); + } + return date; +} + +// start-of-first-week - start-of-year +function firstWeekOffset(year, dow, doy) { + var // first-week day -- which january is always in the first week (4 for iso, 1 for other) + fwd = 7 + dow - doy, + // first-week day local weekday -- which local weekday is fwd + fwdlw = (7 + createUTCDate(year, 0, fwd).getUTCDay() - dow) % 7; + + return -fwdlw + fwd - 1; +} + +// https://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday +function dayOfYearFromWeeks(year, week, weekday, dow, doy) { + var localWeekday = (7 + weekday - dow) % 7, + weekOffset = firstWeekOffset(year, dow, doy), + dayOfYear = 1 + 7 * (week - 1) + localWeekday + weekOffset, + resYear, resDayOfYear; + + if (dayOfYear <= 0) { + resYear = year - 1; + resDayOfYear = daysInYear(resYear) + dayOfYear; + } else if (dayOfYear > daysInYear(year)) { + resYear = year + 1; + resDayOfYear = dayOfYear - daysInYear(year); + } else { + resYear = year; + resDayOfYear = dayOfYear; + } + + return { + year: resYear, + dayOfYear: resDayOfYear + }; +} + +function weekOfYear(mom, dow, doy) { + var weekOffset = firstWeekOffset(mom.year(), dow, doy), + week = Math.floor((mom.dayOfYear() - weekOffset - 1) / 7) + 1, + resWeek, resYear; + + if (week < 1) { + resYear = mom.year() - 1; + resWeek = week + weeksInYear(resYear, dow, doy); + } else if (week > weeksInYear(mom.year(), dow, doy)) { + resWeek = week - weeksInYear(mom.year(), dow, doy); + resYear = mom.year() + 1; + } else { + resYear = mom.year(); + resWeek = week; + } + + return { + week: resWeek, + year: resYear + }; +} + +function weeksInYear(year, dow, doy) { + var weekOffset = firstWeekOffset(year, dow, doy), + weekOffsetNext = firstWeekOffset(year + 1, dow, doy); + return (daysInYear(year) - weekOffset + weekOffsetNext) / 7; +} + +// FORMATTING + +addFormatToken('w', ['ww', 2], 'wo', 'week'); +addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek'); + +// ALIASES + +addUnitAlias('week', 'w'); +addUnitAlias('isoWeek', 'W'); + +// PRIORITIES + +addUnitPriority('week', 5); +addUnitPriority('isoWeek', 5); + +// PARSING + +addRegexToken('w', match1to2); +addRegexToken('ww', match1to2, match2); +addRegexToken('W', match1to2); +addRegexToken('WW', match1to2, match2); + +addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) { + week[token.substr(0, 1)] = toInt(input); +}); + +// HELPERS + +// LOCALES + +function localeWeek (mom) { + return weekOfYear(mom, this._week.dow, this._week.doy).week; +} + +var defaultLocaleWeek = { + dow : 0, // Sunday is the first day of the week. + doy : 6 // The week that contains Jan 1st is the first week of the year. +}; + +function localeFirstDayOfWeek () { + return this._week.dow; +} + +function localeFirstDayOfYear () { + return this._week.doy; +} + +// MOMENTS + +function getSetWeek (input) { + var week = this.localeData().week(this); + return input == null ? week : this.add((input - week) * 7, 'd'); +} + +function getSetISOWeek (input) { + var week = weekOfYear(this, 1, 4).week; + return input == null ? week : this.add((input - week) * 7, 'd'); +} + +// FORMATTING + +addFormatToken('d', 0, 'do', 'day'); + +addFormatToken('dd', 0, 0, function (format) { + return this.localeData().weekdaysMin(this, format); +}); + +addFormatToken('ddd', 0, 0, function (format) { + return this.localeData().weekdaysShort(this, format); +}); + +addFormatToken('dddd', 0, 0, function (format) { + return this.localeData().weekdays(this, format); +}); + +addFormatToken('e', 0, 0, 'weekday'); +addFormatToken('E', 0, 0, 'isoWeekday'); + +// ALIASES + +addUnitAlias('day', 'd'); +addUnitAlias('weekday', 'e'); +addUnitAlias('isoWeekday', 'E'); + +// PRIORITY +addUnitPriority('day', 11); +addUnitPriority('weekday', 11); +addUnitPriority('isoWeekday', 11); + +// PARSING + +addRegexToken('d', match1to2); +addRegexToken('e', match1to2); +addRegexToken('E', match1to2); +addRegexToken('dd', function (isStrict, locale) { + return locale.weekdaysMinRegex(isStrict); +}); +addRegexToken('ddd', function (isStrict, locale) { + return locale.weekdaysShortRegex(isStrict); +}); +addRegexToken('dddd', function (isStrict, locale) { + return locale.weekdaysRegex(isStrict); +}); + +addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config, token) { + var weekday = config._locale.weekdaysParse(input, token, config._strict); + // if we didn't get a weekday name, mark the date as invalid + if (weekday != null) { + week.d = weekday; + } else { + getParsingFlags(config).invalidWeekday = input; + } +}); + +addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) { + week[token] = toInt(input); +}); + +// HELPERS + +function parseWeekday(input, locale) { + if (typeof input !== 'string') { + return input; + } + + if (!isNaN(input)) { + return parseInt(input, 10); + } + + input = locale.weekdaysParse(input); + if (typeof input === 'number') { + return input; + } + + return null; +} + +function parseIsoWeekday(input, locale) { + if (typeof input === 'string') { + return locale.weekdaysParse(input) % 7 || 7; + } + return isNaN(input) ? null : input; +} + +// LOCALES + +var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'); +function localeWeekdays (m, format) { + if (!m) { + return isArray(this._weekdays) ? this._weekdays : + this._weekdays['standalone']; + } + return isArray(this._weekdays) ? this._weekdays[m.day()] : + this._weekdays[this._weekdays.isFormat.test(format) ? 'format' : 'standalone'][m.day()]; +} + +var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'); +function localeWeekdaysShort (m) { + return (m) ? this._weekdaysShort[m.day()] : this._weekdaysShort; +} + +var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'); +function localeWeekdaysMin (m) { + return (m) ? this._weekdaysMin[m.day()] : this._weekdaysMin; +} + +function handleStrictParse$1(weekdayName, format, strict) { + var i, ii, mom, llc = weekdayName.toLocaleLowerCase(); + if (!this._weekdaysParse) { + this._weekdaysParse = []; + this._shortWeekdaysParse = []; + this._minWeekdaysParse = []; + + for (i = 0; i < 7; ++i) { + mom = createUTC([2000, 1]).day(i); + this._minWeekdaysParse[i] = this.weekdaysMin(mom, '').toLocaleLowerCase(); + this._shortWeekdaysParse[i] = this.weekdaysShort(mom, '').toLocaleLowerCase(); + this._weekdaysParse[i] = this.weekdays(mom, '').toLocaleLowerCase(); + } + } + + if (strict) { + if (format === 'dddd') { + ii = indexOf.call(this._weekdaysParse, llc); + return ii !== -1 ? ii : null; + } else if (format === 'ddd') { + ii = indexOf.call(this._shortWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } + } else { + if (format === 'dddd') { + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else if (format === 'ddd') { + ii = indexOf.call(this._shortWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._minWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } else { + ii = indexOf.call(this._minWeekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._weekdaysParse, llc); + if (ii !== -1) { + return ii; + } + ii = indexOf.call(this._shortWeekdaysParse, llc); + return ii !== -1 ? ii : null; + } + } +} + +function localeWeekdaysParse (weekdayName, format, strict) { + var i, mom, regex; + + if (this._weekdaysParseExact) { + return handleStrictParse$1.call(this, weekdayName, format, strict); + } + + if (!this._weekdaysParse) { + this._weekdaysParse = []; + this._minWeekdaysParse = []; + this._shortWeekdaysParse = []; + this._fullWeekdaysParse = []; + } + + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already + + mom = createUTC([2000, 1]).day(i); + if (strict && !this._fullWeekdaysParse[i]) { + this._fullWeekdaysParse[i] = new RegExp('^' + this.weekdays(mom, '').replace('.', '\.?') + '$', 'i'); + this._shortWeekdaysParse[i] = new RegExp('^' + this.weekdaysShort(mom, '').replace('.', '\.?') + '$', 'i'); + this._minWeekdaysParse[i] = new RegExp('^' + this.weekdaysMin(mom, '').replace('.', '\.?') + '$', 'i'); + } + if (!this._weekdaysParse[i]) { + regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, ''); + this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i'); + } + // test the regex + if (strict && format === 'dddd' && this._fullWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (strict && format === 'ddd' && this._shortWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (strict && format === 'dd' && this._minWeekdaysParse[i].test(weekdayName)) { + return i; + } else if (!strict && this._weekdaysParse[i].test(weekdayName)) { + return i; + } + } +} + +// MOMENTS + +function getSetDayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay(); + if (input != null) { + input = parseWeekday(input, this.localeData()); + return this.add(input - day, 'd'); + } else { + return day; + } +} + +function getSetLocaleDayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7; + return input == null ? weekday : this.add(input - weekday, 'd'); +} + +function getSetISODayOfWeek (input) { + if (!this.isValid()) { + return input != null ? this : NaN; + } + + // behaves the same as moment#day except + // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6) + // as a setter, sunday should belong to the previous week. + + if (input != null) { + var weekday = parseIsoWeekday(input, this.localeData()); + return this.day(this.day() % 7 ? weekday : weekday - 7); + } else { + return this.day() || 7; + } +} + +var defaultWeekdaysRegex = matchWord; +function weekdaysRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysStrictRegex; + } else { + return this._weekdaysRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysRegex')) { + this._weekdaysRegex = defaultWeekdaysRegex; + } + return this._weekdaysStrictRegex && isStrict ? + this._weekdaysStrictRegex : this._weekdaysRegex; + } +} + +var defaultWeekdaysShortRegex = matchWord; +function weekdaysShortRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysShortStrictRegex; + } else { + return this._weekdaysShortRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysShortRegex')) { + this._weekdaysShortRegex = defaultWeekdaysShortRegex; + } + return this._weekdaysShortStrictRegex && isStrict ? + this._weekdaysShortStrictRegex : this._weekdaysShortRegex; + } +} + +var defaultWeekdaysMinRegex = matchWord; +function weekdaysMinRegex (isStrict) { + if (this._weekdaysParseExact) { + if (!hasOwnProp(this, '_weekdaysRegex')) { + computeWeekdaysParse.call(this); + } + if (isStrict) { + return this._weekdaysMinStrictRegex; + } else { + return this._weekdaysMinRegex; + } + } else { + if (!hasOwnProp(this, '_weekdaysMinRegex')) { + this._weekdaysMinRegex = defaultWeekdaysMinRegex; + } + return this._weekdaysMinStrictRegex && isStrict ? + this._weekdaysMinStrictRegex : this._weekdaysMinRegex; + } +} + + +function computeWeekdaysParse () { + function cmpLenRev(a, b) { + return b.length - a.length; + } + + var minPieces = [], shortPieces = [], longPieces = [], mixedPieces = [], + i, mom, minp, shortp, longp; + for (i = 0; i < 7; i++) { + // make the regex if we don't have it already + mom = createUTC([2000, 1]).day(i); + minp = this.weekdaysMin(mom, ''); + shortp = this.weekdaysShort(mom, ''); + longp = this.weekdays(mom, ''); + minPieces.push(minp); + shortPieces.push(shortp); + longPieces.push(longp); + mixedPieces.push(minp); + mixedPieces.push(shortp); + mixedPieces.push(longp); + } + // Sorting makes sure if one weekday (or abbr) is a prefix of another it + // will match the longer piece. + minPieces.sort(cmpLenRev); + shortPieces.sort(cmpLenRev); + longPieces.sort(cmpLenRev); + mixedPieces.sort(cmpLenRev); + for (i = 0; i < 7; i++) { + shortPieces[i] = regexEscape(shortPieces[i]); + longPieces[i] = regexEscape(longPieces[i]); + mixedPieces[i] = regexEscape(mixedPieces[i]); + } + + this._weekdaysRegex = new RegExp('^(' + mixedPieces.join('|') + ')', 'i'); + this._weekdaysShortRegex = this._weekdaysRegex; + this._weekdaysMinRegex = this._weekdaysRegex; + + this._weekdaysStrictRegex = new RegExp('^(' + longPieces.join('|') + ')', 'i'); + this._weekdaysShortStrictRegex = new RegExp('^(' + shortPieces.join('|') + ')', 'i'); + this._weekdaysMinStrictRegex = new RegExp('^(' + minPieces.join('|') + ')', 'i'); +} + +// FORMATTING + +function hFormat() { + return this.hours() % 12 || 12; +} + +function kFormat() { + return this.hours() || 24; +} + +addFormatToken('H', ['HH', 2], 0, 'hour'); +addFormatToken('h', ['hh', 2], 0, hFormat); +addFormatToken('k', ['kk', 2], 0, kFormat); + +addFormatToken('hmm', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2); +}); + +addFormatToken('hmmss', 0, 0, function () { + return '' + hFormat.apply(this) + zeroFill(this.minutes(), 2) + + zeroFill(this.seconds(), 2); +}); + +addFormatToken('Hmm', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2); +}); + +addFormatToken('Hmmss', 0, 0, function () { + return '' + this.hours() + zeroFill(this.minutes(), 2) + + zeroFill(this.seconds(), 2); +}); + +function meridiem (token, lowercase) { + addFormatToken(token, 0, 0, function () { + return this.localeData().meridiem(this.hours(), this.minutes(), lowercase); + }); +} + +meridiem('a', true); +meridiem('A', false); + +// ALIASES + +addUnitAlias('hour', 'h'); + +// PRIORITY +addUnitPriority('hour', 13); + +// PARSING + +function matchMeridiem (isStrict, locale) { + return locale._meridiemParse; +} + +addRegexToken('a', matchMeridiem); +addRegexToken('A', matchMeridiem); +addRegexToken('H', match1to2); +addRegexToken('h', match1to2); +addRegexToken('k', match1to2); +addRegexToken('HH', match1to2, match2); +addRegexToken('hh', match1to2, match2); +addRegexToken('kk', match1to2, match2); + +addRegexToken('hmm', match3to4); +addRegexToken('hmmss', match5to6); +addRegexToken('Hmm', match3to4); +addRegexToken('Hmmss', match5to6); + +addParseToken(['H', 'HH'], HOUR); +addParseToken(['k', 'kk'], function (input, array, config) { + var kInput = toInt(input); + array[HOUR] = kInput === 24 ? 0 : kInput; +}); +addParseToken(['a', 'A'], function (input, array, config) { + config._isPm = config._locale.isPM(input); + config._meridiem = input; +}); +addParseToken(['h', 'hh'], function (input, array, config) { + array[HOUR] = toInt(input); + getParsingFlags(config).bigHour = true; +}); +addParseToken('hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); + getParsingFlags(config).bigHour = true; +}); +addParseToken('hmmss', function (input, array, config) { + var pos1 = input.length - 4; + var pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); + getParsingFlags(config).bigHour = true; +}); +addParseToken('Hmm', function (input, array, config) { + var pos = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos)); + array[MINUTE] = toInt(input.substr(pos)); +}); +addParseToken('Hmmss', function (input, array, config) { + var pos1 = input.length - 4; + var pos2 = input.length - 2; + array[HOUR] = toInt(input.substr(0, pos1)); + array[MINUTE] = toInt(input.substr(pos1, 2)); + array[SECOND] = toInt(input.substr(pos2)); +}); + +// LOCALES + +function localeIsPM (input) { + // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays + // Using charAt should be more compatible. + return ((input + '').toLowerCase().charAt(0) === 'p'); +} + +var defaultLocaleMeridiemParse = /[ap]\.?m?\.?/i; +function localeMeridiem (hours, minutes, isLower) { + if (hours > 11) { + return isLower ? 'pm' : 'PM'; + } else { + return isLower ? 'am' : 'AM'; + } +} + + +// MOMENTS + +// Setting the hour should keep the time, because the user explicitly +// specified which hour he wants. So trying to maintain the same hour (in +// a new timezone) makes sense. Adding/subtracting hours does not follow +// this rule. +var getSetHour = makeGetSet('Hours', true); + +// months +// week +// weekdays +// meridiem +var baseConfig = { + calendar: defaultCalendar, + longDateFormat: defaultLongDateFormat, + invalidDate: defaultInvalidDate, + ordinal: defaultOrdinal, + dayOfMonthOrdinalParse: defaultDayOfMonthOrdinalParse, + relativeTime: defaultRelativeTime, + + months: defaultLocaleMonths, + monthsShort: defaultLocaleMonthsShort, + + week: defaultLocaleWeek, + + weekdays: defaultLocaleWeekdays, + weekdaysMin: defaultLocaleWeekdaysMin, + weekdaysShort: defaultLocaleWeekdaysShort, + + meridiemParse: defaultLocaleMeridiemParse +}; + +// internal storage for locale config files +var locales = {}; +var localeFamilies = {}; +var globalLocale; + +function normalizeLocale(key) { + return key ? key.toLowerCase().replace('_', '-') : key; +} + +// pick the locale from the array +// try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each +// substring from most specific to least, but move to the next array item if it's a more specific variant than the current root +function chooseLocale(names) { + var i = 0, j, next, locale, split; + + while (i < names.length) { + split = normalizeLocale(names[i]).split('-'); + j = split.length; + next = normalizeLocale(names[i + 1]); + next = next ? next.split('-') : null; + while (j > 0) { + locale = loadLocale(split.slice(0, j).join('-')); + if (locale) { + return locale; + } + if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) { + //the next array item is better than a shallower substring of this one + break; + } + j--; + } + i++; + } + return null; +} + +function loadLocale(name) { + var oldLocale = null; + // TODO: Find a better way to register and load all the locales in Node + if (!locales[name] && (typeof module !== 'undefined') && + module && module.exports) { + try { + oldLocale = globalLocale._abbr; + var aliasedRequire = require; + aliasedRequire('./locale/' + name); + getSetGlobalLocale(oldLocale); + } catch (e) {} + } + return locales[name]; +} + +// This function will load locale and then set the global locale. If +// no arguments are passed in, it will simply return the current global +// locale key. +function getSetGlobalLocale (key, values) { + var data; + if (key) { + if (isUndefined(values)) { + data = getLocale(key); + } + else { + data = defineLocale(key, values); + } + + if (data) { + // moment.duration._locale = moment._locale = data; + globalLocale = data; + } + } + + return globalLocale._abbr; +} + +function defineLocale (name, config) { + if (config !== null) { + var parentConfig = baseConfig; + config.abbr = name; + if (locales[name] != null) { + deprecateSimple('defineLocaleOverride', + 'use moment.updateLocale(localeName, config) to change ' + + 'an existing locale. moment.defineLocale(localeName, ' + + 'config) should only be used for creating a new locale ' + + 'See http://momentjs.com/guides/#/warnings/define-locale/ for more info.'); + parentConfig = locales[name]._config; + } else if (config.parentLocale != null) { + if (locales[config.parentLocale] != null) { + parentConfig = locales[config.parentLocale]._config; + } else { + if (!localeFamilies[config.parentLocale]) { + localeFamilies[config.parentLocale] = []; + } + localeFamilies[config.parentLocale].push({ + name: name, + config: config + }); + return null; + } + } + locales[name] = new Locale(mergeConfigs(parentConfig, config)); + + if (localeFamilies[name]) { + localeFamilies[name].forEach(function (x) { + defineLocale(x.name, x.config); + }); + } + + // backwards compat for now: also set the locale + // make sure we set the locale AFTER all child locales have been + // created, so we won't end up with the child locale set. + getSetGlobalLocale(name); + + + return locales[name]; + } else { + // useful for testing + delete locales[name]; + return null; + } +} + +function updateLocale(name, config) { + if (config != null) { + var locale, tmpLocale, parentConfig = baseConfig; + // MERGE + tmpLocale = loadLocale(name); + if (tmpLocale != null) { + parentConfig = tmpLocale._config; + } + config = mergeConfigs(parentConfig, config); + locale = new Locale(config); + locale.parentLocale = locales[name]; + locales[name] = locale; + + // backwards compat for now: also set the locale + getSetGlobalLocale(name); + } else { + // pass null for config to unupdate, useful for tests + if (locales[name] != null) { + if (locales[name].parentLocale != null) { + locales[name] = locales[name].parentLocale; + } else if (locales[name] != null) { + delete locales[name]; + } + } + } + return locales[name]; +} + +// returns locale data +function getLocale (key) { + var locale; + + if (key && key._locale && key._locale._abbr) { + key = key._locale._abbr; + } + + if (!key) { + return globalLocale; + } + + if (!isArray(key)) { + //short-circuit everything else + locale = loadLocale(key); + if (locale) { + return locale; + } + key = [key]; + } + + return chooseLocale(key); +} + +function listLocales() { + return keys(locales); +} + +function checkOverflow (m) { + var overflow; + var a = m._a; + + if (a && getParsingFlags(m).overflow === -2) { + overflow = + a[MONTH] < 0 || a[MONTH] > 11 ? MONTH : + a[DATE] < 1 || a[DATE] > daysInMonth(a[YEAR], a[MONTH]) ? DATE : + a[HOUR] < 0 || a[HOUR] > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR : + a[MINUTE] < 0 || a[MINUTE] > 59 ? MINUTE : + a[SECOND] < 0 || a[SECOND] > 59 ? SECOND : + a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND : + -1; + + if (getParsingFlags(m)._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) { + overflow = DATE; + } + if (getParsingFlags(m)._overflowWeeks && overflow === -1) { + overflow = WEEK; + } + if (getParsingFlags(m)._overflowWeekday && overflow === -1) { + overflow = WEEKDAY; + } + + getParsingFlags(m).overflow = overflow; + } + + return m; +} + +// Pick the first defined of two or three arguments. +function defaults(a, b, c) { + if (a != null) { + return a; + } + if (b != null) { + return b; + } + return c; +} + +function currentDateArray(config) { + // hooks is actually the exported moment object + var nowValue = new Date(hooks.now()); + if (config._useUTC) { + return [nowValue.getUTCFullYear(), nowValue.getUTCMonth(), nowValue.getUTCDate()]; + } + return [nowValue.getFullYear(), nowValue.getMonth(), nowValue.getDate()]; +} + +// convert an array to a date. +// the array should mirror the parameters below +// note: all values past the year are optional and will default to the lowest possible value. +// [year, month, day , hour, minute, second, millisecond] +function configFromArray (config) { + var i, date, input = [], currentDate, expectedWeekday, yearToUse; + + if (config._d) { + return; + } + + currentDate = currentDateArray(config); + + //compute day of the year from weeks and weekdays + if (config._w && config._a[DATE] == null && config._a[MONTH] == null) { + dayOfYearFromWeekInfo(config); + } + + //if the day of the year is set, figure out what it is + if (config._dayOfYear != null) { + yearToUse = defaults(config._a[YEAR], currentDate[YEAR]); + + if (config._dayOfYear > daysInYear(yearToUse) || config._dayOfYear === 0) { + getParsingFlags(config)._overflowDayOfYear = true; + } + + date = createUTCDate(yearToUse, 0, config._dayOfYear); + config._a[MONTH] = date.getUTCMonth(); + config._a[DATE] = date.getUTCDate(); + } + + // Default to current date. + // * if no year, month, day of month are given, default to today + // * if day of month is given, default month and year + // * if month is given, default only year + // * if year is given, don't default anything + for (i = 0; i < 3 && config._a[i] == null; ++i) { + config._a[i] = input[i] = currentDate[i]; + } + + // Zero out whatever was not defaulted, including time + for (; i < 7; i++) { + config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i]; + } + + // Check for 24:00:00.000 + if (config._a[HOUR] === 24 && + config._a[MINUTE] === 0 && + config._a[SECOND] === 0 && + config._a[MILLISECOND] === 0) { + config._nextDay = true; + config._a[HOUR] = 0; + } + + config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input); + expectedWeekday = config._useUTC ? config._d.getUTCDay() : config._d.getDay(); + + // Apply timezone offset from input. The actual utcOffset can be changed + // with parseZone. + if (config._tzm != null) { + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + } + + if (config._nextDay) { + config._a[HOUR] = 24; + } + + // check for mismatching day of week + if (config._w && typeof config._w.d !== 'undefined' && config._w.d !== expectedWeekday) { + getParsingFlags(config).weekdayMismatch = true; + } +} + +function dayOfYearFromWeekInfo(config) { + var w, weekYear, week, weekday, dow, doy, temp, weekdayOverflow; + + w = config._w; + if (w.GG != null || w.W != null || w.E != null) { + dow = 1; + doy = 4; + + // TODO: We need to take the current isoWeekYear, but that depends on + // how we interpret now (local, utc, fixed offset). So create + // a now version of current config (take local/utc/offset flags, and + // create now). + weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year); + week = defaults(w.W, 1); + weekday = defaults(w.E, 1); + if (weekday < 1 || weekday > 7) { + weekdayOverflow = true; + } + } else { + dow = config._locale._week.dow; + doy = config._locale._week.doy; + + var curWeek = weekOfYear(createLocal(), dow, doy); + + weekYear = defaults(w.gg, config._a[YEAR], curWeek.year); + + // Default to current week. + week = defaults(w.w, curWeek.week); + + if (w.d != null) { + // weekday -- low day numbers are considered next week + weekday = w.d; + if (weekday < 0 || weekday > 6) { + weekdayOverflow = true; + } + } else if (w.e != null) { + // local weekday -- counting starts from begining of week + weekday = w.e + dow; + if (w.e < 0 || w.e > 6) { + weekdayOverflow = true; + } + } else { + // default to begining of week + weekday = dow; + } + } + if (week < 1 || week > weeksInYear(weekYear, dow, doy)) { + getParsingFlags(config)._overflowWeeks = true; + } else if (weekdayOverflow != null) { + getParsingFlags(config)._overflowWeekday = true; + } else { + temp = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy); + config._a[YEAR] = temp.year; + config._dayOfYear = temp.dayOfYear; + } +} + +// iso 8601 regex +// 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) +var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; +var basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?$/; + +var tzRegex = /Z|[+-]\d\d(?::?\d\d)?/; + +var isoDates = [ + ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], + ['YYYY-MM-DD', /\d{4}-\d\d-\d\d/], + ['GGGG-[W]WW-E', /\d{4}-W\d\d-\d/], + ['GGGG-[W]WW', /\d{4}-W\d\d/, false], + ['YYYY-DDD', /\d{4}-\d{3}/], + ['YYYY-MM', /\d{4}-\d\d/, false], + ['YYYYYYMMDD', /[+-]\d{10}/], + ['YYYYMMDD', /\d{8}/], + // YYYYMM is NOT allowed by the standard + ['GGGG[W]WWE', /\d{4}W\d{3}/], + ['GGGG[W]WW', /\d{4}W\d{2}/, false], + ['YYYYDDD', /\d{7}/] +]; + +// iso time formats and regexes +var isoTimes = [ + ['HH:mm:ss.SSSS', /\d\d:\d\d:\d\d\.\d+/], + ['HH:mm:ss,SSSS', /\d\d:\d\d:\d\d,\d+/], + ['HH:mm:ss', /\d\d:\d\d:\d\d/], + ['HH:mm', /\d\d:\d\d/], + ['HHmmss.SSSS', /\d\d\d\d\d\d\.\d+/], + ['HHmmss,SSSS', /\d\d\d\d\d\d,\d+/], + ['HHmmss', /\d\d\d\d\d\d/], + ['HHmm', /\d\d\d\d/], + ['HH', /\d\d/] +]; + +var aspNetJsonRegex = /^\/?Date\((\-?\d+)/i; + +// date from iso format +function configFromISO(config) { + var i, l, + string = config._i, + match = extendedIsoRegex.exec(string) || basicIsoRegex.exec(string), + allowTime, dateFormat, timeFormat, tzFormat; + + if (match) { + getParsingFlags(config).iso = true; + + for (i = 0, l = isoDates.length; i < l; i++) { + if (isoDates[i][1].exec(match[1])) { + dateFormat = isoDates[i][0]; + allowTime = isoDates[i][2] !== false; + break; + } + } + if (dateFormat == null) { + config._isValid = false; + return; + } + if (match[3]) { + for (i = 0, l = isoTimes.length; i < l; i++) { + if (isoTimes[i][1].exec(match[3])) { + // match[2] should be 'T' or space + timeFormat = (match[2] || ' ') + isoTimes[i][0]; + break; + } + } + if (timeFormat == null) { + config._isValid = false; + return; + } + } + if (!allowTime && timeFormat != null) { + config._isValid = false; + return; + } + if (match[4]) { + if (tzRegex.exec(match[4])) { + tzFormat = 'Z'; + } else { + config._isValid = false; + return; + } + } + config._f = dateFormat + (timeFormat || '') + (tzFormat || ''); + configFromStringAndFormat(config); + } else { + config._isValid = false; + } +} + +// RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 +var rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/; + +function extractFromRFC2822Strings(yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) { + var result = [ + untruncateYear(yearStr), + defaultLocaleMonthsShort.indexOf(monthStr), + parseInt(dayStr, 10), + parseInt(hourStr, 10), + parseInt(minuteStr, 10) + ]; + + if (secondStr) { + result.push(parseInt(secondStr, 10)); + } + + return result; +} + +function untruncateYear(yearStr) { + var year = parseInt(yearStr, 10); + if (year <= 49) { + return 2000 + year; + } else if (year <= 999) { + return 1900 + year; + } + return year; +} + +function preprocessRFC2822(s) { + // Remove comments and folding whitespace and replace multiple-spaces with a single space + return s.replace(/\([^)]*\)|[\n\t]/g, ' ').replace(/(\s\s+)/g, ' ').trim(); +} + +function checkWeekday(weekdayStr, parsedInput, config) { + if (weekdayStr) { + // TODO: Replace the vanilla JS Date object with an indepentent day-of-week check. + var weekdayProvided = defaultLocaleWeekdaysShort.indexOf(weekdayStr), + weekdayActual = new Date(parsedInput[0], parsedInput[1], parsedInput[2]).getDay(); + if (weekdayProvided !== weekdayActual) { + getParsingFlags(config).weekdayMismatch = true; + config._isValid = false; + return false; + } + } + return true; +} + +var obsOffsets = { + UT: 0, + GMT: 0, + EDT: -4 * 60, + EST: -5 * 60, + CDT: -5 * 60, + CST: -6 * 60, + MDT: -6 * 60, + MST: -7 * 60, + PDT: -7 * 60, + PST: -8 * 60 +}; + +function calculateOffset(obsOffset, militaryOffset, numOffset) { + if (obsOffset) { + return obsOffsets[obsOffset]; + } else if (militaryOffset) { + // the only allowed military tz is Z + return 0; + } else { + var hm = parseInt(numOffset, 10); + var m = hm % 100, h = (hm - m) / 100; + return h * 60 + m; + } +} + +// date and time from ref 2822 format +function configFromRFC2822(config) { + var match = rfc2822.exec(preprocessRFC2822(config._i)); + if (match) { + var parsedArray = extractFromRFC2822Strings(match[4], match[3], match[2], match[5], match[6], match[7]); + if (!checkWeekday(match[1], parsedArray, config)) { + return; + } + + config._a = parsedArray; + config._tzm = calculateOffset(match[8], match[9], match[10]); + + config._d = createUTCDate.apply(null, config._a); + config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm); + + getParsingFlags(config).rfc2822 = true; + } else { + config._isValid = false; + } +} + +// date from iso format or fallback +function configFromString(config) { + var matched = aspNetJsonRegex.exec(config._i); + + if (matched !== null) { + config._d = new Date(+matched[1]); + return; + } + + configFromISO(config); + if (config._isValid === false) { + delete config._isValid; + } else { + return; + } + + configFromRFC2822(config); + if (config._isValid === false) { + delete config._isValid; + } else { + return; + } + + // Final attempt, use Input Fallback + hooks.createFromInputFallback(config); +} + +hooks.createFromInputFallback = deprecate( + 'value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), ' + + 'which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are ' + + 'discouraged and will be removed in an upcoming major release. Please refer to ' + + 'http://momentjs.com/guides/#/warnings/js-date/ for more info.', + function (config) { + config._d = new Date(config._i + (config._useUTC ? ' UTC' : '')); + } +); + +// constant that refers to the ISO standard +hooks.ISO_8601 = function () {}; + +// constant that refers to the RFC 2822 form +hooks.RFC_2822 = function () {}; + +// date from string and format string +function configFromStringAndFormat(config) { + // TODO: Move this to another part of the creation flow to prevent circular deps + if (config._f === hooks.ISO_8601) { + configFromISO(config); + return; + } + if (config._f === hooks.RFC_2822) { + configFromRFC2822(config); + return; + } + config._a = []; + getParsingFlags(config).empty = true; + + // This array is used to make a Date, either with `new Date` or `Date.UTC` + var string = '' + config._i, + i, parsedInput, tokens, token, skipped, + stringLength = string.length, + totalParsedInputLength = 0; + + tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; + + for (i = 0; i < tokens.length; i++) { + token = tokens[i]; + parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; + // console.log('token', token, 'parsedInput', parsedInput, + // 'regex', getParseRegexForToken(token, config)); + if (parsedInput) { + skipped = string.substr(0, string.indexOf(parsedInput)); + if (skipped.length > 0) { + getParsingFlags(config).unusedInput.push(skipped); + } + string = string.slice(string.indexOf(parsedInput) + parsedInput.length); + totalParsedInputLength += parsedInput.length; + } + // don't parse if it's not a known token + if (formatTokenFunctions[token]) { + if (parsedInput) { + getParsingFlags(config).empty = false; + } + else { + getParsingFlags(config).unusedTokens.push(token); + } + addTimeToArrayFromToken(token, parsedInput, config); + } + else if (config._strict && !parsedInput) { + getParsingFlags(config).unusedTokens.push(token); + } + } + + // add remaining unparsed input length to the string + getParsingFlags(config).charsLeftOver = stringLength - totalParsedInputLength; + if (string.length > 0) { + getParsingFlags(config).unusedInput.push(string); + } + + // clear _12h flag if hour is <= 12 + if (config._a[HOUR] <= 12 && + getParsingFlags(config).bigHour === true && + config._a[HOUR] > 0) { + getParsingFlags(config).bigHour = undefined; + } + + getParsingFlags(config).parsedDateParts = config._a.slice(0); + getParsingFlags(config).meridiem = config._meridiem; + // handle meridiem + config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem); + + configFromArray(config); + checkOverflow(config); +} + + +function meridiemFixWrap (locale, hour, meridiem) { + var isPm; + + if (meridiem == null) { + // nothing to do + return hour; + } + if (locale.meridiemHour != null) { + return locale.meridiemHour(hour, meridiem); + } else if (locale.isPM != null) { + // Fallback + isPm = locale.isPM(meridiem); + if (isPm && hour < 12) { + hour += 12; + } + if (!isPm && hour === 12) { + hour = 0; + } + return hour; + } else { + // this is not supposed to happen + return hour; + } +} + +// date from string and array of format strings +function configFromStringAndArray(config) { + var tempConfig, + bestMoment, + + scoreToBeat, + i, + currentScore; + + if (config._f.length === 0) { + getParsingFlags(config).invalidFormat = true; + config._d = new Date(NaN); + return; + } + + for (i = 0; i < config._f.length; i++) { + currentScore = 0; + tempConfig = copyConfig({}, config); + if (config._useUTC != null) { + tempConfig._useUTC = config._useUTC; + } + tempConfig._f = config._f[i]; + configFromStringAndFormat(tempConfig); + + if (!isValid(tempConfig)) { + continue; + } + + // if there is any input that was not parsed add a penalty for that format + currentScore += getParsingFlags(tempConfig).charsLeftOver; + + //or tokens + currentScore += getParsingFlags(tempConfig).unusedTokens.length * 10; + + getParsingFlags(tempConfig).score = currentScore; + + if (scoreToBeat == null || currentScore < scoreToBeat) { + scoreToBeat = currentScore; + bestMoment = tempConfig; + } + } + + extend(config, bestMoment || tempConfig); +} + +function configFromObject(config) { + if (config._d) { + return; + } + + var i = normalizeObjectUnits(config._i); + config._a = map([i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond], function (obj) { + return obj && parseInt(obj, 10); + }); + + configFromArray(config); +} + +function createFromConfig (config) { + var res = new Moment(checkOverflow(prepareConfig(config))); + if (res._nextDay) { + // Adding is smart enough around DST + res.add(1, 'd'); + res._nextDay = undefined; + } + + return res; +} + +function prepareConfig (config) { + var input = config._i, + format = config._f; + + config._locale = config._locale || getLocale(config._l); + + if (input === null || (format === undefined && input === '')) { + return createInvalid({nullInput: true}); + } + + if (typeof input === 'string') { + config._i = input = config._locale.preparse(input); + } + + if (isMoment(input)) { + return new Moment(checkOverflow(input)); + } else if (isDate(input)) { + config._d = input; + } else if (isArray(format)) { + configFromStringAndArray(config); + } else if (format) { + configFromStringAndFormat(config); + } else { + configFromInput(config); + } + + if (!isValid(config)) { + config._d = null; + } + + return config; +} + +function configFromInput(config) { + var input = config._i; + if (isUndefined(input)) { + config._d = new Date(hooks.now()); + } else if (isDate(input)) { + config._d = new Date(input.valueOf()); + } else if (typeof input === 'string') { + configFromString(config); + } else if (isArray(input)) { + config._a = map(input.slice(0), function (obj) { + return parseInt(obj, 10); + }); + configFromArray(config); + } else if (isObject(input)) { + configFromObject(config); + } else if (isNumber(input)) { + // from milliseconds + config._d = new Date(input); + } else { + hooks.createFromInputFallback(config); + } +} + +function createLocalOrUTC (input, format, locale, strict, isUTC) { + var c = {}; + + if (locale === true || locale === false) { + strict = locale; + locale = undefined; + } + + if ((isObject(input) && isObjectEmpty(input)) || + (isArray(input) && input.length === 0)) { + input = undefined; + } + // object construction must be done this way. + // https://github.com/moment/moment/issues/1423 + c._isAMomentObject = true; + c._useUTC = c._isUTC = isUTC; + c._l = locale; + c._i = input; + c._f = format; + c._strict = strict; + + return createFromConfig(c); +} + +function createLocal (input, format, locale, strict) { + return createLocalOrUTC(input, format, locale, strict, false); +} + +var prototypeMin = deprecate( + 'moment().min is deprecated, use moment.max instead. http://momentjs.com/guides/#/warnings/min-max/', + function () { + var other = createLocal.apply(null, arguments); + if (this.isValid() && other.isValid()) { + return other < this ? this : other; + } else { + return createInvalid(); + } + } +); + +var prototypeMax = deprecate( + 'moment().max is deprecated, use moment.min instead. http://momentjs.com/guides/#/warnings/min-max/', + function () { + var other = createLocal.apply(null, arguments); + if (this.isValid() && other.isValid()) { + return other > this ? this : other; + } else { + return createInvalid(); + } + } +); + +// Pick a moment m from moments so that m[fn](other) is true for all +// other. This relies on the function fn to be transitive. +// +// moments should either be an array of moment objects or an array, whose +// first element is an array of moment objects. +function pickBy(fn, moments) { + var res, i; + if (moments.length === 1 && isArray(moments[0])) { + moments = moments[0]; + } + if (!moments.length) { + return createLocal(); + } + res = moments[0]; + for (i = 1; i < moments.length; ++i) { + if (!moments[i].isValid() || moments[i][fn](res)) { + res = moments[i]; + } + } + return res; +} + +// TODO: Use [].sort instead? +function min () { + var args = [].slice.call(arguments, 0); + + return pickBy('isBefore', args); +} + +function max () { + var args = [].slice.call(arguments, 0); + + return pickBy('isAfter', args); +} + +var now = function () { + return Date.now ? Date.now() : +(new Date()); +}; + +var ordering = ['year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond']; + +function isDurationValid(m) { + for (var key in m) { + if (!(indexOf.call(ordering, key) !== -1 && (m[key] == null || !isNaN(m[key])))) { + return false; + } + } + + var unitHasDecimal = false; + for (var i = 0; i < ordering.length; ++i) { + if (m[ordering[i]]) { + if (unitHasDecimal) { + return false; // only allow non-integers for smallest unit + } + if (parseFloat(m[ordering[i]]) !== toInt(m[ordering[i]])) { + unitHasDecimal = true; + } + } + } + + return true; +} + +function isValid$1() { + return this._isValid; +} + +function createInvalid$1() { + return createDuration(NaN); +} + +function Duration (duration) { + var normalizedInput = normalizeObjectUnits(duration), + years = normalizedInput.year || 0, + quarters = normalizedInput.quarter || 0, + months = normalizedInput.month || 0, + weeks = normalizedInput.week || 0, + days = normalizedInput.day || 0, + hours = normalizedInput.hour || 0, + minutes = normalizedInput.minute || 0, + seconds = normalizedInput.second || 0, + milliseconds = normalizedInput.millisecond || 0; + + this._isValid = isDurationValid(normalizedInput); + + // representation for dateAddRemove + this._milliseconds = +milliseconds + + seconds * 1e3 + // 1000 + minutes * 6e4 + // 1000 * 60 + hours * 1000 * 60 * 60; //using 1000 * 60 * 60 instead of 36e5 to avoid floating point rounding errors https://github.com/moment/moment/issues/2978 + // Because of dateAddRemove treats 24 hours as different from a + // day when working around DST, we need to store them separately + this._days = +days + + weeks * 7; + // It is impossible to translate months into days without knowing + // which months you are are talking about, so we have to store + // it separately. + this._months = +months + + quarters * 3 + + years * 12; + + this._data = {}; + + this._locale = getLocale(); + + this._bubble(); +} + +function isDuration (obj) { + return obj instanceof Duration; +} + +function absRound (number) { + if (number < 0) { + return Math.round(-1 * number) * -1; + } else { + return Math.round(number); + } +} + +// FORMATTING + +function offset (token, separator) { + addFormatToken(token, 0, 0, function () { + var offset = this.utcOffset(); + var sign = '+'; + if (offset < 0) { + offset = -offset; + sign = '-'; + } + return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2); + }); +} + +offset('Z', ':'); +offset('ZZ', ''); + +// PARSING + +addRegexToken('Z', matchShortOffset); +addRegexToken('ZZ', matchShortOffset); +addParseToken(['Z', 'ZZ'], function (input, array, config) { + config._useUTC = true; + config._tzm = offsetFromString(matchShortOffset, input); +}); + +// HELPERS + +// timezone chunker +// '+10:00' > ['10', '00'] +// '-1530' > ['-15', '30'] +var chunkOffset = /([\+\-]|\d\d)/gi; + +function offsetFromString(matcher, string) { + var matches = (string || '').match(matcher); + + if (matches === null) { + return null; + } + + var chunk = matches[matches.length - 1] || []; + var parts = (chunk + '').match(chunkOffset) || ['-', 0, 0]; + var minutes = +(parts[1] * 60) + toInt(parts[2]); + + return minutes === 0 ? + 0 : + parts[0] === '+' ? minutes : -minutes; +} + +// Return a moment from input, that is local/utc/zone equivalent to model. +function cloneWithOffset(input, model) { + var res, diff; + if (model._isUTC) { + res = model.clone(); + diff = (isMoment(input) || isDate(input) ? input.valueOf() : createLocal(input).valueOf()) - res.valueOf(); + // Use low-level api, because this fn is low-level api. + res._d.setTime(res._d.valueOf() + diff); + hooks.updateOffset(res, false); + return res; + } else { + return createLocal(input).local(); + } +} + +function getDateOffset (m) { + // On Firefox.24 Date#getTimezoneOffset returns a floating point. + // https://github.com/moment/moment/pull/1871 + return -Math.round(m._d.getTimezoneOffset() / 15) * 15; +} + +// HOOKS + +// This function will be called whenever a moment is mutated. +// It is intended to keep the offset in sync with the timezone. +hooks.updateOffset = function () {}; + +// MOMENTS + +// keepLocalTime = true means only change the timezone, without +// affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]--> +// 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset +// +0200, so we adjust the time as needed, to be valid. +// +// Keeping the time actually adds/subtracts (one hour) +// from the actual represented time. That is why we call updateOffset +// a second time. In case it wants us to change the offset again +// _changeInProgress == true case, then we have to adjust, because +// there is no such time in the given timezone. +function getSetOffset (input, keepLocalTime, keepMinutes) { + var offset = this._offset || 0, + localAdjust; + if (!this.isValid()) { + return input != null ? this : NaN; + } + if (input != null) { + if (typeof input === 'string') { + input = offsetFromString(matchShortOffset, input); + if (input === null) { + return this; + } + } else if (Math.abs(input) < 16 && !keepMinutes) { + input = input * 60; + } + if (!this._isUTC && keepLocalTime) { + localAdjust = getDateOffset(this); + } + this._offset = input; + this._isUTC = true; + if (localAdjust != null) { + this.add(localAdjust, 'm'); + } + if (offset !== input) { + if (!keepLocalTime || this._changeInProgress) { + addSubtract(this, createDuration(input - offset, 'm'), 1, false); + } else if (!this._changeInProgress) { + this._changeInProgress = true; + hooks.updateOffset(this, true); + this._changeInProgress = null; + } + } + return this; + } else { + return this._isUTC ? offset : getDateOffset(this); + } +} + +function getSetZone (input, keepLocalTime) { + if (input != null) { + if (typeof input !== 'string') { + input = -input; + } + + this.utcOffset(input, keepLocalTime); + + return this; + } else { + return -this.utcOffset(); + } +} + +function setOffsetToUTC (keepLocalTime) { + return this.utcOffset(0, keepLocalTime); +} + +function setOffsetToLocal (keepLocalTime) { + if (this._isUTC) { + this.utcOffset(0, keepLocalTime); + this._isUTC = false; + + if (keepLocalTime) { + this.subtract(getDateOffset(this), 'm'); + } + } + return this; +} + +function setOffsetToParsedOffset () { + if (this._tzm != null) { + this.utcOffset(this._tzm, false, true); + } else if (typeof this._i === 'string') { + var tZone = offsetFromString(matchOffset, this._i); + if (tZone != null) { + this.utcOffset(tZone); + } + else { + this.utcOffset(0, true); + } + } + return this; +} + +function hasAlignedHourOffset (input) { + if (!this.isValid()) { + return false; + } + input = input ? createLocal(input).utcOffset() : 0; + + return (this.utcOffset() - input) % 60 === 0; +} + +function isDaylightSavingTime () { + return ( + this.utcOffset() > this.clone().month(0).utcOffset() || + this.utcOffset() > this.clone().month(5).utcOffset() + ); +} + +function isDaylightSavingTimeShifted () { + if (!isUndefined(this._isDSTShifted)) { + return this._isDSTShifted; + } + + var c = {}; + + copyConfig(c, this); + c = prepareConfig(c); + + if (c._a) { + var other = c._isUTC ? createUTC(c._a) : createLocal(c._a); + this._isDSTShifted = this.isValid() && + compareArrays(c._a, other.toArray()) > 0; + } else { + this._isDSTShifted = false; + } + + return this._isDSTShifted; +} + +function isLocal () { + return this.isValid() ? !this._isUTC : false; +} + +function isUtcOffset () { + return this.isValid() ? this._isUTC : false; +} + +function isUtc () { + return this.isValid() ? this._isUTC && this._offset === 0 : false; +} + +// ASP.NET json date format regex +var aspNetRegex = /^(\-|\+)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)(\.\d*)?)?$/; + +// from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html +// somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere +// and further modified to allow for strings containing both week and day +var isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; + +function createDuration (input, key) { + var duration = input, + // matching against regexp is expensive, do it on demand + match = null, + sign, + ret, + diffRes; + + if (isDuration(input)) { + duration = { + ms : input._milliseconds, + d : input._days, + M : input._months + }; + } else if (isNumber(input)) { + duration = {}; + if (key) { + duration[key] = input; + } else { + duration.milliseconds = input; + } + } else if (!!(match = aspNetRegex.exec(input))) { + sign = (match[1] === '-') ? -1 : 1; + duration = { + y : 0, + d : toInt(match[DATE]) * sign, + h : toInt(match[HOUR]) * sign, + m : toInt(match[MINUTE]) * sign, + s : toInt(match[SECOND]) * sign, + ms : toInt(absRound(match[MILLISECOND] * 1000)) * sign // the millisecond decimal point is included in the match + }; + } else if (!!(match = isoRegex.exec(input))) { + sign = (match[1] === '-') ? -1 : (match[1] === '+') ? 1 : 1; + duration = { + y : parseIso(match[2], sign), + M : parseIso(match[3], sign), + w : parseIso(match[4], sign), + d : parseIso(match[5], sign), + h : parseIso(match[6], sign), + m : parseIso(match[7], sign), + s : parseIso(match[8], sign) + }; + } else if (duration == null) {// checks for null or undefined + duration = {}; + } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) { + diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to)); + + duration = {}; + duration.ms = diffRes.milliseconds; + duration.M = diffRes.months; + } + + ret = new Duration(duration); + + if (isDuration(input) && hasOwnProp(input, '_locale')) { + ret._locale = input._locale; + } + + return ret; +} + +createDuration.fn = Duration.prototype; +createDuration.invalid = createInvalid$1; + +function parseIso (inp, sign) { + // We'd normally use ~~inp for this, but unfortunately it also + // converts floats to ints. + // inp may be undefined, so careful calling replace on it. + var res = inp && parseFloat(inp.replace(',', '.')); + // apply sign while we're at it + return (isNaN(res) ? 0 : res) * sign; +} + +function positiveMomentsDifference(base, other) { + var res = {milliseconds: 0, months: 0}; + + res.months = other.month() - base.month() + + (other.year() - base.year()) * 12; + if (base.clone().add(res.months, 'M').isAfter(other)) { + --res.months; + } + + res.milliseconds = +other - +(base.clone().add(res.months, 'M')); + + return res; +} + +function momentsDifference(base, other) { + var res; + if (!(base.isValid() && other.isValid())) { + return {milliseconds: 0, months: 0}; + } + + other = cloneWithOffset(other, base); + if (base.isBefore(other)) { + res = positiveMomentsDifference(base, other); + } else { + res = positiveMomentsDifference(other, base); + res.milliseconds = -res.milliseconds; + res.months = -res.months; + } + + return res; +} + +// TODO: remove 'name' arg after deprecation is removed +function createAdder(direction, name) { + return function (val, period) { + var dur, tmp; + //invert the arguments, but complain about it + if (period !== null && !isNaN(+period)) { + deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period). ' + + 'See http://momentjs.com/guides/#/warnings/add-inverted-param/ for more info.'); + tmp = val; val = period; period = tmp; + } + + val = typeof val === 'string' ? +val : val; + dur = createDuration(val, period); + addSubtract(this, dur, direction); + return this; + }; +} + +function addSubtract (mom, duration, isAdding, updateOffset) { + var milliseconds = duration._milliseconds, + days = absRound(duration._days), + months = absRound(duration._months); + + if (!mom.isValid()) { + // No op + return; + } + + updateOffset = updateOffset == null ? true : updateOffset; + + if (months) { + setMonth(mom, get(mom, 'Month') + months * isAdding); + } + if (days) { + set$1(mom, 'Date', get(mom, 'Date') + days * isAdding); + } + if (milliseconds) { + mom._d.setTime(mom._d.valueOf() + milliseconds * isAdding); + } + if (updateOffset) { + hooks.updateOffset(mom, days || months); + } +} + +var add = createAdder(1, 'add'); +var subtract = createAdder(-1, 'subtract'); + +function getCalendarFormat(myMoment, now) { + var diff = myMoment.diff(now, 'days', true); + return diff < -6 ? 'sameElse' : + diff < -1 ? 'lastWeek' : + diff < 0 ? 'lastDay' : + diff < 1 ? 'sameDay' : + diff < 2 ? 'nextDay' : + diff < 7 ? 'nextWeek' : 'sameElse'; +} + +function calendar$1 (time, formats) { + // We want to compare the start of today, vs this. + // Getting start-of-today depends on whether we're local/utc/offset or not. + var now = time || createLocal(), + sod = cloneWithOffset(now, this).startOf('day'), + format = hooks.calendarFormat(this, sod) || 'sameElse'; + + var output = formats && (isFunction(formats[format]) ? formats[format].call(this, now) : formats[format]); + + return this.format(output || this.localeData().calendar(format, this, createLocal(now))); +} + +function clone () { + return new Moment(this); +} + +function isAfter (input, units) { + var localInput = isMoment(input) ? input : createLocal(input); + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(!isUndefined(units) ? units : 'millisecond'); + if (units === 'millisecond') { + return this.valueOf() > localInput.valueOf(); + } else { + return localInput.valueOf() < this.clone().startOf(units).valueOf(); + } +} + +function isBefore (input, units) { + var localInput = isMoment(input) ? input : createLocal(input); + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(!isUndefined(units) ? units : 'millisecond'); + if (units === 'millisecond') { + return this.valueOf() < localInput.valueOf(); + } else { + return this.clone().endOf(units).valueOf() < localInput.valueOf(); + } +} + +function isBetween (from, to, units, inclusivity) { + inclusivity = inclusivity || '()'; + return (inclusivity[0] === '(' ? this.isAfter(from, units) : !this.isBefore(from, units)) && + (inclusivity[1] === ')' ? this.isBefore(to, units) : !this.isAfter(to, units)); +} + +function isSame (input, units) { + var localInput = isMoment(input) ? input : createLocal(input), + inputMs; + if (!(this.isValid() && localInput.isValid())) { + return false; + } + units = normalizeUnits(units || 'millisecond'); + if (units === 'millisecond') { + return this.valueOf() === localInput.valueOf(); + } else { + inputMs = localInput.valueOf(); + return this.clone().startOf(units).valueOf() <= inputMs && inputMs <= this.clone().endOf(units).valueOf(); + } +} + +function isSameOrAfter (input, units) { + return this.isSame(input, units) || this.isAfter(input,units); +} + +function isSameOrBefore (input, units) { + return this.isSame(input, units) || this.isBefore(input,units); +} + +function diff (input, units, asFloat) { + var that, + zoneDelta, + delta, output; + + if (!this.isValid()) { + return NaN; + } + + that = cloneWithOffset(input, this); + + if (!that.isValid()) { + return NaN; + } + + zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4; + + units = normalizeUnits(units); + + switch (units) { + case 'year': output = monthDiff(this, that) / 12; break; + case 'month': output = monthDiff(this, that); break; + case 'quarter': output = monthDiff(this, that) / 3; break; + case 'second': output = (this - that) / 1e3; break; // 1000 + case 'minute': output = (this - that) / 6e4; break; // 1000 * 60 + case 'hour': output = (this - that) / 36e5; break; // 1000 * 60 * 60 + case 'day': output = (this - that - zoneDelta) / 864e5; break; // 1000 * 60 * 60 * 24, negate dst + case 'week': output = (this - that - zoneDelta) / 6048e5; break; // 1000 * 60 * 60 * 24 * 7, negate dst + default: output = this - that; + } + + return asFloat ? output : absFloor(output); +} + +function monthDiff (a, b) { + // difference in months + var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()), + // b is in (anchor - 1 month, anchor + 1 month) + anchor = a.clone().add(wholeMonthDiff, 'months'), + anchor2, adjust; + + if (b - anchor < 0) { + anchor2 = a.clone().add(wholeMonthDiff - 1, 'months'); + // linear across the month + adjust = (b - anchor) / (anchor - anchor2); + } else { + anchor2 = a.clone().add(wholeMonthDiff + 1, 'months'); + // linear across the month + adjust = (b - anchor) / (anchor2 - anchor); + } + + //check for negative zero, return zero if negative zero + return -(wholeMonthDiff + adjust) || 0; +} + +hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ'; +hooks.defaultFormatUtc = 'YYYY-MM-DDTHH:mm:ss[Z]'; + +function toString () { + return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'); +} + +function toISOString(keepOffset) { + if (!this.isValid()) { + return null; + } + var utc = keepOffset !== true; + var m = utc ? this.clone().utc() : this; + if (m.year() < 0 || m.year() > 9999) { + return formatMoment(m, utc ? 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYYYY-MM-DD[T]HH:mm:ss.SSSZ'); + } + if (isFunction(Date.prototype.toISOString)) { + // native implementation is ~50x faster, use it when we can + if (utc) { + return this.toDate().toISOString(); + } else { + return new Date(this._d.valueOf()).toISOString().replace('Z', formatMoment(m, 'Z')); + } + } + return formatMoment(m, utc ? 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]' : 'YYYY-MM-DD[T]HH:mm:ss.SSSZ'); +} + +/** + * Return a human readable representation of a moment that can + * also be evaluated to get a new moment which is the same + * + * @link https://nodejs.org/dist/latest/docs/api/util.html#util_custom_inspect_function_on_objects + */ +function inspect () { + if (!this.isValid()) { + return 'moment.invalid(/* ' + this._i + ' */)'; + } + var func = 'moment'; + var zone = ''; + if (!this.isLocal()) { + func = this.utcOffset() === 0 ? 'moment.utc' : 'moment.parseZone'; + zone = 'Z'; + } + var prefix = '[' + func + '("]'; + var year = (0 <= this.year() && this.year() <= 9999) ? 'YYYY' : 'YYYYYY'; + var datetime = '-MM-DD[T]HH:mm:ss.SSS'; + var suffix = zone + '[")]'; + + return this.format(prefix + year + datetime + suffix); +} + +function format (inputString) { + if (!inputString) { + inputString = this.isUtc() ? hooks.defaultFormatUtc : hooks.defaultFormat; + } + var output = formatMoment(this, inputString); + return this.localeData().postformat(output); +} + +function from (time, withoutSuffix) { + if (this.isValid() && + ((isMoment(time) && time.isValid()) || + createLocal(time).isValid())) { + return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix); + } else { + return this.localeData().invalidDate(); + } +} + +function fromNow (withoutSuffix) { + return this.from(createLocal(), withoutSuffix); +} + +function to (time, withoutSuffix) { + if (this.isValid() && + ((isMoment(time) && time.isValid()) || + createLocal(time).isValid())) { + return createDuration({from: this, to: time}).locale(this.locale()).humanize(!withoutSuffix); + } else { + return this.localeData().invalidDate(); + } +} + +function toNow (withoutSuffix) { + return this.to(createLocal(), withoutSuffix); +} + +// If passed a locale key, it will set the locale for this +// instance. Otherwise, it will return the locale configuration +// variables for this instance. +function locale (key) { + var newLocaleData; + + if (key === undefined) { + return this._locale._abbr; + } else { + newLocaleData = getLocale(key); + if (newLocaleData != null) { + this._locale = newLocaleData; + } + return this; + } +} + +var lang = deprecate( + 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.', + function (key) { + if (key === undefined) { + return this.localeData(); + } else { + return this.locale(key); + } + } +); + +function localeData () { + return this._locale; +} + +function startOf (units) { + units = normalizeUnits(units); + // the following switch intentionally omits break keywords + // to utilize falling through the cases. + switch (units) { + case 'year': + this.month(0); + /* falls through */ + case 'quarter': + case 'month': + this.date(1); + /* falls through */ + case 'week': + case 'isoWeek': + case 'day': + case 'date': + this.hours(0); + /* falls through */ + case 'hour': + this.minutes(0); + /* falls through */ + case 'minute': + this.seconds(0); + /* falls through */ + case 'second': + this.milliseconds(0); + } + + // weeks are a special case + if (units === 'week') { + this.weekday(0); + } + if (units === 'isoWeek') { + this.isoWeekday(1); + } + + // quarters are also special + if (units === 'quarter') { + this.month(Math.floor(this.month() / 3) * 3); + } + + return this; +} + +function endOf (units) { + units = normalizeUnits(units); + if (units === undefined || units === 'millisecond') { + return this; + } + + // 'date' is an alias for 'day', so it should be considered as such. + if (units === 'date') { + units = 'day'; + } + + return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms'); +} + +function valueOf () { + return this._d.valueOf() - ((this._offset || 0) * 60000); +} + +function unix () { + return Math.floor(this.valueOf() / 1000); +} + +function toDate () { + return new Date(this.valueOf()); +} + +function toArray () { + var m = this; + return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()]; +} + +function toObject () { + var m = this; + return { + years: m.year(), + months: m.month(), + date: m.date(), + hours: m.hours(), + minutes: m.minutes(), + seconds: m.seconds(), + milliseconds: m.milliseconds() + }; +} + +function toJSON () { + // new Date(NaN).toJSON() === null + return this.isValid() ? this.toISOString() : null; +} + +function isValid$2 () { + return isValid(this); +} + +function parsingFlags () { + return extend({}, getParsingFlags(this)); +} + +function invalidAt () { + return getParsingFlags(this).overflow; +} + +function creationData() { + return { + input: this._i, + format: this._f, + locale: this._locale, + isUTC: this._isUTC, + strict: this._strict + }; +} + +// FORMATTING + +addFormatToken(0, ['gg', 2], 0, function () { + return this.weekYear() % 100; +}); + +addFormatToken(0, ['GG', 2], 0, function () { + return this.isoWeekYear() % 100; +}); + +function addWeekYearFormatToken (token, getter) { + addFormatToken(0, [token, token.length], 0, getter); +} + +addWeekYearFormatToken('gggg', 'weekYear'); +addWeekYearFormatToken('ggggg', 'weekYear'); +addWeekYearFormatToken('GGGG', 'isoWeekYear'); +addWeekYearFormatToken('GGGGG', 'isoWeekYear'); + +// ALIASES + +addUnitAlias('weekYear', 'gg'); +addUnitAlias('isoWeekYear', 'GG'); + +// PRIORITY + +addUnitPriority('weekYear', 1); +addUnitPriority('isoWeekYear', 1); + + +// PARSING + +addRegexToken('G', matchSigned); +addRegexToken('g', matchSigned); +addRegexToken('GG', match1to2, match2); +addRegexToken('gg', match1to2, match2); +addRegexToken('GGGG', match1to4, match4); +addRegexToken('gggg', match1to4, match4); +addRegexToken('GGGGG', match1to6, match6); +addRegexToken('ggggg', match1to6, match6); + +addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) { + week[token.substr(0, 2)] = toInt(input); +}); + +addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { + week[token] = hooks.parseTwoDigitYear(input); +}); + +// MOMENTS + +function getSetWeekYear (input) { + return getSetWeekYearHelper.call(this, + input, + this.week(), + this.weekday(), + this.localeData()._week.dow, + this.localeData()._week.doy); +} + +function getSetISOWeekYear (input) { + return getSetWeekYearHelper.call(this, + input, this.isoWeek(), this.isoWeekday(), 1, 4); +} + +function getISOWeeksInYear () { + return weeksInYear(this.year(), 1, 4); +} + +function getWeeksInYear () { + var weekInfo = this.localeData()._week; + return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy); +} + +function getSetWeekYearHelper(input, week, weekday, dow, doy) { + var weeksTarget; + if (input == null) { + return weekOfYear(this, dow, doy).year; + } else { + weeksTarget = weeksInYear(input, dow, doy); + if (week > weeksTarget) { + week = weeksTarget; + } + return setWeekAll.call(this, input, week, weekday, dow, doy); + } +} + +function setWeekAll(weekYear, week, weekday, dow, doy) { + var dayOfYearData = dayOfYearFromWeeks(weekYear, week, weekday, dow, doy), + date = createUTCDate(dayOfYearData.year, 0, dayOfYearData.dayOfYear); + + this.year(date.getUTCFullYear()); + this.month(date.getUTCMonth()); + this.date(date.getUTCDate()); + return this; +} + +// FORMATTING + +addFormatToken('Q', 0, 'Qo', 'quarter'); + +// ALIASES + +addUnitAlias('quarter', 'Q'); + +// PRIORITY + +addUnitPriority('quarter', 7); + +// PARSING + +addRegexToken('Q', match1); +addParseToken('Q', function (input, array) { + array[MONTH] = (toInt(input) - 1) * 3; +}); + +// MOMENTS + +function getSetQuarter (input) { + return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3); +} + +// FORMATTING + +addFormatToken('D', ['DD', 2], 'Do', 'date'); + +// ALIASES + +addUnitAlias('date', 'D'); + +// PRIOROITY +addUnitPriority('date', 9); + +// PARSING + +addRegexToken('D', match1to2); +addRegexToken('DD', match1to2, match2); +addRegexToken('Do', function (isStrict, locale) { + // TODO: Remove "ordinalParse" fallback in next major release. + return isStrict ? + (locale._dayOfMonthOrdinalParse || locale._ordinalParse) : + locale._dayOfMonthOrdinalParseLenient; +}); + +addParseToken(['D', 'DD'], DATE); +addParseToken('Do', function (input, array) { + array[DATE] = toInt(input.match(match1to2)[0]); +}); + +// MOMENTS + +var getSetDayOfMonth = makeGetSet('Date', true); + +// FORMATTING + +addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear'); + +// ALIASES + +addUnitAlias('dayOfYear', 'DDD'); + +// PRIORITY +addUnitPriority('dayOfYear', 4); + +// PARSING + +addRegexToken('DDD', match1to3); +addRegexToken('DDDD', match3); +addParseToken(['DDD', 'DDDD'], function (input, array, config) { + config._dayOfYear = toInt(input); +}); + +// HELPERS + +// MOMENTS + +function getSetDayOfYear (input) { + var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1; + return input == null ? dayOfYear : this.add((input - dayOfYear), 'd'); +} + +// FORMATTING + +addFormatToken('m', ['mm', 2], 0, 'minute'); + +// ALIASES + +addUnitAlias('minute', 'm'); + +// PRIORITY + +addUnitPriority('minute', 14); + +// PARSING + +addRegexToken('m', match1to2); +addRegexToken('mm', match1to2, match2); +addParseToken(['m', 'mm'], MINUTE); + +// MOMENTS + +var getSetMinute = makeGetSet('Minutes', false); + +// FORMATTING + +addFormatToken('s', ['ss', 2], 0, 'second'); + +// ALIASES + +addUnitAlias('second', 's'); + +// PRIORITY + +addUnitPriority('second', 15); + +// PARSING + +addRegexToken('s', match1to2); +addRegexToken('ss', match1to2, match2); +addParseToken(['s', 'ss'], SECOND); + +// MOMENTS + +var getSetSecond = makeGetSet('Seconds', false); + +// FORMATTING + +addFormatToken('S', 0, 0, function () { + return ~~(this.millisecond() / 100); +}); + +addFormatToken(0, ['SS', 2], 0, function () { + return ~~(this.millisecond() / 10); +}); + +addFormatToken(0, ['SSS', 3], 0, 'millisecond'); +addFormatToken(0, ['SSSS', 4], 0, function () { + return this.millisecond() * 10; +}); +addFormatToken(0, ['SSSSS', 5], 0, function () { + return this.millisecond() * 100; +}); +addFormatToken(0, ['SSSSSS', 6], 0, function () { + return this.millisecond() * 1000; +}); +addFormatToken(0, ['SSSSSSS', 7], 0, function () { + return this.millisecond() * 10000; +}); +addFormatToken(0, ['SSSSSSSS', 8], 0, function () { + return this.millisecond() * 100000; +}); +addFormatToken(0, ['SSSSSSSSS', 9], 0, function () { + return this.millisecond() * 1000000; +}); + + +// ALIASES + +addUnitAlias('millisecond', 'ms'); + +// PRIORITY + +addUnitPriority('millisecond', 16); + +// PARSING + +addRegexToken('S', match1to3, match1); +addRegexToken('SS', match1to3, match2); +addRegexToken('SSS', match1to3, match3); + +var token; +for (token = 'SSSS'; token.length <= 9; token += 'S') { + addRegexToken(token, matchUnsigned); +} + +function parseMs(input, array) { + array[MILLISECOND] = toInt(('0.' + input) * 1000); +} + +for (token = 'S'; token.length <= 9; token += 'S') { + addParseToken(token, parseMs); +} +// MOMENTS + +var getSetMillisecond = makeGetSet('Milliseconds', false); + +// FORMATTING + +addFormatToken('z', 0, 0, 'zoneAbbr'); +addFormatToken('zz', 0, 0, 'zoneName'); + +// MOMENTS + +function getZoneAbbr () { + return this._isUTC ? 'UTC' : ''; +} + +function getZoneName () { + return this._isUTC ? 'Coordinated Universal Time' : ''; +} + +var proto = Moment.prototype; + +proto.add = add; +proto.calendar = calendar$1; +proto.clone = clone; +proto.diff = diff; +proto.endOf = endOf; +proto.format = format; +proto.from = from; +proto.fromNow = fromNow; +proto.to = to; +proto.toNow = toNow; +proto.get = stringGet; +proto.invalidAt = invalidAt; +proto.isAfter = isAfter; +proto.isBefore = isBefore; +proto.isBetween = isBetween; +proto.isSame = isSame; +proto.isSameOrAfter = isSameOrAfter; +proto.isSameOrBefore = isSameOrBefore; +proto.isValid = isValid$2; +proto.lang = lang; +proto.locale = locale; +proto.localeData = localeData; +proto.max = prototypeMax; +proto.min = prototypeMin; +proto.parsingFlags = parsingFlags; +proto.set = stringSet; +proto.startOf = startOf; +proto.subtract = subtract; +proto.toArray = toArray; +proto.toObject = toObject; +proto.toDate = toDate; +proto.toISOString = toISOString; +proto.inspect = inspect; +proto.toJSON = toJSON; +proto.toString = toString; +proto.unix = unix; +proto.valueOf = valueOf; +proto.creationData = creationData; + +// Year +proto.year = getSetYear; +proto.isLeapYear = getIsLeapYear; + +// Week Year +proto.weekYear = getSetWeekYear; +proto.isoWeekYear = getSetISOWeekYear; + +// Quarter +proto.quarter = proto.quarters = getSetQuarter; + +// Month +proto.month = getSetMonth; +proto.daysInMonth = getDaysInMonth; + +// Week +proto.week = proto.weeks = getSetWeek; +proto.isoWeek = proto.isoWeeks = getSetISOWeek; +proto.weeksInYear = getWeeksInYear; +proto.isoWeeksInYear = getISOWeeksInYear; + +// Day +proto.date = getSetDayOfMonth; +proto.day = proto.days = getSetDayOfWeek; +proto.weekday = getSetLocaleDayOfWeek; +proto.isoWeekday = getSetISODayOfWeek; +proto.dayOfYear = getSetDayOfYear; + +// Hour +proto.hour = proto.hours = getSetHour; + +// Minute +proto.minute = proto.minutes = getSetMinute; + +// Second +proto.second = proto.seconds = getSetSecond; + +// Millisecond +proto.millisecond = proto.milliseconds = getSetMillisecond; + +// Offset +proto.utcOffset = getSetOffset; +proto.utc = setOffsetToUTC; +proto.local = setOffsetToLocal; +proto.parseZone = setOffsetToParsedOffset; +proto.hasAlignedHourOffset = hasAlignedHourOffset; +proto.isDST = isDaylightSavingTime; +proto.isLocal = isLocal; +proto.isUtcOffset = isUtcOffset; +proto.isUtc = isUtc; +proto.isUTC = isUtc; + +// Timezone +proto.zoneAbbr = getZoneAbbr; +proto.zoneName = getZoneName; + +// Deprecations +proto.dates = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth); +proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth); +proto.years = deprecate('years accessor is deprecated. Use year instead', getSetYear); +proto.zone = deprecate('moment().zone is deprecated, use moment().utcOffset instead. http://momentjs.com/guides/#/warnings/zone/', getSetZone); +proto.isDSTShifted = deprecate('isDSTShifted is deprecated. See http://momentjs.com/guides/#/warnings/dst-shifted/ for more information', isDaylightSavingTimeShifted); + +function createUnix (input) { + return createLocal(input * 1000); +} + +function createInZone () { + return createLocal.apply(null, arguments).parseZone(); +} + +function preParsePostFormat (string) { + return string; +} + +var proto$1 = Locale.prototype; + +proto$1.calendar = calendar; +proto$1.longDateFormat = longDateFormat; +proto$1.invalidDate = invalidDate; +proto$1.ordinal = ordinal; +proto$1.preparse = preParsePostFormat; +proto$1.postformat = preParsePostFormat; +proto$1.relativeTime = relativeTime; +proto$1.pastFuture = pastFuture; +proto$1.set = set; + +// Month +proto$1.months = localeMonths; +proto$1.monthsShort = localeMonthsShort; +proto$1.monthsParse = localeMonthsParse; +proto$1.monthsRegex = monthsRegex; +proto$1.monthsShortRegex = monthsShortRegex; + +// Week +proto$1.week = localeWeek; +proto$1.firstDayOfYear = localeFirstDayOfYear; +proto$1.firstDayOfWeek = localeFirstDayOfWeek; + +// Day of Week +proto$1.weekdays = localeWeekdays; +proto$1.weekdaysMin = localeWeekdaysMin; +proto$1.weekdaysShort = localeWeekdaysShort; +proto$1.weekdaysParse = localeWeekdaysParse; + +proto$1.weekdaysRegex = weekdaysRegex; +proto$1.weekdaysShortRegex = weekdaysShortRegex; +proto$1.weekdaysMinRegex = weekdaysMinRegex; + +// Hours +proto$1.isPM = localeIsPM; +proto$1.meridiem = localeMeridiem; + +function get$1 (format, index, field, setter) { + var locale = getLocale(); + var utc = createUTC().set(setter, index); + return locale[field](utc, format); +} + +function listMonthsImpl (format, index, field) { + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + + if (index != null) { + return get$1(format, index, field, 'month'); + } + + var i; + var out = []; + for (i = 0; i < 12; i++) { + out[i] = get$1(format, i, field, 'month'); + } + return out; +} + +// () +// (5) +// (fmt, 5) +// (fmt) +// (true) +// (true, 5) +// (true, fmt, 5) +// (true, fmt) +function listWeekdaysImpl (localeSorted, format, index, field) { + if (typeof localeSorted === 'boolean') { + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + } else { + format = localeSorted; + index = format; + localeSorted = false; + + if (isNumber(format)) { + index = format; + format = undefined; + } + + format = format || ''; + } + + var locale = getLocale(), + shift = localeSorted ? locale._week.dow : 0; + + if (index != null) { + return get$1(format, (index + shift) % 7, field, 'day'); + } + + var i; + var out = []; + for (i = 0; i < 7; i++) { + out[i] = get$1(format, (i + shift) % 7, field, 'day'); + } + return out; +} + +function listMonths (format, index) { + return listMonthsImpl(format, index, 'months'); +} + +function listMonthsShort (format, index) { + return listMonthsImpl(format, index, 'monthsShort'); +} + +function listWeekdays (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdays'); +} + +function listWeekdaysShort (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdaysShort'); +} + +function listWeekdaysMin (localeSorted, format, index) { + return listWeekdaysImpl(localeSorted, format, index, 'weekdaysMin'); +} + +getSetGlobalLocale('en', { + dayOfMonthOrdinalParse: /\d{1,2}(th|st|nd|rd)/, + ordinal : function (number) { + var b = number % 10, + output = (toInt(number % 100 / 10) === 1) ? 'th' : + (b === 1) ? 'st' : + (b === 2) ? 'nd' : + (b === 3) ? 'rd' : 'th'; + return number + output; + } +}); + +// Side effect imports +hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale); +hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale); + +var mathAbs = Math.abs; + +function abs () { + var data = this._data; + + this._milliseconds = mathAbs(this._milliseconds); + this._days = mathAbs(this._days); + this._months = mathAbs(this._months); + + data.milliseconds = mathAbs(data.milliseconds); + data.seconds = mathAbs(data.seconds); + data.minutes = mathAbs(data.minutes); + data.hours = mathAbs(data.hours); + data.months = mathAbs(data.months); + data.years = mathAbs(data.years); + + return this; +} + +function addSubtract$1 (duration, input, value, direction) { + var other = createDuration(input, value); + + duration._milliseconds += direction * other._milliseconds; + duration._days += direction * other._days; + duration._months += direction * other._months; + + return duration._bubble(); +} + +// supports only 2.0-style add(1, 's') or add(duration) +function add$1 (input, value) { + return addSubtract$1(this, input, value, 1); +} + +// supports only 2.0-style subtract(1, 's') or subtract(duration) +function subtract$1 (input, value) { + return addSubtract$1(this, input, value, -1); +} + +function absCeil (number) { + if (number < 0) { + return Math.floor(number); + } else { + return Math.ceil(number); + } +} + +function bubble () { + var milliseconds = this._milliseconds; + var days = this._days; + var months = this._months; + var data = this._data; + var seconds, minutes, hours, years, monthsFromDays; + + // if we have a mix of positive and negative values, bubble down first + // check: https://github.com/moment/moment/issues/2166 + if (!((milliseconds >= 0 && days >= 0 && months >= 0) || + (milliseconds <= 0 && days <= 0 && months <= 0))) { + milliseconds += absCeil(monthsToDays(months) + days) * 864e5; + days = 0; + months = 0; + } + + // The following code bubbles up values, see the tests for + // examples of what that means. + data.milliseconds = milliseconds % 1000; + + seconds = absFloor(milliseconds / 1000); + data.seconds = seconds % 60; + + minutes = absFloor(seconds / 60); + data.minutes = minutes % 60; + + hours = absFloor(minutes / 60); + data.hours = hours % 24; + + days += absFloor(hours / 24); + + // convert days to months + monthsFromDays = absFloor(daysToMonths(days)); + months += monthsFromDays; + days -= absCeil(monthsToDays(monthsFromDays)); + + // 12 months -> 1 year + years = absFloor(months / 12); + months %= 12; + + data.days = days; + data.months = months; + data.years = years; + + return this; +} + +function daysToMonths (days) { + // 400 years have 146097 days (taking into account leap year rules) + // 400 years have 12 months === 4800 + return days * 4800 / 146097; +} + +function monthsToDays (months) { + // the reverse of daysToMonths + return months * 146097 / 4800; +} + +function as (units) { + if (!this.isValid()) { + return NaN; + } + var days; + var months; + var milliseconds = this._milliseconds; + + units = normalizeUnits(units); + + if (units === 'month' || units === 'year') { + days = this._days + milliseconds / 864e5; + months = this._months + daysToMonths(days); + return units === 'month' ? months : months / 12; + } else { + // handle milliseconds separately because of floating point math errors (issue #1867) + days = this._days + Math.round(monthsToDays(this._months)); + switch (units) { + case 'week' : return days / 7 + milliseconds / 6048e5; + case 'day' : return days + milliseconds / 864e5; + case 'hour' : return days * 24 + milliseconds / 36e5; + case 'minute' : return days * 1440 + milliseconds / 6e4; + case 'second' : return days * 86400 + milliseconds / 1000; + // Math.floor prevents floating point math errors here + case 'millisecond': return Math.floor(days * 864e5) + milliseconds; + default: throw new Error('Unknown unit ' + units); + } + } +} + +// TODO: Use this.as('ms')? +function valueOf$1 () { + if (!this.isValid()) { + return NaN; + } + return ( + this._milliseconds + + this._days * 864e5 + + (this._months % 12) * 2592e6 + + toInt(this._months / 12) * 31536e6 + ); +} + +function makeAs (alias) { + return function () { + return this.as(alias); + }; +} + +var asMilliseconds = makeAs('ms'); +var asSeconds = makeAs('s'); +var asMinutes = makeAs('m'); +var asHours = makeAs('h'); +var asDays = makeAs('d'); +var asWeeks = makeAs('w'); +var asMonths = makeAs('M'); +var asYears = makeAs('y'); + +function clone$1 () { + return createDuration(this); +} + +function get$2 (units) { + units = normalizeUnits(units); + return this.isValid() ? this[units + 's']() : NaN; +} + +function makeGetter(name) { + return function () { + return this.isValid() ? this._data[name] : NaN; + }; +} + +var milliseconds = makeGetter('milliseconds'); +var seconds = makeGetter('seconds'); +var minutes = makeGetter('minutes'); +var hours = makeGetter('hours'); +var days = makeGetter('days'); +var months = makeGetter('months'); +var years = makeGetter('years'); + +function weeks () { + return absFloor(this.days() / 7); +} + +var round = Math.round; +var thresholds = { + ss: 44, // a few seconds to seconds + s : 45, // seconds to minute + m : 45, // minutes to hour + h : 22, // hours to day + d : 26, // days to month + M : 11 // months to year +}; + +// helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize +function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) { + return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture); +} + +function relativeTime$1 (posNegDuration, withoutSuffix, locale) { + var duration = createDuration(posNegDuration).abs(); + var seconds = round(duration.as('s')); + var minutes = round(duration.as('m')); + var hours = round(duration.as('h')); + var days = round(duration.as('d')); + var months = round(duration.as('M')); + var years = round(duration.as('y')); + + var a = seconds <= thresholds.ss && ['s', seconds] || + seconds < thresholds.s && ['ss', seconds] || + minutes <= 1 && ['m'] || + minutes < thresholds.m && ['mm', minutes] || + hours <= 1 && ['h'] || + hours < thresholds.h && ['hh', hours] || + days <= 1 && ['d'] || + days < thresholds.d && ['dd', days] || + months <= 1 && ['M'] || + months < thresholds.M && ['MM', months] || + years <= 1 && ['y'] || ['yy', years]; + + a[2] = withoutSuffix; + a[3] = +posNegDuration > 0; + a[4] = locale; + return substituteTimeAgo.apply(null, a); +} + +// This function allows you to set the rounding function for relative time strings +function getSetRelativeTimeRounding (roundingFunction) { + if (roundingFunction === undefined) { + return round; + } + if (typeof(roundingFunction) === 'function') { + round = roundingFunction; + return true; + } + return false; +} + +// This function allows you to set a threshold for relative time strings +function getSetRelativeTimeThreshold (threshold, limit) { + if (thresholds[threshold] === undefined) { + return false; + } + if (limit === undefined) { + return thresholds[threshold]; + } + thresholds[threshold] = limit; + if (threshold === 's') { + thresholds.ss = limit - 1; + } + return true; +} + +function humanize (withSuffix) { + if (!this.isValid()) { + return this.localeData().invalidDate(); + } + + var locale = this.localeData(); + var output = relativeTime$1(this, !withSuffix, locale); + + if (withSuffix) { + output = locale.pastFuture(+this, output); + } + + return locale.postformat(output); +} + +var abs$1 = Math.abs; + +function sign(x) { + return ((x > 0) - (x < 0)) || +x; +} + +function toISOString$1() { + // for ISO strings we do not use the normal bubbling rules: + // * milliseconds bubble up until they become hours + // * days do not bubble at all + // * months bubble up until they become years + // This is because there is no context-free conversion between hours and days + // (think of clock changes) + // and also not between days and months (28-31 days per month) + if (!this.isValid()) { + return this.localeData().invalidDate(); + } + + var seconds = abs$1(this._milliseconds) / 1000; + var days = abs$1(this._days); + var months = abs$1(this._months); + var minutes, hours, years; + + // 3600 seconds -> 60 minutes -> 1 hour + minutes = absFloor(seconds / 60); + hours = absFloor(minutes / 60); + seconds %= 60; + minutes %= 60; + + // 12 months -> 1 year + years = absFloor(months / 12); + months %= 12; + + + // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js + var Y = years; + var M = months; + var D = days; + var h = hours; + var m = minutes; + var s = seconds ? seconds.toFixed(3).replace(/\.?0+$/, '') : ''; + var total = this.asSeconds(); + + if (!total) { + // this is the same as C#'s (Noda) and python (isodate)... + // but not other JS (goog.date) + return 'P0D'; + } + + var totalSign = total < 0 ? '-' : ''; + var ymSign = sign(this._months) !== sign(total) ? '-' : ''; + var daysSign = sign(this._days) !== sign(total) ? '-' : ''; + var hmsSign = sign(this._milliseconds) !== sign(total) ? '-' : ''; + + return totalSign + 'P' + + (Y ? ymSign + Y + 'Y' : '') + + (M ? ymSign + M + 'M' : '') + + (D ? daysSign + D + 'D' : '') + + ((h || m || s) ? 'T' : '') + + (h ? hmsSign + h + 'H' : '') + + (m ? hmsSign + m + 'M' : '') + + (s ? hmsSign + s + 'S' : ''); +} + +var proto$2 = Duration.prototype; + +proto$2.isValid = isValid$1; +proto$2.abs = abs; +proto$2.add = add$1; +proto$2.subtract = subtract$1; +proto$2.as = as; +proto$2.asMilliseconds = asMilliseconds; +proto$2.asSeconds = asSeconds; +proto$2.asMinutes = asMinutes; +proto$2.asHours = asHours; +proto$2.asDays = asDays; +proto$2.asWeeks = asWeeks; +proto$2.asMonths = asMonths; +proto$2.asYears = asYears; +proto$2.valueOf = valueOf$1; +proto$2._bubble = bubble; +proto$2.clone = clone$1; +proto$2.get = get$2; +proto$2.milliseconds = milliseconds; +proto$2.seconds = seconds; +proto$2.minutes = minutes; +proto$2.hours = hours; +proto$2.days = days; +proto$2.weeks = weeks; +proto$2.months = months; +proto$2.years = years; +proto$2.humanize = humanize; +proto$2.toISOString = toISOString$1; +proto$2.toString = toISOString$1; +proto$2.toJSON = toISOString$1; +proto$2.locale = locale; +proto$2.localeData = localeData; + +// Deprecations +proto$2.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString$1); +proto$2.lang = lang; + +// Side effect imports + +// FORMATTING + +addFormatToken('X', 0, 0, 'unix'); +addFormatToken('x', 0, 0, 'valueOf'); + +// PARSING + +addRegexToken('x', matchSigned); +addRegexToken('X', matchTimestamp); +addParseToken('X', function (input, array, config) { + config._d = new Date(parseFloat(input, 10) * 1000); +}); +addParseToken('x', function (input, array, config) { + config._d = new Date(toInt(input)); +}); + +// Side effect imports + + +hooks.version = '2.20.1'; + +setHookCallback(createLocal); + +hooks.fn = proto; +hooks.min = min; +hooks.max = max; +hooks.now = now; +hooks.utc = createUTC; +hooks.unix = createUnix; +hooks.months = listMonths; +hooks.isDate = isDate; +hooks.locale = getSetGlobalLocale; +hooks.invalid = createInvalid; +hooks.duration = createDuration; +hooks.isMoment = isMoment; +hooks.weekdays = listWeekdays; +hooks.parseZone = createInZone; +hooks.localeData = getLocale; +hooks.isDuration = isDuration; +hooks.monthsShort = listMonthsShort; +hooks.weekdaysMin = listWeekdaysMin; +hooks.defineLocale = defineLocale; +hooks.updateLocale = updateLocale; +hooks.locales = listLocales; +hooks.weekdaysShort = listWeekdaysShort; +hooks.normalizeUnits = normalizeUnits; +hooks.relativeTimeRounding = getSetRelativeTimeRounding; +hooks.relativeTimeThreshold = getSetRelativeTimeThreshold; +hooks.calendarFormat = getCalendarFormat; +hooks.prototype = proto; + +// currently HTML5 input type only supports 24-hour formats +hooks.HTML5_FMT = { + DATETIME_LOCAL: 'YYYY-MM-DDTHH:mm', // + DATETIME_LOCAL_SECONDS: 'YYYY-MM-DDTHH:mm:ss', // + DATETIME_LOCAL_MS: 'YYYY-MM-DDTHH:mm:ss.SSS', // + DATE: 'YYYY-MM-DD', // + TIME: 'HH:mm', // + TIME_SECONDS: 'HH:mm:ss', // + TIME_MS: 'HH:mm:ss.SSS', // + WEEK: 'YYYY-[W]WW', // + MONTH: 'YYYY-MM' // +}; + +return hooks; + +}))); diff --git a/js_sdk/js-base64/.attic/test-moment/yoshinoya.js b/js_sdk/js-base64/.attic/test-moment/yoshinoya.js new file mode 100644 index 0000000..4576c79 --- /dev/null +++ b/js_sdk/js-base64/.attic/test-moment/yoshinoya.js @@ -0,0 +1,19 @@ +/* + * use mocha to test me + * http://visionmedia.github.com/mocha/ + */ +var assert = assert || require("assert"); +var Base64 = Base64 || require('../base64.js').Base64; +var is = function (a, e, m) { + return function () { + assert.equal(a, e, m) + } +}; + +describe('Yoshinoya', function () { + it('.encode', is(Base64.encode('𠮷野家'), '8KCut+mHjuWutg==')); + it('.encodeURI', is(Base64.encodeURI('𠮷野家'), '8KCut-mHjuWutg')); + it('.decode', is(Base64.decode('8KCut+mHjuWutg=='), '𠮷野家')); + it('.decode', is(Base64.decode('8KCut-mHjuWutg'), '𠮷野家')); + /* it('.decode', is(Base64.decode('7aGC7b636YeO5a62'), '𠮷野家')); */ +}); diff --git a/js_sdk/js-base64/1x1.png b/js_sdk/js-base64/1x1.png new file mode 100644 index 0000000..909c66d Binary files /dev/null and b/js_sdk/js-base64/1x1.png differ diff --git a/js_sdk/js-base64/LICENSE.md b/js_sdk/js-base64/LICENSE.md new file mode 100644 index 0000000..fd579a4 --- /dev/null +++ b/js_sdk/js-base64/LICENSE.md @@ -0,0 +1,27 @@ +Copyright (c) 2014, Dan Kogai +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of {{{project}}} nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/js_sdk/js-base64/README.md b/js_sdk/js-base64/README.md new file mode 100644 index 0000000..1dfb104 --- /dev/null +++ b/js_sdk/js-base64/README.md @@ -0,0 +1,94 @@ +[![build status](https://secure.travis-ci.org/dankogai/js-base64.png)](http://travis-ci.org/dankogai/js-base64) + +# base64.js + +Yet another Base64 transcoder + +## Install + +```javascript +$ npm install --save js-base64 +``` + +If you are using it on ES6 transpilers, you may also need: + +```javascript +$ npm install --save babel-preset-env +``` + +Note `js-base64` itself is stand-alone so its `package.json` has no `dependencies`.  However, it is also tested on ES6 environment so `"babel-preset-env": "^1.7.0"` is on `devDependencies`. + + +## Usage + +### In Browser + +```html + +``` + +### node.js + +```javascript +var Base64 = require('js-base64').Base64; +``` + +## es6+ + +```javascript +import { Base64 } from 'js-base64'; +``` + +## SYNOPSIS + +```javascript +Base64.encode('dankogai'); // ZGFua29nYWk= +Base64.encode('小飼弾'); // 5bCP6aO85by+ +Base64.encodeURI('小飼弾'); // 5bCP6aO85by- + +Base64.decode('ZGFua29nYWk='); // dankogai +Base64.decode('5bCP6aO85by+'); // 小飼弾 +// note .decodeURI() is unnecessary since it accepts both flavors +Base64.decode('5bCP6aO85by-'); // 小飼弾 +``` + +### String Extension for ES5 + +```javascript +if (Base64.extendString) { + // you have to explicitly extend String.prototype + Base64.extendString(); + // once extended, you can do the following + 'dankogai'.toBase64(); // ZGFua29nYWk= + '小飼弾'.toBase64(); // 5bCP6aO85by+ + '小飼弾'.toBase64(true); // 5bCP6aO85by- + '小飼弾'.toBase64URI(); // 5bCP6aO85by- + 'ZGFua29nYWk='.fromBase64(); // dankogai + '5bCP6aO85by+'.fromBase64(); // 小飼弾 + '5bCP6aO85by-'.fromBase64(); // 小飼弾 +} +``` + +### TypeScript + +TypeScript 2.0 type definition was added to the [DefinitelyTyped repository](https://github.com/DefinitelyTyped/DefinitelyTyped). + +```bash +$ npm install --save @types/js-base64 +``` + +## `.decode()` vs `.atob` (and `.encode()` vs `btoa()`) + +Suppose you have: + +``` +var pngBase64 = + "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII="; +``` + +Which is a Base64-encoded 1x1 transparent PNG, **DO NOT USE** `Base64.decode(pngBase64)`.  Use `Base64.atob(pngBase64)` instead.  `Base64.decode()` decodes to UTF-8 string while `Base64.atob()` decodes to bytes, which is compatible to browser built-in `atob()` (Which is absent in node.js).  The same rule applies to the opposite direction. + + +## SEE ALSO + ++ http://en.wikipedia.org/wiki/Base64 diff --git a/js_sdk/js-base64/base64.html b/js_sdk/js-base64/base64.html new file mode 100644 index 0000000..dd18305 --- /dev/null +++ b/js_sdk/js-base64/base64.html @@ -0,0 +1,47 @@ + + + + + +Demo for base64.js + + +

Demo for base64.js

+

$Id: base64.html,v 1.1 2009/03/01 22:00:28 dankogai Exp dankogai $

+ + + + + + + + + + + +
TextBase64 +(URL Safe )
Roundtripiframe w/ data: (no IE)
+ + + + + + diff --git a/js_sdk/js-base64/base64.js b/js_sdk/js-base64/base64.js new file mode 100644 index 0000000..bac1cb2 --- /dev/null +++ b/js_sdk/js-base64/base64.js @@ -0,0 +1,231 @@ +/* + * base64.js + * + * Licensed under the BSD 3-Clause License. + * http://opensource.org/licenses/BSD-3-Clause + * + * References: + * http://en.wikipedia.org/wiki/Base64 + */ +;(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + ? module.exports = factory(global) + : typeof define === 'function' && define.amd + ? define(factory) : factory(global) +}(( + typeof self !== 'undefined' ? self + : typeof window !== 'undefined' ? window + : typeof global !== 'undefined' ? global +: this +), function(global) { + 'use strict'; + // existing version for noConflict() + var _Base64 = global.Base64; + var version = "2.4.9"; + // if node.js and NOT React Native, we use Buffer + var buffer; + if (typeof module !== 'undefined' && module.exports) { + try { + buffer = eval("require('buffer').Buffer"); + } catch (err) { + buffer = undefined; + } + } + // constants + var b64chars + = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + var b64tab = function(bin) { + var t = {}; + for (var i = 0, l = bin.length; i < l; i++) t[bin.charAt(i)] = i; + return t; + }(b64chars); + var fromCharCode = String.fromCharCode; + // encoder stuff + var cb_utob = function(c) { + if (c.length < 2) { + var cc = c.charCodeAt(0); + return cc < 0x80 ? c + : cc < 0x800 ? (fromCharCode(0xc0 | (cc >>> 6)) + + fromCharCode(0x80 | (cc & 0x3f))) + : (fromCharCode(0xe0 | ((cc >>> 12) & 0x0f)) + + fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) + + fromCharCode(0x80 | ( cc & 0x3f))); + } else { + var cc = 0x10000 + + (c.charCodeAt(0) - 0xD800) * 0x400 + + (c.charCodeAt(1) - 0xDC00); + return (fromCharCode(0xf0 | ((cc >>> 18) & 0x07)) + + fromCharCode(0x80 | ((cc >>> 12) & 0x3f)) + + fromCharCode(0x80 | ((cc >>> 6) & 0x3f)) + + fromCharCode(0x80 | ( cc & 0x3f))); + } + }; + var re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g; + var utob = function(u) { + return u.replace(re_utob, cb_utob); + }; + var cb_encode = function(ccc) { + var padlen = [0, 2, 1][ccc.length % 3], + ord = ccc.charCodeAt(0) << 16 + | ((ccc.length > 1 ? ccc.charCodeAt(1) : 0) << 8) + | ((ccc.length > 2 ? ccc.charCodeAt(2) : 0)), + chars = [ + b64chars.charAt( ord >>> 18), + b64chars.charAt((ord >>> 12) & 63), + padlen >= 2 ? '=' : b64chars.charAt((ord >>> 6) & 63), + padlen >= 1 ? '=' : b64chars.charAt(ord & 63) + ]; + return chars.join(''); + }; + var btoa = global.btoa ? function(b) { + return global.btoa(b); + } : function(b) { + return b.replace(/[\s\S]{1,3}/g, cb_encode); + }; + var _encode = buffer ? + buffer.from && Uint8Array && buffer.from !== Uint8Array.from + ? function (u) { + return (u.constructor === buffer.constructor ? u : buffer.from(u)) + .toString('base64') + } + : function (u) { + return (u.constructor === buffer.constructor ? u : new buffer(u)) + .toString('base64') + } + : function (u) { return btoa(utob(u)) } + ; + var encode = function(u, urisafe) { + return !urisafe + ? _encode(String(u)) + : _encode(String(u)).replace(/[+\/]/g, function(m0) { + return m0 == '+' ? '-' : '_'; + }).replace(/=/g, ''); + }; + var encodeURI = function(u) { return encode(u, true) }; + // decoder stuff + var re_btou = new RegExp([ + '[\xC0-\xDF][\x80-\xBF]', + '[\xE0-\xEF][\x80-\xBF]{2}', + '[\xF0-\xF7][\x80-\xBF]{3}' + ].join('|'), 'g'); + var cb_btou = function(cccc) { + switch(cccc.length) { + case 4: + var cp = ((0x07 & cccc.charCodeAt(0)) << 18) + | ((0x3f & cccc.charCodeAt(1)) << 12) + | ((0x3f & cccc.charCodeAt(2)) << 6) + | (0x3f & cccc.charCodeAt(3)), + offset = cp - 0x10000; + return (fromCharCode((offset >>> 10) + 0xD800) + + fromCharCode((offset & 0x3FF) + 0xDC00)); + case 3: + return fromCharCode( + ((0x0f & cccc.charCodeAt(0)) << 12) + | ((0x3f & cccc.charCodeAt(1)) << 6) + | (0x3f & cccc.charCodeAt(2)) + ); + default: + return fromCharCode( + ((0x1f & cccc.charCodeAt(0)) << 6) + | (0x3f & cccc.charCodeAt(1)) + ); + } + }; + var btou = function(b) { + return b.replace(re_btou, cb_btou); + }; + var cb_decode = function(cccc) { + var len = cccc.length, + padlen = len % 4, + n = (len > 0 ? b64tab[cccc.charAt(0)] << 18 : 0) + | (len > 1 ? b64tab[cccc.charAt(1)] << 12 : 0) + | (len > 2 ? b64tab[cccc.charAt(2)] << 6 : 0) + | (len > 3 ? b64tab[cccc.charAt(3)] : 0), + chars = [ + fromCharCode( n >>> 16), + fromCharCode((n >>> 8) & 0xff), + fromCharCode( n & 0xff) + ]; + chars.length -= [0, 0, 2, 1][padlen]; + return chars.join(''); + }; + var atob = global.atob ? function(a) { + return global.atob(a); + } : function(a){ + return a.replace(/[\s\S]{1,4}/g, cb_decode); + }; + var _decode = buffer ? + buffer.from && Uint8Array && buffer.from !== Uint8Array.from + ? function(a) { + return (a.constructor === buffer.constructor + ? a : buffer.from(a, 'base64')).toString(); + } + : function(a) { + return (a.constructor === buffer.constructor + ? a : new buffer(a, 'base64')).toString(); + } + : function(a) { return btou(atob(a)) }; + var decode = function(a){ + return _decode( + String(a).replace(/[-_]/g, function(m0) { return m0 == '-' ? '+' : '/' }) + .replace(/[^A-Za-z0-9\+\/]/g, '') + ); + }; + var noConflict = function() { + var Base64 = global.Base64; + global.Base64 = _Base64; + return Base64; + }; + // export Base64 + global.Base64 = { + VERSION: version, + atob: atob, + btoa: btoa, + fromBase64: decode, + toBase64: encode, + utob: utob, + encode: encode, + encodeURI: encodeURI, + btou: btou, + decode: decode, + noConflict: noConflict, + __buffer__: buffer + }; + // if ES5 is available, make Base64.extendString() available + if (typeof Object.defineProperty === 'function') { + var noEnum = function(v){ + return {value:v,enumerable:false,writable:true,configurable:true}; + }; + global.Base64.extendString = function () { + Object.defineProperty( + String.prototype, 'fromBase64', noEnum(function () { + return decode(this) + })); + Object.defineProperty( + String.prototype, 'toBase64', noEnum(function (urisafe) { + return encode(this, urisafe) + })); + Object.defineProperty( + String.prototype, 'toBase64URI', noEnum(function () { + return encode(this, true) + })); + }; + } + // + // export Base64 to the namespace + // + if (global['Meteor']) { // Meteor.js + Base64 = global.Base64; + } + // module.exports and AMD are mutually exclusive. + // module.exports has precedence. + if (typeof module !== 'undefined' && module.exports) { + module.exports.Base64 = global.Base64; + } + else if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define([], function(){ return global.Base64 }); + } + // that's it! + return {Base64: global.Base64} +})); diff --git a/js_sdk/js-base64/base64.min.js b/js_sdk/js-base64/base64.min.js new file mode 100644 index 0000000..df072aa --- /dev/null +++ b/js_sdk/js-base64/base64.min.js @@ -0,0 +1 @@ +(function(global,factory){typeof exports==="object"&&typeof module!=="undefined"?module.exports=factory(global):typeof define==="function"&&define.amd?define(factory):factory(global)})(typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:this,function(global){"use strict";var _Base64=global.Base64;var version="2.4.9";var buffer;if(typeof module!=="undefined"&&module.exports){try{buffer=eval("require('buffer').Buffer")}catch(err){buffer=undefined}}var b64chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var b64tab=function(bin){var t={};for(var i=0,l=bin.length;i>>6)+fromCharCode(128|cc&63):fromCharCode(224|cc>>>12&15)+fromCharCode(128|cc>>>6&63)+fromCharCode(128|cc&63)}else{var cc=65536+(c.charCodeAt(0)-55296)*1024+(c.charCodeAt(1)-56320);return fromCharCode(240|cc>>>18&7)+fromCharCode(128|cc>>>12&63)+fromCharCode(128|cc>>>6&63)+fromCharCode(128|cc&63)}};var re_utob=/[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;var utob=function(u){return u.replace(re_utob,cb_utob)};var cb_encode=function(ccc){var padlen=[0,2,1][ccc.length%3],ord=ccc.charCodeAt(0)<<16|(ccc.length>1?ccc.charCodeAt(1):0)<<8|(ccc.length>2?ccc.charCodeAt(2):0),chars=[b64chars.charAt(ord>>>18),b64chars.charAt(ord>>>12&63),padlen>=2?"=":b64chars.charAt(ord>>>6&63),padlen>=1?"=":b64chars.charAt(ord&63)];return chars.join("")};var btoa=global.btoa?function(b){return global.btoa(b)}:function(b){return b.replace(/[\s\S]{1,3}/g,cb_encode)};var _encode=buffer?buffer.from&&Uint8Array&&buffer.from!==Uint8Array.from?function(u){return(u.constructor===buffer.constructor?u:buffer.from(u)).toString("base64")}:function(u){return(u.constructor===buffer.constructor?u:new buffer(u)).toString("base64")}:function(u){return btoa(utob(u))};var encode=function(u,urisafe){return!urisafe?_encode(String(u)):_encode(String(u)).replace(/[+\/]/g,function(m0){return m0=="+"?"-":"_"}).replace(/=/g,"")};var encodeURI=function(u){return encode(u,true)};var re_btou=new RegExp(["[À-ß][€-¿]","[à-ï][€-¿]{2}","[ð-÷][€-¿]{3}"].join("|"),"g");var cb_btou=function(cccc){switch(cccc.length){case 4:var cp=(7&cccc.charCodeAt(0))<<18|(63&cccc.charCodeAt(1))<<12|(63&cccc.charCodeAt(2))<<6|63&cccc.charCodeAt(3),offset=cp-65536;return fromCharCode((offset>>>10)+55296)+fromCharCode((offset&1023)+56320);case 3:return fromCharCode((15&cccc.charCodeAt(0))<<12|(63&cccc.charCodeAt(1))<<6|63&cccc.charCodeAt(2));default:return fromCharCode((31&cccc.charCodeAt(0))<<6|63&cccc.charCodeAt(1))}};var btou=function(b){return b.replace(re_btou,cb_btou)};var cb_decode=function(cccc){var len=cccc.length,padlen=len%4,n=(len>0?b64tab[cccc.charAt(0)]<<18:0)|(len>1?b64tab[cccc.charAt(1)]<<12:0)|(len>2?b64tab[cccc.charAt(2)]<<6:0)|(len>3?b64tab[cccc.charAt(3)]:0),chars=[fromCharCode(n>>>16),fromCharCode(n>>>8&255),fromCharCode(n&255)];chars.length-=[0,0,2,1][padlen];return chars.join("")};var atob=global.atob?function(a){return global.atob(a)}:function(a){return a.replace(/[\s\S]{1,4}/g,cb_decode)};var _decode=buffer?buffer.from&&Uint8Array&&buffer.from!==Uint8Array.from?function(a){return(a.constructor===buffer.constructor?a:buffer.from(a,"base64")).toString()}:function(a){return(a.constructor===buffer.constructor?a:new buffer(a,"base64")).toString()}:function(a){return btou(atob(a))};var decode=function(a){return _decode(String(a).replace(/[-_]/g,function(m0){return m0=="-"?"+":"/"}).replace(/[^A-Za-z0-9\+\/]/g,""))};var noConflict=function(){var Base64=global.Base64;global.Base64=_Base64;return Base64};global.Base64={VERSION:version,atob:atob,btoa:btoa,fromBase64:decode,toBase64:encode,utob:utob,encode:encode,encodeURI:encodeURI,btou:btou,decode:decode,noConflict:noConflict,__buffer__:buffer};if(typeof Object.defineProperty==="function"){var noEnum=function(v){return{value:v,enumerable:false,writable:true,configurable:true}};global.Base64.extendString=function(){Object.defineProperty(String.prototype,"fromBase64",noEnum(function(){return decode(this)}));Object.defineProperty(String.prototype,"toBase64",noEnum(function(urisafe){return encode(this,urisafe)}));Object.defineProperty(String.prototype,"toBase64URI",noEnum(function(){return encode(this,true)}))}}if(global["Meteor"]){Base64=global.Base64}if(typeof module!=="undefined"&&module.exports){module.exports.Base64=global.Base64}else if(typeof define==="function"&&define.amd){define([],function(){return global.Base64})}return{Base64:global.Base64}}); \ No newline at end of file diff --git a/js_sdk/js-base64/bower.json b/js_sdk/js-base64/bower.json new file mode 100644 index 0000000..1a6df79 --- /dev/null +++ b/js_sdk/js-base64/bower.json @@ -0,0 +1,18 @@ +{ + "name": "js-base64", + "version": "2.4.9", + "license": "BSD-3-Clause", + "main": [ + "./base64.js" + ], + "ignore": [ + "old", + "test", + ".gitignore", + ".travis.yml", + "base64.html", + "package.json" + ], + "dependencies": { + } +} diff --git a/js_sdk/js-base64/package.js b/js_sdk/js-base64/package.js new file mode 100644 index 0000000..5b56425 --- /dev/null +++ b/js_sdk/js-base64/package.js @@ -0,0 +1,9 @@ +Package.describe({ + summary: "Yet another Base64 transcoder" +}) + +Package.on_use(function(api){ + api.export('Base64'); + + api.add_files(['base64.js'], 'server'); +}); \ No newline at end of file diff --git a/js_sdk/js-base64/package.json b/js_sdk/js-base64/package.json new file mode 100644 index 0000000..ea1aa18 --- /dev/null +++ b/js_sdk/js-base64/package.json @@ -0,0 +1,59 @@ +{ + "_from": "js-base64", + "_id": "js-base64@2.4.9", + "_inBundle": false, + "_integrity": "sha512-xcinL3AuDJk7VSzsHgb9DvvIXayBbadtMZ4HFPx8rUszbW1MuNMlwYVC4zzCZ6e1sqZpnNS5ZFYOhXqA39T7LQ==", + "_location": "/js-base64", + "_phantomChildren": {}, + "_requested": { + "type": "tag", + "registry": true, + "raw": "js-base64", + "name": "js-base64", + "escapedName": "js-base64", + "rawSpec": "", + "saveSpec": null, + "fetchSpec": "latest" + }, + "_requiredBy": [ + "#DEV:/", + "#USER" + ], + "_resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.9.tgz", + "_shasum": "748911fb04f48a60c4771b375cac45a80df11c03", + "_spec": "js-base64", + "_where": "C:\\Users\\dcloud\\Documents\\HBuilderProjects\\test-npm", + "author": { + "name": "Dan Kogai" + }, + "bugs": { + "url": "https://github.com/dankogai/js-base64/issues" + }, + "bundleDependencies": false, + "deprecated": false, + "description": "Yet another Base64 transcoder in pure-JS", + "devDependencies": { + "babel-preset-env": "^1.7.0", + "babel-register": "^6.26.0", + "mocha": "*" + }, + "directories": { + "test": "test" + }, + "gitHead": "8bfa436f733bec60c95c720e1d720c28b43ae0b2", + "homepage": "https://github.com/dankogai/js-base64#readme", + "keywords": [ + "base64" + ], + "license": "BSD-3-Clause", + "main": "base64.js", + "name": "js-base64", + "repository": { + "type": "git", + "url": "git://github.com/dankogai/js-base64.git" + }, + "scripts": { + "test": "mocha --compilers js:babel-register" + }, + "version": "2.4.9" +} diff --git a/js_sdk/js-base64/test/dankogai.js b/js_sdk/js-base64/test/dankogai.js new file mode 100644 index 0000000..b631414 --- /dev/null +++ b/js_sdk/js-base64/test/dankogai.js @@ -0,0 +1,44 @@ +/* + * $Id: dankogai.js,v 0.4 2012/08/24 05:23:18 dankogai Exp dankogai $ + * + * use mocha to test me + * http://visionmedia.github.com/mocha/ + */ +var assert = assert || require("assert"); +var Base64 = Base64 || require('../base64.js').Base64; +var is = function (a, e, m) { + return function () { + assert.equal(a, e, m) + } +}; + +describe('basic', function () { + it('d', is(Base64.encode('d'), 'ZA==')); + it('da', is(Base64.encode('da'), 'ZGE=')); + it('dan', is(Base64.encode('dan'), 'ZGFu')); + it('ZA==', is(Base64.decode('ZA=='), 'd' )); + it('ZGE=', is(Base64.decode('ZGE='), 'da' )); + it('ZGFu', is(Base64.decode('ZGFu'), 'dan' )); +}); + +describe('whitespace', function () { + it('Z A==', is(Base64.decode('ZA =='), 'd' )); + it('ZG E=', is(Base64.decode('ZG E='), 'da' )); + it('ZGF u', is(Base64.decode('ZGF u'), 'dan' )); +}); + +describe('null', function () { + it('\\0', is(Base64.encode('\0'), 'AA==')); + it('\\0\\0', is(Base64.encode('\0\0'), 'AAA=')); + it('\\0\\0\\0', is(Base64.encode('\0\0\0'), 'AAAA')); + it('AA==', is(Base64.decode('AA=='), '\0' )); + it('AAA=', is(Base64.decode('AAA='), '\0\0' )); + it('AAAA', is(Base64.decode('AAAA'), '\0\0\0')); +}); + +describe('Base64', function () { + it('.encode', is(Base64.encode('小飼弾'), '5bCP6aO85by+')); + it('.encodeURI', is(Base64.encodeURI('小飼弾'), '5bCP6aO85by-')); + it('.decode', is(Base64.decode('5bCP6aO85by+'), '小飼弾')); + it('.decode', is(Base64.decode('5bCP6aO85by-'), '小飼弾')); +}); diff --git a/js_sdk/js-base64/test/es5.js b/js_sdk/js-base64/test/es5.js new file mode 100644 index 0000000..ef134f6 --- /dev/null +++ b/js_sdk/js-base64/test/es5.js @@ -0,0 +1,24 @@ +/* + * $Id: es5.js,v 0.1 2012/08/23 19:43:17 dankogai Exp dankogai $ + * + * use mocha to test me + * http://visionmedia.github.com/mocha/ + */ +var assert = assert || require("assert"); +var Base64 = Base64 || require('../base64.js').Base64; +var is = function (a, e, m) { + return function () { + assert.equal(a, e, m) + } +}; + +if ('extendString' in Base64){ + Base64.extendString(); + describe('String', function () { + it('.toBase64', is('小飼弾'.toBase64(), '5bCP6aO85by+')); + it('.toBase64', is('小飼弾'.toBase64(true), '5bCP6aO85by-')); + it('.toBase64URI', is('小飼弾'.toBase64URI(), '5bCP6aO85by-')); + it('.fromBase64', is('5bCP6aO85by+'.fromBase64(), '小飼弾')); + it('.fromBase64', is('5bCP6aO85by-'.fromBase64(), '小飼弾')); + }); +} diff --git a/js_sdk/js-base64/test/es6.js b/js_sdk/js-base64/test/es6.js new file mode 100644 index 0000000..7dbe475 --- /dev/null +++ b/js_sdk/js-base64/test/es6.js @@ -0,0 +1,25 @@ +/* + * $Id: es6.js,v 0.1 2017/11/29 21:43:17 ufolux Exp ufolux $ + * + * use mocha to test me + * http://visionmedia.github.com/mocha/ + */ +import {Base64} from '../base64' + +var assert = assert || require("assert"); +var is = function (a, e, m) { + return function () { + assert.equal(a, e, m) + } +}; + +if ('extendString' in Base64){ + Base64.extendString(); + describe('String', function () { + it('.toBase64', is('小飼弾'.toBase64(), '5bCP6aO85by+')); + it('.toBase64', is('小飼弾'.toBase64(true), '5bCP6aO85by-')); + it('.toBase64URI', is('小飼弾'.toBase64URI(), '5bCP6aO85by-')); + it('.fromBase64', is('5bCP6aO85by+'.fromBase64(), '小飼弾')); + it('.fromBase64', is('5bCP6aO85by-'.fromBase64(), '小飼弾')); + }); +} diff --git a/js_sdk/js-base64/test/index.html b/js_sdk/js-base64/test/index.html new file mode 100644 index 0000000..4232d33 --- /dev/null +++ b/js_sdk/js-base64/test/index.html @@ -0,0 +1,39 @@ + + + + Mocha Tests + + + +
+ + + + + + + + + + + + + + + $Id: index.html,v 0.3 2017/09/11 08:43:43 dankogai Exp dankogai $ +
+ + diff --git a/js_sdk/js-base64/test/large.js b/js_sdk/js-base64/test/large.js new file mode 100644 index 0000000..20d7842 --- /dev/null +++ b/js_sdk/js-base64/test/large.js @@ -0,0 +1,25 @@ +/* + * $Id: large.js,v 0.3 2012/08/23 19:14:37 dankogai Exp dankogai $ + * + * use mocha to test me + * http://visionmedia.github.com/mocha/ + */ +var assert = assert || require("assert"); +var Base64 = Base64 || require('../base64.js').Base64; +var is = function (a, e, m) { + return function () { + assert.equal(a, e, m) + } +}; +var seed = function () { + var a, i; + for (a = [], i = 0; i < 256; i++) { + a.push(String.fromCharCode(i)); + } + return a.join(''); +}(); +describe('Base64', function () { + for (var i = 0, str = seed; i < 16; str += str, i++) { + it(''+str.length, is(Base64.decode(Base64.encode(str)), str)); + } +}); diff --git a/js_sdk/js-base64/test/yoshinoya.js b/js_sdk/js-base64/test/yoshinoya.js new file mode 100644 index 0000000..4576c79 --- /dev/null +++ b/js_sdk/js-base64/test/yoshinoya.js @@ -0,0 +1,19 @@ +/* + * use mocha to test me + * http://visionmedia.github.com/mocha/ + */ +var assert = assert || require("assert"); +var Base64 = Base64 || require('../base64.js').Base64; +var is = function (a, e, m) { + return function () { + assert.equal(a, e, m) + } +}; + +describe('Yoshinoya', function () { + it('.encode', is(Base64.encode('𠮷野家'), '8KCut+mHjuWutg==')); + it('.encodeURI', is(Base64.encodeURI('𠮷野家'), '8KCut-mHjuWutg')); + it('.decode', is(Base64.decode('8KCut+mHjuWutg=='), '𠮷野家')); + it('.decode', is(Base64.decode('8KCut-mHjuWutg'), '𠮷野家')); + /* it('.decode', is(Base64.decode('7aGC7b636YeO5a62'), '𠮷野家')); */ +}); diff --git a/main.js b/main.js new file mode 100644 index 0000000..fdfb8eb --- /dev/null +++ b/main.js @@ -0,0 +1,56 @@ +// 设置env配置文件 +import envConfig from '@/env/config.js' +// 全局配置项 +import appConfig from '@/config/appConfig.js' +import storageManage from '@/commons/utils/storageManage.js' +import uviewPlus,{setConfig} from 'uview-plus' +// 下面的在特殊场景下才需要配置,通常不用配置即可直接使用uvire-plus框架。 +// 调用setConfig方法,方法内部会进行对象属性深度合并,可以放心嵌套配置 +// 需要在app.use(uview-plus)之后执行 +setConfig({ + // 修改$u.config对象的属性 + config: { + // 修改默认单位为rpx,相当于执行 uni.$u.config.unit = 'rpx' + unit: 'px' + }, + // 修改$u.props对象的属性 + props: { + // 修改radio组件的size参数的默认值,相当于执行 uni.$u.props.radio.size = 30 + radio: { + // size: 20 + } + // 其他组件属性配置 + // ...... + } +}) +// 设置node环境 +envConfig.changeEnv(storageManage.env()) + +// #ifndef VUE3 + +import App from './App' + +import Vue from 'vue' +Vue.config.productionTip = false + +App.mpType = 'app' + +const app = new Vue({ + ...App +}) +app.$mount() +// #endif + +// #ifdef VUE3 +import { createSSRApp } from 'vue' +import App from './App.vue' +export function createApp() { + const app = createSSRApp(App) + app.use(uviewPlus) + app.config.globalProperties.$appName = appConfig.appName + uni.$appName = appConfig.appName + return { + app + } +} +// #endif \ No newline at end of file diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..49f8f4a --- /dev/null +++ b/manifest.json @@ -0,0 +1,239 @@ +{ + "name" : "银收客点餐宝", + "appid" : "__UNI__66E7BD0", + "description" : "", + "versionName" : "1.0.0", + "versionCode" : 100, + "transformPx" : false, + "app-plus" : { + "orientation" : "landscape", + /* 5+App特有相关 */ + "usingComponents" : true, + "nvueCompiler" : "uni-app", + "nvueStyleCompiler" : "uni-app", + "splashscreen" : { + "alwaysShowBeforeRender" : true, + "waiting" : true, + "autoclose" : true, + "delay" : 0 + }, + "modules" : { + "Canvas" : "nvue canvas", //使用Canvas模块 + "Geolocation" : {}, + "Maps" : {}, + "Barcode" : {}, + "Camera" : {} + }, + "screenOrientation" : [ + "portrait-primary", + "portrait-secondary", + "landscape-primary", + "landscape-secondary" + ], + /* 模块配置 */ + "distribute" : { + /* 应用发布信息 */ + "android" : { + "orientation" : "landscape", + /* android打包配置 */ + "permissions" : [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ], + "abiFilters" : [ "armeabi-v7a" ], + "permissionExternalStorage" : { + "request" : "none", + "prompt" : "应用保存运行状态等信息,需要获取读写手机存储(系统提示为访问设备上的照片、媒体内容和文件)权限,请允许。" + }, + "permissionPhoneState" : { + "request" : "none", + "prompt" : "为保证您正常、安全地使用,需要获取设备识别码(部分手机提示为获取手机号码)使用权限,请允许。" + }, + "autoSdkPermissions" : true, + "targetSdkVersion" : 26, + "minSdkVersion" : 21 + }, + "ios" : { + "dSYMs" : false + }, + /* ios打包配置 */ + "sdkConfigs" : { + "geolocation" : { + "amap" : { + "__platform__" : [ "ios", "android" ], + "appkey_ios" : "0b9be2631525ee5e218ac26d333f215c", + "appkey_android" : "9d1e62050f8558a082f7aa3ad5bb3c68" + } + }, + "maps" : { + "amap" : { + "appkey_ios" : "0b9be2631525ee5e218ac26d333f215c", + "appkey_android" : "9d1e62050f8558a082f7aa3ad5bb3c68" + } + }, + "ad" : {}, + "push" : {} + }, + "icons" : { + "android" : { + "hdpi" : "unpackage/res/icons/72x72.png", + "xhdpi" : "unpackage/res/icons/96x96.png", + "xxhdpi" : "unpackage/res/icons/144x144.png", + "xxxhdpi" : "unpackage/res/icons/192x192.png" + }, + "ios" : { + "appstore" : "unpackage/res/icons/1024x1024.png", + "ipad" : { + "app" : "unpackage/res/icons/76x76.png", + "app@2x" : "unpackage/res/icons/152x152.png", + "notification" : "unpackage/res/icons/20x20.png", + "notification@2x" : "unpackage/res/icons/40x40.png", + "proapp@2x" : "unpackage/res/icons/167x167.png", + "settings" : "unpackage/res/icons/29x29.png", + "settings@2x" : "unpackage/res/icons/58x58.png", + "spotlight" : "unpackage/res/icons/40x40.png", + "spotlight@2x" : "unpackage/res/icons/80x80.png" + }, + "iphone" : { + "app@2x" : "unpackage/res/icons/120x120.png", + "app@3x" : "unpackage/res/icons/180x180.png", + "notification@2x" : "unpackage/res/icons/40x40.png", + "notification@3x" : "unpackage/res/icons/60x60.png", + "settings@2x" : "unpackage/res/icons/58x58.png", + "settings@3x" : "unpackage/res/icons/87x87.png", + "spotlight@2x" : "unpackage/res/icons/80x80.png", + "spotlight@3x" : "unpackage/res/icons/120x120.png" + } + } + }, + "splashscreen" : { + "alwaysShowBeforeRender" : true, + "autoclose" : true, + "delay" : 0, + "orientation" : "landscape", + "androidStyle" : "default", + "android" : { + "hdpi" : "C:/Users/Administrator/Desktop/bg.png", + "xhdpi" : "C:/Users/Administrator/Desktop/bg.png", + "xxhdpi" : "C:/Users/Administrator/Desktop/bg.png" + }, + "useOriginalMsgbox" : true, + "iosStyle" : "storyboard", + "ios" : { + "storyboard" : "C:/Users/Administrator/Downloads/CustomStoryboard.zip" + } + } + } + }, + /* SDK配置 */ + "quickapp" : {}, + /* 快应用特有相关 */ + "mp-weixin" : { + "appid" : "wxcbff1cfb27c1066c", + "setting" : { + "urlCheck" : false, + "minified" : true, + "postcss" : true, + "es6" : true + }, + "optimization" : { + "subPackages" : true + }, + "usingComponents" : true, + "libVersion" : "latest" + }, + "vueVersion" : "3", + "h5" : { + "unipush" : { + "enable" : true + }, + "devServer" : { + "disableHostCheck" : true, + "proxy" : { + "/shopApi" : { + // 需要被代理的后台地址 + "target" : "https://wxcashiertest.sxczgkj.cn/cashierService", + "changeOrigin" : true, + "secure" : false, + "pathRewrite" : { + "^/shopApi" : "" + } + }, + "/mch" : { + // 需要被代理的后台地址 + "target" : "https://b.rscygroup.com", + "changeOrigin" : true, + "secure" : false, + "pathRewrite" : { + "^/mch" : "" + } + }, + "/server1" : { + // 需要被代理的后台地址 + "target" : "http://101.37.12.135:8080", + "changeOrigin" : true, + "secure" : false, + "pathRewrite" : { + "^/server1" : "" + } + }, + "/server3" : { + // 需要被代理的后台地址 + "target" : "http://101.37.12.135:8080", + "changeOrigin" : true, + "secure" : false, + "pathRewrite" : { + "^/server3" : "" + } + }, + "/ysk" : { + // 需要被代理的后台地址 + "target" : "https://admintestpapi.sxczgkj.cn", + "changeOrigin" : true, + "secure" : false, + "pathRewrite" : { + "/ysk" : "" + } + }, + "/ww" : { + // 需要被代理的后台地址 + "target" : "http://192.168.1.15:8000", + "changeOrigin" : true, + "secure" : false, + "pathRewrite" : { + "/ww" : "" + } + } + } + }, + "sdkConfigs" : { + "maps" : { + "amap" : { + "key" : "6033c97e67bf2e9ceac306e1a3fa35f8", + "securityJsCode" : "0547b69252ef0ed14e11f5c4ac152f07", + "serviceHost" : "" + } + } + } + }, + "mp-alipay" : { + "appid" : "2021004128648214" + } +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..0e18f38 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,629 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmmirror.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true + }, + "@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true + }, + "ajv": { + "version": "8.16.0", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.16.0.tgz", + "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + } + }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "requires": { + "ajv": "^8.0.0" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmmirror.com/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true + }, + "braces": { + "version": "3.0.3", + "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "requires": { + "fill-range": "^7.1.1" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "clipboard": { + "version": "2.0.11", + "resolved": "https://registry.npmmirror.com/clipboard/-/clipboard-2.0.11.tgz", + "integrity": "sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==", + "requires": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, + "copy-webpack-plugin": { + "version": "12.0.2", + "resolved": "https://registry.npmmirror.com/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz", + "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==", + "dev": true, + "requires": { + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.1", + "globby": "^14.0.0", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2" + } + }, + "dayjs": { + "version": "1.11.13", + "resolved": "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.13.tgz", + "integrity": "sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==" + }, + "delegate": { + "version": "3.2.0", + "resolved": "https://registry.npmmirror.com/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==" + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-glob": { + "version": "3.3.2", + "resolved": "https://registry.npmmirror.com/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "dependencies": { + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + } + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fastq": { + "version": "1.17.1", + "resolved": "https://registry.npmmirror.com/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "optional": true + }, + "glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmmirror.com/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "globby": { + "version": "14.0.2", + "resolved": "https://registry.npmmirror.com/globby/-/globby-14.0.2.tgz", + "integrity": "sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==", + "dev": true, + "requires": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.2", + "ignore": "^5.2.4", + "path-type": "^5.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.1.0" + } + }, + "gm-crypto": { + "version": "0.1.8", + "resolved": "https://registry.npmmirror.com/gm-crypto/-/gm-crypto-0.1.8.tgz", + "integrity": "sha512-gbTkobkbj3F70HJDQNhN9JNTvcR3O1YQJ0xGc8jTc4bZ1KuikmkjuFm5kZhyUbWxK/PwWDpPuTNyGwRYOopBLw==", + "requires": { + "buffer": "^5.7.0", + "jsbn": "^1.1.0", + "to-arraybuffer": "^1.0.1" + } + }, + "good-listener": { + "version": "1.2.2", + "resolved": "https://registry.npmmirror.com/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==", + "requires": { + "delegate": "^3.1.2" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, + "ignore": { + "version": "5.3.1", + "resolved": "https://registry.npmmirror.com/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "dev": true + }, + "immutable": { + "version": "4.3.7", + "resolved": "https://registry.npmmirror.com/immutable/-/immutable-4.3.7.tgz", + "integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "js-base64": { + "version": "3.7.2", + "resolved": "https://registry.npmmirror.com/js-base64/-/js-base64-3.7.2.tgz", + "integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ==" + }, + "jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==" + }, + "jsencrypt": { + "version": "3.3.2", + "resolved": "https://registry.npmmirror.com/jsencrypt/-/jsencrypt-3.3.2.tgz", + "integrity": "sha512-arQR1R1ESGdAxY7ZheWr12wCaF2yF47v5qpB76TtV64H1pyGudk9Hvw8Y9tb/FiTIaaTRUyaSnm5T/Y53Ghm/A==" + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true + }, + "klona": { + "version": "2.0.6", + "resolved": "https://registry.npmmirror.com/klona/-/klona-2.0.6.tgz", + "integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==", + "dev": true + }, + "loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmmirror.com/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "requires": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + } + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmmirror.com/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "path-type": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/path-type/-/path-type-5.0.0.tgz", + "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmmirror.com/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmmirror.com/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "sass": { + "version": "1.78.0", + "resolved": "https://registry.npmmirror.com/sass/-/sass-1.78.0.tgz", + "integrity": "sha512-AaIqGSrjo5lA2Yg7RvFZrlXDBCp3nV4XP73GrLGvdRWWwk+8H3l0SDvq/5bA4eF+0RFPLuWUk3E+P1U/YqnpsQ==", + "dev": true, + "requires": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + } + }, + "sass-loader": { + "version": "10.5.2", + "resolved": "https://registry.npmmirror.com/sass-loader/-/sass-loader-10.5.2.tgz", + "integrity": "sha512-vMUoSNOUKJILHpcNCCyD23X34gve1TS7Rjd9uXHeKqhvBG39x6XbswFDtpbTElj6XdMFezoWhkh5vtKudf2cgQ==", + "dev": true, + "requires": { + "klona": "^2.0.4", + "loader-utils": "^2.0.0", + "neo-async": "^2.6.2", + "schema-utils": "^3.0.0", + "semver": "^7.3.2" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "schema-utils": { + "version": "3.3.0", + "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "schema-utils": { + "version": "4.2.0", + "resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-4.2.0.tgz", + "integrity": "sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + } + }, + "select": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/select/-/select-1.1.2.tgz", + "integrity": "sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==" + }, + "semver": { + "version": "7.6.3", + "resolved": "https://registry.npmmirror.com/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true + }, + "serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmmirror.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "slash": { + "version": "5.1.0", + "resolved": "https://registry.npmmirror.com/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true + }, + "source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true + }, + "tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==" + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==" + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "unicorn-magic": { + "version": "0.1.0", + "resolved": "https://registry.npmmirror.com/unicorn-magic/-/unicorn-magic-0.1.0.tgz", + "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==", + "dev": true + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "uview-plus": { + "version": "3.3.32", + "resolved": "https://registry.npmmirror.com/uview-plus/-/uview-plus-3.3.32.tgz", + "integrity": "sha512-rl/Bw9uH7sNY8GAzKVv3Wel27wvUx08UuADEPxQB5U2LrkdHD2r6Cvk6BTbQbLKDTpFR7rrbVTQiK/DNKFIe4Q==", + "requires": { + "clipboard": "^2.0.11", + "dayjs": "^1.11.3" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..e93d886 --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "dependencies": { + "clipboard": "^2.0.11", + "dayjs": "^1.11.13", + "gm-crypto": "^0.1.8", + "immutable": "^4.3.7", + "js-base64": "^3.7.2", + "jsencrypt": "^3.3.2", + "lodash": "^4.17.21", + "uview-plus": "^3.3.32" + }, + "devDependencies": { + "copy-webpack-plugin": "^12.0.2", + "sass": "^1.78.0", + "sass-loader": "^10.5.2" + } +} diff --git a/pageTable/index/components/add-table.vue b/pageTable/index/components/add-table.vue new file mode 100644 index 0000000..fe5a4ee --- /dev/null +++ b/pageTable/index/components/add-table.vue @@ -0,0 +1,358 @@ + + + + + \ No newline at end of file diff --git a/pageTable/index/components/table-item.vue b/pageTable/index/components/table-item.vue new file mode 100644 index 0000000..f8b1df1 --- /dev/null +++ b/pageTable/index/components/table-item.vue @@ -0,0 +1,249 @@ + + + + + \ No newline at end of file diff --git a/pageTable/index/images/1.png b/pageTable/index/images/1.png new file mode 100644 index 0000000..ab68bfb Binary files /dev/null and b/pageTable/index/images/1.png differ diff --git a/pageTable/index/images/2.png b/pageTable/index/images/2.png new file mode 100644 index 0000000..dde53f0 Binary files /dev/null and b/pageTable/index/images/2.png differ diff --git a/pageTable/index/images/3.png b/pageTable/index/images/3.png new file mode 100644 index 0000000..ef435ca Binary files /dev/null and b/pageTable/index/images/3.png differ diff --git a/pageTable/index/index - 副本.vue b/pageTable/index/index - 副本.vue new file mode 100644 index 0000000..0a73ddf --- /dev/null +++ b/pageTable/index/index - 副本.vue @@ -0,0 +1,155 @@ + + + + + + diff --git a/pageTable/index/index.vue b/pageTable/index/index.vue new file mode 100644 index 0000000..47ea6c3 --- /dev/null +++ b/pageTable/index/index.vue @@ -0,0 +1,522 @@ + + + + + \ No newline at end of file diff --git a/pageTable/index/util.js b/pageTable/index/util.js new file mode 100644 index 0000000..abb1c45 --- /dev/null +++ b/pageTable/index/util.js @@ -0,0 +1,31 @@ +import * as Api from '@/http/yskApi/Instead.js' +import go from '@/commons/utils/go.js' +//打印订单 +export function printOrder(tableId) { + return new Promise((resolve, reject) => { + uni.showModal({ + title: '提示', + content: '确定要打印订单吗?', + success(res) { + if (res.confirm) { + Api.$printOrder({ + tableId + }).then(res => { + resolve(res) + }) + } + } + }) + }) + +} +//去支付页面 +export function toPay(options) { + go.to('PAGES_CRESATE_ORDER_PAY', { + tableId: options.tableId, + tableName: options.name, + masterId: options.masterId, + orderId: orderDetail.info.id, + discount: 1 + }) +} \ No newline at end of file diff --git a/pageTable/static/images/icon-arrow-down-fill.svg b/pageTable/static/images/icon-arrow-down-fill.svg new file mode 100644 index 0000000..4275b7e --- /dev/null +++ b/pageTable/static/images/icon-arrow-down-fill.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pages.json b/pages.json new file mode 100644 index 0000000..04103d3 --- /dev/null +++ b/pages.json @@ -0,0 +1,146 @@ +{ + "easycom": { + "autoscan": true, + "custom": { + "^my-(.*)": "@/components/my-components/my-$1.vue", + "^u--(.*)": "uview-plus/components/u-$1/u-$1.vue", + "^up-(.*)": "uview-plus/components/u-$1/u-$1.vue", + "^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue" + } + }, + "pages": [ + { + "pageId": "PAGES_CREATE_ORDER", + "path": "pagesCreateOrder/index/index", + "style": { + // "navigationBarTitleText": "代客下单" + "navigationBarTitleText": "", + "navigationStyle": "custom" + } + }, + { + "pageId": "PAGES_LOGIN", + "path": "pages/login/index", + "style": { + "navigationBarTitleText": "登录(自定义导航)", + "navigationStyle": "custom" + } + }, + { + "pageId": "PAGES_CHOOSE_USER", + "path": "pagesCreateOrder/choose-user/choose-user", + "style": { + "navigationBarTitleText": "选择用户" + } + }, + { + "pageId": "PAGES_CONFIRM_ORDER", + "path": "pagesCreateOrder/confirm-order/confirm-order", + "style": { + "navigationBarTitleText": "确认订单" + } + }, + { + "pageId": "PAGES_CHOOSE_TABLE", + "path": "pagesCreateOrder/choose-table/choose-table", + "style": { + "navigationBarTitleText": "选择桌台" + } + }, + { + "pageId": "PAGES_ADD_TEMP_CUISINE", + "path": "pagesCreateOrder/add-temp-cuisine/add-temp-cuisine", + "style": { + "navigationBarTitleText": "添加临时菜" + } + }, + { + "pageId": "PAGES_ORDER_INDEX", + "path": "pagesOrder/index/index", + "style": { + "navigationBarTitleText": "订单管理" + } + }, + { + "pageId": "PAGES_ORDER_DETAIL", + "path": "pagesOrder/detail/detail", + "style": { + "navigationBarTitleText": "订单详情" + } + }, + { + "pageId": "PAGES_ORDER_PAY", + "path": "pagesOrder/pay-order/pay-order", + "style": { + "navigationBarTitleText": "结账" + } + }, + { + "pageId": "PAGES_ORDER_TUIKUAN", + "path": "pagesOrder/tuikuan/tuikuan", + "style": { + "navigationBarTitleText": "退款" + } + }, + { + "path" : "pagesOrder/quan/quan", + "pageId": "PAGES_ORDER_QUAN", + "style" : + { + "navigationBarTitleText" : "券包" + } + }, + { + "pageId": "PAGES_TABLE", + "path": "pageTable/index/index", + "style": { + "navigationBarTitleText": "桌台管理" + } + } + + ], + "globalStyle": { + "pageOrientation":"landscape", + "navigationBarTextStyle": "black", + "navigationBarBackgroundColor": "#FFFFFF", + "backgroundColor": "#FFFFFF", + "backgroundColorBottom": "#FFFFFF", + "backgroundColorTop": "#FFFFFF", + "app-plus": { + "background": "#FFFFFF", + "scrollIndicator": "none", + "bounce": "none" + } + }, + "tabBar": { + "color": "#999999", + "selectedColor": "#2980FD", + "borderStyle": "black", + "iconWidth": "24px", + "fontSize": "11px", + "spacing": "5px", + "height": "58px", + "backgroundColor": "#FCFCFC", + "list": [{ + "pagePath": "pages/index/index", + "iconPath": "static/tabImg/index.png", + "selectedIconPath": "static/tabImg/index-select.png", + "text": "首页" + } + // , + // { + // "pagePath": "pages/order/order", + // "iconPath": "static/tabImg/order.png", + // "selectedIconPath": "static/tabImg/order-select.png", + // "text": "订单" + // } + , + { + "pagePath": "pages/user/user", + "iconPath": "static/tabImg/user.png", + "selectedIconPath": "static/tabImg/user-select.png", + "text": "我的" + } + ] + } +} \ No newline at end of file diff --git a/pages/index/components/Stats.vue b/pages/index/components/Stats.vue new file mode 100644 index 0000000..1dda7c0 --- /dev/null +++ b/pages/index/components/Stats.vue @@ -0,0 +1,268 @@ + + + + + diff --git a/pages/index/index.vue b/pages/index/index.vue new file mode 100644 index 0000000..33247b0 --- /dev/null +++ b/pages/index/index.vue @@ -0,0 +1,3 @@ + \ No newline at end of file diff --git a/pages/index/indexCopy.vue b/pages/index/indexCopy.vue new file mode 100644 index 0000000..bd4a8b2 --- /dev/null +++ b/pages/index/indexCopy.vue @@ -0,0 +1,191 @@ + + + + + + diff --git a/pages/login/index.vue b/pages/login/index.vue new file mode 100644 index 0000000..0060345 --- /dev/null +++ b/pages/login/index.vue @@ -0,0 +1,531 @@ + + + + \ No newline at end of file diff --git a/pages/webview/webview.vue b/pages/webview/webview.vue new file mode 100644 index 0000000..3f1e2f8 --- /dev/null +++ b/pages/webview/webview.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/pagesCreateOrder/add-temp-cuisine/add-temp-cuisine.vue b/pagesCreateOrder/add-temp-cuisine/add-temp-cuisine.vue new file mode 100644 index 0000000..4d364ea --- /dev/null +++ b/pagesCreateOrder/add-temp-cuisine/add-temp-cuisine.vue @@ -0,0 +1,222 @@ + + + + + \ No newline at end of file diff --git a/pagesCreateOrder/choose-table/choose-table.vue b/pagesCreateOrder/choose-table/choose-table.vue new file mode 100644 index 0000000..fbee499 --- /dev/null +++ b/pagesCreateOrder/choose-table/choose-table.vue @@ -0,0 +1,297 @@ + + + + + \ No newline at end of file diff --git a/pagesCreateOrder/choose-user/choose-user.vue b/pagesCreateOrder/choose-user/choose-user.vue new file mode 100644 index 0000000..f6bd8fc --- /dev/null +++ b/pagesCreateOrder/choose-user/choose-user.vue @@ -0,0 +1,194 @@ + + + + + \ No newline at end of file diff --git a/pagesCreateOrder/components/edit-discount.vue b/pagesCreateOrder/components/edit-discount.vue new file mode 100644 index 0000000..5ca910e --- /dev/null +++ b/pagesCreateOrder/components/edit-discount.vue @@ -0,0 +1,203 @@ + + + + + \ No newline at end of file diff --git a/pagesCreateOrder/confirm-order/components/discount.vue b/pagesCreateOrder/confirm-order/components/discount.vue new file mode 100644 index 0000000..478f954 --- /dev/null +++ b/pagesCreateOrder/confirm-order/components/discount.vue @@ -0,0 +1,258 @@ + + + + + \ No newline at end of file diff --git a/pagesCreateOrder/confirm-order/components/give-food.vue b/pagesCreateOrder/confirm-order/components/give-food.vue new file mode 100644 index 0000000..5687dc6 --- /dev/null +++ b/pagesCreateOrder/confirm-order/components/give-food.vue @@ -0,0 +1,197 @@ + + + + + \ No newline at end of file diff --git a/pagesCreateOrder/confirm-order/components/remark.vue b/pagesCreateOrder/confirm-order/components/remark.vue new file mode 100644 index 0000000..3fbe349 --- /dev/null +++ b/pagesCreateOrder/confirm-order/components/remark.vue @@ -0,0 +1,170 @@ + + + + + \ No newline at end of file diff --git a/pagesCreateOrder/confirm-order/confirm-order.vue b/pagesCreateOrder/confirm-order/confirm-order.vue new file mode 100644 index 0000000..c7d7939 --- /dev/null +++ b/pagesCreateOrder/confirm-order/confirm-order.vue @@ -0,0 +1,854 @@ + + + + + \ No newline at end of file diff --git a/pagesCreateOrder/index/components/car.vue b/pagesCreateOrder/index/components/car.vue new file mode 100644 index 0000000..864b1c0 --- /dev/null +++ b/pagesCreateOrder/index/components/car.vue @@ -0,0 +1,536 @@ + + + + + \ No newline at end of file diff --git a/pagesCreateOrder/index/components/cart-goods-item.vue b/pagesCreateOrder/index/components/cart-goods-item.vue new file mode 100644 index 0000000..ada393f --- /dev/null +++ b/pagesCreateOrder/index/components/cart-goods-item.vue @@ -0,0 +1,230 @@ + + + + + \ No newline at end of file diff --git a/pagesCreateOrder/index/components/guige.vue b/pagesCreateOrder/index/components/guige.vue new file mode 100644 index 0000000..6960214 --- /dev/null +++ b/pagesCreateOrder/index/components/guige.vue @@ -0,0 +1,249 @@ + + + + + \ No newline at end of file diff --git a/pagesCreateOrder/index/components/pop-goods-detail.vue b/pagesCreateOrder/index/components/pop-goods-detail.vue new file mode 100644 index 0000000..f591b3a --- /dev/null +++ b/pagesCreateOrder/index/components/pop-goods-detail.vue @@ -0,0 +1,133 @@ + + + + + \ No newline at end of file diff --git a/pagesCreateOrder/index/components/pop-search.vue b/pagesCreateOrder/index/components/pop-search.vue new file mode 100644 index 0000000..334c147 --- /dev/null +++ b/pagesCreateOrder/index/components/pop-search.vue @@ -0,0 +1,74 @@ + + + + + \ No newline at end of file diff --git a/pagesCreateOrder/index/components/skeleton.vue b/pagesCreateOrder/index/components/skeleton.vue new file mode 100644 index 0000000..8514209 --- /dev/null +++ b/pagesCreateOrder/index/components/skeleton.vue @@ -0,0 +1,155 @@ + + + + + \ No newline at end of file diff --git a/pagesCreateOrder/index/components/surcharge.vue b/pagesCreateOrder/index/components/surcharge.vue new file mode 100644 index 0000000..2bf8ebf --- /dev/null +++ b/pagesCreateOrder/index/components/surcharge.vue @@ -0,0 +1,109 @@ + + + + + \ No newline at end of file diff --git a/pagesCreateOrder/index/components/swiper-page.nvue b/pagesCreateOrder/index/components/swiper-page.nvue new file mode 100644 index 0000000..ccc882f --- /dev/null +++ b/pagesCreateOrder/index/components/swiper-page.nvue @@ -0,0 +1,90 @@ + + + + + diff --git a/pagesCreateOrder/index/index - 副本.vue b/pagesCreateOrder/index/index - 副本.vue new file mode 100644 index 0000000..432c05c --- /dev/null +++ b/pagesCreateOrder/index/index - 副本.vue @@ -0,0 +1,1535 @@ + + + + \ No newline at end of file diff --git a/pagesCreateOrder/index/index-back.vue b/pagesCreateOrder/index/index-back.vue new file mode 100644 index 0000000..7f8da3e --- /dev/null +++ b/pagesCreateOrder/index/index-back.vue @@ -0,0 +1,1564 @@ + + + + \ No newline at end of file diff --git a/pagesCreateOrder/index/index.vue b/pagesCreateOrder/index/index.vue new file mode 100644 index 0000000..f8c389a --- /dev/null +++ b/pagesCreateOrder/index/index.vue @@ -0,0 +1,1740 @@ + + + + \ No newline at end of file diff --git a/pagesCreateOrder/index/util.js b/pagesCreateOrder/index/util.js new file mode 100644 index 0000000..f756cb8 --- /dev/null +++ b/pagesCreateOrder/index/util.js @@ -0,0 +1,175 @@ +import { + $productCategory, + $layoutpage +} from '@/http/yskApi/pad.js' + +//根据布局返回商品列表 +export function returnSelCategotyGoods(arr, size) { + // 检查size是否为正整数 + if (size <= 0) { + throw new Error('Size must be a positive integer.'); + } + + // 计算数组的长度,并确保size不会超过数组长度 + const length = arr.length; + size = Math.min(size, length); + + // 创建一个新数组来存储结果 + const groups = []; + + // 循环遍历原始数组,每size个元素分为一组 + for (let i = 0; i < length; i += size) { + groups.push(arr.slice(i, i + size)); // 使用slice方法获取子数组 + } + + return groups; // 返回新的数组 +} +//根据店铺信息返回是否是后付款 +export function $trturnPayAfter(shop) { + //munchies 先付 restaurant 后付 + const payAfter = shop.registerType == "munchies" ? false : true; + return payAfter +} +//根据店铺信息返回就餐类型 +export function $returnUseType(shop, useType) { + //是否是后付款 + const payAfter = $trturnPayAfter(shop) + let result = "takeout"; + if (useType == "takeout") { + result = 'takeout' + } else { + //堂食 + result = `dine-in-${payAfter ? "after" : "before"}`; + } + return result +} +//判断商品是否可以下单 +export function isCanBuy(goods, isStock) { + return goods.isGrounding && goods.isPauseSale == 0 && (isStock ? goods.stockNumber > 0 : true); +} + + +// 一个数组是否包含另外一个数组全部元素 +function arrayContainsAll(arr1, arr2) { + for (let i = 0; i < arr2.length; i++) { + if (!arr1.includes(arr2[i])) { + return false; + } + } + return true; +} + +//n项 n-1项组合,生成全部结果 +function generateCombinations(arr, k) { + let result = []; + + function helper(index, current) { + if (current.length === k) { + result.push(current.slice()); // 使用slice()来避免直接修改原始数组 + } else { + for (let i = index; i < arr.length; i++) { + current.push(arr[i]); // 将当前元素添加到组合中 + helper(i + 1, current); // 递归调用,索引增加以避免重复选择相同的元素 + current.pop(); // 回溯,移除当前元素以便尝试其他组合 + } + } + } + + helper(0, []); // 从索引0开始,初始空数组作为起点 + return result; +} + +export function returnReverseVal(val, isReturnString = true) { + const isBol = typeof val === "boolean"; + const isString = typeof val === "string"; + let reverseNewval = ""; + if (isBol) { + reverseNewval = !val; + } + if (isString) { + reverseNewval = val === "true" ? "false" : "true"; + } + return reverseNewval; +} + +export function returnPrveId(par) { + const obj = { + prveData: [], + nowData: [], + nextData: [], + page: 0 + } + Object.assign(obj, par) + if (par.page == 0 || par.nowData.length <= 1) { + const prveIndex = obj.prveData.length - 1 <= 0 ? 0 : obj.prveData.length - 1 + return obj.prveData[prveIndex] ? obj.prveData[prveIndex].id : undefined + } + return obj.nowData[par.page - 1] ? obj.nowData[par.page - 1].id : undefined + +} +export function returnNowId(par) { + const obj = { + prveData: [], + nowData: [], + nextData: [], + page: 0 + } + Object.assign(obj, par) + if (!par.nowData[par.page]) { + return undefined + } + return obj.nowData[par.page] ? obj.nowData[par.page].id : undefined +} +export function returnNextId(par) { + const obj = { + prveData: [], + nowData: [], + nextData: [], + page: 0 + } + Object.assign(obj, par) + if (par.page >= par.nowData.length - 1 || par.nowData.length <= 1) { + const nextIndex = obj.nextData.length - 1 <= 0 ? 0 : obj.nextData.length - 1 + return obj.nextData[nextIndex] ? obj.nextData[nextIndex].id : undefined + } + return obj.nextData[par.page + 1] ? obj.nextData[par.page + 1].id : undefined +} + + +export async function returnLayoutPage(id) { + if (!id) { + return { + content: [], + totalElements: 0 + } + } + return $layoutpage({ + page: 1, + size: 999, + productCategoryId: id, + padLayoutId: '' + }) +} +export async function returnCategoryLayoutGoods(id,category) { + if (!id) { + return { + productList: [], + padLayoutCode: "single", + productCategoryId:category?category.id:'' + } + } + return $productCategory(id) +} + +export default { + isCanBuy, + returnNowId, + returnCategoryLayoutGoods, + returnLayoutPage, + returnPrveId, + returnNextId, + arrayContainsAll, + generateCombinations, + returnReverseVal, + $returnUseType +} \ No newline at end of file diff --git a/pagesCreateOrder/static/images/icon-add-black.svg b/pagesCreateOrder/static/images/icon-add-black.svg new file mode 100644 index 0000000..bdd891f --- /dev/null +++ b/pagesCreateOrder/static/images/icon-add-black.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pagesCreateOrder/static/images/icon-add.svg b/pagesCreateOrder/static/images/icon-add.svg new file mode 100644 index 0000000..fc5cb1d --- /dev/null +++ b/pagesCreateOrder/static/images/icon-add.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pagesCreateOrder/static/images/icon-car.svg b/pagesCreateOrder/static/images/icon-car.svg new file mode 100644 index 0000000..bf9a2d8 --- /dev/null +++ b/pagesCreateOrder/static/images/icon-car.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pagesCreateOrder/static/images/icon-reduce-black.svg b/pagesCreateOrder/static/images/icon-reduce-black.svg new file mode 100644 index 0000000..204a98e --- /dev/null +++ b/pagesCreateOrder/static/images/icon-reduce-black.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pagesCreateOrder/static/images/icon-reduce.svg b/pagesCreateOrder/static/images/icon-reduce.svg new file mode 100644 index 0000000..b45dfc7 --- /dev/null +++ b/pagesCreateOrder/static/images/icon-reduce.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pagesCreateOrder/static/images/icon-saoma.svg b/pagesCreateOrder/static/images/icon-saoma.svg new file mode 100644 index 0000000..fcfab1f --- /dev/null +++ b/pagesCreateOrder/static/images/icon-saoma.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pagesCreateOrder/static/images/icon-table.svg b/pagesCreateOrder/static/images/icon-table.svg new file mode 100644 index 0000000..5999a78 --- /dev/null +++ b/pagesCreateOrder/static/images/icon-table.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pagesCreateOrder/util.js b/pagesCreateOrder/util.js new file mode 100644 index 0000000..d584538 --- /dev/null +++ b/pagesCreateOrder/util.js @@ -0,0 +1,36 @@ +import { + returnBoolean +} from '@/commons/utils/format.js'; +// 返回购物车未下单的数据 +export function getNowCart(records) { + const nowCart = records.find(v => v.placeNum == 0) + const Cart = nowCart ? nowCart.info : [] + const goodsMap = {} + const arr = [] + for (let i in Cart) { + const item=Cart[i] + const key = item.productId + '_' + item.skuId + if (goodsMap.hasOwnProperty(key)) { + const index = goodsMap[key] + arr[index].number = arr[index].number * 1 + item.number + arr[index].totalNumber = arr[index].totalNumber * 1 + item.totalNumber + arr[index].totalAmount = arr[index].totalAmount * 1 + item.totalAmount + arr[index].packFee = arr[index].packFee * 1 + item.packFee + } else { + arr.push({ + ...item, + isPack: returnBoolean(item.isPack), + isGift: returnBoolean(item.isGift) + }) + goodsMap[key] = arr.length - 1; + } + } + // const result = Cart.map(item => { + // return { + // ...item, + // isPack: returnBoolean(item.isPack), + // isGift: returnBoolean(item.isGift) + // } + // }) + return arr +} \ No newline at end of file diff --git a/pagesOrder/detail/components/extra.vue b/pagesOrder/detail/components/extra.vue new file mode 100644 index 0000000..fd67051 --- /dev/null +++ b/pagesOrder/detail/components/extra.vue @@ -0,0 +1,168 @@ + + + + + \ No newline at end of file diff --git a/pagesOrder/detail/components/list - 副本.vue b/pagesOrder/detail/components/list - 副本.vue new file mode 100644 index 0000000..8aec0e9 --- /dev/null +++ b/pagesOrder/detail/components/list - 副本.vue @@ -0,0 +1,548 @@ + + + + + \ No newline at end of file diff --git a/pagesOrder/detail/components/list.vue b/pagesOrder/detail/components/list.vue new file mode 100644 index 0000000..1e18940 --- /dev/null +++ b/pagesOrder/detail/components/list.vue @@ -0,0 +1,612 @@ + + + + + \ No newline at end of file diff --git a/pagesOrder/detail/components/order.vue b/pagesOrder/detail/components/order.vue new file mode 100644 index 0000000..026830f --- /dev/null +++ b/pagesOrder/detail/components/order.vue @@ -0,0 +1,88 @@ + + + + + \ No newline at end of file diff --git a/pagesOrder/detail/components/step.vue b/pagesOrder/detail/components/step.vue new file mode 100644 index 0000000..0230944 --- /dev/null +++ b/pagesOrder/detail/components/step.vue @@ -0,0 +1,34 @@ + + + + + \ No newline at end of file diff --git a/pagesOrder/detail/components/tuicai.vue b/pagesOrder/detail/components/tuicai.vue new file mode 100644 index 0000000..dc833b1 --- /dev/null +++ b/pagesOrder/detail/components/tuicai.vue @@ -0,0 +1,232 @@ + + + + + \ No newline at end of file diff --git a/pagesOrder/detail/components/user.vue b/pagesOrder/detail/components/user.vue new file mode 100644 index 0000000..80820d6 --- /dev/null +++ b/pagesOrder/detail/components/user.vue @@ -0,0 +1,89 @@ + + + + + \ No newline at end of file diff --git a/pagesOrder/detail/detail.vue b/pagesOrder/detail/detail.vue new file mode 100644 index 0000000..4ba1343 --- /dev/null +++ b/pagesOrder/detail/detail.vue @@ -0,0 +1,381 @@ + + + + + \ No newline at end of file diff --git a/pagesOrder/detail/page.js b/pagesOrder/detail/page.js new file mode 100644 index 0000000..10c3daa --- /dev/null +++ b/pagesOrder/detail/page.js @@ -0,0 +1,23 @@ +import { + reactive, ref +} from 'vue'; +function isSameType(a, b) { + return a instanceof b === true || b instanceof a === true; +} +class OrderDetail { + constructor(data) { + const user ={} + const table = {} + const goodsList =[] + const orderInfo = {} + this.data=reactive({ + user,table,goodsList,orderInfo + }) + Object.assign(this, data) + } + setVal(key,val){ + this.data[key]=val + } +} + +export default OrderDetail \ No newline at end of file diff --git a/pagesOrder/index/compoents/filter.vue b/pagesOrder/index/compoents/filter.vue new file mode 100644 index 0000000..1df1665 --- /dev/null +++ b/pagesOrder/index/compoents/filter.vue @@ -0,0 +1,270 @@ + + + + + \ No newline at end of file diff --git a/pagesOrder/index/compoents/order-item.vue b/pagesOrder/index/compoents/order-item.vue new file mode 100644 index 0000000..3592fa1 --- /dev/null +++ b/pagesOrder/index/compoents/order-item.vue @@ -0,0 +1,289 @@ + + + + + \ No newline at end of file diff --git a/pagesOrder/index/compoents/order-list.vue b/pagesOrder/index/compoents/order-list.vue new file mode 100644 index 0000000..8725001 --- /dev/null +++ b/pagesOrder/index/compoents/order-list.vue @@ -0,0 +1,34 @@ + + + + + \ No newline at end of file diff --git a/pagesOrder/index/index.vue b/pagesOrder/index/index.vue new file mode 100644 index 0000000..379d18c --- /dev/null +++ b/pagesOrder/index/index.vue @@ -0,0 +1,152 @@ + + + + + \ No newline at end of file diff --git a/pagesOrder/pay-order/components/edit-accountPoints.vue b/pagesOrder/pay-order/components/edit-accountPoints.vue new file mode 100644 index 0000000..48e5c7f --- /dev/null +++ b/pagesOrder/pay-order/components/edit-accountPoints.vue @@ -0,0 +1,195 @@ + + + + + \ No newline at end of file diff --git a/pagesOrder/pay-order/pay-order.vue b/pagesOrder/pay-order/pay-order.vue new file mode 100644 index 0000000..3811782 --- /dev/null +++ b/pagesOrder/pay-order/pay-order.vue @@ -0,0 +1,938 @@ + + + + + \ No newline at end of file diff --git a/pagesOrder/quan/quan.vue b/pagesOrder/quan/quan.vue new file mode 100644 index 0000000..7b0ad03 --- /dev/null +++ b/pagesOrder/quan/quan.vue @@ -0,0 +1,580 @@ + + + + + \ No newline at end of file diff --git a/pagesOrder/quan_util.js b/pagesOrder/quan_util.js new file mode 100644 index 0000000..b11f492 --- /dev/null +++ b/pagesOrder/quan_util.js @@ -0,0 +1,250 @@ +export function isTui(item) { + return item.status == 'return' || item.status == 'refund' || item.status == 'refunding' +} +//是否使用会员价 +export function isUseVipPrice(vipUser,goods){ + return vipUser.id&&vipUser.isVip&&goods.isMember +} + +//计算商品券优惠价格 +export function returnProductCouponPrice(coup, goodsArr, vipUser) { + const item = goodsArr.find(v => v.productId == coup.proId); + if (!item) { + return 0 + } + const memberPrice = item.memberPrice ? item.memberPrice : item.price; + const price = item ? (isUseVipPrice(vipUser,item) ? memberPrice : item.price) : 0; + return price * coup.num + +} +//返回新的商品列表,过滤掉退菜的,退单的商品 +export function returnNewGoodsList(arr) { + let goodsMap = {} + return arr.filter(v => !isTui(v)) +} +//根据当前购物车商品以及数量,已选券对应商品数量,判断该商品券是否可用 +export function returnCoupCanUse(goodsArr = [], coup, selCoupArr = []) { + // if(!coup.use){ + // return false + // } + const findGoods = goodsArr.filter(v => v.productId == coup.proId) + if (!findGoods.length) { + return false + } + const findGoodsTotalNumber = findGoods.reduce((prve, cur) => { + return prve + cur.num * 1 + }, 0) + const selCoupNumber = selCoupArr.filter(v => v.proId == coup.proId).reduce((prve, cur) => { + return prve + cur.num * 1 + }, 0) + if (selCoupNumber >= findGoodsTotalNumber) { + return false + } + console.log(selCoupNumber,findGoodsTotalNumber); + return findGoodsTotalNumber < selCoupNumber ? false : true +} +//查找购物车商品根据购物车商品数据返回商品券信息(抵扣价格以及是否满足可用需求) +export function returnProductCoupon(coup, goodsArr, vipUser, selCoupArr = []) { + const newGoodsArr = returnNewGoodsList(goodsArr) + const item = newGoodsArr.find(v => v.productId == coup.proId); + if (!item) { + return { + ...coup, + discountAmount: 0, + use: false + } + } + const memberPrice = item.memberPrice ? item.memberPrice : item.price; + const price = item ? (isUseVipPrice(vipUser,item) ? memberPrice : item.price) : 0; + const discountAmount = (price * coup.num).toFixed(2) + console.log(discountAmount); + + // const canUse = !coup.use ? false : (discountAmount > 0 && returnCoupCanUse(goodsArr, coup, selCoupArr)) + // const canUse=discountAmount>0 + const canUse=coup.use + return { + ...coup, + discountAmount: discountAmount, + use: canUse + } + +} +/** + * 根据购物车商品计算商品券抵扣价格以及是否满足可用需求 + * 1.商品券对应商品数量大于购物车对应商品数量不可用 + * 2.未在购物车找到相关商品不可用 + * @param {*} coupArr + * @param {*} goodsArr + * @param {*} vipUser + * @returns + */ +export function returnProductAllCoup(coupArr, goodsArr, vipUser) { + return coupArr.map((v) => { + return returnProductCoupon(v, goodsArr, vipUser) + }) + +} +//返回商品实际支付价格 +export function returnProductPayPrice(goods,vipUser){ + const memberPrice = goods.memberPrice ? goods.memberPrice : goods.price; + const price = isUseVipPrice(vipUser,goods) ? memberPrice : goods.price; + return price +} +//返回商品券抵扣的商品价格 +export function returnProductCoupAllPrice(productPriceArr,startIndex,num,isMember=true){ + console.log(productPriceArr); + return productPriceArr.slice(startIndex,startIndex+num).reduce((prve,cur)=>{ + let curPrice=0 + if(typeof cur==='object'){ + curPrice=isMember?cur.memberPrice*1:cur.price + }else{ + curPrice=cur*1 + } + return prve+curPrice + },0) +} + +//返回商品券可抵扣的商品数量 +export function returnProductCanUseNum(productPriceArr,startIndex,num){ + console.log(productPriceArr); + console.log(num); + let n=0; + for(let i=0;i{ + return prve+cur.num*1 + },0) +} +//返回商品数量从0到n每一个对应的价格对照表 +export function returnGoodsPayPriceMap(goodsArr){ + return goodsArr.reduce((prve,cur)=>{ + if(!prve.hasOwnProperty(cur.productId)){ + prve[cur.productId]=[] + } + const arr=new Array(cur.num).fill(cur).map(v=>{ + return { + memberPrice:v.memberPrice?v.memberPrice:v.price, + price:v.price + } + }) + prve[cur.productId].push(...arr) + return prve + },{}) +} +//计算商品券总优惠价格 +export function returnProductCouponAllPrice(coupArr, goodsArr, vipUser) { + if (coupArr.length == 0) { + return 0; + } + //商品分组 + const goodsMap={} + //商品数量从0到n每一个对应的价格 + const goodsPayPriceMap={} + //商品券分组 + let coupMap={} + for(let i in coupArr){ + const coup=coupArr[i] + if(coupMap.hasOwnProperty(coup.proId)){ + coupMap[coup.proId].push(coup) + }else{ + coupMap[coup.proId]=[coup] + } + } + let total=0 + for(let key in coupMap){ + const arr=coupMap[key] + for(let i in arr){ + const coup=arr[i] + if(!goodsMap.hasOwnProperty(coup.proId)){ + goodsMap[coup.proId]=goodsArr.filter(v=>v.productId==coup.proId).map(v=>{ + return { + ...v, + payPrice:returnProductPayPrice(v,vipUser) + } + }).sort((a,b)=>{ + const aPrice=a.payPrice + const bPrice=b.payPrice + return aPrice-bPrice + }) + goodsPayPriceMap[coup.proId]=goodsMap[coup.proId].reduce((prve,cur)=>{ + const arr=new Array(cur.num).fill(cur.payPrice) + console.log(arr); + prve.push(...arr) + return prve + },[]) + } + const proCoupStartIndex=returnProCoupStartIndex(arr,i) + console.log(proCoupStartIndex); + const coupNum=Math.min(goodsPayPriceMap[coup.proId].length,coup.num) + console.log(coupNum); + total+=returnProductCoupAllPrice(goodsPayPriceMap[coup.proId],proCoupStartIndex,coupNum) + } + } + + return total.toFixed(2); + +} +//计算满减券总优惠价格 +export function returnFullReductionCouponAllPrice(coupArr) { + if (coupArr.length == 0) { + return 0; + } + return coupArr.filter(v => v.type == 1).reduce((a, b) => { + const price = b.discountAmount + return a + price; + }, 0).toFixed(2); + +} +//计算优惠券总价格 +export function returnCouponAllPrice(coupArr, goodsArr, vipUser) { + const poductAllprice = returnProductCouponAllPrice(coupArr, goodsArr, vipUser) + const pointAllPrice = returnFullReductionCouponAllPrice(coupArr) + return (poductAllprice * 1 + pointAllPrice * 1).toFixed(2); +} + +//返回当前满减券列表可用状态 +export function returnCanUseFullReductionCoupon(coupArr, payPrice, selCoup) { + return coupArr.map(v => { + if (v.id == selCoup.id) { + return v + } + const isfullAmount = payPrice >= v.fullAmount * 1 + if(payPrice<=0){ + return { + ...v, + use: false + } + } + return { + ...v, + use: v.use && isfullAmount + } + }) +} + +//根据商品数量还有商品券数量返回优惠券可以使用的数量数组 +export function returnCanUseNumProductCoup(coupArr,){ + let productCoup = coupArr.filter(v => v.type == 2) + //商品券分组 + let coupMap={} + for(let i in productCoup){ + const coup=productCoup[i] + if(coupMap.hasOwnProperty(coup.proId)){ + coupMap[coup.proId].push(coup) + }else{ + coupMap[coup.proId]=[coup] + } + } + return arr +} \ No newline at end of file diff --git a/pagesOrder/static/image/icon-search.svg b/pagesOrder/static/image/icon-search.svg new file mode 100644 index 0000000..1438df0 --- /dev/null +++ b/pagesOrder/static/image/icon-search.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pagesOrder/static/image/no-use.svg b/pagesOrder/static/image/no-use.svg new file mode 100644 index 0000000..a5df700 --- /dev/null +++ b/pagesOrder/static/image/no-use.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pagesOrder/tuikuan/tuikuan.vue b/pagesOrder/tuikuan/tuikuan.vue new file mode 100644 index 0000000..6e5084e --- /dev/null +++ b/pagesOrder/tuikuan/tuikuan.vue @@ -0,0 +1,254 @@ + + + + + \ No newline at end of file diff --git a/static/bgImg/quik-bg-img.svg b/static/bgImg/quik-bg-img.svg new file mode 100644 index 0000000..ad992ab --- /dev/null +++ b/static/bgImg/quik-bg-img.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/static/devIconImg/icon-code.svg b/static/devIconImg/icon-code.svg new file mode 100644 index 0000000..01e19cf --- /dev/null +++ b/static/devIconImg/icon-code.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/static/devIconImg/icon-face-1.svg b/static/devIconImg/icon-face-1.svg new file mode 100644 index 0000000..4e7082a --- /dev/null +++ b/static/devIconImg/icon-face-1.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/static/devIconImg/icon-horn.svg b/static/devIconImg/icon-horn.svg new file mode 100644 index 0000000..1ea06af --- /dev/null +++ b/static/devIconImg/icon-horn.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/static/devIconImg/icon-pos.svg b/static/devIconImg/icon-pos.svg new file mode 100644 index 0000000..65a901e --- /dev/null +++ b/static/devIconImg/icon-pos.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/static/devIconImg/icon-print.svg b/static/devIconImg/icon-print.svg new file mode 100644 index 0000000..bf85464 --- /dev/null +++ b/static/devIconImg/icon-print.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/static/devIconImg/icon-scanPos.svg b/static/devIconImg/icon-scanPos.svg new file mode 100644 index 0000000..6576a71 --- /dev/null +++ b/static/devIconImg/icon-scanPos.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/static/devIconImg/icon-term.svg b/static/devIconImg/icon-term.svg new file mode 100644 index 0000000..376411f --- /dev/null +++ b/static/devIconImg/icon-term.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/static/icon-empty.svg b/static/icon-empty.svg new file mode 100644 index 0000000..e991ff1 --- /dev/null +++ b/static/icon-empty.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/iconImg/ali-none.svg b/static/iconImg/ali-none.svg new file mode 100644 index 0000000..05a7b57 --- /dev/null +++ b/static/iconImg/ali-none.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/iconImg/ali-resete.svg b/static/iconImg/ali-resete.svg new file mode 100644 index 0000000..40d18cb --- /dev/null +++ b/static/iconImg/ali-resete.svg @@ -0,0 +1,4 @@ + + + + diff --git a/static/iconImg/ali-success.svg b/static/iconImg/ali-success.svg new file mode 100644 index 0000000..9d35a2d --- /dev/null +++ b/static/iconImg/ali-success.svg @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/iconImg/computer.svg b/static/iconImg/computer.svg new file mode 100644 index 0000000..12ffe7d --- /dev/null +++ b/static/iconImg/computer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/iconImg/custom-time-icon.svg b/static/iconImg/custom-time-icon.svg new file mode 100644 index 0000000..40eb541 --- /dev/null +++ b/static/iconImg/custom-time-icon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/static/iconImg/default-img.svg b/static/iconImg/default-img.svg new file mode 100644 index 0000000..40999f7 --- /dev/null +++ b/static/iconImg/default-img.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/static/iconImg/icon-arrow-black.svg b/static/iconImg/icon-arrow-black.svg new file mode 100644 index 0000000..5a745c9 --- /dev/null +++ b/static/iconImg/icon-arrow-black.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/iconImg/icon-arrow-downWhite.svg b/static/iconImg/icon-arrow-downWhite.svg new file mode 100644 index 0000000..a949e5e --- /dev/null +++ b/static/iconImg/icon-arrow-downWhite.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/iconImg/icon-arrow-left.svg b/static/iconImg/icon-arrow-left.svg new file mode 100644 index 0000000..4356fbc --- /dev/null +++ b/static/iconImg/icon-arrow-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/iconImg/icon-arrow-right.svg b/static/iconImg/icon-arrow-right.svg new file mode 100644 index 0000000..3af849c --- /dev/null +++ b/static/iconImg/icon-arrow-right.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/iconImg/icon-arrow-small.svg b/static/iconImg/icon-arrow-small.svg new file mode 100644 index 0000000..bfd2d6d --- /dev/null +++ b/static/iconImg/icon-arrow-small.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/iconImg/icon-calendar.svg b/static/iconImg/icon-calendar.svg new file mode 100644 index 0000000..cd97cad --- /dev/null +++ b/static/iconImg/icon-calendar.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/static/iconImg/icon-check.svg b/static/iconImg/icon-check.svg new file mode 100644 index 0000000..837d6a7 --- /dev/null +++ b/static/iconImg/icon-check.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/iconImg/icon-code.svg b/static/iconImg/icon-code.svg new file mode 100644 index 0000000..7f71213 --- /dev/null +++ b/static/iconImg/icon-code.svg @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/iconImg/icon-delete.svg b/static/iconImg/icon-delete.svg new file mode 100644 index 0000000..f4c8348 --- /dev/null +++ b/static/iconImg/icon-delete.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/static/iconImg/icon-disable.svg b/static/iconImg/icon-disable.svg new file mode 100644 index 0000000..f81de97 --- /dev/null +++ b/static/iconImg/icon-disable.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/iconImg/icon-more.svg b/static/iconImg/icon-more.svg new file mode 100644 index 0000000..66cbe85 --- /dev/null +++ b/static/iconImg/icon-more.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/static/iconImg/icon-nav-left.svg b/static/iconImg/icon-nav-left.svg new file mode 100644 index 0000000..903f8e7 --- /dev/null +++ b/static/iconImg/icon-nav-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/iconImg/icon-nav-white.svg b/static/iconImg/icon-nav-white.svg new file mode 100644 index 0000000..84fd689 --- /dev/null +++ b/static/iconImg/icon-nav-white.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/iconImg/icon-scan-index.svg b/static/iconImg/icon-scan-index.svg new file mode 100644 index 0000000..0539828 --- /dev/null +++ b/static/iconImg/icon-scan-index.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/static/iconImg/icon-scan.svg b/static/iconImg/icon-scan.svg new file mode 100644 index 0000000..d72d828 --- /dev/null +++ b/static/iconImg/icon-scan.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/static/iconImg/icon-screen.svg b/static/iconImg/icon-screen.svg new file mode 100644 index 0000000..24c9e35 --- /dev/null +++ b/static/iconImg/icon-screen.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/iconImg/icon-search.svg b/static/iconImg/icon-search.svg new file mode 100644 index 0000000..c5fe331 --- /dev/null +++ b/static/iconImg/icon-search.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/iconImg/icon-success.svg b/static/iconImg/icon-success.svg new file mode 100644 index 0000000..491f4c7 --- /dev/null +++ b/static/iconImg/icon-success.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/static/iconImg/icon-x-white.svg b/static/iconImg/icon-x-white.svg new file mode 100644 index 0000000..4f9e98c --- /dev/null +++ b/static/iconImg/icon-x-white.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/iconImg/icon-x.svg b/static/iconImg/icon-x.svg new file mode 100644 index 0000000..deb25b0 --- /dev/null +++ b/static/iconImg/icon-x.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/add.svg b/static/img/add.svg new file mode 100644 index 0000000..8f3b983 --- /dev/null +++ b/static/img/add.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/img/del.svg b/static/img/del.svg new file mode 100644 index 0000000..6558c28 --- /dev/null +++ b/static/img/del.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/PAGE_SALES_SUMMARY.svg b/static/indexImg/PAGE_SALES_SUMMARY.svg new file mode 100644 index 0000000..a53761d --- /dev/null +++ b/static/indexImg/PAGE_SALES_SUMMARY.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/business.svg b/static/indexImg/business.svg new file mode 100644 index 0000000..3d624e9 --- /dev/null +++ b/static/indexImg/business.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/del.svg b/static/indexImg/del.svg new file mode 100644 index 0000000..51ddecb --- /dev/null +++ b/static/indexImg/del.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/indexImg/goods-group.svg b/static/indexImg/goods-group.svg new file mode 100644 index 0000000..ca243ef --- /dev/null +++ b/static/indexImg/goods-group.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/icon-about.svg b/static/indexImg/icon-about.svg new file mode 100644 index 0000000..7aa803e --- /dev/null +++ b/static/indexImg/icon-about.svg @@ -0,0 +1,4 @@ + + + + diff --git a/static/indexImg/icon-ad.svg b/static/indexImg/icon-ad.svg new file mode 100644 index 0000000..efae2be --- /dev/null +++ b/static/indexImg/icon-ad.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/static/indexImg/icon-ali-pay.svg b/static/indexImg/icon-ali-pay.svg new file mode 100644 index 0000000..e8b7f6b --- /dev/null +++ b/static/indexImg/icon-ali-pay.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/static/indexImg/icon-app.svg b/static/indexImg/icon-app.svg new file mode 100644 index 0000000..8897601 --- /dev/null +++ b/static/indexImg/icon-app.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/static/indexImg/icon-arrow-down-sm.svg b/static/indexImg/icon-arrow-down-sm.svg new file mode 100644 index 0000000..ad9d617 --- /dev/null +++ b/static/indexImg/icon-arrow-down-sm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/icon-arrow-right.svg b/static/indexImg/icon-arrow-right.svg new file mode 100644 index 0000000..93d56c5 --- /dev/null +++ b/static/indexImg/icon-arrow-right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/icon-calc.svg b/static/indexImg/icon-calc.svg new file mode 100644 index 0000000..96a8503 --- /dev/null +++ b/static/indexImg/icon-calc.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/static/indexImg/icon-cashier.svg b/static/indexImg/icon-cashier.svg new file mode 100644 index 0000000..89ffad0 --- /dev/null +++ b/static/indexImg/icon-cashier.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/icon-category.svg b/static/indexImg/icon-category.svg new file mode 100644 index 0000000..89107d4 --- /dev/null +++ b/static/indexImg/icon-category.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/icon-invoicing.svg b/static/indexImg/icon-invoicing.svg new file mode 100644 index 0000000..79a8a59 --- /dev/null +++ b/static/indexImg/icon-invoicing.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/icon-ledger.svg b/static/indexImg/icon-ledger.svg new file mode 100644 index 0000000..951cb60 --- /dev/null +++ b/static/indexImg/icon-ledger.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/static/indexImg/icon-line-up.svg b/static/indexImg/icon-line-up.svg new file mode 100644 index 0000000..cf14ce1 --- /dev/null +++ b/static/indexImg/icon-line-up.svg @@ -0,0 +1 @@ +01 \ No newline at end of file diff --git a/static/indexImg/icon-member.svg b/static/indexImg/icon-member.svg new file mode 100644 index 0000000..0fa1a59 --- /dev/null +++ b/static/indexImg/icon-member.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/static/indexImg/icon-order.svg b/static/indexImg/icon-order.svg new file mode 100644 index 0000000..fb672b7 --- /dev/null +++ b/static/indexImg/icon-order.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/icon-passage.svg b/static/indexImg/icon-passage.svg new file mode 100644 index 0000000..4085838 --- /dev/null +++ b/static/indexImg/icon-passage.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/static/indexImg/icon-printer.svg b/static/indexImg/icon-printer.svg new file mode 100644 index 0000000..0892970 --- /dev/null +++ b/static/indexImg/icon-printer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/icon-pro.svg b/static/indexImg/icon-pro.svg new file mode 100644 index 0000000..89b021f --- /dev/null +++ b/static/indexImg/icon-pro.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/static/indexImg/icon-product-control.svg b/static/indexImg/icon-product-control.svg new file mode 100644 index 0000000..2d3a80f --- /dev/null +++ b/static/indexImg/icon-product-control.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/icon-recharge.svg b/static/indexImg/icon-recharge.svg new file mode 100644 index 0000000..598b693 --- /dev/null +++ b/static/indexImg/icon-recharge.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/icon-setup.svg b/static/indexImg/icon-setup.svg new file mode 100644 index 0000000..5145b15 --- /dev/null +++ b/static/indexImg/icon-setup.svg @@ -0,0 +1,4 @@ + + + + diff --git a/static/indexImg/icon-staff.svg b/static/indexImg/icon-staff.svg new file mode 100644 index 0000000..759ff01 --- /dev/null +++ b/static/indexImg/icon-staff.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/static/indexImg/icon-store.svg b/static/indexImg/icon-store.svg new file mode 100644 index 0000000..6f0436c --- /dev/null +++ b/static/indexImg/icon-store.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/static/indexImg/icon-substitute-ordering.svg b/static/indexImg/icon-substitute-ordering.svg new file mode 100644 index 0000000..9698162 --- /dev/null +++ b/static/indexImg/icon-substitute-ordering.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/icon-table.svg b/static/indexImg/icon-table.svg new file mode 100644 index 0000000..3fde787 --- /dev/null +++ b/static/indexImg/icon-table.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/icon-user.svg b/static/indexImg/icon-user.svg new file mode 100644 index 0000000..ebad65f --- /dev/null +++ b/static/indexImg/icon-user.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/icon-wine.svg b/static/indexImg/icon-wine.svg new file mode 100644 index 0000000..4460386 --- /dev/null +++ b/static/indexImg/icon-wine.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/icon-work.svg b/static/indexImg/icon-work.svg new file mode 100644 index 0000000..54aef2c --- /dev/null +++ b/static/indexImg/icon-work.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/icon-yuyue-zuo.svg b/static/indexImg/icon-yuyue-zuo.svg new file mode 100644 index 0000000..9e1a3ba --- /dev/null +++ b/static/indexImg/icon-yuyue-zuo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/icon-yuyue.svg b/static/indexImg/icon-yuyue.svg new file mode 100644 index 0000000..05caf58 --- /dev/null +++ b/static/indexImg/icon-yuyue.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/mch-info.svg b/static/indexImg/mch-info.svg new file mode 100644 index 0000000..af635f2 --- /dev/null +++ b/static/indexImg/mch-info.svg @@ -0,0 +1,4 @@ + + + + diff --git a/static/indexImg/red-envelope.svg b/static/indexImg/red-envelope.svg new file mode 100644 index 0000000..e8d2877 --- /dev/null +++ b/static/indexImg/red-envelope.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/indexImg/user-bg.svg b/static/indexImg/user-bg.svg new file mode 100644 index 0000000..e9fc2b5 --- /dev/null +++ b/static/indexImg/user-bg.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/static/indexImg/user-contact.svg b/static/indexImg/user-contact.svg new file mode 100644 index 0000000..014c1cd --- /dev/null +++ b/static/indexImg/user-contact.svg @@ -0,0 +1,4 @@ + + + + diff --git a/static/login/Group 24.svg b/static/login/Group 24.svg new file mode 100644 index 0000000..2442585 --- /dev/null +++ b/static/login/Group 24.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/static/login/icon-arrow-left.svg b/static/login/icon-arrow-left.svg new file mode 100644 index 0000000..8295a45 --- /dev/null +++ b/static/login/icon-arrow-left.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/login/icon-confirm-pw.svg b/static/login/icon-confirm-pw.svg new file mode 100644 index 0000000..c6342e7 --- /dev/null +++ b/static/login/icon-confirm-pw.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/static/login/icon-invite-code.svg b/static/login/icon-invite-code.svg new file mode 100644 index 0000000..8de8eb9 --- /dev/null +++ b/static/login/icon-invite-code.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/static/login/icon-merchantuser.svg b/static/login/icon-merchantuser.svg new file mode 100644 index 0000000..364af0f --- /dev/null +++ b/static/login/icon-merchantuser.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/static/login/icon-phone.svg b/static/login/icon-phone.svg new file mode 100644 index 0000000..cc81079 --- /dev/null +++ b/static/login/icon-phone.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/static/login/icon-pw.svg b/static/login/icon-pw.svg new file mode 100644 index 0000000..55b5424 --- /dev/null +++ b/static/login/icon-pw.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/static/login/icon-sms-code.svg b/static/login/icon-sms-code.svg new file mode 100644 index 0000000..0def6b4 --- /dev/null +++ b/static/login/icon-sms-code.svg @@ -0,0 +1,4 @@ + + + + diff --git a/static/login/icon-user.svg b/static/login/icon-user.svg new file mode 100644 index 0000000..9805024 --- /dev/null +++ b/static/login/icon-user.svg @@ -0,0 +1,4 @@ + + + + diff --git a/static/login/select.svg b/static/login/select.svg new file mode 100644 index 0000000..03f088f --- /dev/null +++ b/static/login/select.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/static/login/selected.svg b/static/login/selected.svg new file mode 100644 index 0000000..c4890f3 --- /dev/null +++ b/static/login/selected.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/static/logo.png b/static/logo.png new file mode 100644 index 0000000..b5771e2 Binary files /dev/null and b/static/logo.png differ diff --git a/static/logo.svg b/static/logo.svg new file mode 100644 index 0000000..a2e2ac3 --- /dev/null +++ b/static/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/member/account-history.svg b/static/member/account-history.svg new file mode 100644 index 0000000..276977d --- /dev/null +++ b/static/member/account-history.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/static/member/delete.svg b/static/member/delete.svg new file mode 100644 index 0000000..bda3350 --- /dev/null +++ b/static/member/delete.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/static/member/edit.svg b/static/member/edit.svg new file mode 100644 index 0000000..c7b3845 --- /dev/null +++ b/static/member/edit.svg @@ -0,0 +1,4 @@ + + + + diff --git a/static/member/member-arrow.svg b/static/member/member-arrow.svg new file mode 100644 index 0000000..f6809cd --- /dev/null +++ b/static/member/member-arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/member/recharge-record.svg b/static/member/recharge-record.svg new file mode 100644 index 0000000..f1f36a1 --- /dev/null +++ b/static/member/recharge-record.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/static/member/recharge-rule.svg b/static/member/recharge-rule.svg new file mode 100644 index 0000000..49b1038 --- /dev/null +++ b/static/member/recharge-rule.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/static/noiseless.mp3 b/static/noiseless.mp3 new file mode 100644 index 0000000..253da45 Binary files /dev/null and b/static/noiseless.mp3 differ diff --git a/static/orderImg/code.svg b/static/orderImg/code.svg new file mode 100644 index 0000000..dc6486e --- /dev/null +++ b/static/orderImg/code.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/static/orderImg/copy.svg b/static/orderImg/copy.svg new file mode 100644 index 0000000..c0b60a6 --- /dev/null +++ b/static/orderImg/copy.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/static/orderImg/default-pay.svg b/static/orderImg/default-pay.svg new file mode 100644 index 0000000..f666c0e --- /dev/null +++ b/static/orderImg/default-pay.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/orderImg/refresh.svg b/static/orderImg/refresh.svg new file mode 100644 index 0000000..46d0323 --- /dev/null +++ b/static/orderImg/refresh.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/static/orderImg/union-pay.svg b/static/orderImg/union-pay.svg new file mode 100644 index 0000000..25c2fe5 --- /dev/null +++ b/static/orderImg/union-pay.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/static/orderImg/wechat.svg b/static/orderImg/wechat.svg new file mode 100644 index 0000000..1ed54f6 --- /dev/null +++ b/static/orderImg/wechat.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/orderImg/ysf.svg b/static/orderImg/ysf.svg new file mode 100644 index 0000000..63cb440 --- /dev/null +++ b/static/orderImg/ysf.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/static/orderImg/zfb.svg b/static/orderImg/zfb.svg new file mode 100644 index 0000000..1719187 --- /dev/null +++ b/static/orderImg/zfb.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/static/pay/scancode.svg b/static/pay/scancode.svg new file mode 100644 index 0000000..089d99b --- /dev/null +++ b/static/pay/scancode.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/static/pay/type-wx.svg b/static/pay/type-wx.svg new file mode 100644 index 0000000..8558912 --- /dev/null +++ b/static/pay/type-wx.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/static/pay/type-ysf.svg b/static/pay/type-ysf.svg new file mode 100644 index 0000000..21abb77 --- /dev/null +++ b/static/pay/type-ysf.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/static/pay/type-zfb.svg b/static/pay/type-zfb.svg new file mode 100644 index 0000000..0eb8372 --- /dev/null +++ b/static/pay/type-zfb.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/static/payImg/icon-qt.svg b/static/payImg/icon-qt.svg new file mode 100644 index 0000000..19710af --- /dev/null +++ b/static/payImg/icon-qt.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/payImg/icon-wx.svg b/static/payImg/icon-wx.svg new file mode 100644 index 0000000..4002962 --- /dev/null +++ b/static/payImg/icon-wx.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/payImg/icon-yl.svg b/static/payImg/icon-yl.svg new file mode 100644 index 0000000..10f9aea --- /dev/null +++ b/static/payImg/icon-yl.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/static/payImg/icon-ysf.svg b/static/payImg/icon-ysf.svg new file mode 100644 index 0000000..2187c6c --- /dev/null +++ b/static/payImg/icon-ysf.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/static/payImg/icon-zfb.svg b/static/payImg/icon-zfb.svg new file mode 100644 index 0000000..349e076 --- /dev/null +++ b/static/payImg/icon-zfb.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/static/privacy.html b/static/privacy.html new file mode 100644 index 0000000..df88aff --- /dev/null +++ b/static/privacy.html @@ -0,0 +1,1455 @@ + + + + + + + + + + + + + + +

隐私政策

+

商福通商户通APP(以下简称“我们”)尊重并保护所有商福通商户通用户的个人信息及隐私安全。为了给您提供更准确、更有个性化的服务,我们依据《中华人民共和国网络安全法》、《信息安全技术 个人信息安全规范》以及其他相关法律法规和技术规范明确了我们收集/使用/披露您的个人信息的原则。本隐私政策进一步阐述了关于您个人信息的相关权利。

+

本政策与您所使用的我们的产品与/或服务息息相关,您在下载、安装、启动、浏览、注册、登录、使用我们的产品和/或服务(以下统称“使用我们的产品和/或服务时”)时,我们将按照本政策的约定处理和保护您的个人信息。

+

请在使用/继续使用我们的各项产品与服务前,仔细阅读并充分理解本政策。如果您不同意本政策的内容,将可能导致我们的产品/服务无法正常运行,您应立即停止访问/使用我们的产品与/或服务。若您同意本《隐私政策》,即视为您已经仔细阅读/充分理解,并同意本《隐私政策》的全部内容。若您使用/继续使用我们提供的产品与/或服务的行为,均视为您已仔细阅读/充分理解,并同意本《隐私政策》(包括更新版本)的全部内容。

+

关于我们

+

商福通付网站及商福通商户通APP的经营者为河北商福通科技有限公司及其关联公司。

+

注册地址为河北省沧州市运河区御河新城小区东16号楼2-2202

+

目录

+

一、我们如何收集和使用您的个人信息

+

二、我们如何共享、转让、公开披露您的个人信息

+

三、我们如何存储和保护您的个人信息

+

四、您如何管理您的个人信息

+

五、您如何注销您的账号

+

六、有关第三方提供产品和/或服务的特别说明

+

七、我们如何使用Cookie和其他同类技术

+

八、更新隐私政策

+

九、联系我们

+

十、其他

+

一、我们如何收集和使用您的个人信息

+

我们会遵循正当、合法、必要的原则,处于对本政策所述的以下目的,收集和使用您在使用我们的产品与/或服务时所主动提供,或因使用我们的产品与/或服务时被动产生的个人信息。除本政策另有规定外,在未征得您事先许可的情况下,我们不会将这些信息对外披露或提供给第三方。若我们需要将您的个人信息用于本政策未载明的其他用途,或基于特定目的将已经收集的信息用于其他目的,我们将以合理的方式告知您,并在使用前征得您的同意。

+

1.账号注册及登录

+

1.1当您注册商福通商户通APP账号时,您需要根据商福通商户通APP的要求提供您的个人注册信息,我们会收集您所填写的商户名称、手机号码以及您所选择的商户类型。

+

1.2为了给您提供更合理的服务,当您登录商福通商户通APP时,我们会使用您的用户ID/手机号,以确认您账号所属的商户信息。

+

2.向您提供产品与/或服务时

+

2.1信息浏览、管理、修改、新增等功能。

+

当您使用商福通商户通APP中的信息浏览、管理、修改和新增等功能时,我们会请求您授权照片、相机、和存储功能的权限。如果您拒绝授权提供,将无法使用相应的功能,但并不影响您使用商福通商户通APP的其他功能。

+

2.1.1当您使用用户头像修改/上传等功能时,我们会请求您授权存储功能的权限,如果您拒绝授权提供,将无法使用相应功能。但并不影响您使用商福通商户通APP的其他功能。

+

2.1.2当您使用商福通商户通APP中的编辑个人信息、门店管理、码牌管理、云喇叭管理、云打印机管理、扫码POS管理等功能时,您所提供的图片、文字、状态等信息将会上传并存储至云端服务器中,由于存储是实现以上功能及其多端同步的必要条件。我们会以加密的方式存储这些信息,您也可以随时修改这些信息。

+

2.2我们的产品基于DCloud uni-app(5+ App/Wap2App)开发,应用运行期间需要收集您的设备唯一识别码(IMEI/android ID/DEVICE_ID/IDFA、SIM 卡 IMSI 信息、OAID)以提供统计分析服务,并通过应用启动数据及异常错误日志分析改进性能和用户体验,为用户提供更好的服务。详情内容请访问《DCloud用户服务条款》

+ + + + + + + + + + + + + + + + + +
SDK名称包名信息使用目的使用的权限涉及个人信息
uni-app(5+、web2app)io.dcloud基础模块android.permission.INTERNET
android.permission.ACCESS_NETWORK_STATE
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.READ_EXTERNAL_STORAG
android.permission.READ_PHONE_STATE
存储的个人文件,设备信息(IMEI、ANDROID_ID、DEVICE_ID、IMSI),网络信息
+

2.3搜索功能。当您使用商福通商户通APP提供的搜索功能时,我们会收集您所输入的关键词信息、访问时间信息。这些信息是搜索功能的必要条件。

+

2.4扫码。当您使用商福通商户通APP提供的扫一扫支付、绑定新码、扫码获取云喇叭/打印机设备号等功能和/或服务时,我们会请求您授权相机的权限。如果您拒绝授权提供,将无法使用上述功能。

+

2.5地址。当您使用商福通商户通APP提供的门店/辅助终端设备信息修改或新增中的选择地址功能时,我们会请求您授权位置的权限。如果您拒绝授权提供,将无法使用上述功能。

+

2.6收款。当您使用商福通商户通APP提供的收款功能时、我们会收集该笔收款订单的订单号、收款金额、收款时间、支付时间、支付方式、订单状态、门店信息、用户信息,这些信息用于生成详细的订单记录。

+

2.7退款。当您使用商福通商户通APP提供的订单退款功能时、我们会收集该笔订单的订单号、订单金额、支付金额、退款金额、支付时间、退款时间、门店信息、用户信息,这些信息用于生成详细的退款记录,并对比收退款金额,以限制退款金额不能大于支付金额。

+

2.8查询。当您使用商福通商户通APP提供的订单记录、门店列表、码牌列表、云喇叭列表、云打印机列表、收款通知接收人列表等功能时,我们会收集您的账户信息和商户ID,用于展示在您查询权限内的信息。

+

2.9拨号。当您使用商福通商户通APP,关于我们-联系电话中的快捷拨号功能时,我们会请求您设备的拨号权限。如果您拒绝授权提供,将无法使用快捷拨号功能,但不会影响您使用商福通商户通APP的其他服务。

+

2.10设备权限调用汇总

+

我们对商福通商户通APP为您提供服务时,所需要您授权的设备权限汇总如下。注意:您可以拒绝其中部分权限,但将无法使用需要该权限的功能和服务。您可以随时取消已授权的设备权限,不同设备权限显示方式和关闭方式可能有所不同,具体请参考设备及操作系统开发方的说明和操作指引:

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
设备权限对应业务功能功能场景说明取消授权
相机扫一扫收款 与喇叭/云打印机新增、修改 绑定新码1.扫描消费者付款码,使用相机识别二维码。 2.扫描未绑定的码牌时,使用相机识别二维码。 3.获取云打印机/云喇叭设备号时,使用相机识别设备条码该权限允许拒绝或取消授权,不影响APP其他功能
访问照片头像上传 通道申请上传照片1.用户头像上传时我们需要访问您的相册,以便您选取要上传的照片 2.通道申请时上传企业营业执照、法人身份证照片、商户门头照等信息时,我们需要访问您的相册,以便您选取要上传的照片该权限允许拒绝或取消授权,不影响APP其他功能
存储APP稳定运行 下载码牌图片1.日志信息记录、信息缓存 2.下载码牌图片至手机相册中该权限允许拒绝或取消授权,不影响APP其他功能
获取电话状态(设备信息)APP安全运行1.本政策第一部分,2.2条描述该权限允许拒绝或取消授权,不影响APP其他功能
定位门店、辅助终端设备管理1.本政策第一部分,2.5条描述该权限允许拒绝或取消授权,不影响APP其他功能
+

3.征得授权同意的例外

+

根据相关法律法规的规定,在以下情形中,我们可以在不征得您的授权同意的情况下收集、使用一些必要的个人信息:

+

(1)与我们旅行法律法规规定的义务相关的;

+

(2)与国家安全、国防安全直接相关的;

+

(3)与公共安全、公共卫生、重大公共利益直接相关的;

+

(4)与犯罪侦查、起诉、审判和判决执行及相关事项直接相关的;

+

(5)出于维护您或其他个人的生命、财产及相关重大合法权益但有很难得到本人同意的;

+

(6)所收集的个人信息是您自行向社会公众公开的;

+

(7)从合法公开披露的信息中收集到您的客人信息:从合法的新闻报道、政府信息公开等相关渠道;

+

(8)根据您与平台签署的在线协议或合同所必需的;

+

(9)用于维护我们产品和/或服务的安全稳定运行所必需的:发现、处置产品或服务的故障及相关问题处理;

+

(10)法律法规规定的其他情形。

+

二、我们如何共享、转让、公开披露您的个人信息

+

1.共享

+

对于您的个人信息,我们不会与任何公司、组织和个人进行共享,除非存在以下一种或多种情形:

+

(1)事先已获得您的授权;

+

(2)您自行提出的;

+

(3)与商业合作伙伴的必要共享:

+

您理解并知悉,为了向您提供更完善、优质的产品和服务;或由于您在使用商福通商户通中由第三方服务提供企业/机构所提供的服务时的情况下,我们将授权第三方服务提供企业/机构为您提供部分服务。此种情况下,我们可能会与合作伙伴共享您的某些个人信息,其中包括您已授权或自行提出的(包括但不限于商户名称、手机号、法人信息、商户营业执照等)必要信息,以及您在使用本APP时自动产生的某些信息(包括订单、订单金额、交易时间、收款方式、收款金额、门店信息、退款信息)。请您注意、我们仅处于合法、正当、必要、特定、明确的目的共享这些信息。我们将对信息数据的输出形式、流转、使用进行安全评估与处理,以保护数据安全。同时,我们会对合作伙伴、服务商机构进行严格的监督与管理,一但发现其存在违规处理个人信息的行为,将立即停止合作并追究其法律责任。

+

目前,我们的合作伙伴包括以下类型:

+

A.第三方支付机构:当您使用商福通商户通提供的支付业务时,将会使用并通过第三方支付机构的支付通道,其中包括但不限于微信支付、支付宝支付、银联云闪付支付、盛付通等第三方支付平台。我们会与第三方支付机构共享来自于您的部分交易信息。为保障您在使用我们所提供的收款功能/服务时的合理、合规及合法性,在您正式使用前述功能/服务前,您需要向对应的第三方支付机构发起支付通道申请,在此情况下,我们会收集您所主动提供的商户名称、企业名称、法人信息、营业执照、账户信息等必要信息,并将上述信息与第三方支付机构共享。

+

B.消息推送服务供应商:由每日互动股份有限公司提供推送技术服务,我们可能会将您的设备平台、设备厂商、设备品牌、设备识别码等设备信息,应用列表信息、网络信息以及位置相关信息提供给每日互动股份有限公司,用于为您提供消息推送技术服务。我们在向您推送消息时,我们可能会授权每日互动股份有限公司进行链路调节,相互促活被关闭的SDK推送进程,保障您可以及时接收到我们向您推送的消息。详细内容请访问《个推用户隐私政策》

+

当您使用商福通商户通APP的收款通知及语音播报等功能时,为了保证通知的时效性,我们需使用自启动服务以便您能够正常接收通知。如果您关掉自启动,可能会无法正常接收通知。如需关闭,请在手机设置-应用-自启动管理中关闭本APP的自启动权限。具体操作方法可能会因手机系统产生差异,请前往手机品牌操作指南处查看。

+

UniPush模块集成的三方SDK说明:

+ + + + + + + + + + + + + + + + + + + +
SDK名称包名信息使用目的使用的权限涉及个人信息隐私权政策链接
个推·消息推送com.igexin消息推送android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE
android.permission.READ_PHONE_STATE
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.VIBRATE
android.permission.GET_TASKS
android.permission.QUERY_ALL_PACKAGES
存储的个人文件、设备信息(IMEI、MAC、ANDROID_ID、DEVICE_ID、IMSI)、应用已安装列表、网络信息个推用户隐私政策-个推文档中心
+

(4)您可以基于商福通商户通APP与第三人(包括不特定对象)共享您的个人信息或其他信息,但因您的共享行为而导致的信息泄露、被使用及其他相关请何况,与商福通商户通APP无关,商福通商户通不因此承担法律责任。

+

2.转让

+

转让是指将取得您个人信息的控制权转让给其他公司、组织或个人。除非获取您的明确同意,否则我们不会将您的个人信息转让给任何公司、组织或个人。但下述情形除外:

+

(1)已事先征得您的同意;

+

(2)您自行提出的;

+

(3)如果公司发生合并、收购或破产清算,将可能涉及到个人信息转让,此种情况下我们会告知您有关情况并要求新的持有您个人信息的公司、组织继续受本政策的约束。否则我们将要求其重新获取您的明示同意。

+

(4)其他法律法规规定的情形。

+

3.公开披露

+

公开披露是指向社会或不特定人群发布信息的行为。原则上,我们不会对您的个人信息进行公开披露。但下述情况除外:

+

(1)取得您的明示同意后。

+

(2)基于法律的披露:在法律、法律程序、诉讼或政府主管部门强制性要求的情况下,我们会公开披露您的个人信息。

+

4.共享、转让、公开披露个人信息授权同意的例外情形

+

根据相关法律法规的固定,在以下情形中,我们可能在未事先征得您的授权同意的情况下共享、转让、公开披露您的个人信息:

+

(1)与我们履行法律法规规定的义务相关的,含依照法律规定、司法机关或行政机关强制要求向有权机关披露您的个人信息;在该种情况下,我们会要求披露请求方出局与其请求相应的有效法律文件,并对被披露的信息采取符合法律和业界标准的安全防护措施;

+

(2)与国家安全、国防安全直接相关的;

+

(3)与公共安全、公共卫生、重大公共利益直接相关的;

+

(4)与犯罪侦擦、 起诉、审判和判决执行及相关事项直接相关的;

+

(5)出于维护您或其他个人的生命、财产及相关重大合法权益但又很难得到本人同意的;

+

(6)您自行向社会公众公开的个人信息;

+

(7)从合法公开披露的信息中收集到的个人信息:合法的新闻报道、政府信息公开及其他相关渠道;

+

(8)法律法规规定的其他情形。

+

请您了解,根据现行法律规定及监管要求,共享、转让经去标识化处理的个人信息,且确保数据接收方无法复原并重新识别个人信息主体的,无需另行向您通知并征得您的同意。

+

三、我们如何存储和保护您的个人信息

+

1.存储

+

存储地点:我们将从中华人民共和国境内获得的个人信息存放于中华人民共和国境内。如果发生个人信息的跨境传输,我们会单独向您以邮件或通知的方式告知您个人信息处境的目的与接受方,并征得您的同意。我们会严格遵守中华人民共和国法律法规,确保数据接收方有充足的数据能力来保护您的个人信息安全。

+

存储时间:我们承诺始终按照法律的规定在合理必要期限内存储您的个人信息。超出上述期限后,我们将删除您的个人信息或对您的个人信息进行脱敏、去标识化、匿名化处理。

+

如果我们停止运营,我们将立即停止收集您的个人信息,并将停止运营这一决定和/或事实以右键或通知的方式告知您,并对所有已获取的您的个人信息进行删除或匿名化处理。

+

2.保护

+

为了您的个人信息安全,我们将采用各种符合行业标准的安全措施来保护您的个人信息安全,以最大程度降低您的个人信息被损毁、泄露、盗用、非授权方式访问、使用、披露和更改的风险。我们将积极建立数据分类分级制度、数据安全管理规范、数据安全开发规范来管理规范个人信息的采集、存储和使用,确保未收集与我们提供的产品和服务无关的信息。

+

在数据存储安全上,我们与第三方机构合作,包括但不限于阿里云、腾讯云等。

+

为保障您的账户和个人信息的安全,请妥善保管您的账户及密码信息。我们将通过多端服务器备份的方式保障您的信息不丢失、损毁或因不可抗力因素而导致的无法使用。通过第三方存储服务机构提供的堡垒机、安全防火墙等服务,保障您的信息不被滥用、变造和泄露。

+

尽管有上述安全措施,但也请您注意:在信息网络上并不存在绝对“完善的安全措施”。为防止安全事故的发生,我们已按照法律法规规定,制定了妥善的预警机制和应急预案。如确发生安全事件,我们将及时将相关情况以邮件、电话、信函、短信等方式告知您、难以逐一告知单一个体时,我们会采取合理、有效的方式发布公告。同时,我们还将按照监管部门要求,主动上报个人信息安全事件的处置情况、紧密配合政府机关的工作。

+

当我们的产品或服务发生停止运营的情况下,我们将立即停止收集您的个人信息,并将停止运营这一决定和/或事实以邮件或通知的方式告知您,并对所有已获取的您的个人信息进行删除或匿名化处理。

+

3.匿名化处理

+

为保障我们已收集到的您的个人信息的安全,当我们不再提供服务、停止运营或因其他不可抗力因素而不得不销毁您的个人信息的情况下。我们将会采取删除或匿名化的方式处理您的个人信息。

+

匿名化是指通过对个人信息的技术处理,使个人信息的主体无法被识别,且处理后无法被复原的过程。严格意义上,匿名化后的信息不属于个人信息。

+

四、您如何管理您的个人信息

+

1.自主决定授权信息

+

您可以自主决定是否授权我们向您申请的某些设备权限,具体请参考第一条,2.10所述。

+

注意:根据不同的操作系统及硬件设备,您管理这些权限的方式可能会有所不同,具体操作方式,请参照您的设备或操作系统开发方的说明和操作指引。

+

2.访问、获取、更改和删除相关信息

+

您可以通过交互本APP的交互界面对相关信息进行访问、获取、更改和删除。

+

(1)您登录账户的名称和头像:

+

您可以通过在“我的”页面,通过点击头像一栏的按钮进入修改个人信息页面,对个人名称进行查看和修改。通过点击个人头像,查看您的账户头像,授权我们访问您的相册或相机后,您可以更改您的账户头像。

+

(2)门店信息:

+

您可以在“首页-门店管理”页面,通过点击门店列表中的单个门店进入所选门店的编辑页面,对门店名称和备注信息进行查看和修改。通过点击状态条目中的开关按钮,您可以启用或禁用所选门店的状态。

+

(3)云喇叭/云打印机/码牌/扫码POS/辅助终端设备信息:

+

您可以在“我的-设备管理-云喇叭管理/云打印管理/码牌/扫码POS/辅助终端设备”页面,通过点击设备列表中的单个云喇叭/云打印机进入所选设备的编辑页面,对设备名称、设备编号、所属门店等信息进行查看和修改。通过点击状态条目中的开关按钮,您可以启用或禁用所选设备的状态。

+

五、您如何注销您的账号

+

您可以通过第九条中指明的联系方式联系我们,或在本APP的”我的-设置-其他设置-注销账号“页面提供的联系方式联系我们,并向我们阐明您注销账号的原因。在满足账号注销的条件下,我们将尽快注销您的账号。注意:由于您账号在使用期间内产生的交易信息将不会被立刻处理,而是需要经过确认、复查后,确保该笔交易已完成所有流程后,进行脱敏处理。此外,除法律明确规定必须由我们保留的个人信息外,您在使用本APP期间内所产生或由您提交的其他个人信息将会被删除或匿名化处理,且该处理不可逆,您将无法找回这些个人信息。

+

六、有关第三方提供产品和/或服务的特别说明

+

您在使用商福通商户通APP时,可能会使用到由第三方提供的产品和/或服务,在这种情况下,您需要接受该第三方的服务条款及隐私政策(而非本隐私政策)的约束,您需要仔细阅读其条款并自行决定是否接受。请您妥善保管您的个人信息,仅在必要的情况下向他人提供。本政策仅适用于我们所收集、保存、使用、共享、披露信息,并不适用于任何第三方提供服务时(包含您向该第三方提供的任何个人信息)或第三方信息的使用规则,第三方使用您的个人信息时的行为,由其自行负责。

+

七、我们如何使用Cookie和其他同类技术

+

在您未拒绝接受cookies的情况下,我们会在您的计算机以及相关移动设备上设定或取用cookies,以便您能登录或使用依赖于cookies的商福通商户通的产品与/或服务。您有权选择接受或拒绝接受cookies。您可以通过修改浏览器设置的方式或在移动设备设置中设置拒绝我们使用cookies。若您拒绝使用cookies,则您可能无法登录或使用依赖于cookies的商福通商户通App网络服务或功能。

+

八、更新隐私政策

+

我们保留更新或修订本隐私政策的权力。这些修订或更新构成本政策的一部分,并具有等同于本政策的效。未经您的同意,我们不会削减您依据当前生效的本政策所应享受的权利。

+

我们会不时更新本政策,如遇本政策更新,我们会通过APP通知等相关合理方式通知您,如遇重大更新,您需要重新仔细阅读、充分理解并同意修订更新后的政策,才可继续使用我们所提供的产品和/或服务。

+

九、联系我们

+

如果您对本政策有任何疑问,您可以通过以下方式联系我们,我们将尽快审核所涉问题,并在验证您的用户身份后予以答复。

+

网站:www.jeequan.com

+

十、其他

+

如果您认为我们的个人信息处理行为损害了您的合法权益,您可以向有关政府部门进行反应。或因本政策以及我们处理您个人信息事宜引起的任何争议,您可以诉至沧州市人民法院。

+
+ + \ No newline at end of file diff --git a/static/right.svg b/static/right.svg new file mode 100644 index 0000000..e9e9af6 --- /dev/null +++ b/static/right.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/service.html b/static/service.html new file mode 100644 index 0000000..e36bf41 --- /dev/null +++ b/static/service.html @@ -0,0 +1,1299 @@ + + + + + + 服务协议 + + + + + + + + +

用户服务协议

+

感谢您使用商福通付产品,在使用“商福通商户通”、“商福通展业宝”、“商福通店管家”、“商福通付商户系统”、“商福通付代理商系统”、“商福通付门店系统”等软件及相关服务前,请您认真阅读本协议,并确认承诺同意遵守本协议的全部约定。本协议由您与商福通科技(河北)有限公司(包括其关联机构,以下合成“本公司”)于您点击同意本协议之时,在河北省沧州市签署并生效。

+

一、协议条款的确认及接受

+

1.商福通付(包括网址为www.xxx.com 的网站,以及可在IOS系统及Android 系统中运行的名为“商福通商户通APP”、“商福通展业宝APP”、“商福通店管家APP”及其他不同版本的应用程序,以及名为“商福通商户通”、“商福通展业宝”、“商福通店管家APP”的微信小程序,以下简称"本网站"或“商福通付”)由商福通科技(河北)有限公司(包括其关联机构,以下合称“本公司”)运营并享有完全的所有权及知识产权等权益,商福通付提供的服务将完全按照其发布的条款和操作规则严格执行。

+

2.您确认同意本协议(协议文本包括《商福通付用户服务协议》、《商福通付用户隐私政策》及商福通付已公示或将来公示的各项规则及提示,所有前述协议、规则及提示乃不可分割的整体,具有同等法律效力,共同构成用户使用商福通付及相关服务的整体协议,以下合称“本协议”)所有条款并完成注册程序时,本协议在您于本公司间成立并发生法律效力,同时您成为商福通付正式用户。

+

二、账号注册及使用规则

+

1.当您使用“商福通商户通”APP和/或小程序,及“商福通付商户系统”时,您可以在APP/微信小程序中的注册页,或在地址为https://mch.s.jeepay.vip/register的网页进行注册,注册成功后,商福通付将给与您一个商户账号及相应的密码,该商户账号和密码由您负责保管,您应当对以其商户账号进行的所有活动和事件负法律责任。

+

1.1.当您使用“商福通展业宝”APP和/或小程序,及“商福通付代理商系统”时,我们会为您创建一个代理商账号并给与您该账号及相应密码。该代理商账号和密码由您负责保管,您应当对以其代理商账号进行的所有活动和事件负法律责任。

+

1.2.当您使用“商福通店管家”APP和/或小程序,及“商福通付门店系统”时,我们或对应商户用户将会为您创建一个门店操作员用户账号,并给与您该账号及相应密码。该门店操作员用户账号和密码由您负责保管,您应当对以其门店操作员账号进行的所有活动和事件负法律责任。

+

2.您须对在商福通付注册信息的真实性、合法性、有效性承担全部责任,您不得冒充他人(包括但不限于冒用他人姓名、名称、字号、头像等足以让人引起混淆的方式,以及冒用他人手机号码)开设账号;不得利用他人的名义发布任何信息;不得利用他人的名义发起任何交易;不得恶意使用注册账户导致他人误认;否则商福通付有权立即停止提供服务,收回账号,并由您独自承担由此而产生的一切法律责任。

+

3.您理解且确认,您在商福通付注册的账号的所有权及有关权益均归本公司所有,您完成注册手续后仅享有该账号的使用权(包括但不限于该账号绑定的由商福通付提供的产品和/或服务)。您的账号仅限于您本人使用,未经本公司书面同意,禁止以任何形式赠与、借用、出租、转让、售卖或以其他任何形式许可他人使用该账号。如果本公司发现或有合理理由认为使用者并非账号初始注册人,公司有权在未通知您的请款修改,暂停或终止向该账号提供服务,并有权注销该账号,而无需向注册该账号的用户承担法律责任。

+

4.您理解并确认,除用于登录、使用本APP相关服务外,您还可以使用您的注册账号登录使用商福通付提供的其他产品和/或服务,以及其他本公司的合作伙伴、第三方服务提供商所提供的软件及服务。若您以商福通付账号登录和/或使用前述服务时,同样应受到其他软件、服务实际提供方的用户协议及其他协议条款的约束。

+

5.您理解并确认,部分由其他第三方平台(包括但不限于银联云闪付、微信支付、支付宝支付、盛付通等)提供的产品及服务,在您使用商福通付提供的产品和/或服务时,仅作为基础服务为您提供。您的商福通付账号与您在上述第三方平台注册的第三方平台账号仅在技术层面上构成单方面绑定。如果您不使用/不继续使用商福通付提供的产品和/或服务,您的第三方平台账号均不会受到影响,您可以继续第三方平台提供的产品及服务。

+

6.您承诺不得以任何方式利用商福通付直接或间接从事违反中国法律、社会公德的行为,商福通付有权对违反上述承诺的内容予以屏蔽、留证,并将由您独自承担由此而产生的一切法律责任。

+

7.您不得利用本网站制作、上传、复制、发布、传播或转载如下内容:

+

(1)反对宪法所确定的基本原则的;

+

(2)危害国家安全,泄露国家秘密,颠覆国家政权,破坏国家统一的;

+

(3)损害国家荣誉和利益的;

+

(4)煽动民族仇恨、民族歧视,破坏民族团结的;

+

(5)破坏国家宗教政策,宣扬邪教和封建迷信的;

+

(6)散布谣言,扰乱社会秩序,破坏社会稳定的;

+

(7)散布淫秽、色情、赌博、暴力、凶杀、恐怖或者教唆犯罪的;

+

(8)侮辱或者诽谤他人,侵害他人合法权益的;

+

(9)侵害未成年人合法权益或者损害未成年人身心健康的;

+

(10)含有法律、行政法规禁止的其他内容的信息。

+

8.商福通付有权对您使用我们的产品和/或服务时的情况进行审查和监督,如您在使用商福通付时违反任何上述规定,本公司有权暂停或终止对您提供服务,以减轻您的不当行为所造成的影响。

+

三、服务内容

+

1.本公司可能为不同的终端设备及使用需求开发不同的应用程序软件版本,您应当更具实际设备需求状况获取、下载、安装合适的版本。

+

2.本网站的服务具体内容根据实际情况提供,商福通付保留变更、中断或终止部分或全部服务的权力。商福通付不承担因业务调整给您造成的损失。除非本协议另有其他明示规定,增加或强化目前本网站的任何新功能,包括所推出的新产品,均受到本协议之规范。您了解并同意,本网站服务仅依其当前所呈现的状况提供,对于任何用户通讯或个人化设定之时效、删除、传递错误、未予储存或其他任何问题,商福通付均不承担任何责任。如您不接受服务调整,请停止使用本服务;否则,您的继续使用行为将被视为其对调整服务的完全同意且承诺遵守。

+

3.商福通付在提供服务时, 可能会对部分服务的用户收取一定的费用或交易佣金。在此情况下,商福通付会在相关页面上做明确的提示。如您拒绝支付该等费用,则不能使用相关的服务。

+

4.您理解,商福通付仅提供相应的服务,除此外与相关服务有关的设备(如电脑、移动设备、调制解调器及其他与接入互联网有关的装置)及所需的费用(如电话费、上网费等)均应由您自行负担。

+

5.商福通付提供的服务可能包括:文字、软件、声音、图片、视频、数据统计、图表、支付通道等。所有这些内容均受著作权、商标和其他财产所有权法律保护。您只有在获得商福通付或其他相关权利人的授权之后才能使用这些内容,不能擅自复制、再造这些内容、或创造与内容有关的派生产品。

+

四、知识产权

+

1.本公司在商福通付软件及相关服务中提供的内容(包括但不限于软件、技术、程序、网页、文字、图片、图像、商标、标识、音频、视频、图表、版面设计、电子文档等,未申明版权或网络上公开的无版权内容除外)的知识产权属于本公司所有。同时本公司提供服务所依托的软件著作权、专利权、商标及其他知识产权均归本公司所有。未经本公司许可,任何人不得擅自使用。

+

2.请您在任何情况下都不要私自使用本公司的包括但不限于“商福通”、“商福通支付”、“商福通付”、“xxx”、“xxx.cn”、“xxx.com”、“jeequan”和“jeequan.com”等在内的任何商标、服务标记、商号、域名、网站名称或其他显著品牌特征等(以下统称为“标识”)。未经本公司事先书面同意,您不得将本条款前述标识以单独或结合任何方式展示、使用或申请注册商标、进行域名注册等,也不得实时向他人明示或暗示有权展示、使用或其他有权处理这些标识的行为。由于您违反本协议使用公司上述商标、标识等给本公司或他人造成损失的,由您承担全部法律责任。

+

五、用户授权及隐私保护

+

商福通付尊重并保护所有商福通付用户的个人信息及隐私安全。为了给您提供更准确、更有个性化的服务,商福通付依据《中华人民共和国网络安全法》、《信息安全技术 个人信息安全规范》以及其他相关法律法规和技术规范明确了本公司收集/使用/披露您的个人信息的原则。详情请参照《隐私协议》

+

六、免责声明

+

1.商福通付不担保本网站服务一定能满足您的要求,也不担保本网站服务不会中断,对本网站服务的及时性、安全性、准确性、真实性、完整性也都不作担保。

+

2.对于因不可抗力或本公司不能控制的原因造成的本网站服务中断或其他缺陷,本网站不承担任何责任,但本公司将尽力减少因此而给您造成的损失和影响。

+

3.对于您利用商福通付或本公司发布的其他产品和/或服务,进行违法犯罪,或进行任何违反中国法律、社会公德的行为,本公司有权立即停止对您提供服务,并将由您独自承担由此产生的一切法律责任。

+

七、违约责任

+

1.针对您违反本协议或其他服务条款的行为,本公司有权独立判断并视情况采取预先警示、限制帐号部分或者全部功能直至永久关闭帐号等措施。本公司有权公告处理结果,且有权根据实际情况决定是否恢复使用。对涉嫌违反法律法规、涉嫌违法犯罪的行为将保存有关记录,并依法向有关主管部门报告、配合有关主管部门调查。

+

八、协议修改

+

1.我们有权根据法律法规政策、国家有权机构或公司经营要求修改本协议的有关条款,我们会通过适当的方式在网站或产品上予以公示。

+

2.若您不同意我们对本协议相关条款所做的修改,您有权停止使用本网站服务。如果您继续使用本网站服务,则视为您接受本公司对本协议相关条款所做的修改。

+
+ + \ No newline at end of file diff --git a/static/startImg/mch-name.svg b/static/startImg/mch-name.svg new file mode 100644 index 0000000..86a98c9 --- /dev/null +++ b/static/startImg/mch-name.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/static/startImg/start-bg.svg b/static/startImg/start-bg.svg new file mode 100644 index 0000000..069737d --- /dev/null +++ b/static/startImg/start-bg.svg @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/static/tabImg/index-select.png b/static/tabImg/index-select.png new file mode 100644 index 0000000..28685e9 Binary files /dev/null and b/static/tabImg/index-select.png differ diff --git a/static/tabImg/index.png b/static/tabImg/index.png new file mode 100644 index 0000000..377d634 Binary files /dev/null and b/static/tabImg/index.png differ diff --git a/static/tabImg/order-select.png b/static/tabImg/order-select.png new file mode 100644 index 0000000..b198332 Binary files /dev/null and b/static/tabImg/order-select.png differ diff --git a/static/tabImg/order.png b/static/tabImg/order.png new file mode 100644 index 0000000..1057b40 Binary files /dev/null and b/static/tabImg/order.png differ diff --git a/static/tabImg/user-select.png b/static/tabImg/user-select.png new file mode 100644 index 0000000..3130e23 Binary files /dev/null and b/static/tabImg/user-select.png differ diff --git a/static/tabImg/user.png b/static/tabImg/user.png new file mode 100644 index 0000000..07d5c3d Binary files /dev/null and b/static/tabImg/user.png differ diff --git a/static/uni.png b/static/uni.png new file mode 100644 index 0000000..8e3a80f Binary files /dev/null and b/static/uni.png differ diff --git a/uni.scss b/uni.scss new file mode 100644 index 0000000..5eba1a6 --- /dev/null +++ b/uni.scss @@ -0,0 +1,25 @@ +/** + * uni.scss是一个特殊文件,在代码中无需 import 这个文件即可在scss代码中使用这里的样式变量。 + * 每个scss文件都被注入这个uni.scss + * 规范: 该文件只用作,调整uni官方定义的 变量。 其他的请在App.vue中自行引入。 + **/ + +/* 引入 uni-ui 组件库的 uni-scss样式。 若不引入则无法使用: $uni-primary 主题色等变量。 */ +@import "@/uni_modules/uni-scss/variables.scss"; + +/* 修改 【 uni-ui 】 主题色 */ +$uni-primary: #00aeff; +$uni-primary-disable:mix(#fff,$uni-primary,50%); +$uni-primary-light: mix(#fff,$uni-primary,80%); + +/** 定义 本系统的 全局 背景色, 默认蓝色渐变 */ +// 原始颜色: linear-gradient(270deg, rgba(35, 143, 252, 1) 0%, rgba(26, 102, 255, 1) 100%); +$jeepay-bg-primary: linear-gradient(270deg, rgba(35, 143, 252, 1) 0%, rgba(26, 102, 255, 1) 100%); + +/* uni.scss */ +@import 'uview-plus/theme.scss'; +/** 系统级别: 自定义变量 */ +@import "@/commons/style/vars.scss"; + + + diff --git a/uni_modules/iRainna-dayjs/changelog.md b/uni_modules/iRainna-dayjs/changelog.md new file mode 100644 index 0000000..c434fbc --- /dev/null +++ b/uni_modules/iRainna-dayjs/changelog.md @@ -0,0 +1,2 @@ +## 1.0.0(2023-09-19) +first diff --git a/uni_modules/iRainna-dayjs/js_sdk/dayjs.min.js b/uni_modules/iRainna-dayjs/js_sdk/dayjs.min.js new file mode 100644 index 0000000..0eecdfb --- /dev/null +++ b/uni_modules/iRainna-dayjs/js_sdk/dayjs.min.js @@ -0,0 +1 @@ +const fn=function(){"use strict";var t=1e3,e=6e4,n=36e5,r="millisecond",i="second",s="minute",u="hour",a="day",o="week",c="month",f="quarter",h="year",d="date",l="Invalid Date",$=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,y=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,M={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function(t){var e=["th","st","nd","rd"],n=t%100;return"["+t+(e[(n-20)%10]||e[n]||e[0])+"]"}},m=function(t,e,n){var r=String(t);return!r||r.length>=e?t:""+Array(e+1-r.length).join(n)+t},v={s:m,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),i=n%60;return(e<=0?"+":"-")+m(r,2,"0")+":"+m(i,2,"0")},m:function t(e,n){if(e.date()1)return t(u[0])}else{var a=e.name;D[a]=e,i=a}return!r&&i&&(g=i),i||!r&&g},w=function(t,e){if(p(t))return t.clone();var n="object"==typeof e?e:{};return n.date=t,n.args=arguments,new b(n)},O=v;O.l=S,O.i=p,O.w=function(t,e){return w(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var b=function(){function M(t){this.$L=S(t.locale,null,!0),this.parse(t)}var m=M.prototype;return m.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(O.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var r=e.match($);if(r){var i=r[2]-1||0,s=(r[7]||"0").substring(0,3);return n?new Date(Date.UTC(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)):new Date(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)}}return new Date(e)}(t),this.$x=t.x||{},this.init()},m.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},m.$utils=function(){return O},m.isValid=function(){return!(this.$d.toString()===l)},m.isSame=function(t,e){var n=w(t);return this.startOf(e)<=n&&n<=this.endOf(e)},m.isAfter=function(t,e){return w(t)() + private lunarMonthDaysMap = new Map() + constructor() { } + /** + * 传入农历数字月份返回汉语通俗表示法 + * @param lunar month + * @return Cn string + * @eg:let cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月' + */ + toChinaMonth(m : number, leap : boolean = false) : string { // 月 => \u6708 + return leap ? (N_STR_3[4] + N_STR_3[m] + N_STR_3[0]) : (N_STR_3[m] + N_STR_3[0]); + } + + /** + * 传入农历日期数字返回汉字表示法 + * @param lunar day + * @return Cn string + * @eg:let cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一' + */ + toChinaDay(d : number) : string { // 日 => \u65e5 + let s : string + switch (d) { + case 10: + s = '\u521d\u5341'; + break + case 20: + s = '\u4e8c\u5341'; + break + case 30: + s = '\u4e09\u5341'; + break + default: + s = N_STR_2[Math.floor(d / 10)] + s += N_STR_1[d % 10] + } + return (s) + } + + + /** + * 返回农历y年闰月是哪个月;若y年没有闰月 则返回0 + * @param lunar Year + * @return Number (0-12) + * @eg:let leapMonth = calendar.leapMonth(1987) ;//leapMonth=6 + */ + leapMonth(year : number) : number { + return lunarYears[year - 1900] & 0xF; + } + + /** + * 返回农历y年闰月的天数 若该年没有闰月则返回0 + * @param lunar Year + * @return Number (0、29、30) + * @eg:let leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29 + */ + leapDays(year : number) : number { + if (this.leapMonth(year) > 0) { + return (lunarYears[year - 1900] & 0x10000) != 0 ? 30 : 29; + } + return 0; + } + + // 某年份农历各月天数 + lunarMonthDays(year : number) : number[] { + + let monthDays = this.lunarMonthDaysMap.get(year) + if (monthDays != null) { + return monthDays + } + + monthDays = []; + + let lunarYear = lunarYears[year - 1900]; + + for (let i = 15; i >= 4; i--) { + let monthDay = (lunarYear >> i & 0x1) != 0 ? 30 : 29; + monthDays.push(monthDay); + } + + // 添加闰月 + let leapM = this.leapMonth(year); + + if (leapM > 0) monthDays.splice(leapM, 0, this.leapDays(year)); + this.lunarMonthDaysMap.set(year, monthDays) + + return monthDays; + } + + + // 某年农历天数 + lunarYearDays(year : number) : number { + if (this.lunarYearDaysMap.has(year)) { + return this.lunarYearDaysMap.get(year)! + } + let num = 0; + this.lunarMonthDays(year).forEach(item => { + num += item; + }); + this.lunarYearDaysMap.set(year, num) + return num; + + } + + + /** + * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON + * @param y solar year + * @param m solar month + * @param d solar day + * @return JSON object + * @eg:console.log(calendar.solar2lunar(1987,11,01)); + */ + solar2lunar(y : number, m : number, d : number) : LunarInfoType { // 参数区间1900.1.31~2100.12.31 + let moonDay = this.solar_date(y, m, d); + let lYear = moonDay.lunarY + let lMonth = moonDay.lunarM + let lDay = moonDay.lunarD + let isLeap = moonDay.isLeap + + // 计算农历日期 + const IMonthCn = this.toChinaMonth(lMonth, isLeap) + + let IDayCn = lDay == 1 ? IMonthCn : this.toChinaDay(lDay) + + // 是否今天 + let isTodayObj = new Date() + let isToday = false + if (isTodayObj.getFullYear() == y && isTodayObj.getMonth() + 1 == m && isTodayObj.getDate() == d) { + isToday = true + } + + let info : LunarInfoType = { + 'lYear': lYear, + 'lMonth': lMonth, + 'lDay': lDay, + 'IMonthCn': IMonthCn, + 'IDayCn': IDayCn, + 'cYear': y, + 'cMonth': m, + 'cDay': d, + 'isToday': isToday, + 'isLeap': isLeap, + } + return info + } + + solar_date(y : number, m : number, d : number) : InfoType { // 参数区间1900.1.31~2100.12.31 + + let date = new Date(y, m - 1, d); + + // 参照日期 1901-02-19 正月初一 + let offset = (Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()) - Date.UTC(1901, 1, 19)) / 86400000; + let temp = 0 + let i : number; + for (i = 1901; i < 2101 && offset > 0; i++) { + temp = this.lunarYearDays(i); + offset -= temp; + } + if (offset < 0) { + offset += temp; + i--; + } + + // 农历年、月、日 + let isLeap : boolean = false + let j : number = 0; + let monthDays = this.lunarMonthDays(i); + let leapM = this.leapMonth(i); + + if (offset > 0) { + for (j = 0; j < monthDays.length && offset > 0; j++) { + temp = monthDays[j]; + offset -= temp; + } + if (offset == 0) { + j++; + } + if (offset < 0) { + offset += temp; + } + } else { + // 补偿公历1901年2月的农历信息 + if (offset == -23) { + let info : InfoType = { + lunarY: i, + lunarM: 12, + lunarD: 8, + isLeap: false + } + info = info + } + } + + // 矫正闰年月 + if (leapM > 0) { + if (j == leapM + 1) { + isLeap = true + } + if (j >= leapM + 1) { + j-- + } + } + const info : InfoType = { + lunarY: i, + lunarM: j, + lunarD: ++offset, + isLeap: isLeap + } + + + return info + } +} diff --git a/uni_modules/kux-dayjs/common/constant.uts b/uni_modules/kux-dayjs/common/constant.uts new file mode 100644 index 0000000..7d2933e --- /dev/null +++ b/uni_modules/kux-dayjs/common/constant.uts @@ -0,0 +1,18 @@ +export const WEEKDAYS = Array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'); + +export const MONTHS = Array( + 'Jan', + 'Feb', + 'Mar', + 'Apr', + 'May', + 'Jun', + 'Jul', + 'Aug', + 'Sep', + 'Oct', + 'Nov', + 'Dec' +); + +export const MONTH_DAYS = Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31); \ No newline at end of file diff --git a/uni_modules/kux-dayjs/common/date.uts b/uni_modules/kux-dayjs/common/date.uts new file mode 100644 index 0000000..3cff411 --- /dev/null +++ b/uni_modules/kux-dayjs/common/date.uts @@ -0,0 +1,88 @@ +import { Lunar, LunarInfoType } from './calendar'; + +export type DateType = { + fullDate: string; + year: number; + month: number; + date: number; + hour: number; + minute: number; + second: number; + millisecond: number; + day: number; + isToday: boolean; + lunar: string; +}; + +export class DateUtil { + private lunar: Lunar; + constructor () { + this.lunar = new Lunar(); + }; + + /** + * 计算阴历日期显示 + */ + getlunar (year : number, month : number, date : number) : LunarInfoType { + return this.lunar.solar2lunar(year, month, date) + } + + /** + * 获取任意时间 + */ + getDate (date: string): DateType { + let dd: Date = new Date(); + let hour = 0; + let minute = 0; + let second = 0; + let milllisceond = 0; + + if (date !== '') { + const datePart = date.split(" "); + const dateData = datePart[0].split("-"); + const year = parseInt(dateData[0]); + const month = parseInt(dateData[1]); + const day = parseInt(dateData[2]); + + if (datePart.length > 1) { + const timeData = datePart[1].split(":"); + hour = parseInt(timeData[0]); + minute = parseInt(timeData[1]); + const secondPart = timeData[2].split("."); + second = parseInt(secondPart[0]); + if (secondPart.length > 1) { + milllisceond = parseInt(secondPart[1]); + } + } + + dd = new Date(year, month - 1, day, hour, minute, second, milllisceond); + } + + const y = dd.getFullYear(); + const m = dd.getMonth() + 1; + const d = dd.getDate(); + const h = dd.getHours(); + const M = dd.getMinutes(); + const s = dd.getSeconds(); + const ms = dd.getMilliseconds(); + + let nowDate = y + '-' + m + '-' + d; + const lunarData = this.getlunar(y, m, d); + + const data: DateType = { + fullDate: nowDate, + year: y, + month: m, + date: d, + hour: h, + minute: M, + second: s, + millisecond: ms, + day: dd.getDay() + 1, + lunar: lunarData.IDayCn, + isToday: this.getlunar(y, m, d).isToday + }; + + return data; + }; +}; \ No newline at end of file diff --git a/uni_modules/kux-dayjs/common/index.uts b/uni_modules/kux-dayjs/common/index.uts new file mode 100644 index 0000000..8e426a8 --- /dev/null +++ b/uni_modules/kux-dayjs/common/index.uts @@ -0,0 +1,1302 @@ +import { DateFormat, LunarType, DiffUnit, FromToOptions, DatetimeOptions, IsBetweenContains, DatetimeUnit } from "../utssdk/interface.uts"; +import { Lunar } from './calendar'; +import { DateType, DateUtil } from './date'; +import { MONTHS, WEEKDAYS, MONTH_DAYS } from './constant'; + +class KuxDayjs { + private d: Date + private dd: DateType + private lunar: Lunar + private dateUtil: DateUtil + private dateStr: string + constructor (date: string = '') { + this.dateStr = date; + this.lunar = new Lunar(); + this.dateUtil = new DateUtil(); + const dd = this.dateUtil.getDate(date); + this.dd = dd; + this.d = new Date(dd.year, dd.month - 1, dd.date, dd.hour, dd.minute, dd.second, dd.millisecond); + } + + /** + * 当前时间对象 + * @description 返回一个基于指定日期和时间的 KuxDayjs 对象 + * @param {string} date 日期时间字符串,比如:'2023-12-12 19:35:35' + */ + dayjs (date: string): KuxDayjs { + this.dateStr = date; + this.lunar = new Lunar(); + this.dateUtil = new DateUtil(); + const dd = this.dateUtil.getDate(date); + this.dd = dd; + this.d = new Date(dd.year, dd.month - 1, dd.date, dd.hour, dd.minute, dd.second, dd.millisecond); + + return this; + } + + /** + * 基于当前时间复制一个 KuxDayjs 对象 + * @returns {KuxDayjs} + * @example + * const a = dayjs(); + * const b = a.clone(); + * // a 和 b 是两个独立的 KuxDayjs 对象 + */ + clone (): KuxDayjs { + return new KuxDayjs(); + } + + /** + * 日期格式化 + * @description 根据传入的占位符返回格式化后的日期 + * @param format 格式,如 'YYYY-MM-DD HH:mm:ss' + * @returns string + */ + format (format: string): string { + const YYYY = `${this.d.getFullYear()}`; + const M = `${this.d.getMonth() + 1}`; + const MM = M.padStart(2, '0'); + const DD = `${this.d.getDate()}`.padStart(2, '0'); + const HH = `${this.d.getHours()}`.padStart(2, '0'); + const mm = `${this.d.getMinutes()}`.padStart(2, '0'); + const ss = `${this.d.getSeconds()}`.padStart(2, '0'); + const SSS = `${this.d.getMilliseconds()}`.padStart(3, '0'); + + // 上午/下午 + let ampm = 'AM'; + let ampmCN = '上午'; + let ampmZN = 'am'; + let formattedHours = HH; + if (Math.abs(parseInt(HH)) >= 12 && (format.includes('A') || format.includes('a') || format.includes('AA'))) { + ampm = 'PM'; + ampmCN = '下午'; + ampmZN = 'pm'; + formattedHours = `${(Math.abs(parseInt(HH)) - 12)}`.padStart(2, '0'); + } + + return format + .replace('YYYY', YYYY) + .replace('MM', MM) + .replace('DD', DD) + .replace('HH', formattedHours) + .replace('mm', mm) + .replace('ss', ss) + .replace('SSS', SSS) + .replace('A', ampm) + .replace('a', ampmZN) + .replace('AA', ampmCN) + } + + /** + * 差异 + * @description 返回指定单位下两个日期时间之间的差异 + * @param {string} date 比较的日期 + * @param {DiffUnit} unit 单位,默认为 `day` + * + week 周,缩写 `w` + * + day 天,缩写 `d` + * + month 月份,缩写 `M` + * + year 年,缩写 `y` + * + hour 小时,缩写 `h` + * + minute 分钟,缩写 `m` + * + second 秒,缩写 `s` + * + millisecond 毫秒,缩写 `ms` + * @param {boolean} strict 严格模式,设置为 `true` 时,会保持浮点数格式 + * @returns number + */ + diff (date: string, unit: DiffUnit = 'day', strict: boolean = false): number { + // 将日期转换为毫秒数 + const time1 = this.d.getTime(); + const dd = this.dateUtil.getDate(date); + const time2 = new Date(dd.year, dd.month - 1, dd.date).getTime(); + + // 计算两个日期的毫秒数差 + const diffInMilliseconds = Math.abs(time1 - time2); + // 秒数差 + const diffSeconds = diffInMilliseconds / 1000; + // 分钟差 + const diffMinutes = diffSeconds / 60; + // 小时差 + const diffHours = diffMinutes / 60; + // 天数差 + const diffDays = diffHours / 24; + // 周数差 + // const diffWeeks = diffDays / 7; + const week1 = Math.ceil((new Date(dd.year, dd.month, dd.date).getDate() - 1) / 7); + const week2 = Math.ceil((this.d.getDate() - 1) / 7); + const diffWeeks = Math.abs(week1 - week2); + // 月数差 + const year1 = dd.year; + const year2 = this.d.getFullYear(); + const month1 = dd.month; + const month2 = this.d.getMonth() + 1; + + const diffMonths = (year1 - year2) * 12 + (month1 - month2); + + // 判断单位 + let data: number; + + switch (unit) { + case 'millisecond': + data = diffInMilliseconds; + break; + case 'ms': + data = diffInMilliseconds; + break; + case 'second': + data = diffSeconds; + break; + case 's': + data = diffSeconds; + break; + case 'minute': + data = diffMinutes; + break; + case 'M': + data = diffMinutes; + break; + case 'hour': + data = diffHours; + break; + case 'h': + data = diffHours; + break; + case 'week': + data = diffWeeks; + break; + case 'w': + data = diffWeeks; + break; + case 'month': + data = diffMonths; + break; + case 'm': + data = diffMonths; + break; + default: + data = diffDays; + break; + } + + if (!strict) { + data = Math.floor(data); + } + + return data; + } + + /** + * 日历时间 + * @description 获取指定年月的日历面板数据 + * @param {number} 年 + * @param {number} 月 + * @returns {DateFormat} 返回数据 + */ + calendar (year: number = 0, month: number = 0): DateFormat[] { + let outDate: DateFormat[] = []; + let date = new Date(); + let curYear = year; + let curMonth = month; + + if (isNaN(curYear) || curYear < 1900) { + curYear = date.getFullYear(); + } + + if (isNaN(curMonth) || curMonth < 1) { + curMonth = date.getMonth() + 1; + } + + // 获取当月第一天 + const firstDayOfThisMonth = new Date(curYear, curMonth - 1, 1); + const preMonthDay = firstDayOfThisMonth.getDay(); + // 获取上月的最后一天,即本月第0天 + const lastDayOfPreMonth = new Date(curYear, curMonth - 1, 0); + const lastDateOfLastMonth = lastDayOfPreMonth.getDate(); + // 获取本月最后一天,即下月第0天 + const lastDayOfThisMonth = new Date(curYear, curMonth, 0); + const lastDateOfThisMonth = lastDayOfThisMonth.getDate(); + + // 获取周日期数据,一个月最多跨6周,即6 * 7格式排版 + for (let i = 0; i < 6 * 7; i++) { + // 获取当前排序日期 + let thisYear: number = curYear, + thisMonth: number = curMonth, + dateN: number = i + 1 - preMonthDay, + cursorDate: number = dateN; + + if (dateN <= 0) { + thisMonth -= 1; + cursorDate = dateN + lastDateOfLastMonth; + } else if (dateN > lastDateOfThisMonth) { + // date大于本月最后一天为下月预留天数 + thisMonth += 1; + cursorDate = dateN - lastDateOfThisMonth; + } + + if (thisMonth == 13) { + thisMonth = 1; + thisYear += 1; + } + if (thisMonth == 0) { + thisMonth = 12; + thisYear -= 1; + } + + // 计算该日期与当前时间的天数差 + // const diffInDays = this.diff() + const startDate = new Date(thisYear, thisMonth - 1, cursorDate); + const endDate = new Date(this.d.getFullYear(), this.d.getMonth(), this.d.getDate()); + const fullDate = `${thisYear}-${`${thisMonth}`.padStart(2, '0')}-${`${cursorDate}`.padStart(2, '0')}`; + + let diffInDays = this.diff(fullDate); + // let diffInDays = 0; + + if (startDate.getTime() < endDate.getTime()) { + diffInDays *= -1; + } + + outDate.push({ + year: thisYear, + month: thisMonth, + date: cursorDate, + isToday: this.dateUtil.getlunar(thisYear, thisMonth, cursorDate).isToday, + diffDays: diffInDays, + render: {}, + lunar: { + month: this.lunar.toChinaMonth(this.lunar.solar_date(thisYear, thisMonth, cursorDate).lunarM), + date: this.lunar.toChinaDay(this.lunar.solar_date(thisYear, thisMonth, cursorDate).lunarD) + } as LunarType, + fullLunar: this.lunar.solar_date(thisYear, thisMonth, cursorDate), + fullDate + } as DateFormat) + } + + return outDate; + } + + /** + * 获取/设置毫秒数 + * @description 获取或设置毫秒 + * @param {number} ms 0-999的毫秒数,如果大于-1就是设置操作,否则为获取操作 + * @returns {number} 返回0-999的毫秒数 + */ + millisecond (ms: number = -1): number { + if (ms > -1) { + return this.d.getTime(); + } + + return this.d.setMilliseconds(ms); + } + + /** + * 获取/设置秒数 + * @description 获取或设置秒 + * @param {number} s 0-59的秒数,如果大于-1就是设置操作,否则为获取操作 + * @returns {number} 返回0-59的秒数 + */ + second (s: number = -1): number { + if (s > -1) { + return this.d.setSeconds(s); + } + + return this.d.getSeconds(); + } + + /** + * 获取/设置分钟 + * @description 获取或设置分钟 + * @param {number} M 0-59的分钟数,如果大于-1就是设置操作,否则为获取操作 + * @returns {number} 返回0-59的分钟数 + */ + minute (M: number = -1): number { + if (M > -1) { + return this.d.setMinutes(M); + } + + return this.d.getMinutes(); + } + + /** + * 获取/设置小时 + * @description 获取或设置小时 + * @param {number} h 0-23的小时数,如果大于-1就是设置操作,否则为获取操作 + * @returns {number} 返回0-23的小时数 + */ + hour (h: number = -1): number { + if (h > -1) { + return this.d.setHours(h); + } + + return this.d.getHours(); + } + + /** + * 获取/设置日期 + * @description 获取或设置日期 + * @param {number} d 日期数,传入参数就是设置操作,否则为获取操作。如果为 d 指定 0,那么日期就会被设置为上个月的最后一天。如果 d 被设置为负数,日期会设置为上个月最后一天往前数这个负数绝对值天数后的日期。-1 会设置为上月最后一天的前一天(译者注:例如当前为 4 月,如果 date(-2),则为 3 月 29 日) + * @returns {number} 返回1-31的日期数 + */ + date (d?: number): number { + if (!isNaN(parseInt(`${d}`))) { + return this.d.setDate(parseInt(`${d}`)); + } + + return this.d.getDate(); + } + + /** + * 获取星期几,0 表示星期天。目前仅支持获取,不支持设置操作 + * @description 获取或设置星期 + * @returns {number} 返回0-6的整数,0代表星期日,1代表星期一,以此类推。 + */ + day (): number { + return this.d.getDay(); + } + + /** + * 获取/设置时间 + * @description 获取或设置毫秒 + * @param {number} t 一个整数,表示从 1970-1-1 00:00:00 UTC 开始计时的毫秒数。 传入参数就是设置操作,否则为获取操作。 + * @returns {number} 返回UTC 1970 年 1 月 1 日 00:00:00 与更新日期之间的毫秒数(实际上是自变量的值)。 + */ + time (t: number): number { + if (!isNaN(parseInt(`${t}`))) { + return this.d.setTime(parseInt(`${t}`)); + } + + return this.d.getTime(); + } + + /** + * 获取/设置月份 + * @description 获取或设置月份 + * @param {number} m 0-11的整数,如果m大于0则为设置操作,否则为获取操作 + * @returns {number} n + * + 获取操作返回0-11的整数(表示一月到十二月)。 + * + 设置操作返回基于 1 January 1970 00:00:00 UTC 开始计算的毫秒数。 + */ + month (m: number = -1): number { + if (m > -1) { + return this.d.setMonth(m); + } + + return this.d.getMonth(); + } + + /** + * 获取/设置年 + * @description 获取或设置年份 + * @param {number} y 大于1969的整数,如果大于1969则为设置操作,否则为获取操作 + * @returns {number} 返回操作后的年份数 + */ + year (y: number = 1969): number { + if (y > 1969) { + return this.d.setFullYear(y); + } + + return this.d.getFullYear(); + } + + /** + * 增加 + * @description 返回增加一定时间的复制的 KuxDayjs 对象 + * @param {string} count 需要增加的整数,支持配合单位操作 + * @param {DiffUnit} unit 单位,默认为 `day` + * + week 周,缩写 `w` + * + day 天,缩写 `d` + * + month 月份,缩写 `M` + * + year 年,缩写 `y` + * + hour 小时,缩写 `h` + * + minute 分钟,缩写 `m` + * + second 秒,缩写 `s` + * + millisecond 毫秒,缩写 `ms` + * @returns {Date} d 操作后的Date对象 + */ + add (count: number = 0, unit: DiffUnit = 'day'): KuxDayjs { + if (count < 0) { + console.warn('【kux-dayjs:add】请输入大于0的数字'); + return this; + } + if (unit === 'day' || unit === 'd') { + this.d.setDate(this.d.getDate() + count); + } else if (unit === 'month' || unit === 'M') { + this.d.setMonth(this.d.getMonth() + count); + } else if (unit === 'year' || unit === 'y') { + this.d.setFullYear(this.d.getFullYear() + count); + } else if (unit === 'week' || unit === 'w') { + this.d.setDate((this.d.getDate() + 7) * count); + } else if (unit === 'hour' || unit === 'h') { + this.d.setHours(this.d.getHours() + count); + } else if (unit === 'minute' || unit === 'm') { + this.d.setMinutes(this.d.getMinutes() + count); + } else if (unit === 'second' || unit === 's') { + this.d.setSeconds(this.d.getSeconds() + count); + } else if (unit === 'millisecond' || unit === 'ms') { + this.d.setMilliseconds(this.d.getMilliseconds() + count); + } + + return this; + } + + /** + * 减去 + * @description 返回减去一定时间的复制的 KuxDayjs 对象 + * @param {string} count 需要减去的整数,支持配合单位操作 + * @param {DiffUnit} unit 单位,默认为 `day` + * + week 周,缩写 `w` + * + day 天,缩写 `d` + * + month 月份,缩写 `M` + * + year 年,缩写 `y` + * + hour 小时,缩写 `h` + * + minute 分钟,缩写 `m` + * + second 秒,缩写 `s` + * + millisecond 毫秒,缩写 `ms` + * @returns {Date} d 操作后的Date对象 + */ + subtract (count: number = 0, unit: DiffUnit = 'day'): KuxDayjs { + if (count < 0) { + console.warn('【kux-dayjs:subtract】请输入大于0的数字'); + return this; + } + if (unit === 'day' || unit === 'd') { + this.d.setDate(this.d.getDate() - count); + } else if (unit === 'month' || unit === 'M') { + this.d.setMonth(this.d.getMonth() - count); + } else if (unit === 'year' || unit === 'y') { + this.d.setFullYear(this.d.getFullYear() - count); + } else if (unit === 'week' || unit === 'w') { + this.d.setDate((this.d.getDate() - 7) * count); + } else if (unit === 'hour' || unit === 'h') { + this.d.setHours(this.d.getHours() - count); + } else if (unit === 'minute' || unit === 'm') { + this.d.setMinutes(this.d.getMinutes() - count); + } else if (unit === 'second' || unit === 's') { + this.d.setSeconds(this.d.getSeconds() - count); + } else if (unit === 'millisecond' || unit === 'ms') { + this.d.setMilliseconds(this.d.getMilliseconds() - count); + } + + return this; + } + + /** + * 设置时间为0时0分0秒0毫秒 + */ + private _setTimeStart (): KuxDayjs { + this.d.setHours(0); + this.d.setMinutes(0); + this.d.setSeconds(0); + this.d.setMilliseconds(0); + + return this; + } + + /** + * 设置时间为23时59分59秒999毫秒 + */ + private _setTimeEnd () { + this.d.setHours(23); + this.d.setMinutes(59); + this.d.setSeconds(59); + this.d.setMilliseconds(999); + } + + /** + * 设置时间为今天 + */ + today (): KuxDayjs { + this.d = new Date(); + + return this; + } + + /** + * 时间的开始 + * @description 返回复制的 KuxDayjs 对象,并设置到一个时间的开始。 + * @param {DiffUnit} unit 单位 + * + week 周,缩写 `w` + * + day 天,缩写 `d` + * + month 月份,缩写 `M` + * + year 年,缩写 `y` + * + hour 小时,缩写 `h` + * + minute 分钟,缩写 `m` + * + second 秒,缩写 `s` + * @returns {Date} d 操作后的Date对象 + */ + startOf (unit: DiffUnit): KuxDayjs { + this.today(); + + if (unit === 'week' || unit === 'w') { + const day = this.d.getDay(); + this.d.setDate((this.d.getDate() - day + (day == 0 ? -6 : 1))); + this._setTimeStart(); + } else if (unit === 'day' || unit === 'd') { + this._setTimeStart(); + } else if (unit === 'month' || unit === 'M') { + this.d.setDate(1); + this._setTimeStart(); + } else if (unit === 'year' || unit === 'y') { + this.d.setMonth(0); + this.d.setDate(1); + this._setTimeStart(); + } else if (unit === 'hour' || unit === 'h') { + this.d.setMinutes(0); + this.d.setSeconds(0); + this.d.setMilliseconds(0); + } else if (unit === 'minute' || unit === 'm') { + this.d.setSeconds(0); + this.d.setMilliseconds(0); + } else if (unit === 'second' || unit === 's') { + this.d.setMilliseconds(0); + } + + return this; + } + + /** + * 时间的结束 + * @description 返回复制的 KuxDayjs 对象,并设置到一个时间的末尾。 + * @param {DiffUnit} unit 单位 + * + week 周,缩写 `w` + * + day 天,缩写 `d` + * + month 月份,缩写 `M` + * + year 年,缩写 `y` + * + hour 小时,缩写 `h` + * + minute 分钟,缩写 `m` + * + second 秒,缩写 `s` + * @returns {Date} d 操作后的Date对象 + */ + endOf (unit: DiffUnit): KuxDayjs { + this.today(); + + if (unit === 'week' || unit === 'w') { + const day = this.d.getDay(); + this.d.setDate(this.d.getDate() + (7 - day)); + this._setTimeEnd(); + } else if (unit === 'day' || unit === 'd') { + this._setTimeEnd(); + } else if (unit === 'month' || unit === 'M') { + const year = this.d.getFullYear(); + const month = this.d.getMonth() + 1; + this.d = new Date(year, month, 0); + this._setTimeEnd(); + } else if (unit === 'year' || unit === 'y') { + const year = this.d.getFullYear(); + this.d = new Date(year, 11, 31); + this._setTimeEnd(); + } else if (unit === 'hour' || unit === 'h') { + this.d.setMinutes(59); + this.d.setSeconds(59); + this.d.setMilliseconds(999); + } else if (unit === 'minute' || unit === 'm') { + this.d.setSeconds(59); + this.d.setMilliseconds(999); + } else if (unit === 'second' || unit === 's') { + this.d.setMilliseconds(999); + } + + return this; + }; + + private _fromOrto (date: Date, options: FromToOptions = { + isSuffix: false, + relativeTime: { + s: '', + m: '', + mm: '', + h: '', + hh: '', + d: '', + dd: '', + mon: '', + mons: '', + y: '', + yy: '' + } + } as FromToOptions, type: 'from' | 'to' = 'from'): string { + const now = date.getTime(); + let diff = now - this.d.getTime(); + const diffSeconds = Math.floor(diff / 1000); + const diffMinutes = Math.floor(diffSeconds / 60); + const diffHours = Math.floor(diffMinutes / 60); + const diffDays = Math.floor(diffHours / 24); + const diffMonths = Math.floor(diffDays / 30.44); + const diffYears = Math.floor(diffMonths / 12); + + const isSuffix = options.isSuffix ?? false; + const s = options.relativeTime?.s ?? ''; + const m = options.relativeTime?.m ?? ''; + const mm = options.relativeTime?.mm ?? ''; + const h = options.relativeTime?.h ?? ''; + const hh = options.relativeTime?.hh ?? ''; + const d = options.relativeTime?.d ?? ''; + const dd = options.relativeTime?.dd ?? ''; + const mon = options.relativeTime?.mon ?? ''; + const mons = options.relativeTime?.mons ?? ''; + const y = options.relativeTime?.y ?? ''; + const yy = options.relativeTime?.yy ?? ''; + + let outStr = ''; + let suffix = isSuffix ? '' : (type === 'from' ? '前' : '后'); + + if (diffSeconds > 0 && diffSeconds < 45) { + outStr = `${diffSeconds}秒${suffix}`; + if (s.includes('%s')) { + outStr = s; + outStr = outStr.replace('%s', `${diffSeconds}`); + } + } else if (diffSeconds >= 45 && diffSeconds <= 89) { + outStr = `1分钟${suffix}`; + if (m.includes('%m')) { + outStr = m; + outStr = outStr.replace('%m', `1`); + } + } else if (diffSeconds >= 90 && diffMinutes <= 44) { + outStr = `${diffMinutes}分钟${suffix}`; + if (mm.includes('%mm')) { + outStr = mm; + outStr = outStr.replace('%mm', `${diffMinutes}`); + } + } else if (diffMinutes >= 45 && diffMinutes <= 89) { + outStr = `1小时${suffix}`; + if (h.includes('%h')) { + outStr = h; + outStr = outStr.replace('%h', '1'); + } + } else if (diffMinutes >= 90 && diffHours <= 21) { + outStr = `${diffHours}小时${suffix}`; + if (hh.includes('%hh')) { + outStr = hh; + outStr = outStr.replace('%hh', `${diffHours}`); + } + } else if (diffHours >= 22 && diffHours <= 35) { + outStr = `1天${suffix}`; + if (d.includes('%d')) { + outStr = d; + outStr = outStr.replace('%d', `1`); + } + } else if (diffHours >= 36 && diffDays <= 25) { + outStr = `${diffDays}天${suffix}`; + if (dd.includes('%dd')) { + outStr = dd; + outStr = outStr.replace('%dd', `${diffDays}`); + } + } else if (diffDays >= 26 && diffDays <= 45) { + outStr = `1个月${suffix}`; + if (mon.includes('%mon')) { + outStr = mon; + outStr = outStr.replace('%mon', '1'); + } + } else if (diffDays >= 46 && diffMonths <= 10) { + outStr = `${diffMonths}个月${suffix}`; + if (mons.includes('%mons')) { + outStr = mons; + outStr = outStr.replace('%mons', `${diffMonths}`); + } + } else if (diffMonths >= 11 && diffMonths <= 17) { + outStr = `1年${suffix}`; + if (y.includes('%y')) { + outStr = y; + outStr = outStr.replace('%y', '1'); + } + } else if (diffMonths >= 18) { + outStr = `${diffYears}年${suffix}`; + if (yy.includes('%yy')) { + outStr = yy; + outStr = outStr.replace('%yy', `${diffYears}`); + } + } + + return outStr; + }; + + /** + * 相对当前时间(前) + * @description 返回现在到当前实例的相对时间 + * @param {FromNowOptions} options 配置项 + * + isSuffix - boolean类型,是否自动携带后缀,为true的时候会自动添加“前”后缀,如 1年前;手动指定 `relativeTime` 时该项不生效 + * + relativeTime - RelativeTime类型,自定义格式,支持变量见下方说明 + * | 范围 | 键量 | 使用变量 | 说明 | 示例 | + * | --- | --- | --- | --- | --- | + * | 0 to 44seconds | s | %s | 几秒前 | %s seconds ago | + * | 45 to 89 seconds | m | %m | 1分钟前 | %m minute ago | + * | 90 seconds to 44 minutes | mm | %mm | 几分钟前 | %mm minutes ago | + * | 45 to 89 minutes | h | %h | 1小时前 | %h hour ago | + * | 90 minutes to 21 hours | hh | %hh | 几小时前 | %hh hours ago | + * | 22 to 35 hours | d | d | %d | 1天前 | %d day ago | + * | 36 hours to 25 days | dd | %dd | 几天前 | %dd days ago | + * | 26 to 45 days | mon | %mon | 1个月前 | %mon month ago | + * | 46 days to 10 months | mons | %mons | 几个月前 | %mons months ago | + * | 11 months to 17 months | y | %y | 1年前 | %y year ago | + * | 18 months + | yy | %yy | 几年前 | %yy years ago | + * + * @returns string + * + * @example + * ### 基本示例 + * const datetime = dayjs('2021-12-12 15:43:58'); + * console.log(datetime.fromNow()); // 输出 1年前 + * + * ### 自定义格式示例 + * const datetime = dayjs('2021-12-12 15:43:58'); + * const options: FromNowOptions = { + * isSuffix: false, + * relativeTime: { + * y: '%s year ago' + * } as RelativeTime + * }; + * console.log(datetime.fromNow(options)); // 输出 1 year ago + */ + fromNow (options: FromToOptions = { + isSuffix: false, + relativeTime: { + s: '', + m: '', + mm: '', + h: '', + hh: '', + d: '', + dd: '', + mon: '', + mons: '', + y: '', + yy: '' + } + } as FromToOptions): string { + return this._fromOrto(new Date(), options); + }; + + /** + * 相对指定时间(前) + * @description 返回 X 到当前实例的相对时间 + * @param {FromNowOptions} options 配置项 + * + isSuffix - boolean类型,是否自动携带后缀,为true的时候会自动添加“前”后缀,如 1年前;手动指定 `relativeTime` 时该项不生效 + * + relativeTime - RelativeTime类型,自定义格式,支持变量见下方说明 + * | 范围 | 键量 | 使用变量 | 说明 | 示例 | + * | --- | --- | --- | --- | --- | + * | 0 to 44seconds | s | %s | 几秒前 | %s seconds ago | + * | 45 to 89 seconds | m | %m | 1分钟前 | %m minute ago | + * | 90 seconds to 44 minutes | mm | %mm | 几分钟前 | %mm minutes ago | + * | 45 to 89 minutes | h | %h | 1小时前 | %h hour ago | + * | 90 minutes to 21 hours | hh | %hh | 几小时前 | %hh hours ago | + * | 22 to 35 hours | d | d | %d | 1天前 | %d day ago | + * | 36 hours to 25 days | dd | %dd | 几天前 | %dd days ago | + * | 26 to 45 days | mon | %mon | 1个月前 | %mon month ago | + * | 46 days to 10 months | mons | %mons | 几个月前 | %mons months ago | + * | 11 months to 17 months | y | %y | 1年前 | %y year ago | + * | 18 months + | yy | %yy | 几年前 | %yy years ago | + * + * @returns string + * + * @example + * ### 基本示例 + * const datetime = dayjs('2021-12-12 15:43:58'); + * const a = dayjs('2022-12-12'); + * console.log(datetime.from(a)); // 输出 1年前 + * + * ### 自定义格式示例 + * const datetime = dayjs('2021-12-12 15:43:58'); + * const a = dayjs('2022-12-12'); + * const options: FromNowOptions = { + * isSuffix: false, + * relativeTime: { + * y: '%s year ago' + * } as RelativeTime + * }; + * console.log(datetime.from(a, options)); // 输出 1 year ago + */ + from (dayjs: KuxDayjs, options: FromToOptions = { + isSuffix: false, + relativeTime: { + s: '', + m: '', + mm: '', + h: '', + hh: '', + d: '', + dd: '', + mon: '', + mons: '', + y: '', + yy: '' + } + } as FromToOptions): string { + return this._fromOrto(dayjs.d, options); + } + + /** + * 相对当前时间(后) + * @description 返回当前实例到现在的相对时间 + * @param {FromNowOptions} options 配置项 + * + isSuffix - boolean类型,是否自动携带后缀,为true的时候会自动添加“后”后缀,如 1年后;手动指定 `relativeTime` 时该项不生效 + * + relativeTime - RelativeTime类型,自定义格式,支持变量见下方说明 + * | 范围 | 键量 | 使用变量 | 说明 | 示例 | + * | --- | --- | --- | --- | --- | + * | 0 to 44seconds | s | %s | 几秒后 | %s seconds after | + * | 45 to 89 seconds | m | %m | 1分钟后 | %m minute after | + * | 90 seconds to 44 minutes | mm | %mm | 几分钟后 | %mm minutes after | + * | 45 to 89 minutes | h | %h | 1小时后 | %h hour after | + * | 90 minutes to 21 hours | hh | %hh | 几小时后 | %hh hours after | + * | 22 to 35 hours | d | d | %d | 1天后 | %d day after | + * | 36 hours to 25 days | dd | %dd | 几天后 | %dd days after | + * | 26 to 45 days | mon | %mon | 1个月后 | %mon month after | + * | 46 days to 10 months | mons | %mons | 几个月后 | %mons months after | + * | 11 months to 17 months | y | %y | 1年后 | %y year after | + * | 18 months + | yy | %yy | 几年后 | %yy years after | + * + * @returns string + * + * @example + * ### 基本示例 + * const datetime = dayjs('2021-12-12 15:43:58'); + * console.log(datetime.toNow()); // 输出 1年后 + * + * ### 自定义格式示例 + * const datetime = dayjs('2021-12-12 15:43:58'); + * const options: FromToOptions = { + * isSuffix: false, + * relativeTime: { + * y: '%s year after' + * } as RelativeTime + * }; + * console.log(datetime.toNow(options)); // 输出 1 year after + */ + toNow (options: FromToOptions = { + isSuffix: false, + relativeTime: { + s: '', + m: '', + mm: '', + h: '', + hh: '', + d: '', + dd: '', + mon: '', + mons: '', + y: '', + yy: '' + } + } as FromToOptions): string { + return this._fromOrto(new Date(), options); + } + + /** + * 相对指定时间(后) + * @description 返回当前实例到 X 的相对时间 + * @param {FromNowOptions} options 配置项 + * + isSuffix - boolean类型,是否自动携带后缀,为true的时候会自动添加“前”后缀,如 1年后;手动指定 `relativeTime` 时该项不生效 + * + relativeTime - RelativeTime类型,自定义格式,支持变量见下方说明 + * | 范围 | 键量 | 使用变量 | 说明 | 示例 | + * | --- | --- | --- | --- | --- | + * | 0 to 44seconds | s | %s | 几秒后 | %s seconds after | + * | 45 to 89 seconds | m | %m | 1分钟后 | %m minute after | + * | 90 seconds to 44 minutes | mm | %mm | 几分钟后 | %mm minutes after | + * | 45 to 89 minutes | h | %h | 1小时后 | %h hour after | + * | 90 minutes to 21 hours | hh | %hh | 几小时后 | %hh hours after | + * | 22 to 35 hours | d | d | %d | 1天后 | %d day after | + * | 36 hours to 25 days | dd | %dd | 几天后 | %dd days after | + * | 26 to 45 days | mon | %mon | 1个月后 | %mon month after | + * | 46 days to 10 months | mons | %mons | 几个月后 | %mons months after | + * | 11 months to 17 months | y | %y | 1年后 | %y year after | + * | 18 months + | yy | %yy | 几年后 | %yy years after | + * + * @returns string + * + * @example + * ### 基本示例 + * const datetime = dayjs('2021-12-12 15:43:58'); + * const a = dayjs('2022-12-12'); + * console.log(datetime.to(a)); // 输出 1年后 + * + * ### 自定义格式示例 + * const datetime = dayjs('2021-12-12 15:43:58'); + * const a = dayjs('2022-12-12'); + * const options: FromToOptions = { + * isSuffix: false, + * relativeTime: { + * y: '%s year after' + * } as RelativeTime + * }; + * console.log(datetime.to(a, options)); // 输出 1 year after + */ + to (date: KuxDayjs, options: FromToOptions = { + isSuffix: false, + relativeTime: { + s: '', + m: '', + mm: '', + h: '', + hh: '', + d: '', + dd: '', + mon: '', + mons: '', + y: '', + yy: '' + } + } as FromToOptions): string { + return this._fromOrto(date.d, options); + } + + /** + * Unix时间戳(毫秒) + * @description 返回当前实例的 UNIX 时间戳,13位数字,毫秒 + */ + valueOf (): number { + return this.d.getTime(); + } + + /** + * Unix时间戳 + * @description 返回当前实例的 UNIX 时间戳,10位数字,秒。 + */ + unix (): number { + return Math.floor(this.valueOf() / 1000); + } + + /** + * 是否闰年 + * @description 查询 KuxDayjs 对象的年份是否是闰年 + * @returns {boolean} + * @example + * const date = dayjs('2000-01-01'); + * console.log(date.isLeapYear()); // 输出 true + */ + isLeapYear (): boolean { + return (this.dd.year % 4 == 0 && this.dd.year % 100 != 0) || this.dd.year % 400 == 0; + } + + /** + * 获取月天数 + * @description 获取当前月份包含的天数 + * @example + * const date = dayjs('2023-12-12'); + * console.log(date.daysInMonth()); // 输出 31 + */ + daysInMonth (): number { + + // 如果是闰年,2月有 29 天 + if (this.dd.month == 2 && this.isLeapYear()) { + return 29; + } + + return MONTH_DAYS[this.dd.month - 1]; + } + + /** + * 转Date + * @description 从KuxDayjs中获取原生的Date对象 + */ + toDate (): Date { + return this.d; + } + + /** + * 转数组 + * @description 返回一个包含各个时间信息的 Array + * @example + * const datetime = dayjs('2023-12-13 10:16:18'); + * console.log(datetime.toArray()); // 输出 [2023,12,13,10,16,18,0] + */ + toArray(): number[] { + return Array(this.dd.year, this.dd.month, this.dd.date, this.dd.hour, this.dd.minute, this.dd.second, this.dd.millisecond); + } + + /** + * 转JSON + * @description 序列化为 ISO 8601 格式的字符串 + * @example + * const datetime = dayjs('2023-12-13 10:16:18'); + * console.log(datetime.toJSON()); // 输出 2023-12-13T10:16:18.000Z + */ + toJSON(): string { + const year = `${this.dd.year}`.padStart(2, '0'); + const month = `${this.dd.month}`.padStart(2, '0'); + const date = `${this.dd.date}`.padStart(2, '0'); + const hours = `${this.dd.hour}`.padStart(2, '0'); + const minutes = `${this.dd.minute}`.padStart(2, '0'); + const seconds = `${this.dd.second}`.padStart(2, '0'); + const milliseconds = `${this.dd.millisecond}`.padStart(3, '0'); + + return `${year}-${month}-${date}T${hours}:${minutes}:${seconds}.${milliseconds}Z`; + } + + /** + * 转对象 + * @description 返回包含时间信息的 Object + * @example + * const datetime = dayjs('2023-12-13 10:16:18'); + * console.log(datetime.toObject()); // 输出 {"date":13,"hours":10,"milliseconds":0,"minutes":16,"months":12,"seconds":18,"years":2023} + */ + toObject(): DatetimeOptions { + return { + years: this.dd.year, + months: this.dd.month, + date: this.dd.date, + hours: this.dd.hour, + minutes: this.dd.minute, + seconds: this.dd.second, + milliseconds: this.dd.millisecond + } as DatetimeOptions; + } + + /** + * 转字符串 + * @description 返回包含时间信息的"RFC 822" 或 "RFC 5322" 格式字符串 + * @example + * const datetime = dayjs('2023-12-13 10:16:18'); + * console.log(datetime.toRFCString()); // 输出 Wed, 13 Dec 2023 10:16:18 GMT + */ + toRFCString (): string { + const weekday = WEEKDAYS[this.toDate().getDay()]; + const year = `${this.dd.year}`; + const month = MONTHS[this.toDate().getMonth()]; + const day = `${this.dd.date}`.padStart(2, '0'); + const hours = `${this.dd.hour}`.padStart(2, '0'); + const minutes = `${this.dd.minute}`.padStart(2, '0'); + const seconds = `${this.dd.second}`.padStart(2, '0'); + + return `${weekday}, ${day} ${month} ${year} ${hours}:${minutes}:${seconds} GMT`; + } + + private _isGetDate (dayjs: KuxDayjs, unit: DiffUnit = 'ms'): Date { + let date: Date; + + const year = dayjs.dd.year; + const month = dayjs.dd.month; + const day = dayjs.dd.date; + const hour = dayjs.dd.hour; + const minute = dayjs.dd.minute; + const second = dayjs.dd.second; + const millsecond = dayjs.dd.millisecond; + + if (unit === 'year' || unit === 'y') { + date = new Date(year, 0, 0, 0, 0, 0, 0); + } else if (unit === 'month' || unit === 'M') { + date = new Date(year, month - 1); + } else if (unit === 'day' || unit === 'd') { + date = new Date(year, month - 1, day); + } else if (unit === 'hour' || unit === 'h') { + date = new Date(year, month - 1, day, hour); + } else if (unit === 'minute' || unit === 'm') { + date = new Date(year, month - 1, day, hour, minute); + } else if (unit === 'second' || unit === 's') { + date = new Date(year, month - 1, day, hour, minute, second); + } else { + date = new Date(year, month - 1, day, hour, minute, second, millsecond); + } + + return date; + } + + /** + * 是否之前 + * @description 表示 KuxDayjs 对象是否在另一个提供的日期时间之前 + * @param {string} datetime 日期时间字符串,仅支持 'YYYY-MM-DD HH:mm:ss.S'格式 + * @param {DiffUnit} unit 比较单位,默认为ms + * + year - 年,缩写为 `y` + * + month - 月,缩写为 `M` + * + day - 日,缩写为 `d` + * + hour - 小时,缩写为 `h` + * + minute - 分钟,缩写为 `m` + * + second - 秒,缩写为 `s` + * + millisecond - 毫秒,缩写为 `ms` + * @returns {boolean} + * @example + * const datetime = dayjs('2023-12-13 10:16:18'); + * console.log(datetime.isBefore('2024-12-12')); // 输出 true + * console.log(datetime.isBefore('2024-12-12', 'year')); // 输出 true + */ + isBefore (datetime: string, unit: DiffUnit = 'ms'): boolean { + const dayjs = this.dayjs(datetime); + const date1 = this._isGetDate(dayjs, unit); + const date2 = this._isGetDate(this.clone(), unit); + + return date2.getTime() < date1.getTime(); + } + + /** + * 是否相同 + * @description 表示 KuxDayjs 对象是否和另一个提供的日期时间相同 + * @param {string} date 日期时间字符串,仅支持 'YYYY-MM-DD HH:mm:ss.S'格式 + * @param {DatetimeUnit} unit 比较单位,默认为ms + * + year - 年,缩写为 `y` + * + month - 月,缩写为 `M` + * + day - 日,缩写为 `d` + * + hour - 小时,缩写为 `h` + * + minute - 分钟,缩写为 `m` + * + second - 秒,缩写为 `s` + * + millisecond - 毫秒,缩写为 `ms` + * @returns {boolean} + * @example + * const datetime = dayjs('2023-12-13 10:16:18'); + * console.log(datetime.isSame('2023-12-12')); // 输出 false + * console.log(datetime.isSame('2023-12-12', 'year')); // 输出 true + */ + isSame (datetime: string, unit: DatetimeUnit = 'ms'): boolean { + const dayjs = this.dayjs(datetime); + const date1 = this._isGetDate(dayjs, unit); + const date2 = this._isGetDate(this.clone()); + + return date2.getTime() === date1.getTime(); + } + + /** + * 是否之后 + * @description 表示 KuxDayjs 对象是否在另一个提供的日期时间之后 + * @param {string} datetime 日期时间字符串,仅支持 'YYYY-MM-DD HH:mm:ss.S'格式 + * @param {DatetimeUnit} unit 比较单位,默认为ms + * + year - 年,缩写为 `y` + * + month - 月,缩写为 `M` + * + day - 日,缩写为 `d` + * + hour - 小时,缩写为 `h` + * + minute - 分钟,缩写为 `m` + * + second - 秒,缩写为 `s` + * + millisecond - 毫秒,缩写为 `ms` + * @returns {boolean} + * @example + * const datetime = dayjs('2023-12-13 10:16:18'); + * console.log(datetime.isAfter('2023-12-12')); // 输出 true + * console.log(datetime.isAfter('2023-12-12', 'year')); // 输出 true + */ + isAfter (datetime: string, unit: DatetimeUnit = 'ms'): boolean { + const dayjs = this.dayjs(datetime); + const date1 = this._isGetDate(dayjs, unit); + const date2 = this._isGetDate(this.clone(), unit); + + return date2.getTime() > date1.getTime(); + } + + /** + * 是否相同或之前 + * @description 表示 KuxDayjs 对象是和另一个提供的日期时间相同或在其之前 + * @param {string} datetime 日期时间字符串,仅支持 'YYYY-MM-DD HH:mm:ss.S'格式 + * @param {DatetimeUnit} unit 比较单位,默认为ms + * + year - 年,缩写为 `y` + * + month - 月,缩写为 `M` + * + day - 日,缩写为 `d` + * + hour - 小时,缩写为 `h` + * + minute - 分钟,缩写为 `m` + * + second - 秒,缩写为 `s` + * + millisecond - 毫秒,缩写为 `ms` + * @returns {boolean} + * @example + * const datetime = dayjs('2023-12-13 10:16:18'); + * console.log(datetime.isSameOrBefore('2023-12-12')); // 输出 false + * console.log(datetime.isSameOrBefore('2023-12-12', 'year')); // 输出 true + */ + isSameOrBefore (datetime: string, unit: DatetimeUnit = 'ms'): boolean { + const dayjs = this.dayjs(datetime); + const date1 = this._isGetDate(dayjs, unit); + const date2 = this._isGetDate(this.clone(), unit); + + const time1 = date1.getTime(); + const time2 = date2.getTime(); + + return time2 <= time1; + } + + /** + * 是否相同或之后 + * @description 表示 KuxDayjs 对象是否和另一个提供的日期时间相同或在其之后 + * @param {string} datetime 日期时间字符串,仅支持 'YYYY-MM-DD HH:mm:ss.S'格式 + * @param {DatetimeUnit} unit 比较单位,默认为ms + * + year - 年,缩写为 `y` + * + month - 月,缩写为 `M` + * + day - 日,缩写为 `d` + * + hour - 小时,缩写为 `h` + * + minute - 分钟,缩写为 `m` + * + second - 秒,缩写为 `s` + * + millisecond - 毫秒,缩写为 `ms` + * @returns {boolean} + * @example + * const datetime = dayjs('2023-12-13 10:16:18'); + * console.log(datetime.isSameOrAfter('2023-12-12')); // 输出 true + * console.log(datetime.isSameOrAfter('2023-12-12', 'year')); // 输出 true + */ + isSameOrAfter (datetime: string, unit: DatetimeUnit = 'ms'): boolean { + const dayjs = this.dayjs(datetime); + const date1 = this._isGetDate(dayjs, unit); + const date2 = this._isGetDate(this.clone(), unit); + + const time1 = date1.getTime(); + const time2 = date2.getTime(); + + return time2 >= time1; + } + + /** + * 是否两者之间 + * @description 表示 KuxDayjs 对象是否在其他两个的日期时间之间 + * @param {string} datetime1 日期时间字符串,仅支持 'YYYY-MM-DD HH:mm:ss.S'格式 + * @param {string} datetime2 日期时间字符串,仅支持 'YYYY-MM-DD HH:mm:ss.S'格式 + * @param {DatetimeUnit} unit 比较单位,默认为 `ms` + * + year - 年,缩写为 `y` + * + month - 月,缩写为 `M` + * + day - 日,缩写为 `d` + * + hour - 小时,缩写为 `h` + * + minute - 分钟,缩写为 `m` + * + second - 秒,缩写为 `s` + * + millisecond - 毫秒,缩写为 `ms` + * @param {IsBetweenContains} contains 包含关系,见下方说明 + * + `[` - 向前包含,等同于 `<=` + * + `]` - 向后包含,等同于 `>=` + * + `[]` - 前后都包含 + * @returns {boolean} + * @example + * const date = dayjs('2023-12-13'); + * console.log(date.isBetween('2023-12-13', '2023-12-14', 'day')); // 输出 false + * console.log(date.isBetween('2023-12-13', '2023-12-14', 'day', '[')); // 输出 true + */ + isBetween (datetime1: string, datetime2: string, unit: DatetimeUnit = 'ms', contains: IsBetweenContains = ''): boolean { + const dayjs1 = this.dayjs(datetime1); + const date1 = this._isGetDate(dayjs1, unit); + + const dayjs2 = this.dayjs(datetime2); + const date2 = this._isGetDate(dayjs2, unit); + + const date3 = this._isGetDate(this.clone(), unit); + + const time1 = date1.getTime(); + const time2 = date2.getTime(); + const time3 = date3.getTime(); + + // 向前包含 + if (contains === '[') { + return time3 >= time1 && time3 < time2; + } + + // 向后包含 + if (contains === ']') { + return time3 > time1 && time3 <= time2; + } + + // 前后都包含 + if (contains === '[]') { + return time3 >= time1 && time3 <= time2; + } + + // 前后都不包含 + return time3 > time1 && time3 < time2; + } + + /** + * 是否是Dayjs + * @description 这表示一个变量是否为 KuxDayjs 对象 + * @param {any} dayjs 判断的对象 + * @returns {boolean} + * @example + * const now = dayjs(); + * console.log(now.isDayjs(dayjs())); // 输出 true + * console.log(now.isDayjs(new Date())); // 输出 false + */ + isDayjs (dayjs: any): boolean { + return dayjs instanceof KuxDayjs; + } +}; + +export function dayjs (date: string = ''): KuxDayjs { + return new KuxDayjs(date); +}; + +// 导出类型 +export * from '../utssdk/interface'; \ No newline at end of file diff --git a/uni_modules/kux-dayjs/common/solar.uts b/uni_modules/kux-dayjs/common/solar.uts new file mode 100644 index 0000000..e69de29 diff --git a/uni_modules/kux-dayjs/package.json b/uni_modules/kux-dayjs/package.json new file mode 100644 index 0000000..71cc65b --- /dev/null +++ b/uni_modules/kux-dayjs/package.json @@ -0,0 +1,87 @@ +{ + "id": "kux-dayjs", + "displayName": "kux-dayjs", + "version": "1.0.0", + "description": "一个极简的 `uts` 库,API 设计完全参考 `dayjs` 的设计、所以上手该库基本零成本了,方便开发者们验证、操作和显示日期和时间。", + "keywords": [ + "时间", + "日期", + "格式化", + "day", + "date" +], + "repository": "https://gitcode.net/kviewui/kviewui-x", + "engines": { + "HBuilderX": "^3.6.8" + }, + "dcloudext": { + "type": "uts", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "1709233528" + }, + "declaration": { + "ads": "无", + "data": "插件不采集任何数据", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "n", + "vue3": "y" + }, + "App": { + "app-android": { + "minVersion": "19" + }, + "app-ios": "n" + }, + "H5-mobile": { + "Safari": "n", + "Android Browser": "n", + "微信浏览器(Android)": "n", + "QQ浏览器(Android)": "n" + }, + "H5-pc": { + "Chrome": "n", + "IE": "n", + "Edge": "n", + "Firefox": "n", + "Safari": "n" + }, + "小程序": { + "微信": "n", + "阿里": "n", + "百度": "n", + "字节跳动": "n", + "QQ": "n", + "钉钉": "n", + "快手": "n", + "飞书": "n", + "京东": "n" + }, + "快应用": { + "华为": "n", + "联盟": "n" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/kux-dayjs/readme.md b/uni_modules/kux-dayjs/readme.md new file mode 100644 index 0000000..059a805 --- /dev/null +++ b/uni_modules/kux-dayjs/readme.md @@ -0,0 +1,685 @@ +# kux-dayjs +`KuxDayjs` 是一个极简的 `uts` 库,API 设计完全参考 `dayjs` 的设计、所以上手该库基本零成本了,方便开发者们验证、操作和显示日期和时间。 + +## 目录结构 +
    +
  1. 导入插件
  2. +
  3. 解析 +
      +
    1. 实例
    2. +
    3. 当前时间
    4. +
    5. 克隆复制
    6. +
    +
  4. +
  5. 取值/赋值 +
      +
    1. 毫秒
    2. +
    3. +
    4. 分钟
    5. +
    6. 小时
    7. +
    8. 日期
    9. +
    10. 星期
    11. +
    12. 时间
    13. +
    14. +
    15. +
    +
  6. +
  7. 操作 +
      +
    1. 增加
    2. +
    3. 减去
    4. +
    5. 今天
    6. +
    7. 时间的开始
    8. +
    9. 时间的结束
    10. +
    +
  8. +
  9. 显示 +
      +
    1. 格式化
    2. +
    3. 相对当前时间(前)
    4. +
    5. 相对指定时间(前)
    6. +
    7. 相对当前时间(后)
    8. +
    9. 相对指定时间(后)
    10. +
    11. 日历时间
    12. +
    13. 差异(Diff)
    14. +
    15. Unix时间戳(毫秒)
    16. +
    17. Unix时间戳
    18. +
    19. 获取月天数
    20. +
    21. 转Date
    22. +
    23. 转数组
    24. +
    25. 转JSON
    26. +
    27. 转对象
    28. +
    29. 转字符串
    30. +
    +
  10. +
  11. 查询 +
      +
    1. 是否之前
    2. +
    3. 是否相同
    4. +
    5. 是否之后
    6. +
    7. 是否相同或之前
    8. +
    9. 是否相同或之后
    10. +
    11. 是否两者之间
    12. +
    13. 是否是KuxDayjs
    14. +
    15. 是否闰年
    16. +
    +
  12. +
+ +### 导入插件 + +```ts +import { dayjs } from '@/uni_modules/kux-dayjs'; +``` + +### 解析 + + +#### 实例 + +代替修改本地Date.prototype,`KuxDayjs` 对 `Date` 对象进行了封装,只需要调用 `dayjs()` 即可 + +`KuxDayjs` 对象是不可变的,也就是说,以某种方式改变 `KuxDayjs` 对象的所有API操作都将返回它的一个新实例。 + +#### 当前时间 + +直接调用 `dayjs()` 将返回一个包含当前日期和时间的 `KuxDayjs` 对象。 +```ts +const now = dayjs(); +``` +>目前仅支持传入 `YYYY-MM-DD HH:mm:ss.S` 格式的日期时间字符串 + +#### 克隆复制 + +所有的 `KuxDayjs` 对象都是不可变的。 但如果有必要,使用 `dayjs().clone()` 可以复制出一个当前对象。 +```ts +const a = dayjs(); +const b = a.clone(); +// a 和 b 是两个独立的 KuxDayjs 对象 +``` + +### 取值/赋值 + + +#### 毫秒 + +获取或设置毫秒。
+传入0到999的数字。 如果超出这个范围,它会进位到秒。 +```ts +dayjs().millisecond() +dayjs().millisecond(1) +``` + +#### 秒 + +获取或设置秒。
+传入0到59的数字。 如果超出这个范围,它会进位到分钟。 +```ts +dayjs().second() +dayjs().second(1) +``` + +#### 分钟 + +获取或设置分钟。
+传入0到59的数字。 如果超出这个范围,它会进位到小时。 +```ts +dayjs().minute() +dayjs().minute(59) +``` + +#### 小时 + +获取或设置小时。
+传入0到23的数字。 如果超出这个范围,它会进位到天数。 +```ts +dayjs().hour() +dayjs().hour(12) +``` + +#### 日期 + +获取或设置日期。
+传入1到31的数字。 如果超出这个范围,它会进位到月份。 +```ts +dayjs().date() +dayjs().date(1) +``` +> ****注意****
`dayjs().date()` 是该月的日期。`dayjs().day()` 是星期几。 + +#### 星期 + +获取或设置星期几。
+传入 number 从0(星期天)到6(星期六)。 如果超出这个范围,它会进位到其他周。 +```ts +dayjs().day() +dayjs().day(0) +``` +> ****注意****
`dayjs().date()` 是该月的日期。`dayjs().day()` 是星期几。 + +#### 时间 + +获取或设置时间。
+传入一个整数,表示从 1970-1-1 00:00:00 UTC 开始计时的毫秒数。 传入参数就是设置操作,否则为获取操作。 +```ts +dayjs().time() +dayjs().time(1) +``` + +#### 月 + +获取或设置月份。
+传入0到11的 number。 如果超出这个范围,它会进位到年份。 +```ts +dayjs().month() +dayjs().month(0) +``` +> ****注意****
月份是从 0 开始计算的,即 1 月是 0。 + +#### 年 + +获取或设置年份。
+```ts +dayjs().year() +dayjs().year(2000) +``` + +### 操作 + +您可能需要一些方法来操作 `KuxDayjs` 对象。
+`KuxDayjs` 支持像这样的链式调用。 +```ts +dayjs('2019-01-25').add(1, 'day').subtract(1, 'year').year(2009); +``` + +#### 增加 + +返回增加一定时间的复制的 `KuxDayjs` 对象。 +```ts +dayjs().add(7, 'day') +``` +支持配合单位操作。缩写要区分大小写。
+支持的单位列表如下:
++ week 周,缩写 `w` ++ month 月份,缩写 `M` ++ year 年,缩写 `y` ++ hour 小时,缩写 `h` ++ minute 分钟,缩写 `m` ++ second 秒,缩写 `s` ++ millisecond 毫秒,缩写 `ms` + +#### 减去 + +返回减去一定时间的复制的 `KuxDayjs` 对象。 +```ts +dayjs().subtract(7, 'day') +``` +支持配合单位操作。缩写要区分大小写。
+支持的单位列表如下:
++ week 周,缩写 `w` ++ month 月份,缩写 `M` ++ year 年,缩写 `y` ++ hour 小时,缩写 `h` ++ minute 分钟,缩写 `m` ++ second 秒,缩写 `s` ++ millisecond 毫秒,缩写 `ms` + +#### 今天 + +返回设置时间为今天的复制的 `KuxDayjs` 对象。 +```ts +dayjs().today() +``` + +#### 时间的开始 + +返回复制的 `KuxDayjs` 对象,并设置到一个时间的开始。 +```ts +dayjs().startOf('year') +``` +支持配合单位操作。缩写要区分大小写。
+支持的单位列表如下:
++ week 周,缩写 `w` ++ month 月份,缩写 `M` ++ year 年,缩写 `y` ++ hour 小时,缩写 `h` ++ minute 分钟,缩写 `m` ++ second 秒,缩写 `s` ++ millisecond 毫秒,缩写 `ms` + +>****注意****
暂时不支持跨年操作。 + +#### 时间的结束 + +返回复制的 `KuxDayjs` 对象,并设置到一个时间的末尾。 +```ts +dayjs().endOf('month') +``` +支持配合单位操作。缩写要区分大小写。
+支持的单位列表如下:
++ week 周,缩写 `w` ++ month 月份,缩写 `M` ++ year 年,缩写 `y` ++ hour 小时,缩写 `h` ++ minute 分钟,缩写 `m` ++ second 秒,缩写 `s` ++ millisecond 毫秒,缩写 `ms` + +>****注意****
暂时不支持跨年操作。 + +### 显示 + +当解析和操作完成后,您需要一些方式来展示 `KuxDayjs` 对象。 + +#### 格式化 + +根据传入的占位符返回格式化后的日期。 +```ts +dayjs().format('YYYY-MM-DD HH:mm:ss') +dayjs().format('YYYY-MM-DD a HH:mm:ss') +dayjs().format('YYYY-MM-DD HH:mm:ss A') +``` +支持的格式占位符列表:
+ +| 标识 | 示例 | 描述 | +| --- | --- | --- | +| YYYY | 2023 | 年份,四位数 | +| MM | 12 | 月份 | +| DD | 01 | 日,两位数 | +| HH | 22 | 小时,两位数 | +| mm | 59 | 分钟,两位数 | +| ss | 01 | 秒,两位数 | +| SSS | 999 | 毫秒,三位数 | +| A | AM/PM | 上/下午,大写 | +| a | am/pm | 上/下午,小写 | +| AA | 上/下午 | 上/下午 | + +#### 相对当前时间(前) + +返回现在到当前实例的相对时间。 +```ts +dayjs('2021-12-12').fromNow(); // 1年前 +``` +支持传入配置项自定义输出格式以及显示隐藏后缀,配置项定义如下:
+ +| 参数名 | 默认值 | 说明 | +| --- | --- | --- | +| isSuffix | `false` | 是否自动携带后缀,为 `true` 的时候会自动添加 `'前'` 后缀,如 1年前;手动指定 `relativeTime` 时该项不生效 +| relativeTime | `{s: '', m: '', mm: '', h: '', hh: '', d: '', dd: '', mon: '', mons: '', y: '', yy: ''}` | 自定义格式,变量说明见下方说明 | + +#### RelativeTime 说明 +| 范围 | 键量 | 使用变量 | 说明 | 示例 | +| --- | --- | --- | --- | --- | +| 0 to 44seconds | s | %s | 几秒前 | %s seconds ago | +| 45 to 89 seconds | m | %m | 1分钟前 | %m minute ago | +| 90 seconds to 44 minutes | mm | %mm | 几分钟前 | %mm minutes ago | +| 45 to 89 minutes | h | %h | 1小时前 | %h hour ago | +| 90 minutes to 21 hours | hh | %hh | 几小时前 | %hh hours ago | +| 22 to 35 hours | d | d | %d | 1天前 | %d day ago | +| 36 hours to 25 days | dd | %dd | 几天前 | %dd days ago | +| 26 to 45 days | mon | %mon | 1个月前 | %mon month ago | +| 46 days to 10 months | mons | %mons | 几个月前 | %mons months ago | +| 11 months to 17 months | y | %y | 1年前 | %y year ago | +| 18 months + | yy | %yy | 几年前 | %yy years ago | + +#### 相对指定时间(前) + +返回 X 到当前实例的相对时间。 +```ts +const datetime = dayjs('2021-12-12 15:43:58'); +const a = dayjs('2022-12-12'); +datetime.from(a); // 1年前 +``` +支持传入配置项自定义输出格式以及显示隐藏后缀,配置项定义如下:
+ +| 参数名 | 默认值 | 说明 | +| --- | --- | --- | +| isSuffix | `false` | 是否自动携带后缀,为 `true` 的时候会自动添加 `'前'` 后缀,如 1年前;手动指定 `relativeTime` 时该项不生效 +| relativeTime | `{s: '', m: '', mm: '', h: '', hh: '', d: '', dd: '', mon: '', mons: '', y: '', yy: ''}` | 自定义格式,变量说明见下方说明 | + +#### RelativeTime 说明 +| 范围 | 键量 | 使用变量 | 说明 | 示例 | +| --- | --- | --- | --- | --- | +| 0 to 44seconds | s | %s | 几秒前 | %s seconds ago | +| 45 to 89 seconds | m | %m | 1分钟前 | %m minute ago | +| 90 seconds to 44 minutes | mm | %mm | 几分钟前 | %mm minutes ago | +| 45 to 89 minutes | h | %h | 1小时前 | %h hour ago | +| 90 minutes to 21 hours | hh | %hh | 几小时前 | %hh hours ago | +| 22 to 35 hours | d | d | %d | 1天前 | %d day ago | +| 36 hours to 25 days | dd | %dd | 几天前 | %dd days ago | +| 26 to 45 days | mon | %mon | 1个月前 | %mon month ago | +| 46 days to 10 months | mons | %mons | 几个月前 | %mons months ago | +| 11 months to 17 months | y | %y | 1年前 | %y year ago | +| 18 months + | yy | %yy | 几年前 | %yy years ago | + +#### 相对当前时间(后) + +返回当前实例到现在的相对时间。 +```ts +dayjs('2021-12-12').toNow(); // 1年后 +``` +支持传入配置项自定义输出格式以及显示隐藏后缀,配置项定义如下:
+ +| 参数名 | 默认值 | 说明 | +| --- | --- | --- | +| isSuffix | `false` | 是否自动携带后缀,为 `true` 的时候会自动添加 `'后'` 后缀,如 1年前;手动指定 `relativeTime` 时该项不生效 +| relativeTime | `{s: '', m: '', mm: '', h: '', hh: '', d: '', dd: '', mon: '', mons: '', y: '', yy: ''}` | 自定义格式,变量说明见下方说明 | + +#### RelativeTime 说明 +| 范围 | 键量 | 使用变量 | 说明 | 示例 | +| --- | --- | --- | --- | --- | +| 0 to 44seconds | s | %s | 几秒后 | %s seconds after | +| 45 to 89 seconds | m | %m | 1分钟后 | %m minute after | +| 90 seconds to 44 minutes | mm | %mm | 几分钟后 | %mm minutes after | +| 45 to 89 minutes | h | %h | 1小时后 | %h hour after | +| 90 minutes to 21 hours | hh | %hh | 几小时后 | %hh hours after | +| 22 to 35 hours | d | d | %d | 1天后 | %d day after | +| 36 hours to 25 days | dd | %dd | 几天后 | %dd days after | +| 26 to 45 days | mon | %mon | 1个月后 | %mon month after | +| 46 days to 10 months | mons | %mons | 几个月后 | %mons months after | +| 11 months to 17 months | y | %y | 1年后 | %y year after | +| 18 months + | yy | %yy | 几年后 | %yy years after | + +#### 相对指定时间(后) + +返回当前实例到现在的相对时间。 +```ts +const datetime = dayjs('2021-12-12 15:43:58'); +const a = dayjs('2022-12-12'); +console.log(datetime.to(a)); // 输出 1年后 +``` +支持传入配置项自定义输出格式以及显示隐藏后缀,配置项定义如下:
+ +| 参数名 | 默认值 | 说明 | +| --- | --- | --- | +| isSuffix | `false` | 是否自动携带后缀,为 `true` 的时候会自动添加 `'后'` 后缀,如 1年前;手动指定 `relativeTime` 时该项不生效 +| relativeTime | `{s: '', m: '', mm: '', h: '', hh: '', d: '', dd: '', mon: '', mons: '', y: '', yy: ''}` | 自定义格式,变量说明见下方说明 | + +#### RelativeTime 说明 +| 范围 | 键量 | 使用变量 | 说明 | 示例 | +| --- | --- | --- | --- | --- | +| 0 to 44seconds | s | %s | 几秒后 | %s seconds after | +| 45 to 89 seconds | m | %m | 1分钟后 | %m minute after | +| 90 seconds to 44 minutes | mm | %mm | 几分钟后 | %mm minutes after | +| 45 to 89 minutes | h | %h | 1小时后 | %h hour after | +| 90 minutes to 21 hours | hh | %hh | 几小时后 | %hh hours after | +| 22 to 35 hours | d | d | %d | 1天后 | %d day after | +| 36 hours to 25 days | dd | %dd | 几天后 | %dd days after | +| 26 to 45 days | mon | %mon | 1个月后 | %mon month after | +| 46 days to 10 months | mons | %mons | 几个月后 | %mons months after | +| 11 months to 17 months | y | %y | 1年后 | %y year after | +| 18 months + | yy | %yy | 几年后 | %yy years after | + +#### 日历时间 + +传入指定年月获取指定年月的日历面板数据,指定年月省略时默认获取当年年月的数据。返回 `DateFormat[]`,`DateFormat` 见下方说明。 +```ts +dayjs().calendar(); +``` + +##### 传入参数 +
+ +| 参数名 | 类型 | 是否必填 | 默认值 | 说明 | +| --- | --- | --- | --- | --- | +| year | `number` | 否 | `0` | 指定年份,默认值为 0 +| month | `number` | 否 | `0` | 指定月份,默认值为 0 + +##### DateFormat 说明 +
+ +| 参数名 | 类型 | 说明 | +| --- | --- | --- | +| year | `number` | 年份 +| month | `number` | 月份 +| render | `any` | 留存字段 +| lunar | `LunarType` | 农历信息,见下方说明 +| fullLunar | `InfoType` | 农历完整数据信息,见下方说明 +| diffDays | `number` | 距离今天的差值,正数表示多少天后,负数表示多少天前,`0` 表示今天时间 +| isToday | `boolean` | 农历中是否为今天 +| fullDate | `string` | 完整日期 + +##### LunarType 说明 +
+ + +| 参数名 | 类型 | 说明 | +| --- | --- | --- | +| month | `string` | 农历月份大写 +| date | `string` | 农历日期大写 + +##### InfoType 说明 +
+ +| 参数名 | 类型 | 说明 | +| --- | --- | --- | +| lunarY | `number` | 农历年份数字 +| lunarM | `number` | 农历月份数字 +| lunarD | `number` | 农历日期数字 +| isLeap | `boolean` | 是否闰月 + +#### 差异(Diff) + +返回指定单位下两个日期时间之间的差异。 +```ts +const date1 = dayjs('2019-01-25'); +const date2 = dayjs('2018-06-05'); +date1.diff(date2) // 20214000000 默认单位是毫秒 +``` +要获取其他单位下的差异,则在第二个参数传入相应的单位。 +```ts +const date1 = dayjs('2019-01-25'); +date1.diff('2018-06-05', 'month') // 7; +``` +默认情况下会将结果进位成整数。 如果要得到一个浮点数,将 `true` 作为第三个参数传入。 +```ts +const date1 = dayjs('2019-01-25'); +date1.diff('2018-06-05', 'month', true) // 7.645161290322581; +``` +支持的单位列表:
++ week 周,缩写 `w` ++ day 天,缩写 `d` ++ month 月份,缩写 `M` ++ year 年,缩写 `y` ++ hour 小时,缩写 `h` ++ minute 分钟,缩写 `m` ++ second 秒,缩写 `s` ++ millisecond 毫秒,缩写 `ms` + +#### Unix时间戳(毫秒) + +返回当前实例的 UNIX 时间戳,13位数字,毫秒 +```ts +dayjs('2019-01-25').valueOf() // 1548381600000 +``` + +#### Unix时间戳 + +返回当前实例的 UNIX 时间戳,10位数字,秒 +```ts +dayjs('2019-01-25').valueOf() // 1548381600 +``` +此值不包含毫秒信息,会进位到秒。 + + +#### 获取月天数 + +获取当前月份包含的天数。 +```ts +const date = dayjs('2023-12-12'); // 31 +``` + +#### 转Date + +从 `KuxDayjs` 中获取原生的Date对象。 +```ts +dayjs('2023-12-12').toDate(); +``` + +#### 转数组 + +返回一个包含各个时间信息的 Array。 +```ts +const datetime = dayjs('2023-12-13 10:16:18');// [2023,12,13,10,16,18,0] +``` + +#### 转JSON + +序列化为 `ISO 8601` 格式的字符串。 +```ts +dayjs('2023-12-13 10:16:18').toJSON(); // 2023-12-13T10:16:18.000Z +``` + +#### 转对象 + +返回包含时间信息的 Object。 +```ts +dayjs('2023-12-13 10:16:18').toObject(); // {"date":13,"hours":10,"milliseconds":0,"minutes":16,"months":12,"seconds":18,"years":2023} +``` + +#### 转字符串 + +返回包含时间信息的 `RFC 822` 或 `RFC 5322` 格式字符串。 +```ts +dayjs('2023-12-13 10:16:18').toRFCString(); // Wed, 13 Dec 2023 10:16:18 GMT +``` + +### 查询 + +`KuxDayjs` 对象还有很多查询的方法。 + +#### 是否之前 + +表示 `KuxDayjs` 对象是否在另一个提供的日期时间之前。 +```ts +dayjs('2023-12-13 10:16:18').isBefore('2024-12-12'); // true +``` +如果想使用除了毫秒以外的单位进行比较,则将单位作为第二个参数传入。 +```ts +dayjs('2023-12-13 10:16:18').isBefore('2024-12-12', 'year'); // true +``` +支持的单位列表如下:
++ year - 年,缩写为 `y` ++ month - 月,缩写为 `M` ++ day - 日,缩写为 `d` ++ hour - 小时,缩写为 `h` ++ minute - 分钟,缩写为 `m` ++ second - 秒,缩写为 `s` ++ millisecond - 毫秒,缩写为 `ms` + +#### 是否相同 + +表示 `KuxDayjs` 对象是否和另一个提供的日期时间相同。 +```ts +dayjs('2023-12-13 10:16:18').isBefore('2023-12-12'); // false +``` +如果想使用除了毫秒以外的单位进行比较,则将单位作为第二个参数传入。 +```ts +dayjs('2023-12-13 10:16:18').isBefore('2023-12-12', 'year'); // true +``` +支持的单位列表如下:
++ year - 年,缩写为 `y` ++ month - 月,缩写为 `M` ++ day - 日,缩写为 `d` ++ hour - 小时,缩写为 `h` ++ minute - 分钟,缩写为 `m` ++ second - 秒,缩写为 `s` ++ millisecond - 毫秒,缩写为 `ms` + +#### 是否之后 + +表示 `KuxDayjs` 对象是否在另一个提供的日期时间之后。 +```ts +dayjs('2023-12-13 10:16:18').isAfter('2023-12-12'); // true +``` +如果想使用除了毫秒以外的单位进行比较,则将单位作为第二个参数传入。 +```ts +dayjs('2023-12-13 10:16:18').isAfter('2023-12-12', 'year'); // true +``` +支持的单位列表如下:
++ year - 年,缩写为 `y` ++ month - 月,缩写为 `M` ++ day - 日,缩写为 `d` ++ hour - 小时,缩写为 `h` ++ minute - 分钟,缩写为 `m` ++ second - 秒,缩写为 `s` ++ millisecond - 毫秒,缩写为 `ms` + +#### 是否相同或之前 + +表示 `KuxDayjs` 对象是和另一个提供的日期时间相同或在其之前。 +```ts +dayjs('2023-12-13 10:16:18').isSameOrBefore('2023-12-12'); // false +``` +如果想使用除了毫秒以外的单位进行比较,则将单位作为第二个参数传入。 +```ts +dayjs('2023-12-13 10:16:18').isSameOrBefore('2023-12-12', 'year'); // true +``` +支持的单位列表如下:
++ year - 年,缩写为 `y` ++ month - 月,缩写为 `M` ++ day - 日,缩写为 `d` ++ hour - 小时,缩写为 `h` ++ minute - 分钟,缩写为 `m` ++ second - 秒,缩写为 `s` ++ millisecond - 毫秒,缩写为 `ms` + +#### 是否相同或之后 + +表示 `KuxDayjs` 对象是和另一个提供的日期时间相同或在其之前。 +```ts +dayjs('2023-12-13 10:16:18').isSameOrAfter('2023-12-12'); // true +``` +如果想使用除了毫秒以外的单位进行比较,则将单位作为第二个参数传入。 +```ts +dayjs('2023-12-13 10:16:18').isSameOrAfter('2023-12-12', 'year'); // true +``` +支持的单位列表如下:
++ year - 年,缩写为 `y` ++ month - 月,缩写为 `M` ++ day - 日,缩写为 `d` ++ hour - 小时,缩写为 `h` ++ minute - 分钟,缩写为 `m` ++ second - 秒,缩写为 `s` ++ millisecond - 毫秒,缩写为 `ms` + +#### 是否两者之间 + +表示 `KuxDayjs` 对象是否在其他两个的日期时间之间。 +```ts +dayjs('2023-12-13').isBetween('2023-12-13', '2023-12-14'); // 默认毫秒 +``` +如果想使用除了毫秒以外的单位进行比较,则将单位作为第三个参数传入。 +```ts +dayjs('2023-12-13').isBetween('2023-12-13', '2023-12-14', 'year'); +``` +支持的单位列表如下:
++ year - 年,缩写为 `y` ++ month - 月,缩写为 `M` ++ day - 日,缩写为 `d` ++ hour - 小时,缩写为 `h` ++ minute - 分钟,缩写为 `m` ++ second - 秒,缩写为 `s` ++ millisecond - 毫秒,缩写为 `ms` + +如果想自定义包含关系进行比较,则将包含关系作为第四个参数传入。 +```ts +dayjs('2023-12-13').isBetween('2023-12-13', '2023-12-14', 'day', '['); +``` +包含关系列表如下:
++ `[` - 向前包含,等同于 `<=` ++ `]` - 向后包含,等同于 `>=` ++ `[]` - 前后都包含 + +#### 是否是KuxDayjs +这表示一个变量是否为 `KuxDayjs` 对象。 +```ts +dayjs().isDayjs(dayjs()); // true +dayjs().isDayjs(new Date()); // false +``` + +#### 是否闰年 +查询 `KuxDayjs` 对象的年份是否是闰年。 +```ts +dayjs('2000-01-01').isLeapYear(); // true +``` \ No newline at end of file diff --git a/uni_modules/kux-dayjs/utssdk/app-android/config.json b/uni_modules/kux-dayjs/utssdk/app-android/config.json new file mode 100644 index 0000000..7ed4299 --- /dev/null +++ b/uni_modules/kux-dayjs/utssdk/app-android/config.json @@ -0,0 +1,3 @@ +{ + "minSdkVersion": "19" +} \ No newline at end of file diff --git a/uni_modules/kux-dayjs/utssdk/app-android/index.uts b/uni_modules/kux-dayjs/utssdk/app-android/index.uts new file mode 100644 index 0000000..a26d00c --- /dev/null +++ b/uni_modules/kux-dayjs/utssdk/app-android/index.uts @@ -0,0 +1 @@ +export * from '../../common/index'; \ No newline at end of file diff --git a/uni_modules/kux-dayjs/utssdk/app-ios/index.uts b/uni_modules/kux-dayjs/utssdk/app-ios/index.uts new file mode 100644 index 0000000..e69de29 diff --git a/uni_modules/kux-dayjs/utssdk/interface.uts b/uni_modules/kux-dayjs/utssdk/interface.uts new file mode 100644 index 0000000..b621ea8 --- /dev/null +++ b/uni_modules/kux-dayjs/utssdk/interface.uts @@ -0,0 +1,97 @@ +import { InfoType } from '../common/calendar'; + +export type LunarType = { + month: string; + date: string; +}; + +export type DatetimeUnit = +| 'day' +| 'd' +| 'month' +| 'M' +| 'year' +| 'y' +| 'hour' +| 'h' +| 'minute' +| 'm' +| 'second' +| 's' +| 'millisecond' +| 'ms' + +export type WeekUnit = +| 'week' +| 'w' + +export type DiffUnit = +| 'week' +| 'w' +| 'day' +| 'd' +| 'month' +| 'M' +| 'year' +| 'y' +| 'hour' +| 'h' +| 'minute' +| 'm' +| 'second' +| 's' +| 'millisecond' +| 'ms' +; + +export type DateFormat = { + year: number; + month: number; + date: number; + render: any; + lunar: LunarType; + fullLunar: InfoType; + diffDays: number; + isToday: boolean; + fullDate: string; +}; + +export type RelativeTime = { + s?: string; + m?: string; + mm?: string; + h?: string; + hh?: string; + d?: string; + dd?: string; + mon?: string; + mons?: string; + y?: string; + yy?: string; +}; + +export type FromToOptions = { + isSuffix?: boolean; + relativeTime?: RelativeTime; +}; + +export type DatetimeOptions = { + years: number; + months: number; + date: number; + hours: number; + minutes: number; + seconds: number; + milliseconds: number; +}; + +export type DateDiff = { + date1: Date, + date2: Date +}; + +export type IsBetweenContains = +| '[' +| ']' +| '[]' +| '' \ No newline at end of file diff --git a/uni_modules/lime-clipper/changelog.md b/uni_modules/lime-clipper/changelog.md new file mode 100644 index 0000000..1fa8ac2 --- /dev/null +++ b/uni_modules/lime-clipper/changelog.md @@ -0,0 +1,56 @@ +## 1.0.1(2023-06-12) +- fix: 修复vue3 QQ小程序无法生成问题 +## 1.0.0(2023-06-01) +- feat: 支持 vue3 并把 `stylus` 改成 `scss` +## 0.9.0(2022-12-12) +- chore: 更新文档 +- feat: 当缩放为1时 旋转自适应裁剪框 +## 0.8.0(2022-11-02) +- fix: 修复 正方形图片 不充满裁剪框的BUG +## 0.7.0(2021-07-10) +- chore: 统一css3 变量 命名规范 +- chore: 更新文档 +## 0.6.9(2021-07-09) +- chore: 统一命名规范,无须主动引入组件 +- fix: 修复第一次传入图片路径无自适应问题 +- fix: 修复安卓方向导致无法正确得到尺寸问题 +## 0.6.8(2021-06-26) +- fix: 修复 钉钉小程序 返回图片为 `null` 问题 +## 0.6.7(2021-06-19) +- fix: 修复`@touchstart`书写错误 +## 0.6.6(2021-06-19) +- fix: 修复支付宝引用图标的错误 +## 0.6.5(2021-06-14) +- fix: 修复锁定比例失效问题 +## 0.6.4(2021-04-16) +- 修复因mode引起的高度异常 +## 0.6.3(2021-04-13) +- 测试到微信小程序无法进第二次`draw`,故更新使用`v-model`的方式,显示隐藏组件。 +- 原先使用v-if显示隐藏组件依然可以使用,若发现无法二次`draw`请使用`v-model` +```html + +``` +```js +data: () => ({ + show: false +}) +``` +## 0.6.2(2021-03-26) +1、修复图片初始化BUG +2、增加`fileType`属性,默认值为`png` +## 0.6.1(2021-03-10) +- 给事件添加阻止冒泡 +## 0.6.0(2021-03-06) +增加`source`属性,`Object`类型,key为图片来源类型,value为选项说明。
+```js +// source 默认值 +{ + album: '从相册中选择', + camera: '拍照', + // #ifdef MP-WEIXIN + message: '从微信中选择' + // #endif +} +``` +## 0.5.0(2021-02-26) +- 调整为uni_modules目录规范 diff --git a/uni_modules/lime-clipper/components/l-clipper/index.scss b/uni_modules/lime-clipper/components/l-clipper/index.scss new file mode 100644 index 0000000..8c4a78e --- /dev/null +++ b/uni_modules/lime-clipper/components/l-clipper/index.scss @@ -0,0 +1,184 @@ +$clipper-edge-border-width: 6rpx !default; +$clipper-confirm-color: #07c160 !default; + +.flex-auto { + flex:auto +} + +.bg-transparent { + background-color: rgba(0, 0, 0, 0.9); + transition-duration: 0.35s; +} + +.lime-clipper { + width: 100vw; + height: calc( 100vh - var(--window-top)); + background-color: rgba(0, 0, 0, 0.9); + position: fixed; + top: var(--window-top); + left: 300vw; + z-index: 1; + &.open { + left: 0; + } + &-mask { + position: relative; + z-index: 2; + pointer-events: none; + } + &__content { + pointer-events: none; + position: absolute; + border: 1rpx solid rgba(255,255,255,.3); + box-sizing: border-box; + box-shadow: rgba(0, 0, 0, 0.5) 0 0 0 80vh; + background: transparent; + // transition-duration 0.35s + // transition-property left,top + &::before,&::after { + content: ''; + position: absolute; + border: 1rpx dashed rgba(255,255,255,.3); + } + + &::before { + width: 100%; + top: 33.33%; + height: 33.33%; + border-left: none; + border-right: none; + } + + &::after { + width: 33.33%; + left: 33.33%; + height: 100%; + border-top:none; + border-bottom: none; + } + + } + + &__edge { + position: absolute; + // left 6rpx + width: 34rpx; + height: 34rpx; + border: $clipper-edge-border-width solid #ffffff; + pointer-events: auto; + &::before { + content: ''; + position: absolute; + width: 40rpx; + height: 40rpx; + background-color: transparent; + } + + &:nth-child(1) { + left: - $clipper-edge-border-width; + top: - $clipper-edge-border-width; + border-bottom-width: 0 !important; + border-right-width: 0 !important; + &:before { + top: -50%; + left: -50%; + } + } + + &:nth-child(2) { + right: - $clipper-edge-border-width; + top: - $clipper-edge-border-width; + border-bottom-width: 0 !important; + border-left-width: 0 !important; + &:before { + top: -50%; + left: 50%; + } + + } + + &:nth-child(3) { + left: - $clipper-edge-border-width; + bottom: - $clipper-edge-border-width; + border-top-width: 0 !important; + border-right-width: 0 !important; + &:before { + bottom: -50%; + left: -50%; + } + } + + &:nth-child(4) { + right: - $clipper-edge-border-width; + bottom: - $clipper-edge-border-width; + border-top-width: 0 !important; + border-left-width: 0 !important; + &:before { + bottom: -50%; + left: 50%; + } + } + + } + + &-image { + width: 100%; + max-width: inherit; + border-style: none; + position: absolute; + top: 0; + left: 0; + z-index: 1; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + transform-origin: center; + } + + &-canvas { + position: fixed; + z-index: 10; + left: -200vw; + top: -200vw; + pointer-events: none; + } + + &-tools { + position: absolute; + left: 0; + bottom: 10px; + width: 100%; + z-index: 99; + color: #fff; + &__btns { + font-weight: bold; + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + padding: 20rpx 40rpx; + box-sizing: border-box; + .cancel { + width: 112rpx; + height: 60rpx; + text-align: center; + line-height: 60rpx; + } + + .confirm { + width: 112rpx; + height: 60rpx; + line-height: 60rpx; + background: var(--lime-clipper-confirm-color, $clipper-confirm-color); + border-radius: 6rpx; + text-align: center; + } + + image { + display: block; + width: 60rpx; + height: 60rpx; + } + } + } +} + diff --git a/uni_modules/lime-clipper/components/l-clipper/l-clipper.vue b/uni_modules/lime-clipper/components/l-clipper/l-clipper.vue new file mode 100644 index 0000000..a361738 --- /dev/null +++ b/uni_modules/lime-clipper/components/l-clipper/l-clipper.vue @@ -0,0 +1,842 @@ + + + + + diff --git a/uni_modules/lime-clipper/components/l-clipper/utils.js b/uni_modules/lime-clipper/components/l-clipper/utils.js new file mode 100644 index 0000000..3d4d30e --- /dev/null +++ b/uni_modules/lime-clipper/components/l-clipper/utils.js @@ -0,0 +1,248 @@ +/** + * 判断手指触摸位置 + */ +export function determineDirection(clipX, clipY, clipWidth, clipHeight, currentX, currentY) { + /* + * (右下>>1 右上>>2 左上>>3 左下>>4) + */ + let corner; + /** + * 思路:(利用直角坐标系) + * 1.找出裁剪框中心点 + * 2.如点击坐标在上方点与左方点区域内,则点击为左上角 + * 3.如点击坐标在下方点与右方点区域内,则点击为右下角 + * 4.其他角同理 + */ + const mainPoint = [clipX + clipWidth / 2, clipY + clipHeight / 2]; // 中心点 + const currentPoint = [currentX, currentY]; // 触摸点 + + if (currentPoint[0] <= mainPoint[0] && currentPoint[1] <= mainPoint[1]) { + corner = 3; // 左上 + } else if (currentPoint[0] >= mainPoint[0] && currentPoint[1] <= mainPoint[1]) { + corner = 2; // 右上 + } else if (currentPoint[0] <= mainPoint[0] && currentPoint[1] >= mainPoint[1]) { + corner = 4; // 左下 + } else if (currentPoint[0] >= mainPoint[0] && currentPoint[1] >= mainPoint[1]) { + corner = 1; // 右下 + } + + return corner; +} + +/** + * 图片边缘检测检测时,计算图片偏移量 + */ +export function calcImageOffset(data, scale) { + let left = data.imageLeft; + let top = data.imageTop; + scale = scale || data.scale; + + let imageWidth = data.imageWidth; + let imageHeight = data.imageHeight; + if ((data.angle / 90) % 2) { + imageWidth = data.imageHeight; + imageHeight = data.imageWidth; + } + const { + clipX, + clipWidth, + clipY, + clipHeight + } = data; + + // 当前图片宽度/高度 + const currentImageSize = (size) => (size * scale) / 2; + const currentImageWidth = currentImageSize(imageWidth); + const currentImageHeight = currentImageSize(imageHeight); + + left = clipX + currentImageWidth >= left ? left : clipX + currentImageWidth; + left = clipX + clipWidth - currentImageWidth <= left ? left : clipX + clipWidth - currentImageWidth; + top = clipY + currentImageHeight >= top ? top : clipY + currentImageHeight; + top = clipY + clipHeight - currentImageHeight <= top ? top : clipY + clipHeight - currentImageHeight; + return { + left, + top, + scale + }; +} + +/** + * 图片边缘检测时,计算图片缩放比例 + */ +export function calcImageScale(data, scale) { + scale = scale || data.scale; + let { + imageWidth, + imageHeight, + clipWidth, + clipHeight, + angle + } = data + if ((angle / 90) % 2) { + [imageWidth, imageHeight] = [imageHeight, imageWidth] + } + if(angle !== 0 && scale == Math.max(clipWidth / imageHeight , clipHeight / imageWidth )) { + return Math.max(clipWidth / imageWidth , clipHeight / imageHeight ) + } + if (imageWidth * scale < clipWidth) { + scale = clipWidth / imageWidth; + } + if (imageHeight * scale < clipHeight) { + scale = Math.max(scale, clipHeight / imageHeight); + } + return scale +} + +/** + * 计算图片尺寸 + */ +export function calcImageSize(width, height, data) { + let imageWidth = width, + imageHeight = height; + let { + clipWidth, + clipHeight, + sysinfo, + width: originWidth, + height: originHeight + } = data + const cw = clipWidth || originWidth + const ch = clipHeight || originHeight + if (imageWidth && imageHeight) { + if (imageWidth / imageHeight > cw / ch) { + imageHeight = clipHeight || originHeight; + imageWidth = (width / height) * imageHeight; + } else { + imageWidth = cw; + imageHeight = (height / width) * imageWidth; + } + } else { + let sys = sysinfo || uni.getSystemInfoSync(); + imageWidth = sys.windowWidth; + imageHeight = 0; + } + return { + imageWidth, + imageHeight + }; +} + +/** + * 勾股定理求斜边 + */ +export function calcPythagoreanTheorem(width, height) { + return Math.sqrt(Math.pow(width, 2) + Math.pow(height, 2)); +} + +/** + * 拖动裁剪框时计算 + */ +export function clipTouchMoveOfCalculate(data, event) { + const clientX = event.touches[0].clientX; + const clientY = event.touches[0].clientY; + + let { + clipWidth, + clipHeight, + clipY: oldClipY, + clipX: oldClipX, + clipStart, + isLockRatio, + maxWidth, + minWidth, + maxHeight, + minHeight + } = data; + maxWidth = uni.upx2px(maxWidth) // maxWidth / 2; + minWidth = uni.upx2px(minWidth) // minWidth / 2; + minHeight = uni.upx2px(minHeight) // minHeight / 2; + maxHeight = uni.upx2px(maxHeight) // maxHeight / 2; + + let width = clipWidth, + height = clipHeight, + clipY = oldClipY, + clipX = oldClipX, + // 获取裁剪框实际宽度/高度 + // 如果大于最大值则使用最大值 + // 如果小于最小值则使用最小值 + sizecorrect = () => { + width = width <= maxWidth ? (width >= minWidth ? width : minWidth) : maxWidth; + height = height <= maxHeight ? (height >= minHeight ? height : minHeight) : maxHeight; + }, + sizeinspect = () => { + + if ((width > maxWidth || width < minWidth || height > maxHeight || height < minHeight) && isLockRatio) { + sizecorrect(); + return false; + } else { + sizecorrect(); + return true; + } + }; + //if (clipStart.corner) { + height = clipStart.height + (clipStart.corner > 1 && clipStart.corner < 4 ? 1 : -1) * (clipStart.y - clientY); + //} + switch (clipStart.corner) { + case 1: + width = clipStart.width - clipStart.x + clientX; + if (isLockRatio) { + height = width / (clipWidth / clipHeight); + } + if (!sizeinspect()) return; + break; + case 2: + width = clipStart.width - clipStart.x + clientX; + if (isLockRatio) { + height = width / (clipWidth / clipHeight); + } + if (!sizeinspect()) { + return; + } else { + clipY = clipStart.clipY - (height - clipStart.height); + } + + break; + case 3: + width = clipStart.width + clipStart.x - clientX; + if (isLockRatio) { + height = width / (clipWidth / clipHeight); + } + if (!sizeinspect()) { + return; + } else { + clipY = clipStart.clipY - (height - clipStart.height); + clipX = clipStart.clipX - (width - clipStart.width); + } + + break; + case 4: + width = clipStart.width + clipStart.x - clientX; + if (isLockRatio) { + height = width / (clipWidth / clipHeight); + } + if (!sizeinspect()) { + return; + } else { + clipX = clipStart.clipX - (width - clipStart.width); + } + break; + default: + break; + } + return { + width, + height, + clipX, + clipY + }; +} + +/** + * 单指拖动图片计算偏移 + */ +export function imageTouchMoveOfCalcOffset(data, clientXForLeft, clientYForLeft) { + return { + left: clientXForLeft - data.touchRelative[0].x, + top: clientYForLeft - data.touchRelative[0].y + }; +} diff --git a/uni_modules/lime-clipper/components/lime-clipper/lime-clipper.vue b/uni_modules/lime-clipper/components/lime-clipper/lime-clipper.vue new file mode 100644 index 0000000..5fd80d6 --- /dev/null +++ b/uni_modules/lime-clipper/components/lime-clipper/lime-clipper.vue @@ -0,0 +1,21 @@ + + + + + diff --git a/uni_modules/lime-clipper/package.json b/uni_modules/lime-clipper/package.json new file mode 100644 index 0000000..eec34ed --- /dev/null +++ b/uni_modules/lime-clipper/package.json @@ -0,0 +1,76 @@ +{ + "id": "lime-clipper", + "displayName": "图片剪刀-LimeUI", + "version": "1.0.1", + "description": "一款自我感觉良好的图片裁剪插件", + "keywords": [ + "图片裁剪", + "缩放", + "旋转", + "拖动" +], + "repository": "https://gitee.com/liangei/lime-clipper", + "engines": { + "HBuilderX": "^3.6.4" + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "305716444" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": [], + "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": "u", + "Edge": "u", + "Firefox": "u", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/lime-clipper/readme.md b/uni_modules/lime-clipper/readme.md new file mode 100644 index 0000000..dcc2462 --- /dev/null +++ b/uni_modules/lime-clipper/readme.md @@ -0,0 +1,239 @@ +# Clipper 图片裁剪 +> uniapp 图片裁剪,可用于图片头像等裁剪处理 +> [查看更多 站点1](https://limeui.qcoon.cn/#/clipper)
+> [查看更多 站点2](http://liangei.gitee.io/limeui/#/clipper)
+> Q群:1169785031 + + +## 平台兼容 + +| H5 | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ 小程序 | App | +| --- | ---------- | ------------ | ---------- | ---------- | --------- | --- | +| √ | √ | √ | 未测 | √ | √ | √ | + +## 安装 +在市场导入**[图片剪刀](https://ext.dcloud.net.cn/plugin?id=3594)uni_modules**版本的即可,无需`import` + + + +## 代码演示 +### 基本用法 +`@success` 事件点击 👉 **确定** 后会返回生成的图片信息,包含 `url`、`width`、`height` + +```html + + + +``` + +```js +export default { + data() { + return { + show: false, + url: '', + } + } +} +``` + + +### 传入图片 +`image-url`可传入**相对路径**、**临时路径**、**本地路径**、**网络图片**
+ +* **当为网络地址时** +* H5:👉 需要解决跨域问题。
+* 小程序:👉 需要配置 downloadFile 域名
+ + +```html + + + +``` + +```js +export default { + data() { + return { + imageUrl: 'https://img12.360buyimg.com/pop/s1180x940_jfs/t1/97205/26/1142/87801/5dbac55aEf795d962/48a4d7a63ff80b8b.jpg', + show: false, + url: '', + } + } +} +``` + + +### 确定按钮颜色 +样式变量名:`--clipper_confirm_color`, `nvue` 无效, `nvue`需要通过挂载全局样式表实现。 +可放到全局样式的 `page` 里或节点的 `style` +```html + +``` +```css +// css 中为组件设置 CSS 变量 +.clipper { + --clipper_confirm_color: linear-gradient(to right, #ff6034, #ee0a24) +} +// 全局 +page { + --clipper_confirm_color: linear-gradient(to right, #ff6034, #ee0a24) +} +``` + + +### 使用插槽 +共五个插槽 `cancel` 取消按钮、 `photo` 选择图片按钮、 `rotate` 旋转按钮、 `confirm` 确定按钮和默认插槽。 + +```html + + + + 取消 + 选择图片 + 旋转 + 确定 + + + 显示取消按钮 + + + 显示选择图片按钮 + + + 显示旋转按钮 + + + 显示确定按钮 + + + 锁定裁剪框宽度 + + + 锁定裁剪框高度 + + + 锁定裁剪框比例 + + + 限制移动范围 + + + 禁止缩放 + + + 禁止旋转 + + + + + +``` + +```js +export default { + + data() { + return { + show: false, + url: '', + isLockWidth: false, + isLockHeight: false, + isLockRatio: true, + isLimitMove: false, + isDisableScale: false, + isDisableRotate: false, + isShowCancelBtn: true, + isShowPhotoBtn: true, + isShowRotateBtn: true, + isShowConfirmBtn: true + } + } +} +``` + +### 查看示例 +- 导入后直接使用这个标签查看演示效果 + +```html + + +``` + + +### 插件标签 +- 默认 l-clipper 为 component +- 默认 lime-clipper 为 demo + + + + +## API + +### Props + +| 参数 | 说明 | 类型 | 默认值 | +| ------------- | ------------ | ---------------- | ------------ | +| image-url | 图片路径 | string | | +| quality | 图片的质量,取值范围为 [0, 1],不在范围内时当作1处理 | number | `1` | +| source | `{album: '从相册中选择'}`key为图片来源类型,value为选项说明 | Object | | +| width | 裁剪框宽度,单位为 `rpx` | number | `400` | +| height | 裁剪框高度 | number | `400` | +| min-width | 裁剪框最小宽度 | number | `200` | +| min-height |裁剪框最小高度 | number | `200` | +| max-width | 裁剪框最大宽度 | number | `600` | +| max-height | 裁剪框最大宽度 | number | `600` | +| min-ratio | 图片最小缩放比 | number | `0.5` | +| max-ratio | 图片最大缩放比 | number | `2` | +| rotate-angle | 旋转按钮每次旋转的角度 | number | `90` | +| scale-ratio | 生成图片相对于裁剪框的比例, **比例越高生成图片越清晰** | number | `1` | +| is-lock-width | 是否锁定裁剪框宽度 | boolean | `false` | +| is-lock-height | 是否锁定裁剪框高度上 | boolean | `false` | +| is-lock-ratio | 是否锁定裁剪框比例 | boolean | `true` | +| is-disable-scale | 是否禁止缩放 | boolean | `false` | +| is-disable-rotate | 是否禁止旋转 | boolean | `false` | +| is-limit-move | 是否限制移动范围 | boolean | `false` | +| is-show-photo-btn | 是否显示选择图片按钮 | boolean | `true` | +| is-show-rotate-btn | 是否显示转按钮 | boolean | `true` | +| is-show-confirm-btn | 是否显示确定按钮 | boolean | `true` | +| is-show-cancel-btn | 是否显示关闭按钮 | boolean | `true` | + + + +### 事件 Events + +| 事件名 | 说明 | 回调 | +| ------- | ------------ | -------------- | +| success | 生成图片成功 | {`width`, `height`, `url`} | +| fail | 生成图片失败 | `error` | +| cancel | 关闭 | `false` | +| ready | 图片加载完成 | {`width`, `height`, `path`, `orientation`, `type`} | +| change | 图片大小改变时触发 | {`width`, `height`} | +| rotate | 图片旋转时触发 | `angle` | + +## 常见问题 +- 1、H5端使用网络图片需要解决跨域问题。 +- 2、小程序使用网络图片需要去公众平台增加下载白名单!二级域名也需要配! +- 3、H5端生成图片是base64,有时显示只有一半可以使用原生标签`` +- 4、IOS APP 请勿使用HBX2.9.3.20201014的版本!这个版本无法生成图片。 +- 5、APP端无成功反馈、也无失败反馈时,请更新基座和HBX。 + + +## 打赏 +如果你觉得本插件,解决了你的问题,赠人玫瑰,手留余香。 +![](https://testingcf.jsdelivr.net/gh/liangei/image@1.9/alipay.png) +![](https://testingcf.jsdelivr.net/gh/liangei/image@1.9/wpay.png) \ No newline at end of file diff --git a/uni_modules/lime-clipper/static/photo.svg b/uni_modules/lime-clipper/static/photo.svg new file mode 100644 index 0000000..7b4b590 --- /dev/null +++ b/uni_modules/lime-clipper/static/photo.svg @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/uni_modules/lime-clipper/static/rotate.svg b/uni_modules/lime-clipper/static/rotate.svg new file mode 100644 index 0000000..0143706 --- /dev/null +++ b/uni_modules/lime-clipper/static/rotate.svg @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/uni_modules/lime-painter/changelog.md b/uni_modules/lime-painter/changelog.md new file mode 100644 index 0000000..b988d35 --- /dev/null +++ b/uni_modules/lime-painter/changelog.md @@ -0,0 +1,223 @@ +## 1.9.6.5(2024-04-14) +- fix: 修复`nvue`无法生图的问题 +## 1.9.6.4(2024-03-10) +- fix: 修复代理ctx导致H5不能使用ctx.save +## 1.9.6.3(2024-03-08) +- fix: 修复支付宝真机无法使用的问题 +## 1.9.6.2(2024-02-22) +- fix: 修复使用render函数报错的问题 +## 1.9.6.1(2023-12-22) +- fix: 修复字节小程序非2d字体偏移 +- fix: 修复`canvasToTempFilePathSync`会触发两次的问题 +- fix: 修复`parser`图片没有宽度的问题 +## 1.9.6(2023-12-06) +- fix: 修复背景图受padding影响 +- fix: 修复因字节报错改了代理实现导致微信报错 +- 1.9.5.8(2023-11-16) +- fix: 修复margin问题 +- fix: 修复borderWidth问题 +- fix: 修复textBox问题 +- fix: 修复字节开发工具报`could not be cloned.`问题 +## 1.9.5.7(2023-07-27) +- fix: 去掉多余的方法 +- chore: 更新文档,增加自定义字体说明 +## 1.9.5.6(2023-07-21) +- feat: 有限的支持富文本 +- feat: H5和APP 增加 `hidpi` prop,主要用于大尺寸无法生成图片时用 +- fix: 修复 钉钉小程序 缺少 `measureText` 方法 +- chore: 由于微信小程序 pc 端的 canvas 2d 时不时抽风,故不使用canvas 2d +## 1.9.5.5(2023-06-27) +- fix: 修复把`emoji`表情字符拆分成多个字符的情况 +## 1.9.5.4(2023-06-05) +- fix: 修复因`canvasToTempFilePathSync`监听导致重复调用 +## 1.9.5.3(2023-05-23) +- fix: 因isPc错写成了isPC导致小程序PC不能生成图片 +## 1.9.5.2(2023-05-22) +- feat: 删除多余文件 +## 1.9.5.1(2023-05-22) +- fix: 修复 文字行数与`line-clamp`相同但不满一行时也加了省略号的问题 +## 1.9.5(2023-05-14) +- feat: 增加 `text-indent` 和 `calc` 方法 +- feat: 优化 布局时间 +## 1.9.4.4(2023-04-15) +- fix: 修复无法匹配负值 +- fix: 修复 Nvue IOS getImageInfo `useCORS` 为 undefined +## 1.9.4.3(2023-04-01) +- feat: 增加支持文字描边 `text-stroke: '5rpx #fff'` +## 1.9.4.2(2023-03-30) +- fix: 修复 支付宝小程序 isPC 在手机也为true的问题 +- feat: 由 微信开发工具 3060 版 无法获取图片尺寸,现 微信开发工具 3220 版 修复该问题,故还原上一版的获取图片方式。 +## 1.9.4.1(2023-03-28) +- fix: 修复固定高度不正确问题 +## 1.9.4(2023-03-17) +- fix: nvue ios getImageInfo缺少this报错 +- fix: pathType 非2d无效问题 +- fix: 修复 小米9se 可能会存在多次init 导致画面多次放大 +- fix: 修复 border 分开写 width style无效问题 +- fix: 修复 支付宝小程序IOS 再次进入不渲染的问题 +- fix: 修复 支付宝小程序安卓Zindex排序错乱问题 +- fix: 修复 微信开发工具 3060 版 无法获取图片的问题 +- feat: 把 for in 改为 forEach +- feat: 增加 hidden +- feat: 根节点 box-sizing 默认 `border-box` +- feat: 增加支持 `vw` `wh` +- chore: pathType 取消 默认值,因为字节开发工具不能显示 +- chore: 支付宝小程序开发工具不支持 生成图片 请以真机调试为准 +- bug: 企业微信 2.20.3无法使用 +## 1.9.3.5(2022-06-29) +- feat: justifyContent 增加 `space-around`、`space-between` +- feat: canvas 2d 也使用`getImageInfo` +- fix: 修复 `text`的 `text-decoration`错位 +## 1.9.3.4(2022-06-20) +- fix: 修复 因创建节点速度问题导致顺序出错。 +- fix: 修复 微信小程序 PC 无法显示本地图片 +- fix: 修复 flex-box 对齐问题 +- feat: 增加 `text-shadow` +- feat: 重写 `text` 对齐方式 +- chore: 更新文档 +## 1.9.3.3(2022-06-17) +- fix: 修复 支付宝小程序 canvas 2d 存在ctx.draw问题导致报错 +- fix: 修复 支付宝小程序 toDataURL 存在权限问题改用 `toTempFilePath` +- fix: 修复 支付宝小程序 image size 问题导致 `objectFit` 无效 +## 1.9.3.2(2022-06-14) +- fix: 修复 image 设置背景色不生效问题 +- fix: 修复 nvue 环境判断缺少参数问题 +## 1.9.3.1(2022-06-14) +- fix: 修复 bottom 定位不对问题 +- fix: 修复 因小数导致计算出错换行问题 +- feat: 增加 `useCORS` h5端图片跨域 在设置请求头无效果后试一下设置这个值 +- chore: 更新文档 +## 1.9.3(2022-06-13) +- feat: 增加 `zIndex` +- feat: 增加 `flex-box` 该功能处于原始阶段,非常简陋。 +- tips: QQ小程序 vue3 不支持, 为 uni 官方BUG +## 1.9.2.9(2022-06-10) +- fix: 修复`text-align`及`margin`居中问题 +## 1.9.2.8(2022-06-10) +- fix: 修复 Nvue `canvasToTempFilePathSync` 不生效问题 +## 1.9.2.7(2022-06-10) +- fix: 修复 margin及padding的bug +- fix: 修复 Nvue `isCanvasToTempFilePath` 不生效问题 +## 1.9.2.6(2022-06-09) +- fix: 修复 Nvue 不显示 +- feat: 增加支持字体渐变 +```html + +``` +## 1.9.2.5(2022-06-09) +- chore: 更变获取父级宽度的设定 +- chore: `pathType` 在canvas 2d 默认为 `url` +## 1.9.2.4(2022-06-08) +- fix: 修复 `pathType` 不生效问题 +## 1.9.2.3(2022-06-08) +- fix: 修复 `canvasToTempFilePath` 漏写 `success` 参数 +## 1.9.2.2(2022-06-07) +- chore: 更新文档 +## 1.9.2.1(2022-06-07) +- fix: 修复 vue3 赋值给this再传入导致image无法绘制 +- fix: 修复 `canvasToTempFilePathSync` 时机问题 +- feat: canvas 2d 更改图片生成方式 `toDataURL` +## 1.9.2(2022-05-30) +- fix: 修复 `canvasToTempFilePathSync` 在 vue3 下只生成一次 +## 1.9.1.7(2022-05-28) +- fix: 修复 `qrcode`显示不全问题 +## 1.9.1.6(2022-05-28) +- fix: 修复 `canvasToTempFilePathSync` 会重复多次问题 +- fix: 修复 `view` css `backgroundImage` 图片下载失败导致 子节点不渲染 +## 1.9.1.5(2022-05-27) +- fix: 修正支付宝小程序 canvas 2d版本号 2.7.15 +## 1.9.1.4(2022-05-22) +- fix: 修复字节小程序无法使用xml方式 +- fix: 修复字节小程序无法使用base64(非2D情况下工具上无法显示) +- fix: 修复支付宝小程序 `canvasToTempFilePath` 报错 +## 1.9.1.3(2022-04-29) +- fix: 修复vue3打包后uni对象为空后的报错 +## 1.9.1.2(2022-04-25) +- fix: 删除多余文件 +## 1.9.1.1(2022-04-25) +- fix: 修复图片不显示问题 +## 1.9.1(2022-04-12) +- fix: 因四舍五入导致有些机型错位 +- fix: 修复无views报错 +- chore: nvue下因ios无法读取插件内static文件,改由下载方式 +## 1.9.0(2022-03-20) +- fix: 因无法固定尺寸导致生成图片不全 +- fix: 特定情况下text判断无效 +- chore: 本地化APP Nvue webview +## 1.8.9(2022-02-20) +- fix: 修复 小程序下载最多10次并发的问题 +- fix: 修复 APP端无法获取本地图片 +- fix: 修复 APP Nvue端不执行问题 +- chore: 增加图片缓存机制 +## 1.8.8.8(2022-01-27) +- fix: 修复 主动调用尺寸问题 +## 1.8.8.6(2022-01-26) +- fix: 修复 nvue 下无宽度时获取父级宽度 +- fix: 修复 ios app 无法渲染问题 +## 1.8.8(2022-01-23) +- fix: 修复 主动调用时无节点问题 +- fix: 修复 `box-shadow` 颜色问题 +- fix: 修复 `transform:rotate` 角度位置问题 +- feat: 增加 `overflow:hidden` +## 1.8.7(2022-01-07) +- fix: 修复 image 方向为 `right` 时原始宽高问题 +- feat: 支持 view 设置背景图 `background-image: url(xxx)` +- chore: 去掉可选链 +## 1.8.6(2021-11-28) +- feat: 支持`view`对`inline-block`的子集使用`text-align` +## 1.8.5.5(2021-08-17) +- chore: 更新文档,删除 replace +- fix: 修复 text 值为 number时报错 +## 1.8.5.4(2021-08-16) +- fix: 字节小程序兼容 +## 1.8.5.3(2021-08-15) +- fix: 修复线性渐变与css现实效果不一致的问题 +- chore: 更新文档 +## 1.8.5.2(2021-08-13) +- chore: 增加`background-image`、`background-repeat` 能力,主要用于背景纹理的绘制,并不是代替`image`。例如:大面积的重复平铺的水印 +- 注意:这个功能H5暂时无法使用,因为[官方的API有BUG](https://ask.dcloud.net.cn/question/128793),待官方修复!!! +## 1.8.5.1(2021-08-10) +- fix: 修复因`margin`报错问题 +## 1.8.5(2021-08-09) +- chore: 增加margin支持`auto`,以达到居中效果 +## 1.8.4(2021-08-06) +- chore: 增加判断缓存文件条件 +- fix: 修复css 多余空格报错问题 +## 1.8.3(2021-08-04) +- tips: 1.6.x 以下的版本升级到1.8.x后要为每个元素都加上定位:position: 'absolute' +- fix: 修复只有一个view子元素时不计算高度的问题 +## 1.8.2(2021-08-03) +- fix: 修复 path-type 为 `url` 无效问题 +- fix: 修复 qrcode `text` 为空时报错问题 +- fix: 修复 image `src` 动态设置时不生效问题 +- feat: 增加 css 属性 `min-width` `max-width` +## 1.8.1(2021-08-02) +- fix: 修复无法加载本地图片 +## 1.8.0(2021-08-02) +- chore 文档更新 +- 使用旧版的同学不要升级! +## 1.8.0-beta(2021-07-30) +- ## 全新布局方式 不兼容旧版! +- chore: 布局方式变更 +- tips: 微信canvas 2d 不支持真机调试 +## 1.6.6(2021-07-09) +- chore: 统一命名规范,无须主动引入组件 +## 1.6.5(2021-06-08) +- chore: 去掉console +## 1.6.4(2021-06-07) +- fix: 修复 数字 为纯字符串时不转换的BUG +## 1.6.3(2021-06-06) +- fix: 修复 PC 端放大的BUG +## 1.6.2(2021-05-31) +- fix: 修复 报`adaptor is not a function`错误 +- fix: 修复 text 多行高度 +- fix: 优化 默认文字的基准线 +- feat: `@progress`事件,监听绘制进度 +## 1.6.1(2021-02-28) +- 删除多余节点 +## 1.6.0(2021-02-26) +- 调整为uni_modules目录规范 +- 修复:transform的rotate不能为负数问题 +- 新增:`pathType` 指定生成图片返回的路径类型,可选值有 `base64`、`url` diff --git a/uni_modules/lime-painter/components/common/relation.js b/uni_modules/lime-painter/components/common/relation.js new file mode 100644 index 0000000..6ed37e8 --- /dev/null +++ b/uni_modules/lime-painter/components/common/relation.js @@ -0,0 +1,150 @@ +const styles = (v ='') => v.split(';').filter(v => v && !/^[\n\s]+$/.test(v)).map(v => { + const key = v.slice(0, v.indexOf(':')) + const value = v.slice(v.indexOf(':')+1) + return { + [key + .replace(/-([a-z])/g, function() { return arguments[1].toUpperCase()}) + .replace(/\s+/g, '') + ]: value.replace(/^\s+/, '').replace(/\s+$/, '') || '' + } + }) +export function parent(parent) { + return { + provide() { + return { + [parent]: this + } + }, + data() { + return { + el: { + id: null, + css: {}, + views: [] + }, + } + }, + watch: { + css: { + handler(v) { + if(this.canvasId) { + this.el.css = (typeof v == 'object' ? v : v && Object.assign(...styles(v))) || {} + this.canvasWidth = this.el.css && this.el.css.width || this.canvasWidth + this.canvasHeight = this.el.css && this.el.css.height || this.canvasHeight + } + }, + immediate: true + } + } + } +} +export function children(parent, options = {}) { + const indexKey = options.indexKey || 'index' + return { + inject: { + [parent]: { + default: null + } + }, + watch: { + el: { + handler(v, o) { + if(JSON.stringify(v) != JSON.stringify(o)) + this.bindRelation() + }, + deep: true, + immediate: true + }, + src: { + handler(v, o) { + if(v != o) + this.bindRelation() + }, + immediate: true + }, + text: { + handler(v, o) { + if(v != o) this.bindRelation() + }, + immediate: true + }, + css: { + handler(v, o) { + if(v != o) + this.el.css = (typeof v == 'object' ? v : v && Object.assign(...styles(v))) || {} + }, + immediate: true + }, + replace: { + handler(v, o) { + if(JSON.stringify(v) != JSON.stringify(o)) + this.bindRelation() + }, + deep: true, + immediate: true + } + }, + created() { + if(!this._uid) { + this._uid = this._.uid + } + Object.defineProperty(this, 'parent', { + get: () => this[parent] || [], + }) + Object.defineProperty(this, 'index', { + get: () => { + this.bindRelation(); + const {parent: {el: {views=[]}={}}={}} = this + return views.indexOf(this.el) + }, + }); + this.el.type = this.type + if(this.uid) { + this.el.uid = this.uid + } + this.bindRelation() + }, + // #ifdef VUE3 + beforeUnmount() { + this.removeEl() + }, + // #endif + // #ifdef VUE2 + beforeDestroy() { + this.removeEl() + }, + // #endif + methods: { + removeEl() { + if (this.parent) { + this.parent.el.views = this.parent.el.views.filter( + (item) => item._uid !== this._uid + ); + } + }, + bindRelation() { + if(!this.el._uid) { + this.el._uid = this._uid + } + if(['text','qrcode'].includes(this.type)) { + this.el.text = this.$slots && this.$slots.default && this.$slots.default[0].text || `${this.text || ''}`.replace(/\\n/g, '\n') + } + if(this.type == 'image') { + this.el.src = this.src + } + if (!this.parent) { + return; + } + let views = this.parent.el.views || []; + if(views.indexOf(this.el) !== -1) { + this.parent.el.views = views.map(v => v._uid == this._uid ? this.el : v) + } else { + this.parent.el.views = [...views, this.el]; + } + } + }, + mounted() { + // this.bindRelation() + }, + } +} \ No newline at end of file diff --git a/uni_modules/lime-painter/components/l-painter-image/l-painter-image.vue b/uni_modules/lime-painter/components/l-painter-image/l-painter-image.vue new file mode 100644 index 0000000..e24e3aa --- /dev/null +++ b/uni_modules/lime-painter/components/l-painter-image/l-painter-image.vue @@ -0,0 +1,28 @@ + + + + + diff --git a/uni_modules/lime-painter/components/l-painter-qrcode/l-painter-qrcode.vue b/uni_modules/lime-painter/components/l-painter-qrcode/l-painter-qrcode.vue new file mode 100644 index 0000000..a73e5ed --- /dev/null +++ b/uni_modules/lime-painter/components/l-painter-qrcode/l-painter-qrcode.vue @@ -0,0 +1,27 @@ + + + + + diff --git a/uni_modules/lime-painter/components/l-painter-text/l-painter-text.vue b/uni_modules/lime-painter/components/l-painter-text/l-painter-text.vue new file mode 100644 index 0000000..b332b02 --- /dev/null +++ b/uni_modules/lime-painter/components/l-painter-text/l-painter-text.vue @@ -0,0 +1,33 @@ + + + + + diff --git a/uni_modules/lime-painter/components/l-painter-view/l-painter-view.vue b/uni_modules/lime-painter/components/l-painter-view/l-painter-view.vue new file mode 100644 index 0000000..94596e5 --- /dev/null +++ b/uni_modules/lime-painter/components/l-painter-view/l-painter-view.vue @@ -0,0 +1,34 @@ + + + + + diff --git a/uni_modules/lime-painter/components/l-painter/l-painter.vue b/uni_modules/lime-painter/components/l-painter/l-painter.vue new file mode 100644 index 0000000..83926fd --- /dev/null +++ b/uni_modules/lime-painter/components/l-painter/l-painter.vue @@ -0,0 +1,461 @@ + + + + diff --git a/uni_modules/lime-painter/components/l-painter/nvue.js b/uni_modules/lime-painter/components/l-painter/nvue.js new file mode 100644 index 0000000..25645fb --- /dev/null +++ b/uni_modules/lime-painter/components/l-painter/nvue.js @@ -0,0 +1,214 @@ +// #ifdef APP-NVUE +import { + sleep, + getImageInfo, + isBase64, + networkReg +} from './utils'; +const dom = weex.requireModule('dom') +import { + version +} from '../../package.json' + +export default { + data() { + return { + tempFilePath: [], + isInitFile: false, + osName: uni.getSystemInfoSync().osName + } + }, + methods: { + getParentWeith() { + return new Promise(resolve => { + dom.getComponentRect(this.$refs.limepainter, (res) => { + this.parentWidth = Math.ceil(res.size.width) + this.canvasWidth = this.canvasWidth || this.parentWidth || 300 + this.canvasHeight = res.size.height || this.canvasHeight || 150 + resolve(res.size) + }) + }) + }, + onPageFinish() { + this.webview = this.$refs.webview + this.webview.evalJS(`init(${this.dpr})`) + }, + onMessage(e) { + const res = e.detail.data[0] || null; + if (res.event) { + if (res.event == 'inited') { + this.inited = true + } + if (res.event == 'fail') { + this.$emit('fail', res) + } + if (res.event == 'layoutChange') { + const data = typeof res.data == 'string' ? JSON.parse(res.data) : res.data + this.canvasWidth = Math.ceil(data.width); + this.canvasHeight = Math.ceil(data.height); + } + if (res.event == 'progressChange') { + this.progress = res.data * 1 + } + if (res.event == 'file') { + this.tempFilePath.push(res.data) + if (this.tempFilePath.length > 7) { + this.tempFilePath.shift() + } + return + } + if (res.event == 'success') { + if (res.data) { + this.tempFilePath.push(res.data) + if (this.tempFilePath.length > 8) { + this.tempFilePath.shift() + } + if (this.isCanvasToTempFilePath) { + this.setFilePath(this.tempFilePath.join(''), { + isEmit: true + }) + } + } else { + this.$emit('fail', 'canvas no data') + } + return + } + this.$emit(res.event, JSON.parse(res.data)); + } else if (res.file) { + this.file = res.data; + } else { + console.info(res[0]) + } + }, + getWebViewInited() { + if (this.inited) return Promise.resolve(this.inited); + return new Promise((resolve) => { + this.$watch( + 'inited', + async val => { + if (val) { + resolve(val) + } + }, { + immediate: true + } + ); + }) + }, + getTempFilePath() { + if (this.tempFilePath.length == 8) return Promise.resolve(this.tempFilePath) + return new Promise((resolve) => { + this.$watch( + 'tempFilePath', + async val => { + if (val.length == 8) { + resolve(val.join('')) + } + }, { + deep: true + } + ); + }) + }, + getWebViewDone() { + if (this.progress == 1) return Promise.resolve(this.progress); + return new Promise((resolve) => { + this.$watch( + 'progress', + async val => { + if (val == 1) { + this.$emit('done') + this.done = true + this.runTask() + resolve(val) + } + }, { + immediate: true + } + ); + }) + }, + async render(args) { + try { + await this.getSize(args) + const { + width + } = args.css || args + if (!width && this.parentWidth) { + Object.assign(args, { + width: this.parentWidth + }) + } + const newNode = await this.calcImage(args); + await this.getWebViewInited() + this.webview.evalJS(`source(${JSON.stringify(newNode)})`) + await this.getWebViewDone() + await sleep(this.afterDelay) + if (this.isCanvasToTempFilePath) { + const params = { + fileType: this.fileType, + quality: this.quality + } + this.webview.evalJS(`save(${JSON.stringify(params)})`) + } + return Promise.resolve() + } catch (e) { + this.$emit('fail', e) + } + }, + async calcImage(args) { + let node = JSON.parse(JSON.stringify(args)) + const urlReg = /url\((.+)\)/ + const { + backgroundImage + } = node.css || {} + const isBG = backgroundImage && urlReg.exec(backgroundImage)[1] + const url = node.url || node.src || isBG + if (['text', 'qrcode'].includes(node.type)) { + return node + } + if ((node.type === "image" || isBG) && url && !isBase64(url) && (this.osName == 'ios' || !networkReg + .test(url))) { + let { + path + } = await getImageInfo(url, true) + if (isBG) { + node.css.backgroundImage = `url(${path})` + } else { + node.src = path + } + } else if (node.views && node.views.length) { + for (let i = 0; i < node.views.length; i++) { + node.views[i] = await this.calcImage(node.views[i]) + } + } + return node + }, + async canvasToTempFilePath(args = {}) { + if (!this.inited) { + return this.$emit('fail', 'no init') + } + this.tempFilePath = [] + if (args.fileType == 'jpg') { + args.fileType = 'jpeg' + } + + this.webview.evalJS(`save(${JSON.stringify(args)})`) + try { + let tempFilePath = await this.getTempFilePath() + + tempFilePath = await this.setFilePath(tempFilePath, args) + args.success({ + errMsg: "canvasToTempFilePath:ok", + tempFilePath + }) + } catch (e) { + console.log('e', e) + args.fail({ + error: e + }) + } + } + } +} +// #endif \ No newline at end of file diff --git a/uni_modules/lime-painter/components/l-painter/painter.js b/uni_modules/lime-painter/components/l-painter/painter.js new file mode 100644 index 0000000..bd42fc9 --- /dev/null +++ b/uni_modules/lime-painter/components/l-painter/painter.js @@ -0,0 +1 @@ +var t=function(){return t=Object.assign||function(t){for(var e,i=1,n=arguments.length;i0&&r[r.length-1])||6!==o[0]&&2!==o[0])){s=0;continue}if(3===o[0]&&(!r||o[1]>r[0]&&o[1]=360&&(s-=360);s<0&&(s+=360);if(0===(s=Math.round(s)))return{x0:Math.round(e/2)+n,y0:i+r,x1:Math.round(e/2)+n,y1:r};if(180===s)return{x0:Math.round(e/2)+n,y0:r,x1:Math.round(e/2)+n,y1:i+r};if(90===s)return{x0:n,y0:Math.round(i/2)+r,x1:e+n,y1:Math.round(i/2)+r};if(270===s)return{x0:e+n,y0:Math.round(i/2)+r,x1:n,y1:Math.round(i/2)+r};var a=Math.round(180*Math.asin(e/Math.sqrt(Math.pow(e,2)+Math.pow(i,2)))/Math.PI);if(s===a)return{x0:n,y0:i+r,x1:e+n,y1:r};if(s===180-a)return{x0:n,y0:r,x1:e+n,y1:i+r};if(s===180+a)return{x0:e+n,y0:r,x1:n,y1:i+r};if(s===360-a)return{x0:e+n,y0:i+r,x1:n,y1:r};var h=0,c=0,f=0,l=0;if(s180-a&&s<180||s>180&&s<180+a||s>360-a){var d=s*Math.PI/180,u=s360-a?i/2:-i/2,p=Math.tan(d)*u,g=s180-a&&s<180?e/2-p:-e/2-p;h=-(f=p+(v=Math.pow(Math.sin(d),2)*g)),c=-(l=u+v/Math.tan(d))}if(s>a&&s<90||s>90&&s<90+a||s>180+a&&s<270||s>270&&s<360-a){var v;d=(90-s)*Math.PI/180,p=s>a&&s<90||s>90&&s<90+a?e/2:-e/2,u=Math.tan(d)*p,g=s>a&&s<90||s>270&&s<360-a?i/2-u:-i/2-u;h=-(f=p+(v=Math.pow(Math.sin(d),2)*g)/Math.tan(d)),c=-(l=u+v)}return h=Math.round(h+e/2)+n,c=Math.round(i/2-c)+r,f=Math.round(f+e/2)+n,l=Math.round(i/2-l)+r,{x0:h,y0:c,x1:f,y1:l}}(r,t,e,i,n),a=s.x0,h=s.y0,c=s.x1,f=s.y1,l=o.createLinearGradient(a,h,c,f),d=r.match(/linear-gradient\((.+)\)/)[1],u=L(d.substring(d.indexOf(",")+1)),p=0;pt.length)&&(e=t.length);for(var i=0,n=new Array(e);i=t.length?{done:!0}:{done:!1,value:t[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function C(t){return"number"==typeof t}function H(t){return"auto"===t||null===t}function D(t){return/%$/.test(t)}var Y=p,$=u,U=d,N=g,X=y,_=w,q=m;function G(t){return t.replace(/-([a-z])/g,(function(t,e){return e.toUpperCase()}))}function V(t,e){var i,n,o=function(t){var e=t.match(/([a-z]+)/)[1];return[e,G(t.split(e)[1])]}(t),s=o[0],a=o[1],h=e.split(" ");if(a)return(i={})[s+a]=e,i;if(h.length&&!a){var c=h[0],f=h[1],l=h[2],d=h[3];return(n={})[s+r[0]]=c,n[s+r[1]]=f||c,n[s+r[2]]=l||c,n[s+r[3]]=d||f||c,n}}function J(t){t=t.trim();for(var e=new Array,i="+",n="",r=t.length,o=0;o0;)"("===t[a+=1]&&(s+=1),")"===t[a]&&(s-=1);n="".concat(J(t.slice(o+1,a))),o=a}if(isNaN(Number(t[o]))&&"."!==t[o]||o===r-1){var h=parseFloat(n);switch(i){case"+":e.push(h);break;case"-":e.push(-h);break;case"*":e.push(e.pop()*h);break;case"/":e.push(e.pop()/h)}i=t[o],n=""}}for(var c=0;e.length;)c+=e.pop();return c}var Q,Z=0,K=function(){function t(){R(this,"elements",[]),R(this,"afterElements",[]),R(this,"beforeElements",[]),R(this,"ids",[]),R(this,"width",0),R(this,"height",0),R(this,"top",0),R(this,"left",0),R(this,"pre",null),R(this,"offsetX",0),R(this,"offsetY",0),Z++,this.id=Z}var e=t.prototype;return e.fixedBind=function(t,e){void 0===e&&(e=0),this.container=e?t.parent:t.root,this.container.fixedLine=this,this.fixedAdd(t)},e.fixedAdd=function(t){if(!this.ids.includes(t.id)){this.ids.push(t.id),this.elements.push(t);var e=t.computedStyle.zIndex;(void 0===e?0:e)>=0?this.afterElements.push(t):this.beforeElements.push(t),this.refreshLayout()}},e.bind=function(t){this.container=t.parent,this.container.line=null,this.container.lines?(this.container.lines.push(this),this.pre=this.getPreLine(),this.top=this.pre.top+this.pre.height,this.left=this.container.contentSize.left):(this.top=this.container.contentSize.top,this.left=this.container.contentSize.left,this.container.lines=[this]),this.isInline=t.isInline(),this.container.line=this,this.outerWidth=t.parent&&t.parent.contentSize.width?t.parent.contentSize.width:1/0,this.add(t)},e.getPreLine=function(){return this.container.lines[this.container.lines.length-2]},e.canIEnter=function(t){return!((100*t.offsetSize.width+100*this.width)/100>this.outerWidth)||(this.closeLine(),!1)},e.closeLine=function(){delete this.container.line},e.add=function(t){this.ids.includes(t.id)||(this.ids.push(t.id),this.elements.push(t),this.refreshWidthHeight(t))},e.refreshWidthHeight=function(t){t.offsetSize.height>this.height&&(this.height=t.offsetSize.height),this.width+=t.offsetSize.width||0,(this.container.lineMaxWidth||0)this[this.key.height]&&(this.container[this.key.lineMaxHeight]=this[this.key.height]=i),this[this.key.width]+=this.getWidth(t.offsetSize);var n=Math.min(this.getWidth(this),!this.getWidth(this.container.contentSize)&&1/0);(this.container[this.key.lineMaxWidth]||0)1)return 0;var e=t.style.alignSelf,i=this.getHeight(this.container.contentSize),n=i-this.getHeight(t.offsetSize);return"flex-end"===e?n:"center"===e?n/2:"stretch"===e?(n&&t.name==d&&(t.style[this.key.width]=this.getWidth(t.offsetSize),t.style[this.key.height]=i,delete t.line,delete t.lines,t.getBoxWidthHeight()),0):0},r.layout=function(t,e){var i=this;this.refreshXAlign(),this.pre?(this.top=this.pre.top+this.pre.height+this.offsetY,this.left=e+this.offsetX):(this.top=Math.max(this.top,this.container.contentSize.top,t)+this.offsetY,this.left=Math.max(this.left,this.container.contentSize.left,e)+this.offsetX),this.elements.forEach((function(t,e){i.setIndent(t);var n=i.elements[e-1],r=i.getOffsetY(t);t.style[i.key.top]=i[i.key.top]+r,t.style[i.key.left]=n?n.offsetSize[i.key.left]+i.getWidth(n.offsetSize):i[i.key.left],t.getBoxPosition()}))},n}(K),nt=p,rt=u,ot=d,st=v,at=y,ht=b,ct=w,ft=m,lt=0,dt={left:null,top:null,width:null,height:null},ut=new Map,pt=function(){function t(t,e,i,n){var o=this;R(this,"id",lt++),R(this,"style",{left:null,top:null,width:null,height:null}),R(this,"computedStyle",{}),R(this,"originStyle",{}),R(this,"children",{}),R(this,"layoutBox",F({},dt)),R(this,"contentSize",F({},dt)),R(this,"clientSize",F({},dt)),R(this,"borderSize",F({},dt)),R(this,"offsetSize",F({},dt)),this.ctx=n,this.root=i,e&&(this.parent=e),this.name=t.type||t.name,this.attributes=this.getAttributes(t);var s=function(t,e){var i,n=["color","fontSize","lineHeight","verticalAlign","fontWeight","textAlign"],o=t.type,s=void 0===o?U:o,a=t.styles,h=void 0===a?{}:a,c=(e||{}).computedStyle,f=Object.assign({},S);if([$,Y,N].includes(s)&&!h.display&&(f.display=X),c)for(var l=0;l=0&&l<0,Y=c>=0&&u<0;return i==a[0]&&(this[i].left=t.left+s+v+E+(D?2*-l:0),this[i].top=t.top+c+x+W+(Y?2*-u:0),this[i].width=t.width+(this[i].widthAdd?0:C),this[i].height=t.height+(this[i].heightAdd?0:H),this[i].widthAdd=C,this[i].heightAdd=H),i==a[1]&&(this[i].left=t.left+s+E+(D<0?-l:0),this[i].top=t.top+c+W+(Y?-u:0),this[i].width=t.width+v+w,this[i].height=t.height+x+S),i==a[2]&&(this[i].left=t.left+s+E/2+(D<0?-l:0),this[i].top=t.top+c+W/2+(Y?-u:0),this[i].width=t.width+v+w+E/2+F/2,this[i].height=t.height+x+S+T/2+W/2),i==a[3]&&(this[i].left=t.left+(D<0?-l:0),this[i].top=t.top+(Y?-u:0),this[i].width=t.width+v+w+E+F+s+l,this[i].height=t.height+x+S+T+W+u+c),this[i]},e.layoutBoxUpdate=function(t,e,i,n){var r=this;if(void 0===i&&(i=-1),"border-box"==e.boxSizing){var o=e||{},s=o.border,h=(s=void 0===s?{}:s).borderWidth,c=void 0===h?0:h,f=o.borderTop,l=(f=void 0===f?{}:f).borderTopWidth,d=void 0===l?c:l,u=o.borderBottom,p=(u=void 0===u?{}:u).borderBottomWidth,g=void 0===p?c:p,v=o.borderRight,y=(v=void 0===v?{}:v).borderRightWidth,x=void 0===y?c:y,b=o.borderLeft,w=(b=void 0===b?{}:b).borderLeftWidth,m=void 0===w?c:w,S=o.padding,z=(S=void 0===S?{}:S).paddingTop,I=void 0===z?0:z,M=S.paddingRight,k=void 0===M?0:M,B=S.paddingBottom,W=void 0===B?0:B,P=S.paddingLeft,O=void 0===P?0:P;i||(t.width-=O+k+x+m),1!==i||n||(t.height-=I+W+d+g)}this.layoutBox&&(a.forEach((function(i){return r.layoutBox[i]=r.getOffsetSize(t,e,i)})),this.layoutBox=Object.assign({},this.layoutBox,this.layoutBox.borderSize))},e.getBoxPosition=function(){var t=this.computedStyle,e=this.fixedLine,i=this.lines,n=t.left,r=void 0===n?0:n,o=t.top,s=void 0===o?0:o,a=F({},this.contentSize,{left:r,top:s}),h=this.contentSize.top-this.offsetSize.top,c=this.contentSize.left-this.offsetSize.left;if(this.root.fixedLine&&!this.root.isDone){this.root.isDone=!0;for(var f,l=E(this.root.fixedLine.elements);!(f=l()).done;){var d=f.value;d.setPosition(d,this.root.offsetSize),d.getBoxPosition()}}if(e)for(var u,p=E(e.elements);!(u=p()).done;){var g=u.value,v=F({},this.borderSize,{left:r,top:s});g.setPosition(g,v);var y=this.borderSize.top-this.offsetSize.top,x=this.borderSize.left-this.offsetSize.left;g.style.left+=r+x,g.style.top+=s+y,g.getBoxPosition()}if(i)for(var b,w=E(i);!(b=w()).done;){b.value.layout(a.top+h,a.left+c)}return this.layoutBoxUpdate(a,t),this.layoutBox},e.getBoxState=function(t,e){return this.isBlock(t)||this.isBlock(e)},e.isBlock=function(t){return void 0===t&&(t=this),t&&t.style.display==st},e.isFlex=function(t){return void 0===t&&(t=this),t&&t.style.display==ht},e.isInFlow=function(){return!(this.isAbsolute||this.isFixed)},e.inFlexBox=function(t){return void 0===t&&(t=this),!!t.isInFlow()&&(!!t.parent&&(!(!t.parent||t.parent.style.display!==ht)||void 0))},e.isInline=function(t){return void 0===t&&(t=this),t&&t.style.display==at},e.contrastSize=function(t,e,i){var n=t;return i&&(n=Math.min(n,i)),e&&(n=Math.max(n,e)),n},e.measureText=function(t,e){var i=this.ctx.measureText(t),n=i.width,r=i.actualBoundingBoxAscent,o=i.actualBoundingBoxDescent;return{ascent:r,descent:o,width:n,fontHeight:r+o||.7*e+1}},e.getParentSize=function(t,e){if(void 0===t&&(t=this),void 0===e&&(e=!1),t&&t.parent){if(t.parent.contentSize.width)return t.parent.contentSize;if(e)return this.getParentSize(t.parent,e)}return null},e.getBoxWidthHeight=function(){var t=this,e=this.name,i=this.computedStyle,n=this.attributes,r=this.parent,o=void 0===r?{}:r,s=this.ctx,a=this.getChildren(),h=i.left,c=void 0===h?0:h,f=i.top,l=void 0===f?0:f,d=i.bottom,u=i.right,p=i.width,g=void 0===p?0:p,v=i.minWidth,y=i.maxWidth,x=i.minHeight,b=i.maxHeight,w=i.height,m=void 0===w?0:w,S=i.fontSize,z=i.fontWeight,I=i.fontFamily,M=i.fontStyle,k=i.position;i.textIndent;var B=i.lineClamp,P=i.lineHeight,O=i.padding,T=void 0===O?{}:O,L=i.margin,R=void 0===L?{}:L,F=i.border,A=(F=void 0===F?{}:F).borderWidth,j=void 0===A?0:A,E=i.borderRight,C=(E=void 0===E?{}:E).borderRightWidth,Y=void 0===C?j:C,$=i.borderLeft,U=($=void 0===$?{}:$).borderLeftWidth,N=void 0===U?j:U,X=o.contentSize&&o.contentSize.width,_=o.contentSize&&o.contentSize.height;if(D(g)&&X&&(g=W(g,X)),D(g)&&!X&&(g=null),D(m)&&_&&(m=W(m,_)),D(m)&&!_&&(m=null),D(v)&&X&&(v=W(v,X)),D(y)&&X&&(y=W(y,X)),D(x)&&_&&(x=W(x,_)),D(b)&&_&&(b=W(b,_)),i.padding&&X)for(var q in i.padding)Object.hasOwnProperty.call(T,q)&&(T[q]=W(T[q],X));var G=T.paddingRight,V=void 0===G?0:G,J=T.paddingLeft,Q=void 0===J?0:J;if(i.margin&&[R.marginLeft,R.marginRight].includes("auto"))if(g){var Z=X&&X-g-V-Q-N-Y||0;R.marginLeft==R.marginRight?R.marginLeft=R.marginRight=Z/2:H(R.marginLeft)?R.marginLeft=Z:R.marginRight=Z}else R.marginLeft=R.marginRight=0;var tt=R.marginRight,et=void 0===tt?0:tt,st=R.marginLeft,at={width:g,height:m,left:0,top:0},ht=Q+V+N+Y+(void 0===st?0:st)+et;if(this.offsetWidth=ht,e==rt&&!this.attributes.widths){var ft=n.text||"";s.save(),s.setFonts({fontFamily:I,fontSize:S,fontWeight:z,fontStyle:M}),ft.length,"\n"==ft&&(ft="",this.isBr=!0),(""+ft).split("\n").map((function(e){var i=Array.from(e).map((function(e){var i=""+(/^[\u4e00-\u9fa5]+$/.test(e)?"cn":e)+I+S+z+M,n=ut.get(i);if(n)return{width:n,text:e};var r=t.measureText(e,S).width;return ut.set(i,r),{width:r,text:e}})),n=t.measureText(e,S),r=n.fontHeight,o=n.ascent,s=n.descent;t.attributes.fontHeight=r,t.attributes.ascent=o,t.attributes.descent=s,t.attributes.widths||(t.attributes.widths=[]),t.attributes.widths.push({widths:i,total:i.reduce((function(t,e){return t+e.width}),0)})})),s.restore()}if(e==nt&&null==g){var lt=n.width,dt=n.height;at.width=this.contrastSize(Math.round(lt*m/dt)||0,v,y),this.layoutBoxUpdate(at,i,0)}if(e==rt&&null==g){var pt=this.attributes.widths,gt=Math.max.apply(Math,pt.map((function(t){return t.total})));if(o&&X>0&&(gt>X||this.isBlock(this))&&!this.isAbsolute&&!this.isFixed)gt=X;at.width=this.contrastSize(gt,v,y),this.layoutBoxUpdate(at,i,0)}if(e==rt&&(o.style.flex||!this.attributes.lines)){var vt=this.attributes.widths.length;this.attributes.widths.forEach((function(t){return t.widths.reduce((function(t,e,i){return t+e.width>at.width?(vt++,e.width):t+e.width}),0)})),vt=B&&vt>B?B:vt,this.attributes.lines=vt}if(e==nt&&null==m){var yt=n.width,xt=n.height;n.text,at.height=this.contrastSize(W(at.width*xt/yt)||0,x,b),this.layoutBoxUpdate(at,i,1)}e==rt&&null==m&&(P=W(P,S),at.height=this.contrastSize(W(this.attributes.lines*P),x,b),this.layoutBoxUpdate(at,i,1,!0)),!g&&o&&o.children&&X&&(!this.isFlex(o)||o.isFlexCalc)&&([ot,rt].includes(e)&&this.isFlex()||e==ot&&this.isBlock(this)&&this.isInFlow())&&(at.width=this.contrastSize(X-(o.isFlexCalc?0:ht),v,y),this.layoutBoxUpdate(at,i)),g&&!D(g)&&(at.width=this.contrastSize(g,v,y),this.layoutBoxUpdate(at,i,0)),m&&!D(m)&&(at.height=this.contrastSize(at.height,x,b),this.layoutBoxUpdate(at,i,1));var bt=0;if(a.length){var wt=null,mt=!1;a.forEach((function(e,n){e.getBoxWidthHeight();var r=a[n+1];if(r&&r.isInFlow()&&(e.next=r),!t.line||!t.line.ids.includes(e.id))if(e.isInFlow()&&!e.inFlexBox()){var o=t.getBoxState(wt,e);if(e.isBr)return mt=!0;t.line&&t.line.canIEnter(e)&&!o&&!mt?t.line.add(e):(mt=!1,(new K).bind(e)),wt=e}else e.inFlexBox()?t.line&&(t.line.canIEnter(e)||"nowrap"==i.flexWrap)?t.line.add(e):(new it).bind(e):e.isFixed?t.root.fixedLine?t.root.fixedLine.fixedAdd(e):(new K).fixedBind(e):t.fixedLine?t.fixedLine.fixedAdd(e):(new K).fixedBind(e,1)})),this.lines&&(bt=this.lines.reduce((function(t,e){return t+e.height}),0))}var St=0,zt=0;if(!g&&(this.isAbsolute||this.isFixed)&&X){var It=k==ct?X:this.root.width,Mt=It-(D(c)?W(c,It):c)-(D(u)?W(u,It):u);St=i.left?Mt:this.lineMaxWidth}if(!m&&(null!=l?l:this.isAbsolute||this.isFixed&&_)){var kt=k==ct?_:this.root.height,Bt=kt-(D(l)?W(l,kt):l)-(D(d)?W(d,kt):d);zt=i.top?Bt:0}if(g&&!D(g)||at.width||(at.width=St||this.contrastSize((this.isBlock(this)&&!this.isInFlow()?X||o.lineMaxWidth:this.lineMaxWidth)||this.lineMaxWidth,v,y),this.layoutBoxUpdate(at,i,0)),m||!bt&&!zt||(at.height=zt||this.contrastSize(bt,x,b),this.layoutBoxUpdate(at,i)),i.borderRadius&&this.borderSize&&this.borderSize.width)for(var q in i.borderRadius)Object.hasOwnProperty.call(i.borderRadius,q)&&(i.borderRadius[q]=W(i.borderRadius[q],this.borderSize.width));return this.layoutBox},e.layout=function(){return this.getBoxWidthHeight(),this.root.offsetSize=this.offsetSize,this.root.contentSize=this.contentSize,this.getBoxPosition(),this.offsetSize},t}(),gt=function(){var t,e,i,n,r,o,s=[0,11,15,19,23,27,31,16,18,20,22,24,26,28,20,22,24,24,26,28,28,22,24,24,26,26,28,28,24,24,26,26,26,28,28,24,26,26,26,28,28],a=[3220,1468,2713,1235,3062,1890,2119,1549,2344,2936,1117,2583,1330,2470,1667,2249,2028,3780,481,4011,142,3098,831,3445,592,2517,1776,2234,1951,2827,1070,2660,1345,3177],h=[30660,29427,32170,30877,26159,25368,27713,26998,21522,20773,24188,23371,17913,16590,20375,19104,13663,12392,16177,14854,9396,8579,11994,11245,5769,5054,7399,6608,1890,597,3340,2107],c=[1,0,19,7,1,0,16,10,1,0,13,13,1,0,9,17,1,0,34,10,1,0,28,16,1,0,22,22,1,0,16,28,1,0,55,15,1,0,44,26,2,0,17,18,2,0,13,22,1,0,80,20,2,0,32,18,2,0,24,26,4,0,9,16,1,0,108,26,2,0,43,24,2,2,15,18,2,2,11,22,2,0,68,18,4,0,27,16,4,0,19,24,4,0,15,28,2,0,78,20,4,0,31,18,2,4,14,18,4,1,13,26,2,0,97,24,2,2,38,22,4,2,18,22,4,2,14,26,2,0,116,30,3,2,36,22,4,4,16,20,4,4,12,24,2,2,68,18,4,1,43,26,6,2,19,24,6,2,15,28,4,0,81,20,1,4,50,30,4,4,22,28,3,8,12,24,2,2,92,24,6,2,36,22,4,6,20,26,7,4,14,28,4,0,107,26,8,1,37,22,8,4,20,24,12,4,11,22,3,1,115,30,4,5,40,24,11,5,16,20,11,5,12,24,5,1,87,22,5,5,41,24,5,7,24,30,11,7,12,24,5,1,98,24,7,3,45,28,15,2,19,24,3,13,15,30,1,5,107,28,10,1,46,28,1,15,22,28,2,17,14,28,5,1,120,30,9,4,43,26,17,1,22,28,2,19,14,28,3,4,113,28,3,11,44,26,17,4,21,26,9,16,13,26,3,5,107,28,3,13,41,26,15,5,24,30,15,10,15,28,4,4,116,28,17,0,42,26,17,6,22,28,19,6,16,30,2,7,111,28,17,0,46,28,7,16,24,30,34,0,13,24,4,5,121,30,4,14,47,28,11,14,24,30,16,14,15,30,6,4,117,30,6,14,45,28,11,16,24,30,30,2,16,30,8,4,106,26,8,13,47,28,7,22,24,30,22,13,15,30,10,2,114,28,19,4,46,28,28,6,22,28,33,4,16,30,8,4,122,30,22,3,45,28,8,26,23,30,12,28,15,30,3,10,117,30,3,23,45,28,4,31,24,30,11,31,15,30,7,7,116,30,21,7,45,28,1,37,23,30,19,26,15,30,5,10,115,30,19,10,47,28,15,25,24,30,23,25,15,30,13,3,115,30,2,29,46,28,42,1,24,30,23,28,15,30,17,0,115,30,10,23,46,28,10,35,24,30,19,35,15,30,17,1,115,30,14,21,46,28,29,19,24,30,11,46,15,30,13,6,115,30,14,23,46,28,44,7,24,30,59,1,16,30,12,7,121,30,12,26,47,28,39,14,24,30,22,41,15,30,6,14,121,30,6,34,47,28,46,10,24,30,2,64,15,30,17,4,122,30,29,14,46,28,49,10,24,30,24,46,15,30,4,18,122,30,13,32,46,28,48,14,24,30,42,32,15,30,20,4,117,30,40,7,47,28,43,22,24,30,10,67,15,30,19,6,118,30,18,31,47,28,34,34,24,30,20,61,15,30],f=[255,0,1,25,2,50,26,198,3,223,51,238,27,104,199,75,4,100,224,14,52,141,239,129,28,193,105,248,200,8,76,113,5,138,101,47,225,36,15,33,53,147,142,218,240,18,130,69,29,181,194,125,106,39,249,185,201,154,9,120,77,228,114,166,6,191,139,98,102,221,48,253,226,152,37,179,16,145,34,136,54,208,148,206,143,150,219,189,241,210,19,92,131,56,70,64,30,66,182,163,195,72,126,110,107,58,40,84,250,133,186,61,202,94,155,159,10,21,121,43,78,212,229,172,115,243,167,87,7,112,192,247,140,128,99,13,103,74,222,237,49,197,254,24,227,165,153,119,38,184,180,124,17,68,146,217,35,32,137,46,55,63,209,91,149,188,207,205,144,135,151,178,220,252,190,97,242,86,211,171,20,42,93,158,132,60,57,83,71,109,65,162,31,45,67,216,183,123,164,118,196,23,73,236,127,12,111,246,108,161,59,82,41,157,85,170,251,96,134,177,187,204,62,90,203,89,95,176,156,169,160,81,11,245,22,235,122,117,44,215,79,174,213,233,230,231,173,232,116,214,244,234,168,80,88,175],l=[1,2,4,8,16,32,64,128,29,58,116,232,205,135,19,38,76,152,45,90,180,117,234,201,143,3,6,12,24,48,96,192,157,39,78,156,37,74,148,53,106,212,181,119,238,193,159,35,70,140,5,10,20,40,80,160,93,186,105,210,185,111,222,161,95,190,97,194,153,47,94,188,101,202,137,15,30,60,120,240,253,231,211,187,107,214,177,127,254,225,223,163,91,182,113,226,217,175,67,134,17,34,68,136,13,26,52,104,208,189,103,206,129,31,62,124,248,237,199,147,59,118,236,197,151,51,102,204,133,23,46,92,184,109,218,169,79,158,33,66,132,21,42,84,168,77,154,41,82,164,85,170,73,146,57,114,228,213,183,115,230,209,191,99,198,145,63,126,252,229,215,179,123,246,241,255,227,219,171,75,150,49,98,196,149,55,110,220,165,87,174,65,130,25,50,100,200,141,7,14,28,56,112,224,221,167,83,166,81,162,89,178,121,242,249,239,195,155,43,86,172,69,138,9,18,36,72,144,61,122,244,245,247,243,251,235,203,139,11,22,44,88,176,125,250,233,207,131,27,54,108,216,173,71,142,0],d=[],u=[],p=[],g=[],v=[],y=2;function x(t,e){var i;t>e&&(i=t,t=e,e=i),i=e,i*=e,i+=e,i>>=1,g[i+=t]=1}function b(t,i){var n;for(p[t+e*i]=1,n=-2;n<2;n++)p[t+n+e*(i-2)]=1,p[t-2+e*(i+n+1)]=1,p[t+2+e*(i+n)]=1,p[t+n+1+e*(i+2)]=1;for(n=0;n<2;n++)x(t-1,i+n),x(t+1,i-n),x(t-n,i-1),x(t+n,i+1)}function w(t){for(;t>=255;)t=((t-=255)>>8)+(255&t);return t}var m=[];function S(t,e,i,n){var r,o,s;for(r=0;re&&(i=t,t=e,e=i),i=e,i+=e*e,i>>=1,g[i+=t]}function I(t){var i,n,r,o;switch(t){case 0:for(n=0;n>1&1,i=0;i=5&&(i+=3+v[e]-5);for(e=3;et||3*v[e-3]>=4*v[e]||3*v[e+3]>=4*v[e])&&(i+=40);return i}function k(){var t,i,n,r,o,s=0,a=0;for(i=0;ie*e;)h-=e*e,c++;for(s+=10*c,t=0;t1)for(P=s[t],B=e-7;;){for(M=e-7;M>P-3&&(b(M,B),!(M6)for(P=a[t-7],W=17,M=0;M<6;M++)for(B=0;B<3;B++,W--)1&(W>11?t>>W-12:P>>W)?(p[5-M+e*(2-B+e-11)]=1,p[2-B+e-11+e*(5-M)]=1):(x(5-M,2-B+e-11),x(2-B+e-11,5-M));for(B=0;B=(M=r*(i+n)+n)-2&&(O=M-2,t>9&&O--),T=O,t>9){for(d[T+2]=0,d[T+3]=0;T--;)P=d[T],d[T+3]|=255&P<<4,d[T+2]=P>>4;d[2]|=255&O<<4,d[1]=O>>4,d[0]=64|O>>12}else{for(d[T+1]=0,d[T+2]=0;T--;)P=d[T],d[T+2]|=255&P<<4,d[T+1]=P>>4;d[1]|=255&O<<4,d[0]=64|O>>4}for(T=O+3-(t<10);T0;L--)m[L]=m[L]?m[L-1]^l[w(f[m[L]]+T)]:m[L-1];m[0]=l[w(f[m[0]]+T)]}for(T=0;T<=o;T++)m[T]=f[m[T]];for(W=M,B=0,T=0;T>=1)1&B&&(p[e-1-W+8*e]=1,W<6?p[8+e*W]=1:p[8+e*(W+1)]=1);for(W=0;W<7;W++,B>>=1)1&B&&(p[8+e*(e-7+W)]=1,W?p[6-W+8*e]=1:p[7+8*e]=1);return p}(v)},utf16to8:function(t){var e,i,n,r;for(e="",n=t.length,i=0;i=1&&r<=127?e+=t.charAt(i):r>2047?(e+=String.fromCharCode(224|r>>12&15),e+=String.fromCharCode(128|r>>6&63),e+=String.fromCharCode(128|r>>0&63)):(e+=String.fromCharCode(192|r>>6&31),e+=String.fromCharCode(128|r>>0&63));return e},draw:function(t,i,n,r,o){i.drawView(n,r);var s=i.ctx,a=n.contentSize,h=a.width,c=a.height,f=a.left,l=a.top;r.borderRadius,r.backgroundColor;var d=r.color,u=void 0===d?"#000000":d;r.border,n.contentSize.left,n.borderSize.left,n.contentSize.top,n.borderSize.top;if(y=o||y,s){s.save(),i.setOpacity(r),i.setTransform(n,r);var p=Math.min(h,c);t=this.utf16to8(t);var g=this.getFrame(t),v=p/e;s.setFillStyle(u);for(var x=0;x=s||n==c&&o=s)&&(a=e.width/i.width);var f=i.width*a,l=i.height*a,d=r||[],u=d[0],p=d[1],g=B(u)?W(u,e.width):(e.width-f)*(P(u)?W(u,1):{left:0,center:.5,right:1}[u||"center"]),v=B(p)?W(p,e.height):(e.height-l)*(P(p)?W(p,1):{top:0,center:.5,bottom:1}[p||"center"]),y=function(t,e){return[(t-g)/a,(e-v)/a]},x=y(0,0),b=x[0],w=x[1],m=y(e.width,e.height),S=m[0],z=m[1],I=Math.max,M=Math.min;return{sx:I(b,0),sy:I(w,0),sw:M(S-b,i.width),sh:M(z-w,i.height),dx:I(g,0),dy:I(v,0),dw:M(f,e.width),dh:M(l,e.height)}}({objectFit:u,objectPosition:v},r.contentSize,t),o=i.sx,s=i.sy,a=i.sh,h=i.sw,c=i.dx,f=i.dy,l=i.dh,d=i.dw;I==n.MP_BAIDU?e.drawImage(t.src,c+m,f+S,d,l,o,s,h,a):e.drawImage(t.src,o,s,h,a,c+m,f+S,d,l)}else e.drawImage(t.src,m,S,b,w)},O=function(){e.restore(),L.drawView(r,o,!1,!0,!1),h(1)},T=function(t){k(t),O()},T(t),[2]}))}))}))];case 1:return h.sent(),[2]}}))}))},r.prototype.drawText=function(t,e,i,n){var r=this,o=this.ctx,s=e.borderSize,a=e.contentSize,h=e.left,c=e.top,f=a.width,l=a.height,d=a.left-s.left||0,u=a.top-s.top||0,p=i.color,g=i.lineHeight,v=i.fontSize,y=i.fontWeight,x=i.fontFamily,b=i.fontStyle,w=i.textIndent,m=void 0===w?0:w,S=i.textAlign,z=i.textStroke,I=i.verticalAlign,M=void 0===I?mt:I,k=i.backgroundColor,P=i.lineClamp,O=i.backgroundClip,T=i.textShadow,L=i.textDecoration;if(m=B(m)?m:0,this.drawView(e,i,O!=yt),g=W(g,v),t){o.save(),h+=d,c+=u;var R=n.fontHeight,F=n.descent,A=void 0===F?0:F,j=n.ascent,E=A+(void 0===j?0:j);switch(o.setFonts({fontFamily:x,fontSize:v,fontWeight:y,fontStyle:b}),o.setTextBaseline(mt),o.setTextAlign(S),O?this.setBackground(k,f,l,h,c):o.setFillStyle(p),S){case zt:break;case It:h+=.5*f;break;case Mt:h+=f}var C=n.lines*g,H=Math.ceil((l-C)/2);switch(H<0&&(H=0),M){case wt:break;case mt:c+=H;break;case St:c+=2*H}var D=(g-R)/2,Y=g/2,$=function(t){var e=o.measureText(t),i=e.actualBoundingBoxDescent,n=void 0===i?0:i,r=e.actualBoundingBoxAscent;return M==wt?{fix:E?void 0===r?0:r:Y-D/2,lineY:E?0:D-D/2}:M==mt?{fix:E?Y+n/4:Y,lineY:E?0:D}:M==St?{fix:E?g-n:Y+D/2,lineY:E?2*D:D+D/2}:{fix:0,height:0,lineY:0}},U=function(t,e,i){var r=t;switch(S){case zt:r+=i;break;case It:r=(t-=i/2)+i;break;case Mt:r=t,t-=i}if(L){o.setLineWidth(v/13),o.beginPath();var s=.1*n.fontHeight;/\bunderline\b/.test(L)&&(o.moveTo(t,e+n.fontHeight+s),o.lineTo(r,e+n.fontHeight+s)),/\boverline\b/.test(L)&&(o.moveTo(t,e-s),o.lineTo(r,e-s)),/\bline-through\b/.test(L)&&(o.moveTo(t,e+.5*n.fontHeight),o.lineTo(r,e+.5*n.fontHeight)),o.closePath(),o.setStrokeStyle(p),o.stroke()}},N=function(t,e,i){var n=function(){o.setLineWidth(z.width),o.setStrokeStyle(z.color),o.strokeText(t,e,i)},s="outset";z&&z.type!==s?(o.save(),r.setShadow({boxShadow:T}),o.fillText(t,e,i),o.restore(),n()):z&&z.type==s?(o.save(),r.setShadow({boxShadow:T}),n(),o.restore(),o.save(),o.fillText(t,e,i),o.restore()):(r.setShadow({boxShadow:T}),o.fillText(t,e,i))};if(!n.widths||1==n.widths.length&&n.widths[0].total+m<=a.width){var X=$(t),_=X.fix,q=void 0===_?0:_,G=X.lineY;return N(t,h+m,c+q),U(h+m,c+G,n&&n.widths&&n.widths[0].total||n.text),c+=g,o.restore(),void this.setBorder(e,i)}for(var V=c,J=h,Q="",Z=0,K=o.measureText("...").width,tt=n.widths,et=0;eta.width){Z>=P&&(Q+="…"),Z++,nt=0;var ct=$(Q);q=ct.fix,G=ct.lineY;N(Q,J,c+q),U(J,c+G,nt),c+=g,Q=""}else if(rt==it.length-1){et!=tt.length-1&&Z==P&&K+ntV+l||Z>P)break}}o.restore()}},r.prototype.source=function(t){return e(this,void 0,void 0,(function(){var e,n,r,o,s=this;return i(this,(function(i){switch(i.label){case 0:if(this.node=null,e=+new Date,"{}"==JSON.stringify(t))return[2];if(t.styles=t.styles||t.css||{},!t.type)for(n in t.type=bt,t)["views","children","type","css","styles"].includes(n)||(t.styles[n]=t[n],delete t[n]);return t.styles.boxSizing||(t.styles.boxSizing="border-box"),[4,this.create(t)];case 1:return(r=i.sent())?(o=r.layout()||{},this.size=o,this.node=r,this.onEffectFinished().then((function(t){return s.lifecycle("onEffectSuccess",t)})).catch((function(t){return s.lifecycle("onEffectFail",t)})),this.performance&&console.log("布局用时:"+(+new Date-e)+"ms"),[2,this.size]):[2,console.warn("no node")]}}))}))},r.prototype.getImageInfo=function(t){return this.imageBus[t]||(this.imageBus[t]=this.createImage(t,this.useCORS)),this.imageBus[t]},r.prototype.create=function(n,r){return e(this,void 0,void 0,(function(){function e(i,n,r){void 0===n&&(n={}),void 0===r&&(r=!0);var o=[];return i.forEach((function(i){var s=i.styles,a=void 0===s?{}:s,h=i.css,c=void 0===h?{}:h,f=i.children,l=void 0===f?[]:f,d=i.views,u=void 0===d?[]:d,p=i.text,g=void 0===p?"":p,v=i.type,y=void 0===v?"":v;!l&&u&&(i.children=l=u);var x={};x=t(t(r?t({},n):{},a),c);var b={},w={},m={};Object.keys(x).map((function(t){if(t.includes("padding")||t.includes("margin")){var e=V(t,x[t]);Object.keys(e).map((function(t){t.includes("Left")?w[t]=e[t]:t.includes("Right")?m[t]=e[t]:b[t]=e[t]}))}}));if(x.textIndent&&(w.textIndent=x.textIndent,delete n.textIndent),""!==g){var S=Array.from(g);S.forEach((function(t,e){var i=Object.assign({},x,b);0===e?Object.assign(i,w):e==S.length-1&&Object.assign(i,m),delete i.padding,delete i.margin,o.push({type:"text",text:t,styles:i})}))}if(y==vt||y==xt)o.push(i);else if("block"===a.display&&l.length>0){var z=e(l,x,!1);i.children=z,i.flattened=!0,o.push(i)}else if(l.length>0){z=e(l,x,r);o=o.concat(z)}})),o}var o,s,a,h,c,f,l,d,u,p,g,v,y,b,w,m,S,z,I,M,k,B,W,P;return i(this,(function(i){switch(i.label){case 0:if(!n)return[2];if(n.styles||(n.styles=n.css||{}),o=n.type,s=n.show,a=void 0===s||s,h=o==vt,c=[yt,xt].includes(o),f="textBox"==o,l=n.styles||{},d=l.backgroundImage,u=l.display,h&&!n.src&&!n.url)return[2];if(u==x||!a)return[2];if(c||f){if(p=n.children,g=n.views,!p&&g&&(n.children=p=g),!n.text&&(!p||p&&!p.length))return[2];p&&p.length&&!n.flattened&&(v=e(n.children||n.views),n.type="view",n.children=v)}if(!(h||n.type==bt&&d))return[3,4];y=h?n.src:"",b=/url\(['"]?(.*?)['"]?\)/.exec(d),d&&b&&b[1]&&(y=b[1]||""),i.label=1;case 1:return i.trys.push([1,3,,4]),[4,this.getImageInfo(y)];case 2:return w=i.sent(),m=w.width,S=w.height,!(z=w.path)&&h?[2]:(z&&(n.attributes=Object.assign(n.attributes||{},{width:m,height:S,path:z,src:z,naturalSrc:y})),[3,4]);case 3:return I=i.sent(),n.type!=bt?[2]:(this.lifecycle("onEffectFail",t(t({},I),{src:y})),[3,4]);case 4:if(this.count+=1,M=new pt(n,r,this.root,this.ctx),!(k=n.children||n.views))return[3,8];B=0,i.label=5;case 5:return B0&&r[r.length-1])||6!==o[0]&&2!==o[0])){s=0;continue}if(3===o[0]&&(!r||o[1]>r[0]&&o[1]=360&&(s-=360);s<0&&(s+=360);if(0===(s=Math.round(s)))return{x0:Math.round(e/2)+n,y0:i+r,x1:Math.round(e/2)+n,y1:r};if(180===s)return{x0:Math.round(e/2)+n,y0:r,x1:Math.round(e/2)+n,y1:i+r};if(90===s)return{x0:n,y0:Math.round(i/2)+r,x1:e+n,y1:Math.round(i/2)+r};if(270===s)return{x0:e+n,y0:Math.round(i/2)+r,x1:n,y1:Math.round(i/2)+r};var h=Math.round(180*Math.asin(e/Math.sqrt(Math.pow(e,2)+Math.pow(i,2)))/Math.PI);if(s===h)return{x0:n,y0:i+r,x1:e+n,y1:r};if(s===180-h)return{x0:n,y0:r,x1:e+n,y1:i+r};if(s===180+h)return{x0:e+n,y0:r,x1:n,y1:i+r};if(s===360-h)return{x0:e+n,y0:i+r,x1:n,y1:r};var a=0,l=0,d=0,c=0;if(s180-h&&s<180||s>180&&s<180+h||s>360-h){var f=s*Math.PI/180,u=s360-h?i/2:-i/2,p=Math.tan(f)*u,g=s180-h&&s<180?e/2-p:-e/2-p;a=-(d=p+(v=Math.pow(Math.sin(f),2)*g)),l=-(c=u+v/Math.tan(f))}if(s>h&&s<90||s>90&&s<90+h||s>180+h&&s<270||s>270&&s<360-h){var v;f=(90-s)*Math.PI/180,p=s>h&&s<90||s>90&&s<90+h?e/2:-e/2,u=Math.tan(f)*p,g=s>h&&s<90||s>270&&s<360-h?i/2-u:-i/2-u;a=-(d=p+(v=Math.pow(Math.sin(f),2)*g)/Math.tan(f)),l=-(c=u+v)}return a=Math.round(a+e/2)+n,l=Math.round(i/2-l)+r,d=Math.round(d+e/2)+n,c=Math.round(i/2-c)+r,{x0:a,y0:l,x1:d,y1:c}}(r,t,e,i,n),h=s.x0,a=s.y0,l=s.x1,d=s.y1,c=o.createLinearGradient(h,a,l,d),f=r.match(/linear-gradient\((.+)\)/)[1],u=L(f.substring(f.indexOf(",")+1)),p=0;pt.length)&&(e=t.length);for(var i=0,n=new Array(e);i=t.length?{done:!0}:{done:!1,value:t[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function H(t){return"number"==typeof t}function C(t){return"auto"===t||null===t}function D(t){return/%$/.test(t)}var Y=p,$=u,U=f,N=g,X=y,_=w,q=m;function G(t){return t.replace(/-([a-z])/g,(function(t,e){return e.toUpperCase()}))}function V(t,e){var i,n,o=function(t){var e=t.match(/([a-z]+)/)[1];return[e,G(t.split(e)[1])]}(t),s=o[0],h=o[1],a=e.split(" ");if(h)return(i={})[s+h]=e,i;if(a.length&&!h){var l=a[0],d=a[1],c=a[2],f=a[3];return(n={})[s+r[0]]=l,n[s+r[1]]=d||l,n[s+r[2]]=c||l,n[s+r[3]]=f||d||l,n}}function J(t){t=t.trim();for(var e=new Array,i="+",n="",r=t.length,o=0;o0;)"("===t[h+=1]&&(s+=1),")"===t[h]&&(s-=1);n="".concat(J(t.slice(o+1,h))),o=h}if(isNaN(Number(t[o]))&&"."!==t[o]||o===r-1){var a=parseFloat(n);switch(i){case"+":e.push(a);break;case"-":e.push(-a);break;case"*":e.push(e.pop()*a);break;case"/":e.push(e.pop()/a)}i=t[o],n=""}}for(var l=0;e.length;)l+=e.pop();return l}var Q,Z=0,K=function(){function t(){R(this,"elements",[]),R(this,"afterElements",[]),R(this,"beforeElements",[]),R(this,"ids",[]),R(this,"width",0),R(this,"height",0),R(this,"top",0),R(this,"left",0),R(this,"pre",null),R(this,"offsetX",0),R(this,"offsetY",0),Z++,this.id=Z}var e=t.prototype;return e.fixedBind=function(t,e){void 0===e&&(e=0),this.container=e?t.parent:t.root,this.container.fixedLine=this,this.fixedAdd(t)},e.fixedAdd=function(t){if(!this.ids.includes(t.id)){this.ids.push(t.id),this.elements.push(t);var e=t.computedStyle.zIndex;(void 0===e?0:e)>=0?this.afterElements.push(t):this.beforeElements.push(t),this.refreshLayout()}},e.bind=function(t){this.container=t.parent,this.container.line=null,this.container.lines?(this.container.lines.push(this),this.pre=this.getPreLine(),this.top=this.pre.top+this.pre.height,this.left=this.container.contentSize.left):(this.top=this.container.contentSize.top,this.left=this.container.contentSize.left,this.container.lines=[this]),this.isInline=t.isInline(),this.container.line=this,this.outerWidth=t.parent&&t.parent.contentSize.width?t.parent.contentSize.width:1/0,this.add(t)},e.getPreLine=function(){return this.container.lines[this.container.lines.length-2]},e.canIEnter=function(t){return!((100*t.offsetSize.width+100*this.width)/100>this.outerWidth)||(this.closeLine(),!1)},e.closeLine=function(){delete this.container.line},e.add=function(t){this.ids.includes(t.id)||(this.ids.push(t.id),this.elements.push(t),this.refreshWidthHeight(t))},e.refreshWidthHeight=function(t){t.offsetSize.height>this.height&&(this.height=t.offsetSize.height),this.width+=t.offsetSize.width||0,(this.container.lineMaxWidth||0)this[this.key.height]&&(this.container[this.key.lineMaxHeight]=this[this.key.height]=i),this[this.key.width]+=this.getWidth(t.offsetSize);var n=Math.min(this.getWidth(this),!this.getWidth(this.container.contentSize)&&1/0);(this.container[this.key.lineMaxWidth]||0)1)return 0;var e=t.style.alignSelf,i=this.getHeight(this.container.contentSize),n=i-this.getHeight(t.offsetSize);return"flex-end"===e?n:"center"===e?n/2:"stretch"===e?(n&&t.name==f&&(t.style[this.key.width]=this.getWidth(t.offsetSize),t.style[this.key.height]=i,delete t.line,delete t.lines,t.getBoxWidthHeight()),0):0},r.layout=function(t,e){var i=this;this.refreshXAlign(),this.pre?(this.top=this.pre.top+this.pre.height+this.offsetY,this.left=e+this.offsetX):(this.top=Math.max(this.top,this.container.contentSize.top,t)+this.offsetY,this.left=Math.max(this.left,this.container.contentSize.left,e)+this.offsetX),this.elements.forEach((function(t,e){i.setIndent(t);var n=i.elements[e-1],r=i.getOffsetY(t);t.style[i.key.top]=i[i.key.top]+r,t.style[i.key.left]=n?n.offsetSize[i.key.left]+i.getWidth(n.offsetSize):i[i.key.left],t.getBoxPosition()}))},n}(K),nt=p,rt=u,ot=f,st=v,ht=y,at=b,lt=w,dt=m,ct=0,ft={left:null,top:null,width:null,height:null},ut=new Map,pt=function(){function t(t,e,i,n){var o=this;R(this,"id",ct++),R(this,"style",{left:null,top:null,width:null,height:null}),R(this,"computedStyle",{}),R(this,"originStyle",{}),R(this,"children",{}),R(this,"layoutBox",F({},ft)),R(this,"contentSize",F({},ft)),R(this,"clientSize",F({},ft)),R(this,"borderSize",F({},ft)),R(this,"offsetSize",F({},ft)),this.ctx=n,this.root=i,e&&(this.parent=e),this.name=t.type||t.name,this.attributes=this.getAttributes(t);var s=function(t,e){var i,n=["color","fontSize","lineHeight","verticalAlign","fontWeight","textAlign"],o=t.type,s=void 0===o?U:o,h=t.styles,a=void 0===h?{}:h,l=(e||{}).computedStyle,d=Object.assign({},S);if([$,Y,N].includes(s)&&!a.display&&(d.display=X),l)for(var c=0;c=0&&c<0,Y=l>=0&&u<0;return i==h[0]&&(this[i].left=t.left+s+v+E+(D?2*-c:0),this[i].top=t.top+l+x+k+(Y?2*-u:0),this[i].width=t.width+(this[i].widthAdd?0:H),this[i].height=t.height+(this[i].heightAdd?0:C),this[i].widthAdd=H,this[i].heightAdd=C),i==h[1]&&(this[i].left=t.left+s+E+(D<0?-c:0),this[i].top=t.top+l+k+(Y?-u:0),this[i].width=t.width+v+w,this[i].height=t.height+x+S),i==h[2]&&(this[i].left=t.left+s+E/2+(D<0?-c:0),this[i].top=t.top+l+k/2+(Y?-u:0),this[i].width=t.width+v+w+E/2+F/2,this[i].height=t.height+x+S+T/2+k/2),i==h[3]&&(this[i].left=t.left+(D<0?-c:0),this[i].top=t.top+(Y?-u:0),this[i].width=t.width+v+w+E+F+s+c,this[i].height=t.height+x+S+T+k+u+l),this[i]},e.layoutBoxUpdate=function(t,e,i,n){var r=this;if(void 0===i&&(i=-1),"border-box"==e.boxSizing){var o=e||{},s=o.border,a=(s=void 0===s?{}:s).borderWidth,l=void 0===a?0:a,d=o.borderTop,c=(d=void 0===d?{}:d).borderTopWidth,f=void 0===c?l:c,u=o.borderBottom,p=(u=void 0===u?{}:u).borderBottomWidth,g=void 0===p?l:p,v=o.borderRight,y=(v=void 0===v?{}:v).borderRightWidth,x=void 0===y?l:y,b=o.borderLeft,w=(b=void 0===b?{}:b).borderLeftWidth,m=void 0===w?l:w,S=o.padding,z=(S=void 0===S?{}:S).paddingTop,I=void 0===z?0:z,M=S.paddingRight,B=void 0===M?0:M,W=S.paddingBottom,k=void 0===W?0:W,P=S.paddingLeft,O=void 0===P?0:P;i||(t.width-=O+B+x+m),1!==i||n||(t.height-=I+k+f+g)}this.layoutBox&&(h.forEach((function(i){return r.layoutBox[i]=r.getOffsetSize(t,e,i)})),this.layoutBox=Object.assign({},this.layoutBox,this.layoutBox.borderSize))},e.getBoxPosition=function(){var t=this.computedStyle,e=this.fixedLine,i=this.lines,n=t.left,r=void 0===n?0:n,o=t.top,s=void 0===o?0:o,h=F({},this.contentSize,{left:r,top:s}),a=this.contentSize.top-this.offsetSize.top,l=this.contentSize.left-this.offsetSize.left;if(this.root.fixedLine&&!this.root.isDone){this.root.isDone=!0;for(var d,c=E(this.root.fixedLine.elements);!(d=c()).done;){var f=d.value;f.setPosition(f,this.root.offsetSize),f.getBoxPosition()}}if(e)for(var u,p=E(e.elements);!(u=p()).done;){var g=u.value,v=F({},this.borderSize,{left:r,top:s});g.setPosition(g,v);var y=this.borderSize.top-this.offsetSize.top,x=this.borderSize.left-this.offsetSize.left;g.style.left+=r+x,g.style.top+=s+y,g.getBoxPosition()}if(i)for(var b,w=E(i);!(b=w()).done;){b.value.layout(h.top+a,h.left+l)}return this.layoutBoxUpdate(h,t),this.layoutBox},e.getBoxState=function(t,e){return this.isBlock(t)||this.isBlock(e)},e.isBlock=function(t){return void 0===t&&(t=this),t&&t.style.display==st},e.isFlex=function(t){return void 0===t&&(t=this),t&&t.style.display==at},e.isInFlow=function(){return!(this.isAbsolute||this.isFixed)},e.inFlexBox=function(t){return void 0===t&&(t=this),!!t.isInFlow()&&(!!t.parent&&(!(!t.parent||t.parent.style.display!==at)||void 0))},e.isInline=function(t){return void 0===t&&(t=this),t&&t.style.display==ht},e.contrastSize=function(t,e,i){var n=t;return i&&(n=Math.min(n,i)),e&&(n=Math.max(n,e)),n},e.measureText=function(t,e){var i=this.ctx.measureText(t),n=i.width,r=i.actualBoundingBoxAscent,o=i.actualBoundingBoxDescent;return{ascent:r,descent:o,width:n,fontHeight:r+o||.7*e+1}},e.getParentSize=function(t,e){if(void 0===t&&(t=this),void 0===e&&(e=!1),t&&t.parent){if(t.parent.contentSize.width)return t.parent.contentSize;if(e)return this.getParentSize(t.parent,e)}return null},e.getBoxWidthHeight=function(){var t=this,e=this.name,i=this.computedStyle,n=this.attributes,r=this.parent,o=void 0===r?{}:r,s=this.ctx,h=this.getChildren(),a=i.left,l=void 0===a?0:a,d=i.top,c=void 0===d?0:d,f=i.bottom,u=i.right,p=i.width,g=void 0===p?0:p,v=i.minWidth,y=i.maxWidth,x=i.minHeight,b=i.maxHeight,w=i.height,m=void 0===w?0:w,S=i.fontSize,z=i.fontWeight,I=i.fontFamily,M=i.fontStyle,B=i.position;i.textIndent;var W=i.lineClamp,P=i.lineHeight,O=i.padding,T=void 0===O?{}:O,L=i.margin,R=void 0===L?{}:L,F=i.border,A=(F=void 0===F?{}:F).borderWidth,j=void 0===A?0:A,E=i.borderRight,H=(E=void 0===E?{}:E).borderRightWidth,Y=void 0===H?j:H,$=i.borderLeft,U=($=void 0===$?{}:$).borderLeftWidth,N=void 0===U?j:U,X=o.contentSize&&o.contentSize.width,_=o.contentSize&&o.contentSize.height;if(D(g)&&X&&(g=k(g,X)),D(g)&&!X&&(g=null),D(m)&&_&&(m=k(m,_)),D(m)&&!_&&(m=null),D(v)&&X&&(v=k(v,X)),D(y)&&X&&(y=k(y,X)),D(x)&&_&&(x=k(x,_)),D(b)&&_&&(b=k(b,_)),i.padding&&X)for(var q in i.padding)Object.hasOwnProperty.call(T,q)&&(T[q]=k(T[q],X));var G=T.paddingRight,V=void 0===G?0:G,J=T.paddingLeft,Q=void 0===J?0:J;if(i.margin&&[R.marginLeft,R.marginRight].includes("auto"))if(g){var Z=X&&X-g-V-Q-N-Y||0;R.marginLeft==R.marginRight?R.marginLeft=R.marginRight=Z/2:C(R.marginLeft)?R.marginLeft=Z:R.marginRight=Z}else R.marginLeft=R.marginRight=0;var tt=R.marginRight,et=void 0===tt?0:tt,st=R.marginLeft,ht={width:g,height:m,left:0,top:0},at=Q+V+N+Y+(void 0===st?0:st)+et;if(this.offsetWidth=at,e==rt&&!this.attributes.widths){var dt=n.text||"";s.save(),s.setFonts({fontFamily:I,fontSize:S,fontWeight:z,fontStyle:M}),dt.length,"\n"==dt&&(dt="",this.isBr=!0),(""+dt).split("\n").map((function(e){var i=Array.from(e).map((function(e){var i=""+(/^[\u4e00-\u9fa5]+$/.test(e)?"cn":e)+I+S+z+M,n=ut.get(i);if(n)return{width:n,text:e};var r=t.measureText(e,S).width;return ut.set(i,r),{width:r,text:e}})),n=t.measureText(e,S),r=n.fontHeight,o=n.ascent,s=n.descent;t.attributes.fontHeight=r,t.attributes.ascent=o,t.attributes.descent=s,t.attributes.widths||(t.attributes.widths=[]),t.attributes.widths.push({widths:i,total:i.reduce((function(t,e){return t+e.width}),0)})})),s.restore()}if(e==nt&&null==g){var ct=n.width,ft=n.height;ht.width=this.contrastSize(Math.round(ct*m/ft)||0,v,y),this.layoutBoxUpdate(ht,i,0)}if(e==rt&&null==g){var pt=this.attributes.widths,gt=Math.max.apply(Math,pt.map((function(t){return t.total})));if(o&&X>0&&(gt>X||this.isBlock(this))&&!this.isAbsolute&&!this.isFixed)gt=X;ht.width=this.contrastSize(gt,v,y),this.layoutBoxUpdate(ht,i,0)}if(e==rt&&(o.style.flex||!this.attributes.lines)){var vt=this.attributes.widths.length;this.attributes.widths.forEach((function(t){return t.widths.reduce((function(t,e,i){return t+e.width>ht.width?(vt++,e.width):t+e.width}),0)})),vt=W&&vt>W?W:vt,this.attributes.lines=vt}if(e==nt&&null==m){var yt=n.width,xt=n.height;n.text,ht.height=this.contrastSize(k(ht.width*xt/yt)||0,x,b),this.layoutBoxUpdate(ht,i,1)}e==rt&&null==m&&(P=k(P,S),ht.height=this.contrastSize(k(this.attributes.lines*P),x,b),this.layoutBoxUpdate(ht,i,1,!0)),!g&&o&&o.children&&X&&(!this.isFlex(o)||o.isFlexCalc)&&([ot,rt].includes(e)&&this.isFlex()||e==ot&&this.isBlock(this)&&this.isInFlow())&&(ht.width=this.contrastSize(X-(o.isFlexCalc?0:at),v,y),this.layoutBoxUpdate(ht,i)),g&&!D(g)&&(ht.width=this.contrastSize(g,v,y),this.layoutBoxUpdate(ht,i,0)),m&&!D(m)&&(ht.height=this.contrastSize(ht.height,x,b),this.layoutBoxUpdate(ht,i,1));var bt=0;if(h.length){var wt=null,mt=!1;h.forEach((function(e,n){e.getBoxWidthHeight();var r=h[n+1];if(r&&r.isInFlow()&&(e.next=r),!t.line||!t.line.ids.includes(e.id))if(e.isInFlow()&&!e.inFlexBox()){var o=t.getBoxState(wt,e);if(e.isBr)return mt=!0;t.line&&t.line.canIEnter(e)&&!o&&!mt?t.line.add(e):(mt=!1,(new K).bind(e)),wt=e}else e.inFlexBox()?t.line&&(t.line.canIEnter(e)||"nowrap"==i.flexWrap)?t.line.add(e):(new it).bind(e):e.isFixed?t.root.fixedLine?t.root.fixedLine.fixedAdd(e):(new K).fixedBind(e):t.fixedLine?t.fixedLine.fixedAdd(e):(new K).fixedBind(e,1)})),this.lines&&(bt=this.lines.reduce((function(t,e){return t+e.height}),0))}var St=0,zt=0;if(!g&&(this.isAbsolute||this.isFixed)&&X){var It=B==lt?X:this.root.width,Mt=It-(D(l)?k(l,It):l)-(D(u)?k(u,It):u);St=i.left?Mt:this.lineMaxWidth}if(!m&&(null!=c?c:this.isAbsolute||this.isFixed&&_)){var Bt=B==lt?_:this.root.height,Wt=Bt-(D(c)?k(c,Bt):c)-(D(f)?k(f,Bt):f);zt=i.top?Wt:0}if(g&&!D(g)||ht.width||(ht.width=St||this.contrastSize((this.isBlock(this)&&!this.isInFlow()?X||o.lineMaxWidth:this.lineMaxWidth)||this.lineMaxWidth,v,y),this.layoutBoxUpdate(ht,i,0)),m||!bt&&!zt||(ht.height=zt||this.contrastSize(bt,x,b),this.layoutBoxUpdate(ht,i)),i.borderRadius&&this.borderSize&&this.borderSize.width)for(var q in i.borderRadius)Object.hasOwnProperty.call(i.borderRadius,q)&&(i.borderRadius[q]=k(i.borderRadius[q],this.borderSize.width));return this.layoutBox},e.layout=function(){return this.getBoxWidthHeight(),this.root.offsetSize=this.offsetSize,this.root.contentSize=this.contentSize,this.getBoxPosition(),this.offsetSize},t}(),gt=p,vt=u,yt=g,xt=f,bt=d.TOP,wt=d.MIDDLE,mt=d.BOTTOM,St=c.LEFT,zt=c.CENTER,It=c.RIGHT,Mt=function(){function r(t){var e,i,r=this;this.v="1.9.5.1",this.id=null,this.pixelRatio=1,this.width=0,this.height=0,this.sleep=1e3/30,this.count=0,this.isRate=!1,this.isDraw=!0,this.isCache=!0,this.fixed="",this.useCORS=!1,this.performance=!1,this.imageBus=[],this.createImage=function(t,e){return new Promise((function(i,n){var o=null;window||r.canvas.createImage?(o=r.canvas&&r.canvas.createImage?r.canvas.createImage():new Image,e&&o.setAttribute("crossOrigin","Anonymous"),o.src=t,o.onload=function(){i({width:o.naturalWidth||o.width,height:o.naturalHeight||o.height,path:o,src:this.src})},o.onerror=function(t){n(t)}):n({fail:"getImageInfo fail",src:t})}))},this.options=t,Object.assign(this,t),this.ctx=(e=t.context,i={get:function(t,i){if("setFonts"===i)return function(t){var i=t.fontFamily,r=void 0===i?"sans-serif":i,o=t.fontSize,s=void 0===o?14:o,h=t.fontWeight,a=void 0===h?"normal":h,l=t.fontStyle,d=void 0===l?"normal":l;I==n.MP_TOUTIAO&&(a="bold"==a?"bold":"",d="italic"==d?"italic":""),e.font="".concat(d," ").concat(a," ").concat(Math.round(s),"px ").concat(r)};if(!e.draw||!e.setFillStyle){if("setFillStyle"===i)return function(t){e.fillStyle=t};if("setStrokeStyle"===i)return function(t){e.strokeStyle=t};if("setLineWidth"===i)return function(t){e.lineWidth=t};if("setLineCap"===i)return function(t){e.lineCap=t};if("setFontSize"===i)return function(t){e.font="".concat(String(t),"px sans-serif")};if("setGlobalAlpha"===i)return function(t){e.globalAlpha=t};if("setLineJoin"===i)return function(t){e.lineJoin=t};if("setTextAlign"===i)return function(t){e.textAlign=t};if("setMiterLimit"===i)return function(t){e.miterLimit=t};if("setShadow"===i)return function(t,i,n,r){e.shadowOffsetX=t,e.shadowOffsetY=i,e.shadowBlur=n,e.shadowColor=r};if("setTextBaseline"===i)return function(t){e.textBaseline=t};if("createCircularGradient"===i)return function(){};if("draw"===i)return function(){};if("function"==typeof e[i])return function(){for(var t=[],n=0;n=s||n==l&&o=s)&&(h=e.width/i.width);var d=i.width*h,c=i.height*h,f=r||[],u=f[0],p=f[1],g=W(u)?k(u,e.width):(e.width-d)*(P(u)?k(u,1):{left:0,center:.5,right:1}[u||"center"]),v=W(p)?k(p,e.height):(e.height-c)*(P(p)?k(p,1):{top:0,center:.5,bottom:1}[p||"center"]),y=function(t,e){return[(t-g)/h,(e-v)/h]},x=y(0,0),b=x[0],w=x[1],m=y(e.width,e.height),S=m[0],z=m[1],I=Math.max,M=Math.min;return{sx:I(b,0),sy:I(w,0),sw:M(S-b,i.width),sh:M(z-w,i.height),dx:I(g,0),dy:I(v,0),dw:M(d,e.width),dh:M(c,e.height)}}({objectFit:u,objectPosition:v},r.contentSize,t),o=i.sx,s=i.sy,h=i.sh,a=i.sw,l=i.dx,d=i.dy,c=i.dh,f=i.dw;I==n.MP_BAIDU?e.drawImage(t.src,l+m,d+S,f,c,o,s,a,h):e.drawImage(t.src,o,s,a,h,l+m,d+S,f,c)}else e.drawImage(t.src,m,S,b,w)},O=function(){e.restore(),L.drawView(r,o,!1,!0,!1),a(1)},T=function(t){B(t),O()},T(t),[2]}))}))}))];case 1:return a.sent(),[2]}}))}))},r.prototype.drawText=function(t,e,i,n){var r=this,o=this.ctx,s=e.borderSize,h=e.contentSize,a=e.left,l=e.top,d=h.width,c=h.height,f=h.left-s.left||0,u=h.top-s.top||0,p=i.color,g=i.lineHeight,v=i.fontSize,y=i.fontWeight,x=i.fontFamily,b=i.fontStyle,w=i.textIndent,m=void 0===w?0:w,S=i.textAlign,z=i.textStroke,I=i.verticalAlign,M=void 0===I?wt:I,B=i.backgroundColor,P=i.lineClamp,O=i.backgroundClip,T=i.textShadow,L=i.textDecoration;if(m=W(m)?m:0,this.drawView(e,i,O!=vt),g=k(g,v),t){o.save(),a+=f,l+=u;var R=n.fontHeight,F=n.descent,A=void 0===F?0:F,j=n.ascent,E=A+(void 0===j?0:j);switch(o.setFonts({fontFamily:x,fontSize:v,fontWeight:y,fontStyle:b}),o.setTextBaseline(wt),o.setTextAlign(S),O?this.setBackground(B,d,c,a,l):o.setFillStyle(p),S){case St:break;case zt:a+=.5*d;break;case It:a+=d}var H=n.lines*g,C=Math.ceil((c-H)/2);switch(C<0&&(C=0),M){case bt:break;case wt:l+=C;break;case mt:l+=2*C}var D=(g-R)/2,Y=g/2,$=function(t){var e=o.measureText(t),i=e.actualBoundingBoxDescent,n=void 0===i?0:i,r=e.actualBoundingBoxAscent;return M==bt?{fix:E?void 0===r?0:r:Y-D/2,lineY:E?0:D-D/2}:M==wt?{fix:E?Y+n/4:Y,lineY:E?0:D}:M==mt?{fix:E?g-n:Y+D/2,lineY:E?2*D:D+D/2}:{fix:0,height:0,lineY:0}},U=function(t,e,i){var r=t;switch(S){case St:r+=i;break;case zt:r=(t-=i/2)+i;break;case It:r=t,t-=i}if(L){o.setLineWidth(v/13),o.beginPath();var s=.1*n.fontHeight;/\bunderline\b/.test(L)&&(o.moveTo(t,e+n.fontHeight+s),o.lineTo(r,e+n.fontHeight+s)),/\boverline\b/.test(L)&&(o.moveTo(t,e-s),o.lineTo(r,e-s)),/\bline-through\b/.test(L)&&(o.moveTo(t,e+.5*n.fontHeight),o.lineTo(r,e+.5*n.fontHeight)),o.closePath(),o.setStrokeStyle(p),o.stroke()}},N=function(t,e,i){var n=function(){o.setLineWidth(z.width),o.setStrokeStyle(z.color),o.strokeText(t,e,i)},s="outset";z&&z.type!==s?(o.save(),r.setShadow({boxShadow:T}),o.fillText(t,e,i),o.restore(),n()):z&&z.type==s?(o.save(),r.setShadow({boxShadow:T}),n(),o.restore(),o.save(),o.fillText(t,e,i),o.restore()):(r.setShadow({boxShadow:T}),o.fillText(t,e,i))};if(!n.widths||1==n.widths.length&&n.widths[0].total+m<=h.width){var X=$(t),_=X.fix,q=void 0===_?0:_,G=X.lineY;return N(t,a+m,l+q),U(a+m,l+G,n&&n.widths&&n.widths[0].total||n.text),l+=g,o.restore(),void this.setBorder(e,i)}for(var V=l,J=a,Q="",Z=0,K=o.measureText("...").width,tt=n.widths,et=0;eth.width){Z>=P&&(Q+="…"),Z++,nt=0;var lt=$(Q);q=lt.fix,G=lt.lineY;N(Q,J,l+q),U(J,l+G,nt),l+=g,Q=""}else if(rt==it.length-1){et!=tt.length-1&&Z==P&&K+ntV+c||Z>P)break}}o.restore()}},r.prototype.source=function(t){return e(this,void 0,void 0,(function(){var e,n,r,o,s=this;return i(this,(function(i){switch(i.label){case 0:if(this.node=null,e=+new Date,"{}"==JSON.stringify(t))return[2];if(!t.type)for(n in t.type=xt,t.styles=t.styles||t.css||{},t)["views","children","type","css","styles"].includes(n)||(t.styles[n]=t[n],delete t[n]);return t.styles.boxSizing||(t.styles.boxSizing="border-box"),[4,this.create(t)];case 1:return(r=i.sent())?(o=r.layout()||{},this.size=o,this.node=r,this.onEffectFinished().then((function(t){return s.lifecycle("onEffectSuccess",t)})).catch((function(t){return s.lifecycle("onEffectFail",t)})),this.performance&&console.log("布局用时:"+(+new Date-e)+"ms"),[2,this.size]):[2,console.warn("no node")]}}))}))},r.prototype.getImageInfo=function(t){return this.imageBus[t]||(this.imageBus[t]=this.createImage(t,this.useCORS)),this.imageBus[t]},r.prototype.create=function(n,r){return e(this,void 0,void 0,(function(){function e(i,n,r){void 0===n&&(n={}),void 0===r&&(r=!0);var o=[];return i.forEach((function(i){var s=i.styles,h=void 0===s?{}:s,a=i.children,l=void 0===a?[]:a,d=i.text,c=void 0===d?"":d,f=i.type,u=void 0===f?"":f,p={};p=t(r?t({},n):{},h);var g={},v={},y={};Object.keys(p).map((function(t){if(t.includes("padding")||t.includes("margin")){var e=V(t,p[t]);Object.keys(e).map((function(t){t.includes("Left")?v[t]=e[t]:t.includes("Right")?y[t]=e[t]:g[t]=e[t]}))}}));if(p.textIndent&&(v.textIndent=p.textIndent,delete n.textIndent),""!==c){var x=Array.from(c);x.forEach((function(t,e){var i=Object.assign({},p,g);0===e?Object.assign(i,v):e==x.length-1&&Object.assign(i,y),delete i.padding,delete i.margin,o.push({type:"text",text:t,styles:i})}))}if(u==gt||u==yt)o.push(i);else if("block"===h.display&&l.length>0){var b=e(l,p,!1);i.children=b,i.flattened=!0,o.push(i)}else if(l.length>0){b=e(l,p,r);o=o.concat(b)}})),o}var o,s,h,a,l,d,c,f,u,p,g,v,y,b,w,m,S,z,I,M,B;return i(this,(function(i){switch(i.label){case 0:if(!n)return[2];if(n.styles||(n.styles=n.css||{}),o=n.type,s=o==gt,h=[vt,yt].includes(o),a="textBox"==o,l=n.styles||{},d=l.backgroundImage,c=l.display,s&&!n.src&&!n.url)return[2];if(c==x)return[2];if(h||a){if(f=n.children,!n.text&&(!f||f&&!f.length))return[2];f&&f.length&&!n.flattened&&(u=e(n.children),n.type="view",n.children=u)}if(!(s||n.type==xt&&d))return[3,4];p=s?n.src:"",g=/url\(['"]?(.*?)['"]?\)/.exec(d),d&&g&&g[1]&&(p=g[1]||""),i.label=1;case 1:return i.trys.push([1,3,,4]),[4,this.getImageInfo(p)];case 2:return v=i.sent(),y=v.width,b=v.height,!(w=v.path)&&s?[2]:(w&&(n.attributes=Object.assign(n.attributes||{},{width:y,height:b,path:w,src:w,naturalSrc:p})),[3,4]);case 3:return m=i.sent(),n.type!=xt?[2]:(this.lifecycle("onEffectFail",t(t({},m),{src:p})),[3,4]);case 4:if(this.count+=1,S=new pt(n,r,this.root,this.ctx),!(z=n.views||n.children))return[3,8];I=0,i.label=5;case 5:return I /^data:image\/(\w+);base64/.test(path); +export function sleep(delay) { + return new Promise(resolve => setTimeout(resolve, delay)) +} +let {platform, SDKVersion} = uni.getSystemInfoSync() +export const isPC = /windows|mac/.test(platform) +// 缓存图片 +let cache = {} +export function isNumber(value) { + return /^-?\d+(\.\d+)?$/.test(value); +} +export function toPx(value, baseSize, isDecimal = false) { + // 如果是数字 + if (typeof value === 'number') { + return value + } + // 如果是字符串数字 + if (isNumber(value)) { + return value * 1 + } + // 如果有单位 + if (typeof value === 'string') { + const reg = /^-?([0-9]+)?([.]{1}[0-9]+){0,1}(em|rpx|px|%)$/g + const results = reg.exec(value); + if (!value || !results) { + return 0; + } + const unit = results[3]; + value = parseFloat(value); + let res = 0; + if (unit === 'rpx') { + res = uni.upx2px(value); + } else if (unit === 'px') { + res = value * 1; + } else if (unit === '%') { + res = value * toPx(baseSize) / 100; + } else if (unit === 'em') { + res = value * toPx(baseSize || 14); + } + return isDecimal ? res.toFixed(2) * 1 : Math.round(res); + } + return 0 +} + +// 计算版本 +export function compareVersion(v1, v2) { + v1 = v1.split('.') + v2 = v2.split('.') + const len = Math.max(v1.length, v2.length) + while (v1.length < len) { + v1.push('0') + } + while (v2.length < len) { + v2.push('0') + } + for (let i = 0; i < len; i++) { + const num1 = parseInt(v1[i], 10) + const num2 = parseInt(v2[i], 10) + + if (num1 > num2) { + return 1 + } else if (num1 < num2) { + return -1 + } + } + return 0 +} + +function gte(version) { + // #ifdef MP-ALIPAY + SDKVersion = my.SDKVersion + // #endif + return compareVersion(SDKVersion, version) >= 0; +} +export function canIUseCanvas2d() { + // #ifdef MP-WEIXIN + return gte('2.9.2'); + // #endif + // #ifdef MP-ALIPAY + return gte('2.7.15'); + // #endif + // #ifdef MP-TOUTIAO + return gte('1.78.0'); + // #endif + return false +} + +// #ifdef MP +export const prefix = () => { + // #ifdef MP-TOUTIAO + return tt + // #endif + // #ifdef MP-WEIXIN + return wx + // #endif + // #ifdef MP-BAIDU + return swan + // #endif + // #ifdef MP-ALIPAY + return my + // #endif + // #ifdef MP-QQ + return qq + // #endif + // #ifdef MP-360 + return qh + // #endif +} +// #endif + + + +/** + * base64转路径 + * @param {Object} base64 + */ +export function base64ToPath(base64) { + const [, format] = /^data:image\/(\w+);base64,/.exec(base64) || []; + + return new Promise((resolve, reject) => { + // #ifdef MP + const fs = uni.getFileSystemManager() + //自定义文件名 + if (!format) { + reject(new Error('ERROR_BASE64SRC_PARSE')) + } + const time = new Date().getTime(); + let pre = prefix() + // #ifdef MP-TOUTIAO + const filePath = `${pre.getEnvInfoSync().common.USER_DATA_PATH}/${time}.${format}` + // #endif + // #ifndef MP-TOUTIAO + const filePath = `${pre.env.USER_DATA_PATH}/${time}.${format}` + // #endif + fs.writeFile({ + filePath, + data: base64.split(',')[1], + encoding: 'base64', + success() { + resolve(filePath) + }, + fail(err) { + console.error(err) + reject(err) + } + }) + // #endif + + // #ifdef H5 + // mime类型 + let mimeString = base64.split(',')[0].split(':')[1].split(';')[0]; + //base64 解码 + let byteString = atob(base64.split(',')[1]); + //创建缓冲数组 + let arrayBuffer = new ArrayBuffer(byteString.length); + //创建视图 + let intArray = new Uint8Array(arrayBuffer); + for (let i = 0; i < byteString.length; i++) { + intArray[i] = byteString.charCodeAt(i); + } + resolve(URL.createObjectURL(new Blob([intArray], { + type: mimeString + }))) + // #endif + + // #ifdef APP-PLUS + const bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now()) + bitmap.loadBase64Data(base64, () => { + if (!format) { + reject(new Error('ERROR_BASE64SRC_PARSE')) + } + const time = new Date().getTime(); + const filePath = `_doc/uniapp_temp/${time}.${format}` + bitmap.save(filePath, {}, + () => { + bitmap.clear() + resolve(filePath) + }, + (error) => { + bitmap.clear() + reject(error) + }) + }, (error) => { + bitmap.clear() + reject(error) + }) + // #endif + }) +} + +/** + * 路径转base64 + * @param {Object} string + */ +export function pathToBase64(path) { + if (/^data:/.test(path)) return path + return new Promise((resolve, reject) => { + // #ifdef H5 + let image = new Image(); + image.setAttribute("crossOrigin", 'Anonymous'); + image.onload = function() { + let canvas = document.createElement('canvas'); + canvas.width = this.naturalWidth; + canvas.height = this.naturalHeight; + canvas.getContext('2d').drawImage(image, 0, 0); + let result = canvas.toDataURL('image/png') + resolve(result); + canvas.height = canvas.width = 0 + } + image.src = path + '?v=' + Math.random() + image.onerror = (error) => { + reject(error); + }; + // #endif + + // #ifdef MP + if (uni.canIUse('getFileSystemManager')) { + uni.getFileSystemManager().readFile({ + filePath: path, + encoding: 'base64', + success: (res) => { + resolve('data:image/png;base64,' + res.data) + }, + fail: (error) => { + console.error({error, path}) + reject(error) + } + }) + } + // #endif + + // #ifdef APP-PLUS + plus.io.resolveLocalFileSystemURL(getLocalFilePath(path), (entry) => { + entry.file((file) => { + const fileReader = new plus.io.FileReader() + fileReader.onload = (data) => { + resolve(data.target.result) + } + fileReader.onerror = (error) => { + reject(error) + } + fileReader.readAsDataURL(file) + }, reject) + }, reject) + // #endif + }) +} + + + +export function getImageInfo(path, useCORS) { + const isCanvas2D = this && this.canvas && this.canvas.createImage + return new Promise(async (resolve, reject) => { + // let time = +new Date() + let src = path.replace(/^@\//,'/') + if (cache[path] && cache[path].errMsg) { + resolve(cache[path]) + } else { + try { + // #ifdef MP || APP-PLUS + if (isBase64(path) && (isCanvas2D ? isPC : true)) { + src = await base64ToPath(path) + } + // #endif + // #ifdef H5 + if(useCORS) { + src = await pathToBase64(path) + } + // #endif + } catch (error) { + reject({ + ...error, + src + }) + } + // #ifndef APP-NVUE + if(isCanvas2D && !isPC) { + const img = this.canvas.createImage() + img.onload = function() { + const image = { + path: img, + width: img.width, + height: img.height + } + cache[path] = image + resolve(cache[path]) + } + img.onerror = function(err) { + reject({err,path}) + } + img.src = src + return + } + // #endif + uni.getImageInfo({ + src, + success: (image) => { + const localReg = /^\.|^\/(?=[^\/])/; + // #ifdef MP-WEIXIN || MP-BAIDU || MP-QQ || MP-TOUTIAO + image.path = localReg.test(src) ? `/${image.path}` : image.path; + // #endif + if(isCanvas2D) { + const img = this.canvas.createImage() + img.onload = function() { + image.path = img + cache[path] = image + resolve(cache[path]) + } + img.onerror = function(err) { + reject({err,path}) + } + img.src = src + return + } + // #ifdef APP-PLUS + // console.log('getImageInfo', +new Date() - time) + // ios 比较严格 可能需要设置跨域 + if(uni.getSystemInfoSync().osName == 'ios' && useCORS) { + pathToBase64(image.path).then(base64 => { + image.path = base64 + cache[path] = image + resolve(cache[path]) + }).catch(err => { + console.error({err, path}) + reject({err,path}) + }) + return + } + // #endif + cache[path] = image + resolve(cache[path]) + }, + fail(err) { + console.error({err, path}) + reject({err,path}) + } + }) + } + }) +} + + +// #ifdef APP-PLUS +const getLocalFilePath = (path) => { + if (path.indexOf('_www') === 0 || path.indexOf('_doc') === 0 || path.indexOf('_documents') === 0 || path + .indexOf('_downloads') === 0) { + return path + } + if (path.indexOf('file://') === 0) { + return path + } + if (path.indexOf('/storage/emulated/0/') === 0) { + return path + } + if (path.indexOf('/') === 0) { + const localFilePath = plus.io.convertAbsoluteFileSystem(path) + if (localFilePath !== path) { + return localFilePath + } else { + path = path.substr(1) + } + } + return '_www/' + path +} +// #endif + + diff --git a/uni_modules/lime-painter/components/lime-painter/lime-painter.vue b/uni_modules/lime-painter/components/lime-painter/lime-painter.vue new file mode 100644 index 0000000..f3b614b --- /dev/null +++ b/uni_modules/lime-painter/components/lime-painter/lime-painter.vue @@ -0,0 +1,235 @@ + + + + + diff --git a/uni_modules/lime-painter/hybrid/html/index.html b/uni_modules/lime-painter/hybrid/html/index.html new file mode 100644 index 0000000..fdf884e --- /dev/null +++ b/uni_modules/lime-painter/hybrid/html/index.html @@ -0,0 +1,119 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/uni_modules/lime-painter/hybrid/html/painter.js b/uni_modules/lime-painter/hybrid/html/painter.js new file mode 100644 index 0000000..fc3e2c2 --- /dev/null +++ b/uni_modules/lime-painter/hybrid/html/painter.js @@ -0,0 +1 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).Painter={})}(this,(function(t){"use strict";var e=function(){return e=Object.assign||function(t){for(var e,i=1,n=arguments.length;i0&&r[r.length-1])||6!==o[0]&&2!==o[0])){s=0;continue}if(3===o[0]&&(!r||o[1]>r[0]&&o[1]=360&&(s-=360);s<0&&(s+=360);if(0===(s=Math.round(s)))return{x0:Math.round(e/2)+n,y0:i+r,x1:Math.round(e/2)+n,y1:r};if(180===s)return{x0:Math.round(e/2)+n,y0:r,x1:Math.round(e/2)+n,y1:i+r};if(90===s)return{x0:n,y0:Math.round(i/2)+r,x1:e+n,y1:Math.round(i/2)+r};if(270===s)return{x0:e+n,y0:Math.round(i/2)+r,x1:n,y1:Math.round(i/2)+r};var a=Math.round(180*Math.asin(e/Math.sqrt(Math.pow(e,2)+Math.pow(i,2)))/Math.PI);if(s===a)return{x0:n,y0:i+r,x1:e+n,y1:r};if(s===180-a)return{x0:n,y0:r,x1:e+n,y1:i+r};if(s===180+a)return{x0:e+n,y0:r,x1:n,y1:i+r};if(s===360-a)return{x0:e+n,y0:i+r,x1:n,y1:r};var h=0,c=0,f=0,d=0;if(s180-a&&s<180||s>180&&s<180+a||s>360-a){var l=s*Math.PI/180,u=s360-a?i/2:-i/2,p=Math.tan(l)*u,g=s180-a&&s<180?e/2-p:-e/2-p;h=-(f=p+(v=Math.pow(Math.sin(l),2)*g)),c=-(d=u+v/Math.tan(l))}if(s>a&&s<90||s>90&&s<90+a||s>180+a&&s<270||s>270&&s<360-a){var v;l=(90-s)*Math.PI/180,p=s>a&&s<90||s>90&&s<90+a?e/2:-e/2,u=Math.tan(l)*p,g=s>a&&s<90||s>270&&s<360-a?i/2-u:-i/2-u;h=-(f=p+(v=Math.pow(Math.sin(l),2)*g)/Math.tan(l)),c=-(d=u+v)}return h=Math.round(h+e/2)+n,c=Math.round(i/2-c)+r,f=Math.round(f+e/2)+n,d=Math.round(i/2-d)+r,{x0:h,y0:c,x1:f,y1:d}}(r,t,e,i,n),a=s.x0,h=s.y0,c=s.x1,f=s.y1,d=o.createLinearGradient(a,h,c,f),l=r.match(/linear-gradient\((.+)\)/)[1],u=X(l.substring(l.indexOf(",")+1)),p=0;pt.length)&&(e=t.length);for(var i=0,n=new Array(e);i=t.length?{done:!0}:{done:!1,value:t[n++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function Z(t){return"number"==typeof t}function K(t){return"auto"===t||null===t}function et(t){return/%$/.test(t)}var it=I,nt=z,rt=S,ot=M,st=B,at=O,ht=T;function ct(t){return t.replace(/-([a-z])/g,(function(t,e){return e.toUpperCase()}))}function ft(t,e){var i,n,r=function(t){var e=t.match(/([a-z]+)/)[1];return[e,ct(t.split(e)[1])]}(t),o=r[0],s=r[1],a=e.split(" ");if(s)return(i={})[o+s]=e,i;if(a.length&&!s){var h=a[0],c=a[1],f=a[2],l=a[3];return(n={})[o+d[0]]=h,n[o+d[1]]=c||h,n[o+d[2]]=f||h,n[o+d[3]]=l||c||h,n}}function dt(t){t=t.trim();for(var e=new Array,i="+",n="",r=t.length,o=0;o0;)"("===t[a+=1]&&(s+=1),")"===t[a]&&(s-=1);n="".concat(dt(t.slice(o+1,a))),o=a}if(isNaN(Number(t[o]))&&"."!==t[o]||o===r-1){var h=parseFloat(n);switch(i){case"+":e.push(h);break;case"-":e.push(-h);break;case"*":e.push(e.pop()*h);break;case"/":e.push(e.pop()/h)}i=t[o],n=""}}for(var c=0;e.length;)c+=e.pop();return c}var lt,ut=0,pt=function(){function t(){q(this,"elements",[]),q(this,"afterElements",[]),q(this,"beforeElements",[]),q(this,"ids",[]),q(this,"width",0),q(this,"height",0),q(this,"top",0),q(this,"left",0),q(this,"pre",null),q(this,"offsetX",0),q(this,"offsetY",0),ut++,this.id=ut}var e=t.prototype;return e.fixedBind=function(t,e){void 0===e&&(e=0),this.container=e?t.parent:t.root,this.container.fixedLine=this,this.fixedAdd(t)},e.fixedAdd=function(t){if(!this.ids.includes(t.id)){this.ids.push(t.id),this.elements.push(t);var e=t.computedStyle.zIndex;(void 0===e?0:e)>=0?this.afterElements.push(t):this.beforeElements.push(t),this.refreshLayout()}},e.bind=function(t){this.container=t.parent,this.container.line=null,this.container.lines?(this.container.lines.push(this),this.pre=this.getPreLine(),this.top=this.pre.top+this.pre.height,this.left=this.container.contentSize.left):(this.top=this.container.contentSize.top,this.left=this.container.contentSize.left,this.container.lines=[this]),this.isInline=t.isInline(),this.container.line=this,this.outerWidth=t.parent&&t.parent.contentSize.width?t.parent.contentSize.width:1/0,this.add(t)},e.getPreLine=function(){return this.container.lines[this.container.lines.length-2]},e.canIEnter=function(t){return!((100*t.offsetSize.width+100*this.width)/100>this.outerWidth)||(this.closeLine(),!1)},e.closeLine=function(){delete this.container.line},e.add=function(t){this.ids.includes(t.id)||(this.ids.push(t.id),this.elements.push(t),this.refreshWidthHeight(t))},e.refreshWidthHeight=function(t){t.offsetSize.height>this.height&&(this.height=t.offsetSize.height),this.width+=t.offsetSize.width||0,(this.container.lineMaxWidth||0)this[this.key.height]&&(this.container[this.key.lineMaxHeight]=this[this.key.height]=i),this[this.key.width]+=this.getWidth(t.offsetSize);var n=Math.min(this.getWidth(this),!this.getWidth(this.container.contentSize)&&1/0);(this.container[this.key.lineMaxWidth]||0)1)return 0;var e=t.style.alignSelf,i=this.getHeight(this.container.contentSize),n=i-this.getHeight(t.offsetSize);return e===f?n:e===h?n/2:"stretch"===e?(n&&t.name==S&&(t.style[this.key.width]=this.getWidth(t.offsetSize),t.style[this.key.height]=i,delete t.line,delete t.lines,t.getBoxWidthHeight()),0):0},r.layout=function(t,e){var i=this;this.refreshXAlign(),this.pre?(this.top=this.pre.top+this.pre.height+this.offsetY,this.left=e+this.offsetX):(this.top=Math.max(this.top,this.container.contentSize.top,t)+this.offsetY,this.left=Math.max(this.left,this.container.contentSize.left,e)+this.offsetX),this.elements.forEach((function(t,e){i.setIndent(t);var n=i.elements[e-1],r=i.getOffsetY(t);t.style[i.key.top]=i[i.key.top]+r,t.style[i.key.left]=n?n.offsetSize[i.key.left]+i.getWidth(n.offsetSize):i[i.key.left],t.getBoxPosition()}))},n}(pt),xt=I,wt=z,mt=S,St=k,zt=B,It=P,Mt=O,kt=T,Bt=0,Wt={left:null,top:null,width:null,height:null},Pt=new Map,Ot=function(){function t(t,e,i,n){var r=this;q(this,"id",Bt++),q(this,"style",{left:null,top:null,width:null,height:null}),q(this,"computedStyle",{}),q(this,"originStyle",{}),q(this,"children",{}),q(this,"layoutBox",G({},Wt)),q(this,"contentSize",G({},Wt)),q(this,"clientSize",G({},Wt)),q(this,"borderSize",G({},Wt)),q(this,"offsetSize",G({},Wt)),this.ctx=n,this.root=i,e&&(this.parent=e),this.name=t.type||t.name,this.attributes=this.getAttributes(t);var o=function(t,e){var i,n=["color","fontSize","lineHeight","verticalAlign","fontWeight","textAlign"],r=t.type,o=void 0===r?rt:r,s=t.styles,h=void 0===s?{}:s,c=(e||{}).computedStyle,f=Object.assign({},F);if([nt,it,ot].includes(o)&&!h.display&&(f.display=st),c)for(var l=0;l=0&&f<0,Y=h>=0&&l<0;return i==y[0]&&(this[i].left=t.left+s+g+j+(D?2*-f:0),this[i].top=t.top+h+b+W+(Y?2*-l:0),this[i].width=t.width+(this[i].widthAdd?0:C),this[i].height=t.height+(this[i].heightAdd?0:H),this[i].widthAdd=C,this[i].heightAdd=H),i==y[1]&&(this[i].left=t.left+s+j+(D<0?-f:0),this[i].top=t.top+h+W+(Y?-l:0),this[i].width=t.width+g+w,this[i].height=t.height+b+S),i==y[2]&&(this[i].left=t.left+s+j/2+(D<0?-f:0),this[i].top=t.top+h+W/2+(Y?-l:0),this[i].width=t.width+g+w+j/2+F/2,this[i].height=t.height+b+S+T/2+W/2),i==y[3]&&(this[i].left=t.left+(D<0?-f:0),this[i].top=t.top+(Y?-l:0),this[i].width=t.width+g+w+j+F+s+f,this[i].height=t.height+b+S+T+W+l+h),this[i]},e.layoutBoxUpdate=function(t,e,i,n){var r=this;if(void 0===i&&(i=-1),"border-box"==e.boxSizing){var o=e||{},s=o.border,a=(s=void 0===s?{}:s).borderWidth,h=void 0===a?0:a,c=o.borderTop,f=(c=void 0===c?{}:c).borderTopWidth,d=void 0===f?h:f,l=o.borderBottom,u=(l=void 0===l?{}:l).borderBottomWidth,p=void 0===u?h:u,g=o.borderRight,v=(g=void 0===g?{}:g).borderRightWidth,b=void 0===v?h:v,x=o.borderLeft,w=(x=void 0===x?{}:x).borderLeftWidth,m=void 0===w?h:w,S=o.padding,z=(S=void 0===S?{}:S).paddingTop,I=void 0===z?0:z,M=S.paddingRight,k=void 0===M?0:M,B=S.paddingBottom,W=void 0===B?0:B,P=S.paddingLeft,O=void 0===P?0:P;i||(t.width-=O+k+b+m),1!==i||n||(t.height-=I+W+d+p)}this.layoutBox&&(y.forEach((function(i){return r.layoutBox[i]=r.getOffsetSize(t,e,i)})),this.layoutBox=Object.assign({},this.layoutBox,this.layoutBox.borderSize))},e.getBoxPosition=function(){var t=this.computedStyle,e=this.fixedLine,i=this.lines,n=t.left,r=void 0===n?0:n,o=t.top,s=void 0===o?0:o,a=G({},this.contentSize,{left:r,top:s}),h=this.contentSize.top-this.offsetSize.top,c=this.contentSize.left-this.offsetSize.left;if(this.root.fixedLine&&!this.root.isDone){this.root.isDone=!0;for(var f,d=Q(this.root.fixedLine.elements);!(f=d()).done;){var l=f.value;l.setPosition(l,this.root.offsetSize),l.getBoxPosition()}}if(e)for(var u,p=Q(e.elements);!(u=p()).done;){var g=u.value,v=G({},this.borderSize,{left:r,top:s});g.setPosition(g,v);var y=this.borderSize.top-this.offsetSize.top,b=this.borderSize.left-this.offsetSize.left;g.style.left+=r+b,g.style.top+=s+y,g.getBoxPosition()}if(i)for(var x,w=Q(i);!(x=w()).done;){x.value.layout(a.top+h,a.left+c)}return this.layoutBoxUpdate(a,t),this.layoutBox},e.getBoxState=function(t,e){return this.isBlock(t)||this.isBlock(e)},e.isBlock=function(t){return void 0===t&&(t=this),t&&t.style.display==St},e.isFlex=function(t){return void 0===t&&(t=this),t&&t.style.display==It},e.isInFlow=function(){return!(this.isAbsolute||this.isFixed)},e.inFlexBox=function(t){return void 0===t&&(t=this),!!t.isInFlow()&&(!!t.parent&&(!(!t.parent||t.parent.style.display!==It)||void 0))},e.isInline=function(t){return void 0===t&&(t=this),t&&t.style.display==zt},e.contrastSize=function(t,e,i){var n=t;return i&&(n=Math.min(n,i)),e&&(n=Math.max(n,e)),n},e.measureText=function(t,e){var i=this.ctx.measureText(t),n=i.width,r=i.actualBoundingBoxAscent,o=i.actualBoundingBoxDescent;return{ascent:r,descent:o,width:n,fontHeight:r+o||.7*e+1}},e.getParentSize=function(t,e){if(void 0===t&&(t=this),void 0===e&&(e=!1),t&&t.parent){if(t.parent.contentSize.width)return t.parent.contentSize;if(e)return this.getParentSize(t.parent,e)}return null},e.getBoxWidthHeight=function(){var t=this,e=this.name,i=this.computedStyle,n=this.attributes,r=this.parent,o=void 0===r?{}:r,s=this.ctx,a=this.getChildren(),h=i.left,c=void 0===h?0:h,f=i.top,d=void 0===f?0:f,l=i.bottom,u=i.right,p=i.width,g=void 0===p?0:p,v=i.minWidth,y=i.maxWidth,b=i.minHeight,x=i.maxHeight,w=i.height,m=void 0===w?0:w,S=i.fontSize,z=i.fontWeight,I=i.fontFamily,M=i.fontStyle,k=i.position;i.textIndent;var B=i.lineClamp,W=i.lineHeight,P=i.padding,O=void 0===P?{}:P,T=i.margin,L=void 0===T?{}:T,R=i.border,F=(R=void 0===R?{}:R).borderWidth,A=void 0===F?0:F,E=i.borderRight,j=(E=void 0===E?{}:E).borderRightWidth,C=void 0===j?A:j,H=i.borderLeft,D=(H=void 0===H?{}:H).borderLeftWidth,Y=void 0===D?A:D,U=o.contentSize&&o.contentSize.width,N=o.contentSize&&o.contentSize.height;if(et(g)&&U&&(g=$(g,U)),et(g)&&!U&&(g=null),et(m)&&N&&(m=$(m,N)),et(m)&&!N&&(m=null),et(v)&&U&&(v=$(v,U)),et(y)&&U&&(y=$(y,U)),et(b)&&N&&(b=$(b,N)),et(x)&&N&&(x=$(x,N)),i.padding&&U)for(var _ in i.padding)Object.hasOwnProperty.call(O,_)&&(O[_]=$(O[_],U));var X=O.paddingRight,q=void 0===X?0:X,G=O.paddingLeft,V=void 0===G?0:G;if(i.margin&&[L.marginLeft,L.marginRight].includes("auto"))if(g){var J=U&&U-g-q-V-Y-C||0;L.marginLeft==L.marginRight?L.marginLeft=L.marginRight=J/2:K(L.marginLeft)?L.marginLeft=J:L.marginRight=J}else L.marginLeft=L.marginRight=0;var Q=L.marginRight,Z=void 0===Q?0:Q,tt=L.marginLeft,it={width:g,height:m,left:0,top:0},nt=V+q+Y+C+(void 0===tt?0:tt)+Z;if(this.offsetWidth=nt,e==wt&&!this.attributes.widths){var rt=n.text||"";s.save(),s.setFonts({fontFamily:I,fontSize:S,fontWeight:z,fontStyle:M}),rt.length,"\n"==rt&&(rt="",this.isBr=!0),(""+rt).split("\n").map((function(e){var i=Array.from(e).map((function(e){var i=""+(/^[\u4e00-\u9fa5]+$/.test(e)?"cn":e)+I+S+z+M,n=Pt.get(i);if(n)return{width:n,text:e};var r=t.measureText(e,S).width;return Pt.set(i,r),{width:r,text:e}})),n=t.measureText(e,S),r=n.fontHeight,o=n.ascent,s=n.descent;t.attributes.fontHeight=r,t.attributes.ascent=o,t.attributes.descent=s,t.attributes.widths||(t.attributes.widths=[]),t.attributes.widths.push({widths:i,total:i.reduce((function(t,e){return t+e.width}),0)})})),s.restore()}if(e==xt&&null==g){var ot=n.width,st=n.height;it.width=this.contrastSize(Math.round(ot*m/st)||0,v,y),this.layoutBoxUpdate(it,i,0)}if(e==wt&&null==g){var at=this.attributes.widths,ht=Math.max.apply(Math,at.map((function(t){return t.total})));if(o&&U>0&&(ht>U||this.isBlock(this))&&!this.isAbsolute&&!this.isFixed)ht=U;it.width=this.contrastSize(ht,v,y),this.layoutBoxUpdate(it,i,0)}if(e==wt&&(o.style.flex||!this.attributes.lines)){var ct=this.attributes.widths.length;this.attributes.widths.forEach((function(t){return t.widths.reduce((function(t,e,i){return t+e.width>it.width?(ct++,e.width):t+e.width}),0)})),ct=B&&ct>B?B:ct,this.attributes.lines=ct}if(e==xt&&null==m){var ft=n.width,dt=n.height;n.text,it.height=this.contrastSize($(it.width*dt/ft)||0,b,x),this.layoutBoxUpdate(it,i,1)}e==wt&&null==m&&(W=$(W,S),it.height=this.contrastSize($(this.attributes.lines*W),b,x),this.layoutBoxUpdate(it,i,1,!0)),!g&&o&&o.children&&U&&(!this.isFlex(o)||o.isFlexCalc)&&([mt,wt].includes(e)&&this.isFlex()||e==mt&&this.isBlock(this)&&this.isInFlow())&&(it.width=this.contrastSize(U-(o.isFlexCalc?0:nt),v,y),this.layoutBoxUpdate(it,i)),g&&!et(g)&&(it.width=this.contrastSize(g,v,y),this.layoutBoxUpdate(it,i,0)),m&&!et(m)&&(it.height=this.contrastSize(it.height,b,x),this.layoutBoxUpdate(it,i,1));var lt=0;if(a.length){var ut=null,gt=!1;a.forEach((function(e,n){e.getBoxWidthHeight();var r=a[n+1];if(r&&r.isInFlow()&&(e.next=r),!t.line||!t.line.ids.includes(e.id))if(e.isInFlow()&&!e.inFlexBox()){var o=t.getBoxState(ut,e);if(e.isBr)return gt=!0;t.line&&t.line.canIEnter(e)&&!o&&!gt?t.line.add(e):(gt=!1,(new pt).bind(e)),ut=e}else e.inFlexBox()?t.line&&(t.line.canIEnter(e)||"nowrap"==i.flexWrap)?t.line.add(e):(new bt).bind(e):e.isFixed?t.root.fixedLine?t.root.fixedLine.fixedAdd(e):(new pt).fixedBind(e):t.fixedLine?t.fixedLine.fixedAdd(e):(new pt).fixedBind(e,1)})),this.lines&&(lt=this.lines.reduce((function(t,e){return t+e.height}),0))}var vt=0,yt=0;if(!g&&(this.isAbsolute||this.isFixed)&&U){var St=k==Mt?U:this.root.width,zt=St-(et(c)?$(c,St):c)-(et(u)?$(u,St):u);vt=i.left?zt:this.lineMaxWidth}if(!m&&(null!=d?d:this.isAbsolute||this.isFixed&&N)){var It=k==Mt?N:this.root.height,kt=It-(et(d)?$(d,It):d)-(et(l)?$(l,It):l);yt=i.top?kt:0}if(g&&!et(g)||it.width||(it.width=vt||this.contrastSize((this.isBlock(this)&&!this.isInFlow()?U||o.lineMaxWidth:this.lineMaxWidth)||this.lineMaxWidth,v,y),this.layoutBoxUpdate(it,i,0)),m||!lt&&!yt||(it.height=yt||this.contrastSize(lt,b,x),this.layoutBoxUpdate(it,i)),i.borderRadius&&this.borderSize&&this.borderSize.width)for(var _ in i.borderRadius)Object.hasOwnProperty.call(i.borderRadius,_)&&(i.borderRadius[_]=$(i.borderRadius[_],this.borderSize.width));return this.layoutBox},e.layout=function(){return this.getBoxWidthHeight(),this.root.offsetSize=this.offsetSize,this.root.contentSize=this.contentSize,this.getBoxPosition(),this.offsetSize},t}(),Tt=function(){var t,e,i,n,r,o,s=[0,11,15,19,23,27,31,16,18,20,22,24,26,28,20,22,24,24,26,28,28,22,24,24,26,26,28,28,24,24,26,26,26,28,28,24,26,26,26,28,28],a=[3220,1468,2713,1235,3062,1890,2119,1549,2344,2936,1117,2583,1330,2470,1667,2249,2028,3780,481,4011,142,3098,831,3445,592,2517,1776,2234,1951,2827,1070,2660,1345,3177],h=[30660,29427,32170,30877,26159,25368,27713,26998,21522,20773,24188,23371,17913,16590,20375,19104,13663,12392,16177,14854,9396,8579,11994,11245,5769,5054,7399,6608,1890,597,3340,2107],c=[1,0,19,7,1,0,16,10,1,0,13,13,1,0,9,17,1,0,34,10,1,0,28,16,1,0,22,22,1,0,16,28,1,0,55,15,1,0,44,26,2,0,17,18,2,0,13,22,1,0,80,20,2,0,32,18,2,0,24,26,4,0,9,16,1,0,108,26,2,0,43,24,2,2,15,18,2,2,11,22,2,0,68,18,4,0,27,16,4,0,19,24,4,0,15,28,2,0,78,20,4,0,31,18,2,4,14,18,4,1,13,26,2,0,97,24,2,2,38,22,4,2,18,22,4,2,14,26,2,0,116,30,3,2,36,22,4,4,16,20,4,4,12,24,2,2,68,18,4,1,43,26,6,2,19,24,6,2,15,28,4,0,81,20,1,4,50,30,4,4,22,28,3,8,12,24,2,2,92,24,6,2,36,22,4,6,20,26,7,4,14,28,4,0,107,26,8,1,37,22,8,4,20,24,12,4,11,22,3,1,115,30,4,5,40,24,11,5,16,20,11,5,12,24,5,1,87,22,5,5,41,24,5,7,24,30,11,7,12,24,5,1,98,24,7,3,45,28,15,2,19,24,3,13,15,30,1,5,107,28,10,1,46,28,1,15,22,28,2,17,14,28,5,1,120,30,9,4,43,26,17,1,22,28,2,19,14,28,3,4,113,28,3,11,44,26,17,4,21,26,9,16,13,26,3,5,107,28,3,13,41,26,15,5,24,30,15,10,15,28,4,4,116,28,17,0,42,26,17,6,22,28,19,6,16,30,2,7,111,28,17,0,46,28,7,16,24,30,34,0,13,24,4,5,121,30,4,14,47,28,11,14,24,30,16,14,15,30,6,4,117,30,6,14,45,28,11,16,24,30,30,2,16,30,8,4,106,26,8,13,47,28,7,22,24,30,22,13,15,30,10,2,114,28,19,4,46,28,28,6,22,28,33,4,16,30,8,4,122,30,22,3,45,28,8,26,23,30,12,28,15,30,3,10,117,30,3,23,45,28,4,31,24,30,11,31,15,30,7,7,116,30,21,7,45,28,1,37,23,30,19,26,15,30,5,10,115,30,19,10,47,28,15,25,24,30,23,25,15,30,13,3,115,30,2,29,46,28,42,1,24,30,23,28,15,30,17,0,115,30,10,23,46,28,10,35,24,30,19,35,15,30,17,1,115,30,14,21,46,28,29,19,24,30,11,46,15,30,13,6,115,30,14,23,46,28,44,7,24,30,59,1,16,30,12,7,121,30,12,26,47,28,39,14,24,30,22,41,15,30,6,14,121,30,6,34,47,28,46,10,24,30,2,64,15,30,17,4,122,30,29,14,46,28,49,10,24,30,24,46,15,30,4,18,122,30,13,32,46,28,48,14,24,30,42,32,15,30,20,4,117,30,40,7,47,28,43,22,24,30,10,67,15,30,19,6,118,30,18,31,47,28,34,34,24,30,20,61,15,30],f=[255,0,1,25,2,50,26,198,3,223,51,238,27,104,199,75,4,100,224,14,52,141,239,129,28,193,105,248,200,8,76,113,5,138,101,47,225,36,15,33,53,147,142,218,240,18,130,69,29,181,194,125,106,39,249,185,201,154,9,120,77,228,114,166,6,191,139,98,102,221,48,253,226,152,37,179,16,145,34,136,54,208,148,206,143,150,219,189,241,210,19,92,131,56,70,64,30,66,182,163,195,72,126,110,107,58,40,84,250,133,186,61,202,94,155,159,10,21,121,43,78,212,229,172,115,243,167,87,7,112,192,247,140,128,99,13,103,74,222,237,49,197,254,24,227,165,153,119,38,184,180,124,17,68,146,217,35,32,137,46,55,63,209,91,149,188,207,205,144,135,151,178,220,252,190,97,242,86,211,171,20,42,93,158,132,60,57,83,71,109,65,162,31,45,67,216,183,123,164,118,196,23,73,236,127,12,111,246,108,161,59,82,41,157,85,170,251,96,134,177,187,204,62,90,203,89,95,176,156,169,160,81,11,245,22,235,122,117,44,215,79,174,213,233,230,231,173,232,116,214,244,234,168,80,88,175],d=[1,2,4,8,16,32,64,128,29,58,116,232,205,135,19,38,76,152,45,90,180,117,234,201,143,3,6,12,24,48,96,192,157,39,78,156,37,74,148,53,106,212,181,119,238,193,159,35,70,140,5,10,20,40,80,160,93,186,105,210,185,111,222,161,95,190,97,194,153,47,94,188,101,202,137,15,30,60,120,240,253,231,211,187,107,214,177,127,254,225,223,163,91,182,113,226,217,175,67,134,17,34,68,136,13,26,52,104,208,189,103,206,129,31,62,124,248,237,199,147,59,118,236,197,151,51,102,204,133,23,46,92,184,109,218,169,79,158,33,66,132,21,42,84,168,77,154,41,82,164,85,170,73,146,57,114,228,213,183,115,230,209,191,99,198,145,63,126,252,229,215,179,123,246,241,255,227,219,171,75,150,49,98,196,149,55,110,220,165,87,174,65,130,25,50,100,200,141,7,14,28,56,112,224,221,167,83,166,81,162,89,178,121,242,249,239,195,155,43,86,172,69,138,9,18,36,72,144,61,122,244,245,247,243,251,235,203,139,11,22,44,88,176,125,250,233,207,131,27,54,108,216,173,71,142,0],l=[],u=[],p=[],g=[],v=[],y=2;function b(t,e){var i;t>e&&(i=t,t=e,e=i),i=e,i*=e,i+=e,i>>=1,g[i+=t]=1}function x(t,i){var n;for(p[t+e*i]=1,n=-2;n<2;n++)p[t+n+e*(i-2)]=1,p[t-2+e*(i+n+1)]=1,p[t+2+e*(i+n)]=1,p[t+n+1+e*(i+2)]=1;for(n=0;n<2;n++)b(t-1,i+n),b(t+1,i-n),b(t-n,i-1),b(t+n,i+1)}function w(t){for(;t>=255;)t=((t-=255)>>8)+(255&t);return t}var m=[];function S(t,e,i,n){var r,o,s;for(r=0;re&&(i=t,t=e,e=i),i=e,i+=e*e,i>>=1,g[i+=t]}function I(t){var i,n,r,o;switch(t){case 0:for(n=0;n>1&1,i=0;i=5&&(i+=3+v[e]-5);for(e=3;et||3*v[e-3]>=4*v[e]||3*v[e+3]>=4*v[e])&&(i+=40);return i}function k(){var t,i,n,r,o,s=0,a=0;for(i=0;ie*e;)h-=e*e,c++;for(s+=10*c,t=0;t1)for(P=s[t],B=e-7;;){for(M=e-7;M>P-3&&(x(M,B),!(M6)for(P=a[t-7],W=17,M=0;M<6;M++)for(B=0;B<3;B++,W--)1&(W>11?t>>W-12:P>>W)?(p[5-M+e*(2-B+e-11)]=1,p[2-B+e-11+e*(5-M)]=1):(b(5-M,2-B+e-11),b(2-B+e-11,5-M));for(B=0;B=(M=r*(i+n)+n)-2&&(O=M-2,t>9&&O--),T=O,t>9){for(l[T+2]=0,l[T+3]=0;T--;)P=l[T],l[T+3]|=255&P<<4,l[T+2]=P>>4;l[2]|=255&O<<4,l[1]=O>>4,l[0]=64|O>>12}else{for(l[T+1]=0,l[T+2]=0;T--;)P=l[T],l[T+2]|=255&P<<4,l[T+1]=P>>4;l[1]|=255&O<<4,l[0]=64|O>>4}for(T=O+3-(t<10);T0;L--)m[L]=m[L]?m[L-1]^d[w(f[m[L]]+T)]:m[L-1];m[0]=d[w(f[m[0]]+T)]}for(T=0;T<=o;T++)m[T]=f[m[T]];for(W=M,B=0,T=0;T>=1)1&B&&(p[e-1-W+8*e]=1,W<6?p[8+e*W]=1:p[8+e*(W+1)]=1);for(W=0;W<7;W++,B>>=1)1&B&&(p[8+e*(e-7+W)]=1,W?p[6-W+8*e]=1:p[7+8*e]=1);return p}(v)},utf16to8:function(t){var e,i,n,r;for(e="",n=t.length,i=0;i=1&&r<=127?e+=t.charAt(i):r>2047?(e+=String.fromCharCode(224|r>>12&15),e+=String.fromCharCode(128|r>>6&63),e+=String.fromCharCode(128|r>>0&63)):(e+=String.fromCharCode(192|r>>6&31),e+=String.fromCharCode(128|r>>0&63));return e},draw:function(t,i,n,r,o){i.drawView(n,r);var s=i.ctx,a=n.contentSize,h=a.width,c=a.height,f=a.left,d=a.top;r.borderRadius,r.backgroundColor;var l=r.color,u=void 0===l?"#000000":l;r.border,n.contentSize.left,n.borderSize.left,n.contentSize.top,n.borderSize.top;if(y=o||y,s){s.save(),i.setOpacity(r),i.setTransform(n,r);var p=Math.min(h,c);t=this.utf16to8(t);var g=this.getFrame(t),v=p/e;s.setFillStyle(u);for(var b=0;b=s||n==c&&o=s)&&(a=e.width/i.width);var f=i.width*a,d=i.height*a,l=r||[],u=l[0],p=l[1],g=Y(u)?$(u,e.width):(e.width-f)*(U(u)?$(u,1):{left:0,center:.5,right:1}[u||"center"]),v=Y(p)?$(p,e.height):(e.height-d)*(U(p)?$(p,1):{top:0,center:.5,bottom:1}[p||"center"]),y=function(t,e){return[(t-g)/a,(e-v)/a]},b=y(0,0),x=b[0],w=b[1],m=y(e.width,e.height),S=m[0],z=m[1],I=Math.max,M=Math.min;return{sx:I(x,0),sy:I(w,0),sw:M(S-x,i.width),sh:M(z-w,i.height),dx:I(g,0),dy:I(v,0),dw:M(f,e.width),dh:M(d,e.height)}}({objectFit:u,objectPosition:v},e.contentSize,t),o=n.sx,s=n.sy,a=n.sh,h=n.sw,c=n.dx,f=n.dy,d=n.dh,l=n.dw;C==r.MP_BAIDU?i.drawImage(t.src,c+m,f+S,l,d,o,s,h,a):i.drawImage(t.src,o,s,h,a,c+m,f+S,l,d)}else i.drawImage(t.src,m,S,x,w)},k=function(){i.restore(),W.drawView(e,o,!1,!0,!1),h(1)},B=function(t){M(t),k()},B(t),[2]}))}))}))];case 1:return h.sent(),[2]}}))}))},t.prototype.drawText=function(t,e,i,n){var r=this,o=this.ctx,s=e.borderSize,a=e.contentSize,h=e.left,c=e.top,f=a.width,d=a.height,l=a.left-s.left||0,u=a.top-s.top||0,p=i.color,g=i.lineHeight,v=i.fontSize,y=i.fontWeight,b=i.fontFamily,x=i.fontStyle,w=i.textIndent,m=void 0===w?0:w,S=i.textAlign,z=i.textStroke,I=i.verticalAlign,M=void 0===I?jt:I,k=i.backgroundColor,B=i.lineClamp,W=i.backgroundClip,P=i.textShadow,O=i.textDecoration;if(m=Y(m)?m:0,this.drawView(e,i,W!=Rt),g=$(g,v),t){o.save(),h+=l,c+=u;var T=n.fontHeight,L=n.descent,R=void 0===L?0:L,F=n.ascent,A=R+(void 0===F?0:F);switch(o.setFonts({fontFamily:b,fontSize:v,fontWeight:y,fontStyle:x}),o.setTextBaseline(jt),o.setTextAlign(S),W?this.setBackground(k,f,d,h,c):o.setFillStyle(p),S){case Ht:break;case Dt:h+=.5*f;break;case Yt:h+=f}var E=n.lines*g,j=Math.ceil((d-E)/2);switch(j<0&&(j=0),M){case Et:break;case jt:c+=j;break;case Ct:c+=2*j}var C=(g-T)/2,H=g/2,D=function(t){var e=o.measureText(t),i=e.actualBoundingBoxDescent,n=void 0===i?0:i,r=e.actualBoundingBoxAscent;return M==Et?{fix:A?void 0===r?0:r:H-C/2,lineY:A?0:C-C/2}:M==jt?{fix:A?H+n/4:H,lineY:A?0:C}:M==Ct?{fix:A?g-n:H+C/2,lineY:A?2*C:C+C/2}:{fix:0,height:0,lineY:0}},U=function(t,e,i){var r=t;switch(S){case Ht:r+=i;break;case Dt:r=(t-=i/2)+i;break;case Yt:r=t,t-=i}if(O){o.setLineWidth(v/13),o.beginPath();var s=.1*n.fontHeight;/\bunderline\b/.test(O)&&(o.moveTo(t,e+n.fontHeight+s),o.lineTo(r,e+n.fontHeight+s)),/\boverline\b/.test(O)&&(o.moveTo(t,e-s),o.lineTo(r,e-s)),/\bline-through\b/.test(O)&&(o.moveTo(t,e+.5*n.fontHeight),o.lineTo(r,e+.5*n.fontHeight)),o.closePath(),o.setStrokeStyle(p),o.stroke()}},N=function(t,e,i){var n=function(){o.setLineWidth(z.width),o.setStrokeStyle(z.color),o.strokeText(t,e,i)},s="outset";z&&z.type!==s?(o.save(),r.setShadow({boxShadow:P}),o.fillText(t,e,i),o.restore(),n()):z&&z.type==s?(o.save(),r.setShadow({boxShadow:P}),n(),o.restore(),o.save(),o.fillText(t,e,i),o.restore()):(r.setShadow({boxShadow:P}),o.fillText(t,e,i))};if(!n.widths||1==n.widths.length&&n.widths[0].total+m<=a.width){var _=D(t),X=_.fix,q=void 0===X?0:X,G=_.lineY;return N(t,h+m,c+q),U(h+m,c+G,n&&n.widths&&n.widths[0].total||n.text),c+=g,o.restore(),void this.setBorder(e,i)}for(var V=c,J=h,Q="",Z=0,K=o.measureText("...").width,tt=n.widths,et=0;eta.width){Z>=B&&(Q+="…"),Z++,nt=0;var ct=D(Q);q=ct.fix,G=ct.lineY;N(Q,J,c+q),U(J,c+G,nt),c+=g,Q=""}else if(rt==it.length-1){et!=tt.length-1&&Z==B&&K+ntV+d||Z>B)break}}o.restore()}},t.prototype.source=function(t){return i(this,void 0,void 0,(function(){var e,i,r,o,s=this;return n(this,(function(n){switch(n.label){case 0:if(this.node=null,e=+new Date,"{}"==JSON.stringify(t))return[2];if(t.styles=t.styles||t.css||{},!t.type)for(i in t.type=At,t)["views","children","type","css","styles"].includes(i)||(t.styles[i]=t[i],delete t[i]);return t.styles.boxSizing||(t.styles.boxSizing="border-box"),[4,this.create(t)];case 1:return(r=n.sent())?(o=r.layout()||{},this.size=o,this.node=r,this.onEffectFinished().then((function(t){return s.lifecycle("onEffectSuccess",t)})).catch((function(t){return s.lifecycle("onEffectFail",t)})),this.performance&&console.log("布局用时:"+(+new Date-e)+"ms"),[2,this.size]):[2,console.warn("no node")]}}))}))},t.prototype.getImageInfo=function(t){return this.imageBus[t]||(this.imageBus[t]=this.createImage(t,this.useCORS)),this.imageBus[t]},t.prototype.create=function(t,r){return i(this,void 0,void 0,(function(){function i(t,n,r){void 0===n&&(n={}),void 0===r&&(r=!0);var o=[];return t.forEach((function(t){var s=t.styles,a=void 0===s?{}:s,h=t.css,c=void 0===h?{}:h,f=t.children,d=void 0===f?[]:f,l=t.views,u=void 0===l?[]:l,p=t.text,g=void 0===p?"":p,v=t.type,y=void 0===v?"":v;!d&&u&&(t.children=d=u);var b={};b=e(e(r?e({},n):{},a),c);var x={},w={},m={};Object.keys(b).map((function(t){if(t.includes("padding")||t.includes("margin")){var e=ft(t,b[t]);Object.keys(e).map((function(t){t.includes("Left")?w[t]=e[t]:t.includes("Right")?m[t]=e[t]:x[t]=e[t]}))}}));if(b.textIndent&&(w.textIndent=b.textIndent,delete n.textIndent),""!==g){var S=Array.from(g);S.forEach((function(t,e){var i=Object.assign({},b,x);0===e?Object.assign(i,w):e==S.length-1&&Object.assign(i,m),delete i.padding,delete i.margin,o.push({type:"text",text:t,styles:i})}))}if(y==Lt||y==Ft)o.push(t);else if("block"===a.display&&d.length>0){var z=i(d,b,!1);t.children=z,t.flattened=!0,o.push(t)}else if(d.length>0){z=i(d,b,r);o=o.concat(z)}})),o}var o,s,a,h,c,f,d,l,u,p,g,v,y,b,x,w,m,S,z,I,M,k,B,P;return n(this,(function(n){switch(n.label){case 0:if(!t)return[2];if(t.styles||(t.styles=t.css||{}),o=t.type,s=t.show,a=void 0===s||s,h=o==Lt,c=[Rt,Ft].includes(o),f="textBox"==o,d=t.styles||{},l=d.backgroundImage,u=d.display,h&&!t.src&&!t.url)return[2];if(u==W||!a)return[2];if(c||f){if(p=t.children,g=t.views,!p&&g&&(t.children=p=g),!t.text&&(!p||p&&!p.length))return[2];p&&p.length&&!t.flattened&&(v=i(t.children||t.views),t.type="view",t.children=v)}if(!(h||t.type==At&&l))return[3,4];y=h?t.src:"",b=/url\(['"]?(.*?)['"]?\)/.exec(l),l&&b&&b[1]&&(y=b[1]||""),n.label=1;case 1:return n.trys.push([1,3,,4]),[4,this.getImageInfo(y)];case 2:return x=n.sent(),w=x.width,m=x.height,!(S=x.path)&&h?[2]:(S&&(t.attributes=Object.assign(t.attributes||{},{width:w,height:m,path:S,src:S,naturalSrc:y})),[3,4]);case 3:return z=n.sent(),t.type!=At?[2]:(this.lifecycle("onEffectFail",e(e({},z),{src:y})),[3,4]);case 4:if(this.count+=1,I=new Ot(t,r,this.root,this.ctx),!(M=t.children||t.views))return[3,8];k=0,n.label=5;case 5:return k0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;r("navigateTo",{url:encodeURI(n)})},navigateBack:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.delta;r("navigateBack",{delta:parseInt(n)||1})},switchTab:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;r("switchTab",{url:encodeURI(n)})},reLaunch:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;r("reLaunch",{url:encodeURI(n)})},redirectTo:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=e.url;r("redirectTo",{url:encodeURI(n)})},getEnv:function(e){o()?e({nvue:!0}):window.plus?e({plus:!0}):e({h5:!0})},postMessage:function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};r("postMessage",e.data||{})}},d=/uni-app/i.test(navigator.userAgent),s=/Html5Plus/i.test(navigator.userAgent),w=/complete|loaded|interactive/;var u=window.my&&navigator.userAgent.indexOf("AlipayClient")>-1;var g=window.swan&&window.swan.webView&&/swan/i.test(navigator.userAgent);var c=window.qq&&window.qq.miniProgram&&/QQ/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var v=window.tt&&window.tt.miniProgram&&/toutiaomicroapp/i.test(navigator.userAgent);var m=window.wx&&window.wx.miniProgram&&/micromessenger/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var p=window.qa&&/quickapp/i.test(navigator.userAgent);var f=window.ks&&window.ks.miniProgram&&/micromessenger/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);var l=window.tt&&window.tt.miniProgram&&/Lark|Feishu/i.test(navigator.userAgent);var _=window.jd&&window.jd.miniProgram&&/micromessenger/i.test(navigator.userAgent)&&/miniProgram/i.test(navigator.userAgent);for(var E,b=function(){window.UniAppJSBridge=!0,document.dispatchEvent(new CustomEvent("UniAppJSBridgeReady",{bubbles:!0,cancelable:!0}))},h=[function(e){if(d||s)return window.__dcloud_weex_postMessage||window.__dcloud_weex_?document.addEventListener("DOMContentLoaded",e):window.plus&&w.test(document.readyState)?setTimeout(e,0):document.addEventListener("plusready",e),a},function(e){if(m)return window.WeixinJSBridge&&window.WeixinJSBridge.invoke?setTimeout(e,0):document.addEventListener("WeixinJSBridgeReady",e),window.wx.miniProgram},function(e){if(c)return window.QQJSBridge&&window.QQJSBridge.invoke?setTimeout(e,0):document.addEventListener("QQJSBridgeReady",e),window.qq.miniProgram},function(e){if(u){document.addEventListener("DOMContentLoaded",e);var n=window.my;return{navigateTo:n.navigateTo,navigateBack:n.navigateBack,switchTab:n.switchTab,reLaunch:n.reLaunch,redirectTo:n.redirectTo,postMessage:n.postMessage,getEnv:n.getEnv}}},function(e){if(g)return document.addEventListener("DOMContentLoaded",e),window.swan.webView},function(e){if(v)return document.addEventListener("DOMContentLoaded",e),window.tt.miniProgram},function(e){if(p){window.QaJSBridge&&window.QaJSBridge.invoke?setTimeout(e,0):document.addEventListener("QaJSBridgeReady",e);var n=window.qa;return{navigateTo:n.navigateTo,navigateBack:n.navigateBack,switchTab:n.switchTab,reLaunch:n.reLaunch,redirectTo:n.redirectTo,postMessage:n.postMessage,getEnv:n.getEnv}}},function(e){if(f)return window.WeixinJSBridge&&window.WeixinJSBridge.invoke?setTimeout(e,0):document.addEventListener("WeixinJSBridgeReady",e),window.ks.miniProgram},function(e){if(l)return document.addEventListener("DOMContentLoaded",e),window.tt.miniProgram},function(e){if(_)return window.JDJSBridgeReady&&window.JDJSBridgeReady.invoke?setTimeout(e,0):document.addEventListener("JDJSBridgeReady",e),window.jd.miniProgram},function(e){return document.addEventListener("DOMContentLoaded",e),a}],y=0;y\s]+))?)*)\s*(\/?)>/; +var endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/; +var attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; // Empty Elements - HTML 5 + +var empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'); // Block Elements - HTML 5 +// fixed by xxx 将 ins 标签从块级名单中移除 + +var block = makeMap('a,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video'); // Inline Elements - HTML 5 + +var inline = makeMap('abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'); // Elements that you can, intentionally, leave open +// (and which close themselves) + +var closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); // Attributes that have their values filled in disabled="disabled" + +var fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'); // Special Elements (can contain anything) + +var special = makeMap('script,style'); +function HTMLParser(html, handler) { + var index; + var chars; + var match; + var stack = []; + var last = html; + + stack.last = function () { + return this[this.length - 1]; + }; + + while (html) { + chars = true; // Make sure we're not in a script or style element + + if (!stack.last() || !special[stack.last()]) { + // Comment + if (html.indexOf(''); + + if (index >= 0) { + if (handler.comment) { + handler.comment(html.substring(4, index)); + } + + html = html.substring(index + 3); + chars = false; + } // end tag + + } else if (html.indexOf(']*>'), function (all, text) { + text = text.replace(/|/g, '$1$2'); + + if (handler.chars) { + handler.chars(text); + } + + return ''; + }); + parseEndTag('', stack.last()); + } + + if (html == last) { + throw 'Parse Error: ' + html; + } + + last = html; + } // Clean up any remaining tags + + + parseEndTag(); + + function parseStartTag(tag, tagName, rest, unary) { + tagName = tagName.toLowerCase(); + if (block[tagName]) { + while (stack.last() && inline[stack.last()]) { + parseEndTag('', stack.last()); + } + } + + if (closeSelf[tagName] && stack.last() == tagName) { + parseEndTag('', tagName); + } + + unary = empty[tagName] || !!unary; + + if (!unary) { + stack.push(tagName); + } + + if (handler.start) { + var attrs = []; + rest.replace(attr, function (match, name) { + var value = arguments[2] ? arguments[2] : arguments[3] ? arguments[3] : arguments[4] ? arguments[4] : fillAttrs[name] ? name : ''; + attrs.push({ + name: name, + value: value, + escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') // " + + }); + }); + + if (handler.start) { + handler.start(tagName, attrs, unary); + } + } + } + + function parseEndTag(tag, tagName) { + // If no tag name is provided, clean shop + if (!tagName) { + var pos = 0; + } // Find the closest opened tag of the same type + else { + for (var pos = stack.length - 1; pos >= 0; pos--) { + if (stack[pos] == tagName) { + break; + } + } + } + + if (pos >= 0) { + // Close all the open elements, up the stack + for (var i = stack.length - 1; i >= pos; i--) { + if (handler.end) { + handler.end(stack[i]); + } + } // Remove the open elements from the stack + + + stack.length = pos; + } + } +} + +function makeMap(str) { + var obj = {}; + var items = str.split(','); + + for (var i = 0; i < items.length; i++) { + obj[items[i]] = true; + } + + return obj; +} + +function removeDOCTYPE(html) { + return html.replace(/<\?xml.*\?>\n/, '').replace(/\n/, '').replace(/\n/, ''); +} + +function parseAttrs(attrs) { + return attrs.reduce(function (pre, attr) { + var value = attr.value; + var name = attr.name; + if (pre[name]) { + pre[name] = pre[name] + " " + value; + } else { + pre[name] = value; + } + + return pre; + }, {}); +} +function convertStyleStringToJSON(styleString) { + var styles = styleString.split(";"); // 通过分号将样式字符串分割为多个样式声明 + var result = {}; + + styles.forEach(function(style) { + var styleParts = style.split(":"); // 通过冒号将样式声明分割为属性和值 + var property = styleParts[0].trim(); + var value = styleParts[1] && styleParts[1].trim(); + + if (property && value) { + result[property] = value; // 将属性和值添加到结果对象中 + } + }); + + return result; +} +function parseHtml(html) { + html = removeDOCTYPE(html); + var stacks = []; + var results = { + node: 'root', + children: [] + }; + HTMLParser(html, { + start: function start(tag, attrs, unary) { + var node = { + name: tag + }; + + if (attrs.length !== 0) { + node.attrs = parseAttrs(attrs); + node.styles = node.attrs.style ? convertStyleStringToJSON(node.attrs.style) : {} + } + + if(!node.type) { + if(inline[node.name] && node.name !== 'img' ) { + node.type = 'text'; + if(node.name == 'br') { + node.text = '\n' + } else if(node.name == 'strong'){ + node.styles.fontWeight = 'bold' + } + } else if(node.name == 'img'){ + node.type = 'image' + node.src = node.attrs.src + } else { + node.type = 'view' + if(['h1','h2','h3','h4','h5','h6'].includes(node.name)) { + node.styles.fontWeight = 'bold' + } + } + } + if (unary) { + var parent = stacks[0] || results; + + if (!parent.children) { + parent.children = []; + } + + parent.children.push(node); + } else { + stacks.unshift(node); + } + }, + end: function end(tag) { + var node = stacks.shift(); + if (node.name !== tag) console.error('invalid state: mismatch end tag'); + if (stacks.length === 0) { + results.children.push(node); + } else { + var parent = stacks[0]; + + if (!parent.children) { + parent.children = []; + } + parent.children.push(node); + } + const isTextBox = node.children && node.children.length > 1 && node.children.every(child => { + return ['text','image'].includes(child.type) + }) + if(isTextBox) { + node.type = 'textBox' + } + }, + chars: function chars(text) { + var node = { + type: 'text', + text: text + }; + + if (stacks.length === 0) { + results.children.push(node); + } else { + var parent = stacks[0]; + + if (!parent.children) { + parent.children = []; + } + + parent.children.push(node); + } + }, + comment: function comment(text) { + var node = { + node: 'comment', + text: text + }; + var parent = stacks[0]; + + if (!parent.children) { + parent.children = []; + } + + parent.children.push(node); + } + }); + return results.children; +} + +export default parseHtml; \ No newline at end of file diff --git a/uni_modules/lime-painter/readme.md b/uni_modules/lime-painter/readme.md new file mode 100644 index 0000000..9cfdb6d --- /dev/null +++ b/uni_modules/lime-painter/readme.md @@ -0,0 +1,963 @@ +# Painter 画板 测试版 + +> uniapp 海报画板,更优雅的海报生成方案 +> [查看更多 站点 1](https://limeui.qcoon.cn/#/painter) +> [查看更多 站点 2](http://liangei.gitee.io/limeui/#/painter) +> Q 群:1169785031 + +## 平台兼容 + +| H5 | 微信小程序 | 支付宝小程序 | 百度小程序 | 头条小程序 | QQ 小程序 | App | +| --- | ---------- | ------------ | ---------- | ---------- | --------- | --- | +| √ | √ | √ | 未测 | √ | √ | √ | + +## 安装 +在市场导入**[海报画板](https://ext.dcloud.net.cn/plugin?id=2389)uni_modules**版本的即可,无需`import` + +## 代码演示 + +### 插件demo +- lime-painter 为 demo +- 位于 uni_modules/lime-painter/components/lime-painter +- 导入插件后直接使用可查看demo +```vue + +``` + + +### 基本用法 + +- 插件提供 JSON 及 Template 的方式绘制海报 +- 参考 css 块状流布局模拟 css schema。 +- 另外flex布局还不是成完善,请谨慎使用,普通的流布局我觉得已经够用了。 + +#### 方式一 Template + +- 提供`l-painter-view`、`l-painter-text`、`l-painter-image`、`l-painter-qrcode`四种类型组件 +- 通过 `css` 属性绘制样式,与 style 使用方式保持一致。 +```html + + //如果使用Template出现顺序错乱,可使用`template` 等所有变量完成再显示 +