Forráskód Böngészése

会员相关提交

longmh 11 hónapja
szülő
commit
3930728cbd

+ 20 - 0
src/api/dgtmedicine/approvalLog/index.ts

@@ -0,0 +1,20 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { ApprovalLogVO, ApprovalLogForm, ApprovalLogQuery } from '@/api/dgtmedicine/approvalLog/types';
+
+
+/**
+ * 入会申请
+ * @param data
+ */
+export const approvalMember = (data: ApprovalLogForm) => {
+  return request({
+    url: '/dgtmedicine/member/approval',
+    method: 'post',
+    data: data
+  });
+};
+
+
+
+

+ 96 - 0
src/api/dgtmedicine/approvalLog/types.ts

@@ -0,0 +1,96 @@
+export interface ApprovalLogVO {
+  /**
+   * ID
+   */
+  id: string | number;
+
+  /**
+   * 目标类型
+   */
+  targetType: string;
+
+  /**
+   * 目标id
+   */
+  targetId: string | number;
+
+  /**
+   * 结果
+   */
+  res: string;
+
+  /**
+   * 说明
+   */
+  msg: string;
+
+  /**
+   * 创建人
+   */
+  createBy: string;
+
+  /**
+   * 创建时间
+   */
+  createTime: string;
+
+  /**
+   * 更新时间
+   */
+  updateTime: string;
+
+}
+
+export interface ApprovalLogForm extends BaseEntity {
+  /**
+   * ID
+   */
+  id?: string | number;
+
+  /**
+   * 目标类型
+   */
+  targetType?: string;
+
+  /**
+   * 结果
+   */
+  reviewStatus?: string;
+
+  /**
+   * 说明
+   */
+  reviewMsg?: string;
+
+}
+
+export interface ApprovalLogQuery extends PageQuery {
+
+  /**
+   * 目标类型
+   */
+  targetType?: string;
+
+  /**
+   * 目标id
+   */
+  targetId?: string | number;
+
+  /**
+   * 结果
+   */
+  res?: string;
+
+  /**
+   * 说明
+   */
+  msg?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 87 - 0
src/api/dgtmedicine/member/index.ts

@@ -0,0 +1,87 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { MemberVO, MemberForm, MemberQuery,MemberLevelCountVO,vipLevelVO } from '@/api/dgtmedicine/member/types';
+
+/**
+ * 查询会员信息列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listMember = (query?: MemberQuery): AxiosPromise<MemberVO[]> => {
+  return request({
+    url: '/dgtmedicine/member/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询会员信息详细
+ * @param id
+ */
+export const getMember = (id: string | number): AxiosPromise<MemberVO> => {
+  return request({
+    url: '/dgtmedicine/member/getInfo/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增会员信息
+ * @param data
+ */
+export const addMember = (data: MemberForm) => {
+  return request({
+    url: '/dgtmedicine/member/add',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改会员信息
+ * @param data
+ */
+export const updateMember = (data: MemberForm) => {
+  return request({
+    url: '/dgtmedicine/member/edit',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 删除会员信息
+ * @param id
+ */
+export const delMember = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/dgtmedicine/member/remove/' + id,
+    method: 'get'
+  });
+};
+
+
+/**
+ * 会员等级统计
+ * @param id
+ */
+export const countLevelMember = (query?: MemberQuery): AxiosPromise<MemberLevelCountVO[]> => {
+  return request({
+    url: '/dgtmedicine/member/queryMemberCount',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 会员等级列表
+ * @param id
+ */
+export const vipLevelList = (): AxiosPromise<vipLevelVO[]> => {
+  return request({
+    url: '/dgtmedicine/vipLevel/list',
+    method: 'get'
+  });
+};

+ 467 - 0
src/api/dgtmedicine/member/types.ts

@@ -0,0 +1,467 @@
+export interface MemberVO {
+  /**
+   * ID
+   */
+  id: string | number;
+
+  /**
+   * 企业名称
+   */
+  cpyName: string;
+
+  /**
+   * 法人姓名
+   */
+  legalPersonName: string;
+
+  /**
+   * 法人电话
+   */
+  legalPersonPhone: string;
+
+  /**
+   * 法人职务
+   */
+  legalPersonPosition: string;
+
+  /**
+   * 法人身份证正面图片
+   */
+  legalPersonIdFront: string | number;
+
+  /**
+   * 法人身份证背面图片
+   */
+  legalPersonIdBack: string | number;
+
+  /**
+   * 公司证书图片
+   */
+  companyCertificate: string;
+
+  /**
+   * 邮箱
+   */
+  email: string;
+
+  /**
+   * 主管部门
+   */
+  department: string;
+
+  /**
+   * 总资产
+   */
+  totalAssets: string;
+
+  /**
+   * 单位简介
+   */
+  introduction: string;
+
+  /**
+   * 注册类型
+   */
+  regType: string;
+
+  /**
+   * 入会目的
+   */
+  membershipPurpose: string;
+
+  /**
+   * 种植信息
+   */
+  plantingInfo: string;
+
+  /**
+   * 当前会员等级
+   */
+  vipLevel: string;
+
+  /**
+ * 当前会员等级
+ */
+  vipLevelName: string;
+
+  /**
+   * 开始时间
+   */
+  startDate: string;
+
+  /**
+   * 结束时间
+   */
+  endDate: string;
+
+  /**
+   * 审核状态
+   */
+  reviewStatus: string;
+
+  /**
+   * 审核信息
+   */
+  reviewMsg: string;
+
+  /**
+   * 审核人
+   */
+  reviewBy: string;
+
+  /**
+   * 审核时间
+   */
+  reviewTime: string;
+
+  /**
+   * 合作伙伴ID
+   */
+  partnerId: string | number;
+
+  /**
+   * 创建人
+   */
+  createBy: string;
+
+  /**
+   * 创建时间
+   */
+  createTime: string;
+
+  /**
+   * 更新时间
+   */
+  updateTime: string;
+
+  /**
+   * 企业业务类型
+   */
+  cpyBusType: string;
+
+  /**
+   * 申请会员等级
+   */
+  applyLevel: string;
+
+
+  /**
+   * 申请会员等级
+   */
+  applyLevelName: string;
+
+}
+
+
+export interface MemberLevelCountVO {
+
+  /**
+    * 名称
+    */
+  name: string;
+
+  /**
+   * 类型
+   */
+  type: string;
+
+  /**
+   * 数量
+   */
+  num: number;
+
+}
+
+export interface vipLevelVO {
+
+    /**
+     * ID
+     */
+     id: string | number;
+
+    /**
+     * 等级名称
+     */
+     vipName:string;
+
+    /**
+     * 等级编码
+     */
+     vipCode:string;
+
+    /**
+     * 等级
+     */
+     vipLevel:string;
+
+    /**
+     * 年费
+     */
+     feeStandard:string;
+
+}
+
+
+export interface MemberForm extends BaseEntity {
+  /**
+   * ID
+   */
+  id?: string | number;
+
+  /**
+   * 企业名称
+   */
+  cpyName?: string;
+
+  /**
+   * 法人姓名
+   */
+  legalPersonName?: string;
+
+  /**
+   * 法人电话
+   */
+  legalPersonPhone?: string;
+
+  /**
+   * 法人职务
+   */
+  legalPersonPosition?: string;
+
+  /**
+   * 法人身份证正面图片
+   */
+  legalPersonIdFront?: string;
+
+  /**
+   * 法人身份证背面图片
+   */
+  legalPersonIdBack?: string;
+
+  /**
+   * 公司证书图片
+   */
+  companyCertificate?: any;
+
+  /**
+   * 邮箱
+   */
+  email?: string;
+
+  /**
+   * 主管部门
+   */
+  department?: string;
+
+  /**
+   * 总资产
+   */
+  totalAssets?: string;
+
+  /**
+   * 单位简介
+   */
+  introduction?: string;
+
+  /**
+   * 注册类型
+   */
+  regType?: string;
+
+  /**
+   * 入会目的
+   */
+  membershipPurpose?: string;
+
+  /**
+   * 种植信息
+   */
+  plantingInfo?: any[];
+
+  /**
+   * 当前会员等级
+   */
+  vipLevel?: string;
+
+  /**
+   * 开始时间
+   */
+  startDate?: string;
+
+  /**
+   * 结束时间
+   */
+  endDate?: string;
+
+  /**
+   * 审核状态
+   */
+  reviewStatus?: string;
+
+  /**
+   * 审核信息
+   */
+  reviewMsg?: string;
+
+  /**
+   * 审核人
+   */
+  reviewBy?: string;
+
+  /**
+   * 审核时间
+   */
+  reviewTime?: string;
+
+  /**
+   * 合作伙伴ID
+   */
+  partnerId?: string | number;
+
+  /**
+   * 企业业务类型
+   */
+  cpyBusType?: string;
+
+  /**
+   * 申请会员等级
+   */
+  applyLevel?: string;
+
+}
+
+export interface MemberQuery extends PageQuery {
+
+  /**
+   * 企业名称
+   */
+  cpyName?: string;
+
+  /**
+   * 法人姓名
+   */
+  legalPersonName?: string;
+
+  /**
+   * 法人电话
+   */
+  legalPersonPhone?: string;
+
+  /**
+   * 法人职务
+   */
+  legalPersonPosition?: string;
+
+  /**
+   * 法人身份证正面图片
+   */
+  legalPersonIdFront?: string | number;
+
+  /**
+   * 法人身份证背面图片
+   */
+  legalPersonIdBack?: string | number;
+
+  /**
+   * 公司证书图片
+   */
+  companyCertificate?: string;
+
+  /**
+   * 邮箱
+   */
+  email?: string;
+
+  /**
+   * 主管部门
+   */
+  department?: string;
+
+  /**
+   * 总资产
+   */
+  totalAssets?: string;
+
+  /**
+   * 单位简介
+   */
+  introduction?: string;
+
+  /**
+   * 注册类型
+   */
+  regType?: string;
+
+  /**
+   * 入会目的
+   */
+  membershipPurpose?: string;
+
+  /**
+   * 种植信息
+   */
+  plantingInfo?: string;
+
+  /**
+   * 当前会员等级
+   */
+  vipLevel?: string;
+
+  /**
+   * 开始时间
+   */
+  startDate?: string;
+
+  /**
+   * 结束时间
+   */
+  endDate?: string;
+
+  /**
+   * 审核状态
+   */
+  reviewStatus?: string;
+
+  /**
+   * 范围
+   */
+  dateRange?: string;
+
+  /**
+   * 审核信息
+   */
+  reviewMsg?: string;
+
+  /**
+   * 审核人
+   */
+  reviewBy?: string;
+
+  /**
+   * 审核时间
+   */
+  reviewTime?: string;
+
+  /**
+   * 合作伙伴ID
+   */
+  partnerId?: string | number;
+
+  /**
+   * 企业业务类型
+   */
+  cpyBusType?: string;
+
+  /**
+   * 申请会员等级
+   */
+  applyLevel?: string;
+
+  /**
+   * 日期范围参数
+   */
+  params?: any;
+}
+
+
+

+ 75 - 0
src/api/dgtmedicine/vipPayment/index.ts

@@ -0,0 +1,75 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { VipPaymentVO, VipPaymentForm, VipPaymentQuery } from '@/api/dgtmedicine/vipPayment/types';
+
+/**
+ * 查询会员缴费记录列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listVipPayment = (query?: VipPaymentQuery): AxiosPromise<VipPaymentVO[]> => {
+  return request({
+    url: '/dgtmedicine/vipPayment/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询会员缴费记录详细
+ * @param id
+ */
+export const getVipPayment = (id: string | number): AxiosPromise<VipPaymentVO> => {
+  return request({
+    url: '/dgtmedicine/vipPayment/getInfo/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增会员缴费记录
+ * @param data
+ */
+export const addVipPayment = (data: VipPaymentForm) => {
+  return request({
+    url: '/dgtmedicine/vipPayment/add',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改会员缴费记录
+ * @param data
+ */
+export const updateVipPayment = (data: VipPaymentForm) => {
+  return request({
+    url: '/dgtmedicine/vipPayment/edit',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 上传发票
+ * @param data
+ */
+export const uploadInvoice = (data: { id:  string | number, invoiceUrl: String }) => {
+  return request({
+    url: '/dgtmedicine/vipPayment/uploadInvoice',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 删除会员缴费记录
+ * @param id
+ */
+export const delVipPayment = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/dgtmedicine/vipPayment/remove/' + id,
+    method: 'get'
+  });
+};

+ 206 - 0
src/api/dgtmedicine/vipPayment/types.ts

@@ -0,0 +1,206 @@
+export interface VipPaymentVO {
+  /**
+   * ID
+   */
+  id: string | number;
+
+  /**
+   * 会员id
+   */
+  memberId: string | number;
+
+  /**
+   * 缴费金额
+   */
+  paymentAmount: number;
+
+  /**
+   * 缴费时间
+   */
+  paymentTime: string;
+
+  /**
+   * 缴费方式
+   */
+  paymentType: string;
+
+  /**
+   * 缴费状态
+   */
+  paymentStatus: string;
+
+  /**
+   * 缴费备注
+   */
+  paymentRemark: string;
+
+  /**
+   * 开票状态
+   */
+  invoiceStatus: string;
+
+  /**
+   * 发票地址
+   */
+  invoiceUrl: string;
+
+  /**
+   * 企业id
+   */
+  cpyid: string | number;
+
+  /**
+   * 应用id
+   */
+  appid: string | number;
+
+  /**
+   * 合作伙伴ID
+   */
+  partnerId: string | number;
+
+  /**
+   * 创建人
+   */
+  createBy: string;
+
+  /**
+   * 创建时间
+   */
+  createTime: string;
+
+  /**
+   * 更新时间
+   */
+  updateTime: string;
+
+}
+
+export interface VipPaymentForm extends BaseEntity {
+  /**
+   * ID
+   */
+  id?: string | number;
+
+  /**
+   * 会员id
+   */
+  memberId?: string | number;
+
+  /**
+   * 缴费金额
+   */
+  paymentAmount?: number;
+
+  /**
+   * 缴费时间
+   */
+  paymentTime?: string;
+
+  /**
+   * 缴费方式
+   */
+  paymentType?: string;
+
+  /**
+   * 缴费状态
+   */
+  paymentStatus?: string;
+
+  /**
+   * 缴费备注
+   */
+  paymentRemark?: string;
+
+  /**
+   * 开票状态
+   */
+  invoiceStatus?: string;
+
+  /**
+   * 发票地址
+   */
+  invoiceUrl?: string;
+
+  /**
+   * 企业id
+   */
+  cpyid?: string | number;
+
+  /**
+   * 应用id
+   */
+  appid?: string | number;
+
+  /**
+   * 合作伙伴ID
+   */
+  partnerId?: string | number;
+
+}
+
+export interface VipPaymentQuery extends PageQuery {
+
+  /**
+   * 会员id
+   */
+  memberId?: string | number;
+
+  /**
+   * 缴费金额
+   */
+  paymentAmount?: number;
+
+  /**
+   * 缴费时间
+   */
+  paymentTime?: string;
+
+  /**
+   * 缴费方式
+   */
+  paymentType?: string;
+
+  /**
+   * 缴费状态
+   */
+  paymentStatus?: string;
+
+  /**
+   * 缴费备注
+   */
+  paymentRemark?: string;
+
+  /**
+   * 开票状态
+   */
+  invoiceStatus?: string;
+
+  /**
+   * 发票地址
+   */
+  invoiceUrl?: string;
+
+  /**
+   * 企业id
+   */
+  cpyid?: string | number;
+
+  /**
+   * 应用id
+   */
+  appid?: string | number;
+
+  /**
+   * 合作伙伴ID
+   */
+  partnerId?: string | number;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 91 - 0
src/api/global.d.ts

@@ -0,0 +1,91 @@
+import type { ComponentInternalInstance as ComponentInstance, PropType as VuePropType } from 'vue';
+
+declare global {
+  /** vue Instance */
+  declare type ComponentInternalInstance = ComponentInstance;
+  /**vue */
+  declare type PropType<T> = VuePropType<T>;
+
+  /**
+   * 界面字段隐藏属性
+   */
+  declare interface FieldOption {
+    key: number;
+    label: string;
+    visible: boolean;
+    children?: Array<FieldOption>;
+  }
+
+  /**
+   * 弹窗属性
+   */
+  declare interface DialogOption {
+    /**
+     * 弹窗标题
+     */
+    title?: string;
+    /**
+     * 是否显示
+     */
+    visible: boolean;
+  }
+
+  declare interface UploadOption {
+    /** 设置上传的请求头部 */
+    headers: { [key: string]: any };
+
+    /** 上传的地址 */
+    url: string;
+  }
+
+  /**
+   * 导入属性
+   */
+  declare interface ImportOption extends UploadOption {
+    /** 是否显示弹出层 */
+    open: boolean;
+    /** 弹出层标题 */
+    title: string;
+    /** 是否禁用上传 */
+    isUploading: boolean;
+
+    /** 其他参数 */
+    [key: string]: any;
+  }
+  /**
+   * 字典数据  数据配置
+   */
+  declare interface DictDataOption {
+    label: string;
+    value: string;
+    elTagType?: ElTagType;
+    elTagClass?: string;
+  }
+
+  declare interface BaseEntity {
+    createBy?: any;
+    createDept?: any;
+    createTime?: string;
+    updateBy?: any;
+    updateTime?: any;
+  }
+
+  /**
+   * 分页数据
+   * T : 表单数据
+   * D : 查询参数
+   */
+  declare interface PageData<T, D> {
+    form: T;
+    queryParams: D;
+    rules: ElFormRules;
+  }
+  /**
+   * 分页查询参数
+   */
+  declare interface PageQuery {
+    pageNum?: number;
+    pageSize?: number;
+  }
+}
+export {};

+ 46 - 7
src/components/ImageUpload/index.vue

@@ -51,6 +51,8 @@ const props = defineProps({
     type: [String, Object, Array],
     default: () => []
   },
+  isString: propTypes.bool.def(false),
+
   // 图片数量限制
   limit: propTypes.number.def(5),
   // 大小限制(MB)
@@ -92,9 +94,27 @@ watch(
   async (val: string) => {
     if (val) {
       // 首先将值转为数组
-      let list: OssVO[] = [];
+      let list: any[] = [];
       if (Array.isArray(val)) {
-        list = val as OssVO[];
+        if (props.isString) {
+          list = val.map((item) => {
+            return {
+              url: item
+            };
+          });
+        } else {
+          list = val as OssVO[];
+        }
+      } else if (val.startsWith('http')) {
+        if (val.split(',').length > 0){
+          val.split(',').forEach((item) => {
+          list.push({ url: item });
+        });
+        }else {
+          list = [{
+            url: val
+          }];
+        }
       } else {
         const res = await listByIds(val);
         list = res.data;
@@ -170,7 +190,11 @@ const handleExceed = () => {
 // 上传成功回调
 const handleUploadSuccess = (res: any, file: UploadFile) => {
   if (res.code === 200) {
-    uploadList.value.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId });
+    if (props.isString) {
+      uploadList.value.push(res.data.url);
+    } else {
+      uploadList.value.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId });
+    }
     uploadedSuccessfully();
   } else {
     number.value--;
@@ -183,10 +207,17 @@ const handleUploadSuccess = (res: any, file: UploadFile) => {
 
 // 删除图片
 const handleDelete = (file: UploadFile): boolean => {
-  const findex = fileList.value.map((f) => f.name).indexOf(file.name);
+
+  if (props.isString) {
+    var findex = fileList.value.map((f) => f.url).indexOf(file.url);
+  }else {
+    var findex = fileList.value.map((f) => f.name).indexOf(file.name);
+  }
   if (findex > -1 && uploadList.value.length === number.value) {
     let ossId = fileList.value[findex].ossId;
-    delOss(ossId);
+    if (!props.isString) {
+      delOss(ossId);
+    }
     fileList.value.splice(findex, 1);
     emit('update:modelValue', listToString(fileList.value));
     return false;
@@ -197,7 +228,13 @@ const handleDelete = (file: UploadFile): boolean => {
 // 上传结束处理
 const uploadedSuccessfully = () => {
   if (number.value > 0 && uploadList.value.length === number.value) {
-    fileList.value = fileList.value.filter((f) => f.url !== undefined).concat(uploadList.value);
+    if (props.isString) {
+      uploadList.value.forEach((item) => {
+        fileList.value.push({ url: item });
+      });
+    } else {
+      fileList.value = fileList.value.filter((f) => f.url !== undefined).concat(uploadList.value);
+    }
     uploadList.value = [];
     number.value = 0;
     emit('update:modelValue', listToString(fileList.value));
@@ -222,7 +259,9 @@ const listToString = (list: any[], separator?: string) => {
   let strs = '';
   separator = separator || ',';
   for (let i in list) {
-    if (undefined !== list[i].ossId && list[i].url.indexOf('blob:') !== 0) {
+    if (props.isString) {
+      strs += list[i].url + separator;
+    } else if (undefined !== list[i].ossId && list[i].url.indexOf('blob:') !== 0) {
       strs += list[i].ossId + separator;
     }
   }

+ 1 - 1
src/layout/index.vue

@@ -73,7 +73,7 @@ onMounted(() => {
 });
 
 onMounted(() => {
-  initSSE(import.meta.env.VITE_APP_BASE_API + '/resource/sse');
+  // initSSE(import.meta.env.VITE_APP_BASE_API + '/resource/sse');
 });
 
 const handleClickOutside = () => {

+ 2 - 0
src/store/modules/dict.ts

@@ -1,3 +1,5 @@
+import { debug } from "console";
+
 export const useDictStore = defineStore('dict', () => {
   const dict = ref<Map<string, DictDataOption[]>>(new Map());
 

+ 17 - 6
src/utils/dict.ts

@@ -1,4 +1,5 @@
 import { getDicts } from '@/api/system/dict/data';
+import { vipLevelList } from '@/api/dgtmedicine/member';
 import { useDictStore } from '@/store/modules/dict';
 /**
  * 获取字典数据
@@ -14,12 +15,22 @@ export const useDict = (...args: string[]): { [key: string]: DictDataOption[] }
       if (dicts) {
         res.value[dictType] = dicts;
       } else {
-        await getDicts(dictType).then((resp) => {
-          res.value[dictType] = resp.data.map(
-            (p): DictDataOption => ({ label: p.dictLabel, value: p.dictValue, elTagType: p.listClass, elTagClass: p.cssClass })
-          );
-          useDictStore().setDict(dictType, res.value[dictType]);
-        });
+        if(dictType == 'vip_level'){
+          await vipLevelList().then((resp) => {
+            res.value[dictType] = resp.rows.map(
+              (p): DictDataOption => ({ label: p.vipName, value: p.vipLevel + '', elTagType: null, elTagClass: null })
+            );
+            useDictStore().setDict(dictType, res.value[dictType]);
+          });
+        }else{
+          await getDicts(dictType).then((resp) => {
+            res.value[dictType] = resp.data.map(
+              (p): DictDataOption => ({ label: p.dictLabel, value: p.dictValue, elTagType: p.listClass, elTagClass: p.cssClass })
+            );
+            useDictStore().setDict(dictType, res.value[dictType]);
+          });
+        }
+
       }
     });
     return res.value;

+ 484 - 0
src/views/dgtmedicine/member/detail.vue

@@ -0,0 +1,484 @@
+<template>
+  <div class="p-2">
+    <el-card shadow="never">
+      <el-tabs v-model="activeTab" type="border-card">
+        <el-tab-pane label="会员信息" name="meberInfo">
+          <el-form ref="memberFormRef" :model="form" :rules="rules">
+            <el-row :gutter="20">
+              <el-col :span="8">
+                <el-form-item label="企业名称" prop="cpyName">
+                  <el-input v-model="form.cpyName" placeholder="请输入企业名称" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="法人姓名" prop="legalPersonName">
+                  <el-input v-model="form.legalPersonName" placeholder="请输入法人姓名" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="法人电话" prop="legalPersonPhone">
+                  <el-input v-model="form.legalPersonPhone" placeholder="请输入法人电话" />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="8">
+                <el-form-item label="法人职务" prop="legalPersonPosition">
+                  <el-input v-model="form.legalPersonPosition" placeholder="请输入法人职务" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="法人身份证正面图片" prop="legalPersonIdFront">
+                  <image-upload v-model="form.legalPersonIdFront" :limit="1" :isString="true" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="法人身份证背面图片" prop="legalPersonIdBack">
+                  <image-upload v-model="form.legalPersonIdBack" :limit="1" :isString="true" />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="8">
+                <el-form-item label="申请会员等级" prop="applyLevel">
+                  <el-input v-model="form.applyLevel" placeholder="请输入申请会员等级" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="邮箱" prop="email">
+                  <el-input v-model="form.email" placeholder="请输入邮箱" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="主管部门" prop="department">
+                  <el-input v-model="form.department" placeholder="请输入主管部门" />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="8">
+                <el-form-item label="总资产" prop="totalAssets">
+                  <el-input v-model="form.totalAssets" placeholder="请输入总资产" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="单位简介" prop="introduction">
+                  <el-input v-model="form.introduction" type="textarea" placeholder="请输入内容" :rows="5" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="入会目的" prop="membershipPurpose">
+                  <el-input v-model="form.membershipPurpose" type="textarea" placeholder="请输入内容" :rows="5" />
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="8">
+                <el-form-item label="会员等级" prop="vipLevel">
+                  <el-select v-model="form.vipLevel" placeholder="请选择" clearable>
+                    <el-option v-for="dict in vip_level" :key="dict.value" :label="dict.label" :value="dict.value" />
+                  </el-select>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="开始时间" prop="startDate">
+                  <el-date-picker clearable v-model="form.startDate" type="date" value-format="YYYY-MM-DD"
+                    placeholder="请选择开始时间" style="width: 100%;">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="结束时间" prop="endDate">
+                  <el-date-picker clearable v-model="form.endDate" type="date" value-format="YYYY-MM-DD"
+                    placeholder="请选择结束时间" style="width: 100%;">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-row :gutter="20">
+              <el-col :span="8">
+                <el-form-item label="审核信息" prop="reviewMsg">
+                  <el-input v-model="form.reviewMsg" placeholder="请输入审核信息" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="审核人" prop="reviewBy">
+                  <el-input v-model="form.reviewBy" placeholder="请输入审核人" />
+                </el-form-item>
+              </el-col>
+              <el-col :span="8">
+                <el-form-item label="审核时间" prop="reviewTime">
+                  <el-date-picker clearable v-model="form.reviewTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss"
+                    placeholder="请选择审核时间">
+                  </el-date-picker>
+                </el-form-item>
+              </el-col>
+            </el-row>
+            <el-table v-loading="loading" :data="form.plantingInfo">
+              <el-table-column label="品种名称" align="center" prop="variety" width="220" />
+              <el-table-column label="种植面积" align="center" prop="plantingArea" />
+              <el-table-column label="种植地点" align="center" prop="plantingPlace" width="150" />
+            </el-table>
+            <el-row :gutter="20">
+              <el-col>
+                <el-form-item label="荣誉证书" prop="companyCertificate">
+                  <image-upload v-model="form.companyCertificate" :limit="10" :isString="true" />
+                </el-form-item>
+              </el-col>
+            </el-row>
+          </el-form>
+          <div class="dialog-footer" style="text-align: center;">
+            <el-button :loading="buttonLoading" type="primary" @click="submitForm">提 交</el-button>
+            <el-button @click="cancel">取 消</el-button>
+          </div>
+        </el-tab-pane>
+
+        <el-tab-pane label="缴费记录" name="payMentFormRef">
+          <div class="search">
+            <el-form :model="vipPaymentQueryParams" ref="vipPaymentFormRef" :inline="true" label-width="68px">
+              <el-form-item label="续费类型" prop="paymentType">
+                <el-select v-model="vipPaymentQueryParams.paymentType" placeholder="请选择" clearable style="width: 240px">
+                  <el-option v-for="dict in payment_type" :key="dict.value" :label="dict.label" :value="dict.value"
+                    @keyup.enter="handleQueryVipPayment" />
+                </el-select>
+              </el-form-item>
+              <el-form-item label="开票状态" prop="invoiceStatus">
+                <el-select v-model="vipPaymentQueryParams.invoiceStatus" placeholder="请选择" clearable style="width: 240px">
+                  <el-option v-for="dict in invoice_status" :key="dict.value" :label="dict.label" :value="dict.value"
+                    @keyup.enter="handleQueryVipPayment" />
+                </el-select>
+              </el-form-item>
+              <el-form-item>
+                <el-button type="primary" icon="Search" @click="handleQueryVipPayment">搜索</el-button>
+                <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+              </el-form-item>
+            </el-form>
+          </div>
+
+          <el-card shadow="never">
+            <el-table v-loading="loading" :data="vipPaymentList">
+              <el-table-column label="缴费金额" align="center" prop="paymentAmount" />
+              <el-table-column label="缴费时间" align="center" prop="paymentTime" width="180">
+                <template #default="scope">
+                  <span>{{ parseTime(scope.row.paymentTime, '{y}-{m}-{d}') }}</span>
+                </template>
+              </el-table-column>
+              <el-table-column label="缴费方式" align="center" prop="paymentType">
+                <template #default="scope">
+                  <dict-tag :value="scope.row.paymentType" :options="payment_type" />
+                </template>
+              </el-table-column>
+              <el-table-column label="缴费状态" align="center" prop="paymentStatus">
+                <template #default="scope">
+                  <dict-tag :value="scope.row.paymentStatus" :options="payment_status" />
+                </template>
+              </el-table-column>
+              <el-table-column label="缴费备注" align="center" prop="paymentRemark" />
+              <el-table-column label="开票状态" align="center" prop="invoiceStatus">
+                <template #default="scope">
+                  <dict-tag :value="scope.row.invoiceStatus" :options="invoice_status" />
+                </template>
+              </el-table-column>
+              <el-table-column label="发票" align="center" prop="invoiceUrl">
+                <template #default="scope">
+                  <el-link :underline="false" type="primary" :href="scope.row.invoiceUrlAddr" target="_blank"
+                    v-if="scope.row.invoiceStatus != 0">查看发票</el-link>
+                  <el-button link type="primary" @click="showUploadInvoice(scope.row)"
+                    v-hasPermi="['dgtmedicine:vipPayment:edit']" v-if="scope.row.invoiceStatus == 0">
+                    上传发票
+                  </el-button>
+                </template>
+              </el-table-column>
+              <el-table-column label="创建人" align="center" prop="createByName" />
+              <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+                <template #default="scope">
+                  <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
+                </template>
+              </el-table-column>
+              <!-- <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+                <template #default="scope">
+                  <el-tooltip content="删除" placement="top">
+                    <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)"
+                      v-hasPermi="['dgtmedicine:vipPayment:remove']"></el-button>
+                  </el-tooltip>
+                </template>
+              </el-table-column> -->
+            </el-table>
+            <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
+              v-model:limit="queryParams.pageSize" @pagination="getList" />
+          </el-card>
+
+          <el-dialog :close-on-click-modal="false" :title="dialogUpload.title" v-model="dialogUpload.visible"
+            width="500px" append-to-body>
+            <el-form ref="payMentFormRef" :model="paymentFrom" :rules="rules">
+              <el-row :gutter="20">
+                <file-upload v-model="paymentFrom.invoiceUrl" :limit="1" :isString="true" />
+              </el-row>
+            </el-form>
+            <template #footer>
+              <div class="dialog-footer">
+                <el-button :loading="buttonLoading" type="primary" @click="confirmUpload">确 定</el-button>
+                <el-button @click="cancelUpload">取 消</el-button>
+              </div>
+            </template>
+          </el-dialog>
+        </el-tab-pane>
+      </el-tabs>
+    </el-card>
+  </div>
+
+</template>
+
+<script setup name="Member" lang="ts">
+import { listMember, getMember, addMember, updateMember } from '@/api/dgtmedicine/member';
+import { MemberVO, MemberQuery, MemberForm } from '@/api/dgtmedicine/member/types';
+import { listVipPayment, getVipPayment, delVipPayment, uploadInvoice, updateVipPayment } from '@/api/dgtmedicine/vipPayment';
+import { VipPaymentVO, VipPaymentQuery, VipPaymentForm } from '@/api/dgtmedicine/vipPayment/types';
+import { useRouter } from 'vue-router';
+
+const { query } = useRoute();
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+const { vip_level, invoice_status, payment_status, payment_type } =
+  toRefs<any>(proxy?.useDict("vip_level", "invoice_status", "payment_status", "payment_type"));
+const router = useRouter();
+
+const vipPaymentList = ref<VipPaymentVO[]>([]);
+const memberList = ref<MemberVO[]>([]);
+const buttonLoading = ref(false);
+const loading = ref(true);
+const refuseShow = ref(false);
+const ids = ref<Array<string | number>>([]);
+const memberId = ref('');
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+const approvalLogFormRef = ref<ElFormInstance>();
+const activeTab = ref('meberInfo')
+const vipPaymentFormRef = ref<ElFormInstance>();
+const memberFormRef = ref<ElFormInstance>();
+const payMentFormRef = ref<ElFormInstance>();
+
+const dialog = reactive<DialogOption>({
+  visible: false,
+  title: ''
+});
+
+const dialogUpload = reactive<DialogOption>({
+  visible: false,
+  title: ''
+});
+
+const initFormData: MemberForm = {
+  id: undefined,
+  cpyName: undefined,
+  legalPersonName: undefined,
+  legalPersonPhone: undefined,
+  legalPersonPosition: undefined,
+  legalPersonIdFront: undefined,
+  legalPersonIdBack: undefined,
+  companyCertificate: undefined,
+  email: undefined,
+  department: undefined,
+  totalAssets: undefined,
+  introduction: undefined,
+  regType: undefined,
+  membershipPurpose: undefined,
+  plantingInfo: [
+    { variety: undefined, plantingArea: undefined, plantingPlace: 0, paymentDesc: undefined }
+  ],
+  vipLevel: undefined,
+  startDate: undefined,
+  endDate: undefined,
+  reviewStatus: undefined,
+  reviewMsg: undefined,
+  reviewBy: undefined,
+  reviewTime: undefined,
+  partnerId: undefined,
+  cpyBusType: undefined,
+  applyLevel: undefined
+}
+
+
+const initPayFormData: VipPaymentForm = {
+  id: undefined,
+  invoiceUrl: undefined,
+}
+const data = reactive<PageData<MemberForm, MemberQuery>>({
+  form: { ...initFormData },
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    cpyName: undefined,
+    legalPersonName: undefined,
+    legalPersonPhone: undefined,
+    legalPersonPosition: undefined,
+    legalPersonIdFront: undefined,
+    legalPersonIdBack: undefined,
+    companyCertificate: undefined,
+    email: undefined,
+    department: undefined,
+    totalAssets: undefined,
+    introduction: undefined,
+    regType: undefined,
+    membershipPurpose: undefined,
+    plantingInfo: undefined,
+    vipLevel: undefined,
+    startDate: undefined,
+    endDate: undefined,
+    reviewStatus: undefined,
+    reviewMsg: undefined,
+    reviewBy: undefined,
+    reviewTime: undefined,
+    partnerId: undefined,
+    cpyBusType: undefined,
+    applyLevel: undefined,
+    params: {
+    }
+  },
+  rules: {
+
+  }
+});
+
+const vipPaymentData = reactive<PageData<VipPaymentForm, VipPaymentQuery>>({
+  form: { ...initPayFormData },
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    memberId: undefined,
+    paymentAmount: undefined,
+    paymentTime: undefined,
+    paymentType: undefined,
+    paymentStatus: undefined,
+    paymentRemark: undefined,
+    invoiceStatus: undefined,
+    invoiceUrl: undefined,
+    params: {
+    }
+  },
+  rules: {
+    id: [
+      { required: true, message: "ID不能为空", trigger: "blur" }
+    ],
+    invoiceUrl: [
+      { required: true, message: "发票地址不能为空", trigger: "blur" }
+    ]
+  }
+});
+
+
+const { queryParams, form, rules } = toRefs(data);
+const { queryParams: vipPaymentQueryParams, form: paymentFrom } = toRefs(vipPaymentData);
+
+/** 查询会员信息列表 */
+const getList = async () => {
+  loading.value = true;
+  const res = await listMember(queryParams.value);
+  memberList.value = res.rows;
+  total.value = res.total;
+  loading.value = false;
+}
+
+/** 搜索按钮操作 */
+const handleQueryVipPayment = () => {
+  vipPaymentQueryParams.value.pageNum = 1;
+  getVipPaymentList();
+}
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  vipPaymentFormRef.value?.resetFields();
+  getVipPaymentList();
+}
+
+/** 表单重置 */
+const reset = () => {
+  form.value = { ...initFormData };
+  memberFormRef.value?.resetFields();
+}
+
+
+/** 查询会员缴费记录列表 */
+const getVipPaymentList = async () => {
+  loading.value = true;
+  vipPaymentQueryParams.value.memberId = memberId.value;
+  const res = await listVipPayment(vipPaymentQueryParams.value);
+  vipPaymentList.value = res.rows;
+  total.value = res.total;
+  loading.value = false;
+}
+
+/** 修改按钮操作 */
+const getMemberInfo = async () => {
+  reset();
+  const res = await getMember(memberId.value);
+  Object.assign(form.value, res.data);
+}
+
+/** 上传发票 */
+const showUploadInvoice = async (row?: VipPaymentVO) => {
+  dialogUpload.title = '上传发票';
+  dialogUpload.visible = true;
+  paymentFrom.value = { ...initPayFormData, id: row?.id };
+}
+
+/**取消审批弹框 */
+const cancelUpload = () => {
+  dialogUpload.visible = false
+}
+
+/**审批弹框 */
+const confirmUpload = () => {
+  payMentFormRef.value?.validate(async (valid: boolean) => {
+    if (valid) {
+      buttonLoading.value = true;
+      await uploadInvoice({ id: paymentFrom.value.id, invoiceUrl: paymentFrom.value.invoiceUrl }).finally(() => buttonLoading.value = false);
+      proxy?.$modal.msgSuccess("操作成功");
+      dialogUpload.visible = false
+      getVipPaymentList();
+    }
+  });
+}
+
+/** 删除按钮操作 */
+const handleDelete = async (row?: VipPaymentVO) => {
+  const _ids = row?.id || ids.value;
+  await proxy?.$modal.confirm('是否确认删除会员缴费记录编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
+  await delVipPayment(_ids);
+  proxy?.$modal.msgSuccess("删除成功");
+  await getList();
+}
+
+/** 提交按钮 */
+const submitForm = () => {
+  memberFormRef.value?.validate(async (valid: boolean) => {
+    if (valid) {
+      buttonLoading.value = true;
+      if (!Array.isArray(form.value.companyCertificate)) {
+        var companyCertificateList = form.value.companyCertificate.split(',');
+        form.value.companyCertificate = companyCertificateList;
+      }
+      if (form.value.id) {
+        await updateMember(form.value).finally(() => buttonLoading.value = false);
+      } else {
+        await addMember(form.value).finally(() => buttonLoading.value = false);
+      }
+      proxy?.$modal.msgSuccess("修改成功");
+      dialog.visible = false;
+      await getMemberInfo();
+    }
+  });
+}
+
+/** 取消按钮 */
+const cancel = () => {
+  // reset();
+}
+
+
+onMounted(() => {
+  memberId.value = (query.memberId as string)
+  getMemberInfo();
+  getVipPaymentList();
+});
+</script>

+ 550 - 0
src/views/dgtmedicine/member/index.vue

@@ -0,0 +1,550 @@
+<template>
+  <div class="p-2">
+    <transition :enter-active-class="proxy?.animate.searchAnimate.enter"
+      :leave-active-class="proxy?.animate.searchAnimate.leave">
+      <div class="search" v-show="showSearch">
+        <el-form :model="queryParams" ref="queryFormRef" :inline="true" label-width="68px">
+          <el-form-item label="企业名称" prop="cpyName">
+            <el-input v-model="queryParams.cpyName" placeholder="请输入企业名称" clearable style="width: 240px"
+              @keyup.enter="handleQuery" />
+          </el-form-item>
+          <el-form-item label="日期范围" prop="dateRange">
+            <el-date-picker clearable v-model="queryParams.dateRange" type="daterange" range-separator="至"
+              start-placeholder="开始日期" end-placeholder="结束日期" value-format="YYYY-MM-DD"
+              @change="handleDateRangeChange" />
+          </el-form-item>
+          <el-form-item label="审核状态" prop="reviewStatus">
+            <el-select v-model="queryParams.reviewStatus" placeholder="请选择" clearable style="width: 240px">
+              <el-option v-for="dict in cpy_res_status" :key="dict.value" :label="dict.label" :value="dict.value"
+                @keyup.enter="handleQuery" />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+            <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+    </transition>
+
+    <el-card shadow="never">
+      <template #header>
+        <el-row :gutter="20" class="mb8">
+          <el-col :span="2" v-for="level in memberLevelCountList" :key="level.type">
+            <el-button type="text" @click="handleQuery(level)">{{ level.name }}({{ level.num }})</el-button>
+          </el-col>
+          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+        </el-row>
+      </template>
+      <el-table v-loading="loading" :data="memberList" @selection-change="handleSelectionChange">
+        <el-table-column label="企业名称" align="center" prop="cpyName" width="220" />
+        <el-table-column label="法人姓名" align="center" prop="legalPersonName" />
+        <el-table-column label="法人电话" align="center" prop="legalPersonPhone" width="150" />
+        <el-table-column label="当前等级" align="center" prop="vipLevel">
+          <template #default="scope">
+            <dict-tag :value="scope.row.vipLevel" :options="vip_level" />
+          </template>
+        </el-table-column>
+        <el-table-column label="申请等级" align="center" prop="applyLevel">
+          <template #default="scope">
+            <dict-tag :value="scope.row.applyLevel" :options="vip_level" />
+          </template>
+        </el-table-column>
+        <el-table-column label="开始时间" align="center" prop="startDate" width="100">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.startDate, '{y}-{m}-{d}') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="结束时间" align="center" prop="endDate" width="100">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.endDate, '{y}-{m}-{d}') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="业务类型" align="center" prop="cpyBusType" />
+        <el-table-column label="审核状态" align="center" prop="reviewStatus">
+          <template #default="scope">
+            <dict-tag :value="scope.row.reviewStatus" :options="cpy_res_status" />
+          </template>
+        </el-table-column>
+        <el-table-column label="审核信息" align="center" prop="reviewMsg" />
+        <el-table-column label="审核时间" align="center" prop="reviewTime" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.reviewTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="创建时间" align="center" prop="createTime" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+          </template>
+        </el-table-column>
+        <!-- <el-table-column label="更新时间" align="center" prop="updateTime" width="180">
+          <template #default="scope">
+            <span>{{ parseTime(scope.row.updateTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+          </template>
+        </el-table-column> -->
+        <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+          <template #default="scope">
+            <el-button link type="primary" @click="showApp(scope.row)" v-hasPermi="['dgtmedicine:memeber:approval']"
+              v-if="scope.row.reviewStatus == '0'">审批</el-button>
+            <el-button link type="primary" v-hasPermi="['dgtmedicine:memeber:approval']"
+              @click="memberDetail(scope.row)" v-if="scope.row.reviewStatus != '0'">详情</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
+        v-model:limit="queryParams.pageSize" @pagination="getList" />
+    </el-card>
+
+    <!--审核弹窗-->
+    <el-dialog :close-on-click-modal="false" :title="dialogApproval.title" v-model="dialogApproval.visible"
+      width="1200px" append-to-body>
+      <el-form ref="memberFormRef" :model="form" :rules="rules">
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="企业名称" prop="cpyName">
+              <el-text v-model="form.cpyName">{{ form.cpyName }}</el-text>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="法人姓名" prop="legalPersonName">
+              <el-text>{{ form.legalPersonName }}</el-text>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="法人电话" prop="legalPersonPhone">
+              <el-text>{{ form.legalPersonPhone }}</el-text>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="法人职务" prop="legalPersonPosition">
+              <el-text>{{ form.legalPersonPosition }}</el-text>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="法人身份证正面图片" prop="legalPersonIdFront">
+              <el-image :src="form.legalPersonIdFront" style="width: 100px; height: 100px" show-progress
+                :preview-src-list="[form.legalPersonIdFront]" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="法人身份证背面图片" prop="legalPersonIdBack">
+              <el-image :src="form.legalPersonIdBack" style="width: 100px; height: 100px" show-progress
+                :preview-src-list="[form.legalPersonIdBack]" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="申请会员等级" prop="applyLevel">
+              <dict-tag :value="form.applyLevel" :options="vip_level" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="邮箱" prop="email">
+              <el-text>{{ form.email }}</el-text>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="主管部门" prop="department">
+              <el-text>{{ form.department }}</el-text>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="总资产" prop="totalAssets">
+              <el-text>{{ form.totalAssets }}</el-text>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="单位简介" prop="introduction">
+              <el-text>{{ form.introduction }}</el-text>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="入会目的" prop="membershipPurpose">
+              <el-text>{{ form.membershipPurpose }}</el-text>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="当前会员等级" prop="vipLevel">
+              <dict-tag :value="form.vipLevel" :options="vip_level" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="开始时间" prop="startDate">
+              <el-text>{{ form.startDate }}</el-text>
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="结束时间" prop="endDate">
+              <el-text>{{ form.endDate }}</el-text>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <!-- <el-row :gutter="20">
+          <el-col :span="8">
+            <el-form-item label="审核信息" prop="reviewMsg">
+              <el-input v-model="form.reviewMsg" placeholder="请输入审核信息" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="审核人" prop="reviewBy">
+              <el-input v-model="form.reviewBy" placeholder="请输入审核人" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="审核时间" prop="reviewTime">
+              <el-date-picker clearable v-model="form.reviewTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss"
+                placeholder="请选择审核时间">
+              </el-date-picker>
+            </el-form-item>
+          </el-col>
+        </el-row> -->
+        <el-table v-loading="loading" :data="form.plantingInfo">
+          <el-table-column label="品种名称" align="center" prop="variety" />
+          <el-table-column label="种植面积" align="center" prop="plantingArea" />
+          <el-table-column label="种植地点" align="center" prop="plantingPlace" />
+        </el-table>
+        <el-row :gutter="20">
+          <el-col>
+            <el-form-item label="荣誉证书" prop="companyCertificate">
+              <el-image :src="form.companyCertificate" style="width: 100px; height: 100px" show-progress
+                :preview-src-list="form.companyCertificate" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <el-form ref="approvalLogFormRef" :model="approvalForm" :rules="approvalRules" label-width="80px">
+        <el-form-item label="审批类型" prop="reviewStatus">
+          <el-select v-model="approvalForm.reviewStatus" placeholder="请选择" clearable style="width: 100%"
+            @change="showRefuse">
+            <template v-for="dict in cpy_res_status">
+              <el-option v-if="dict.value != '0'" :key="dict.value" :label="dict.label" :value="dict.value" />
+            </template>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="审批理由" prop="msg" v-if="refuseShow">
+          <el-input type="textarea" v-model="approvalForm.reviewMsg" placeholder="请输入拒绝理由" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button :loading="buttonLoading" type="primary" @click="confirmApp">确 定</el-button>
+          <el-button @click="cancelApp">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+
+</template>
+
+<script setup name="Member" lang="ts">
+import { listMember, getMember, delMember, addMember, updateMember, countLevelMember } from '@/api/dgtmedicine/member';
+import { approvalMember } from '@/api/dgtmedicine/approvalLog';
+import { MemberVO, MemberQuery, MemberForm, MemberLevelCountVO } from '@/api/dgtmedicine/member/types';
+import { ApprovalLogQuery, ApprovalLogForm } from '@/api/dgtmedicine/approvalLog/types';
+import { useRouter } from 'vue-router';
+import { debug } from 'console';
+const router = useRouter();
+const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+
+const { cpy_res_status, vip_level } = toRefs<any>(proxy?.useDict("cpy_res_status", "vip_level"));
+
+const memberList = ref<MemberVO[]>([]);
+const memberLevelCountList = ref<MemberLevelCountVO[]>([]);
+const buttonLoading = ref(false);
+const loading = ref(true);
+const showSearch = ref(true);
+const refuseShow = ref(false);
+const ids = ref<Array<string | number>>([]);
+const single = ref(true);
+const multiple = ref(true);
+const total = ref(0);
+const approvalLogFormRef = ref<ElFormInstance>();
+
+const queryFormRef = ref<ElFormInstance>();
+const memberFormRef = ref<ElFormInstance>();
+
+const dialog = reactive<DialogOption>({
+  visible: false,
+  title: ''
+});
+
+const initFormApprovalData: ApprovalLogForm = {
+  id: undefined,
+  targetType: undefined,
+  reviewStatus: '1',
+  reviewMsg: undefined
+}
+
+const dialogApproval = reactive<DialogOption>({
+  visible: false,
+  title: ''
+});
+
+const approvalData = reactive<PageData<ApprovalLogForm, ApprovalLogQuery>>({
+  form: { ...initFormApprovalData },
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    targetType: undefined,
+    targetId: undefined,
+    res: undefined,
+    msg: undefined,
+    params: {
+    }
+  },
+  rules: {
+  }
+});
+
+const initFormData: MemberForm = {
+  id: undefined,
+  cpyName: undefined,
+  legalPersonName: undefined,
+  legalPersonPhone: undefined,
+  legalPersonPosition: undefined,
+  legalPersonIdFront: undefined,
+  legalPersonIdBack: undefined,
+  companyCertificate: undefined,
+  email: undefined,
+  department: undefined,
+  totalAssets: undefined,
+  introduction: undefined,
+  regType: undefined,
+  membershipPurpose: undefined,
+  plantingInfo: undefined,
+  vipLevel: undefined,
+  startDate: undefined,
+  endDate: undefined,
+  reviewStatus: undefined,
+  reviewMsg: undefined,
+  reviewBy: undefined,
+  reviewTime: undefined,
+  partnerId: undefined,
+  cpyBusType: undefined,
+  applyLevel: undefined
+}
+const data = reactive<PageData<MemberForm, MemberQuery>>({
+  form: { ...initFormData },
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    cpyName: undefined,
+    legalPersonName: undefined,
+    legalPersonPhone: undefined,
+    legalPersonPosition: undefined,
+    legalPersonIdFront: undefined,
+    legalPersonIdBack: undefined,
+    companyCertificate: undefined,
+    email: undefined,
+    department: undefined,
+    totalAssets: undefined,
+    introduction: undefined,
+    regType: undefined,
+    membershipPurpose: undefined,
+    plantingInfo: undefined,
+    vipLevel: undefined,
+    startDate: undefined,
+    endDate: undefined,
+    reviewStatus: undefined,
+    reviewMsg: undefined,
+    reviewBy: undefined,
+    reviewTime: undefined,
+    partnerId: undefined,
+    cpyBusType: undefined,
+    applyLevel: undefined,
+    params: {
+    }
+  },
+  rules: {
+
+  }
+});
+
+const { queryParams, form, rules } = toRefs(data);
+const { form: approvalForm, rules: approvalRules } = toRefs(approvalData);
+
+
+/**动态显示审批理由 */
+const showRefuse = (res: any) => {
+  if (res == "2") {
+    refuseShow.value = true
+    return
+  }
+  refuseShow.value = false
+}
+
+/** 查询会员信息列表 */
+const getList = async () => {
+  loading.value = true;
+  const res = await listMember(queryParams.value);
+  memberList.value = res.rows;
+  total.value = res.total;
+  loading.value = false;
+
+}
+
+/** 查询会员信息列表 */
+const getMemberLevelList = async () => {
+  loading.value = true;
+  const res = await countLevelMember(queryParams.value);
+  memberLevelCountList.value = res.data;
+  console.log(memberLevelCountList.value)
+  loading.value = false;
+}
+
+/** 取消按钮 */
+const cancel = () => {
+  reset();
+  dialog.visible = false;
+}
+
+/** 表单重置 */
+const reset = () => {
+  form.value = { ...initFormData };
+  memberFormRef.value?.resetFields();
+}
+
+/** 搜索按钮操作 */
+const handleQuery = (level?: any) => {
+  queryParams.value.pageNum = 1;
+  if (level !== undefined && level !== null && level.type !== 'click') {
+    queryParams.value.vipLevel = level.type;
+  }
+  getList();
+}
+
+
+/** 重置按钮操作 */
+const resetQuery = () => {
+  queryFormRef.value?.resetFields();
+  handleQuery();
+}
+
+/**审批弹框 */
+const showApp = (row: any) => {
+  approvalReset()
+  dialogApproval.visible = true
+  approvalForm.value.id = row.id
+  getMemberInfo(row.id)
+}
+
+/** 修改按钮操作 */
+const getMemberInfo = async (memberId: string) => {
+  reset();
+  const res = await getMember(memberId);
+  Object.assign(form.value, res.data);
+}
+
+const memberDetail = (row: any) => {
+  router.push({ path: `/szyy/member-detail`, query: { memberId: row.id } });
+}
+
+/** 处理日期范围变化 */
+const handleDateRangeChange = (value: [string, string]) => {
+  if (value && value.length === 2) {
+    queryParams.value.startDate = value[0];
+    queryParams.value.endDate = value[1];
+  } else {
+    queryParams.value.startDate = undefined;
+    queryParams.value.endDate = undefined;
+  }
+  handleQuery();
+}
+
+/** 审批表单重置 */
+const approvalReset = () => {
+  refuseShow.value = false
+  approvalForm.value = { ...initFormApprovalData };
+  approvalLogFormRef.value?.resetFields();
+}
+
+/** 多选框选中数据 */
+const handleSelectionChange = (selection: MemberVO[]) => {
+  ids.value = selection.map(item => item.id);
+  single.value = selection.length != 1;
+  multiple.value = !selection.length;
+}
+
+/** 新增按钮操作 */
+const handleAdd = () => {
+  reset();
+  dialog.visible = true;
+  dialog.title = "添加会员信息";
+}
+
+/** 修改按钮操作 */
+const handleUpdate = async (row?: MemberVO) => {
+  reset();
+  const _id = row?.id || ids.value[0]
+  const res = await getMember(_id);
+  Object.assign(form.value, res.data);
+  dialog.visible = true;
+  dialog.title = "修改会员信息";
+}
+
+/** 提交按钮 */
+const submitForm = () => {
+  memberFormRef.value?.validate(async (valid: boolean) => {
+    if (valid) {
+      buttonLoading.value = true;
+      if (form.value.id) {
+        await updateMember(form.value).finally(() => buttonLoading.value = false);
+      } else {
+        await addMember(form.value).finally(() => buttonLoading.value = false);
+      }
+      proxy?.$modal.msgSuccess("修改成功");
+      dialog.visible = false;
+      await getList();
+    }
+  });
+}
+
+/**取消审批弹框 */
+const cancelApp = () => {
+  approvalReset()
+  dialogApproval.visible = false
+}
+
+
+/**审批弹框 */
+const confirmApp = () => {
+  approvalLogFormRef.value?.validate(async (valid: boolean) => {
+    if (valid) {
+      buttonLoading.value = true;
+      await approvalMember(approvalForm.value).finally(() => buttonLoading.value = false);
+      proxy?.$modal.msgSuccess("操作成功");
+      dialogApproval.visible = false
+      getList();
+    }
+  });
+}
+
+/** 删除按钮操作 */
+const handleDelete = async (row?: MemberVO) => {
+  const _ids = row?.id || ids.value;
+  await proxy?.$modal.confirm('是否确认删除会员信息编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
+  await delMember(_ids);
+  proxy?.$modal.msgSuccess("删除成功");
+  await getList();
+}
+
+/** 导出按钮操作 */
+const handleExport = () => {
+  proxy?.download('dgtmedicine/member/export', {
+    ...queryParams.value
+  }, `member_${new Date().getTime()}.xlsx`)
+}
+
+onMounted(() => {
+  getList();
+  getMemberLevelList();
+});
+</script>

+ 2 - 1
src/views/login.vue

@@ -71,7 +71,8 @@ const router = useRouter();
 const { t } = useI18n();
 
 const loginForm = ref<LoginData>({
-  tenantId: '190040',
+  // tenantId: '190040',
+   tenantId: '000000',
   username: 'admin',
   password: 'admin123',
   rememberMe: false,