uniapp
              复制代码
              
            
          
          <template>
  <view class="pie-progress">
    <view class="progress-container" :style="{ width: config.width + 'rpx', height: config.height + 'rpx' }">
      <!-- 使用相同的计算方式 -->
      <view class="progress-bg" :style="{
        background: `conic-gradient(${config.progress.color} 0, ${config.progress.color} ${config.value}%, ${config.progress.backgroundColor } ${config.value}%, ${config.progress.backgroundColor} 100%)`,
        '-webkit-mask': `radial-gradient(transparent 0%, transparent ${config.inner.width * 70}%, #000 ${config.inner.width * 70}%, #000 0)`,
        width: config.width + 'rpx',
        height: config.height + 'rpx'
      }"></view>
      <!-- 内圈背景 -->
      <view
        class="inner-background"
        :style="{
          width: (config.inner.width * 100) + '%',
          height: (config.inner.width * 100) + '%',
          backgroundColor: config.inner.backgroundColor
        }"
      ></view>
      <!-- 文字内容 -->
      <view class="progress-inner flex-c-c">
        <view class="progress-text flex-c">
          <text
            class="value"
            v-if="config.valueText && config.valueText.value"
            :style="{
              color: config.valueText.color,
              fontSize: config.valueText.fontSize,
              fontWeight: config.valueText.fontWeight
            }"
          >{{ config.valueText.value }}</text>
          <text
            class="desc"
            v-if="config.descText && config.descText.value"
            :style="{
              color: config.descText.color,
              fontSize: config.descText.fontSize,
              fontWeight: config.descText.fontWeight
            }"
          >{{ config.descText.value }}</text>
        </view>
      </view>
    </view>
  </view>
</template>
<script>
export default {
  props: {
    // 配置对象
    opts: {
      type: Object,
      default: () => ({})
    }
  },
  computed: {
    config() {
      return this.mergeWithDefault(this.opts)
    }
  },
  data() {
    return {
      defaultConfig: {
        // 进度值 (0-100)
        value: 0,
        width: 200, // 整体宽度 (单位: rpx)
        height: 200, // 整体高度 (单位: rpx)
        // 进度条配置
        progress: {
          color: '#0E9BF3', // 进度条颜色
          backgroundColor: '#E0E4EB' // 进度条背景色
        },
        // 值文本
        valueText: {
          value: "",
          color: "#3B3B4D",
          fontSize: "28rpx",
          fontWeight: "bold",
        },
        // 描述文本
        descText: {
          value: "",
          color: "#999",
          fontSize: "20rpx",
          fontWeight: "normal"
        },
        // 内圈配置
        inner: {
          width: 0.8, // 内圈宽度占比 (0-1) 占比越大内圈越大,进度条越细
          backgroundColor: "transparent" // 内圈背景色
        }
      }
    }
  },
  methods: {
    // 合并函数
    mergeWithDefault(opts) {
      if (!opts || typeof opts !== 'object') {
        return { ...this.defaultConfig };
      }
      const result = {
        // 第一层合并
        ...this.defaultConfig,
        ...opts,
        // 第二层深度合并
        progress: {
          ...this.defaultConfig.progress,
          ...(opts.progress || {})
        },
        valueText: {
          ...this.defaultConfig.valueText,
          ...(opts.valueText || {})
        },
        descText: {
          ...this.defaultConfig.descText,
          ...(opts.descText || {})
        },
        inner: {
          ...this.defaultConfig.inner,
          ...(opts.inner || {})
        }
      }
      return result
    }
  }
}
</script>
<style lang="scss">
.pie-progress {
  .progress-container {
    position: relative;
    .progress-bg {
      position: absolute;
      top: 0;
      left: 0;
      border-radius: 50%;
    }
    .inner-background {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      border-radius: 50%;
      z-index: 1;
    }
    .progress-inner {
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      z-index: 2;
      .progress-text {
        flex-direction: column;
        flex-shrink: 0;
        .value {
          font-weight: bold;
        }
      }
    }
  }
}
</style>
         
      
          
            
            
              uniapp
              复制代码
              
            
          
          <template>
  <view>
    ......
    <MDPieProgress :opts="getPieProgressConfig(item)"></MDPieProgress>
  </view>
</template>
<script>
export default {
  methods: {
    getPieProgressConfig(item) {
      return {
        value:item.rate,
        width: 108,
        height: 108,
        progress: {
          color: isSub ? '#FF451C' : '#0E9BF3',
          backgroundColor: '#E0E4EB'
        },
        valueText: {
          value: `${item.rate}%`,
          color: '#3B3B4D',
          fontSize: '28rpx',
          fontWeight: 'bold'
        },
        descText: {
          value: '达成率',
          color: '#999999',
          fontSize: '20rpx',
          fontWeight: 'normal'
        },
        inner: {
          width: 0.8,
          backgroundColor: '#FFFFFF'
        }
      }
    }, 
  }
}
</script>