Commit feb53f80ce7984a64f7e7dd16774876ce2bea2d4

Authored by guzijian
1 parent 3972b923

feat: 新增取消订单

garbage-removal/src/pages/home/address/addSite.vue
@@ -239,11 +239,12 @@ const reset = () => { @@ -239,11 +239,12 @@ const reset = () => {
239 239
240 .submit-button { 240 .submit-button {
241 display: flex; 241 display: flex;
242 - width: 600rpx; 242 + margin: auto;
  243 + width: 80%;
243 line-height: 100rpx; 244 line-height: 100rpx;
244 position: absolute; 245 position: absolute;
245 bottom: 30rpx; 246 bottom: 30rpx;
246 - left: 80rpx; 247 + left: 10%;
247 font-size: 30rpx; 248 font-size: 30rpx;
248 color: #ffffff; 249 color: #ffffff;
249 250
garbage-removal/src/pages/home/address/index.vue
@@ -151,7 +151,7 @@ onShow(() => { @@ -151,7 +151,7 @@ onShow(() => {
151 display: flex; 151 display: flex;
152 justify-content: center; 152 justify-content: center;
153 align-content: center; 153 align-content: center;
154 - width: 600rpx; 154 + width: 80%;
155 line-height: 100rpx; 155 line-height: 100rpx;
156 position: absolute; 156 position: absolute;
157 bottom: 30rpx; 157 bottom: 30rpx;
garbage-removal/src/pages/home/clean/company-detail/index.vue
@@ -120,7 +120,6 @@ const serverData = ref([ @@ -120,7 +120,6 @@ const serverData = ref([
120 * 拨打电话回调 120 * 拨打电话回调
121 */ 121 */
122 const handleContactClick = (val) => { 122 const handleContactClick = (val) => {
123 - console.log("拨打电话");  
124 uni.makePhoneCall({ phoneNumber: val }).then(res => { 123 uni.makePhoneCall({ phoneNumber: val }).then(res => {
125 console.log(res); 124 console.log(res);
126 }).catch(err => { }); 125 }).catch(err => { });
@@ -142,7 +141,6 @@ const handleCleanGarbage = (companyObj, tel, userAddress) => { @@ -142,7 +141,6 @@ const handleCleanGarbage = (companyObj, tel, userAddress) => {
142 } 141 }
143 142
144 const initData = (baseData) => { 143 const initData = (baseData) => {
145 - console.log(baseData);  
146 baseDataList.value[0].value = baseData.legalRepresentative 144 baseDataList.value[0].value = baseData.legalRepresentative
147 baseDataList.value[1].value = baseData.safetyManagerName 145 baseDataList.value[1].value = baseData.safetyManagerName
148 baseDataList.value[2].value = baseData.safetyManagerPhone 146 baseDataList.value[2].value = baseData.safetyManagerPhone
garbage-removal/src/pages/home/clean/index.vue
@@ -55,7 +55,6 @@ @@ -55,7 +55,6 @@
55 </view> 55 </view>
56 </view> 56 </view>
57 </view> 57 </view>
58 -  
59 <view class="company-clean-container-site-image-info"> 58 <view class="company-clean-container-site-image-info">
60 <view class="company-clean-container-site-image-info-remark"> 59 <view class="company-clean-container-site-image-info-remark">
61 <text style="color: red;">*</text>现场照片(最多上传10张) 60 <text style="color: red;">*</text>现场照片(最多上传10张)
@@ -73,10 +72,11 @@ @@ -73,10 +72,11 @@
73 </view> 72 </view>
74 <view class="company-clean-container-site-image-info-sure-button"> 73 <view class="company-clean-container-site-image-info-sure-button">
75 <view class="company-clean-container-site-image-info-sure-button-radio"> 74 <view class="company-clean-container-site-image-info-sure-button-radio">
76 - <u-radio-group v-model="paramFrom.sureReadFlag">  
77 - <u-radio activeColor="#a9e08f" size="27" labelSize="25" :name="true" :labelDisabled="true"  
78 - labelColor="#909399" label=""></u-radio>本人已确认信息真实有效,并将上述信息告知市容环境卫生主管部门。  
79 - </u-radio-group> 75 + <u-checkbox-group v-model="paramFrom.sureReadFlag" placement="row">
  76 + <u-checkbox activeColor="#a9e08f" size="25" labelSize="25" shape="circle" @change="changeAgree" :key="0"
  77 + :name="true" :labelDisabled="true" labelColor="#909399"
  78 + label="本人已确认信息真实有效,并将上述信息告知市容环境卫生主管部门。"></u-checkbox>
  79 + </u-checkbox-group>
80 </view> 80 </view>
81 </view> 81 </view>
82 </view> 82 </view>
@@ -124,7 +124,7 @@ const garbageTypeList = ref([&quot;建筑垃圾&quot;, &quot;装修垃圾&quot;]) @@ -124,7 +124,7 @@ const garbageTypeList = ref([&quot;建筑垃圾&quot;, &quot;装修垃圾&quot;])
124 const paramFrom = ref({ 124 const paramFrom = ref({
125 carNumber: 1, 125 carNumber: 1,
126 remark: "", 126 remark: "",
127 - sureReadFlag: false, 127 + sureReadFlag: [],
128 carType: "", 128 carType: "",
129 garbageType: "装修垃圾" 129 garbageType: "装修垃圾"
130 }) 130 })
@@ -140,6 +140,12 @@ const handleTimeChoose = () =&gt; { @@ -140,6 +140,12 @@ const handleTimeChoose = () =&gt; {
140 const changeTime = (e) => { 140 const changeTime = (e) => {
141 dayTime.value = e.value 141 dayTime.value = e.value
142 } 142 }
  143 +const changeAgree = (e) => {
  144 + // paramFrom.value.sureReadFlag = e
  145 +}
  146 +const onChange = (e) => {
  147 + // console.log(e);
  148 +}
143 /** 149 /**
144 * 初始化信息 150 * 初始化信息
145 */ 151 */
@@ -148,8 +154,7 @@ onLoad((options) =&gt; { @@ -148,8 +154,7 @@ onLoad((options) =&gt; {
148 tel.value = options.tel; 154 tel.value = options.tel;
149 userAddress.value = JSON.parse(options.userAddress); 155 userAddress.value = JSON.parse(options.userAddress);
150 queryCarList({ companyId: companyObj.value.id }).then(res => { 156 queryCarList({ companyId: companyObj.value.id }).then(res => {
151 - candidates.value = res.data.rows.map(item => item.carType)  
152 - console.log(candidates.value); 157 + candidates.value = [...new Set(res.data.rows.map(item => item.carType))];
153 }) 158 })
154 }) 159 })
155 160
@@ -287,14 +292,18 @@ onMounted(() =&gt; { @@ -287,14 +292,18 @@ onMounted(() =&gt; {
287 movableArea.boundingClientRect(function (data) { 292 movableArea.boundingClientRect(function (data) {
288 // data - 包含元素的高度等信息 293 // data - 包含元素的高度等信息
289 areaHeight = data.height; 294 areaHeight = data.height;
290 - y.value = areaHeight; 295 + y.value = areaHeight > 20 ? (areaHeight - 20) : areaHeight;
291 }).exec(function (res) { 296 }).exec(function (res) {
292 // 注意:exec方法必须执行,即便什么也不做,否则不会获取到任何数据 297 // 注意:exec方法必须执行,即便什么也不做,否则不会获取到任何数据
293 }) 298 })
294 }) 299 })
295 300
  301 +/**
  302 + * 校验参数
  303 + * @param {Object} params
  304 + */
296 const validateParams = (params) => { 305 const validateParams = (params) => {
297 - if (!paramFrom.value.sureReadFlag) { 306 + if (!paramFrom.value.sureReadFlag[0]) {
298 jumpPrompt('请勾选"本人已确认信息真实有效,并将上诉信息告知市容环境卫生主管部门"') 307 jumpPrompt('请勾选"本人已确认信息真实有效,并将上诉信息告知市容环境卫生主管部门"')
299 return false; 308 return false;
300 } 309 }
@@ -313,7 +322,6 @@ const validateParams = (params) =&gt; { @@ -313,7 +322,6 @@ const validateParams = (params) =&gt; {
313 } 322 }
314 return false; 323 return false;
315 } 324 }
316 - console.log("key:", key, key == "imageUrls");  
317 if (key == "imageUrls") { 325 if (key == "imageUrls") {
318 if (params[key].length == 0) { 326 if (params[key].length == 0) {
319 jumpPrompt('请上传现场图片') 327 jumpPrompt('请上传现场图片')
@@ -325,7 +333,6 @@ const validateParams = (params) =&gt; { @@ -325,7 +333,6 @@ const validateParams = (params) =&gt; {
325 } 333 }
326 } 334 }
327 } 335 }
328 -  
329 return true; 336 return true;
330 } 337 }
331 338
@@ -342,7 +349,6 @@ const jumpPrompt = (msg) =&gt; { @@ -342,7 +349,6 @@ const jumpPrompt = (msg) =&gt; {
342 }); 349 });
343 } 350 }
344 const validateImage = (fileList) => { 351 const validateImage = (fileList) => {
345 - console.log(fileList);  
346 352
347 for (let index = 0; index < fileList.length; index++) { 353 for (let index = 0; index < fileList.length; index++) {
348 const str = fileList[index]; 354 const str = fileList[index];
@@ -542,8 +548,8 @@ $custom-bottom-height: 200rpx; @@ -542,8 +548,8 @@ $custom-bottom-height: 200rpx;
542 .company-clean-container-site-image-info-sure-button-radio { 548 .company-clean-container-site-image-info-sure-button-radio {
543 padding: $custom-page-padding; 549 padding: $custom-page-padding;
544 box-sizing: border-box; 550 box-sizing: border-box;
545 - display: flex;  
546 - flex-flow: row wrap; 551 + // display: flex;
  552 + // flex-flow: row wrap;
547 color: $u-info; 553 color: $u-info;
548 } 554 }
549 } 555 }
garbage-removal/src/pages/login/index.vue
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 </view> 11 </view>
12 </view> 12 </view>
13 <view class="buttom"> 13 <view class="buttom">
14 - <view class="loginType"> 14 + <!-- <view class="loginType">
15 <view class="wechat item"> 15 <view class="wechat item">
16 <button class="box" open-type="getPhoneNumber" @getphonenumber="handleWeixinLogin"> 16 <button class="box" open-type="getPhoneNumber" @getphonenumber="handleWeixinLogin">
17 <view class="icon"><u-icon size="60" name="weixin-fill" color="rgb(83,194,64)"></u-icon> 17 <view class="icon"><u-icon size="60" name="weixin-fill" color="rgb(83,194,64)"></u-icon>
@@ -19,11 +19,18 @@ @@ -19,11 +19,18 @@
19 微信登录 19 微信登录
20 </button> 20 </button>
21 </view> 21 </view>
22 - </view> 22 + </view> -->
23 <view class="hint"> 23 <view class="hint">
24 - 登录代表同意  
25 - <text class="link" @click="handleUserAgreement">用户协议、隐私政策,</text>  
26 - 并授权使用您的账号信息(如昵称、头像、收获地址)以便您统一管理 24 + <u-checkbox-group v-model="agree" placement="row" @change="groupChange">
  25 + <u-checkbox shape="circle" :customStyle="{ marginBottom: '8px', marginTop: '2px' }" :key="0" :name="true"
  26 + @change="radioChange">
  27 + </u-checkbox>
  28 + </u-checkbox-group>
  29 + <view class="prompt-txt">
  30 + 登录代表同意
  31 + <text class="link" @click="handleUserAgreement">用户协议、隐私政策,</text>
  32 + 并授权使用您的账号信息(如昵称、头像、收获地址)以便您统一管理。
  33 + </view>
27 </view> 34 </view>
28 </view> 35 </view>
29 </view> 36 </view>
@@ -34,7 +41,8 @@ import { userLogin } from &quot;@/apis/user.js&quot;; @@ -34,7 +41,8 @@ import { userLogin } from &quot;@/apis/user.js&quot;;
34 export default { 41 export default {
35 data() { 42 data() {
36 return { 43 return {
37 - tel: '18977778888' 44 + tel: '18977778888',
  45 + agree: []
38 } 46 }
39 }, 47 },
40 computed: { 48 computed: {
@@ -48,11 +56,28 @@ export default { @@ -48,11 +56,28 @@ export default {
48 } 56 }
49 }, 57 },
50 methods: { 58 methods: {
  59 + groupChange(e) {
  60 + console.log(e);
  61 + },
51 submit() { 62 submit() {
52 if (this.$u.test.mobile(this.tel)) { 63 if (this.$u.test.mobile(this.tel)) {
53 - this.$u.route({  
54 - url: `pages/login/code?iphoneNumber=${this.tel}`,  
55 - }) 64 + if (this.agree[0]) {
  65 + this.$u.route({
  66 + url: `pages/login/code?iphoneNumber=${this.tel}`,
  67 + })
  68 + } else {
  69 + let that = this
  70 + uni.showModal({
  71 + title: '提示',
  72 + content: '需要同意登录协议',
  73 + success: function (res) {
  74 + if (res.confirm) {
  75 + that.agree[0] = true
  76 + } else if (res.cancel) {
  77 + }
  78 + }
  79 + })
  80 + }
56 } else { 81 } else {
57 this.$refs.uToastRef.show({ 82 this.$refs.uToastRef.show({
58 type: 'default', 83 type: 'default',
@@ -67,6 +92,9 @@ export default { @@ -67,6 +92,9 @@ export default {
67 handleUserAgreement() { 92 handleUserAgreement() {
68 console.log("user click agreement"); 93 console.log("user click agreement");
69 }, 94 },
  95 + radioChange(e) {
  96 + this.agree = e
  97 + },
70 handleWeixinLogin(wxInfo) { 98 handleWeixinLogin(wxInfo) {
71 uni.login({ 99 uni.login({
72 provider: 'weixin', 100 provider: 'weixin',
@@ -165,10 +193,16 @@ export default { @@ -165,10 +193,16 @@ export default {
165 padding: 20rpx 40rpx; 193 padding: 20rpx 40rpx;
166 font-size: 20rpx; 194 font-size: 20rpx;
167 color: $u-tips-color; 195 color: $u-tips-color;
  196 + display: flex;
  197 + justify-content: flex-start;
168 198
169 - .link {  
170 - color: $u-warning; 199 + .prompt-txt {
  200 + .link {
  201 + color: $u-warning;
  202 + }
171 } 203 }
  204 +
  205 +
172 } 206 }
173 } 207 }
174 } 208 }
garbage-removal/src/pages/order/detail/index.vue
@@ -14,7 +14,11 @@ @@ -14,7 +14,11 @@
14 </view> 14 </view>
15 <!-- 信息提示 --> 15 <!-- 信息提示 -->
16 <view class="order-detail-container-box-card"> 16 <view class="order-detail-container-box-card">
17 - <text style="color: red;">请于交易完成后线下支付!!</text> 17 + <text v-if="dataGram.garCancelFlag == 0" style="color: red;">请于交易完成后线下支付!!</text>
  18 + <view v-else style="display: flex;color: red;">
  19 + <u-icon name="close-circle" color="red"></u-icon>
  20 + <text style="color: red;">&nbsp;&nbsp;订单已被取消!</text>
  21 + </view>
18 </view> 22 </view>
19 <!-- 派单信息 --> 23 <!-- 派单信息 -->
20 <view class="order-detail-container-box-card"> 24 <view class="order-detail-container-box-card">
@@ -134,23 +138,30 @@ @@ -134,23 +138,30 @@
134 <image class="image-style" style="width: 200rpx; height: 200rpx;" :src="emptyBase64Image"></image> 138 <image class="image-style" style="width: 200rpx; height: 200rpx;" :src="emptyBase64Image"></image>
135 </view> 139 </view>
136 </view> 140 </view>
  141 + <view class="space-box">{{ spaceStr }}</view>
  142 +
137 </view> 143 </view>
138 <!-- 占位符 --> 144 <!-- 占位符 -->
139 - <view class="space-box">{{ spaceStr }}</view>  
140 <view class="order-detail-bottom"> 145 <view class="order-detail-bottom">
141 <view class="order-detail-bottom-box"> 146 <view class="order-detail-bottom-box">
142 <view class="order-detail-bottom-left"> 147 <view class="order-detail-bottom-left">
143 - <!-- <u-button @click="handleOderSure" shape="circle" color="#a9e08f" text="取消订单"></u-button> -->  
144 - <u-button v-if="dataGram.garOrderHandlerStatus == 1" @click="handleSubmitSuccess(orderId)" shape="circle"  
145 - color="#a9e08f" text="完成派单"></u-button> 148 + <!-- <u-button @click="handleOderCancelClick(orderId)" shape="circle" color="#a9e08f" text="取消订单"></u-button> -->
146 </view> 149 </view>
147 <view class="order-detail-bottom-right"> 150 <view class="order-detail-bottom-right">
148 - <u-button @click="handleOrder(orderId)" v-if="dataGram.garOrderHandlerStatus == 0 && dataGram.handleFlag"  
149 - shape="circle" color="#a9e08f" text="处理派单"></u-button>  
150 - <u-button @click="handleUploadImage(orderId)" v-if="dataGram.garOrderHandlerStatus == 1 && dataGram.handleFlag"  
151 - shape="circle" color="#a9e08f" text="上传照片"></u-button> 151 + <u-button @click="handleOrder(orderId)"
  152 + v-if="dataGram.garOrderHandlerStatus == 0 && dataGram.handleFlag && dataGram.garCancelFlag" shape="circle"
  153 + color="#a9e08f" text="处理派单"></u-button>
  154 + <u-button @click="handleUploadImage(orderId, 'putOnImages')"
  155 + v-if="dataGram.garOrderHandlerStatus === 1 && dataGram.putOnImages.length === 0 && dataGram.handleFlag && dataGram.garCancelFlag"
  156 + shape="circle" color="#a9e08f" text="装车照片"></u-button>
  157 + <u-button @click="handleUploadImage(orderId, 'putDownImages')"
  158 + v-else-if="dataGram.garOrderHandlerStatus === 1 && dataGram.putDownImages.length === 0 && dataGram.handleFlag && dataGram.garCancelFlag"
  159 + shape="circle" color="#a9e08f" text="卸车照片"></u-button>
152 <u-button @click="handleEvaluate(orderId)" v-if="dataGram.garEvaluateFlag == 0" shape="circle" color="#a9e08f" 160 <u-button @click="handleEvaluate(orderId)" v-if="dataGram.garEvaluateFlag == 0" shape="circle" color="#a9e08f"
153 text="去评价"></u-button> 161 text="去评价"></u-button>
  162 + <u-button
  163 + v-if="dataGram.garOrderHandlerStatus == 1 && dataGram.putOnImages.length != 0 && dataGram.putDownImages.length != 0 && dataGram.garCancelFlag"
  164 + @click="handleSubmitSuccess(orderId)" shape="circle" color="#a9e08f" text="完成派单"></u-button>
154 </view> 165 </view>
155 </view> 166 </view>
156 </view> 167 </view>
@@ -174,7 +185,6 @@ const spaceStr = ref(&quot;&quot;) @@ -174,7 +185,6 @@ const spaceStr = ref(&quot;&quot;)
174 */ 185 */
175 onLoad((options) => { 186 onLoad((options) => {
176 orderId.value = options.orderId 187 orderId.value = options.orderId
177 - console.log(emptyBase64Image.value);  
178 }) 188 })
179 const handleOrderDetail = (orderId) => { 189 const handleOrderDetail = (orderId) => {
180 queryOrderDetail(orderId).then(res => { 190 queryOrderDetail(orderId).then(res => {
@@ -197,7 +207,9 @@ const handleContactClick = (val) =&gt; { @@ -197,7 +207,9 @@ const handleContactClick = (val) =&gt; {
197 uni.makePhoneCall({ phoneNumber: val }).then(res => { 207 uni.makePhoneCall({ phoneNumber: val }).then(res => {
198 }).catch(err => { }); 208 }).catch(err => { });
199 } 209 }
  210 +const handleOderCancelClick = (orderId) => {
200 211
  212 +}
201 // 提交完成 213 // 提交完成
202 const handleSubmitSuccess = (orderId) => { 214 const handleSubmitSuccess = (orderId) => {
203 uni.showModal({ 215 uni.showModal({
@@ -212,7 +224,6 @@ const handleSubmitSuccess = (orderId) =&gt; { @@ -212,7 +224,6 @@ const handleSubmitSuccess = (orderId) =&gt; {
212 } 224 }
213 }) 225 })
214 } else if (res.cancel) { 226 } else if (res.cancel) {
215 - console.log('用户点击取消');  
216 } 227 }
217 } 228 }
218 }); 229 });
@@ -233,15 +244,14 @@ const handleOrder = (orderId) =&gt; { @@ -233,15 +244,14 @@ const handleOrder = (orderId) =&gt; {
233 244
234 245
235 const currentStep = (step) => { 246 const currentStep = (step) => {
236 - console.log(step);  
237 if (step > 2) { 247 if (step > 2) {
238 return step - 1; 248 return step - 1;
239 } 249 }
240 return step; 250 return step;
241 } 251 }
242 252
243 -const handleUploadImage = (orderId) => {  
244 - uni.$u.route(`pages/order/upload/index?orderId=${orderId}`) 253 +const handleUploadImage = (orderId, putType) => {
  254 + uni.$u.route(`pages/order/upload/index?orderId=${orderId}&putType=${putType}`)
245 } 255 }
246 256
247 onShow(() => { 257 onShow(() => {
garbage-removal/src/pages/order/swiper-list-item/index.vue
@@ -10,10 +10,11 @@ @@ -10,10 +10,11 @@
10 <view class="store">{{ item.garOrderCompanyName }}</view> 10 <view class="store">{{ item.garOrderCompanyName }}</view>
11 <u-icon name="arrow-right" color="rgb(203,203,203)" :size="26"></u-icon> 11 <u-icon name="arrow-right" color="rgb(203,203,203)" :size="26"></u-icon>
12 </view> 12 </view>
13 - <view v-if="item.garOrderHandlerStatus === 0" class="right">待清运 </view>  
14 - <view v-if="item.garOrderHandlerStatus === 1" class="right">清运中 </view>  
15 - <view v-if="item.garEvaluateFlag === 0" class="right">待评价 </view>  
16 - <view v-if="item.garEvaluateFlag === 1" class="right">已评价 </view> 13 + <view v-if="item.garOrderHandlerStatus === 0 && item.garCancelFlag === 0" class="right">待清运 </view>
  14 + <view v-if="item.garCancelFlag === 1" class="right">已取消 </view>
  15 + <view v-if="item.garOrderHandlerStatus === 1 && item.garCancelFlag === 0" class="right">清运中 </view>
  16 + <view v-if="item.garEvaluateFlag === 0 && item.garCancelFlag === 0" class="right">待评价 </view>
  17 + <view v-if="item.garEvaluateFlag === 1 && item.garCancelFlag === 0" class="right">已评价 </view>
17 </view> 18 </view>
18 <view class="item" @click="handleClick(item.garOrderId)"> 19 <view class="item" @click="handleClick(item.garOrderId)">
19 <view class="left"> 20 <view class="left">
@@ -25,21 +26,23 @@ @@ -25,21 +26,23 @@
25 <view class="delivery-time">预约时间 {{ item.garOrderAgreementTime }}</view> 26 <view class="delivery-time">预约时间 {{ item.garOrderAgreementTime }}</view>
26 </view> 27 </view>
27 </view> 28 </view>
28 - <!-- <view class="bottom"> 29 + <view class="bottom" v-if="item.garOrderHandlerStatus === 0 && item.garCancelFlag === 0">
29 <view class="more"> 30 <view class="more">
30 - <u-icon name="more-dot-fill" color="rgb(203,203,203)"></u-icon> 31 + <!-- <u-icon name="more-dot-fill" color="rgb(203,203,203)"></u-icon> -->
31 </view> 32 </view>
32 - <view class="logistics btn" v-if="item.garOrderHandlerStatus === 0" @click="">取消订单</view>  
33 - <view class="evaluate btn" v-if="item.garOrderHandlerStatus === 4">评价</view>  
34 - </view> --> 33 + <view hover-class="btn-hover" class="logistics btn" @click="handleCancelOrder(item.garOrderId)">取消派单</view>
  34 + </view>
35 </view> 35 </view>
36 </view> 36 </view>
37 </z-paging> 37 </z-paging>
  38 + <u-action-sheet :closeOnClickOverlay="true" :closeOnClickAction="false" @actionSheetClose="handleClose"
  39 + @submitFunction="submitFunction" @select="selectClick" :actions="list" round="15" title="取消派单" :show="cancelShow">
  40 + </u-action-sheet>
38 </view> 41 </view>
39 </template> 42 </template>
40 43
41 <script setup> 44 <script setup>
42 -import { queryOrderList } from "@/apis/order.js"; 45 +import { queryOrderList, updateOrder } from "@/apis/order.js";
43 import { ref, watch } from 'vue'; 46 import { ref, watch } from 'vue';
44 const props = defineProps({ 47 const props = defineProps({
45 tabIndex: { 48 tabIndex: {
@@ -49,10 +52,73 @@ const props = defineProps({ @@ -49,10 +52,73 @@ const props = defineProps({
49 type: Number 52 type: Number
50 } 53 }
51 }) 54 })
  55 +
  56 +const currentCancelOrderId = ref("");
  57 +const currentCancelName = ref("");
  58 +const cancelShow = ref(false)
  59 +const list = ref([
  60 + {
  61 + name: '长时间无人接单',
  62 + },
  63 + {
  64 + name: '订单信息填写有误',
  65 + },
  66 + {
  67 + name: '线下协商有问题',
  68 + },
  69 + {
  70 + name: '不需要清运了',
  71 + },
  72 + {
  73 + name: '其他',
  74 + },
  75 + {
  76 + name: '提交',
  77 + }
  78 +])
52 const dataList = ref([]); 79 const dataList = ref([]);
53 const paging = ref(null); 80 const paging = ref(null);
54 const firstLoaded = ref(false) 81 const firstLoaded = ref(false)
  82 +/**
  83 + * 取消订单
  84 + * @param {string} orderId
  85 + */
  86 +const handleCancelOrder = (orderId) => {
  87 + currentCancelOrderId.value = orderId
  88 + cancelShow.value = true
  89 +}
  90 +const handleClose = (e) => {
  91 + cancelShow.value = false
  92 +}
55 93
  94 +const selectClick = (index) => {
  95 + currentCancelName.value = index.name;
  96 +}
  97 +/**
  98 + * 提交取消订单
  99 + */
  100 +const submitFunction = (otherReason) => {
  101 + let reason = otherReason
  102 + if (currentCancelName.value != "其他") {
  103 + reason = currentCancelName.value
  104 + }
  105 + if (!reason) {
  106 + uni.$u.toast("请提供取消派单的原因")
  107 + return
  108 + }
  109 + let params = {
  110 + garOrderId: currentCancelOrderId.value,
  111 + garCancelFlag: 1,
  112 + garReason: reason
  113 + }
  114 + updateOrder(params).then(res => {
  115 + if (res.data.success) {
  116 + cancelShow.value = false
  117 + uni.$u.toast(res.data.data)
  118 + paging.value.reload();
  119 + }
  120 + })
  121 +}
56 const handleClick = (orderId) => { 122 const handleClick = (orderId) => {
57 uni.$u.route({ 123 uni.$u.route({
58 url: `pages/order/detail/index`, 124 url: `pages/order/detail/index`,
@@ -70,7 +136,6 @@ const queryList = (pageNo, pageSize) =&gt; { @@ -70,7 +136,6 @@ const queryList = (pageNo, pageSize) =&gt; {
70 queryOrderList({ type: props.tabIndex, pageNo, pageSize }).then((res) => { 136 queryOrderList({ type: props.tabIndex, pageNo, pageSize }).then((res) => {
71 paging.value.complete(res.data.data.list); 137 paging.value.complete(res.data.data.list);
72 firstLoaded.value = true 138 firstLoaded.value = true
73 - console.log(res.data.data.list);  
74 }).catch(res => { 139 }).catch(res => {
75 //如果请求失败写paging.value.complete(false),会自动展示错误页面 140 //如果请求失败写paging.value.complete(false),会自动展示错误页面
76 //注意,每次都需要在catch中写这句话很麻烦,z-paging提供了方案可以全局统一处理 141 //注意,每次都需要在catch中写这句话很麻烦,z-paging提供了方案可以全局统一处理
@@ -89,7 +154,6 @@ watch(() =&gt; props.currentIndex, (val1, val2) =&gt; { @@ -89,7 +154,6 @@ watch(() =&gt; props.currentIndex, (val1, val2) =&gt; {
89 paging.value.reload(); 154 paging.value.reload();
90 }, 50); 155 }, 50);
91 } 156 }
92 -  
93 } 157 }
94 }, { immediate: true }) 158 }, { immediate: true })
95 </script> 159 </script>
@@ -99,7 +163,7 @@ watch(() =&gt; props.currentIndex, (val1, val2) =&gt; { @@ -99,7 +163,7 @@ watch(() =&gt; props.currentIndex, (val1, val2) =&gt; {
99 height: 100%; 163 height: 100%;
100 164
101 .order { 165 .order {
102 - width: 710rpx; 166 + width: 90%;
103 background-color: #ffffff; 167 background-color: #ffffff;
104 margin: 20rpx auto; 168 margin: 20rpx auto;
105 border-radius: 20rpx; 169 border-radius: 20rpx;
@@ -171,7 +235,7 @@ watch(() =&gt; props.currentIndex, (val1, val2) =&gt; { @@ -171,7 +235,7 @@ watch(() =&gt; props.currentIndex, (val1, val2) =&gt; {
171 235
172 .bottom { 236 .bottom {
173 display: flex; 237 display: flex;
174 - margin-top: 40rpx; 238 + margin-top: 20rpx;
175 padding: 0 10rpx; 239 padding: 0 10rpx;
176 justify-content: space-between; 240 justify-content: space-between;
177 align-items: center; 241 align-items: center;
@@ -186,6 +250,10 @@ watch(() =&gt; props.currentIndex, (val1, val2) =&gt; { @@ -186,6 +250,10 @@ watch(() =&gt; props.currentIndex, (val1, val2) =&gt; {
186 color: $u-info-dark; 250 color: $u-info-dark;
187 } 251 }
188 252
  253 + .btn--hover {
  254 + background-color: $u-success-light;
  255 + }
  256 +
189 .evaluate { 257 .evaluate {
190 color: $u-warning-dark; 258 color: $u-warning-dark;
191 border-color: $u-warning-dark; 259 border-color: $u-warning-dark;
garbage-removal/src/pages/order/upload/index.vue
1 <template> 1 <template>
2 <view class="upload-image-box"> 2 <view class="upload-image-box">
3 <view class="upload-image-box-choose"> 3 <view class="upload-image-box-choose">
4 - <text class="upload-image-box-choose-txt">请选择图片类型:</text> 4 + <text class="upload-image-box-choose-txt">请上传{{ putType }}图片类型:</text>
5 <view class="upload-image-box-choose-type"> 5 <view class="upload-image-box-choose-type">
6 - <u-radio-group v-model="singleItem" @change="groupChange" placement="row">  
7 - <u-radio activeColor="#19be6b" :customStyle="{ marginBottom: '8px' }" size="28" labelSize="28"  
8 - v-for="(item, index) in chooseList" :key="index" :label="item.name" :name="item.name" @change="radioChange">  
9 - </u-radio>  
10 - </u-radio-group> 6 +
11 </view> 7 </view>
12 </view> 8 </view>
13 <view class="upload-image-box-bottom"> 9 <view class="upload-image-box-bottom">
14 - <text class="upload-image-box-bottom-txt">{{ singleItem }}(最多上传10张)</text> 10 + <text class="upload-image-box-bottom-txt">{{ putType }}(最多上传10张)</text>
15 <view class="upload-image-box-button-container"> 11 <view class="upload-image-box-button-container">
16 <u-upload :fileList="fileList" @afterRead="afterRead" @delete="deletePic" name="3" multiple :maxCount="10" 12 <u-upload :fileList="fileList" @afterRead="afterRead" @delete="deletePic" name="3" multiple :maxCount="10"
17 :previewFullImage="true" width="200" height="150"></u-upload> 13 :previewFullImage="true" width="200" height="150"></u-upload>
18 </view> 14 </view>
19 </view> 15 </view>
20 <view class="upload-image-box-submit-box"> 16 <view class="upload-image-box-submit-box">
21 - <view class="upload-image-box-submit-box-button" @click="handleSubmit(orderId, singleItem)"> 17 + <view class="upload-image-box-submit-box-button" @click="handleSubmit(orderId, putType)">
22 <view class="upload-image-box-submit-box-button-container"> 18 <view class="upload-image-box-submit-box-button-container">
23 <up-button color="#19be6b" type="primary" shape="circle" text="确定"></up-button> 19 <up-button color="#19be6b" type="primary" shape="circle" text="确定"></up-button>
24 </view> 20 </view>
@@ -31,23 +27,16 @@ @@ -31,23 +27,16 @@
31 import { uploadFilePromise } from '@/apis/common.js'; 27 import { uploadFilePromise } from '@/apis/common.js';
32 import { uploadImageUrlByType } from '@/apis/order.js'; 28 import { uploadImageUrlByType } from '@/apis/order.js';
33 import { onLoad } from '@dcloudio/uni-app'; 29 import { onLoad } from '@dcloudio/uni-app';
34 -import { reactive, ref } from 'vue';  
35 - 30 +import { ref } from 'vue';
  31 +const putType = ref("")
36 const orderId = ref(); 32 const orderId = ref();
37 const fileList = ref([]) 33 const fileList = ref([])
38 -const singleItem = ref("装车图片")  
39 -const chooseList = reactive([{ name: "装车图片" }, { name: "卸车图片" }])  
40 // 删除图片 34 // 删除图片
41 const deletePic = (event) => { 35 const deletePic = (event) => {
42 fileList.value.splice(event.index, 1); 36 fileList.value.splice(event.index, 1);
43 }; 37 };
44 38
45 -const groupChange = (e) => {  
46 - console.log(e);  
47 -}  
48 -const radioChange = (e) => {  
49 - console.log(e);  
50 -} 39 +
51 40
52 // 新增图片 41 // 新增图片
53 const afterRead = async (event) => { 42 const afterRead = async (event) => {
@@ -82,11 +71,10 @@ const handleSubmit = (id, type) =&gt; { @@ -82,11 +71,10 @@ const handleSubmit = (id, type) =&gt; {
82 } 71 }
83 let params = { 72 let params = {
84 garOrderId: id, 73 garOrderId: id,
85 - type: type == "装车片" ? 1 : 2, 74 + type: type == "装车片" ? 1 : 2,
86 imageUrls: fileList.value.map(item => item.url) 75 imageUrls: fileList.value.map(item => item.url)
87 } 76 }
88 uploadImageUrlByType(params).then(res => { 77 uploadImageUrlByType(params).then(res => {
89 - console.log(res);  
90 if (res.data.success) { 78 if (res.data.success) {
91 uni.$u.toast("图片上传完毕!"); 79 uni.$u.toast("图片上传完毕!");
92 uni.$u.route({ 80 uni.$u.route({
@@ -122,6 +110,7 @@ const validateImage = () =&gt; { @@ -122,6 +110,7 @@ const validateImage = () =&gt; {
122 110
123 onLoad((options) => { 111 onLoad((options) => {
124 orderId.value = options.orderId; 112 orderId.value = options.orderId;
  113 + putType.value = options.putType === "putOnImages" ? "装车照片" : "卸车照片";
125 }) 114 })
126 </script> 115 </script>
127 116
garbage-removal/src/pages/wode/choose/index.vue
@@ -22,10 +22,8 @@ const store = useMainStore(); @@ -22,10 +22,8 @@ const store = useMainStore();
22 const userType = ref("居民用户") 22 const userType = ref("居民用户")
23 const typeList = ref([{ name: "居民用户" }, { name: "管理负责人" }]) 23 const typeList = ref([{ name: "居民用户" }, { name: "管理负责人" }])
24 const radioChange = (e) => { 24 const radioChange = (e) => {
25 - console.log(e);  
26 } 25 }
27 const groupChange = (e) => { 26 const groupChange = (e) => {
28 - console.log(e);  
29 } 27 }
30 const submit = (userType) => { 28 const submit = (userType) => {
31 setRequestToken(store.tempToken) 29 setRequestToken(store.tempToken)
garbage-removal/src/utils/request/request.js
@@ -51,6 +51,9 @@ const instance = axios.create({ @@ -51,6 +51,9 @@ const instance = axios.create({
51 }); 51 });
52 // 请求拦截器 52 // 请求拦截器
53 instance.interceptors.request.use((config) => { 53 instance.interceptors.request.use((config) => {
  54 + if (requestUrlCheck(config.url)) {
  55 + setRequestToken(null);
  56 + }
54 if (config.method.toLocaleLowerCase() == "get") { 57 if (config.method.toLocaleLowerCase() == "get") {
55 handleGet(config); 58 handleGet(config);
56 } 59 }
@@ -58,7 +61,12 @@ instance.interceptors.request.use((config) =&gt; { @@ -58,7 +61,12 @@ instance.interceptors.request.use((config) =&gt; {
58 }); 61 });
59 // 响应拦截器 62 // 响应拦截器
60 instance.interceptors.response.use((response) => { 63 instance.interceptors.response.use((response) => {
61 - if (response.data.code != 200) { 64 +
  65 + // 没有网络时 message的内容为"Network Error"
  66 + if(response.errMsg === "request:fail"){
  67 + uni.$u.toast("网络错误~")
  68 + }
  69 + if (response.data.code != 200) {
62 if (response.data.code == 401) { 70 if (response.data.code == 401) {
63 reSetLoginStatus(); 71 reSetLoginStatus();
64 } else { 72 } else {
@@ -70,17 +78,18 @@ instance.interceptors.response.use((response) =&gt; { @@ -70,17 +78,18 @@ instance.interceptors.response.use((response) =&gt; {
70 } 78 }
71 return response; 79 return response;
72 }, (error) => { 80 }, (error) => {
  81 +
73 if (error.response.status) { 82 if (error.response.status) {
74 switch (error.response.status) { 83 switch (error.response.status) {
75 case 401: 84 case 401:
76 case 403: 85 case 403:
77 - setRequestToken(null); 86 + reSetLoginStatus();
78 break; 87 break;
79 default: 88 default:
80 break; 89 break;
81 } 90 }
82 } 91 }
83 - uni.$u.toast("网络波动请再试~") 92 +
84 return Promise.reject(error) 93 return Promise.reject(error)
85 }); 94 });
86 export default instance; 95 export default instance;
@@ -100,6 +109,15 @@ const reSetLoginStatus = () =&gt; { @@ -100,6 +109,15 @@ const reSetLoginStatus = () =&gt; {
100 }) 109 })
101 return 110 return
102 } 111 }
  112 +let urlRegex = /\/user\/send\/verify/;
  113 +
  114 +/**
  115 + * 检查需要被拦截的路径
  116 + */
  117 +const requestUrlCheck = (url) => {
  118 + // 使用正则表达式进行匹配
  119 + return urlRegex.test(url);
  120 +}
103 121
104 const handleGet = (config) => { 122 const handleGet = (config) => {
105 let strUrl = ""; 123 let strUrl = "";
@@ -115,5 +133,4 @@ const handleGet = (config) =&gt; { @@ -115,5 +133,4 @@ const handleGet = (config) =&gt; {
115 } 133 }
116 config.url += strUrl; 134 config.url += strUrl;
117 config.params = ""; 135 config.params = "";
118 - console.log("请求拦截",config);  
119 } 136 }
garbage-removal/src/uview-plus/components/u-action-sheet/props.js
@@ -50,6 +50,9 @@ export default { @@ -50,6 +50,9 @@ export default {
50 round: { 50 round: {
51 type: [Boolean, String, Number], 51 type: [Boolean, String, Number],
52 default: defprops.actionSheet.round 52 default: defprops.actionSheet.round
  53 + },
  54 + submitFunction: {
  55 + type:Function
53 } 56 }
54 } 57 }
55 } 58 }
garbage-removal/src/uview-plus/components/u-action-sheet/u-action-sheet.vue
1 1
2 <template> 2 <template>
3 - <u-popup  
4 - :show="show"  
5 - mode="bottom"  
6 - @close="closeHandler"  
7 - :safeAreaInsetBottom="safeAreaInsetBottom"  
8 - :round="round"  
9 - > 3 + <u-popup :show="show" mode="bottom" @close="closeHandler" :safeAreaInsetBottom="safeAreaInsetBottom" :round="round">
10 <view class="u-action-sheet"> 4 <view class="u-action-sheet">
11 - <view  
12 - class="u-action-sheet__header"  
13 - v-if="title"  
14 - >  
15 - <text class="u-action-sheet__header__title u-line-1">{{title}}</text>  
16 - <view  
17 - class="u-action-sheet__header__icon-wrap"  
18 - @tap.stop="cancel"  
19 - >  
20 - <u-icon  
21 - name="close"  
22 - size="17"  
23 - color="#c8c9cc"  
24 - bold  
25 - ></u-icon> 5 + <view class="u-action-sheet__header" v-if="title">
  6 + <text class="u-action-sheet__header__title u-line-1">{{ title }}</text>
  7 + <view class="u-action-sheet__header__icon-wrap" @click.stop="cancel">
  8 + <u-icon name="close" size="17" color="#c8c9cc" bold></u-icon>
26 </view> 9 </view>
27 </view> 10 </view>
28 - <text  
29 - class="u-action-sheet__description"  
30 - :style="[{  
31 - marginTop: `${title && description ? 0 : '18px'}`  
32 - }]"  
33 - v-if="description"  
34 - >{{description}}</text> 11 + <text class="u-action-sheet__description" :style="[{
  12 + marginTop: `${title && description ? 0 : '18px'}`
  13 + }]" v-if="description">{{ description }}</text>
35 <slot> 14 <slot>
36 <u-line v-if="description"></u-line> 15 <u-line v-if="description"></u-line>
37 <view class="u-action-sheet__item-wrap"> 16 <view class="u-action-sheet__item-wrap">
38 <view :key="index" v-for="(item, index) in actions"> 17 <view :key="index" v-for="(item, index) in actions">
39 <!-- #ifdef MP --> 18 <!-- #ifdef MP -->
40 - <button  
41 - class="u-reset-button"  
42 - :openType="item.openType"  
43 - @getuserinfo="onGetUserInfo"  
44 - @contact="onContact"  
45 - @getphonenumber="onGetPhoneNumber"  
46 - @error="onError"  
47 - @launchapp="onLaunchApp"  
48 - @opensetting="onOpenSetting"  
49 - :lang="lang"  
50 - :session-from="sessionFrom"  
51 - :send-message-title="sendMessageTitle"  
52 - :send-message-path="sendMessagePath"  
53 - :send-message-img="sendMessageImg"  
54 - :show-message-card="showMessageCard"  
55 - :app-parameter="appParameter"  
56 - @tap="selectHandler(index)"  
57 - :hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''"  
58 - > 19 + <button v-if="item.name != '提交' && item.name != '其他'" class="u-reset-button"
  20 + :class="currentSelect == index ? 'u-action-sheet--active' : ''" :openType="item.openType"
  21 + @getuserinfo="onGetUserInfo" @contact="onContact" @getphonenumber="onGetPhoneNumber" @error="onError"
  22 + @launchapp="onLaunchApp" @opensetting="onOpenSetting" :lang="lang" :session-from="sessionFrom"
  23 + :send-message-title="sendMessageTitle" :send-message-path="sendMessagePath"
  24 + :send-message-img="sendMessageImg" :show-message-card="showMessageCard" :app-parameter="appParameter"
  25 + @tap.stop="selectHandler(index)"
  26 + :hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''">
59 <!-- #endif --> 27 <!-- #endif -->
60 - <view  
61 - class="u-action-sheet__item-wrap__item"  
62 - @tap.stop="selectHandler(index)"  
63 - :hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''"  
64 - :hover-stay-time="150"  
65 - > 28 + <view v-if="item.name != '提交' && item.name != '其他'" class="u-action-sheet__item-wrap__item"
  29 + :class="currentSelect == index ? 'u-action-sheet--active' : ''" @tap.stop="selectHandler(index)"
  30 + :hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''" :hover-stay-time="150">
66 <template v-if="!item.loading"> 31 <template v-if="!item.loading">
67 - <text  
68 - class="u-action-sheet__item-wrap__item__name"  
69 - :style="[itemStyle(index)]"  
70 - >{{ item.name }}</text>  
71 - <text  
72 - v-if="item.subname"  
73 - class="u-action-sheet__item-wrap__item__subname"  
74 - >{{ item.subname }}</text> 32 + <text class="u-action-sheet__item-wrap__item__name" :style="[itemStyle(index)]">{{ item.name }}</text>
  33 + <text v-if="item.subname" class="u-action-sheet__item-wrap__item__subname">{{ item.subname }}</text>
75 </template> 34 </template>
76 - <u-loading-icon  
77 - v-else  
78 - custom-class="van-action-sheet__loading"  
79 - size="18"  
80 - mode="circle"  
81 - /> 35 + <u-loading-icon v-else custom-class="van-action-sheet__loading" size="18" mode="circle" />
82 </view> 36 </view>
83 <!-- #ifdef MP --> 37 <!-- #ifdef MP -->
84 </button> 38 </button>
85 <!-- #endif --> 39 <!-- #endif -->
  40 + <view v-if="item.name == '其他'" class="u-action-sheet__item-wrap__item" :hover-stay-time="150">
  41 + <view class="parent-box">
  42 + <u-collapse>
  43 + <u-collapse-item @selectHandler="selectHandler" :index="index" :name="item.name" ref="childRef"
  44 + title="其他" name="其他">
  45 + <view class="u-collapse-content" style="width: 97vw;text-align: left;">
  46 + <u--textarea v-model="otherReason" placeholder="请输入原因"></u--textarea>
  47 + </view>
  48 + </u-collapse-item>
  49 + </u-collapse>
  50 + </view>
  51 + </view>
  52 + <!-- #ifdef MP -->
  53 + <!-- <button v-if="item.name == '提交'" class="u-reset-button u-reset-button-btn" :openType="item.openType"
  54 + @getuserinfo="onGetUserInfo" @contact="onContact" @getphonenumber="onGetPhoneNumber" @error="onError"
  55 + @launchapp="onLaunchApp" @opensetting="onOpenSetting" :lang="lang" :session-from="sessionFrom"
  56 + :send-message-title="sendMessageTitle" :send-message-path="sendMessagePath"
  57 + :send-message-img="sendMessageImg" :show-message-card="showMessageCard" :app-parameter="appParameter"
  58 + @tap.stop="selectHandler(index,item.name)" :hover-class="!item.disabled && !item.loading ? 'u-action-sheet--hover' : ''"> -->
  59 + <!-- #endif -->
  60 + <view v-if="item.name == '提交'" class="u-action-sheet__item-wrap__item u-reset-button-btn"
  61 + @tap.stop="handleSubmitFunction(item.name)" :hover-stay-time="150">
  62 + <template v-if="!item.loading">
  63 + <text class="u-action-sheet__item-wrap__item__name" :style="[itemStyle(index)]">{{ item.name }}</text>
  64 + </template>
  65 + <u-loading-icon v-else custom-class="van-action-sheet__loading" size="18" mode="circle" />
  66 + </view>
  67 + <!-- #ifdef MP -->
  68 + <!-- </button> -->
  69 + <!-- #endif -->
86 <u-line v-if="index !== actions.length - 1"></u-line> 70 <u-line v-if="index !== actions.length - 1"></u-line>
87 </view> 71 </view>
88 </view> 72 </view>
89 </slot> 73 </slot>
90 - <u-gap  
91 - bgColor="#eaeaec"  
92 - height="6"  
93 - v-if="cancelText"  
94 - ></u-gap> 74 + <u-gap bgColor="#eaeaec" height="6" v-if="cancelText"></u-gap>
95 <view hover-class="u-action-sheet--hover"> 75 <view hover-class="u-action-sheet--hover">
96 - <text  
97 - @touchmove.stop.prevent  
98 - :hover-stay-time="150"  
99 - v-if="cancelText"  
100 - class="u-action-sheet__cancel-text"  
101 - @tap="cancel"  
102 - >{{cancelText}}</text> 76 + <text @touchmove.stop.prevent :hover-stay-time="150" v-if="cancelText" class="u-action-sheet__cancel-text"
  77 + @tap.stop="cancel">{{ cancelText }}</text>
103 </view> 78 </view>
104 </view> 79 </view>
105 </u-popup> 80 </u-popup>
106 </template> 81 </template>
107 82
108 <script> 83 <script>
109 - import openType from '../../libs/mixin/openType'  
110 - import button from '../../libs/mixin/button'  
111 - import props from './props.js';  
112 - import mpMixin from '../../libs/mixin/mpMixin.js';  
113 - import mixin from '../../libs/mixin/mixin.js';  
114 - /**  
115 - * ActionSheet 操作菜单  
116 - * @description 本组件用于从底部弹出一个操作菜单,供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheetAPI,配置更加灵活,所有平台都表现一致。  
117 - * @tutorial https://ijry.github.io/uview-plus/components/actionSheet.html  
118 - *  
119 - * @property {Boolean} show 操作菜单是否展示 (默认 false )  
120 - * @property {String} title 操作菜单标题  
121 - * @property {String} description 选项上方的描述信息  
122 - * @property {Array<Object>} actions 按钮的文字数组,见官方文档示例  
123 - * @property {String} cancelText 取消按钮的提示文字,不为空时显示按钮  
124 - * @property {Boolean} closeOnClickAction 点击某个菜单项时是否关闭弹窗 (默认 true )  
125 - * @property {Boolean} safeAreaInsetBottom 处理底部安全区 (默认 true )  
126 - * @property {String} openType 小程序的打开方式 (contact | launchApp | getUserInfo | openSetting |getPhoneNumber |error )  
127 - * @property {Boolean} closeOnClickOverlay 点击遮罩是否允许关闭 (默认 true )  
128 - * @property {Number|String} round 圆角值,默认无圆角 (默认 0 )  
129 - * @property {String} lang 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文  
130 - * @property {String} sessionFrom 会话来源,openType="contact"时有效  
131 - * @property {String} sendMessageTitle 会话内消息卡片标题,openType="contact"时有效  
132 - * @property {String} sendMessagePath 会话内消息卡片点击跳转小程序路径,openType="contact"时有效  
133 - * @property {String} sendMessageImg 会话内消息卡片图片,openType="contact"时有效  
134 - * @property {Boolean} showMessageCard 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,openType="contact"时有效 (默认 false )  
135 - * @property {String} appParameter 打开 APP 时,向 APP 传递的参数,openType=launchApp 时有效  
136 - *  
137 - * @event {Function} select 点击ActionSheet列表项时触发  
138 - * @event {Function} close 点击取消按钮时触发  
139 - * @event {Function} getuserinfo 用户点击该按钮时,会返回获取到的用户信息,回调的 detail 数据与 wx.getUserInfo 返回的一致,openType="getUserInfo"时有效  
140 - * @event {Function} contact 客服消息回调,openType="contact"时有效  
141 - * @event {Function} getphonenumber 获取用户手机号回调,openType="getPhoneNumber"时有效  
142 - * @event {Function} error 当使用开放能力时,发生错误的回调,openType="error"时有效  
143 - * @event {Function} launchapp 打开 APP 成功的回调,openType="launchApp"时有效  
144 - * @event {Function} opensetting 在打开授权设置页后回调,openType="openSetting"时有效  
145 - * @example <u-action-sheet :actions="list" :title="title" :show="show"></u-action-sheet>  
146 - */  
147 - export default {  
148 - name: "u-action-sheet",  
149 - // 一些props参数和methods方法,通过mixin混入,因为其他文件也会用到  
150 - mixins: [openType, button, mixin, props],  
151 - data() {  
152 - return {  
153 - 84 +import button from '../../libs/mixin/button';
  85 +import mixin from '../../libs/mixin/mixin.js';
  86 +import openType from '../../libs/mixin/openType';
  87 +import props from './props.js';
  88 +/**
  89 + * ActionSheet 操作菜单
  90 + * @description 本组件用于从底部弹出一个操作菜单,供用户选择并返回结果。本组件功能类似于uni的uni.showActionSheetAPI,配置更加灵活,所有平台都表现一致。
  91 + * @tutorial https://ijry.github.io/uview-plus/components/actionSheet.html
  92 + *
  93 + * @property {Boolean} show 操作菜单是否展示 (默认 false )
  94 + * @property {String} title 操作菜单标题
  95 + * @property {String} description 选项上方的描述信息
  96 + * @property {Array<Object>} actions 按钮的文字数组,见官方文档示例
  97 + * @property {String} cancelText 取消按钮的提示文字,不为空时显示按钮
  98 + * @property {Boolean} closeOnClickAction 点击某个菜单项时是否关闭弹窗 (默认 true )
  99 + * @property {Boolean} safeAreaInsetBottom 处理底部安全区 (默认 true )
  100 + * @property {String} openType 小程序的打开方式 (contact | launchApp | getUserInfo | openSetting |getPhoneNumber |error )
  101 + * @property {Boolean} closeOnClickOverlay 点击遮罩是否允许关闭 (默认 true )
  102 + * @property {Number|String} round 圆角值,默认无圆角 (默认 0 )
  103 + * @property {String} lang 指定返回用户信息的语言,zh_CN 简体中文,zh_TW 繁体中文,en 英文
  104 + * @property {String} sessionFrom 会话来源,openType="contact"时有效
  105 + * @property {String} sendMessageTitle 会话内消息卡片标题,openType="contact"时有效
  106 + * @property {String} sendMessagePath 会话内消息卡片点击跳转小程序路径,openType="contact"时有效
  107 + * @property {String} sendMessageImg 会话内消息卡片图片,openType="contact"时有效
  108 + * @property {Boolean} showMessageCard 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话会在右下角显示"可能要发送的小程序"提示,用户点击后可以快速发送小程序消息,openType="contact"时有效 (默认 false )
  109 + * @property {String} appParameter 打开 APP 时,向 APP 传递的参数,openType=launchApp 时有效
  110 + *
  111 + * @event {Function} select 点击ActionSheet列表项时触发
  112 + * @event {Function} close 点击取消按钮时触发
  113 + * @event {Function} getuserinfo 用户点击该按钮时,会返回获取到的用户信息,回调的 detail 数据与 wx.getUserInfo 返回的一致,openType="getUserInfo"时有效
  114 + * @event {Function} contact 客服消息回调,openType="contact"时有效
  115 + * @event {Function} getphonenumber 获取用户手机号回调,openType="getPhoneNumber"时有效
  116 + * @event {Function} error 当使用开放能力时,发生错误的回调,openType="error"时有效
  117 + * @event {Function} launchapp 打开 APP 成功的回调,openType="launchApp"时有效
  118 + * @event {Function} opensetting 在打开授权设置页后回调,openType="openSetting"时有效
  119 + * @example <u-action-sheet :actions="list" :title="title" :show="show"></u-action-sheet>
  120 + */
  121 +export default {
  122 + name: "u-action-sheet",
  123 + // 一些props参数和methods方法,通过mixin混入,因为其他文件也会用到
  124 + mixins: [openType, button, mixin, props],
  125 + data() {
  126 + return {
  127 + currentSelect: -1,
  128 + otherReason: "",
  129 + accordion: false
  130 + }
  131 + }, watch: {
  132 + show(newValue, oldValue) {
  133 + if (newValue === true) {
  134 + this.currentSelect = -1
  135 + this.otherReason = ""
  136 + this.accordion = false
  137 + }
  138 + }
  139 + },
  140 + computed: {
  141 + // 操作项目的样式
  142 + itemStyle() {
  143 + return (index) => {
  144 + let style = {};
  145 + if (this.actions[index].color) style.color = this.actions[index].color
  146 + if (this.actions[index].fontSize) style.fontSize = uni.$u.addUnit(this.actions[index].fontSize)
  147 + // 选项被禁用的样式
  148 + if (this.actions[index].disabled) style.color = '#c0c4cc'
  149 + return style;
154 } 150 }
155 }, 151 },
156 - computed: {  
157 - // 操作项目的样式  
158 - itemStyle() {  
159 - return (index) => {  
160 - let style = {};  
161 - if (this.actions[index].color) style.color = this.actions[index].color  
162 - if (this.actions[index].fontSize) style.fontSize = uni.$u.addUnit(this.actions[index].fontSize)  
163 - // 选项被禁用的样式  
164 - if (this.actions[index].disabled) style.color = '#c0c4cc'  
165 - return style;  
166 - }  
167 - }, 152 + },
  153 + methods: {
  154 + closeHandler() {
  155 + // 允许点击遮罩关闭时,才发出close事件
  156 + if (this.closeOnClickOverlay) {
  157 + this.$emit('actionSheetClose')
  158 + }
168 }, 159 },
169 - methods: {  
170 - closeHandler() {  
171 - // 允许点击遮罩关闭时,才发出close事件  
172 - if(this.closeOnClickOverlay) {  
173 - this.$emit('close') 160 + // 点击取消按钮
  161 + cancel() {
  162 + this.$emit('actionSheetClose')
  163 + },
  164 + selectHandler(index, name) {
  165 + if (name != "其他") {
  166 + if (this.accordion) {
  167 + this.$refs.childRef[0].clickHandler("抽屉");
  168 + this.accordion = false;
174 } 169 }
175 - },  
176 - // 点击取消按钮  
177 - cancel() {  
178 - this.$emit('close')  
179 - },  
180 - selectHandler(index) {  
181 - const item = this.actions[index]  
182 - if (item && !item.disabled && !item.loading) {  
183 - this.$emit('select', item)  
184 - if (this.closeOnClickAction) {  
185 - this.$emit('close')  
186 - } 170 + this.otherReason = ''
  171 + }
  172 + if (name == "其他") {
  173 + this.accordion = true;
  174 + }
  175 + this.currentSelect = index;
  176 + const item = this.actions[index]
  177 + if (item && !item.disabled && !item.loading) {
  178 + this.$emit('select', item)
  179 + if (this.closeOnClickAction) {
  180 + this.$emit('close')
187 } 181 }
188 - }, 182 + }
  183 + },
  184 + handleSubmitFunction(name) {
  185 + if (name == "提交") {
  186 + this.$emit('submitFunction', this.otherReason);
  187 + }
189 } 188 }
190 } 189 }
  190 +}
191 </script> 191 </script>
192 192
193 <style lang="scss" scoped> 193 <style lang="scss" scoped>
194 - @import "../../libs/css/components.scss";  
195 - $u-action-sheet-reset-button-width:100% !default;  
196 - $u-action-sheet-title-font-size: 16px !default;  
197 - $u-action-sheet-title-padding: 12px 30px !default;  
198 - $u-action-sheet-title-color: $u-main-color !default;  
199 - $u-action-sheet-header-icon-wrap-right:15px !default;  
200 - $u-action-sheet-header-icon-wrap-top:15px !default;  
201 - $u-action-sheet-description-font-size:13px !default;  
202 - $u-action-sheet-description-color:14px !default;  
203 - $u-action-sheet-description-margin: 18px 15px !default;  
204 - $u-action-sheet-item-wrap-item-padding:15px !default;  
205 - $u-action-sheet-item-wrap-name-font-size:16px !default;  
206 - $u-action-sheet-item-wrap-subname-font-size:13px !default;  
207 - $u-action-sheet-item-wrap-subname-color: #c0c4cc !default;  
208 - $u-action-sheet-item-wrap-subname-margin-top:10px !default;  
209 - $u-action-sheet-cancel-text-font-size:16px !default;  
210 - $u-action-sheet-cancel-text-color:$u-content-color !default;  
211 - $u-action-sheet-cancel-text-font-size:15px !default;  
212 - $u-action-sheet-cancel-text-hover-background-color:rgb(242, 243, 245) !default; 194 +@import "../../libs/css/components.scss";
  195 +$u-action-sheet-reset-button-width: 100% !default;
  196 +$u-action-sheet-title-font-size: 16px !default;
  197 +$u-action-sheet-title-padding: 12px 30px !default;
  198 +$u-action-sheet-title-color: $u-main-color !default;
  199 +$u-action-sheet-header-icon-wrap-right: 15px !default;
  200 +$u-action-sheet-header-icon-wrap-top: 15px !default;
  201 +$u-action-sheet-description-font-size: 13px !default;
  202 +$u-action-sheet-description-color: 14px !default;
  203 +$u-action-sheet-description-margin: 18px 15px !default;
  204 +$u-action-sheet-item-wrap-item-padding: 15px !default;
  205 +$u-action-sheet-item-wrap-name-font-size: 16px !default;
  206 +$u-action-sheet-item-wrap-subname-font-size: 13px !default;
  207 +$u-action-sheet-item-wrap-subname-color: #c0c4cc !default;
  208 +$u-action-sheet-item-wrap-subname-margin-top: 10px !default;
  209 +$u-action-sheet-cancel-text-font-size: 16px !default;
  210 +$u-action-sheet-cancel-text-color: $u-content-color !default;
  211 +$u-action-sheet-cancel-text-font-size: 15px !default;
  212 +$u-action-sheet-cancel-text-hover-background-color: rgb(242, 243, 245) !default;
213 213
214 - .u-reset-button {  
215 - width: $u-action-sheet-reset-button-width;  
216 - } 214 +.u-reset-button {
  215 + width: $u-action-sheet-reset-button-width;
  216 +}
217 217
218 - .u-action-sheet {  
219 - text-align: center;  
220 - &__header {  
221 - position: relative;  
222 - padding: $u-action-sheet-title-padding;  
223 - &__title {  
224 - font-size: $u-action-sheet-title-font-size;  
225 - color: $u-action-sheet-title-color;  
226 - font-weight: bold;  
227 - text-align: center;  
228 - } 218 +.u-reset-button-btn {
  219 + margin: 20rpx 0;
  220 + background-color: $u-success;
  221 + width: $u-action-sheet-reset-button-width;
  222 + box-sizing: border-box;
  223 +}
229 224
230 - &__icon-wrap {  
231 - position: absolute;  
232 - right: $u-action-sheet-header-icon-wrap-right;  
233 - top: $u-action-sheet-header-icon-wrap-top;  
234 - }  
235 - }  
236 225
237 - &__description {  
238 - font-size: $u-action-sheet-description-font-size;  
239 - color: $u-tips-color;  
240 - margin: $u-action-sheet-description-margin; 226 +.u-action-sheet {
  227 + text-align: center;
  228 +
  229 + &__header {
  230 + position: relative;
  231 + padding: $u-action-sheet-title-padding;
  232 +
  233 + &__title {
  234 + font-size: $u-action-sheet-title-font-size;
  235 + color: $u-action-sheet-title-color;
  236 + font-weight: bold;
241 text-align: center; 237 text-align: center;
242 } 238 }
243 239
244 - &__item-wrap { 240 + &__icon-wrap {
  241 + position: absolute;
  242 + right: $u-action-sheet-header-icon-wrap-right;
  243 + top: $u-action-sheet-header-icon-wrap-top;
  244 + }
  245 + }
  246 +
  247 + &__description {
  248 + font-size: $u-action-sheet-description-font-size;
  249 + color: $u-tips-color;
  250 + margin: $u-action-sheet-description-margin;
  251 + text-align: center;
  252 + }
245 253
246 - &__item {  
247 - padding: $u-action-sheet-item-wrap-item-padding;  
248 - @include flex;  
249 - align-items: center;  
250 - justify-content: center;  
251 - flex-direction: column; 254 + &__item-wrap {
252 255
253 - &__name {  
254 - font-size: $u-action-sheet-item-wrap-name-font-size;  
255 - color: $u-main-color;  
256 - text-align: center;  
257 - } 256 + &__item {
  257 + padding: $u-action-sheet-item-wrap-item-padding;
  258 + @include flex;
  259 + align-items: center;
  260 + justify-content: center;
  261 + flex-direction: column;
258 262
259 - &__subname {  
260 - font-size: $u-action-sheet-item-wrap-subname-font-size;  
261 - color: $u-action-sheet-item-wrap-subname-color;  
262 - margin-top: $u-action-sheet-item-wrap-subname-margin-top;  
263 - text-align: center;  
264 - } 263 + &__name {
  264 + font-size: $u-action-sheet-item-wrap-name-font-size;
  265 + color: $u-main-color;
  266 + text-align: center;
265 } 267 }
266 - }  
267 268
268 - &__cancel-text {  
269 - font-size: $u-action-sheet-cancel-text-font-size;  
270 - color: $u-action-sheet-cancel-text-color;  
271 - text-align: center;  
272 - padding: $u-action-sheet-cancel-text-font-size; 269 + &__subname {
  270 + font-size: $u-action-sheet-item-wrap-subname-font-size;
  271 + color: $u-action-sheet-item-wrap-subname-color;
  272 + margin-top: $u-action-sheet-item-wrap-subname-margin-top;
  273 + text-align: center;
  274 + }
273 } 275 }
  276 + }
274 277
275 - &--hover {  
276 - background-color: $u-action-sheet-cancel-text-hover-background-color;  
277 - } 278 + &__cancel-text {
  279 + font-size: $u-action-sheet-cancel-text-font-size;
  280 + color: $u-action-sheet-cancel-text-color;
  281 + text-align: center;
  282 + padding: $u-action-sheet-cancel-text-font-size;
  283 + }
  284 +
  285 + &--hover {
  286 + background-color: $u-success-light;
  287 + }
  288 +
  289 + &--active {
  290 + background-color: $u-success-light;
278 } 291 }
  292 +}
279 </style> 293 </style>
garbage-removal/src/uview-plus/components/u-checkbox-group/u-checkbox-group.vue
1 <template> 1 <template>
2 - <view  
3 - class="u-checkbox-group"  
4 - :class="bemClass"  
5 - > 2 + <view class="u-checkbox-group" :class="bemClass">
6 <slot></slot> 3 <slot></slot>
7 </view> 4 </view>
8 </template> 5 </template>
9 6
10 <script> 7 <script>
11 - import props from './props.js';  
12 - import mpMixin from '../../libs/mixin/mpMixin.js';  
13 - import mixin from '../../libs/mixin/mixin.js';  
14 - /**  
15 - * checkboxGroup 复选框组  
16 - * @description 复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便  
17 - * @tutorial https://ijry.github.io/uview-plus/components/checkbox.html  
18 - * @property {String} name 标识符  
19 - * @property {Array} value 绑定的值  
20 - * @property {String} shape 形状,circle-圆形,square-方形 (默认 'square' )  
21 - * @property {Boolean} disabled 是否禁用全部checkbox (默认 false )  
22 - * @property {String} activeColor 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值 (默认 '#2979ff' )  
23 - * @property {String} inactiveColor 未选中的颜色 (默认 '#c8c9cc' )  
24 - * @property {String | Number} size 整个组件的尺寸 单位px (默认 18 )  
25 - * @property {String} placement 布局方式,row-横向,column-纵向 (默认 'row' )  
26 - * @property {String | Number} labelSize label的字体大小,px单位 (默认 14 )  
27 - * @property {String} labelColor label的字体颜色 (默认 '#303133' )  
28 - * @property {Boolean} labelDisabled 是否禁止点击文本操作 (默认 false )  
29 - * @property {String} iconColor 图标颜色 (默认 '#ffffff' )  
30 - * @property {String | Number} iconSize 图标的大小,单位px (默认 12 )  
31 - * @property {String} iconPlacement 勾选图标的对齐方式,left-左边,right-右边 (默认 'left' )  
32 - * @property {Boolean} borderBottom placement为row时,是否显示下边框 (默认 false )  
33 - * @event {Function} change 任一个checkbox状态发生变化时触发,回调为一个对象  
34 - * @event {Function} input 修改通过v-model绑定的值时触发,回调为一个对象  
35 - * @example <u-checkbox-group></u-checkbox-group>  
36 - */  
37 - export default {  
38 - name: 'u-checkbox-group',  
39 - mixins: [mpMixin, mixin,props],  
40 - computed: {  
41 - // 这里computed的变量,都是子组件u-checkbox需要用到的,由于头条小程序的兼容性差异,子组件无法实时监听父组件参数的变化  
42 - // 所以需要手动通知子组件,这里返回一个parentData变量,供watch监听,在其中去通知每一个子组件重新从父组件(u-checkbox-group)  
43 - // 拉取父组件新的变化后的参数  
44 - parentData() {  
45 - return [ 8 +import mixin from '../../libs/mixin/mixin.js';
  9 +import mpMixin from '../../libs/mixin/mpMixin.js';
  10 +import props from './props.js';
  11 +/**
  12 + * checkboxGroup 复选框组
  13 + * @description 复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便
  14 + * @tutorial https://ijry.github.io/uview-plus/components/checkbox.html
  15 + * @property {String} name 标识符
  16 + * @property {Array} value 绑定的值
  17 + * @property {String} shape 形状,circle-圆形,square-方形 (默认 'square' )
  18 + * @property {Boolean} disabled 是否禁用全部checkbox (默认 false )
  19 + * @property {String} activeColor 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值 (默认 '#2979ff' )
  20 + * @property {String} inactiveColor 未选中的颜色 (默认 '#c8c9cc' )
  21 + * @property {String | Number} size 整个组件的尺寸 单位px (默认 18 )
  22 + * @property {String} placement 布局方式,row-横向,column-纵向 (默认 'row' )
  23 + * @property {String | Number} labelSize label的字体大小,px单位 (默认 14 )
  24 + * @property {String} labelColor label的字体颜色 (默认 '#303133' )
  25 + * @property {Boolean} labelDisabled 是否禁止点击文本操作 (默认 false )
  26 + * @property {String} iconColor 图标颜色 (默认 '#ffffff' )
  27 + * @property {String | Number} iconSize 图标的大小,单位px (默认 12 )
  28 + * @property {String} iconPlacement 勾选图标的对齐方式,left-左边,right-右边 (默认 'left' )
  29 + * @property {Boolean} borderBottom placement为row时,是否显示下边框 (默认 false )
  30 + * @event {Function} change 任一个checkbox状态发生变化时触发,回调为一个对象
  31 + * @event {Function} input 修改通过v-model绑定的值时触发,回调为一个对象
  32 + * @example <u-checkbox-group></u-checkbox-group>
  33 + */
  34 +export default {
  35 + name: 'u-checkbox-group',
  36 + mixins: [mpMixin, mixin, props],
  37 + computed: {
  38 + // 这里computed的变量,都是子组件u-checkbox需要用到的,由于头条小程序的兼容性差异,子组件无法实时监听父组件参数的变化
  39 + // 所以需要手动通知子组件,这里返回一个parentData变量,供watch监听,在其中去通知每一个子组件重新从父组件(u-checkbox-group)
  40 + // 拉取父组件新的变化后的参数
  41 + parentData() {
  42 + return [
46 // #ifdef VUE2 43 // #ifdef VUE2
47 this.value, 44 this.value,
48 // #endif 45 // #endif
@@ -58,76 +55,76 @@ @@ -58,76 +55,76 @@
58 this.iconSize, 55 this.iconSize,
59 this.borderBottom, 56 this.borderBottom,
60 this.placement, 57 this.placement,
61 - ];  
62 - },  
63 - bemClass() {  
64 - // this.bem为一个computed变量,在mixin中  
65 - return this.bem('checkbox-group', ['placement'])  
66 - }, 58 + ];
67 }, 59 },
68 - watch: {  
69 - // 当父组件需要子组件需要共享的参数发生了变化,手动通知子组件  
70 - parentData: {  
71 - handler() { 60 + bemClass() {
  61 + // this.bem为一个computed变量,在mixin中
  62 + return this.bem('checkbox-group', ['placement'])
  63 + },
  64 + },
  65 + watch: {
  66 + // 当父组件需要子组件需要共享的参数发生了变化,手动通知子组件
  67 + parentData: {
  68 + handler() {
72 if (this.children.length) { 69 if (this.children.length) {
73 - this.children.map((child) => {  
74 - // 判断子组件(u-checkbox)如果有init方法的话,就就执行(执行的结果是子组件重新从父组件拉取了最新的值)  
75 - typeof child.init === "function" && child.init();  
76 - }); 70 + this.children.map((child) => {
  71 + // 判断子组件(u-checkbox)如果有init方法的话,就就执行(执行的结果是子组件重新从父组件拉取了最新的值)
  72 + typeof child.init === "function" && child.init();
  73 + });
77 } 74 }
78 - },  
79 - deep: true,  
80 }, 75 },
  76 + deep: true,
81 }, 77 },
82 - data() {  
83 - return { 78 + },
  79 + data() {
  80 + return {
84 81
85 - }  
86 - },  
87 - created() {  
88 - this.children = []  
89 - },  
90 - // #ifdef VUE3  
91 - emits: ['update:modelValue', 'change'],  
92 - // #endif  
93 - methods: {  
94 - // 将其他的checkbox设置为未选中的状态  
95 - unCheckedOther(childInstance) {  
96 - const values = []  
97 - this.children.map(child => {  
98 - // 将被选中的checkbox,放到数组中返回  
99 - if (child.isChecked) {  
100 - values.push(child.name)  
101 - }  
102 - })  
103 - // 发出事件  
104 - this.$emit('change', values)  
105 - // 修改通过v-model绑定的值  
106 - // #ifdef VUE3  
107 - this.$emit("update:modelValue", values);  
108 - // #endif  
109 - // #ifdef VUE2  
110 - this.$emit("input", values);  
111 - // #endif  
112 - },  
113 } 82 }
  83 + },
  84 + created() {
  85 + this.children = []
  86 + },
  87 + // #ifdef VUE3
  88 + emits: ['update:modelValue', 'change'],
  89 + // #endif
  90 + methods: {
  91 + // 将其他的checkbox设置为未选中的状态
  92 + unCheckedOther(childInstance) {
  93 + const values = []
  94 + this.children.map(child => {
  95 + // 将被选中的checkbox,放到数组中返回
  96 + if (child.isChecked) {
  97 + values.push(child.name)
  98 + }
  99 + })
  100 + // 发出事件
  101 + this.$emit('change', values)
  102 + // 修改通过v-model绑定的值
  103 + // #ifdef VUE3
  104 + this.$emit("update:modelValue", values);
  105 + // #endif
  106 + // #ifdef VUE2
  107 + this.$emit("input", values);
  108 + // #endif
  109 + },
114 } 110 }
  111 +}
115 </script> 112 </script>
116 113
117 <style lang="scss" scoped> 114 <style lang="scss" scoped>
118 - @import "../../libs/css/components.scss"; 115 +@import "../../libs/css/components.scss";
119 116
120 - .u-checkbox-group { 117 +.u-checkbox-group {
121 118
122 - &--row {  
123 - /* #ifndef APP-NVUE */  
124 - display: flex;  
125 - /* #endif */  
126 - flex-flow: row wrap;  
127 - } 119 + &--row {
  120 + /* #ifndef APP-NVUE */
  121 + display: flex;
  122 + /* #endif */
  123 + // flex-flow: row wrap;
  124 + }
128 125
129 - &--column {  
130 - @include flex(column);  
131 - } 126 + &--column {
  127 + @include flex(column);
132 } 128 }
  129 +}
133 </style> 130 </style>
garbage-removal/src/uview-plus/components/u-checkbox/u-checkbox.vue
1 <template> 1 <template>
2 - <view  
3 - class="u-checkbox"  
4 - :style="[checkboxStyle]"  
5 - @tap.stop="wrapperClickHandler"  
6 - :class="[`u-checkbox-label--${parentData.iconPlacement}`, parentData.borderBottom && parentData.placement === 'column' && 'u-border-bottom']"  
7 - >  
8 - <view  
9 - class="u-checkbox__icon-wrap"  
10 - @tap.stop="iconClickHandler"  
11 - :class="iconClasses"  
12 - :style="[iconWrapStyle]"  
13 - > 2 + <view class="u-checkbox" :style="[checkboxStyle]" @tap.stop="wrapperClickHandler"
  3 + :class="[`u-checkbox-label--${parentData.iconPlacement}`, parentData.borderBottom && parentData.placement === 'column' && 'u-border-bottom']">
  4 + <view class="u-checkbox__icon-wrap" @tap.stop="iconClickHandler" :class="iconClasses" :style="[iconWrapStyle]">
14 <slot name="icon"> 5 <slot name="icon">
15 - <u-icon  
16 - class="u-checkbox__icon-wrap__icon"  
17 - name="checkbox-mark"  
18 - :size="elIconSize"  
19 - :color="elIconColor"  
20 - /> 6 + <u-icon class="u-checkbox__icon-wrap__icon" name="checkbox-mark" :size="elIconSize" :color="elIconColor" />
21 </slot> 7 </slot>
22 </view> 8 </view>
23 - <text  
24 - @tap.stop="labelClickHandler"  
25 - :style="{  
26 - color: elDisabled ? elInactiveColor : elLabelColor,  
27 - fontSize: elLabelSize,  
28 - lineHeight: elLabelSize  
29 - }"  
30 - >{{label}}</text> 9 + <text @tap.stop="labelClickHandler" :style="{
  10 + color: elDisabled ? elInactiveColor : elLabelColor,
  11 + fontSize: elLabelSize,
  12 + lineHeight: elLabelSize
  13 + }" style="flex-wrap: wrap;">{{ label }}</text>
31 </view> 14 </view>
32 </template> 15 </template>
33 16
34 <script> 17 <script>
35 - import props from './props.js';  
36 - import mpMixin from '../../libs/mixin/mpMixin.js';  
37 - import mixin from '../../libs/mixin/mixin.js';  
38 - /**  
39 - * checkbox 复选框  
40 - * @description 复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便  
41 - * @tutorial https://uviewui.com/components/checkbox.html  
42 - * @property {String | Number | Boolean} name checkbox组件的标示符  
43 - * @property {String} shape 形状,square为方形,circle为圆型  
44 - * @property {String | Number} size 整体的大小  
45 - * @property {Boolean} checked 是否默认选中  
46 - * @property {String | Boolean} disabled 是否禁用  
47 - * @property {String} activeColor 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值  
48 - * @property {String} inactiveColor 未选中的颜色  
49 - * @property {String | Number} iconSize 图标的大小,单位px  
50 - * @property {String} iconColor 图标颜色  
51 - * @property {String | Number} label label提示文字,因为nvue下,直接slot进来的文字,由于特殊的结构,无法修改样式  
52 - * @property {String} labelColor label的颜色  
53 - * @property {String | Number} labelSize label的字体大小,px单位  
54 - * @property {String | Boolean} labelDisabled 是否禁止点击提示语选中复选框  
55 - * @property {Object} customStyle 定义需要用到的外部样式  
56 - *  
57 - * @event {Function} change 任一个checkbox状态发生变化时触发,回调为一个对象  
58 - * @example <u-checkbox v-model="checked" :disabled="false">天涯</u-checkbox>  
59 - */  
60 - export default {  
61 - name: "u-checkbox",  
62 - mixins: [mpMixin, mixin, props],  
63 - data() {  
64 - return {  
65 - isChecked: false,  
66 - // 父组件的默认值,因为头条小程序不支持在computed中使用this.parent.shape的形式  
67 - // 故只能使用如此方法  
68 - parentData: {  
69 - iconSize: 12,  
70 - labelDisabled: null,  
71 - disabled: null,  
72 - shape: 'square',  
73 - activeColor: null,  
74 - inactiveColor: null,  
75 - size: 18,  
76 - // #ifdef VUE2  
77 - value: null,  
78 - // #endif  
79 - // #ifdef VUE3  
80 - modelValue: null,  
81 - // #endif  
82 - iconColor: null,  
83 - placement: 'row',  
84 - borderBottom: false,  
85 - iconPlacement: 'left'  
86 - } 18 +import mixin from '../../libs/mixin/mixin.js';
  19 +import mpMixin from '../../libs/mixin/mpMixin.js';
  20 +import props from './props.js';
  21 +/**
  22 + * checkbox 复选框
  23 + * @description 复选框组件一般用于需要多个选择的场景,该组件功能完整,使用方便
  24 + * @tutorial https://uviewui.com/components/checkbox.html
  25 + * @property {String | Number | Boolean} name checkbox组件的标示符
  26 + * @property {String} shape 形状,square为方形,circle为圆型
  27 + * @property {String | Number} size 整体的大小
  28 + * @property {Boolean} checked 是否默认选中
  29 + * @property {String | Boolean} disabled 是否禁用
  30 + * @property {String} activeColor 选中状态下的颜色,如设置此值,将会覆盖parent的activeColor值
  31 + * @property {String} inactiveColor 未选中的颜色
  32 + * @property {String | Number} iconSize 图标的大小,单位px
  33 + * @property {String} iconColor 图标颜色
  34 + * @property {String | Number} label label提示文字,因为nvue下,直接slot进来的文字,由于特殊的结构,无法修改样式
  35 + * @property {String} labelColor label的颜色
  36 + * @property {String | Number} labelSize label的字体大小,px单位
  37 + * @property {String | Boolean} labelDisabled 是否禁止点击提示语选中复选框
  38 + * @property {Object} customStyle 定义需要用到的外部样式
  39 + *
  40 + * @event {Function} change 任一个checkbox状态发生变化时触发,回调为一个对象
  41 + * @example <u-checkbox v-model="checked" :disabled="false">天涯</u-checkbox>
  42 + */
  43 +export default {
  44 + name: "u-checkbox",
  45 + mixins: [mpMixin, mixin, props],
  46 + data() {
  47 + return {
  48 + isChecked: false,
  49 + // 父组件的默认值,因为头条小程序不支持在computed中使用this.parent.shape的形式
  50 + // 故只能使用如此方法
  51 + parentData: {
  52 + iconSize: 12,
  53 + labelDisabled: null,
  54 + disabled: null,
  55 + shape: 'square',
  56 + activeColor: null,
  57 + inactiveColor: null,
  58 + size: 18,
  59 + // #ifdef VUE2
  60 + value: null,
  61 + // #endif
  62 + // #ifdef VUE3
  63 + modelValue: null,
  64 + // #endif
  65 + iconColor: null,
  66 + placement: 'row',
  67 + borderBottom: false,
  68 + iconPlacement: 'left'
  69 + }
  70 + }
  71 + },
  72 + computed: {
  73 + // 是否禁用,如果父组件u-raios-group禁用的话,将会忽略子组件的配置
  74 + elDisabled() {
  75 + return this.disabled !== '' ? this.disabled : this.parentData.disabled !== null ? this.parentData.disabled : false;
  76 + },
  77 + // 是否禁用label点击
  78 + elLabelDisabled() {
  79 + return this.labelDisabled !== '' ? this.labelDisabled : this.parentData.labelDisabled !== null ? this.parentData.labelDisabled :
  80 + false;
  81 + },
  82 + // 组件尺寸,对应size的值,默认值为21px
  83 + elSize() {
  84 + return this.size ? this.size : (this.parentData.size ? this.parentData.size : 21);
  85 + },
  86 + // 组件的勾选图标的尺寸,默认12px
  87 + elIconSize() {
  88 + return this.iconSize ? this.iconSize : (this.parentData.iconSize ? this.parentData.iconSize : 12);
  89 + },
  90 + // 组件选中激活时的颜色
  91 + elActiveColor() {
  92 + return this.activeColor ? this.activeColor : (this.parentData.activeColor ? this.parentData.activeColor : '#2979ff');
  93 + },
  94 + // 组件选未中激活时的颜色
  95 + elInactiveColor() {
  96 + return this.inactiveColor ? this.inactiveColor : (this.parentData.inactiveColor ? this.parentData.inactiveColor :
  97 + '#c8c9cc');
  98 + },
  99 + // label的颜色
  100 + elLabelColor() {
  101 + return this.labelColor ? this.labelColor : (this.parentData.labelColor ? this.parentData.labelColor : '#606266')
  102 + },
  103 + // 组件的形状
  104 + elShape() {
  105 + return this.shape ? this.shape : (this.parentData.shape ? this.parentData.shape : 'circle');
  106 + },
  107 + // label大小
  108 + elLabelSize() {
  109 + return uni.$u.addUnit(this.labelSize ? this.labelSize : (this.parentData.labelSize ? this.parentData.labelSize :
  110 + '15'))
  111 + },
  112 + elIconColor() {
  113 + const iconColor = this.iconColor ? this.iconColor : (this.parentData.iconColor ? this.parentData.iconColor :
  114 + '#ffffff');
  115 + // 图标的颜色
  116 + if (this.elDisabled) {
  117 + // disabled状态下,已勾选的checkbox图标改为elInactiveColor
  118 + return this.isChecked ? this.elInactiveColor : 'transparent'
  119 + } else {
  120 + return this.isChecked ? iconColor : 'transparent'
87 } 121 }
88 }, 122 },
89 - computed: {  
90 - // 是否禁用,如果父组件u-raios-group禁用的话,将会忽略子组件的配置  
91 - elDisabled() {  
92 - return this.disabled !== '' ? this.disabled : this.parentData.disabled !== null ? this.parentData.disabled : false;  
93 - },  
94 - // 是否禁用label点击  
95 - elLabelDisabled() {  
96 - return this.labelDisabled !== '' ? this.labelDisabled : this.parentData.labelDisabled !== null ? this.parentData.labelDisabled :  
97 - false;  
98 - },  
99 - // 组件尺寸,对应size的值,默认值为21px  
100 - elSize() {  
101 - return this.size ? this.size : (this.parentData.size ? this.parentData.size : 21);  
102 - },  
103 - // 组件的勾选图标的尺寸,默认12px  
104 - elIconSize() {  
105 - return this.iconSize ? this.iconSize : (this.parentData.iconSize ? this.parentData.iconSize : 12);  
106 - },  
107 - // 组件选中激活时的颜色  
108 - elActiveColor() {  
109 - return this.activeColor ? this.activeColor : (this.parentData.activeColor ? this.parentData.activeColor : '#2979ff');  
110 - },  
111 - // 组件选未中激活时的颜色  
112 - elInactiveColor() {  
113 - return this.inactiveColor ? this.inactiveColor : (this.parentData.inactiveColor ? this.parentData.inactiveColor :  
114 - '#c8c9cc');  
115 - },  
116 - // label的颜色  
117 - elLabelColor() {  
118 - return this.labelColor ? this.labelColor : (this.parentData.labelColor ? this.parentData.labelColor : '#606266')  
119 - }, 123 + iconClasses() {
  124 + let classes = []
120 // 组件的形状 125 // 组件的形状
121 - elShape() {  
122 - return this.shape ? this.shape : (this.parentData.shape ? this.parentData.shape : 'circle');  
123 - },  
124 - // label大小  
125 - elLabelSize() {  
126 - return uni.$u.addUnit(this.labelSize ? this.labelSize : (this.parentData.labelSize ? this.parentData.labelSize :  
127 - '15'))  
128 - },  
129 - elIconColor() {  
130 - const iconColor = this.iconColor ? this.iconColor : (this.parentData.iconColor ? this.parentData.iconColor :  
131 - '#ffffff');  
132 - // 图标的颜色  
133 - if (this.elDisabled) {  
134 - // disabled状态下,已勾选的checkbox图标改为elInactiveColor  
135 - return this.isChecked ? this.elInactiveColor : 'transparent'  
136 - } else {  
137 - return this.isChecked ? iconColor : 'transparent'  
138 - }  
139 - },  
140 - iconClasses() {  
141 - let classes = []  
142 - // 组件的形状  
143 - classes.push('u-checkbox__icon-wrap--' + this.elShape)  
144 - if (this.elDisabled) {  
145 - classes.push('u-checkbox__icon-wrap--disabled')  
146 - }  
147 - if (this.isChecked && this.elDisabled) {  
148 - classes.push('u-checkbox__icon-wrap--disabled--checked')  
149 - }  
150 - // 支付宝,头条小程序无法动态绑定一个数组类名,否则解析出来的结果会带有",",而导致失效  
151 - // #ifdef MP-ALIPAY || MP-TOUTIAO  
152 - classes = classes.join(' ')  
153 - // #endif  
154 - return classes  
155 - },  
156 - iconWrapStyle() {  
157 - // checkbox的整体样式  
158 - const style = {}  
159 - style.backgroundColor = this.isChecked && !this.elDisabled ? this.elActiveColor : '#ffffff'  
160 - style.borderColor = this.isChecked && !this.elDisabled ? this.elActiveColor : this.elInactiveColor  
161 - style.width = uni.$u.addUnit(this.elSize)  
162 - style.height = uni.$u.addUnit(this.elSize)  
163 - // 如果是图标在右边的话,移除它的右边距  
164 - if (this.parentData.iconPlacement === 'right') {  
165 - style.marginRight = 0  
166 - }  
167 - return style  
168 - },  
169 - checkboxStyle() {  
170 - const style = {}  
171 - if (this.parentData.borderBottom && this.parentData.placement === 'row') {  
172 - uni.$u.error('检测到您将borderBottom设置为true,需要同时将u-checkbox-group的placement设置为column才有效')  
173 - }  
174 - // 当父组件设置了显示下边框并且排列形式为纵向时,给内容和边框之间加上一定间隔  
175 - if (this.parentData.borderBottom && this.parentData.placement === 'column') {  
176 - style.paddingBottom = '8px'  
177 - }  
178 - return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle)) 126 + classes.push('u-checkbox__icon-wrap--' + this.elShape)
  127 + if (this.elDisabled) {
  128 + classes.push('u-checkbox__icon-wrap--disabled')
  129 + }
  130 + if (this.isChecked && this.elDisabled) {
  131 + classes.push('u-checkbox__icon-wrap--disabled--checked')
179 } 132 }
  133 + // 支付宝,头条小程序无法动态绑定一个数组类名,否则解析出来的结果会带有",",而导致失效
  134 + // #ifdef MP-ALIPAY || MP-TOUTIAO
  135 + classes = classes.join(' ')
  136 + // #endif
  137 + return classes
180 }, 138 },
181 - mounted() {  
182 - this.init() 139 + iconWrapStyle() {
  140 + // checkbox的整体样式
  141 + const style = {}
  142 + style.backgroundColor = this.isChecked && !this.elDisabled ? this.elActiveColor : '#ffffff'
  143 + style.borderColor = this.isChecked && !this.elDisabled ? this.elActiveColor : this.elInactiveColor
  144 + style.width = uni.$u.addUnit(this.elSize)
  145 + style.height = uni.$u.addUnit(this.elSize)
  146 + // 如果是图标在右边的话,移除它的右边距
  147 + if (this.parentData.iconPlacement === 'right') {
  148 + style.marginRight = 0
  149 + }
  150 + return style
183 }, 151 },
184 - methods: {  
185 - init() {  
186 - // 支付宝小程序不支持provide/inject,所以使用这个方法获取整个父组件,在created定义,避免循环引用  
187 - this.updateParentData()  
188 - if (!this.parent) {  
189 - uni.$u.error('u-checkbox必须搭配u-checkbox-group组件使用')  
190 - }  
191 - // #ifdef VUE2  
192 - const value = this.parentData.value  
193 - // #endif  
194 - // #ifdef VUE3  
195 - const value = this.parentData.modelValue  
196 - // #endif  
197 - // 设置初始化时,是否默认选中的状态,父组件u-checkbox-group的value可能是array,所以额外判断  
198 - if (this.checked) {  
199 - this.isChecked = true  
200 - } else if (uni.$u.test.array(value)) {  
201 - // 查找数组是是否存在this.name元素值  
202 - this.isChecked = value.some(item => {  
203 - return item === this.name  
204 - })  
205 - }  
206 - },  
207 - updateParentData() {  
208 - this.getParentData('u-checkbox-group')  
209 - },  
210 - // 横向两端排列时,点击组件即可触发选中事件  
211 - wrapperClickHandler(e) {  
212 - this.parentData.iconPlacement === 'right' && this.iconClickHandler(e)  
213 - },  
214 - // 点击图标  
215 - iconClickHandler(e) {  
216 - this.preventEvent(e)  
217 - // 如果整体被禁用,不允许被点击  
218 - if (!this.elDisabled) {  
219 - this.setRadioCheckedStatus()  
220 - }  
221 - },  
222 - // 点击label  
223 - labelClickHandler(e) {  
224 - this.preventEvent(e)  
225 - // 如果按钮整体被禁用或者label被禁用,则不允许点击文字修改状态  
226 - if (!this.elLabelDisabled && !this.elDisabled) {  
227 - this.setRadioCheckedStatus()  
228 - }  
229 - },  
230 - emitEvent() {  
231 - this.$emit('change', this.isChecked)  
232 - // 尝试调用u-form的验证方法,进行一定延迟,否则微信小程序更新可能会不及时  
233 - this.$nextTick(() => {  
234 - uni.$u.formValidate(this, 'change') 152 + checkboxStyle() {
  153 + const style = {}
  154 + if (this.parentData.borderBottom && this.parentData.placement === 'row') {
  155 + uni.$u.error('检测到您将borderBottom设置为true,需要同时将u-checkbox-group的placement设置为column才有效')
  156 + }
  157 + // 当父组件设置了显示下边框并且排列形式为纵向时,给内容和边框之间加上一定间隔
  158 + if (this.parentData.borderBottom && this.parentData.placement === 'column') {
  159 + style.paddingBottom = '8px'
  160 + }
  161 + return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
  162 + }
  163 + },
  164 + mounted() {
  165 + this.init()
  166 + },
  167 + methods: {
  168 + init() {
  169 + // 支付宝小程序不支持provide/inject,所以使用这个方法获取整个父组件,在created定义,避免循环引用
  170 + this.updateParentData()
  171 + if (!this.parent) {
  172 + uni.$u.error('u-checkbox必须搭配u-checkbox-group组件使用')
  173 + }
  174 + // #ifdef VUE2
  175 + const value = this.parentData.value
  176 + // #endif
  177 + // #ifdef VUE3
  178 + const value = this.parentData.modelValue
  179 + // #endif
  180 + // 设置初始化时,是否默认选中的状态,父组件u-checkbox-group的value可能是array,所以额外判断
  181 + if (this.checked) {
  182 + this.isChecked = true
  183 + } else if (uni.$u.test.array(value)) {
  184 + // 查找数组是是否存在this.name元素值
  185 + this.isChecked = value.some(item => {
  186 + return item === this.name
235 }) 187 })
236 - },  
237 - // 改变组件选中状态  
238 - // 这里的改变的依据是,更改本组件的checked值为true,同时通过父组件遍历所有u-checkbox实例  
239 - // 将本组件外的其他u-checkbox的checked都设置为false(都被取消选中状态),因而只剩下一个为选中状态  
240 - setRadioCheckedStatus() {  
241 - // 将本组件标记为与原来相反的状态  
242 - this.isChecked = !this.isChecked  
243 - this.emitEvent()  
244 - typeof this.parent.unCheckedOther === 'function' && this.parent.unCheckedOther(this)  
245 } 188 }
246 }, 189 },
247 - watch:{  
248 - checked(){  
249 - this.isChecked = this.checked 190 + updateParentData() {
  191 + this.getParentData('u-checkbox-group')
  192 + },
  193 + // 横向两端排列时,点击组件即可触发选中事件
  194 + wrapperClickHandler(e) {
  195 + this.parentData.iconPlacement === 'right' && this.iconClickHandler(e)
  196 + },
  197 + // 点击图标
  198 + iconClickHandler(e) {
  199 + this.preventEvent(e)
  200 + // 如果整体被禁用,不允许被点击
  201 + if (!this.elDisabled) {
  202 + this.setRadioCheckedStatus()
  203 + }
  204 + },
  205 + // 点击label
  206 + labelClickHandler(e) {
  207 + this.preventEvent(e)
  208 + // 如果按钮整体被禁用或者label被禁用,则不允许点击文字修改状态
  209 + if (!this.elLabelDisabled && !this.elDisabled) {
  210 + this.setRadioCheckedStatus()
250 } 211 }
  212 + },
  213 + emitEvent() {
  214 + this.$emit('change', this.isChecked)
  215 + // 尝试调用u-form的验证方法,进行一定延迟,否则微信小程序更新可能会不及时
  216 + this.$nextTick(() => {
  217 + uni.$u.formValidate(this, 'change')
  218 + })
  219 + },
  220 + // 改变组件选中状态
  221 + // 这里的改变的依据是,更改本组件的checked值为true,同时通过父组件遍历所有u-checkbox实例
  222 + // 将本组件外的其他u-checkbox的checked都设置为false(都被取消选中状态),因而只剩下一个为选中状态
  223 + setRadioCheckedStatus() {
  224 + // 将本组件标记为与原来相反的状态
  225 + this.isChecked = !this.isChecked
  226 + this.emitEvent()
  227 + typeof this.parent.unCheckedOther === 'function' && this.parent.unCheckedOther(this)
  228 + }
  229 + },
  230 + watch: {
  231 + checked() {
  232 + this.isChecked = this.checked
251 } 233 }
252 } 234 }
  235 +}
253 </script> 236 </script>
254 237
255 <style lang="scss" scoped> 238 <style lang="scss" scoped>
256 - @import "../../libs/css/components.scss";  
257 - $u-checkbox-icon-wrap-margin-right:6px !default;  
258 - $u-checkbox-icon-wrap-font-size:6px !default;  
259 - $u-checkbox-icon-wrap-border-width:1px !default;  
260 - $u-checkbox-icon-wrap-border-color:#c8c9cc !default;  
261 - $u-checkbox-icon-wrap-icon-line-height:0 !default;  
262 - $u-checkbox-icon-wrap-circle-border-radius:100% !default;  
263 - $u-checkbox-icon-wrap-square-border-radius:3px !default;  
264 - $u-checkbox-icon-wrap-checked-color:#fff !default;  
265 - $u-checkbox-icon-wrap-checked-background-color:red !default;  
266 - $u-checkbox-icon-wrap-checked-border-color:#2979ff !default;  
267 - $u-checkbox-icon-wrap-disabled-background-color:#ebedf0 !default;  
268 - $u-checkbox-icon-wrap-disabled-checked-color:#c8c9cc !default;  
269 - $u-checkbox-label-margin-left:5px !default;  
270 - $u-checkbox-label-margin-right:12px !default;  
271 - $u-checkbox-label-color:$u-content-color !default;  
272 - $u-checkbox-label-font-size:15px !default;  
273 - $u-checkbox-label-disabled-color:#c8c9cc !default; 239 +@import "../../libs/css/components.scss";
  240 +$u-checkbox-icon-wrap-margin-right: 6px !default;
  241 +$u-checkbox-icon-wrap-font-size: 6px !default;
  242 +$u-checkbox-icon-wrap-border-width: 1px !default;
  243 +$u-checkbox-icon-wrap-border-color: #c8c9cc !default;
  244 +$u-checkbox-icon-wrap-icon-line-height: 0 !default;
  245 +$u-checkbox-icon-wrap-circle-border-radius: 100% !default;
  246 +$u-checkbox-icon-wrap-square-border-radius: 3px !default;
  247 +$u-checkbox-icon-wrap-checked-color: #fff !default;
  248 +$u-checkbox-icon-wrap-checked-background-color: red !default;
  249 +$u-checkbox-icon-wrap-checked-border-color: #2979ff !default;
  250 +$u-checkbox-icon-wrap-disabled-background-color: #ebedf0 !default;
  251 +$u-checkbox-icon-wrap-disabled-checked-color: #c8c9cc !default;
  252 +$u-checkbox-label-margin-left: 5px !default;
  253 +$u-checkbox-label-margin-right: 12px !default;
  254 +$u-checkbox-label-color: $u-content-color !default;
  255 +$u-checkbox-label-font-size: 15px !default;
  256 +$u-checkbox-label-disabled-color: #c8c9cc !default;
  257 +
  258 +.u-checkbox {
  259 + /* #ifndef APP-NVUE */
  260 + @include flex(row);
  261 + /* #endif */
  262 + // overflow: hidden;
  263 + flex-direction: row;
  264 + // align-items: center;
  265 + margin-bottom: 5px;
  266 + margin-top: 5px;
274 267
275 - .u-checkbox { 268 + &-label--left {
  269 + flex-direction: row;
  270 + }
  271 +
  272 + &-label--right {
  273 + flex-direction: row-reverse;
  274 + justify-content: space-between;
  275 + }
  276 +
  277 + &__icon-wrap {
276 /* #ifndef APP-NVUE */ 278 /* #ifndef APP-NVUE */
277 - @include flex(row); 279 + box-sizing: border-box;
  280 + // nvue下,border-color过渡有问题
  281 + transition-property: border-color, background-color, color;
  282 + transition-duration: 0.2s;
278 /* #endif */ 283 /* #endif */
279 - overflow: hidden;  
280 - flex-direction: row; 284 + color: $u-content-color;
  285 + @include flex;
281 align-items: center; 286 align-items: center;
282 - margin-bottom: 5px;  
283 - margin-top: 5px; 287 + justify-content: center;
  288 + color: transparent;
  289 + text-align: center;
  290 + margin-right: $u-checkbox-icon-wrap-margin-right;
284 291
285 - &-label--left {  
286 - flex-direction: row  
287 - } 292 + font-size: $u-checkbox-icon-wrap-font-size;
  293 + border-width: $u-checkbox-icon-wrap-border-width;
  294 + border-color: $u-checkbox-icon-wrap-border-color;
  295 + border-style: solid;
288 296
289 - &-label--right {  
290 - flex-direction: row-reverse;  
291 - justify-content: space-between 297 + /* #ifdef MP-TOUTIAO */
  298 + // 头条小程序兼容性问题,需要设置行高为0,否则图标偏下
  299 + &__icon {
  300 + line-height: $u-checkbox-icon-wrap-icon-line-height;
292 } 301 }
293 302
294 - &__icon-wrap {  
295 - /* #ifndef APP-NVUE */  
296 - box-sizing: border-box;  
297 - // nvue下,border-color过渡有问题  
298 - transition-property: border-color, background-color, color;  
299 - transition-duration: 0.2s;  
300 - /* #endif */  
301 - color: $u-content-color;  
302 - @include flex;  
303 - align-items: center;  
304 - justify-content: center;  
305 - color: transparent;  
306 - text-align: center;  
307 - margin-right: $u-checkbox-icon-wrap-margin-right;  
308 -  
309 - font-size: $u-checkbox-icon-wrap-font-size;  
310 - border-width: $u-checkbox-icon-wrap-border-width;  
311 - border-color: $u-checkbox-icon-wrap-border-color;  
312 - border-style: solid;  
313 -  
314 - /* #ifdef MP-TOUTIAO */  
315 - // 头条小程序兼容性问题,需要设置行高为0,否则图标偏下  
316 - &__icon {  
317 - line-height: $u-checkbox-icon-wrap-icon-line-height;  
318 - }  
319 -  
320 - /* #endif */ 303 + /* #endif */
321 304
322 - &--circle {  
323 - border-radius: $u-checkbox-icon-wrap-circle-border-radius;  
324 - } 305 + &--circle {
  306 + border-radius: $u-checkbox-icon-wrap-circle-border-radius;
  307 + }
325 308
326 - &--square {  
327 - border-radius: $u-checkbox-icon-wrap-square-border-radius;  
328 - } 309 + &--square {
  310 + border-radius: $u-checkbox-icon-wrap-square-border-radius;
  311 + }
329 312
330 - &--checked {  
331 - color: $u-checkbox-icon-wrap-checked-color;  
332 - background-color: $u-checkbox-icon-wrap-checked-background-color;  
333 - border-color: $u-checkbox-icon-wrap-checked-border-color;  
334 - } 313 + &--checked {
  314 + color: $u-checkbox-icon-wrap-checked-color;
  315 + background-color: $u-checkbox-icon-wrap-checked-background-color;
  316 + border-color: $u-checkbox-icon-wrap-checked-border-color;
  317 + }
335 318
336 - &--disabled {  
337 - background-color: $u-checkbox-icon-wrap-disabled-background-color !important;  
338 - } 319 + &--disabled {
  320 + background-color: $u-checkbox-icon-wrap-disabled-background-color !important;
  321 + }
339 322
340 - &--disabled--checked {  
341 - color: $u-checkbox-icon-wrap-disabled-checked-color !important;  
342 - } 323 + &--disabled--checked {
  324 + color: $u-checkbox-icon-wrap-disabled-checked-color !important;
343 } 325 }
  326 + }
344 327
345 - &__label {  
346 - /* #ifndef APP-NVUE */  
347 - word-wrap: break-word;  
348 - /* #endif */  
349 - margin-left: $u-checkbox-label-margin-left;  
350 - margin-right: $u-checkbox-label-margin-right;  
351 - color: $u-checkbox-label-color;  
352 - font-size: $u-checkbox-label-font-size; 328 + &__label {
  329 + /* #ifndef APP-NVUE */
  330 + word-wrap: break-word;
  331 + /* #endif */
  332 + margin-left: $u-checkbox-label-margin-left;
  333 + margin-right: $u-checkbox-label-margin-right;
  334 + color: $u-checkbox-label-color;
  335 + font-size: $u-checkbox-label-font-size;
353 336
354 - &--disabled {  
355 - color: $u-checkbox-label-disabled-color;  
356 - } 337 + &--disabled {
  338 + color: $u-checkbox-label-disabled-color;
357 } 339 }
358 } 340 }
  341 +}
359 </style> 342 </style>
garbage-removal/src/uview-plus/components/u-collapse-item/u-collapse-item.vue
1 <template> 1 <template>
2 <view class="u-collapse-item"> 2 <view class="u-collapse-item">
3 - <u-cell  
4 - :title="title"  
5 - :value="value"  
6 - :label="label"  
7 - :icon="icon"  
8 - :isLink="isLink"  
9 - :clickable="clickable"  
10 - :border="parentData.border && showBorder"  
11 - @click="clickHandler"  
12 - :arrowDirection="expanded ? 'up' : 'down'"  
13 - :disabled="disabled"  
14 - > 3 + <u-cell :title="title" :value="value" :label="label" :icon="icon" :isLink="isLink" :clickable="clickable"
  4 + :border="parentData.border && showBorder" @click="clickHandler" :arrowDirection="expanded ? 'up' : 'down'"
  5 + :disabled="disabled">
15 <!-- #ifndef MP-WEIXIN --> 6 <!-- #ifndef MP-WEIXIN -->
16 <!-- 微信小程序不支持,因为微信中不支持 <slot name="title" slot="title" />的写法 --> 7 <!-- 微信小程序不支持,因为微信中不支持 <slot name="title" slot="title" />的写法 -->
17 <template #title> 8 <template #title>
@@ -28,200 +19,189 @@ @@ -28,200 +19,189 @@
28 </template> 19 </template>
29 <!-- #endif --> 20 <!-- #endif -->
30 </u-cell> 21 </u-cell>
31 - <view  
32 - class="u-collapse-item__content"  
33 - :animation="animationData"  
34 - ref="animation"  
35 - >  
36 - <view  
37 - class="u-collapse-item__content__text content-class"  
38 - :id="elId"  
39 - :ref="elId"  
40 - ><slot /></view> 22 + <view class="u-collapse-item__content" :animation="animationData" ref="animation">
  23 + <view class="u-collapse-item__content__text content-class" :id="elId" :ref="elId">
  24 + <slot />
  25 + </view>
41 </view> 26 </view>
42 <u-line v-if="parentData.border"></u-line> 27 <u-line v-if="parentData.border"></u-line>
43 </view> 28 </view>
44 </template> 29 </template>
45 30
46 <script> 31 <script>
47 - import props from './props.js';  
48 - import mpMixin from '../../libs/mixin/mpMixin.js';  
49 - import mixin from '../../libs/mixin/mixin.js';  
50 - import { nextTick } from 'vue'  
51 - // #ifdef APP-NVUE  
52 - const animation = uni.requireNativePlugin('animation')  
53 - const dom = uni.requireNativePlugin('dom')  
54 - // #endif  
55 - /**  
56 - * collapseItem 折叠面板Item  
57 - * @description 通过折叠面板收纳内容区域(搭配u-collapse使用)  
58 - * @tutorial https://ijry.github.io/uview-plus/components/collapse.html  
59 - * @property {String} title 标题  
60 - * @property {String} value 标题右侧内容  
61 - * @property {String} label 标题下方的描述信息  
62 - * @property {Boolean} disbled 是否禁用折叠面板 ( 默认 false )  
63 - * @property {Boolean} isLink 是否展示右侧箭头并开启点击反馈 ( 默认 true )  
64 - * @property {Boolean} clickable 是否开启点击反馈 ( 默认 true )  
65 - * @property {Boolean} border 是否显示内边框 ( 默认 true )  
66 - * @property {String} align 标题的对齐方式 ( 默认 'left' )  
67 - * @property {String | Number} name 唯一标识符  
68 - * @property {String} icon 标题左侧图片,可为绝对路径的图片或内置图标  
69 - * @event {Function} change 某个item被打开或者收起时触发  
70 - * @example <u-collapse-item :title="item.head" v-for="(item, index) in itemList" :key="index">{{item.body}}</u-collapse-item>  
71 - */  
72 - export default {  
73 - name: "u-collapse-item",  
74 - mixins: [mpMixin, mixin, props],  
75 - data() {  
76 - return {  
77 - elId: uni.$u.guid(),  
78 - // uni.createAnimation的导出数据  
79 - animationData: {},  
80 - // 是否展开状态  
81 - expanded: false,  
82 - // 根据expanded确定是否显示border,为了控制展开时,cell的下划线更好的显示效果,进行一定时间的延时  
83 - showBorder: false,  
84 - // 是否动画中,如果是则不允许继续触发点击  
85 - animating: false,  
86 - // 父组件u-collapse的参数  
87 - parentData: {  
88 - accordion: false,  
89 - border: false 32 +import { nextTick } from 'vue';
  33 +import mixin from '../../libs/mixin/mixin.js';
  34 +import mpMixin from '../../libs/mixin/mpMixin.js';
  35 +import props from './props.js';
  36 +// #ifdef APP-NVUE
  37 +const animation = uni.requireNativePlugin('animation')
  38 +const dom = uni.requireNativePlugin('dom')
  39 +// #endif
  40 +/**
  41 + * collapseItem 折叠面板Item
  42 + * @description 通过折叠面板收纳内容区域(搭配u-collapse使用)
  43 + * @tutorial https://ijry.github.io/uview-plus/components/collapse.html
  44 + * @property {String} title 标题
  45 + * @property {String} value 标题右侧内容
  46 + * @property {String} label 标题下方的描述信息
  47 + * @property {Boolean} disbled 是否禁用折叠面板 ( 默认 false )
  48 + * @property {Boolean} isLink 是否展示右侧箭头并开启点击反馈 ( 默认 true )
  49 + * @property {Boolean} clickable 是否开启点击反馈 ( 默认 true )
  50 + * @property {Boolean} border 是否显示内边框 ( 默认 true )
  51 + * @property {String} align 标题的对齐方式 ( 默认 'left' )
  52 + * @property {String | Number} name 唯一标识符
  53 + * @property {String} icon 标题左侧图片,可为绝对路径的图片或内置图标
  54 + * @event {Function} change 某个item被打开或者收起时触发
  55 + * @example <u-collapse-item :title="item.head" v-for="(item, index) in itemList" :key="index">{{item.body}}</u-collapse-item>
  56 + */
  57 +export default {
  58 + name: "u-collapse-item",
  59 + mixins: [mpMixin, mixin, props],
  60 + data() {
  61 + return {
  62 + elId: uni.$u.guid(),
  63 + // uni.createAnimation的导出数据
  64 + animationData: {},
  65 + // 是否展开状态
  66 + expanded: false,
  67 + // 根据expanded确定是否显示border,为了控制展开时,cell的下划线更好的显示效果,进行一定时间的延时
  68 + showBorder: false,
  69 + // 是否动画中,如果是则不允许继续触发点击
  70 + animating: false,
  71 + // 父组件u-collapse的参数
  72 + parentData: {
  73 + accordion: false,
  74 + border: false
  75 + }
  76 + };
  77 + },
  78 + watch: {
  79 + expanded(n) {
  80 + clearTimeout(this.timer)
  81 + this.timer = null
  82 + // 这里根据expanded的值来进行一定的延时,是为了cell的下划线更好的显示效果
  83 + this.timer = setTimeout(() => {
  84 + this.showBorder = n
  85 + }, n ? 10 : 290)
  86 + }
  87 + },
  88 + mounted() {
  89 + this.init()
  90 + },
  91 + methods: {
  92 + // 异步获取内容,或者动态修改了内容时,需要重新初始化
  93 + async init() {
  94 + // 初始化数据
  95 + this.updateParentData()
  96 + if (!this.parent) {
  97 + return uni.$u.error('u-collapse-item必须要搭配u-collapse组件使用')
  98 + }
  99 + const {
  100 + value,
  101 + accordion,
  102 + children = []
  103 + } = this.parent
  104 +
  105 + if (accordion) {
  106 + if (uni.$u.test.array(value)) {
  107 + return uni.$u.error('手风琴模式下,u-collapse组件的value参数不能为数组')
90 } 108 }
91 - };  
92 - },  
93 - watch: {  
94 - expanded(n) {  
95 - clearTimeout(this.timer)  
96 - this.timer = null  
97 - // 这里根据expanded的值来进行一定的延时,是为了cell的下划线更好的显示效果  
98 - this.timer = setTimeout(() => {  
99 - this.showBorder = n  
100 - }, n ? 10 : 290) 109 + this.expanded = this.name == value
  110 + } else {
  111 + if (!uni.$u.test.array(value) && value !== null) {
  112 + return uni.$u.error('非手风琴模式下,u-collapse组件的value参数必须为数组')
  113 + }
  114 + this.expanded = (value || []).some(item => item == this.name)
101 } 115 }
  116 + // 设置组件的展开或收起状态
  117 + await nextTick()
  118 + this.setContentAnimate()
102 }, 119 },
103 - mounted() {  
104 - this.init() 120 + updateParentData() {
  121 + // 此方法在mixin中
  122 + this.getParentData('u-collapse')
105 }, 123 },
106 - methods: {  
107 - // 异步获取内容,或者动态修改了内容时,需要重新初始化  
108 - async init() {  
109 - // 初始化数据  
110 - this.updateParentData()  
111 - if (!this.parent) {  
112 - return uni.$u.error('u-collapse-item必须要搭配u-collapse组件使用')  
113 - }  
114 - const {  
115 - value,  
116 - accordion,  
117 - children = []  
118 - } = this.parent 124 + async setContentAnimate() {
  125 + // 每次面板打开或者收起时,都查询元素尺寸
  126 + // 好处是,父组件从服务端获取内容后,变更折叠面板后可以获得最新的高度
  127 + const rect = await this.queryRect()
  128 + const height = this.expanded ? rect.height : 0
  129 + this.animating = true
  130 + // #ifdef APP-NVUE
  131 + const ref = this.$refs['animation'].ref
  132 + animation.transition(ref, {
  133 + styles: {
  134 + height: height + 'px'
  135 + },
  136 + duration: this.duration,
  137 + // 必须设置为true,否则会到面板收起或展开时,页面其他元素不会随之调整它们的布局
  138 + needLayout: true,
  139 + timingFunction: 'ease-in-out',
  140 + }, () => {
  141 + this.animating = false
  142 + })
  143 + // #endif
119 144
120 - if (accordion) {  
121 - if (uni.$u.test.array(value)) {  
122 - return uni.$u.error('手风琴模式下,u-collapse组件的value参数不能为数组')  
123 - }  
124 - this.expanded = this.name == value  
125 - } else {  
126 - if (!uni.$u.test.array(value) && value !== null) {  
127 - return uni.$u.error('非手风琴模式下,u-collapse组件的value参数必须为数组')  
128 - }  
129 - this.expanded = (value || []).some(item => item == this.name)  
130 - }  
131 - // 设置组件的展开或收起状态  
132 - await nextTick()  
133 - this.setContentAnimate()  
134 - },  
135 - updateParentData() {  
136 - // 此方法在mixin中  
137 - this.getParentData('u-collapse')  
138 - },  
139 - async setContentAnimate() {  
140 - // 每次面板打开或者收起时,都查询元素尺寸  
141 - // 好处是,父组件从服务端获取内容后,变更折叠面板后可以获得最新的高度  
142 - const rect = await this.queryRect()  
143 - const height = this.expanded ? rect.height : 0  
144 - this.animating = true  
145 - // #ifdef APP-NVUE  
146 - const ref = this.$refs['animation'].ref  
147 - animation.transition(ref, {  
148 - styles: {  
149 - height: height + 'px'  
150 - }, 145 + // #ifndef APP-NVUE
  146 + const animation = uni.createAnimation({
  147 + timingFunction: 'ease-in-out',
  148 + });
  149 + animation
  150 + .height(height)
  151 + .step({
151 duration: this.duration, 152 duration: this.duration,
152 - // 必须设置为true,否则会到面板收起或展开时,页面其他元素不会随之调整它们的布局  
153 - needLayout: true,  
154 - timingFunction: 'ease-in-out',  
155 - }, () => {  
156 - this.animating = false  
157 }) 153 })
158 - // #endif  
159 -  
160 - // #ifndef APP-NVUE  
161 - const animation = uni.createAnimation({  
162 - timingFunction: 'ease-in-out',  
163 - });  
164 - animation  
165 - .height(height)  
166 - .step({  
167 - duration: this.duration,  
168 - })  
169 - .step()  
170 - // 导出动画数据给面板的animationData值  
171 - this.animationData = animation.export()  
172 - // 标识动画结束  
173 - uni.$u.sleep(this.duration).then(() => {  
174 - this.animating = false  
175 - })  
176 - // #endif  
177 - },  
178 - // 点击collapsehead头部  
179 - clickHandler() {  
180 - if (this.disabled && this.animating) return  
181 - // 设置本组件为相反的状态  
182 - this.parent && this.parent.onChange(this)  
183 - },  
184 - // 查询内容高度  
185 - queryRect() {  
186 - // #ifndef APP-NVUE  
187 - // $uGetRect为uView自带的节点查询简化方法,详见文档介绍:https://ijry.github.io/uview-plus/js/getRect.html  
188 - // 组件内部一般用this.$uGetRect,对外的为uni.$u.getRect,二者功能一致,名称不同  
189 - return new Promise(resolve => {  
190 - this.$uGetRect(`#${this.elId}`).then(size => {  
191 - resolve(size)  
192 - })  
193 - })  
194 - // #endif  
195 -  
196 - // #ifdef APP-NVUE  
197 - // nvue下,使用dom模块查询元素高度  
198 - // 返回一个promise,让调用此方法的主体能使用then回调  
199 - return new Promise(resolve => {  
200 - dom.getComponentRect(this.$refs[this.elId], res => {  
201 - resolve(res.size)  
202 - })  
203 - })  
204 - // #endif 154 + .step()
  155 + // 导出动画数据给面板的animationData值
  156 + this.animationData = animation.export()
  157 + // 标识动画结束
  158 + uni.$u.sleep(this.duration).then(() => {
  159 + this.animating = false
  160 + })
  161 + // #endif
  162 + },
  163 + // 点击collapsehead头部
  164 + clickHandler(scheduling) {
  165 + if (this.disabled && this.animating) return
  166 + // 设置本组件为相反的状态
  167 + this.parent && this.parent.onChange(this)
  168 + if (scheduling == "抽屉") {
  169 + // this.$emit('selectHandler', this.index, this.name)
  170 + } else {
  171 + this.$emit('selectHandler', 4, "其他")
205 } 172 }
206 }, 173 },
207 - }; 174 + // 查询内容高度
  175 + queryRect() {
  176 + // #ifndef APP-NVUE
  177 + // $uGetRect为uView自带的节点查询简化方法,详见文档介绍:https://ijry.github.io/uview-plus/js/getRect.html
  178 + // 组件内部一般用this.$uGetRect,对外的为uni.$u.getRect,二者功能一致,名称不同
  179 + return new Promise(resolve => {
  180 + this.$uGetRect(`#${this.elId}`).then(size => {
  181 + resolve(size)
  182 + })
  183 + })
  184 + // #endif
  185 + }
  186 + },
  187 +};
208 </script> 188 </script>
209 189
210 <style lang="scss" scoped> 190 <style lang="scss" scoped>
211 - @import "../../libs/css/components.scss"; 191 +@import "../../libs/css/components.scss";
212 192
213 - .u-collapse-item { 193 +.u-collapse-item {
214 194
215 - &__content {  
216 - overflow: hidden;  
217 - height: 0; 195 + &__content {
  196 + overflow: hidden;
  197 + height: 0;
218 198
219 - &__text {  
220 - padding: 12px 15px;  
221 - color: $u-content-color;  
222 - font-size: 14px;  
223 - line-height: 18px;  
224 - } 199 + &__text {
  200 + padding: 12px 15px;
  201 + color: $u-content-color;
  202 + font-size: 14px;
  203 + line-height: 18px;
225 } 204 }
226 } 205 }
  206 +}
227 </style> 207 </style>
garbage-removal/src/uview-plus/components/u-collapse/props.js
@@ -15,6 +15,15 @@ export default { @@ -15,6 +15,15 @@ export default {
15 border: { 15 border: {
16 type: Boolean, 16 type: Boolean,
17 default: defprops.collapse.border 17 default: defprops.collapse.border
  18 + },
  19 + selectHandler: {
  20 + type: Function,
  21 + },
  22 + index: {
  23 + type:Number,
  24 + },
  25 + name: {
  26 + type:String
18 } 27 }
19 } 28 }
20 } 29 }
garbage-removal/src/uview-plus/components/u-collapse/u-collapse.vue
@@ -6,85 +6,86 @@ @@ -6,85 +6,86 @@
6 </template> 6 </template>
7 7
8 <script> 8 <script>
9 - import props from './props.js';  
10 - import mpMixin from '../../libs/mixin/mpMixin.js';  
11 - import mixin from '../../libs/mixin/mixin.js';  
12 - /**  
13 - * collapse 折叠面板  
14 - * @description 通过折叠面板收纳内容区域  
15 - * @tutorial https://ijry.github.io/uview-plus/components/collapse.html  
16 - * @property {String | Number | Array} value 当前展开面板的name,非手风琴模式:[<string | number>],手风琴模式:string | number  
17 - * @property {Boolean} accordion 是否手风琴模式( 默认 false )  
18 - * @property {Boolean} border 是否显示外边框 ( 默认 true )  
19 - * @event {Function} change 当前激活面板展开时触发(如果是手风琴模式,参数activeNames类型为String,否则为Array)  
20 - * @example <u-collapse></u-collapse>  
21 - */  
22 - export default {  
23 - name: "u-collapse",  
24 - mixins: [mpMixin, mixin,props],  
25 - watch: {  
26 - needInit() {  
27 - this.init()  
28 - },  
29 - // 当父组件需要子组件需要共享的参数发生了变化,手动通知子组件  
30 - parentData() {  
31 - if (this.children.length) {  
32 - this.children.map(child => {  
33 - // 判断子组件(u-checkbox)如果有updateParentData方法的话,就就执行(执行的结果是子组件重新从父组件拉取了最新的值)  
34 - typeof(child.updateParentData) === 'function' && child.updateParentData()  
35 - })  
36 - }  
37 - }  
38 - },  
39 - created() {  
40 - this.children = [] 9 +import mixin from '../../libs/mixin/mixin.js';
  10 +import mpMixin from '../../libs/mixin/mpMixin.js';
  11 +import props from './props.js';
  12 +/**
  13 + * collapse 折叠面板
  14 + * @description 通过折叠面板收纳内容区域
  15 + * @tutorial https://ijry.github.io/uview-plus/components/collapse.html
  16 + * @property {String | Number | Array} value 当前展开面板的name,非手风琴模式:[<string | number>],手风琴模式:string | number
  17 + * @property {Boolean} accordion 是否手风琴模式( 默认 false )
  18 + * @property {Boolean} border 是否显示外边框 ( 默认 true )
  19 + * @event {Function} change 当前激活面板展开时触发(如果是手风琴模式,参数activeNames类型为String,否则为Array)
  20 + * @example <u-collapse></u-collapse>
  21 + */
  22 +export default {
  23 + name: "u-collapse",
  24 + mixins: [mpMixin, mixin, props],
  25 + watch: {
  26 + needInit() {
  27 + this.init()
41 }, 28 },
42 - computed: {  
43 - needInit() {  
44 - // 通过computed,同时监听accordion和value值的变化  
45 - // 再通过watch去执行init()方法,进行再一次的初始化  
46 - return [this.accordion, this.value]  
47 - }  
48 - },  
49 - methods: {  
50 - // 重新初始化一次内部的所有子元素  
51 - init() { 29 + // 当父组件需要子组件需要共享的参数发生了变化,手动通知子组件
  30 + parentData() {
  31 + if (this.children.length) {
52 this.children.map(child => { 32 this.children.map(child => {
53 - child.init() 33 + // 判断子组件(u-checkbox)如果有updateParentData方法的话,就就执行(执行的结果是子组件重新从父组件拉取了最新的值)
  34 + typeof (child.updateParentData) === 'function' && child.updateParentData()
54 }) 35 })
55 - },  
56 - /**  
57 - * collapse-item被点击时触发,由collapse统一处理各子组件的状态  
58 - * @param {Object} target 被操作的面板的实例  
59 - */  
60 - onChange(target) {  
61 - let changeArr = []  
62 - this.children.map((child, index) => {  
63 - // 如果是手风琴模式,将其他的折叠面板收起来  
64 - if (this.accordion) {  
65 - child.expanded = child === target ? !target.expanded : false 36 + }
  37 + }
  38 + },
  39 + created() {
  40 + this.children = []
  41 + },
  42 + computed: {
  43 + needInit() {
  44 + // 通过computed,同时监听accordion和value值的变化
  45 + // 再通过watch去执行init()方法,进行再一次的初始化
  46 + return [this.accordion, this.value]
  47 + }
  48 + },
  49 + methods: {
  50 +
  51 + // 重新初始化一次内部的所有子元素
  52 + init() {
  53 + this.children.map(child => {
  54 + child.init()
  55 + })
  56 + },
  57 + /**
  58 + * collapse-item被点击时触发,由collapse统一处理各子组件的状态
  59 + * @param {Object} target 被操作的面板的实例
  60 + */
  61 + onChange(target) {
  62 + let changeArr = []
  63 + this.children.map((child, index) => {
  64 + // 如果是手风琴模式,将其他的折叠面板收起来
  65 + if (this.accordion) {
  66 + child.expanded = child === target ? !target.expanded : false
  67 + child.setContentAnimate()
  68 + } else {
  69 + if (child === target) {
  70 + child.expanded = !child.expanded
66 child.setContentAnimate() 71 child.setContentAnimate()
67 - } else {  
68 - if(child === target) {  
69 - child.expanded = !child.expanded  
70 - child.setContentAnimate()  
71 - }  
72 } 72 }
73 - // 拼接change事件中,数组元素的状态  
74 - changeArr.push({  
75 - // 如果没有定义name属性,则默认返回组件的index索引  
76 - name: child.name || index,  
77 - status: child.expanded ? 'open' : 'close'  
78 - }) 73 + }
  74 + // 拼接change事件中,数组元素的状态
  75 + changeArr.push({
  76 + // 如果没有定义name属性,则默认返回组件的index索引
  77 + name: child.name || index,
  78 + status: child.expanded ? 'open' : 'close'
79 }) 79 })
  80 + })
80 81
81 - this.$emit('change', changeArr)  
82 - this.$emit(target.expanded ? 'open' : 'close', target.name)  
83 - } 82 + this.$emit('change', changeArr)
  83 + this.$emit(target.expanded ? 'open' : 'close', target.name)
84 } 84 }
85 } 85 }
  86 +}
86 </script> 87 </script>
87 88
88 <style lang="scss" scoped> 89 <style lang="scss" scoped>
89 - @import "../../libs/css/components.scss"; 90 +@import "../../libs/css/components.scss";
90 </style> 91 </style>
garbage-removal/src/uview-plus/components/u-popup/u-popup.vue
1 <template> 1 <template>
2 <view class="u-popup"> 2 <view class="u-popup">
3 - <u-overlay  
4 - :show="show"  
5 - @click="overlayClick"  
6 - v-if="overlay"  
7 - :duration="overlayDuration"  
8 - :customStyle="overlayStyle"  
9 - :opacity="overlayOpacity"  
10 - ></u-overlay>  
11 - <u-transition  
12 - :show="show"  
13 - :customStyle="transitionStyle"  
14 - :mode="position"  
15 - :duration="duration"  
16 - @afterEnter="afterEnter"  
17 - @click="clickHandler"  
18 - >  
19 - <view  
20 - class="u-popup__content"  
21 - :style="[contentStyle]"  
22 - @tap.stop="noop"  
23 - > 3 + <u-overlay :show="show" @click="overlayClick" v-if="overlay" :duration="overlayDuration" :customStyle="overlayStyle"
  4 + :opacity="overlayOpacity"></u-overlay>
  5 + <u-transition :show="show" :customStyle="transitionStyle" :mode="position" :duration="duration"
  6 + @afterEnter="afterEnter" @click="clickHandler">
  7 + <view class="u-popup__content" :style="[contentStyle]" @tap.stop="noop">
24 <u-status-bar v-if="safeAreaInsetTop"></u-status-bar> 8 <u-status-bar v-if="safeAreaInsetTop"></u-status-bar>
25 <slot></slot> 9 <slot></slot>
26 - <view  
27 - v-if="closeable"  
28 - @tap.stop="close"  
29 - class="u-popup__content__close"  
30 - :class="['u-popup__content__close--' + closeIconPos]"  
31 - hover-class="u-popup__content__close--hover"  
32 - hover-stay-time="150"  
33 - >  
34 - <u-icon  
35 - name="close"  
36 - color="#909399"  
37 - size="18"  
38 - bold  
39 - ></u-icon> 10 + <view v-if="closeable" @tap.stop="close" class="u-popup__content__close"
  11 + :class="['u-popup__content__close--' + closeIconPos]" hover-class="u-popup__content__close--hover"
  12 + hover-stay-time="150">
  13 + <u-icon name="close" color="#909399" size="18" bold></u-icon>
40 </view> 14 </view>
41 <u-safe-bottom v-if="safeAreaInsetBottom"></u-safe-bottom> 15 <u-safe-bottom v-if="safeAreaInsetBottom"></u-safe-bottom>
42 </view> 16 </view>
@@ -45,262 +19,262 @@ @@ -45,262 +19,262 @@
45 </template> 19 </template>
46 20
47 <script> 21 <script>
48 - import props from './props.js';  
49 - import mpMixin from '../../libs/mixin/mpMixin.js';  
50 - import mixin from '../../libs/mixin/mixin.js'; 22 +import mixin from '../../libs/mixin/mixin.js';
  23 +import mpMixin from '../../libs/mixin/mpMixin.js';
  24 +import props from './props.js';
51 25
52 - /**  
53 - * popup 弹窗  
54 - * @description 弹出层容器,用于展示弹窗、信息提示等内容,支持上、下、左、右和中部弹出。组件只提供容器,内部内容由用户自定义  
55 - * @tutorial https://ijry.github.io/uview-plus/components/popup.html  
56 - * @property {Boolean} show 是否展示弹窗 (默认 false )  
57 - * @property {Boolean} overlay 是否显示遮罩 (默认 true )  
58 - * @property {String} mode 弹出方向(默认 'bottom' )  
59 - * @property {String | Number} duration 动画时长,单位ms (默认 300 )  
60 - * @property {String | Number} overlayDuration 遮罩层动画时长,单位ms (默认 350 )  
61 - * @property {Boolean} closeable 是否显示关闭图标(默认 false )  
62 - * @property {Object | String} overlayStyle 自定义遮罩的样式  
63 - * @property {String | Number} overlayOpacity 遮罩透明度,0-1之间(默认 0.5)  
64 - * @property {Boolean} closeOnClickOverlay 点击遮罩是否关闭弹窗 (默认 true )  
65 - * @property {String | Number} zIndex 层级 (默认 10075 )  
66 - * @property {Boolean} safeAreaInsetBottom 是否为iPhoneX留出底部安全距离 (默认 true )  
67 - * @property {Boolean} safeAreaInsetTop 是否留出顶部安全距离(状态栏高度) (默认 false )  
68 - * @property {String} closeIconPos 自定义关闭图标位置(默认 'top-right' )  
69 - * @property {String | Number} round 圆角值(默认 0)  
70 - * @property {Boolean} zoom 当mode=center时 是否开启缩放(默认 true )  
71 - * @property {Object} customStyle 组件的样式,对象形式  
72 - * @event {Function} open 弹出层打开  
73 - * @event {Function} close 弹出层收起  
74 - * @example <u-popup v-model="show"><text>出淤泥而不染,濯清涟而不妖</text></u-popup>  
75 - */  
76 - export default {  
77 - name: 'u-popup',  
78 - mixins: [mpMixin, mixin, props],  
79 - data() {  
80 - return {  
81 - overlayDuration: this.duration + 50 26 +/**
  27 + * popup 弹窗
  28 + * @description 弹出层容器,用于展示弹窗、信息提示等内容,支持上、下、左、右和中部弹出。组件只提供容器,内部内容由用户自定义
  29 + * @tutorial https://ijry.github.io/uview-plus/components/popup.html
  30 + * @property {Boolean} show 是否展示弹窗 (默认 false )
  31 + * @property {Boolean} overlay 是否显示遮罩 (默认 true )
  32 + * @property {String} mode 弹出方向(默认 'bottom' )
  33 + * @property {String | Number} duration 动画时长,单位ms (默认 300 )
  34 + * @property {String | Number} overlayDuration 遮罩层动画时长,单位ms (默认 350 )
  35 + * @property {Boolean} closeable 是否显示关闭图标(默认 false )
  36 + * @property {Object | String} overlayStyle 自定义遮罩的样式
  37 + * @property {String | Number} overlayOpacity 遮罩透明度,0-1之间(默认 0.5)
  38 + * @property {Boolean} closeOnClickOverlay 点击遮罩是否关闭弹窗 (默认 true )
  39 + * @property {String | Number} zIndex 层级 (默认 10075 )
  40 + * @property {Boolean} safeAreaInsetBottom 是否为iPhoneX留出底部安全距离 (默认 true )
  41 + * @property {Boolean} safeAreaInsetTop 是否留出顶部安全距离(状态栏高度) (默认 false )
  42 + * @property {String} closeIconPos 自定义关闭图标位置(默认 'top-right' )
  43 + * @property {String | Number} round 圆角值(默认 0)
  44 + * @property {Boolean} zoom 当mode=center时 是否开启缩放(默认 true )
  45 + * @property {Object} customStyle 组件的样式,对象形式
  46 + * @event {Function} open 弹出层打开
  47 + * @event {Function} close 弹出层收起
  48 + * @example <u-popup v-model="show"><text>出淤泥而不染,濯清涟而不妖</text></u-popup>
  49 + */
  50 +export default {
  51 + name: 'u-popup',
  52 + mixins: [mpMixin, mixin, props],
  53 + data() {
  54 + return {
  55 + overlayDuration: this.duration + 50
  56 + }
  57 + },
  58 + watch: {
  59 + show(newValue, oldValue) {
  60 + if (newValue === true) {
  61 + // #ifdef MP-WEIXIN
  62 + const children = this.$children
  63 + this.retryComputedComponentRect(children)
  64 + // #endif
82 } 65 }
83 - },  
84 - watch: {  
85 - show(newValue, oldValue) {  
86 - if (newValue === true) {  
87 - // #ifdef MP-WEIXIN  
88 - const children = this.$children  
89 - this.retryComputedComponentRect(children)  
90 - // #endif  
91 - } 66 + }
  67 + },
  68 + computed: {
  69 + transitionStyle() {
  70 + const style = {
  71 + zIndex: this.zIndex,
  72 + position: 'fixed',
  73 + display: 'flex',
  74 + }
  75 + style[this.mode] = 0
  76 + if (this.mode === 'left') {
  77 + return uni.$u.deepMerge(style, {
  78 + bottom: 0,
  79 + top: 0,
  80 + })
  81 + } else if (this.mode === 'right') {
  82 + return uni.$u.deepMerge(style, {
  83 + bottom: 0,
  84 + top: 0,
  85 + })
  86 + } else if (this.mode === 'top') {
  87 + return uni.$u.deepMerge(style, {
  88 + left: 0,
  89 + right: 0
  90 + })
  91 + } else if (this.mode === 'bottom') {
  92 + return uni.$u.deepMerge(style, {
  93 + left: 0,
  94 + right: 0,
  95 + })
  96 + } else if (this.mode === 'center') {
  97 + return uni.$u.deepMerge(style, {
  98 + alignItems: 'center',
  99 + 'justify-content': 'center',
  100 + top: 0,
  101 + left: 0,
  102 + right: 0,
  103 + bottom: 0
  104 + })
92 } 105 }
93 }, 106 },
94 - computed: {  
95 - transitionStyle() {  
96 - const style = {  
97 - zIndex: this.zIndex,  
98 - position: 'fixed',  
99 - display: 'flex',  
100 - }  
101 - style[this.mode] = 0  
102 - if (this.mode === 'left') {  
103 - return uni.$u.deepMerge(style, {  
104 - bottom: 0,  
105 - top: 0,  
106 - })  
107 - } else if (this.mode === 'right') {  
108 - return uni.$u.deepMerge(style, {  
109 - bottom: 0,  
110 - top: 0,  
111 - })  
112 - } else if (this.mode === 'top') {  
113 - return uni.$u.deepMerge(style, {  
114 - left: 0,  
115 - right: 0  
116 - }) 107 + contentStyle() {
  108 + const style = {}
  109 + // 通过设备信息的safeAreaInsets值来判断是否需要预留顶部状态栏和底部安全局的位置
  110 + // 不使用css方案,是因为nvue不支持css的iPhoneX安全区查询属性
  111 + const {
  112 + safeAreaInsets
  113 + } = uni.$u.sys()
  114 + if (this.mode !== 'center') {
  115 + style.flex = 1
  116 + }
  117 + // 背景色,一般用于设置为transparent,去除默认的白色背景
  118 + if (this.bgColor) {
  119 + style.backgroundColor = this.bgColor
  120 + }
  121 + if (this.round) {
  122 + const value = uni.$u.addUnit(this.round)
  123 + if (this.mode === 'top') {
  124 + style.borderBottomLeftRadius = value
  125 + style.borderBottomRightRadius = value
117 } else if (this.mode === 'bottom') { 126 } else if (this.mode === 'bottom') {
118 - return uni.$u.deepMerge(style, {  
119 - left: 0,  
120 - right: 0,  
121 - }) 127 + style.borderTopLeftRadius = value
  128 + style.borderTopRightRadius = value
122 } else if (this.mode === 'center') { 129 } else if (this.mode === 'center') {
123 - return uni.$u.deepMerge(style, {  
124 - alignItems: 'center',  
125 - 'justify-content': 'center',  
126 - top: 0,  
127 - left: 0,  
128 - right: 0,  
129 - bottom: 0  
130 - })  
131 - }  
132 - },  
133 - contentStyle() {  
134 - const style = {}  
135 - // 通过设备信息的safeAreaInsets值来判断是否需要预留顶部状态栏和底部安全局的位置  
136 - // 不使用css方案,是因为nvue不支持css的iPhoneX安全区查询属性  
137 - const {  
138 - safeAreaInsets  
139 - } = uni.$u.sys()  
140 - if (this.mode !== 'center') {  
141 - style.flex = 1 130 + style.borderRadius = value
142 } 131 }
143 - // 背景色,一般用于设置为transparent,去除默认的白色背景  
144 - if (this.bgColor) {  
145 - style.backgroundColor = this.bgColor  
146 - }  
147 - if(this.round) {  
148 - const value = uni.$u.addUnit(this.round)  
149 - if(this.mode === 'top') {  
150 - style.borderBottomLeftRadius = value  
151 - style.borderBottomRightRadius = value  
152 - } else if(this.mode === 'bottom') {  
153 - style.borderTopLeftRadius = value  
154 - style.borderTopRightRadius = value  
155 - } else if(this.mode === 'center') {  
156 - style.borderRadius = value  
157 - }  
158 - }  
159 - return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))  
160 - },  
161 - position() {  
162 - if (this.mode === 'center') {  
163 - return this.zoom ? 'fade-zoom' : 'fade'  
164 - }  
165 - if (this.mode === 'left') {  
166 - return 'slide-left'  
167 - }  
168 - if (this.mode === 'right') {  
169 - return 'slide-right'  
170 - }  
171 - if (this.mode === 'bottom') {  
172 - return 'slide-up'  
173 - }  
174 - if (this.mode === 'top') {  
175 - return 'slide-down'  
176 - }  
177 - }, 132 + }
  133 + return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
178 }, 134 },
179 - methods: {  
180 - // 点击遮罩  
181 - overlayClick() {  
182 - if (this.closeOnClickOverlay) {  
183 - this.$emit('close')  
184 - }  
185 - },  
186 - close(e) { 135 + position() {
  136 + if (this.mode === 'center') {
  137 + return this.zoom ? 'fade-zoom' : 'fade'
  138 + }
  139 + if (this.mode === 'left') {
  140 + return 'slide-left'
  141 + }
  142 + if (this.mode === 'right') {
  143 + return 'slide-right'
  144 + }
  145 + if (this.mode === 'bottom') {
  146 + return 'slide-up'
  147 + }
  148 + if (this.mode === 'top') {
  149 + return 'slide-down'
  150 + }
  151 + },
  152 + },
  153 + methods: {
  154 + // 点击遮罩
  155 + overlayClick() {
  156 + if (this.closeOnClickOverlay) {
187 this.$emit('close') 157 this.$emit('close')
188 - },  
189 - afterEnter() {  
190 - this.$emit('open')  
191 - },  
192 - clickHandler() {  
193 - // 由于中部弹出时,其u-transition占据了整个页面相当于遮罩,此时需要发出遮罩点击事件,是否无法通过点击遮罩关闭弹窗  
194 - if(this.mode === 'center') {  
195 - this.overlayClick() 158 + }
  159 + },
  160 + close(e) {
  161 + this.$emit('close')
  162 + },
  163 + afterEnter() {
  164 + this.$emit('open')
  165 + },
  166 + clickHandler() {
  167 + // 由于中部弹出时,其u-transition占据了整个页面相当于遮罩,此时需要发出遮罩点击事件,是否无法通过点击遮罩关闭弹窗
  168 + if (this.mode === 'center') {
  169 + this.overlayClick()
  170 + }
  171 + this.$emit('click')
  172 + },
  173 + // #ifdef MP-WEIXIN
  174 + retryComputedComponentRect(children) {
  175 + // 组件内部需要计算节点的组件
  176 + const names = ['u-calendar-month', 'u-album', 'u-collapse-item', 'u-dropdown', 'u-index-item', 'u-index-list',
  177 + 'u-line-progress', 'u-list-item', 'u-rate', 'u-read-more', 'u-row', 'u-row-notice', 'u-scroll-list',
  178 + 'u-skeleton', 'u-slider', 'u-steps-item', 'u-sticky', 'u-subsection', 'u-swipe-action-item', 'u-tabbar',
  179 + 'u-tabs', 'u-tooltip'
  180 + ]
  181 + // 历遍所有的子组件节点
  182 + for (let i = 0; i < children.length; i++) {
  183 + const child = children[i]
  184 + // 拿到子组件的子组件
  185 + const grandChild = child.$children
  186 + // 判断如果在需要重新初始化的组件数组中名中,并且存在init方法的话,则执行
  187 + if (names.includes(child.$options.name) && typeof child?.init === 'function') {
  188 + // 需要进行一定的延时,因为初始化页面需要时间
  189 + uni.$u.sleep(50).then(() => {
  190 + child.init()
  191 + })
196 } 192 }
197 - this.$emit('click')  
198 - },  
199 - // #ifdef MP-WEIXIN  
200 - retryComputedComponentRect(children) {  
201 - // 组件内部需要计算节点的组件  
202 - const names = ['u-calendar-month', 'u-album', 'u-collapse-item', 'u-dropdown', 'u-index-item', 'u-index-list',  
203 - 'u-line-progress', 'u-list-item', 'u-rate', 'u-read-more', 'u-row', 'u-row-notice', 'u-scroll-list',  
204 - 'u-skeleton', 'u-slider', 'u-steps-item', 'u-sticky', 'u-subsection', 'u-swipe-action-item', 'u-tabbar',  
205 - 'u-tabs', 'u-tooltip'  
206 - ]  
207 - // 历遍所有的子组件节点  
208 - for (let i = 0; i < children.length; i++) {  
209 - const child = children[i]  
210 - // 拿到子组件的子组件  
211 - const grandChild = child.$children  
212 - // 判断如果在需要重新初始化的组件数组中名中,并且存在init方法的话,则执行  
213 - if (names.includes(child.$options.name) && typeof child?.init === 'function') {  
214 - // 需要进行一定的延时,因为初始化页面需要时间  
215 - uni.$u.sleep(50).then(() => {  
216 - child.init()  
217 - })  
218 - }  
219 - // 如果子组件还有孙组件,进行递归历遍  
220 - if (grandChild.length) {  
221 - this.retryComputedComponentRect(grandChild)  
222 - } 193 + // 如果子组件还有孙组件,进行递归历遍
  194 + if (grandChild.length) {
  195 + this.retryComputedComponentRect(grandChild)
223 } 196 }
224 } 197 }
225 - // #endif  
226 } 198 }
  199 + // #endif
227 } 200 }
  201 +}
228 </script> 202 </script>
229 203
230 <style lang="scss" scoped> 204 <style lang="scss" scoped>
231 - @import "../../libs/css/components.scss";  
232 - $u-popup-flex:1 !default;  
233 - $u-popup-content-background-color: #fff !default; 205 +@import "../../libs/css/components.scss";
  206 +$u-popup-flex: 1 !default;
  207 +$u-popup-content-background-color: #fff !default;
234 208
235 - .u-popup {  
236 - flex: $u-popup-flex; 209 +.u-popup {
  210 + flex: $u-popup-flex;
237 211
238 - &__content {  
239 - background-color: $u-popup-content-background-color;  
240 - position: relative; 212 + &__content {
  213 + background-color: $u-popup-content-background-color;
  214 + position: relative;
241 215
242 - &--round-top {  
243 - border-top-left-radius: 0;  
244 - border-top-right-radius: 0;  
245 - border-bottom-left-radius: 10px;  
246 - border-bottom-right-radius: 10px;  
247 - } 216 + &--round-top {
  217 + border-top-left-radius: 0;
  218 + border-top-right-radius: 0;
  219 + border-bottom-left-radius: 10px;
  220 + border-bottom-right-radius: 10px;
  221 + }
248 222
249 - &--round-left {  
250 - border-top-left-radius: 0;  
251 - border-top-right-radius: 10px;  
252 - border-bottom-left-radius: 0;  
253 - border-bottom-right-radius: 10px;  
254 - } 223 + &--round-left {
  224 + border-top-left-radius: 0;
  225 + border-top-right-radius: 10px;
  226 + border-bottom-left-radius: 0;
  227 + border-bottom-right-radius: 10px;
  228 + }
255 229
256 - &--round-right {  
257 - border-top-left-radius: 10px;  
258 - border-top-right-radius: 0;  
259 - border-bottom-left-radius: 10px;  
260 - border-bottom-right-radius: 0;  
261 - } 230 + &--round-right {
  231 + border-top-left-radius: 10px;
  232 + border-top-right-radius: 0;
  233 + border-bottom-left-radius: 10px;
  234 + border-bottom-right-radius: 0;
  235 + }
262 236
263 - &--round-bottom {  
264 - border-top-left-radius: 10px;  
265 - border-top-right-radius: 10px;  
266 - border-bottom-left-radius: 0;  
267 - border-bottom-right-radius: 0;  
268 - } 237 + &--round-bottom {
  238 + border-top-left-radius: 10px;
  239 + border-top-right-radius: 10px;
  240 + border-bottom-left-radius: 0;
  241 + border-bottom-right-radius: 0;
  242 + }
269 243
270 - &--round-center {  
271 - border-top-left-radius: 10px;  
272 - border-top-right-radius: 10px;  
273 - border-bottom-left-radius: 10px;  
274 - border-bottom-right-radius: 10px;  
275 - } 244 + &--round-center {
  245 + border-top-left-radius: 10px;
  246 + border-top-right-radius: 10px;
  247 + border-bottom-left-radius: 10px;
  248 + border-bottom-right-radius: 10px;
  249 + }
276 250
277 - &__close {  
278 - position: absolute; 251 + &__close {
  252 + position: absolute;
279 253
280 - &--hover {  
281 - opacity: 0.4;  
282 - } 254 + &--hover {
  255 + opacity: 0.4;
283 } 256 }
  257 + }
284 258
285 - &__close--top-left {  
286 - top: 15px;  
287 - left: 15px;  
288 - } 259 + &__close--top-left {
  260 + top: 15px;
  261 + left: 15px;
  262 + }
289 263
290 - &__close--top-right {  
291 - top: 15px;  
292 - right: 15px;  
293 - } 264 + &__close--top-right {
  265 + top: 15px;
  266 + right: 15px;
  267 + }
294 268
295 - &__close--bottom-left {  
296 - bottom: 15px;  
297 - left: 15px;  
298 - } 269 + &__close--bottom-left {
  270 + bottom: 15px;
  271 + left: 15px;
  272 + }
299 273
300 - &__close--bottom-right {  
301 - right: 15px;  
302 - bottom: 15px;  
303 - } 274 + &__close--bottom-right {
  275 + right: 15px;
  276 + bottom: 15px;
304 } 277 }
305 } 278 }
  279 +}
306 </style> 280 </style>