Ver código fonte

红包规则变动--临时提交一版

shizhongqi 4 meses atrás
pai
commit
d0ce6ba5f7

+ 354 - 0
hdApp/src/admin/hb/ruleList.vue

@@ -0,0 +1,354 @@
+<template>
+    <view class="app-content">
+        <view class="list-wrap">
+            <block v-if="!$util.isEmpty(list.data)">
+                <block v-for="(item, index) in list.data" :key="item.id">
+                    <view class="list" :class="{ dragging: draggedIndex === index }" :style="{
+                        transform: transformStyle(index),
+                        transition: isDragging ? 'none' : 'transform 0.3s ease',
+                        zIndex: draggedIndex === index ? 999 : 1
+                    }" @click="navigateToGoodsSort(item)">
+                        <!-- <view class="list-img">
+                            <image :src="item.img" mode="aspectFit"></image>
+                        </view> -->
+                        <view class="list-det">
+                            <view class="app-size-28 app-color-0">满<text style="margin-left: 8upx;font-size: 32upx; font-weight: bold">{{ item.amount }}元</text>,送{{ item.num }}个红包</view>
+                        </view>
+
+                        <view class="confirm-btn">
+                            <button class="admin-button-com middle blue"
+                                style="position:absolute;top:50rpx;right: 170rpx" @click="navigateToSendHb(item)">修改</button>
+                            <button class="admin-button-com middle blue"
+                                style="position:absolute;top:50rpx;right: 10rpx">删除</button>
+                        </view>
+                    </view>
+                </block>
+            </block>
+            <block v-else>
+                <app-wrapper-empty title="暂无数据" :is-empty="$util.isEmpty(list.data)" />
+            </block>
+        </view>
+        <view class="app-footer">
+			<button class="admin-button-com middle blue" @click="addHbRuleFn">创建规则</button>
+		</view>
+    </view>
+</template>
+<script>
+import ModalModule from '@/components/plugin/modal';
+import AppUploader from '@/components/app-uploader';
+import OperateModule from '@/admin/home/components/module/operate';
+import AppWrapperEmpty from '@/components/app-wrapper-empty';
+import { list } from '@/mixins';
+import { hbRulesList, sendHbRule, deleteHbRule } from '@/api/hb';
+import { categoryListInfo } from '@/api/goods';
+import { sort } from '@/api/category';
+export default {
+    name: 'category',
+    components: {
+        ModalModule,
+        AppUploader,
+        OperateModule,
+        AppWrapperEmpty
+    },
+    mixins: [list],
+    data() {
+        return {
+            draggedIndex: -1,
+            draggedItem: null,
+            dragOffsetY: 0,
+            isDragging: false,
+            itemHeight: 160, // 列表项高度,单位rpx
+            startY: 0
+        };
+    },
+    onPullDownRefresh() {
+        this.resetList();
+        this.getCategoryList().then(() => {
+            uni.stopPullDownRefresh();
+        });
+    },
+    onReachBottom() {
+        if (!this.list.finished) {
+            this.getCategoryList().then(() => {
+                uni.stopPullDownRefresh();
+            });
+        } else {
+            uni.stopPullDownRefresh();
+        }
+    },
+    methods: {
+        async init() {
+            this.getHbRulesList();
+        },
+        getHbRulesList() {
+            hbRulesList().then(res => {
+                if(res.code == 1) {
+                    let data = { code: res.code, msg: res.msg, data: { list: res.data.list } };
+                    this.completes(data);
+                } else {
+                    this.$msg(res.msg);
+                }
+            });
+        },
+        navigateToSendHb(item) {
+            uni.navigateTo({ url: '/admin/hb/sendHb?id=' + item.id})
+        },
+        // 跳转到商品排序页面
+        navigateToGoodsSort(item) {
+            uni.navigateTo({ url: '/admin/goods/goodsSort?id=' + item.id + "&name=" + item.categoryName })
+        },
+        addHbRuleFn() {
+            uni.navigateTo({ url: '/admin/hb/sendHb'})
+        },
+        getCategoryList() {
+            return categoryListInfo().then((res) => {
+                let data = { code: res.code, msg: res.msg, data: { list: res.data } };
+                this.completes(data);
+            });
+        },
+        // 拖拽相关方法
+        transformStyle(index) {
+            if (index === this.draggedIndex) {
+                return `translateY(${this.dragOffsetY}rpx)`;
+            }
+            return 'translateY(0rpx)';
+        },
+
+        dragStart(e) {
+            const index = parseInt(e.currentTarget.dataset.index);
+            this.draggedIndex = index;
+            this.draggedItem = this.list.data[index];
+            this.startY = e.touches[0].clientY;
+            this.isDragging = true;
+        },
+
+        dragMove(e) {
+            if (!this.isDragging || this.draggedIndex === -1) return;
+
+            const currentY = e.touches[0].clientY;
+            const deltaY = currentY - this.startY;
+
+            const systemInfo = uni.getSystemInfoSync();
+            const pixelRatio = 750 / systemInfo.windowWidth;
+            // 根据设备像素比例转换为rpx单位
+            const deltaYrpx = deltaY * pixelRatio;
+
+            this.dragOffsetY = deltaYrpx;
+
+            // 计算目标位置
+            const itemHeightrpx = this.itemHeight * pixelRatio;
+
+            // 使用更精确的计算方法确定移动的项目数
+            const moveDistance = Math.abs(deltaYrpx);
+            const moveDirection = deltaYrpx > 0 ? 1 : -1;
+            const moveItems = Math.floor(moveDistance / (itemHeightrpx * 0.5)) * moveDirection;
+
+            // 确保目标索引在有效范围内
+            const targetIndex = Math.max(0, Math.min(this.list.data.length - 1, this.draggedIndex + moveItems));
+
+            if (targetIndex !== this.draggedIndex) {
+                // 交换元素位置
+                const newData = [...this.list.data];
+                const draggedItem = newData[this.draggedIndex];
+                newData.splice(this.draggedIndex, 1);
+                newData.splice(targetIndex, 0, draggedItem);
+
+                // 更新数据和拖拽状态
+                this.list.data = newData;
+                this.draggedIndex = targetIndex;
+                this.startY = currentY;
+                this.dragOffsetY = 0;
+            }
+        },
+
+        dragEnd() {
+            if (!this.isDragging) return;
+
+            // 重置拖拽状态
+            this.draggedIndex = -1;
+            this.draggedItem = null;
+            this.dragOffsetY = 0;
+            this.isDragging = false;
+            this.startY = 0;
+
+            // 更新排序值并发送到后端
+            this.updateSortOrder();
+        },
+
+        updateSortOrder() {
+            // 更新每个项目的inTurn值,从大到小排序
+            const sortData = this.list.data.map((item, index) => ({
+                id: item.id,
+                inTurn: this.list.data.length - index // 反向索引,使第一个项目有最大值
+                // 如果是分页加载的,请用 data.total 替换掉 this.list.data.length
+            }));
+
+            // 调用API更新排序
+            sort({ items: sortData })
+                .then((res) => {
+                    if (res.code === 1) {
+                        this.$msg('已更新');
+                    } else {
+                        this.$msg('排序更新失败');
+                    }
+                })
+                .catch((err) => {
+                    console.error('更新排序失败:', err);
+                    this.$msg('排序更新失败');
+                });
+        },
+
+        // 上移
+        upFn(id) {
+            const index = this.list.data.findIndex((item) => item.id === id);
+            if (index > 0) {
+                const newData = [...this.list.data];
+                const temp = newData[index];
+                newData[index] = newData[index - 1];
+                newData[index - 1] = temp;
+                this.list.data = newData;
+                this.updateSortOrder();
+            }
+        },
+
+        // 下移
+        downFn(id) {
+            const index = this.list.data.findIndex((item) => item.id === id);
+            if (index < this.list.data.length - 1) {
+                const newData = [...this.list.data];
+                const temp = newData[index];
+                newData[index] = newData[index + 1];
+                newData[index + 1] = temp;
+                this.list.data = newData;
+                this.updateSortOrder();
+            }
+        },
+
+        // 置顶
+        topFn(id) {
+            const index = this.list.data.findIndex((item) => item.id === id);
+            if (index > 0) {
+                const newData = [...this.list.data];
+                const targetItem = newData[index];
+
+                // 将目标项移到第一位
+                newData.splice(index, 1);
+                newData.unshift(targetItem);
+
+                this.list.data = newData;
+                this.updateSortOrder();
+            }
+        },
+
+        // 置底
+        bottomFn(id) {
+            const index = this.list.data.findIndex((item) => item.id === id);
+            if (index < this.list.data.length - 1) {
+                const newData = [...this.list.data];
+                const targetItem = newData[index];
+
+                // 将目标项移到最后一位
+                newData.splice(index, 1);
+                newData.push(targetItem);
+
+                this.list.data = newData;
+                this.updateSortOrder();
+            }
+        }
+    }
+};
+</script>
+<style lang="scss" scoped>
+.app-content {
+    min-height: calc(100vh - 100rpx);
+    padding-bottom: 100rpx;
+}
+
+.list-wrap {
+    position: relative;
+    background-color: #fff;
+
+    .list {
+        height: 160rpx;
+        @include disFlex(center, flex-start);
+        padding: 30rpx 0;
+        margin: 0 30rpx;
+        color: $fontColor3;
+        border-bottom: 1px solid $borderColor;
+        position: relative;
+
+        .list-img {
+            width: 130rpx;
+            height: 130rpx;
+
+            image {
+                width: 130rpx;
+                height: 130rpx;
+                border-radius: 20rpx;
+            }
+        }
+
+        .list-det {
+            margin-left: 20rpx;
+
+            &>div {
+                margin-top: 14rpx;
+
+                &:first-child {
+                    margin-top: 0;
+                }
+            }
+        }
+    }
+}
+
+.move-btn {
+    position: absolute;
+    top: 65rpx;
+    color: blue;
+    border: 1px solid #cccccc;
+    padding: 5rpx 10rpx;
+    border-radius: 50%;
+}
+
+.move-btn-line {
+    position: absolute;
+    top: 65rpx;
+    color: blue;
+}
+
+// 拖拽相关样式
+.list.dragging {
+    border: 2px dashed #007aff !important;
+    box-shadow: 0 4px 20px rgba(0, 122, 255, 0.3) !important;
+    background-color: rgba(0, 122, 255, 0.05) !important;
+    opacity: 0.85;
+    border-radius: 12rpx;
+    transform: scale(1.05);
+}
+
+.drag-handle {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 70rpx;
+    height: 70rpx;
+    border-radius: 12rpx;
+    background-color: rgba(0, 0, 0, 0.03);
+    transition: all 0.2s ease;
+    -webkit-touch-callout: none;
+    /* 禁用长按菜单 */
+    -webkit-user-select: none;
+    /* 禁用文本选择 */
+    user-select: none;
+    touch-action: none;
+    /* 禁用浏览器默认触摸行为 */
+
+    /* 增加触摸反馈 */
+    &:active {
+        transform: scale(1.1);
+        background-color: rgba(0, 122, 255, 0.1);
+        box-shadow: 0 4rpx 16rpx rgba(0, 122, 255, 0.2);
+    }
+}
+</style>

