seatonwan9
2025-08-18 357a4c941549c9d65d74629c38b989683f5db0b4
提交源码
1个文件已添加
3个文件已修改
405 ■■■■■ 已修改文件
src/router/modules/productPriceManage.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/layout/components/sideBar/index.vue 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/pointsManage/ruleDetail/index.vue 389 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productManage/price/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/router/modules/productPriceManage.ts
@@ -1,5 +1,5 @@
export default {
  path: 'productPrice/',
  path: 'product/',
  name: 'productPrice',
  children: [
    {
src/views/layout/components/sideBar/index.vue
@@ -73,18 +73,10 @@
    {
        "id": "4fa90aab-2e3c-4bc4-abbf-fbe536629fb0",
        "icon": "",
        "name": "积分设置列表",
        "name": "积分设置",
        "url": "/points/ruleList",
        "parentId": "266e3ff1-ca98-4946-8975-8526ef83cd2a",
        "sort": "1"
    },
    {
        "id": "4fa90aab-2e3c-4bc4-abbf-fbe536629fb1",
        "icon": "",
        "name": "积分设置",
        "url": "/points/settings",
        "parentId": "266e3ff1-ca98-4946-8975-8526ef83cd2a",
        "sort": "2"
    },
    {
        "id": "14a70ce4-7ce0-40d4-8480-2e590f146002",
@@ -184,7 +176,7 @@
        "id": "4fa90aab-2e3c-4bc4-abbf-fbe516729fa2",
        "icon": "",
        "name": "产品列表",
        "url": "/productPrice/list",
        "url": "/product/list",
        "parentId": "266e3ff1-ca98-4946-8975-7526ef83cd5c",
        "sort": "1"
    }]
src/views/pointsManage/ruleDetail/index.vue
New file
@@ -0,0 +1,389 @@
<template>
  <div class="points-settings">
    <div class="settings-content">
      <!-- 左侧:积分获取规则 -->
      <div class="left-column">
        <el-card class="rule-section" shadow="never">
          <template #header>
            <div class="card-header">
              <span class="section-title">积分获取规则</span>
            </div>
          </template>
          <!-- 资源贡献 -->
          <div class="rule-category" v-for="rule in rules.getPointsRuleList">
            <h4>{{ rule.category}}</h4>
            <div class="rule-subcategory">
              <div class="rule-items">
              <div class="rule-item" v-for="pointRuleDetial in rule.pointsRules">
                <span class="rule-desc">{{ pointRuleDetial.ruleName }} : {{ pointRuleDetial.ruleDescription}} </span>
                <el-input
                  v-model="pointRuleDetial.pointsValue"
                  size="small"
                  style="width: 80px;"
                  placeholder="请输入"
                  readonly
                />
                <span class="unit">积分</span>
                <span class="unit" v-if="pointRuleDetial.isLimit === 1">,每日积分上限</span>
                <el-input
                  v-model="pointRuleDetial.dailyLimit"
                  size="small"
                  style="width: 80px;"
                  placeholder="请输入"
                  readonly
                   v-if="pointRuleDetial.isLimit === 1"
                />
              </div>
              </div>
            </div>
          </div>
        </el-card>
      </div>
      <!-- 右侧:积分消耗规则和积分转换规则 -->
      <div class="right-column">
        <!-- 积分消耗规则 -->
        <el-card class="rule-section" shadow="never">
          <template #header>
            <div class="card-header">
              <span class="section-title">积分消耗规则</span>
            </div>
          </template>
          <!-- 资源传播 -->
          <div class="rule-category" v-for="consumeRule in rules.consumePointsRuleList">
            <h4>{{ consumeRule.category }}</h4>
            <div class="rule-subcategory">
            <div class="rule-items">
              <div class="rule-item" v-for="pointRuleDetials in consumeRule.pointsRules">
                <span class="rule-desc">{{ pointRuleDetials.ruleName }} : {{ pointRuleDetials.ruleDescription}}</span>
                <el-input
                  v-model="pointRuleDetials.pointsValue"
                  size="small"
                  style="width: 60px;"
                  placeholder="请输入"
                  readonly
                />
                <span class="unit">积分</span>
                <span class="unit" v-if="pointRuleDetials.isLimit === 1">,每日积分上限</span>
                  <el-input
                          v-model="pointRuleDetials.dailyLimit"
                          size="small"
                          style="width: 80px;"
                          placeholder="请输入"
                          readonly
                          v-if="pointRuleDetials.isLimit === 1"
                  />
              </div>
            </div>
            </div>
          </div>
        </el-card>
      </div>
    </div>
    <!-- 底部按钮 -->
    <div class="bottom-actions">
      <el-button @click="goBack" size="large">返回</el-button>
    </div>
  </div>
</template>
<script setup lang="ts">
import { ref, onMounted, watch } from 'vue'
import { useRoute } from 'vue-router'
import { ElMessage } from 'element-plus'
import pointsApi from '../../../api/pointsApi'
// 定义props
interface Props {
  ruleId?: string
}
const props = withDefaults(defineProps<Props>(), {
  ruleId: ''
})
// 定义emits
const emit = defineEmits<{
  goBack: []
}>()
// 获取路由实例
const route = useRoute()
// 获取路由参数中的规则id,优先使用props中的ruleId
const ruleId = props.ruleId || (route.query.ruleId as string)
interface PointRule {
  category: string,
  pointsRules: PointRuleDetial[]
}
interface PointRuleDetial {
  category: string,
  id: number,
  ruleDescription: string,
  ruleName: string,
  createdAt: string,
  ruleType: number,
  pointsWinner: number,
  isLimit: number,
  pointsValue: number,
  dailyLimit: number
}
// 积分规则配置
interface PointsRules {
  getPointsRuleList: PointRule[],
  consumePointsRuleList: PointRule[]
}
const rules = ref<PointsRules>({
  consumePointsRuleList: [],
  getPointsRuleList: []
})
// 获取积分规则配置
const getPointsRules = async () => {
  try {
    if (ruleId) {
      // 如果有ruleId参数,则获取特定规则
      const formData = new URLSearchParams();
      formData.append('ruleId', ruleId);
      const res = await pointsApi.getPointsRuleById(formData)
      if (res.code === 200 && res.data) {
        // 将后端数据映射到前端规则对象
        Object.assign(rules.value, res.data)
        console.log(rules.value)
      }
    } else {
      // 如果没有ruleId参数,则获取所有规则
      const res = await pointsApi.getPointsRules({})
      if (res.code === 200 && res.data) {
        // 将后端数据映射到前端规则对象
        Object.assign(rules.value, res.data)
      }
    }
  } catch (error) {
    console.error('获取积分规则失败:', error)
  }
}
// 返回上一页
const goBack = () => {
  // 如果是从组件调用,发出goBack事件
  if (props.ruleId) {
    emit('goBack')
  } else {
    // 否则使用原有的返回逻辑
    history.back()
  }
}
// 监听ruleId变化
watch(() => props.ruleId, (newRuleId) => {
  if (newRuleId) {
    getPointsRules()
  }
}, { immediate: true })
onMounted(() => {
  // 只有在没有props.ruleId时才执行原有的逻辑
  if (!props.ruleId) {
    getPointsRules()
  }
})
</script>
<style scoped lang="scss">
.points-settings {
  padding: 20px;
  background-color: #f5f5f5;
  min-height: 100vh;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  .page-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
    padding: 16px 20px;
    background: white;
    border-radius: 8px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    .breadcrumb {
      display: flex;
      align-items: center;
      gap: 8px;
      .back-arrow {
        cursor: pointer;
        color: #409eff;
        font-size: 18px;
        &:hover {
          color: #66b1ff;
        }
      }
      .title {
        font-size: 16px;
        font-weight: 500;
        color: #303133;
      }
    }
    .actions {
      display: flex;
      gap: 12px;
    }
  }
  .settings-content {
    display: flex;
    gap: 20px;
    max-width: 1665px;
    margin: 0 auto;
    margin-bottom: 40px;
    @media (max-width: 768px) {
      flex-direction: column;
      gap: 16px;
    }
  }
  .bottom-actions {
    display: flex;
    justify-content: center;
    gap: 20px;
    padding: 20px 0;
    .el-button {
      min-width: 120px;
      height: 40px;
      font-size: 14px;
    }
  }
  .left-column {
    flex: 1;
    max-width: 50%;
    @media (max-width: 768px) {
      max-width: 100%;
    }
  }
  .right-column {
    flex: 1;
    max-width: 50%;
    display: flex;
    flex-direction: column;
    gap: 20px;
    @media (max-width: 768px) {
      max-width: 100%;
      gap: 16px;
    }
  }
  .rule-section {
    border-radius: 8px;
    border: 1px solid #e4e7ed;
    .card-header {
      .section-title {
        font-size: 16px;
        font-weight: 600;
        color: #656D9A;
      }
    }
  }
  .rule-category {
    margin-bottom: 24px;
    h4 {
      font-size: 14px;
      font-weight: 600;
      color: #303133;
      margin: 0 0 16px 0;
      padding-bottom: 8px;
      border-bottom: 1px solid #ebeef5;
      background-color: #f8f9fa;
      padding: 8px 12px;
      border-radius: 4px;
      border-left: 3px solid #409eff;
    }
    .rule-subcategory {
      margin-left: 16px;
      margin-bottom: 16px;
      h5 {
        font-size: 13px;
        font-weight: 500;
        color: #606266;
        margin: 0 0 12px 0;
        padding-left: 8px;
      }
    }
    .rule-items {
      display: flex;
      flex-direction: column;
      margin-left: 16px;
      gap: 8px;
    }
    .rule-item {
      display: flex;
      align-items: center;
      gap: 6px;
      padding: 6px 8px;
      border-radius: 4px;
      transition: background-color 0.2s;
      &:hover {
        background-color: #f5f7fa;
      }
      .rule-desc {
        font-size: 13px;
        color: #606266;
        line-height: 1.4;
      }
      .unit {
        font-size: 13px;
        color: #606266;
        white-space: nowrap;
      }
      :deep(.el-input) {
        .el-input__wrapper {
          box-shadow: 0 0 0 1px #dcdfe6 inset;
          background-color: #f5f7fa;
          &:hover {
            box-shadow: 0 0 0 1px #c0c4cc inset;
          }
          &.is-focus {
            box-shadow: 0 0 0 1px #409eff inset;
          }
        }
        .el-input__inner {
          color: #606266;
          cursor: not-allowed;
        }
      }
    }
  }
}
</style>
src/views/productManage/price/index.vue
@@ -17,7 +17,7 @@
        </div>
      </template>
      <el-descriptions v-if="productDetail" :column="3" border>
      <el-descriptions v-if="productDetail" :column="2" border>
        <el-descriptions-item label="产品名称">{{ productDetail.name }}</el-descriptions-item>
        <el-descriptions-item label="提报单位">{{ productDetail.submitUnit }}</el-descriptions-item>
        <el-descriptions-item label="提报人">{{ productDetail.submitter }}</el-descriptions-item>