| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882 |
- <script setup lang="ts">
- import { ref, computed, nextTick, h, watch, onMounted } from 'vue';
- import { notification } from 'ant-design-vue';
- import { getDictionaryMethod } from '@/request/api/dictionary.api';
- import { UploadIFile } from '@/request/api/follow.api';
- import type { UploadFile } from 'ant-design-vue/es/upload/interface';
- import { message } from 'ant-design-vue';
- import {
- pageMedicineMethod,
- pageDiagnoseTypeMethod,
- addSystemCwMethod,
- addOrgCwMethod,
- getConditioningRecordDetailMethod,
- getAllSystemCpMethod,
- getCpContentListMethod,
- } from '@/request/api/care.api';
- import RemoteSelect from '@/libs/v-select-page/RemoteSelect.vue';
- import { usePagination, useRequest } from 'alova/client';
- import 'ant-design-vue/dist/reset.css';
- import type { SystemCwModel } from '@/model/care.model';
- import AcupointEdit from '@/service/AcupointEdit.vue';
- import ServiceDetail from '@/service/ServiceDetail.vue';
- import ServicePackageList from '@/service/ServicePackageList.vue';
- import { MinusCircleOutlined, EyeOutlined, PlusOutlined } from '@ant-design/icons-vue';
- import { VxeUI } from 'vxe-pc-ui';
- type FollowModel = Partial<SystemCwModel>;
- const props = defineProps<{ data: FollowModel }>();
- const fileList = ref<UploadFile[]>([]);
- const uploadProps = reactive({ showRemoveIcon: true });
- const emit = defineEmits<{ submit: [data?: SystemCwModel] }>();
- const { loading: addSystemCwLoading, send: addSystemCw } = useRequest(addSystemCwMethod, {
- immediate: false,
- }).onSuccess(({ data }) => {
- emit('submit');
- });
- const { loading: addOrgCwLoading, send: addOrgCw } = useRequest(addOrgCwMethod, {
- immediate: false,
- }).onSuccess(({ data }) => {
- emit('submit');
- });
- const localData = reactive({ ...props.data }); // Create a local copy of props.data
- const formData = reactive<FollowModel>({
- name: '', //服务包名称
- price: 0, //总计价格
- conditioningWrapPatientMatchRule: {
- sex: '',
- age: '',
- diagnoseDiseaseNames: [],
- diagnoseSyndromeNames: [],
- constitutionGroupNames: [],
- willillStateNames: [],
- },
- cwPatientMatchRules: [
- {
- diagnoseDiseaseNames: [],
- diagnoseSyndromeNames: [],
- constitutionGroupNames: [],
- diagnoseDisease: {
- id: '',
- code: '',
- name: '',
- optionalWords: '',
- attributes: [],
- children: [],
- },
- diagnoseSyndrome: {
- code: '',
- name: '',
- analysis: '',
- remark: '',
- },
- constitutionGroup: {
- id: '',
- code: '',
- name: '',
- definition: '',
- remark: '',
- },
- },
- ], // 适用情况
- items: [], // Initialize as empty array
- });
- const emptyRow = {
- id: '',
- conditioningWrapId: '',
- conditioningProgramId: 0,
- days: '',
- frequencyType: '',
- frequencyTypeing: [],
- frequencyMeasure: '',
- totalMeasure: '',
- totalPrice: '',
- initialDay: '',
- conditioningProgramDetail: {
- id: '',
- name: '',
- conditioningProgramType: '',
- pricingType: '',
- cpFixedPricingRule: {
- unitPrice: 0,
- pricingUnit: '',
- convertDose: 0,
- convertUnit: '',
- },
- cpDynamicPricingRule: [],
- cpMedicines: [],
- effect: '',
- isOffline: null,
- isDelivery: null,
- photo: '',
- institutionId: '',
- institutionName: '',
- remark: '',
- },
- cwcpAcuMeridians: [],
- cwcpAcuPoints: [],
- conditioningProgramSupplierName: '',
- };
- function getInstitutionProjectList() {
- const {
- loading: projectLoading,
- onSuccess,
- replace,
- refresh,
- remove,
- } = usePagination(() => getCpContentListMethod(), {
- initialData: { data: [] },
- immediate: true,
- });
- onSuccess(({ data }: any) => {
- allProjects.value = data;
- });
- }
- function getSystemProjectList() {
- const { loading: projectLoading, onSuccess } = useRequest(getAllSystemCpMethod, {
- immediate: true,
- });
- onSuccess(({ data }: any) => {
- allProjects.value = data;
- });
- }
- async function getProjectList() {
- if (localData.types === 'system') {
- getSystemProjectList();
- } else {
- getInstitutionProjectList();
- }
- }
- const totalPrice = computed(() => {
- return (formData.items ?? []).reduce((sum, row) => {
- const price = Number(row?.totalPrice) || 0;
- return sum + price;
- }, 0);
- });
- watch(totalPrice, (val) => {
- formData.price = val;
- });
- // function addSituation() {
- // if (!formData.cwPatientMatchRules) formData.cwPatientMatchRules = [];
- // formData.cwPatientMatchRules.push({
- // diagnoseDiseaseNames: [],
- // diagnoseSyndromeNames: [],
- // constitutionGroupNames: [],
- // diagnoseDisease: { id: '', code: '', name: '' },
- // diagnoseSyndrome: { code: '', name: '', analysis: '', remark: '' },
- // constitutionGroup: { id: '', code: '', name: '', definition: '', remark: '' },
- // });
- // }
- // function removeSituation(idx: number) {
- // if (formData.cwPatientMatchRules) {
- // formData.cwPatientMatchRules.splice(idx, 1);
- // }
- // }
- const projectSearch = ref('');
- const showProjectPopover = ref(false);
- const allProjects = ref<
- Array<{
- name: string;
- conditioningProgramType?: string;
- effect?: string;
- }>
- >([]);
- const filteredProjects = computed(() => {
- const searchText = projectSearch.value.toLowerCase();
- if (allProjects.value.length > 0) {
- return allProjects.value.filter(
- (p) => p.name.toLowerCase().includes(searchText) || p?.conditioningProgramType?.toLowerCase().includes(searchText) || p.effect?.toLowerCase().includes(searchText)
- );
- } else {
- return [];
- }
- });
- function onSelectProject({ row }: any) {
- if ((formData.items ?? []).some((item) => item.conditioningProgramDetail?.name === row.name)) {
- message.warning('不能重复添加该项目');
- return;
- }
- // 添加新行到主表格
- if (!formData.items) formData.items = [];
- formData.items.push({
- id: '',
- conditioningWrapId: '',
- conditioningProgramId: row.id,
- days: '',
- frequencyType: '',
- frequencyMeasure: '',
- totalMeasure: '',
- totalPrice: '',
- initialDay: '',
- cwcpAcuMeridians: row?.cwcpAcuMeridians ?? [],
- cwcpAcuPoints: row?.cwcpAcuPoints ?? [],
- conditioningProgramDetail: {
- ...row,
- id: row?.id || '',
- name: row?.name,
- conditioningProgramType: row?.conditioningProgramType,
- effect: row?.effect,
- pricingType: row?.pricingType,
- cpFixedPricingRule: {
- unitPrice: row?.cpFixedPricingRule?.unitPrice,
- pricingUnit: row?.cpFixedPricingRule?.pricingUnit,
- convertDose: row?.cpFixedPricingRule?.convertDose,
- convertUnit: row?.cpFixedPricingRule?.convertUnit,
- },
- cpDynamicPricingRule: row?.cpDynamicPricingRule,
- cpMedicines: row?.cpMedicines,
- isOffline: row?.isOffline,
- isDelivery: row?.isDelivery,
- photo: row?.photo,
- conditioningProgramSupplierName: row?.conditioningProgramSupplierName,
- },
- remark: row?.remark,
- });
- // 关闭弹窗
- showProjectPopover.value = false;
- // 清空搜索
- projectSearch.value = '';
- }
- // 预览
- function onPreview(row) {
- if (row.conditioningProgramDetail.id) {
- // 这里写你的预览逻辑
- VxeUI.modal.open({
- title: `预览`,
- height: 600,
- width: 950,
- escClosable: true,
- destroyOnClose: true,
- id: `preview-modal`,
- remember: true,
- storage: true,
- slots: {
- default() {
- return h(ServiceDetail, {
- data: row.conditioningProgramDetail,
- onSubmit: (data) => {
- VxeUI.modal.close(`preview-modal`);
- },
- });
- },
- },
- });
- } else {
- message.warning('请先添加服务包');
- }
- }
- function detailPreview(row: any) {
- if (row.id) {
- // 这里写你的预览逻辑
- VxeUI.modal.open({
- title: `预览`,
- height: 600,
- width: 950,
- escClosable: true,
- destroyOnClose: true,
- id: `preview-modal`,
- remember: true,
- storage: true,
- slots: {
- default() {
- return h(ServiceDetail, {
- data: row,
- onSubmit: (data) => {
- VxeUI.modal.close(`preview-modal`);
- },
- });
- },
- },
- });
- showProjectPopover.value = false;
- } else {
- message.warning('请先添加服务包');
- }
- }
- function editPart(row) {
- if (row.conditioningProgramDetail.id) {
- VxeUI.modal.open({
- title: `编辑部位`,
- height: 700,
- width: 750,
- escClosable: true,
- destroyOnClose: true,
- id: `edit-part-modal`,
- remember: true,
- storage: true,
- slots: {
- default() {
- return h(AcupointEdit, {
- data: row,
- onSubmit: (data) => {
- refresh(page.value);
- VxeUI.modal.close(`edit-part-modal`);
- },
- });
- },
- },
- });
- } else {
- message.warning('请先添加服务包');
- }
- }
- // 添加计算数量的函数
- function calculateCount(row: any) {
- const pricingType = row.conditioningProgramDetail.pricingType;
- const period = Number(row.days) || 0;
- const frequency = Number(row.frequencyMeasure) || 0;
- // 一口价
- if (pricingType === '0') {
- // 检查是否选择了"不限"
- if (row.frequencyType === '不限') {
- row.frequencyMeasure = ''; // 重置 frequencyMeasure
- row.totalMeasure = 1;
- } else {
- const frequencyType = Number(row.frequencyType) || 0;
- row.totalMeasure = Math.ceil(period / frequencyType) * frequency;
- }
- // 获取单价
- const unitPrice = Number(row.conditioningProgramDetail?.cpFixedPricingRule?.unitPrice) || 0;
- // 计算总价
- row.totalPrice = (row.totalMeasure * unitPrice).toFixed(2);
- } else if (pricingType === '1') {
- // 按穴位计价
- row.totalPrice =
- row.conditioningProgramDetail?.cpDynamicPricingRule?.reduce((sum: number, item: any) => {
- return sum + (Number(item.price) || 0);
- }, 0) || 0;
- }
- }
- // 添加监听器
- watch(
- () => formData.items,
- (newData) => {
- if (!newData) return;
- newData.forEach((row) => {
- if (row?.days || row?.frequencyType || row?.frequencyMeasure) {
- calculateCount(row);
- }
- });
- },
- { deep: true }
- );
- function cancel() {
- VxeUI.modal.close(`edit-system-service-modal`);
- }
- function confirm() {
- const isValid = (formData.items ?? []).every((item: any) => {
- delete item.id; // 删除 id 属性
- if (item?.conditioningProgramDetail && item?.conditioningProgramDetail?.pricingType === '1') {
- // 确保 cwcpAcuMeridians 和 cwcpAcuPoints 存在
- const hasMeridians = item.cwcpAcuMeridians?.length > 0; // 使用可选链
- const hasPoints = item.cwcpAcuPoints?.length > 0; // 使用可选链
- // 只要有一个长度大于0,就满足条件
- if (!hasMeridians && !hasPoints) {
- // 如果两个都没有,显示提示
- message.warning('请至少选择一个穴位或经络');
- return false; // 返回 false 表示条件不满足
- }
- }
- return true; // 返回 true 表示条件满足
- });
- formData?.items?.forEach((row: any) => {
- if (row.frequencyTypeing && row.frequencyTypeing.length > 0) {
- row.frequencyType = row.frequencyTypeing[0];
- }
- });
- console.log(localData.types, 'formData.items');
- // 如果所有条件都满足,继续执行后续代码
- if (isValid) {
- // 系统服务包
- if (localData.types === 'system') {
- delete formData.types;
- addSystemCw({
- ...formData,
- }).then((res) => {
- notification.success({ message: '操作成功' });
- VxeUI.modal.close(`edit-system-service-modal`);
- });
- } else if (localData.types === 'institution') {
- if (fileList.value.length > 0) {
- const upImg = fileList.value[0].response?.url;
- formData.photo = upImg;
- fileList.value = upImg
- ? [
- {
- uid: '-1',
- name: 'image.png',
- status: 'done',
- url: upImg,
- thumbUrl: upImg,
- response: { url: upImg },
- },
- ]
- : [];
- }
- addOrgCw({
- ...formData,
- }).then((res) => {
- notification.success({ message: '操作成功' });
- VxeUI.modal.close(`edit-system-service-modal`);
- });
- }
- }
- }
- // 欲病状态
- const desiredConditions = ref<{ id: string; name: string }[]>([]);
- const constitutionGroups = ref<{ id: string; name: string }[]>([]);
- async function getDesiredConditions() {
- const res = await getDictionaryMethod('conditioning_wrap_willill_state');
- if (res?.length > 0) {
- desiredConditions.value = res.map((item: any) => ({
- id: item.value,
- name: item.label,
- }));
- }
- }
- // 获取性别
- const genders = ref<{ id: string; name: string }[]>([]);
- async function getGender() {
- const res = await getDictionaryMethod('sys_user_sex');
- if (res && res.length > 0) {
- genders.value = res.map((item: any) => ({
- id: item.label,
- name: item.label,
- }));
- } else {
- console.log('性别数据未获取到');
- }
- }
- // 获取年龄
- const ages = ref<{ id: string; name: string }[]>([]);
- async function getAge() {
- const res = await getDictionaryMethod('conditioning_wrap_rule_age');
- if (res && res.length > 0) {
- ages.value = res.map((item: any) => ({
- id: item.label,
- name: item.label,
- }));
- }
- }
- async function getConstitutionGroup() {
- const res = await getDictionaryMethod('constitution_group');
- if (res && res.length > 0) {
- constitutionGroups.value = res.map((item: any) => ({
- id: item.value,
- name: item.label,
- }));
- }
- }
- onMounted(async () => {
- getDesiredConditions();
- getGender();
- getAge();
- getConstitutionGroup();
- if (localData.id) {
- localData.types = 'institution'; // Modify the local copy instead
- // 调编辑接口获取数据
- const res: any = await getConditioningRecordDetailMethod(localData);
- Object.assign(formData, res); // Use the response to update formData
- await nextTick(); // 确保视图更新
- formData.conditioningWrapPatientMatchRule = res?.conditioningWrapPatientMatchRule ?? {
- sex: '',
- age: '',
- diagnoseDiseaseNames: [],
- diagnoseSyndromeNames: [],
- constitutionGroupNames: [],
- willillStateNames: [],
- };
- formData.items = res?.items ?? [];
- fileList.value = res?.photo
- ? [
- {
- uid: '-1',
- name: 'image.png',
- status: 'done',
- url: res?.photo,
- thumbUrl: res?.photo,
- },
- ]
- : [];
- formData?.items?.forEach((row: any) => {
- row.frequencyTypeing = row.frequencyType ? [row.frequencyType] : [];
- });
- }
- await getProjectList();
- console.log(formData.items, 'formData');
- });
- const tableData = computed(() => {
- console.log(formData.items, 'formData.items');
- return [...(formData.items ?? []), { ...emptyRow }];
- });
- function removeTableRow(idx: number) {
- if (idx < (formData.items ?? []).length) {
- formData.items?.splice(idx, 1);
- }
- }
- // 引入服务包
- function addInstitution() {
- VxeUI.modal.open({
- title: '选择引入',
- width: 1000,
- height: 700,
- escClosable: true,
- destroyOnClose: true,
- id: `systemService-list-modal`,
- remember: true,
- storage: true,
- slots: {
- default() {
- return h(ServicePackageList, {
- data: formData,
- onSubmit(data: SystemCwModel) {
- VxeUI.modal.close(`systemService-list-modal`);
- },
- });
- },
- },
- });
- }
- function customUpload(e: any) {
- // 二次封装上传接口
- UploadIFile(e.file)
- .then((res) => {
- // 文件上传成功
- e.onSuccess(res, e);
- })
- .catch((err) => {
- // 文件上传失败
- e.onError(err);
- });
- }
- const visible = ref<boolean>(false);
- const setVisible = (value: boolean): void => {
- visible.value = value;
- };
- const previewImg = ref<string>('');
- // 预览图片
- const handlePreview = async (file: UploadFile) => {
- previewImg.value = file.response?.url ?? file.thumbUrl;
- visible.value = true;
- };
- let multiple = ref<boolean>(true);
- </script>
- <template>
- <div style="padding: 24px">
- <div class="flex">
- <div style="margin-bottom: 16px" class="mr-4" v-if="localData?.types === 'institution'">
- <span>机构名称:</span>
- <a-input style="width: 200px" v-model:value="formData.institutionName" />
- </div>
- <div style="margin-bottom: 16px" class="mr-6">
- <span>服务包名称:</span>
- <a-input style="width: 200px" v-model:value="formData.name" />
- <a-button type="primary" @click="addInstitution" class="ml-4" v-if="localData?.types === 'institution'">引入</a-button>
- </div>
- <div class="flex" v-if="localData?.types === 'institution'">
- <div class="w-35">服务形象照:</div>
- <a-upload
- :showUploadList="uploadProps"
- v-model:file-list="fileList"
- name="avatar"
- list-type="picture-card"
- class="avatar-uploader"
- @preview="handlePreview"
- :maxCount="1"
- action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
- :customRequest="customUpload"
- >
- <div v-if="fileList.length < 1">
- <plus-outlined />
- </div>
- </a-upload>
- </div>
- </div>
- <div style="margin-bottom: 16px">
- <div class="mb-3">适用情况</div>
- <div class="flex items-center mb-3">
- <span class="w-20">使用限制</span>
- <div class="mr-10">
- <span>性别:</span>
- <a-select placeholder="请选择" v-model:value="formData.conditioningWrapPatientMatchRule.sex" style="width: 150px; margin: 0 5px" allowClear>
- <a-select-option v-for="option in genders" :key="option.id" :value="option.id" placeholder="请选择">
- {{ option.name }}
- </a-select-option>
- </a-select>
- </div>
- <div>
- <span>年龄:</span>
- <a-select v-model:value="formData.conditioningWrapPatientMatchRule.age" style="width: 150px; margin: 0 8px" placeholder="请选择" allowClear>
- <a-select-option v-for="option in ages" :key="option.id" :value="option.id" placeholder="请选择">{{ option.name }}</a-select-option>
- </a-select>
- </div>
- </div>
- <div class="flex items-center">
- <span class="w-20">适用</span>
- <div class="mr-10 flex items-center">
- <span>专病:</span>
- <RemoteSelect
- :load="pageMedicineMethod"
- key-prop="name"
- v-model:value="formData.conditioningWrapPatientMatchRule.diagnoseDiseaseNames"
- style="margin: 0 8px"
- :multiple="multiple"
- />
- </div>
- <div class="mr-10 flex items-center">
- <span>证型:</span>
- <RemoteSelect
- :load="pageDiagnoseTypeMethod"
- key-prop="name"
- v-model:value="formData.conditioningWrapPatientMatchRule.diagnoseSyndromeNames"
- style="margin: 0 8px"
- :multiple="multiple"
- />
- </div>
- <div class="flex items-center mr-10">
- <span>体质:</span>
- <a-select
- v-model:value="formData.conditioningWrapPatientMatchRule.constitutionGroupNames"
- style="width: 120px; margin: 0 8px"
- placeholder="请选择"
- allowClear
- mode="multiple"
- >
- <a-select-option v-for="option in constitutionGroups" :key="option.id" :value="option.id" placeholder="请选择">{{ option.name }}</a-select-option>
- </a-select>
- </div>
- <div>
- <span>欲病状态:</span>
- <a-select
- v-model:value="formData.conditioningWrapPatientMatchRule.willillStateNames"
- style="width: 120px; margin: 0 8px"
- placeholder="请选择"
- allowClear
- mode="multiple"
- @change="(value) => (formData.conditioningWrapPatientMatchRule.willillStateNames = value)"
- >
- <a-select-option v-for="option in desiredConditions" :key="option.id" :value="option.id" placeholder="请选择">{{ option.name }}</a-select-option>
- </a-select>
- </div>
- </div>
- <!-- <div v-for="(item, idx) in formData.cwPatientMatchRules" :key="idx" style="display: flex; align-items: center; margin-bottom: 8px">
- <span>情况{{ idx + 1 }} 专病:</span>
- <RemoteSelect :load="pageMedicineMethod" key-prop="name" v-model:value="item.diagnoseDisease" style="margin: 0 8px" :multiple="multiple"/>
- <span>且 证型:</span>
- <RemoteSelect :load="pageDiagnoseTypeMethod" key-prop="name" v-model:value="item.diagnoseSyndrome.name" style="margin: 0 8px" :multiple="multiple" />
- <span>且 体质:</span>
- <a-select v-model="item.constitutionGroup" style="width: 120px; margin: 0 8px" placeholder="请选择" allowClear mode="multiple">
- <a-select-option v-for="option in constitutionGroups" :key="option.id" :value="option.id" placeholder="请选择">{{ option.name }}</a-select-option>
- </a-select>
- <a-button v-if="(formData.cwPatientMatchRules?.length ?? 0) > 1" @click="removeSituation(idx)" type="text" danger>
- <MinusCircleOutlined />
- </a-button>
- <a-button v-if="idx === (formData.cwPatientMatchRules?.length ?? 0) - 1" @click="addSituation" type="text">
- <PlusCircleOutlined />
- </a-button>
- </div> -->
- </div>
- <div style="margin-bottom: 16px">
- <span>服务包内容</span>
- <vxe-table :data="tableData" border style="margin-top: 8px">
- <vxe-column width="60" title="">
- <template #default="{ rowIndex }">
- <a-button type="text" danger @click="removeTableRow(rowIndex)" :disabled="rowIndex === tableData.length - 1">
- <MinusCircleOutlined />
- </a-button>
- </template>
- </vxe-column>
- <vxe-column field="conditioningProgramDetail.name" title="项目名称" width="180">
- <template #default="{ row, rowIndex }">
- <template v-if="rowIndex === tableData.length - 1">
- <a-popover v-model:open="showProjectPopover" trigger="click" placement="bottomLeft" :overlayStyle="{ width: '350px', padding: 0 }">
- <template #content>
- <a-input v-model:value="projectSearch" placeholder="输入项目名称搜索" style="margin: 8px; width: 90%" @input="() => nextTick()" />
- <vxe-table :data="filteredProjects" border size="small" style="max-height: 240px; overflow-y: auto" @cell-click="onSelectProject">
- <vxe-column field="name" title="项目名称" />
- <vxe-column field="conditioningProgramType" title="方案类型" />
- <vxe-column field="effect" title="功效" />
- <vxe-column title="预览" width="60">
- <template #default="{ row }">
- <EyeOutlined style="font-size: 18px; color: #1890ff; cursor: pointer" @click.stop="detailPreview(row)" />
- </template>
- </vxe-column>
- </vxe-table>
- </template>
- <a-input v-model:value="row.name" placeholder="请搜索" style="width: 120px" @click="showProjectPopover = true" readonly />
- </a-popover>
- </template>
- <template v-else>
- {{ row.conditioningProgramDetail?.name }}
- </template>
- </template>
- </vxe-column>
- <vxe-column title="预览" width="50">
- <template #default="{ row }">
- <EyeOutlined style="font-size: 18px; color: #1890ff; cursor: pointer" @click="onPreview(row)" v-if="row?.conditioningProgramDetail?.id" />
- </template>
- </vxe-column>
- <vxe-column field="days" title="周期" width="100">
- <template #default="{ row }">
- <div style="display: flex; align-items: center">
- <a-input v-model:value="row.days" @change="() => calculateCount(row)" />
- <span>天</span>
- </div>
- </template>
- </vxe-column>
- <vxe-column field="frequencyType" title="频率" width="auto">
- <template #default="{ row }">
- <div v-if="row.conditioningProgramDetail?.name === '健康咨询' || row.conditioningProgramDetail?.name === '健康评估'" class="flex items-center">
- <div class="flex items-center mr-4">
- <span>每</span>
- <a-input v-model:value="row.frequencyType" style="width: 50px" @change="() => calculateCount(row)" :disabled="row.frequencyType === '不限'" />
- <span>天</span>
- <a-input v-model:value="row.frequencyMeasure" style="width: 50px" @change="() => calculateCount(row)" :disabled="row.frequencyType === '不限'" />
- <span>{{ row.conditioningProgramDetail?.cpFixedPricingRule?.convertUnit }}</span>
- </div>
- <div>
- <a-checkbox-group
- v-model:value="row.frequencyTypeing"
- @change="
- (value) => {
- row.frequencyTypeing = value.includes('不限') ? ['不限'] : [];
- row.frequencyType = value.includes('不限') ? '不限' : '';
- calculateCount(row);
- }
- "
- >
- <a-checkbox value="不限">不限</a-checkbox>
- </a-checkbox-group>
- </div>
- </div>
- <div class="flex items-center" v-else>
- <span>每</span>
- <a-input v-model:value="row.frequencyType" style="width: 50px" @change="() => calculateCount(row)" />
- <span>天</span>
- <a-input v-model:value="row.frequencyMeasure" style="width: 50px" @change="() => calculateCount(row)" />
- <span>{{ row.conditioningProgramDetail?.cpFixedPricingRule?.convertUnit }}</span>
- </div>
- </template>
- </vxe-column>
- <vxe-column field="row?.conditioningProgramDetail?.conditioningProgramType" title="方案类型" width="120">
- <template #default="{ row }">
- {{ row?.conditioningProgramDetail?.conditioningProgramType || '-' }}
- </template>
- </vxe-column>
- <vxe-column field="row.totalMeasure" title="数量" width="60">
- <template #default="{ row }">
- {{ row.totalMeasure || 0 }}
- </template>
- </vxe-column>
- <vxe-column field="row?.conditioningProgramDetail?.cpFixedPricingRule?.unit" title="单位" width="60">
- <template #default="{ row }">
- {{ row?.conditioningProgramDetail?.cpFixedPricingRule?.pricingUnit || '-' }}
- </template>
- </vxe-column>
- <vxe-column field="row.conditioningProgramDetail.cpFixedPricingRule.unitPrice" title="单价(元)" width="100">
- <template #default="{ row }">
- {{ row.conditioningProgramDetail?.cpFixedPricingRule?.unitPrice ?? '-' }}
- </template>
- </vxe-column>
- <vxe-column field="row.totalPrice" title="总价(元)" width="auto" @change="() => calculateCount(row)">
- <template #default="{ row }">
- <span>{{ row.totalPrice || 0 }}</span>
- </template>
- </vxe-column>
- <vxe-column field="start" title="开始时间" width="190">
- <template #default="{ row }">
- <div style="display: flex; align-items: center">
- <span>调养开始第</span>
- <a-input v-model:value="row.initialDay" style="width: 60px" />
- <span>天</span>
- </div>
- </template>
- </vxe-column>
- <vxe-column field="conditioningProgramDetail.isOffline" title="线下项目" width="100">
- <template #default="{ row }">
- <span v-if="row.conditioningProgramDetail?.isOffline">
- {{ row.conditioningProgramDetail.isOffline === 'Y' ? '是' : '否' }}
- </span>
- <span v-else>-</span>
- </template>
- </vxe-column>
- <vxe-column field="conditioningProgramDetail.pricingType" title="穴位/经络/部位" width="120">
- <template #default="{ row }">
- <!-- <a-input v-model:value="row.desc" style="width: 120px" /> -->
- <a @click="editPart(row)" style="color: #1890ff; cursor: pointer" @submit="editPart(row)" v-if="row?.conditioningProgramDetail?.pricingType === '1'">编辑</a>
- </template>
- </vxe-column>
- <vxe-column field="remark" title="说明" width="180">
- <template #default="{ row }">
- <a-textarea v-model:value="row.remark" style="max-width: 180px; width: 100%; height: 50px" :rows="2" show-count :maxLength="200" />
- </template>
- </vxe-column>
- </vxe-table>
- </div>
- <a-image
- :width="200"
- :style="{ display: 'none' }"
- :preview="{
- visible,
- onVisibleChange: setVisible,
- }"
- :src="previewImg"
- />
- <div style="display: flex; justify-content: flex-end">
- <span style="font-weight: bold">合计:{{ formData.price }}元</span>
- </div>
- <div style="display: flex; justify-content: center">
- <a-button style="margin-right: 24px" @click="cancel">取消</a-button>
- <a-button type="primary" @click="confirm">确认</a-button>
- </div>
- </div>
- </template>
- <style scoped lang="scss">
- /* 可根据实际需求自定义样式 */
- .v-dropdown-trigger {
- width: 160px !important;
- }
- .sp-trigger-container .sp-trigger.sp-select .sp-select-content {
- overflow: hidden !important;
- width: 100px !important;
- white-space: nowrap !important;
- text-overflow: ellipsis !important;
- }
- .avatar-uploader > .ant-upload {
- width: 128px;
- height: 128px;
- }
- .ant-upload-select-picture-card i {
- font-size: 32px;
- color: #999;
- }
- .ant-upload-select-picture-card .ant-upload-text {
- margin-top: 8px;
- color: #666;
- }
- </style>
|