+ 122 - 45
hdApp/src/admin/hb/sendHb.vue

@@ -1,22 +1,29 @@
 <template>
   <view class="app-main app-content">
     <view class="rule-list">
-      <view class="rule-card" v-for="(item, index) in rules" :key="index">
-        <view class="form-item">
-          <view class="label">充值金额</view>
-          <input class="input" type="digit" v-model="item.amount" placeholder="请输入金额" />
+      <view class="amount-card">
+        <view class="card-header">
+          <text class="title">充值金额</text>
+          <text class="desc">满足此金额即可获赠红包</text>
         </view>
-        <view class="form-item">
-          <view class="label">送红包数</view>
-          <input class="input" type="number" v-model="item.num" placeholder="请填写数量" />
+        <view class="input-container">
+          <text class="currency">¥</text>
+          <input class="amount-input" type="digit" v-model="amount" placeholder="0.00" placeholder-class="placeholder-style" />
         </view>
+      </view>
+
+      <view class="section-header">
+        <view class="decoration"></view>
+        <text class="title">赠送红包设置</text>
+      </view>
+      <view class="rule-card" v-for="(item, index) in rules" :key="index">
         <view class="form-item">
-          <view class="label">单个包金额</view>
+          <view class="label">包金额</view>
           <input class="input" type="digit" v-model="item.hbAmount" placeholder="请输入金额" />
         </view>
         <view class="form-item">
           <view class="label">有效时长</view>
