class AliyunVoiceTemplate extends AbstractTemplate<AliyunVoiceTemplate> {
    public static final String CALLED_NUMBER_KEY = "calledNumber";

    @Schema(description = "通知模版ID")
    @NotBlank(message = "[ttsCode]不能为空")
    @Deprecated
    private String ttsCode;

    @Schema(description = "通知模版ID")
    private String templateCode;

    private String calledShowNumbers;

    private String calledNumber;

    private TemplateType templateType = TemplateType.tts;

    @Schema(description = "通知播放次数")
    private int playTimes = 1;

    private Map<String, String> ttsParam;

    public String createTtsParam(Map<String, Object> ctx) {
        Map<String, VariableDefinition> variables = getVariables();

        return JSON.toJSONString(Maps.filterEntries(renderMap(ctx),
                                                    e -> variables.containsKey(e.getKey())));
    }

    public Flux<String> getCalledNumber(Map<String, Object> ctx) {
        if (StringUtils.hasText(this.getCalledNumber())) {
            return Flux.just(this.getCalledNumber());
        }
        //如果没有指定固定值,则从上下文中获取
        return RelationUtils
            .resolve(CALLED_NUMBER_KEY, ctx, RelationConstants.UserProperty.telephone)
            .map(String::valueOf);
    }

    public String getTemplateCode() {
        if (templateCode == null) {
            return ttsCode;
        }
        return templateCode;
    }

    @Nonnull
    @Override
    protected List<VariableDefinition> getEmbeddedVariables() {<FILL_FUNCTION_BODY>}

    public enum TemplateType {
        voice, tts
    }
}

        //指定了固定的收信人
        if (StringUtils.hasText(calledNumber)) {
            return Collections.emptyList();
        }
        return Collections.singletonList(
            VariableDefinition
                .builder()
                .id(CALLED_NUMBER_KEY)
                .name("被叫号码")
                .description("收信人手机号码")
                .expand(NotifyVariableBusinessConstant.businessId,
                        NotifyVariableBusinessConstant.NotifyVariableBusinessTypes.userType)
                .required(true)
                .build()
        );
    
<methods>public void <init>() ,public final Optional<org.jetlinks.community.notify.template.VariableDefinition> getVariable(java.lang.String) ,public final Map<java.lang.String,org.jetlinks.community.notify.template.VariableDefinition> getVariables() ,public Map<java.lang.String,java.lang.Object> toMap() ,public org.jetlinks.community.notify.voice.aliyun.AliyunVoiceTemplate validate() ,public org.jetlinks.community.notify.voice.aliyun.AliyunVoiceTemplate with(org.jetlinks.community.notify.template.TemplateProperties) <variables>private java.lang.String configId,private Map<java.lang.String,org.jetlinks.community.notify.template.VariableDefinition> variables