开发规范以及注意点

preiteer在保存时不格式化文件

在这里插入图片描述

Vscode回车到下一行的时候,不保留缩进
加上这一句即可

"editor.autoIndent": "keep",

<template><div class="strategy-edit" v-loading="loading"><el-formclass="strategy-edit":model="form":rules="rules"label-width="150px"ref="formRef":disabled="isDisable"><el-form-item prop="strategyName" label="策略名称:"><el-inputmaxlength="30"placeholder="请输入咨询策略名称"show-word-limitv-model="form.strategyName"@blur="form.strategyName = form.strategyName.trim()"/></el-form-item><el-form-item label="咨询通道:" prop="consultRoute.type"><el-radio-group:disabled="!!strategyId"v-model="form.consultRoute.type"@change="onConsultChannelChange"><el-radio:disabled="[CONSULT_CHANNEL.WECHAT_SINGLE, CONSULT_CHANNEL.WECHAT_GROUP].includes(key) ||(key === CONSULT_CHANNEL.GENERIC ? map[key] >= 5 : map[key] >= 1)"v-for="(val, key) in CONSULT_CHANNEL_TEXT":key="key":label="key">{{ val }}</el-radio></el-radio-group></el-form-item><div class="indent-form-item" v-if="form.consultRoute.type === CONSULT_CHANNEL.GENERIC"><el-form-item label="命名:" label-width="100px"><el-inputmaxlength="6"placeholder="请输入通用咨询通道命名"show-word-limitv-model="form.consultRoute.name"/></el-form-item><el-form-item label="入口说明文案:" label-width="100px"><el-inputmaxlength="10"placeholder="请输入通用咨询通道说明文案"show-word-limitv-model="form.consultRoute.notice"/></el-form-item></div><el-form-itemprop="frontMemberSetting.assignType"label="成员配置"v-if="form.consultRoute.type !== CONSULT_CHANNEL.WECHAT_GROUP"><Staffv-model="form.frontMemberSetting":hideKeys="form.consultRoute.type === CONSULT_CHANNEL.EXPERT ? [] : ['SOURCE_OWNER']"/></el-form-item><el-form-item label="咨询欢迎语配置:"><el-radio-group v-model="form.welcomeConfig.welcomeMsgType" @change="clearWelcomeMsg"><el-radio label="DEFAULT">默认欢迎语</el-radio><el-radio label="CUSTOM">自定义欢迎语(勾选后,将不再发送默认欢迎语)</el-radio></el-radio-group><el-inputtype="textarea"max="100"show-word-limit:disabled="form.welcomeConfig.welcomeMsgType === 'DEFAULT'"v-model="form.welcomeConfig.welcomeMsg"placeholder="您好,欢迎咨询。我们会为您提供免费的健康咨询、用药打卡等服务,有需要及时咨询!"></el-input></el-form-item><el-form-item label="发送图片:" label-width="75px" class="indent-form-item"><div><MultipleUploadersize="small":disabled="isDisable":maxSize="500 * 1024"accept="image/jpeg,image/png"v-model="form.welcomeConfig.welcomeImages":limit="3"/><p class="uploader-tip">支持扩展名:.png/.jpg文件,且不超过500kb/张,最多3</p></div></el-form-item><el-form-item prop="strategyStatus" label="咨询服务设置:"><el-radio-group v-model="form.strategyStatus" :disabled="isImmutable('status')"><el-radio label="TOENABLED">默认开启咨询服务</el-radio><el-radio label="TODISABLED">按规则开启咨询服务</el-radio></el-radio-group></el-form-item><div class="ps">默认开启咨询服务,表示患者可以无条件发起咨询。按规则开启咨询服务,表示患者需要满足设置的规则后才能发起咨询。</div><div v-if="form.value.strategySetting === 'TOENABLED'"><el-form-item prop="strategyStatus" label="患者积分兑换:"><el-radio-group v-model="form.strategyStatus" :disabled="isImmutable('status')"><el-radio label="ENABLED">积分兑换成功后,患者端咨询聊天开启</el-radio></el-radio-group></el-form-item><el-form-item prop="strategyStatus" label="患者积分兑换:"><el-radio-group v-model="form.strategyStatus" :disabled="isImmutable('status')"><el-radio label="ENABLED">积分兑换成功后,患者端咨询聊天开启</el-radio></el-radio-group></el-form-item></div><el-form-item prop="strategyStatus" label="咨询通道状态:"><el-radio-group v-model="form.strategyStatus" :disabled="isImmutable('status')"><el-radio label="ENABLED">启用</el-radio><el-radio label="DISABLED">禁用</el-radio></el-radio-group></el-form-item><div class="ps">咨询通道的状态用以控制患者端咨询通道的展示和隐藏。开启则患者端可见该咨询通道的入口,禁用则患者端不可见该咨询通道的入口。</div><el-form-item prop="comments" label="备注:"><el-inputmaxlength="100"show-word-limittype="textarea"v-model="form.comments"@blur="form.comments = form.comments.trim()"placeholder="请输入对该策略的描述,比如运营逻辑、注意事项等"></el-input></el-form-item><el-form-item v-if="!isDisable"><div style="text-align: right"><el-button @click="router.back">取消</el-button><el-button type="primary" @click="onConfirm">确认</el-button></div></el-form-item></el-form></div>
</template>
<script lang="ts" setup>
import { ref, watch, reactive, computed, onMounted, provide } from 'vue';
import { useRouter, useRoute } from 'vue-router';
import { useStore } from 'vuex';
import { debounce } from 'lodash-es';
import MultipleUploader from '@/components/Uploader/multiple.vue';
import { CONSULT_CHANNEL, CONSULT_CHANNEL_TEXT, STRATEGY_STATUS } from '@/consts/configuration';
import { ElForm, ElButton, ElMessage, ElFormItem, ElRadioGroup, ElRadio, ElInput } from 'element-plus';
import {fetchConsultStrategyDetail,updateConsultStrategy,createConsultStrategy,fetchRobotList,fetchRobotFriends,fetchConsultStrategyList
} from '@/api/configuration/strategy';
import { remarkReg } from '@/utils/validate';
import { fetchAccount, fetchConsultantList } from '@/api/source';
import Staff from './components/Staff.vue';
import { fetchGroup } from '@/api/system/account';const route = useRoute();
const router = useRouter();
const strategyId = route.params.id;
// 查看模式下均不允许修改
const isDisable = strategyId && route.path.indexOf('edit') < 0;
const hasBindSource = computed(() => isDisable || (form.value.bindSourceIds && !!form.value.bindSourceIds.length));
// 编辑已绑定来源的策略时,一些配置不可更改
const isImmutable = (key) => {const obj = {[CONSULT_CHANNEL.WECHAT_GROUP]: ['serviceProvider', 'status'],[CONSULT_CHANNEL.WECHAT_SINGLE]: ['status'],[CONSULT_CHANNEL.EXPERT]: ['status'],[CONSULT_CHANNEL.GENERIC]: ['status']};return hasBindSource.value && (obj[form.value.consultRoute.type] || []).includes(key);
};const initForm = (): Record<string, any> => ({strategyName: '',consultRoute: {type: '',name: '',notice: ''},frontMemberSetting: {groupType: 'DEFAULT',assignType: '',strategyAssignConfigs: []},welcomeConfig: {welcomeMsgType: 'DEFAULT',welcomeMsg: '',welcomeImages: [],miniProgramsCardLink: ''},strategyStatus: 'ENABLED',strategySetting: 'TOENABLED',comments: '',strategyConditionConfigs: []
});const formRef = ref<typeof ElForm>();
const form = ref<Record<string, any>>(initForm());
const loading = ref(false);
const enums = reactive({groupList: [],staff: []
});
const map = reactive({[CONSULT_CHANNEL.GENERIC]: 0,[CONSULT_CHANNEL.EXPERT]: 0,[CONSULT_CHANNEL.WECHAT_SINGLE]: 0,[CONSULT_CHANNEL.WECHAT_GROUP]: 0
});const validateName = (rule, value, cb) => {if (!value || remarkReg().test(value)) {cb();} else {cb(new Error('支持中英文、标点符号、数字输入,不支持特殊字符'));}
};const rules = ref({strategyName: [{ max: 30, message: '长度不超过30字符', trigger: 'blur' },{required: true,message: '请输入策略名称',trigger: 'blur'},{validator: validateName,trigger: 'blur'}],'consultRoute.type': [{required: true,message: '请选择咨询通道',trigger: 'blur'}],tempGroupMembers: [{required: true,message: '请选择企微成员',trigger: 'change'}],'frontMemberSetting.assignType': [{required: true,message: '成员配置不可为空',trigger: 'blur'},{validator: (_, value, cb) => {const { strategyAssignConfigs = [] } = form.value.frontMemberSetting || {};if (value !== 'SOURCE_OWNER' && !strategyAssignConfigs.length) {cb(new Error('成员配置不可为空'));return;}cb();},trigger: 'blur'}],strategyConditionConfigs: [{required: true,message: '成员配置不可为空',trigger: 'blur'},{validator: (rule, value, cb) => {const guidedArr: number[] = [];for (let i = 0; i < value.length; i++) {const item = value[i];if (item.strategyGroupConfigs.some((c) => {if (c.assignType && c.assignType !== 'SOURCE_OWNER' && !c.strategyAssignConfigs.length) {return true;}})) {cb(new Error('至少选择一个分组或者用户'));return;}if (item.strategyGroupConfigs.every((c) => !c.assignType)) {cb(new Error('1个服务方必须配置分诊组和协作组中的其一'));return;}if (item.guided) {guidedArr.push(item.serviceProviderId);}}if (guidedArr.length) return cb();cb(new Error('至少有1个服务方打开导诊开关'));},trigger: 'blur'}],comments: [{ max: 100, message: '长度不超过100字符', trigger: 'blur' },{validator: validateName,trigger: 'blur'}],strategyStatus: [{required: true,message: '请选择策略状态',trigger: 'blur'}]
});const clearWelcomeMsg = () => {form.value.welcomeConfig.welcomeMsg = '';
};const onConsultChannelChange = (v) => {form.value.consultRoute.name = v === CONSULT_CHANNEL.GENERIC ? '' : CONSULT_CHANNEL_TEXT[v];form.value.consultRoute.notice = '';form.value.frontMemberSetting = initForm().frontMemberSetting;
};const formatData = () => {// 生成后端需要的数据const data = JSON.parse(JSON.stringify(form.value));data.strategyId = strategyId;if ([CONSULT_CHANNEL.GENERIC, CONSULT_CHANNEL.EXPERT].includes(form.value.consultRoute.type)) {// 通用+专家data.strategyConditionConfigs = [{strategyGroupConfigs: [data.frontMemberSetting]}];}data.strategyConditionConfigs[0].strategyGroupConfigs[0].groupType = 'DEFAULT';delete data.frontMemberSetting;if (!data.welcomeConfig) {data.welcomeConfig = {welcomeMsgType: 'DEFAULT',welcomeMsg: '',welcomeImages: [],miniProgramsCardLink: ''};}return data;
};const onConfirm = () => {formRef.value &&formRef.value.validate((isValid) => {if (isValid) {loading.value = true;const fn = strategyId ? updateConsultStrategy : createConsultStrategy;fn(formatData()).then(({ data }) => {ElMessage({type: 'success',duration: 500,message: '操作成功!',onClose: () => {router.push({name: 'strategy-management-list'});}});}).finally(() => {loading.value = false;});}});
};const generateData = (originData = {}) => {// 生成前端需要的字段const data = initForm();for (let k in data) {data[k] = originData[k];}data.frontMemberSetting = {assignType: '',strategyAssignConfigs: []};if ([CONSULT_CHANNEL.GENERIC, CONSULT_CHANNEL.EXPERT].includes(data.consultRoute.type)) {// 通用/专家咨询const [{ strategyGroupConfigs } = { strategyGroupConfigs: [] }] = data.strategyConditionConfigs || [];data.frontMemberSetting = {...data.frontMemberSetting,...strategyGroupConfigs[0],strategyAssignConfigs: strategyGroupConfigs[0]?.strategyAssignConfigs || []};}return data;
};const fetchStrategy = async () => {if (!strategyId) return;try {loading.value = true;let res = await fetchConsultStrategyDetail(+strategyId);form.value = generateData(res.data);if (!form.value.welcomeConfig) {form.value.welcomeConfig = {welcomeMsgType: 'DEFAULT',welcomeMsg: '',welcomeImages: [],miniProgramsCardLink: ''};}console.log(form.value);loading.value = false;} catch (err) {loading.value = false;console.log(err);}
};const getEnums = () => {// 临时设置sizefetchConsultantList({ page: 0, size: 1000 }).then((res) => {enums.staff = res.data.content;});fetchGroup().then((res) => {enums.groupList = res.data.filter((v) => v.subGroups && v.subGroups.length);});fetchStrategyCount();
};
const fetchStrategyCount = () => {fetchConsultStrategyList({strategyStatusIn: [STRATEGY_STATUS.ENABLED]},{ page: 0, size: 100 }).then((res) => {for (let k in map) {map[k] = 0;}for (let val of res.data?.content || []) {const { type } = val.consultRoute || {};if (map[type] !== undefined) {map[type]++;}}});
};getEnums();
onMounted(() => {const { type } = route.query;if (!strategyId && type && !CONSULT_CHANNEL_TEXT[<string>type]) {form.value.consultRoute.type = CONSULT_CHANNEL.GENERIC;ElMessage({type: 'error',duration: 2 * 1000,message: '无效的策略类型'});return;}fetchStrategy();
});
provide('enums', enums);
</script><style lang="scss" scoped>
.strategy-edit {width: 900px;margin: 0 auto;.indent-form-item {margin-left: 150px;}
}.group-number {display: flex;> div:first-child {margin-right: 30px;}
}.uploader-wrapper {margin: 24px 0;> div {display: flex;::v-deep .el-upload {width: 80px;height: 80px;margin-right: 16px;border-radius: 0;.el-upload-dragger {background: #f7f8fa;border: none;border-radius: 0;}}}
}.uploader-tip {font-size: 12px;color: #969799;line-height: 1.2;margin-top: 10px;
}.normal-text {color: var(--el-text-color-regular);
}
.ps {color: #999;padding-left: 50px;
}
</style>
.ps {color: #999;padding-left: 50pxpx;
}
  1、代码规范2、注释3、优雅的代码(冗余度,命名)4、开发文档非常重要1、及时沟通,反馈,不要让上级找你

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/322492.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java并发编程面试题(2020最新版)

转载自 Java并发编程面试题&#xff08;2020最新版&#xff09; 基础知识 并发编程的优缺点 为什么要使用并发编程&#xff08;并发编程的优点&#xff09; 充分利用多核CPU的计算能力&#xff1a;通过并发编程的形式可以将多核CPU的计算能力发挥到极致&#xff0c;性能得到…

.NET Core容器化之多容器应用部署@Docker-Compose

1.引言紧接上篇.NET Core容器化Docker&#xff0c;这一节我们先来介绍如何使用Nginx来完成.NET Core应用的反向代理&#xff0c;然后再介绍多容器应用的部署问题。2. Why Need Nginx.NET Core中默认的Web Server为Kestrel。Kestrel is great for serving dynamic content from …

ServerSuperIO Designer IDE 发布,打造物联网通讯大脑,随心而联。附:C#驱动源代码。

1.概况注&#xff1a;ServerSuperIO Designer IDE 同行业网友随便使用&#xff0c;不涉及到软件使用限制的问题。从2015年到现在的将近两年的时间&#xff0c;一直在开发、完善ServerSuperIO&#xff08;SSIO&#xff09;的基础框架&#xff0c;包括&#xff1a;多通讯机制、稳…

MySQL数据库面试题(2020最新版)

转载自 MySQL数据库面试题&#xff08;2020最新版&#xff09; 数据库基础知识 为什么要使用数据库 数据保存在内存 优点&#xff1a;存取速度快 缺点&#xff1a;数据不能永久保存 数据保存在文件 优点&#xff1a;数据永久保存 缺点&#xff1a;1&#xff09;速度比内…

分布式系统的消息服务模式简单总结

在一个分布式系统中&#xff0c;有各种消息的处理&#xff0c;有各种服务模式&#xff0c;有同步异步&#xff0c;有高并发问题甚至应对高并发问题的Actor编程模型&#xff0c;本文尝试对这些问题做一个简单思考和总结。一、消息的“推、拉模式” 在传统的Client/Server结构中&…

Spring Cloud面试题(2020最新版)

转载自 Spring Cloud面试题&#xff08;2020最新版&#xff09; 为什么需要学习Spring Cloud 不论是商业应用还是用户应用&#xff0c;在业务初期都很简单&#xff0c;我们通常会把它实现为单体结构的应用。但是&#xff0c;随着业务逐渐发展&#xff0c;产品思想会变得越来…

《Office 365 开发入门指南》

终于等来了这一天&#xff0c;可以为我的这本新书画上一个句号。我记得是在今年的2月份从西雅图回来之后&#xff0c;就萌发了要为中国的Office 365开发人员写一些东西并最终能帮到更多中国用户的想法&#xff0c;而从2月26日正式写下了第一篇&#xff0c;到今天正好是整整十个…

助力中小企业级连云端,促进工业互联网平台蓬勃发展,全套解决方案。附:技术产品

1&#xff0e;概述经过两年多团体的努力&#xff0c;四个产品终于面世了&#xff0c;做产品不容易&#xff0c;做好产品更不容易&#xff0c;最终形成了体系化的解决方案。下面具体介绍。行业大数据平台以及工业互联网平台的发展是必然趋势&#xff0c;结合自己的工作经验&…

基于百度AI实现 车牌识别

前言目前百度的AI接口相对完善&#xff0c;对于文字识别类的操作还需要开发者一一去尝试&#xff0c;去评估这效果到底是怎么的。文字识别的接口相对简单&#xff0c;官方提供的SDK也集成很好&#xff0c;笔者只是在这上面做了一些前期性的功能数据校验和过滤&#xff0c;以及返…

面试官问我:Redis 内存满了怎么办

转载自 想不到&#xff01;面试官问我&#xff1a;Redis 内存满了怎么办 Redis占用内存大小 Redis的内存淘汰 LRU算法 LRU在Redis中的实现 LFU算法 问题 Redis占用内存大小 我们知道Redis是基于内存的key-value数据库&#xff0c;因为系统的内存大小有限&#xff0c;所以…

开源组件NanUI一周年 - 使用HTML/CSS/JS来构建.Net Winform应用程序界面

NanUI是什么NanUI基于ChromiumFX项目进行开发&#xff0c;它能让你在你的Winform应用程序中使用HTML5/CSS3/Javascript等网页技术来呈现用户界面&#xff08;类似Electron&#xff09;。同时NanUI提供了原生窗口和定制化的无标题栏无边框窗口&#xff0c;你能使用全部的网页技术…

ThreadPoolExecutor 八种拒绝策略,对的,不是4种

转载自 ThreadPoolExecutor 八种拒绝策略&#xff0c;对的&#xff0c;不是4种 前言 谈到 Java 的线程池最熟悉的莫过于 ExecutorService 接口了&#xff0c;jdk1.5 新增的 java.util.concurrent 包下的这个 api&#xff0c;大大的简化了多线程代码的开发。而不论你用 Fixed…

采用Opserver来监控你的ASP.NET项目系列(三、监控你的服务器状态)

前言之前有过2篇关于如何监控ASP.NET core项目的文章,有兴趣的也可以看看. ASP.NET Core之跨平台的实时性能监控ASP.NET Core之跨平台的实时性能监控(2.健康检查)今天我们主要来介绍一下,如何使用Opserver监控我们的服务器状态.Opserver的功能其实很强大,他可以用于连接任何支持…

Net Core中数据库事务隔离详解——以Dapper和Mysql为例

事务隔离级别.NET Core中的IDbConnection接口提供了BeginTransaction方法作为执行事务&#xff0c;BeginTransaction方法提供了两个重载&#xff0c;一个不需要参数BeginTransaction()默认事务隔离级别为RepeatableRead;另一个BeginTransaction(IsolationLevel il)可以根据业务…

2017年,我的身边发生了那些事?

不知不觉&#xff0c;运营独具.NET跨平台特色的微信公众号&#xff1a;dotNet跨平台至今已经整整三年光景了&#xff0c;这三年里微软开源.NET也满三周年了。三年时间说长不长&#xff0c;说短也不短了&#xff0c;然而我还是保持着每天三篇的更新 &#xff0c;或有感而原创&am…

ABP .Net Core Entity Framework迁移使用MySql数据库

一、迁移说明ABP模板项目Entity Framework Core默认使用的是Sql Server&#xff0c;也很容易将数据库迁移到MySQL&#xff0c;步骤如下。二、迁移MySQL步骤1、 下载项目请到 http://aspnetboilerplate.com/Templates 下载一个新的项目&#xff0c;选择ASP.NET Core 2.x标签&…

(四)十大经典排序算法(动画图解,代码完全)

排序算法是《数据结构与算法》中最基本的算法之一 1. 冒泡排序 1.1 算法步骤 比较相邻的元素。如果第一个比第二个大&#xff0c;就交换他们两个。 对每一对相邻元素作同样的工作&#xff0c;从开始第一对到结尾的最后一对。这步做完后&#xff0c;最后的元素会是最大的数。…

(五)SpringBoot 能挣钱的几个项目!!!

不得不佩服 Spring Boot 的生态如此强大&#xff0c;今天给大家推荐几款 Gitee 上优秀的后台开源版本的管理系统&#xff0c;小伙伴们再也不用从头到尾撸一个项目了&#xff0c;简直就是接私活&#xff0c;挣钱的利器啊。SmartAdmin我们开源一套漂亮的代码和一套整洁的代码规范…

手把手引进门之 ASP.NET Core Entity Framework Core(官方教程翻译版 版本3.2.5)

以下是手把手引进门教程&#xff0c;基于 ASP.NET Core&#xff0c; Entity Framework Core &#xff0c;ABP 框架 创建Web 应用&#xff0c; PS&#xff1a; 自带自动的测试模块哦。样例下载 &#xff08;上 github 的请自便&#xff09;介绍这是系列文章的第一部分&#xff1…

图像识别:微信跳一跳机器人

准备IDE&#xff1a;VisualStudioLanguage&#xff1a;VB.NET/C#GitHub&#xff1a;AutoJump.NET本文将向你介绍一种通过图像识别实现“跳一跳”机器人的方法。 第一节 图像识别文中提到的所有方法和步骤均仅涉及简单的向量计算。需要哪些计算&#xff1f;比较像素点的颜色求向…