-          <input class="input" type="number" v-model="item.duration" placeholder="请输入天数,填0永不过期" />
+          <input class="input" type="number" v-model="item.duration" placeholder="请输入天数,填0永不过期" />
         </view>
         <view class="form-item">
           <view class="label">最低消费</view>
@@ -44,44 +51,42 @@
 </template>
 
 <script>
-import { hbRulesList, sendHbRule, deleteHbRule } from '@/api/hb';
+import { hbRuleDetail, sendHbRule, deleteHbRule } from '@/api/hb';
 
 export default {
   data() {
     return {
+      id: '',
+      amount: '', //充值金额
+      num: '', //红包个数
       rules: [
         {
-          id: '',
-          amount: '',
-          num: '',
           hbAmount: '',
-          duration: '',
-          miniCost: ''
+          miniCost: '',
+          duration: ''
         }
       ]
     };
   },
+  onLoad(options) {
+    this.id = options.id || null;
+    if(this.id) {
+      uni.setNavigationBarTitle({title: '修改充值送红包规则'});
+      this.getHbRuleDetail(this.id)
+    } else {
+      uni.setNavigationBarTitle({title: '创建充值送红包规则'});
+      //this.addRule()
+    }
+  },
   methods: {
     init() {
-      this.getHbRulesList()
     },
-    getHbRulesList() {
-      hbRulesList().then(res => {
+    getHbRuleDetail(id) {
+      console.log(id);
+      hbRuleDetail({id: id}).then(res => {
         if(res.code == 1) {
-          if(res.data.list.length == 0) {
-            this.rules = [
-              {
-                id: '',
-                amount: '',
-                num: '',
-                hbAmount: '',
-                duration: '',
-                miniCost: ''
-              }
-            ]
-          } else {
-            this.rules = res.data.list
-          }
+          console.log(res.data);
+          //this.rules = res.data.rules;
         } else {
           this.$msg(res.msg);
         }
@@ -89,9 +94,6 @@ export default {
     },
     addRule() {
       this.rules.push({
-        id: '',
-        amount: '',
-        num: '',
         hbAmount: '',
         duration: '',
         miniCost: ''
@@ -120,18 +122,15 @@ export default {
       uni.navigateBack();
     },
     save() {
+        if (!this.amount) {
+            this.$msg('请输入充值金额');
+            return;
+        }
         for (let i = 0; i < this.rules.length; i++) {
             const rule = this.rules[i];
-            if (!rule.amount) {
-                this.$msg(`请输入第${i+1}项充值金额`);
-                return;
-            }
-            if (!rule.num) {
-                this.$msg(`请输入第${i+1}项送红包数`);
-                return;
-            }
+            
             if (!rule.hbAmount) {
-                this.$msg(`请输入第${i+1}项单个包金额`);
+                this.$msg(`请输入第${i+1}项单个红包金额`);
                 return;
             }
             if (rule.duration === '') {
@@ -144,7 +143,7 @@ export default {
             }
         }
 
-        sendHbRule(this.rules).then(res => {
+        sendHbRule({id: this.id, amount: this.amount, rules: this.rules}).then(res => {
             if(res.code == 1) {
                 this.$msg('保存成功');
                 setTimeout(() => {
@@ -167,6 +166,84 @@ export default {
   box-sizing: border-box;
 }
 
+.amount-card {
+  background: linear-gradient(135deg, #ffffff 0%, #f8fdfa 100%);
+  border-radius: 20upx;
+  padding: 40upx 30upx;
+  margin-bottom: 30upx;
+  box-shadow: 0 4upx 20upx rgba(9, 197, 103, 0.08);
+  border: 2upx solid rgba(9, 197, 103, 0.1);
+
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: flex-end;
+    margin-bottom: 30upx;
+
+    .title {
+      font-size: 34upx;
+      font-weight: bold;
+      color: #333;
+    }
+
+    .desc {
+      font-size: 24upx;
+      color: #999;
+    }
+  }
+
+  .input-container {
+    display: flex;
+    align-items: flex-end;
+    border-bottom: 2upx solid #09C567;
+    padding-bottom: 10upx;
+
+    .currency {
+      font-size: 48upx;
+      font-weight: bold;
+      color: #09C567;
+      margin-right: 16upx;
+      margin-bottom: 4upx;
+    }
+
+    .amount-input {
+      flex: 1;
+      font-size: 64upx;
+      font-weight: bold;
+      color: #333;
+      height: 80upx;
+      line-height: 80upx;
+    }
+
+    .placeholder-style {
+      color: #ccc;
+      font-size: 48upx;
+      font-weight: normal;
+    }
+  }
+}
+
+.section-header {
+  display: flex;
+  align-items: center;
+  margin-bottom: 24upx;
+  padding: 0 10upx;
+
+  .decoration {
+    width: 8upx;
+    height: 32upx;
+    background-color: #09C567;
+    border-radius: 4upx;
+    margin-right: 16upx;
+  }
+
+  .title {
+    font-size: 30upx;
+    font-weight: bold;
+    color: #333;
+  }
+}
+
 .rule-list {
     padding-bottom: 20upx;
 }

+ 1 - 1
hdApp/src/admin/home/apply.vue

@@ -63,7 +63,7 @@ export default {
             { name: "功能开关", emoji: "⚙️", url: "/pagesPurchase/open",pf:1},
             { name: "失信人员", emoji: "⛔", url: "/admin/ll/list",pf:1},
             { name: "会员等级", emoji: "👑", url: "/admin/member/level",pf:1},
-            { name: "充值送红包", emoji: "🧧", url: "/admin/hb/sendHb",pf:1},
+            { name: "充值送红包", emoji: "🧧", url: "/admin/hb/ruleList",pf:1},
             { name: "充值送钱", emoji: "💝", url: "/admin/recharge/discount",pf:1},
             { name: "收款码", emoji: "💳", url: "/admin/cg/code",pf:1},
             { name: "收款流水", emoji: "📱", url: "/admin/order/scanPay",pf:1},

+ 5 - 0
hdApp/src/api/hb/index.js

@@ -33,6 +33,11 @@ export const hbRulesList = data => {
 	return https.get('/hb/hb-rules', data)
 }
 
+//充值送红包规则详情
+export const hbRuleDetail = data => {
+	return https.get('/hb/hb-rule-detail', data)
+}
+
 //充值送红包规则创建
 export const sendHbRule = data => {
 	return https.post('/hb/send-hb-rules', data)

+ 2 - 1
hdApp/src/pages.json

@@ -593,7 +593,8 @@
 			"pages": [
 				{ "path": "list", "style": { "navigationBarTitleText": "红包列表", "enablePullDownRefresh": true } },
 				{ "path": "send", "style": { "navigationBarTitleText": "发红包" } },
-				{ "path": "sendHb", "style": { "navigationBarTitleText": "充值送红包" } },
+				{ "path": "ruleList", "style": { "navigationBarTitleText": "红包规则列表" } },
+				{ "path": "sendHb", "style": { "navigationBarTitleText": "创建充值送红包" } },
 				{ "path": "result", "style": { "navigationBarTitleText": "发放成功" } }
 			]
 		}