snow 2 years ago
parent
commit
922c5038d5
38 changed files with 2854 additions and 72 deletions
  1. 9 2
      src/api/interest/account/index.ts
  2. 2 1
      src/api/interest/accountQuery/index.ts
  3. 52 0
      src/api/supplierManage/supplierAccoutManage/index.ts
  4. 52 0
      src/api/supplierManage/supplierAccoutQuery/index.ts
  5. 1 4
      src/hooks/core/useAsync.ts
  6. 3 0
      src/main.ts
  7. 8 9
      src/utils/auth.ts
  8. 26 0
      src/utils/watchToken.ts
  9. 3 3
      src/views/InvoiceSales/capitalClaim/index.vue
  10. 434 0
      src/views/interest/companyAccount-origin/addEdit.vue
  11. 60 0
      src/views/interest/companyAccount-origin/columns.tsx
  12. 133 0
      src/views/interest/companyAccount-origin/components/company-modal.vue
  13. 329 0
      src/views/interest/companyAccount-origin/index.vue
  14. 198 0
      src/views/interest/companyAccount-origin/resetPassword.vue
  15. 8 0
      src/views/interest/companyAccount-origin/types.ts
  16. 6 10
      src/views/interest/companyAccount/addEdit.vue
  17. 3 4
      src/views/interest/companyAccount/components/company-modal.vue
  18. 5 2
      src/views/interest/companyAccount/index.vue
  19. 2 3
      src/views/reportForm/reportRecord/index.vue
  20. 431 0
      src/views/supplierManage/supplierAccoutManage/addEdit.vue
  21. 60 0
      src/views/supplierManage/supplierAccoutManage/columns.tsx
  22. 133 0
      src/views/supplierManage/supplierAccoutManage/components/company-modal.vue
  23. 331 0
      src/views/supplierManage/supplierAccoutManage/index.vue
  24. 198 0
      src/views/supplierManage/supplierAccoutManage/resetPassword.vue
  25. 8 0
      src/views/supplierManage/supplierAccoutManage/types.ts
  26. 134 0
      src/views/supplierManage/supplierAccoutQuery/components/role-modal.vue
  27. 1 0
      src/views/supplierManage/supplierAccoutQuery/config/_details.ts
  28. 18 0
      src/views/supplierManage/supplierAccoutQuery/config/_options.ts
  29. 101 0
      src/views/supplierManage/supplierAccoutQuery/config/content.config.ts
  30. 18 0
      src/views/supplierManage/supplierAccoutQuery/config/search.config.ts
  31. 62 0
      src/views/supplierManage/supplierAccoutQuery/index.vue
  32. 5 0
      src/views/supplierManage/supplierAccoutQuery/types.ts
  33. 11 5
      src/views/system/finance/components/finance-modal.vue
  34. 1 20
      src/views/system/finance/config/content.config.ts
  35. 2 4
      src/views/system/finance/index.vue
  36. 1 1
      src/views/system/menuOperator/columns.tsx
  37. 2 2
      src/views/system/menuOperator/components/edit-dialog.vue
  38. 3 2
      src/views/system/menuOperator/index.vue

+ 9 - 2
src/api/interest/account/index.ts

@@ -13,8 +13,15 @@ export const httpAdd = (data: object): ResponseType => {
   return http.request("post", `${yewuApi}useradd`, { data });
 };
 // 列表
-export const httpList = (data: object): ResponseType => {
-  return http.request("post", `${yewuApi}usersinglelist`, { data });
+export const httpList = (data: object = {}): ResponseType => {
+  return http.request("post", `${yewuApi}usersinglelist`, {data:{
+      ...data,
+      level: "2"
+    }});
+};
+
+export const httpCompanyList = (data: object = {}): ResponseType => {
+  return http.request("post", `${yewuApi}companylist`, { data });
 };
 // 详情
 export const httpDetail = (data: object): ResponseType => {

+ 2 - 1
src/api/interest/accountQuery/index.ts

@@ -17,7 +17,7 @@ export const httpAdd = (data: object): ResponseType => {
 export const httpList = (param: object): ResponseType => {
   return http.request("post", `${yewuApi}userlist`, {
     data: {
-      islevel: "2",
+      level: "2",
       ...param
     }
   });
@@ -26,6 +26,7 @@ export const httpList = (param: object): ResponseType => {
 export const httpDetail = (data: object): ResponseType => {
   return http.request("post", `${yewuApi}userinfo`, { data });
 };
+
 // 更新
 export const httpUpdate = (data: object): ResponseType => {
   return http.request("post", `${yewuApi}usersave`, { data });

+ 52 - 0
src/api/supplierManage/supplierAccoutManage/index.ts

@@ -0,0 +1,52 @@
+import { http } from "/@/utils/http";
+import { loadEnv } from "@build/index";
+const { VITE_PROXY_DOMAIN_REAL, VITE_PROXY_USER_REAL } = loadEnv();
+const userAPi = VITE_PROXY_DOMAIN_REAL;
+const yewuApi = VITE_PROXY_USER_REAL + "/admin/";
+interface ResponseType extends Promise<any> {
+  data?: object;
+  code?: number;
+  msg?: string;
+}
+// 添加
+export const httpAdd = (data: object): ResponseType => {
+  return http.request("post", `${yewuApi}supplierAccountAdd`, { data });
+};
+// 列表
+export const httpList = (data: object = {}): ResponseType => {
+  return http.request("post", `${yewuApi}usersinglelist`, { data : {
+     ...data,
+      level: "3"
+    }});
+};
+
+// 详情
+export const httpDetail = (data: object): ResponseType => {
+  return http.request("post", `${yewuApi}userinfo`, { data });
+};
+
+// 更新
+export const httpUpdate = (data: object): ResponseType => {
+  return http.request("post", `${yewuApi}usersave`, { data });
+};
+
+// 状态
+export const httpStatus = (data: object): ResponseType => {
+  return http.request("post", `${yewuApi}setstatus`, { data });
+};
+// 删除
+export const httpDelete = (data: object): ResponseType => {
+  return http.request("post", `${yewuApi}menustatus`, { data });
+};
+// 重置密码
+export const httpSetPwd = (data: object): ResponseType => {
+  return http.request("post", `${yewuApi}setpwd`, { data });
+};
+// 全部角色
+export const httpRoleAll = (data: object): ResponseType => {
+  return http.request("post", `${yewuApi}roleall`, { data });
+};
+// 设置角色
+export const httpSetRole = (data: object): ResponseType => {
+  return http.request("post", `${yewuApi}setrole`, { data });
+};

+ 52 - 0
src/api/supplierManage/supplierAccoutQuery/index.ts

@@ -0,0 +1,52 @@
+import { http } from "/@/utils/http";
+import { loadEnv } from "@build/index";
+const { VITE_PROXY_DOMAIN_REAL, VITE_PROXY_USER_REAL } = loadEnv();
+const userAPi = VITE_PROXY_DOMAIN_REAL;
+const yewuApi = VITE_PROXY_USER_REAL + "/admin/";
+interface ResponseType extends Promise<any> {
+  data?: object;
+  code?: number;
+  msg?: string;
+}
+// 添加
+export const httpAdd = (data: object): ResponseType => {
+  return http.request("post", `${yewuApi}useradd`, { data });
+};
+
+// 列表
+export const httpList = (param: object): ResponseType => {
+  return http.request("post", `${yewuApi}userlist`, {
+    data: {
+      level: "3",
+      ...param
+    }
+  });
+};
+// 详情
+export const httpDetail = (data: object): ResponseType => {
+  return http.request("post", `${yewuApi}userinfo`, { data });
+};
+// 更新
+export const httpUpdate = (data: object): ResponseType => {
+  return http.request("post", `${yewuApi}usersave`, { data });
+};
+// 状态
+export const httpStatus = (data: object): ResponseType => {
+  return http.request("post", `${yewuApi}setcompanystatus`, { data });
+};
+// 删除
+export const httpDelete = (data: object): ResponseType => {
+  return http.request("post", `${yewuApi}menustatus`, { data });
+};
+// 重置密码
+export const httpSetPwd = (data: object): ResponseType => {
+  return http.request("post", `${yewuApi}setpwd`, { data });
+};
+// 全部角色
+export const httpRoleAll = (data: object): ResponseType => {
+  return http.request("post", `${yewuApi}roleall`, { data });
+};
+// 设置角色
+export const httpSetRole = (data: object): ResponseType => {
+  return http.request("post", `${yewuApi}setrole`, { data });
+};

+ 1 - 4
src/hooks/core/useAsync.ts

@@ -53,15 +53,12 @@ export function useAsync<D = any>({
   }
 
   function run(promise: Promise<IDataType<D>>) {
-    setloading(true);
 
+    setloading(true);
     return promise.then(response => {
       setloading(false);
-
       const { code: _code, message, data } = response;
-
       if (String(_code) !== "0") isError.value = true;
-
       responseHandle({
         code: _code,
         message,

+ 3 - 0
src/main.ts

@@ -31,6 +31,8 @@ import "vue-virtual-scroller/dist/vue-virtual-scroller.css";
 
 const app = createApp(App);
 
+registerEvent();
+
 // 自定义指令
 import * as directives from "/@/directives";
 Object.keys(directives).forEach(key => {
@@ -44,6 +46,7 @@ import {
   FontIcon
 } from "./components/ReIcon";
 import { setupPageComponent } from "./plugins/globalComponent";
+import { registerEvent } from "/@/utils/watchToken";
 
 app.component("IconifyIconOffline", IconifyIconOffline);
 app.component("IconifyIconOnline", IconifyIconOnline);

+ 8 - 9
src/utils/auth.ts

@@ -1,6 +1,5 @@
 import Cookies from "js-cookie";
 
-const TokenKey = "compute-Console-Token";
 const RelaComNoKey = "compute-Console-RelaComNo";
 const RelaComNameKey = "compute-Console-RelaComName";
 const superKey = "compute-Console-superUser";
@@ -10,14 +9,18 @@ const NoticeKey = "compute-Console-Notice";
 const InfoKey = "compute-Console-Info";
 const ActionKey = "compute-Console-Action";
 
+export const TokenKey = "compute-Console-Token";
+
 export const SECRET_KEY = "key123";
 
-export function getToken() {
-  return Cookies.get(TokenKey);
-}
+export const getToken = () => localStorage.getItem(TokenKey);
 
 export function setToken(token) {
-  return Cookies.set(TokenKey, token);
+  return window.localStorage.setItem(TokenKey, token);
+}
+
+export function removeToken() {
+  return localStorage.removeItem(TokenKey);
 }
 
 export function setSuperUser(state: boolean) {
@@ -44,10 +47,6 @@ export function getSuperUser() {
   return Cookies.get(superKey);
 }
 
-export function removeToken() {
-  return Cookies.remove(TokenKey);
-}
-
 export function getMenu() {
   const menu = Cookies.get(MenuKey);
   if (menu) {

+ 26 - 0
src/utils/watchToken.ts

@@ -0,0 +1,26 @@
+import { TokenKey } from "/@/utils/auth";
+import { SECRET_KEY } from "/@/utils/auth";
+import CryptoJS from "crypto-js";
+import router from "./../router";
+
+function changeToken(token: string) {
+  if (!token) return;
+  const encJson = CryptoJS.AES.encrypt(JSON.stringify({ token }), SECRET_KEY);
+  const encData = CryptoJS.enc.Base64.stringify(
+    CryptoJS.enc.Utf8.parse(encJson)
+  );
+
+  router.push("/accept?t=" + encData);
+}
+
+function listener(event) {
+  const { key, newValue } = event;
+
+  switch (key) {
+    case TokenKey:
+      changeToken(newValue);
+      break;
+  }
+}
+
+export const registerEvent = () => window.addEventListener("storage", listener);

+ 3 - 3
src/views/InvoiceSales/capitalClaim/index.vue

@@ -36,9 +36,9 @@ const { run: withDraw } = useAsync({
 
 //  { code: "009", name: "撤销资金认领" },
 //  { code: "029", name: "下载资金导入模板" },
-//  { code: "030", name: "批量导入客户付款资金数据" }
-//  { code: "034", name: "下载订单认款导入模板" },
-//  { code: "035", name: "批量导入订单认款数据" }
+//  { code: "030", name: "批量导入客户付款资金数据" },
+//  { code: "034", name: "下载订单认款导入模板" },
+//  { code: "035", name: "批量导入订单认款数据" }
 
 const { hasPermissionWithCode, permissions } = usePermission(pageName);
 const loading = ref(false);

+ 434 - 0
src/views/interest/companyAccount-origin/addEdit.vue

@@ -0,0 +1,434 @@
+<script setup lang="ts">
+import {
+  httpAdd,
+  httpUpdate,
+  httpDetail
+} from "/@/api/interest/companyAccount";
+import { ElMessage, FormInstance, FormRules } from "element-plus";
+import { reactive, ref, watch, nextTick } from "vue";
+import { useNav } from "/@/layout/hooks/nav";
+import { isMobile } from "/@/utils/validate";
+import CompanyModal from "./components/company-modal.vue";
+import { type menuType } from "./types";
+import { useUserInfo } from "/@/hooks/core/useUser";
+
+const { logout } = useNav();
+const formSize = ref("default");
+const ruleFormRef = ref<FormInstance>();
+
+const props = defineProps({
+  itemId: {
+    type: String,
+    default: ""
+  },
+  showModel: {
+    type: Boolean,
+    default: false
+  },
+  isDetails: {
+    type: String,
+    default: "add"
+  },
+  sitem: {
+    type: Object as PropType<menuType>
+  }
+});
+
+const defaultCompany = ref<boolean[]>([]);
+let defaultCompanyNo = "";
+
+const showModelThis = ref(false);
+const emit = defineEmits<{
+  (e: "cancel"): void;
+  (e: "refresh"): void;
+}>();
+const id = ref("");
+const editType = ref("add");
+const formModel = {
+  id: "", //账户id
+  nickname: "", //真实姓名
+  mobile: "", //手机号
+  companyArr: []
+};
+
+const tableRef = ref<any>(null);
+const ruleForm = reactive<menuType>({ ...formModel });
+const companyModalRef = ref<InstanceType<typeof CompanyModal> | null>(null);
+const { isSuperUser } = useUserInfo();
+
+let originCompanyArr: any[] = [];
+const rules = reactive<FormRules>({
+  nickname: [
+    { required: true, message: "请输入真实姓名", trigger: "blur" },
+    { min: 2, max: 12, message: "长度在 2 到 12 个字符", trigger: "blur" }
+  ],
+  mobile: [
+    {
+      required: true,
+      validator: (rule, value, callback) => {
+        if (value === "") {
+          callback(new Error("手机号不能为空!"));
+        } else if (!isMobile(value)) {
+          callback(new Error("手机号格式不正确!"));
+        } else {
+          callback();
+        }
+      },
+
+      trigger: "blur"
+    }
+  ],
+  companyArr: [
+    {
+      required: true,
+      validator: (rule, value, callback) => {
+        if (value.length === 0) {
+          callback(new Error("请选择业务公司"));
+        } else {
+          callback();
+        }
+      }
+    }
+  ]
+});
+
+const submitForm = async (formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  if (!defaultCompanyNo) {
+    ElMessage.warning("请选择默认公司");
+    return;
+  }
+
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      if (loading.value === true) return;
+      const model = Object.assign({}, ruleForm);
+
+      if (editType.value === "add") delete model.id;
+      const current = model.companyArr.map(({ companyCode }) => companyCode);
+
+      const dels = originCompanyArr
+        .filter(({ companyCode }) => !current.includes(companyCode))
+        .map(({ companyCode, companyName, id }) => ({
+          id,
+          companyCode,
+          companyName,
+          is_del: 1,
+          is_main: "0"
+        }));
+
+      const orgs = originCompanyArr
+        .filter(({ companyCode }) => current.includes(companyCode))
+        .map(({ companyCode, companyName, id }) => ({
+          id,
+          companyCode,
+          companyName,
+          is_del: 0,
+          is_main: "0"
+        }));
+
+      const adds = model.companyArr
+        .filter(({ companyCode: code }) => {
+          return (
+            !dels.find(({ companyCode }) => companyCode === code) &&
+            !orgs.find(({ companyCode }) => companyCode === code)
+          );
+        })
+        .map(({ companyCode, companyName, id }) => ({
+          id,
+          companyCode,
+          companyName,
+          is_main: "0",
+          is_del: 0
+        }));
+
+      model.companyArr = [...dels, ...orgs, ...adds];
+
+      model.companyArr.forEach(item => {
+        if (item.companyCode === defaultCompanyNo) {
+          item.is_main = "1";
+        }
+      });
+
+      loading.value = true;
+      const { code, message } =
+        editType.value === "add"
+          ? await httpAdd(model)
+          : await httpUpdate(model);
+      loading.value = false;
+
+      if (code === 0) {
+        ElMessage.success(titleType.value + "成功!");
+        showModelThis.value = false;
+        emit("refresh");
+      } else if (code > 100 && code < 140) {
+        showModelThis.value = false;
+        logout();
+      } else {
+        ElMessage.error(message);
+      }
+    } else {
+      console.log("error submit!", fields);
+    }
+  });
+};
+
+const resetForm = async (formEl: FormInstance | undefined, item) => {
+  if (formEl) {
+    formEl.clearValidate();
+    formEl.resetFields();
+  }
+
+  await nextTick(async () => {
+    for (let key in ruleForm) {
+      if (key === "companyArr" && item["company_relaton"]) {
+        if (editType.value !== "add") {
+          item["company_relaton"].forEach(item => {
+            ruleForm.companyArr.push({ ...item });
+          });
+        } else {
+          ruleForm.companyArr = [];
+        }
+      } else {
+        ruleForm[key] = item[key];
+      }
+    }
+  });
+
+  originCompanyArr = item.company_relaton?.map(item => ({ ...item })) || [];
+
+  if (editType.value === "add") {
+    ruleForm.companyArr = [];
+    originCompanyArr = [];
+  }
+};
+
+const closeDialog = () => {
+  showModelThis.value = false;
+  defaultCompany.value = [];
+  ruleForm.companyArr = [];
+  defaultCompanyNo = "";
+  emit("cancel");
+};
+
+const loading = ref(true);
+const titleType = ref("");
+async function initForm(item: Object) {
+  loading.value = true;
+  switch (editType.value) {
+    case "add":
+      titleType.value = "新建账号";
+      break;
+    case "edit":
+      titleType.value = "编辑账号";
+      break;
+    case "view":
+      titleType.value = "账号详情";
+      break;
+    default:
+      titleType.value = "新建账号";
+  }
+  resetForm(ruleFormRef.value, item);
+  loading.value = false;
+}
+
+function handleDelete(index) {
+  ruleForm.companyArr.splice(index, 1);
+  if (defaultCompany.value[index]) {
+    defaultCompanyNo = "";
+  }
+  defaultCompany.value.splice(index, 1);
+
+  if (ruleForm.companyArr.length >= 1) {
+    defaultCompany.value[index] = true;
+    const current = ruleForm.companyArr[index];
+
+    if (current) {
+      defaultCompanyNo = ruleForm.companyArr[index].companyCode;
+      defaultCompany.value[index] = true;
+      return;
+    }
+
+    defaultCompanyNo = ruleForm.companyArr[index - 1].companyCode;
+    defaultCompany.value[index - 1] = true;
+  }
+
+  console.log(defaultCompanyNo, defaultCompany.value);
+}
+
+function handleChoose(companys) {
+  const codes = ruleForm.companyArr.map(({ companyCode }) => companyCode);
+
+  companys.forEach(item => {
+    if (!codes.includes(item.code)) {
+      const { code, name } = item;
+      ruleForm.companyArr.push({
+        companyCode: code,
+        companyName: name
+      });
+    }
+  });
+
+  defaultCompany.value = ruleForm.companyArr.map(() => false);
+  const index = ruleForm.companyArr.findIndex(
+    ({ companyCode }) => companyCode === defaultCompanyNo
+  );
+
+  if (index >= 0) {
+    defaultCompany.value[index] = true;
+  }
+}
+
+watch(
+  () => {
+    return props.showModel;
+  },
+  () => {
+    const { showModel, itemId, isDetails, sitem } = props as any;
+    showModelThis.value = showModel;
+    if (showModelThis.value) {
+      id.value = itemId;
+      editType.value = isDetails;
+      if (isDetails !== "add") {
+        initForm(sitem);
+      } else {
+        initForm(formModel);
+      }
+    }
+
+    if (editType.value === "edit" || editType.value === "view") {
+      const index = sitem.company_relaton.findIndex(
+        ({ is_main }) => String(is_main) === "1"
+      );
+
+      if (index >= 0) {
+        defaultCompany.value = sitem.company_relaton.map(() => false);
+        defaultCompanyNo = sitem.company_relaton[index].companyCode;
+        defaultCompany.value[index] = true;
+      }
+    }
+  }
+);
+
+function handleDefaultCompanyChange(index: number) {
+  defaultCompany.value.forEach((_, index) => {
+    defaultCompany.value[index] = false;
+  });
+
+  defaultCompanyNo = ruleForm.companyArr[index].companyCode;
+  defaultCompany.value[index] = true;
+}
+</script>
+
+<template>
+  <el-dialog
+    :close-on-press-escape="false"
+    v-model="showModelThis"
+    append-to-body
+    :width="'900px'"
+    center
+    :title="titleType"
+    v-loading="loading"
+    @close="closeDialog"
+  >
+    <el-form
+      class="demo-ruleForm"
+      ref="ruleFormRef"
+      :model="ruleForm"
+      :rules="rules"
+      label-width="90px"
+      :size="formSize"
+      status-icon
+    >
+      <el-row>
+        <el-col :span="24">
+          <el-form-item label="真实姓名" prop="nickname">
+            <el-input
+              v-model="ruleForm.nickname"
+              :disabled="editType === 'view'"
+              placeholder="真实姓名"
+            /> </el-form-item
+        ></el-col>
+        <el-col :span="24">
+          <el-form-item label="手机号" prop="mobile">
+            <el-input
+              v-model="ruleForm.mobile"
+              :disabled="editType === 'view'"
+              :maxlength="11"
+              placeholder="手机号"
+            /> </el-form-item
+        ></el-col>
+        <el-col :span="24">
+          <el-form-item label="业务公司" prop="companyArr">
+            <el-table
+              :data="ruleForm.companyArr"
+              border
+              size="small"
+              row-key="companyCode"
+              reserve-selection
+              ref="tableRef"
+            >
+              <el-table-column label="默认公司" width="80px">
+                <template #="{ $index }">
+                  <div class="w-full flex justify-center">
+                    <el-checkbox
+                      :disabled="editType === 'view'"
+                      v-model="defaultCompany[$index]"
+                      @change="() => handleDefaultCompanyChange($index)"
+                    />
+                  </div>
+                </template>
+              </el-table-column>
+
+              <el-table-column label="公司编号" prop="companyCode" />
+              <el-table-column label="公司名称" prop="companyName" />
+
+              <el-table-column
+                v-if="editType !== 'view' && isSuperUser"
+                width="100px"
+                label="操作"
+              >
+                <template #header>
+                  <div class="w-full flex justify-between items-center">
+                    <div>操作</div>
+                    <ElButton
+                      text
+                      type="primary"
+                      @click="() => companyModalRef.onDisplay()"
+                      >添加</ElButton
+                    >
+                  </div>
+                </template>
+
+                <template #="{ $index }">
+                  <ElButton
+                    text
+                    type="danger"
+                    @click="() => handleDelete($index)"
+                    >删除</ElButton
+                  >
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-form-item></el-col
+        >
+      </el-row>
+      <el-col :span="24" class="clear">
+        <el-button
+          v-if="editType === 'add' || editType === 'edit'"
+          type="primary"
+          class="fr"
+          style="margin: 0 0 0 16px"
+          @click="submitForm(ruleFormRef)"
+          :loading="loading"
+          >保存</el-button
+        >
+        <el-button class="fr" style="margin: 0 0 0 16px" @click="closeDialog"
+          >关闭</el-button
+        >
+      </el-col>
+    </el-form>
+
+    <CompanyModal ref="companyModalRef" @choose="handleChoose" />
+  </el-dialog>
+</template>

+ 60 - 0
src/views/interest/companyAccount-origin/columns.tsx

@@ -0,0 +1,60 @@
+import { ref } from "vue";
+import dayjs from "dayjs";
+import { statusList } from "/@/utils/status";
+export function useColumns() {
+  const columns = ref([
+    {
+      type: "selection",
+      width: 55,
+      hide: ({ checkList }) => !checkList.includes("勾选列")
+    },
+    {
+      label: "序号",
+      type: "index",
+      width: 70,
+      hide: ({ checkList }) => !checkList.includes("序号列")
+    },
+    {
+      label: "真实姓名",
+      prop: "nickname"
+    },
+    {
+      label: "用户名称",
+      prop: "username"
+    },
+    {
+      label: "状态",
+      prop: "status",
+      width: 80,
+      cellRenderer: ({ row, props }) => (
+        <el-tag
+          size={props.size}
+          type={
+            (statusList.find(item => item.value == row.status + "") || {})
+              .type || "info"
+          }
+          effect="plain"
+        >
+          {(statusList.find(item => item.value == row.status + "") || {})
+            .label || "--"}
+        </el-tag>
+      )
+    },
+    {
+      label: "创建时间",
+      width: 305,
+      prop: "addtime",
+      formatter: ({ addtime }) => dayjs(addtime).format("YYYY-MM-DD HH:mm:ss")
+    },
+    {
+      label: "操作",
+      fixed: "right",
+      width: 145,
+      slot: "operation"
+    }
+  ]);
+
+  return {
+    columns
+  };
+}

+ 133 - 0
src/views/interest/companyAccount-origin/components/company-modal.vue

@@ -0,0 +1,133 @@
+<script setup lang="ts">
+import { ElTable } from "element-plus";
+import { reactive, ref, unref } from "vue";
+import { useResponseHandle } from "/@/hooks/core/useAsync";
+import { httpList } from "/@/api/parameter/supplierPay";
+
+const paymentList = ref<Array<Record<string, string>>>([]);
+const selectOrder = ref<Array<Record<string, string>>>([]);
+
+const params = ref({
+  name: ""
+});
+
+const loading = ref(false);
+const visible = ref(false);
+
+const emit = defineEmits(["choose"]);
+const tableRef = ref<InstanceType<typeof ElTable>>(null);
+const responseHandle = useResponseHandle();
+
+const pagination = reactive({
+  currentPage: 1,
+  pageSize: 10,
+  total: 0
+});
+
+async function requestPaymentList() {
+  const { pageSize: size, currentPage: page } = pagination;
+  loading.value = true;
+  const { code, message, data } = await httpList({
+    ...params.value,
+    size,
+    page
+  });
+
+  responseHandle({
+    code,
+    message,
+    handler: () => {
+      pagination.total = data.count;
+      paymentList.value = data.list;
+    }
+  });
+
+  loading.value = false;
+}
+
+function handleConfirm() {
+  visible.value = false;
+  emit("choose", unref(selectOrder));
+}
+
+function handleSelectionChange(values) {
+  selectOrder.value = values;
+}
+
+function onSearch(_isReset = false) {
+  if (_isReset) {
+    params.value = {
+      name: ""
+    };
+  }
+
+  pagination.currentPage = 1;
+  requestPaymentList();
+}
+
+defineExpose({
+  onDisplay: () => {
+    visible.value = true;
+  }
+});
+</script>
+
+<template>
+  <el-dialog
+    v-model="visible"
+    title="业务公司"
+    center
+    width="1040px"
+    @open="() => requestPaymentList()"
+    @close="() => (params.name = '')"
+  >
+    <div flex mb-2>
+      <div flex flex-1 gap="5" pr="20px">
+        <el-input placeholder="公司名称" size="small" v-model="params.name" />
+      </div>
+
+      <div flex width="120px">
+        <el-button size="small" type="primary" @click="() => onSearch()"
+          >搜索</el-button
+        >
+        <el-button size="small" @click="() => onSearch(true)">重置</el-button>
+      </div>
+    </div>
+
+    <el-table
+      v-loading="loading"
+      border
+      ref="tableRef"
+      :data="paymentList"
+      size="small"
+      row-key="id"
+      @selection-change="handleSelectionChange"
+    >
+      <el-table-column type="selection" width="55" />
+      <el-table-column label="公司编号" prop="code" show-overflow-tooltip />
+      <el-table-column label="公司名称" prop="name" show-overflow-tooltip />
+      <el-table-column label="公司类型" prop="nature" show-overflow-tooltip />
+    </el-table>
+
+    <div flex justify-between mt-2>
+      <el-pagination
+        v-model:current-page="pagination.currentPage"
+        v-model:page-size="pagination.pageSize"
+        :total="pagination.total"
+        @current-change="requestPaymentList"
+      />
+
+      <el-button type="primary" size="small" @click="handleConfirm"
+        >确定</el-button
+      >
+    </div>
+  </el-dialog>
+</template>
+
+<style lang="scss" scoped>
+:deep(.el-table__header) {
+  .el-checkbox {
+    display: none;
+  }
+}
+</style>

+ 329 - 0
src/views/interest/companyAccount-origin/index.vue

@@ -0,0 +1,329 @@
+<script setup lang="ts">
+import { watch } from "vue";
+import { useColumns } from "./columns";
+import { httpList, httpStatus } from "/@/api/interest/account";
+import { reactive, ref, onMounted } from "vue";
+import { type FormInstance } from "element-plus";
+import { TableProBar } from "/@/components/ReTable";
+import { type PaginationProps } from "@pureadmin/table";
+import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
+import { useNav } from "/@/layout/hooks/nav";
+import { statusList } from "/@/utils/status";
+import addEdit from "./addEdit.vue";
+import resetPassword from "./resetPassword.vue";
+import { responseHandle } from "/@/utils/responseHandle";
+import { useUserStoreHook } from "/@/store/modules/user";
+import { useCompany } from "/@/hooks/core/useCompany";
+import { type menuType } from "./types";
+
+const { logout } = useNav();
+
+defineOptions({
+  name: "companyAccount"
+});
+
+const powers = ref([]);
+const form = reactive({
+  nickname: "",
+  username: "",
+  status: "",
+  page: 1,
+  size: 15
+});
+
+const dataList = ref([]);
+const loading = ref(true);
+const showModel = ref(false);
+const itemId = ref("");
+const isDetails = ref("add");
+
+const { columns } = useColumns();
+const { currentCompany } = useCompany();
+
+const sitem = reactive<menuType>({
+  id: "", //账户id
+  nickname: "", //真实姓名
+  mobile: "", //手机号
+  role: "", //角色,
+  companyArr: []
+});
+
+const passwordModelId = ref("");
+const passwordModel = ref(false);
+const formRef = ref<FormInstance>();
+const pagination = reactive<PaginationProps>({
+  total: 0,
+  pageSize: 15,
+  currentPage: 1,
+  background: true
+});
+
+//重置密码
+const resetRwd = async row => {
+  const { id } = row;
+  passwordModelId.value = id;
+  passwordModel.value = true;
+};
+
+//修改状态
+const handleStatus = async row => {
+  const { id, status } = row;
+  const { code, message } = await httpStatus({
+    id,
+    status: status + "" === "1" ? "0" : "1"
+  });
+  responseHandle({
+    code,
+    message,
+    logout,
+    handler: () => onSearch()
+  });
+};
+
+async function handleCurrentChange(val: number) {
+  form.page = val;
+  await onSearch();
+}
+
+async function handleSizeChange(val: number) {
+  form.size = val;
+  form.page = 1;
+  await onSearch();
+}
+
+function handleSelectionChange(val) {
+  console.log("handleSelectionChange", val);
+}
+
+async function onSearch() {
+  loading.value = true;
+
+  const { code, data, message } = await httpList({
+    ...form,
+    islevel: "2",
+    companyNo: currentCompany.value.companyNo,
+    noRela: currentCompany.value.companyNo === ""
+  });
+
+  responseHandle({
+    code,
+    message,
+    logout,
+    handler: () => {
+      const { list, count } = data;
+      dataList.value = list ?? [];
+      pagination.total = count ?? 0;
+      pagination.pageSize = form.size;
+      pagination.currentPage = form.page;
+    }
+  });
+  loading.value = false;
+}
+async function resetSearch() {
+  form.page = 1;
+  await onSearch();
+}
+//新建/编辑/详情弹窗
+function editItem(id, type, item) {
+  itemId.value = id;
+  isDetails.value = type;
+  for (let key in item) {
+    sitem[key] = item[key];
+  }
+  showModel.value = true;
+}
+const submitRefresh = () => {
+  showModel.value = false;
+  onSearch();
+};
+const submitCancel = () => {
+  showModel.value = false;
+};
+const resetCancel = () => {
+  passwordModel.value = false;
+};
+
+const resetForm = (formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.resetFields();
+  form.page = 1;
+  onSearch();
+};
+
+watch(
+  () => currentCompany.value,
+  () => onSearch()
+);
+
+onMounted(() => {
+  powers.value = useUserStoreHook().getMenuActions("companyAccount");
+  onSearch();
+});
+</script>
+
+<template>
+  <div class="main">
+    <div v-show="powers.some(i => i == '001')">
+      <el-form
+        ref="formRef"
+        :inline="true"
+        :model="form"
+        size="small"
+        :label-width="0"
+        class="bg-white w-99/100 pl-8 pt-4"
+      >
+        <el-form-item prop="status">
+          <el-select
+            v-model="form.status"
+            style="width: 100%"
+            placeholder="账号状态"
+            clearable
+          >
+            <el-option
+              v-for="(si, sii) in statusList"
+              :key="'status' + si.value + sii"
+              :label="si.label"
+              :value="si.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item prop="nickname">
+          <el-input v-model="form.nickname" placeholder="真实姓名" clearable />
+        </el-form-item>
+        <el-form-item prop="username">
+          <el-input v-model="form.username" placeholder="手机号" clearable />
+        </el-form-item>
+        <el-form-item>
+          <el-button
+            type="primary"
+            :icon="useRenderIcon('search')"
+            :loading="loading"
+            @click="resetSearch"
+          >
+            搜索
+          </el-button>
+          <el-button
+            :icon="useRenderIcon('refresh')"
+            @click="resetForm(formRef)"
+          >
+            重置
+          </el-button>
+        </el-form-item>
+      </el-form>
+
+      <TableProBar
+        title="公司账号管理"
+        :loading="loading"
+        :dataList="dataList"
+        size="small"
+        @refresh="onSearch"
+      >
+        <template #buttons>
+          <el-button
+            type="primary"
+            size="small"
+            :icon="useRenderIcon('add')"
+            @click="editItem('', 'add', {})"
+          >
+            新增账号
+          </el-button>
+        </template>
+        <template v-slot="{ size, checkList }">
+          <PureTable
+            border
+            align="left"
+            showOverflowTooltip
+            table-layout="auto"
+            size="small"
+            :data="dataList"
+            :columns="columns"
+            :checkList="checkList"
+            :pagination="pagination"
+            :paginationSmall="size === 'small' ? true : false"
+            :header-cell-style="{ background: '#fafafa', color: '#606266' }"
+            @selection-change="handleSelectionChange"
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+          >
+            <template #operation="{ row }">
+              <el-popconfirm :title="'确认重置密码?'" @confirm="resetRwd(row)">
+                <template #reference>
+                  <el-button
+                    class="reset-margin"
+                    link
+                    type="primary"
+                    size="small"
+                    v-if="powers.some(i => i == '012')"
+                    :icon="useRenderIcon('refresh-right')"
+                  /> </template
+              ></el-popconfirm>
+              <el-button
+                class="reset-margin"
+                v-if="powers.some(i => i == '007')"
+                link
+                type="primary"
+                size="small"
+                @click="editItem(row.id, 'view', row)"
+                :icon="useRenderIcon('eye-view')"
+              />
+              <el-button
+                class="reset-margin"
+                link
+                v-if="powers.some(i => i == '005')"
+                type="primary"
+                size="small"
+                @click="editItem(row.id, 'edit', row)"
+                :icon="useRenderIcon('edits')"
+              />
+              <el-popconfirm
+                :title="
+                  String(row.status) === '1' ? '改为禁用?' : '改为启用?'
+                "
+                v-if="
+                  (powers.some(i => i == '004') && row.status + '' === '1') ||
+                  (powers.some(i => i == '003') && row.status + '' === '0')
+                "
+                @confirm="handleStatus(row)"
+              >
+                <template #reference>
+                  <el-button
+                    class="reset-margin"
+                    link
+                    type="primary"
+                    size="small"
+                    :icon="
+                      useRenderIcon(
+                        String(row.status) === '1'
+                          ? 'close-circle-line'
+                          : 'checkbox-circle-line'
+                      )
+                    " /></template
+              ></el-popconfirm>
+            </template>
+          </PureTable>
+        </template>
+      </TableProBar>
+      <addEdit
+        :itemId="itemId"
+        :isDetails="isDetails"
+        :show-model="showModel"
+        @refresh="submitRefresh"
+        @cancel="submitCancel"
+        :sitem="sitem"
+      />
+      <reset-password
+        :itemId="passwordModelId"
+        :show-model="passwordModel"
+        @refresh="resetCancel"
+        @cancel="resetCancel"
+      />
+    </div>
+    <NoAuth v-show="!powers.some(i => i == '001')" />
+  </div>
+</template>
+
+<style scoped lang="scss">
+:deep(.el-dropdown-menu__item i) {
+  margin: 0;
+}
+</style>

+ 198 - 0
src/views/interest/companyAccount-origin/resetPassword.vue

@@ -0,0 +1,198 @@
+<script setup lang="ts">
+import { httpSetPwd } from "/@/api/interest/account";
+import { ElMessage, FormInstance, FormRules } from "element-plus";
+import { reactive, ref, watch, nextTick } from "vue";
+import { useNav } from "/@/layout/hooks/nav";
+import { isAlphanumeric, isnumber, validAlphabets } from "/@/utils/validate";
+const { logout } = useNav();
+const formSize = ref("default");
+const ruleFormRef = ref<FormInstance>();
+interface formType {
+  id?: string; //账户id
+  password?: string; //新密码
+  confirmPassword?: string; //确认密码
+}
+const props = defineProps({
+  itemId: {
+    type: String,
+    default: ""
+  },
+  showModel: {
+    type: Boolean,
+    default: false
+  }
+});
+const showModelThis = ref(false);
+const emit = defineEmits<{
+  (e: "cancel"): void;
+  (e: "refresh"): void;
+}>();
+const id = ref("");
+const formModel = {
+  id: "", //账户id
+  password: "", //新密码
+  confirmPassword: "" //确认密码
+};
+const ruleForm = reactive<formType>(formModel);
+const rules = reactive<FormRules>({
+  password: [
+    {
+      required: true,
+      validator: (rule, value, callback) => {
+        if (value === "") {
+          callback(new Error("新密码不能为空!"));
+        } else {
+          if (!isAlphanumeric(value)) {
+            callback(new Error("新密码为6-16位数字字母组合!"));
+          } else if (value.length < 6 || value.length > 16) {
+            callback(new Error("新密码为6-16位数字字母组合!"));
+          } else if (isnumber(value)) {
+            callback(new Error("新密码不能为纯数字!"));
+          } else if (validAlphabets(value)) {
+            callback(new Error("新密码不能为纯字母!"));
+          } else {
+            callback();
+          }
+        }
+      },
+      trigger: "blur"
+    }
+  ],
+  confirmPassword: [
+    {
+      required: true,
+      validator: (rule, value, callback) => {
+        if (value === "") {
+          callback(new Error("确认密码不能为空!"));
+        } else {
+          if (ruleForm.password !== value) {
+            callback(new Error("确认密码与新密码不一致!"));
+          } else {
+            callback();
+          }
+        }
+      },
+
+      trigger: "blur"
+    }
+  ]
+});
+const submitForm = async (formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      if (loading.value === true) return;
+      loading.value = true;
+      let model = Object.assign({}, ruleForm);
+      model.id = id.value;
+      const { code, message } = await httpSetPwd(model);
+      loading.value = false;
+      if (code === 0) {
+        ElMessage.success("密码修改成功!");
+        showModelThis.value = false;
+        emit("refresh");
+      } else if (code > 100 && code < 140) {
+        showModelThis.value = false;
+        logout();
+      } else {
+        ElMessage.error(message);
+      }
+    } else {
+      console.log("error submit!", fields);
+    }
+  });
+};
+const resetForm = async (formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.clearValidate();
+  formEl.resetFields();
+  await nextTick(async () => {
+    ruleForm.id = id.value;
+    ruleForm.password = ""; //新密码
+    ruleForm.confirmPassword = ""; //确认密码
+  });
+};
+const closeDialog = () => {
+  showModelThis.value = false;
+  emit("cancel");
+};
+
+const loading = ref(true);
+const titleType = ref("");
+async function initForm() {
+  loading.value = true;
+  titleType.value = "修改密码";
+
+  await resetForm(ruleFormRef.value);
+
+  console.log(ruleForm);
+  loading.value = false;
+}
+watch(
+  () => {
+    return props.showModel;
+  },
+  () => {
+    const { showModel, itemId } = props;
+    showModelThis.value = showModel;
+    if (showModelThis.value) {
+      id.value = itemId;
+      console.log(id.value);
+      initForm();
+    }
+  }
+);
+</script>
+
+<template>
+  <el-dialog
+    :close-on-press-escape="false"
+    v-model="showModelThis"
+    append-to-body
+    :width="'900px'"
+    :title="titleType"
+    v-loading="loading"
+    @close="closeDialog"
+  >
+    <el-form
+      ref="ruleFormRef"
+      :model="ruleForm"
+      :rules="rules"
+      label-width="90px"
+      style="margin-top: -10px"
+      class="demo-ruleForm"
+      :size="formSize"
+      status-icon
+    >
+      <el-row>
+        <el-col :span="8">
+          <el-form-item label="新密码" prop="password">
+            <el-input
+              v-model="ruleForm.password"
+              placeholder="新密码"
+            /> </el-form-item
+        ></el-col>
+        <el-col :span="8">
+          <el-form-item label="确认密码" prop="confirmPassword">
+            <el-input
+              v-model="ruleForm.confirmPassword"
+              :maxlength="11"
+              placeholder="确认密码"
+            /> </el-form-item
+        ></el-col>
+      </el-row>
+      <el-col :span="24" class="clear">
+        <el-button
+          type="primary"
+          class="fr"
+          style="margin: 0 0 0 16px"
+          @click="submitForm(ruleFormRef)"
+          >保存</el-button
+        >
+        <el-button class="fr" style="margin: 0 0 0 16px" @click="closeDialog"
+          >关闭</el-button
+        >
+      </el-col>
+    </el-form>
+  </el-dialog>
+</template>

+ 8 - 0
src/views/interest/companyAccount-origin/types.ts

@@ -0,0 +1,8 @@
+export interface menuType {
+  id?: string; //账户id
+  nickname?: string; //真实姓名
+  mobile?: string; //手机号
+  email?: string; //邮箱
+  role?: string; //角色
+  companyArr?: any;
+}

+ 6 - 10
src/views/interest/companyAccount/addEdit.vue

@@ -1,9 +1,5 @@
 <script setup lang="ts">
-import {
-  httpAdd,
-  httpUpdate,
-  httpDetail
-} from "/@/api/interest/companyAccount";
+import { httpAdd, httpUpdate } from "/@/api/interest/companyAccount";
 import { ElMessage, FormInstance, FormRules } from "element-plus";
 import { reactive, ref, watch, nextTick } from "vue";
 import { useNav } from "/@/layout/hooks/nav";
@@ -74,7 +70,6 @@ const rules = reactive<FormRules>({
           callback();
         }
       },
-
       trigger: "blur"
     }
   ],
@@ -260,11 +255,11 @@ function handleChoose(companys) {
   const codes = ruleForm.companyArr.map(({ companyCode }) => companyCode);
 
   companys.forEach(item => {
-    if (!codes.includes(item.code)) {
-      const { code, name } = item;
+    if (!codes.includes(item.companyNo)) {
+      const { companyNo, company_name } = item;
       ruleForm.companyArr.push({
-        companyCode: code,
-        companyName: name
+        companyCode: companyNo,
+        companyName: company_name
       });
     }
   });
@@ -286,6 +281,7 @@ watch(
   () => {
     const { showModel, itemId, isDetails, sitem } = props as any;
     showModelThis.value = showModel;
+
     if (showModelThis.value) {
       id.value = itemId;
       editType.value = isDetails;

+ 3 - 4
src/views/interest/companyAccount/components/company-modal.vue

@@ -2,7 +2,7 @@
 import { ElTable } from "element-plus";
 import { reactive, ref, unref } from "vue";
 import { useResponseHandle } from "/@/hooks/core/useAsync";
-import { httpList } from "/@/api/parameter/supplierPay";
+import { httpCompanyList } from "/@/api/interest/account";
 
 const paymentList = ref<Array<Record<string, string>>>([]);
 const selectOrder = ref<Array<Record<string, string>>>([]);
@@ -27,7 +27,7 @@ const pagination = reactive({
 async function requestPaymentList() {
   const { pageSize: size, currentPage: page } = pagination;
   loading.value = true;
-  const { code, message, data } = await httpList({
+  const { code, message, data } = await httpCompanyList({
     ...params.value,
     size,
     page
@@ -104,11 +104,10 @@ defineExpose({
       @selection-change="handleSelectionChange"
     >
       <el-table-column type="selection" width="55" />
-      <el-table-column label="公司编号" prop="code" show-overflow-tooltip />
+      <el-table-column label="公司编号" prop="companyNo" show-overflow-tooltip />
       <el-table-column label="公司名称" prop="name" show-overflow-tooltip />
       <el-table-column label="公司类型" prop="nature" show-overflow-tooltip />
     </el-table>
-
     <div flex justify-between mt-2>
       <el-pagination
         v-model:current-page="pagination.currentPage"

+ 5 - 2
src/views/interest/companyAccount/index.vue

@@ -9,13 +9,14 @@ import { type PaginationProps } from "@pureadmin/table";
 import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
 import { useNav } from "/@/layout/hooks/nav";
 import { statusList } from "/@/utils/status";
-import addEdit from "./addEdit.vue";
-import resetPassword from "./resetPassword.vue";
 import { responseHandle } from "/@/utils/responseHandle";
 import { useUserStoreHook } from "/@/store/modules/user";
 import { useCompany } from "/@/hooks/core/useCompany";
 import { type menuType } from "./types";
 
+import addEdit from "./addEdit.vue";
+import resetPassword from "./resetPassword.vue";
+
 const { logout } = useNav();
 
 defineOptions({
@@ -72,6 +73,8 @@ const handleStatus = async row => {
     id,
     status: status + "" === "1" ? "0" : "1"
   });
+
+
   responseHandle({
     code,
     message,

+ 2 - 3
src/views/reportForm/reportRecord/index.vue

@@ -55,8 +55,8 @@ const hooks: PageHooks = {
           ElMessage.warning("立即执行时,时间区间不能超过7天!");
           return false;
         }
-        if (String(type) === "2" && day > 30) {
-          ElMessage.warning("延时执行时,时间区间不能超过30天!");
+        if (String(type) === "2" && day > 31) {
+          ElMessage.warning("延时执行时,时间区间不能超过31天!");
           return false;
         }
         if (!companyNo) {
@@ -73,7 +73,6 @@ const hooks: PageHooks = {
 };
 watchEffect(() => {
   if (currentCompany.value.companyNo) {
-    console.log("1234");
     get_list();
   }
 });

+ 431 - 0
src/views/supplierManage/supplierAccoutManage/addEdit.vue

@@ -0,0 +1,431 @@
+<script setup lang="ts">
+import { ElMessage, FormInstance, FormRules } from "element-plus";
+import { reactive, ref, watch, nextTick } from "vue";
+import { useNav } from "/@/layout/hooks/nav";
+import { isMobile } from "/@/utils/validate";
+import CompanyModal from "./components/company-modal.vue";
+import { type menuType } from "./types";
+import { useUserInfo } from "/@/hooks/core/useUser";
+
+import { httpAdd, httpUpdate } from "/@/api/supplierManage/supplierAccoutManage";
+
+const { logout } = useNav();
+const formSize = ref("default");
+const ruleFormRef = ref<FormInstance>();
+
+const props = defineProps({
+  itemId: {
+    type: String,
+    default: ""
+  },
+  showModel: {
+    type: Boolean,
+    default: false
+  },
+  isDetails: {
+    type: String,
+    default: "add"
+  },
+  sitem: {
+    type: Object as PropType<menuType>
+  }
+});
+
+const defaultCompany = ref<boolean[]>([]);
+let defaultCompanyNo = "";
+
+const showModelThis = ref(false);
+const emit = defineEmits<{
+  (e: "cancel"): void;
+  (e: "refresh"): void;
+}>();
+const id = ref("");
+const editType = ref("add");
+const formModel = {
+  id: "", //账户id
+  nickname: "", //真实姓名
+  mobile: "", //手机号
+  companyArr: []
+};
+
+const tableRef = ref<any>(null);
+const ruleForm = reactive<menuType>({ ...formModel });
+const companyModalRef = ref<InstanceType<typeof CompanyModal> | null>(null);
+const { isSuperUser } = useUserInfo();
+
+let originCompanyArr: any[] = [];
+const rules = reactive<FormRules>({
+  nickname: [
+    { required: true, message: "请输入真实姓名", trigger: "blur" },
+    { min: 2, max: 12, message: "长度在 2 到 12 个字符", trigger: "blur" }
+  ],
+  mobile: [
+    {
+      required: true,
+      validator: (rule, value, callback) => {
+        if (value === "") {
+          callback(new Error("手机号不能为空!"));
+        } else if (!isMobile(value)) {
+          callback(new Error("手机号格式不正确!"));
+        } else {
+          callback();
+        }
+      },
+
+      trigger: "blur"
+    }
+  ],
+  companyArr: [
+    {
+      required: true,
+      validator: (rule, value, callback) => {
+        if (value.length === 0) {
+          callback(new Error("请选择业务公司"));
+        } else {
+          callback();
+        }
+      }
+    }
+  ]
+});
+
+const submitForm = async (formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+
+  if (!defaultCompanyNo) {
+    ElMessage.warning("请选择默认公司");
+    return;
+  }
+
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      if (loading.value === true) return;
+      const model = Object.assign({}, ruleForm);
+
+      if (editType.value === "add") delete model.id;
+      const current = model.companyArr.map(({ companyCode }) => companyCode);
+      const dels = originCompanyArr
+        .filter(({ companyCode }) => !current.includes(companyCode))
+        .map(({ companyCode, companyName, id }) => ({
+          id,
+          companyCode,
+          companyName,
+          is_del: 1,
+          is_main: "0"
+        }));
+
+      const orgs = originCompanyArr
+        .filter(({ companyCode }) => current.includes(companyCode))
+        .map(({ companyCode, companyName, id }) => ({
+          id,
+          companyCode,
+          companyName,
+          is_del: 0,
+          is_main: "0"
+        }));
+
+      const adds = model.companyArr
+        .filter(({ companyCode: code }) => {
+          return (
+            !dels.find(({ companyCode }) => companyCode === code) &&
+            !orgs.find(({ companyCode }) => companyCode === code)
+          );
+        })
+        .map(({ companyCode, companyName, id }) => ({
+          id,
+          companyCode,
+          companyName,
+          is_main: "0",
+          is_del: 0
+        }));
+
+      model.companyArr = [...dels, ...orgs, ...adds];
+
+      model.companyArr.forEach(item => {
+        if (item.companyCode === defaultCompanyNo) {
+          item.is_main = "1";
+        }
+      });
+
+      loading.value = true;
+      const { code, message } =
+        editType.value === "add"
+          ? await httpAdd(model)
+          : await httpUpdate(model);
+      loading.value = false;
+
+      if (code === 0) {
+        ElMessage.success(titleType.value + "成功!");
+        showModelThis.value = false;
+        emit("refresh");
+      } else if (code > 100 && code < 140) {
+        showModelThis.value = false;
+        logout();
+      } else {
+        ElMessage.error(message);
+      }
+    } else {
+      console.log("error submit!", fields);
+    }
+  });
+};
+
+const resetForm = async (formEl: FormInstance | undefined, item) => {
+  if (formEl) {
+    formEl.clearValidate();
+    formEl.resetFields();
+  }
+
+  await nextTick(async () => {
+    for (let key in ruleForm) {
+      if (key === "companyArr" && item["company_relaton"]) {
+        if (editType.value !== "add") {
+          item["company_relaton"].forEach(item => {
+            ruleForm.companyArr.push({ ...item });
+          });
+        } else {
+          ruleForm.companyArr = [];
+        }
+      } else {
+        ruleForm[key] = item[key];
+      }
+    }
+  });
+
+  originCompanyArr = item.company_relaton?.map(item => ({ ...item })) || [];
+
+  if (editType.value === "add") {
+    ruleForm.companyArr = [];
+    originCompanyArr = [];
+  }
+};
+
+const closeDialog = () => {
+  showModelThis.value = false;
+  defaultCompany.value = [];
+  ruleForm.companyArr = [];
+  defaultCompanyNo = "";
+  emit("cancel");
+};
+
+const loading = ref(true);
+const titleType = ref("");
+async function initForm(item: Object) {
+  loading.value = true;
+  switch (editType.value) {
+    case "add":
+      titleType.value = "新建账号";
+      break;
+    case "edit":
+      titleType.value = "编辑账号";
+      break;
+    case "view":
+      titleType.value = "账号详情";
+      break;
+    default:
+      titleType.value = "新建账号";
+  }
+  resetForm(ruleFormRef.value, item);
+  loading.value = false;
+}
+
+function handleDelete(index) {
+  ruleForm.companyArr.splice(index, 1);
+  if (defaultCompany.value[index]) {
+    defaultCompanyNo = "";
+  }
+  defaultCompany.value.splice(index, 1);
+
+  if (ruleForm.companyArr.length >= 1) {
+    defaultCompany.value[index] = true;
+    const current = ruleForm.companyArr[index];
+
+    if (current) {
+      defaultCompanyNo = ruleForm.companyArr[index].companyCode;
+      defaultCompany.value[index] = true;
+      return;
+    }
+
+    defaultCompanyNo = ruleForm.companyArr[index - 1].companyCode;
+    defaultCompany.value[index - 1] = true;
+  }
+
+  console.log(defaultCompanyNo, defaultCompany.value);
+}
+
+function handleChoose(companys) {
+  const codes = ruleForm.companyArr.map(({ companyCode }) => companyCode);
+
+  companys.forEach(item => {
+    if (!codes.includes(item.code)) {
+      const { code, name } = item;
+      ruleForm.companyArr.push({
+        companyCode: code,
+        companyName: name
+      });
+    }
+  });
+
+  defaultCompany.value = ruleForm.companyArr.map(() => false);
+  const index = ruleForm.companyArr.findIndex(
+    ({ companyCode }) => companyCode === defaultCompanyNo
+  );
+
+  if (index >= 0) {
+    defaultCompany.value[index] = true;
+  }
+}
+
+watch(
+  () => {
+    return props.showModel;
+  },
+  () => {
+    const { showModel, itemId, isDetails, sitem } = props as any;
+    showModelThis.value = showModel;
+    if (showModelThis.value) {
+      id.value = itemId;
+      editType.value = isDetails;
+      if (isDetails !== "add") {
+        initForm(sitem);
+      } else {
+        initForm(formModel);
+      }
+    }
+
+    if (editType.value === "edit" || editType.value === "view") {
+      const index = sitem.company_relaton.findIndex(
+        ({ is_main }) => String(is_main) === "1"
+      );
+
+      if (index >= 0) {
+        defaultCompany.value = sitem.company_relaton.map(() => false);
+        defaultCompanyNo = sitem.company_relaton[index].companyCode;
+        defaultCompany.value[index] = true;
+      }
+    }
+  }
+);
+
+function handleDefaultCompanyChange(index: number) {
+  defaultCompany.value.forEach((_, index) => {
+    defaultCompany.value[index] = false;
+  });
+
+  defaultCompanyNo = ruleForm.companyArr[index].companyCode;
+  defaultCompany.value[index] = true;
+}
+</script>
+
+<template>
+  <el-dialog
+    :close-on-press-escape="false"
+    v-model="showModelThis"
+    append-to-body
+    :width="'900px'"
+    center
+    :title="titleType"
+    v-loading="loading"
+    @close="closeDialog"
+  >
+    <el-form
+      class="demo-ruleForm"
+      ref="ruleFormRef"
+      :model="ruleForm"
+      :rules="rules"
+      label-width="90px"
+      :size="formSize"
+      status-icon
+    >
+      <el-row>
+        <el-col :span="24">
+          <el-form-item label="真实姓名" prop="nickname">
+            <el-input
+              v-model="ruleForm.nickname"
+              :disabled="editType === 'view'"
+              placeholder="真实姓名"
+            /> </el-form-item
+        ></el-col>
+        <el-col :span="24">
+          <el-form-item label="手机号" prop="mobile">
+            <el-input
+              v-model="ruleForm.mobile"
+              :disabled="editType === 'view'"
+              :maxlength="11"
+              placeholder="手机号"
+            /> </el-form-item
+        ></el-col>
+        <el-col :span="24">
+          <el-form-item label="业务公司" prop="companyArr">
+            <el-table
+              :data="ruleForm.companyArr"
+              border
+              size="small"
+              row-key="companyCode"
+              reserve-selection
+              ref="tableRef"
+            >
+              <el-table-column label="默认公司" width="80px">
+                <template #="{ $index }">
+                  <div class="w-full flex justify-center">
+                    <el-checkbox
+                      :disabled="editType === 'view'"
+                      v-model="defaultCompany[$index]"
+                      @change="() => handleDefaultCompanyChange($index)"
+                    />
+                  </div>
+                </template>
+              </el-table-column>
+
+              <el-table-column label="公司编号" prop="companyCode" />
+              <el-table-column label="公司名称" prop="companyName" />
+
+              <el-table-column
+                v-if="editType !== 'view' && isSuperUser"
+                width="100px"
+                label="操作"
+              >
+                <template #header>
+                  <div class="w-full flex justify-between items-center">
+                    <div>操作</div>
+                    <ElButton
+                      text
+                      type="primary"
+                      @click="() => companyModalRef.onDisplay()"
+                      >添加</ElButton
+                    >
+                  </div>
+                </template>
+
+                <template #="{ $index }">
+                  <ElButton
+                    text
+                    type="danger"
+                    @click="() => handleDelete($index)"
+                    >删除</ElButton
+                  >
+                </template>
+              </el-table-column>
+            </el-table>
+          </el-form-item></el-col
+        >
+      </el-row>
+      <el-col :span="24" class="clear">
+        <el-button
+          v-if="editType === 'add' || editType === 'edit'"
+          type="primary"
+          class="fr"
+          style="margin: 0 0 0 16px"
+          @click="submitForm(ruleFormRef)"
+          :loading="loading"
+          >保存</el-button
+        >
+        <el-button class="fr" style="margin: 0 0 0 16px" @click="closeDialog"
+          >关闭</el-button
+        >
+      </el-col>
+    </el-form>
+
+    <CompanyModal ref="companyModalRef" @choose="handleChoose" />
+  </el-dialog>
+</template>

+ 60 - 0
src/views/supplierManage/supplierAccoutManage/columns.tsx

@@ -0,0 +1,60 @@
+import { ref } from "vue";
+import dayjs from "dayjs";
+import { statusList } from "/@/utils/status";
+export function useColumns() {
+  const columns = ref([
+    {
+      type: "selection",
+      width: 55,
+      hide: ({ checkList }) => !checkList.includes("勾选列")
+    },
+    {
+      label: "序号",
+      type: "index",
+      width: 70,
+      hide: ({ checkList }) => !checkList.includes("序号列")
+    },
+    {
+      label: "真实姓名",
+      prop: "nickname"
+    },
+    {
+      label: "用户名称",
+      prop: "username"
+    },
+    {
+      label: "状态",
+      prop: "status",
+      width: 80,
+      cellRenderer: ({ row, props }) => (
+        <el-tag
+          size={props.size}
+          type={
+            (statusList.find(item => item.value == row.status + "") || {})
+              .type || "info"
+          }
+          effect="plain"
+        >
+          {(statusList.find(item => item.value == row.status + "") || {})
+            .label || "--"}
+        </el-tag>
+      )
+    },
+    {
+      label: "创建时间",
+      width: 305,
+      prop: "addtime",
+      formatter: ({ addtime }) => dayjs(addtime).format("YYYY-MM-DD HH:mm:ss")
+    },
+    {
+      label: "操作",
+      fixed: "right",
+      width: 145,
+      slot: "operation"
+    }
+  ]);
+
+  return {
+    columns
+  };
+}

+ 133 - 0
src/views/supplierManage/supplierAccoutManage/components/company-modal.vue

@@ -0,0 +1,133 @@
+<script setup lang="ts">
+import { ElTable } from "element-plus";
+import { reactive, ref, unref } from "vue";
+import { useResponseHandle } from "/@/hooks/core/useAsync";
+import { httpList } from "/@/api/parameter/supplierPay";
+
+const paymentList = ref<Array<Record<string, string>>>([]);
+const selectOrder = ref<Array<Record<string, string>>>([]);
+
+const params = ref({
+  name: ""
+});
+
+const loading = ref(false);
+const visible = ref(false);
+
+const emit = defineEmits(["choose"]);
+const tableRef = ref<InstanceType<typeof ElTable>>(null);
+const responseHandle = useResponseHandle();
+
+const pagination = reactive({
+  currentPage: 1,
+  pageSize: 10,
+  total: 0
+});
+
+async function requestPaymentList() {
+  const { pageSize: size, currentPage: page } = pagination;
+  loading.value = true;
+  const { code, message, data } = await httpList({
+    ...params.value,
+    size,
+    page
+  });
+
+  responseHandle({
+    code,
+    message,
+    handler: () => {
+      pagination.total = data.count;
+      paymentList.value = data.list;
+    }
+  });
+
+  loading.value = false;
+}
+
+function handleConfirm() {
+  visible.value = false;
+  emit("choose", unref(selectOrder));
+}
+
+function handleSelectionChange(values) {
+  selectOrder.value = values;
+}
+
+function onSearch(_isReset = false) {
+  if (_isReset) {
+    params.value = {
+      name: ""
+    };
+  }
+
+  pagination.currentPage = 1;
+  requestPaymentList();
+}
+
+defineExpose({
+  onDisplay: () => {
+    visible.value = true;
+  }
+});
+</script>
+
+<template>
+  <el-dialog
+    v-model="visible"
+    title="供应商"
+    center
+    width="1040px"
+    @open="() => requestPaymentList()"
+    @close="() => (params.name = '')"
+  >
+    <div flex mb-2>
+      <div flex flex-1 gap="5" pr="20px">
+        <el-input placeholder="公司名称" size="small" v-model="params.name" />
+      </div>
+
+      <div flex width="120px">
+        <el-button size="small" type="primary" @click="() => onSearch()"
+          >搜索</el-button
+        >
+        <el-button size="small" @click="() => onSearch(true)">重置</el-button>
+      </div>
+    </div>
+
+    <el-table
+      v-loading="loading"
+      border
+      ref="tableRef"
+      :data="paymentList"
+      size="small"
+      row-key="id"
+      @selection-change="handleSelectionChange"
+    >
+      <el-table-column type="selection" width="55" />
+      <el-table-column label="公司编号" prop="code" show-overflow-tooltip />
+      <el-table-column label="公司名称" prop="name" show-overflow-tooltip />
+      <el-table-column label="公司类型" prop="nature" show-overflow-tooltip />
+    </el-table>
+
+    <div flex justify-between mt-2>
+      <el-pagination
+        v-model:current-page="pagination.currentPage"
+        v-model:page-size="pagination.pageSize"
+        :total="pagination.total"
+        @current-change="requestPaymentList"
+      />
+
+      <el-button type="primary" size="small" @click="handleConfirm"
+        >确定</el-button
+      >
+    </div>
+  </el-dialog>
+</template>
+
+<style lang="scss" scoped>
+:deep(.el-table__header) {
+  .el-checkbox {
+    display: none;
+  }
+}
+</style>

+ 331 - 0
src/views/supplierManage/supplierAccoutManage/index.vue

@@ -0,0 +1,331 @@
+<script setup lang="ts">
+import { watch } from "vue";
+import { useColumns } from "./columns";
+import { httpList, httpStatus } from "/@/api/supplierManage/supplierAccoutManage";
+import { reactive, ref, onMounted } from "vue";
+import { type FormInstance } from "element-plus";
+import { TableProBar } from "/@/components/ReTable";
+import { type PaginationProps } from "@pureadmin/table";
+import { useRenderIcon } from "/@/components/ReIcon/src/hooks";
+import { useNav } from "/@/layout/hooks/nav";
+import { statusList } from "/@/utils/status";
+import { responseHandle } from "/@/utils/responseHandle";
+import { useUserStoreHook } from "/@/store/modules/user";
+import { useCompany } from "/@/hooks/core/useCompany";
+import { type menuType } from "./types";
+
+import addEdit from "./addEdit.vue";
+import resetPassword from "./resetPassword.vue";
+
+const { logout } = useNav();
+
+defineOptions({
+  name: "supplierAccoutManage"
+});
+
+const powers = ref([]);
+const form = reactive({
+  nickname: "",
+  username: "",
+  status: "",
+  page: 1,
+  size: 15
+});
+
+const dataList = ref([]);
+const loading = ref(true);
+const showModel = ref(false);
+const itemId = ref("");
+const isDetails = ref("add");
+
+const { columns } = useColumns();
+const { currentCompany } = useCompany();
+
+const sitem = reactive<menuType>({
+  id: "", //账户id
+  nickname: "", //真实姓名
+  mobile: "", //手机号
+  role: "", //角色,
+  companyArr: []
+});
+
+const passwordModelId = ref("");
+const passwordModel = ref(false);
+const formRef = ref<FormInstance>();
+
+const pagination = reactive<PaginationProps>({
+  total: 0,
+  pageSize: 15,
+  currentPage: 1,
+  background: true
+});
+
+// 重置密码
+const resetRwd = async row => {
+  const { id } = row;
+  passwordModelId.value = id;
+  passwordModel.value = true;
+};
+
+//修改状态
+const handleStatus = async row => {
+  const { id, status } = row;
+  const { code, message } = await httpStatus({
+    id,
+    status: status + "" === "1" ? "0" : "1"
+  });
+  responseHandle({
+    code,
+    message,
+    logout,
+    handler: () => onSearch()
+  });
+};
+
+async function handleCurrentChange(val: number) {
+  form.page = val;
+  await onSearch();
+}
+
+async function handleSizeChange(val: number) {
+  form.size = val;
+  form.page = 1;
+  await onSearch();
+}
+
+function handleSelectionChange(val) {
+  console.log("handleSelectionChange", val);
+}
+
+async function onSearch() {
+  loading.value = true;
+
+  const { code, data, message } = await httpList({
+    ...form,
+    companyNo: currentCompany.value.companyNo,
+    noRela: currentCompany.value.companyNo === ""
+  });
+
+  responseHandle({
+    code,
+    message,
+    logout,
+    handler: () => {
+      const { list, count } = data;
+      dataList.value = list ?? [];
+      pagination.total = count ?? 0;
+      pagination.pageSize = form.size;
+      pagination.currentPage = form.page;
+    }
+  });
+
+  loading.value = false;
+}
+async function resetSearch() {
+  form.page = 1;
+  await onSearch();
+}
+//新建/编辑/详情弹窗
+function editItem(id, type, item) {
+  itemId.value = id;
+  isDetails.value = type;
+  for (let key in item) {
+    sitem[key] = item[key];
+  }
+  showModel.value = true;
+}
+const submitRefresh = () => {
+  showModel.value = false;
+  onSearch();
+};
+const submitCancel = () => {
+  showModel.value = false;
+};
+const resetCancel = () => {
+  passwordModel.value = false;
+};
+
+const resetForm = (formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.resetFields();
+  form.page = 1;
+  onSearch();
+};
+
+watch(
+  () => currentCompany.value,
+  () => onSearch()
+);
+
+onMounted(() => {
+  powers.value = useUserStoreHook().getMenuActions("supplierAccoutManage");
+  onSearch();
+});
+</script>
+
+<template>
+  <div class="main">
+    <div v-show="powers.some(i => i == '001')">
+      <el-form
+        ref="formRef"
+        :inline="true"
+        :model="form"
+        size="small"
+        :label-width="0"
+        class="bg-white w-99/100 pl-8 pt-4"
+      >
+        <el-form-item prop="status">
+          <el-select
+            v-model="form.status"
+            style="width: 100%"
+            placeholder="账号状态"
+            clearable
+          >
+            <el-option
+              v-for="(si, sii) in statusList"
+              :key="'status' + si.value + sii"
+              :label="si.label"
+              :value="si.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item prop="nickname">
+          <el-input v-model="form.nickname" placeholder="真实姓名" clearable />
+        </el-form-item>
+        <el-form-item prop="username">
+          <el-input v-model="form.username" placeholder="手机号" clearable />
+        </el-form-item>
+        <el-form-item>
+          <el-button
+            type="primary"
+            :icon="useRenderIcon('search')"
+            :loading="loading"
+            @click="resetSearch"
+          >
+            搜索
+          </el-button>
+          <el-button
+            :icon="useRenderIcon('refresh')"
+            @click="resetForm(formRef)"
+          >
+            重置
+          </el-button>
+        </el-form-item>
+      </el-form>
+
+      <TableProBar
+        title="公司账号管理"
+        :loading="loading"
+        :dataList="dataList"
+        size="small"
+        @refresh="onSearch"
+      >
+        <template #buttons>
+          <el-button
+            type="primary"
+            size="small"
+            :icon="useRenderIcon('add')"
+            @click="editItem('', 'add', {})"
+          >
+            新增账号
+          </el-button>
+        </template>
+        <template v-slot="{ size, checkList }">
+          <PureTable
+            border
+            align="left"
+            showOverflowTooltip
+            table-layout="auto"
+            size="small"
+            :data="dataList"
+            :columns="columns"
+            :checkList="checkList"
+            :pagination="pagination"
+            :paginationSmall="size === 'small' ? true : false"
+            :header-cell-style="{ background: '#fafafa', color: '#606266' }"
+            @selection-change="handleSelectionChange"
+            @size-change="handleSizeChange"
+            @current-change="handleCurrentChange"
+          >
+            <template #operation="{ row }">
+              <el-popconfirm :title="'确认重置密码?'" @confirm="resetRwd(row)">
+                <template #reference>
+                  <el-button
+                    class="reset-margin"
+                    link
+                    type="primary"
+                    size="small"
+                    v-if="powers.some(i => i == '012')"
+                    :icon="useRenderIcon('refresh-right')"
+                  /> </template
+              ></el-popconfirm>
+              <el-button
+                class="reset-margin"
+                v-if="powers.some(i => i == '007')"
+                link
+                type="primary"
+                size="small"
+                @click="editItem(row.id, 'view', row)"
+                :icon="useRenderIcon('eye-view')"
+              />
+              <el-button
+                class="reset-margin"
+                link
+                v-if="powers.some(i => i == '005')"
+                type="primary"
+                size="small"
+                @click="editItem(row.id, 'edit', row)"
+                :icon="useRenderIcon('edits')"
+              />
+              <el-popconfirm
+                :title="
+                  String(row.status) === '1' ? '改为禁用?' : '改为启用?'
+                "
+                v-if="
+                  (powers.some(i => i == '004') && row.status + '' === '1') ||
+                  (powers.some(i => i == '003') && row.status + '' === '0')
+                "
+                @confirm="handleStatus(row)"
+              >
+                <template #reference>
+                  <el-button
+                    class="reset-margin"
+                    link
+                    type="primary"
+                    size="small"
+                    :icon="
+                      useRenderIcon(
+                        String(row.status) === '1'
+                          ? 'close-circle-line'
+                          : 'checkbox-circle-line'
+                      )
+                    " /></template
+              ></el-popconfirm>
+            </template>
+          </PureTable>
+        </template>
+      </TableProBar>
+      <addEdit
+        :itemId="itemId"
+        :isDetails="isDetails"
+        :show-model="showModel"
+        @refresh="submitRefresh"
+        @cancel="submitCancel"
+        :sitem="sitem"
+      />
+      <reset-password
+        :itemId="passwordModelId"
+        :show-model="passwordModel"
+        @refresh="resetCancel"
+        @cancel="resetCancel"
+      />
+    </div>
+    <NoAuth v-show="!powers.some(i => i == '001')" />
+  </div>
+</template>
+
+<style scoped lang="scss">
+:deep(.el-dropdown-menu__item i) {
+  margin: 0;
+}
+</style>

+ 198 - 0
src/views/supplierManage/supplierAccoutManage/resetPassword.vue

@@ -0,0 +1,198 @@
+<script setup lang="ts">
+import { httpSetPwd } from "/@/api/interest/account";
+import { ElMessage, FormInstance, FormRules } from "element-plus";
+import { reactive, ref, watch, nextTick } from "vue";
+import { useNav } from "/@/layout/hooks/nav";
+import { isAlphanumeric, isnumber, validAlphabets } from "/@/utils/validate";
+const { logout } = useNav();
+const formSize = ref("default");
+const ruleFormRef = ref<FormInstance>();
+interface formType {
+  id?: string; //账户id
+  password?: string; //新密码
+  confirmPassword?: string; //确认密码
+}
+const props = defineProps({
+  itemId: {
+    type: String,
+    default: ""
+  },
+  showModel: {
+    type: Boolean,
+    default: false
+  }
+});
+const showModelThis = ref(false);
+const emit = defineEmits<{
+  (e: "cancel"): void;
+  (e: "refresh"): void;
+}>();
+const id = ref("");
+const formModel = {
+  id: "", //账户id
+  password: "", //新密码
+  confirmPassword: "" //确认密码
+};
+const ruleForm = reactive<formType>(formModel);
+const rules = reactive<FormRules>({
+  password: [
+    {
+      required: true,
+      validator: (rule, value, callback) => {
+        if (value === "") {
+          callback(new Error("新密码不能为空!"));
+        } else {
+          if (!isAlphanumeric(value)) {
+            callback(new Error("新密码为6-16位数字字母组合!"));
+          } else if (value.length < 6 || value.length > 16) {
+            callback(new Error("新密码为6-16位数字字母组合!"));
+          } else if (isnumber(value)) {
+            callback(new Error("新密码不能为纯数字!"));
+          } else if (validAlphabets(value)) {
+            callback(new Error("新密码不能为纯字母!"));
+          } else {
+            callback();
+          }
+        }
+      },
+      trigger: "blur"
+    }
+  ],
+  confirmPassword: [
+    {
+      required: true,
+      validator: (rule, value, callback) => {
+        if (value === "") {
+          callback(new Error("确认密码不能为空!"));
+        } else {
+          if (ruleForm.password !== value) {
+            callback(new Error("确认密码与新密码不一致!"));
+          } else {
+            callback();
+          }
+        }
+      },
+
+      trigger: "blur"
+    }
+  ]
+});
+const submitForm = async (formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  await formEl.validate(async (valid, fields) => {
+    if (valid) {
+      if (loading.value === true) return;
+      loading.value = true;
+      let model = Object.assign({}, ruleForm);
+      model.id = id.value;
+      const { code, message } = await httpSetPwd(model);
+      loading.value = false;
+      if (code === 0) {
+        ElMessage.success("密码修改成功!");
+        showModelThis.value = false;
+        emit("refresh");
+      } else if (code > 100 && code < 140) {
+        showModelThis.value = false;
+        logout();
+      } else {
+        ElMessage.error(message);
+      }
+    } else {
+      console.log("error submit!", fields);
+    }
+  });
+};
+const resetForm = async (formEl: FormInstance | undefined) => {
+  if (!formEl) return;
+  formEl.clearValidate();
+  formEl.resetFields();
+  await nextTick(async () => {
+    ruleForm.id = id.value;
+    ruleForm.password = ""; //新密码
+    ruleForm.confirmPassword = ""; //确认密码
+  });
+};
+const closeDialog = () => {
+  showModelThis.value = false;
+  emit("cancel");
+};
+
+const loading = ref(true);
+const titleType = ref("");
+async function initForm() {
+  loading.value = true;
+  titleType.value = "修改密码";
+
+  await resetForm(ruleFormRef.value);
+
+  console.log(ruleForm);
+  loading.value = false;
+}
+watch(
+  () => {
+    return props.showModel;
+  },
+  () => {
+    const { showModel, itemId } = props;
+    showModelThis.value = showModel;
+    if (showModelThis.value) {
+      id.value = itemId;
+      console.log(id.value);
+      initForm();
+    }
+  }
+);
+</script>
+
+<template>
+  <el-dialog
+    :close-on-press-escape="false"
+    v-model="showModelThis"
+    append-to-body
+    :width="'900px'"
+    :title="titleType"
+    v-loading="loading"
+    @close="closeDialog"
+  >
+    <el-form
+      ref="ruleFormRef"
+      :model="ruleForm"
+      :rules="rules"
+      label-width="90px"
+      style="margin-top: -10px"
+      class="demo-ruleForm"
+      :size="formSize"
+      status-icon
+    >
+      <el-row>
+        <el-col :span="8">
+          <el-form-item label="新密码" prop="password">
+            <el-input
+              v-model="ruleForm.password"
+              placeholder="新密码"
+            /> </el-form-item
+        ></el-col>
+        <el-col :span="8">
+          <el-form-item label="确认密码" prop="confirmPassword">
+            <el-input
+              v-model="ruleForm.confirmPassword"
+              :maxlength="11"
+              placeholder="确认密码"
+            /> </el-form-item
+        ></el-col>
+      </el-row>
+      <el-col :span="24" class="clear">
+        <el-button
+          type="primary"
+          class="fr"
+          style="margin: 0 0 0 16px"
+          @click="submitForm(ruleFormRef)"
+          >保存</el-button
+        >
+        <el-button class="fr" style="margin: 0 0 0 16px" @click="closeDialog"
+          >关闭</el-button
+        >
+      </el-col>
+    </el-form>
+  </el-dialog>
+</template>

+ 8 - 0
src/views/supplierManage/supplierAccoutManage/types.ts

@@ -0,0 +1,8 @@
+export interface menuType {
+  id?: string; //账户id
+  nickname?: string; //真实姓名
+  mobile?: string; //手机号
+  email?: string; //邮箱
+  role?: string; //角色
+  companyArr?: any;
+}

+ 134 - 0
src/views/supplierManage/supplierAccoutQuery/components/role-modal.vue

@@ -0,0 +1,134 @@
+<script setup lang="ts">
+import { ref, computed, unref } from "vue";
+import { useAsync } from "/@/hooks/core/useAsync";
+import { httpList } from "/@/api/interest/role";
+import { ModalTypes } from "./../types";
+import { ElForm } from "element-plus";
+import { useCompany } from "/@/hooks/core/useCompany";
+
+const emit = defineEmits(["finance-save"]);
+
+const visible = ref(false);
+const modalType = ref<ModalTypes>(ModalTypes.create);
+const formRef = ref<InstanceType<typeof ElForm>>(null);
+let companyNo = "";
+
+const {
+  run: runRole,
+  data: rolelist,
+  loading: loadingRole
+} = useAsync<Record<string, string>[]>({
+  initalData: [],
+  isList: true
+});
+
+const defaultData = {
+  nickname: "",
+  mobile: "",
+  roleid: ""
+};
+
+const formData = ref<Record<string, any>>({ ...defaultData });
+const company = ref<any>({});
+
+const { currentCompany } = useCompany();
+
+const title = computed(() => {
+  const baseName = "公司账号角色设置";
+
+  switch (modalType.value) {
+    case ModalTypes.create:
+      return "创建" + baseName;
+    case ModalTypes.preview:
+      return "查看" + baseName;
+    default:
+      return "修改" + baseName;
+  }
+});
+
+function handleSave() {
+  formRef.value.validate(isValid => {
+    if (!isValid) return;
+
+    emit(
+      "finance-save",
+      {
+        companyNo,
+        relaComNo: currentCompany.value.companyNo,
+        ...unref(formData)
+      },
+      unref(modalType)
+    );
+    visible.value = false;
+  });
+}
+
+defineExpose({
+  onDisplay: (_data?: any, type?: ModalTypes) => {
+    formData.value = { ...defaultData };
+    visible.value = true;
+    modalType.value = type;
+    companyNo = _data.companyCode;
+    runRole(httpList({ companyNo, size: "1000" }));
+
+    if (_data) {
+      const { mobile, nickname, roleid, id, companyName } = _data;
+      company.value = companyName;
+      formData.value = { mobile, nickname, roleid, id };
+    }
+  }
+});
+</script>
+
+<template>
+  <ElDialog center v-model="visible" :title="title">
+    <ElForm
+      ref="formRef"
+      labelWidth="100px"
+      label-position="left"
+      :model="formData"
+      v-loading="loadingRole"
+      :rules="{}"
+      :disabled="modalType === ModalTypes.preview"
+    >
+      <ElFormItem label="真实姓名" prop="nickname">
+        <ElInput
+          placeholder="请输入真实姓名"
+          v-model="formData.nickname"
+          disabled
+        />
+      </ElFormItem>
+
+      <ElFormItem label="手机号" prop="mobile">
+        <ElInput
+          placeholder="请输入手机号"
+          v-model="formData.mobile"
+          disabled
+        />
+      </ElFormItem>
+
+      <ElFormItem label="业务公司" prop="companyName" v-if="company">
+        <ElInput placeholder="请输入业务公司" :value="company" disabled />
+      </ElFormItem>
+
+      <!--      <ElFormItem label="角色" prop="roleid">-->
+      <!--        <ElRadioGroup v-model="formData.roleid">-->
+      <!--          <ElRadio-->
+      <!--            :disabled="String(role.status) === '0'"-->
+      <!--            v-for="role in rolelist"-->
+      <!--            :key="role.id"-->
+      <!--            :label="role.id"-->
+      <!--          >{{ role.role_name }}</ElRadio-->
+      <!--          >-->
+      <!--        </ElRadioGroup>-->
+      <!--      </ElFormItem>-->
+
+      <ElFormItem>
+        <div class="flex w-full justify-end">
+          <ElButton type="取消" @click="() => (visible = false)">取消</ElButton>
+          <ElButton type="primary" @click="() => handleSave()">保存</ElButton>
+        </div>
+      </ElFormItem>
+    </ElForm>
+  </ElDialog>
+</template>

+ 1 - 0
src/views/supplierManage/supplierAccoutQuery/config/_details.ts

@@ -0,0 +1 @@
+export { reconciliationColumns } from "/@/components/ReconciliationForm";

+ 18 - 0
src/views/supplierManage/supplierAccoutQuery/config/_options.ts

@@ -0,0 +1,18 @@
+export const statusOptions = [
+  {
+    value: "1",
+    label: "买方公司业务审核"
+  },
+  {
+    value: "2",
+    label: "审核成功"
+  },
+  {
+    value: "3",
+    label: "买家驳回"
+  },
+  {
+    value: "4",
+    label: "已撤销申请"
+  }
+];

+ 101 - 0
src/views/supplierManage/supplierAccoutQuery/config/content.config.ts

@@ -0,0 +1,101 @@
+import { h } from "vue";
+
+import {
+  httpList,
+  httpDelete,
+  httpStatus,
+  httpUpdate
+} from "/@/api/supplierManage/supplierAccoutQuery";
+
+import dayjs from "dayjs";
+import { ContentConfig } from "/@/components/PageContent";
+import { ElTag } from "element-plus";
+
+const columns = [
+  {
+    type: "selection",
+    minWidth: 55,
+    align: "left",
+    hide: ({ checkList }) => !checkList.includes("勾选列")
+  },
+  {
+    label: "序号",
+    type: "index",
+    minWidth: 60,
+    align: "left",
+    hide: ({ checkList }) => !checkList.includes("序号列")
+  },
+  {
+    label: "手机号",
+    prop: "mobile",
+    minWidth: 180,
+    align: "left"
+  },
+  {
+    label: "真实姓名",
+    prop: "nickname",
+    minWidth: 120
+  },
+  {
+    label: "状态",
+    prop: "status",
+    cellRenderer: ({ row }) => {
+      return h(
+        ElTag,
+        {
+          type: String(row.status) === "1" ? "success" : "danger"
+        },
+        {
+          default: () => (String(row.status) === "1" ? "启用" : "禁用")
+        }
+      );
+    }
+  },
+  {
+    label: "角色",
+    prop: "role_name",
+    minWidth: 180,
+    align: "left"
+  },
+
+  {
+    label: "公司编号",
+    prop: "companyCode",
+    minWidth: 180,
+    align: "left"
+  },
+  {
+    label: "公司名称",
+    prop: "companyName",
+    minWidth: 180,
+    align: "left"
+  },
+  {
+    label: "创建时间",
+    minWidth: 180,
+    prop: "addtime",
+    formatter: ({ addtime }) => dayjs(addtime).format("YYYY-MM-DD HH:mm:ss")
+  },
+  {
+    label: "操作",
+    fixed: "right",
+    width: 120,
+    slot: "operation"
+  }
+];
+
+const contentConfig: ContentConfig = {
+  title: "公司账号角色查询",
+  columns,
+  deleteProp: "payNo",
+  statusRowProp: ({ companyCode: companyNo }) => ({ companyNo }),
+  apis: {
+    httpList,
+    httpDelete,
+    httpAdd: true,
+    httpStatus,
+    httpUpdate
+  }
+};
+
+export default contentConfig;

+ 18 - 0
src/views/supplierManage/supplierAccoutQuery/config/search.config.ts

@@ -0,0 +1,18 @@
+import { FormConfig } from "/@/components/PageSearch";
+
+const searchFormConfig: FormConfig = {
+  formItems: [
+    {
+      field: "nickname",
+      type: "input",
+      placeholder: "真实姓名"
+    },
+    {
+      field: "username",
+      type: "input",
+      placeholder: "手机号"
+    }
+  ]
+};
+
+export default searchFormConfig;

+ 62 - 0
src/views/supplierManage/supplierAccoutQuery/index.vue

@@ -0,0 +1,62 @@
+<script setup lang="ts">
+import { ref } from "vue";
+import RoleModal from "./components/role-modal.vue";
+import contentConfig from "./config/content.config";
+import searchConfig from "./config/search.config";
+import { usePageSearch, type PageHooks, type PageEvents } from "/@/hooks/page";
+import { httpSetRole } from "/@/api/supplierManage/supplierAccoutQuery";
+import { useAsync } from "/@/hooks/core/useAsync";
+import { ModalTypes } from "./types";
+
+const PageName = "supplierAccoutQuery";
+const roleModalRef = ref<InstanceType<typeof RoleModal> | null>(null);
+const instance = ref(null);
+
+const hooks: PageHooks = {
+  pageSearchHook: () => usePageSearch(undefined, undefined, searchConfig)
+};
+
+const { run } = useAsync({
+  success: () => instance.value.onSearch()
+});
+
+const events: PageEvents = {
+  content: {
+    create: () => roleModalRef.value.onDisplay(undefined, ModalTypes.create),
+    preview: data => roleModalRef.value.onDisplay(data, ModalTypes.preview),
+    update: data => roleModalRef.value.onDisplay(data, ModalTypes.update)
+  }
+};
+
+function handleSave(data: any, type: ModalTypes) {
+  const { roleid, nickname, relaComNo, id, companyNo, mobile } = data;
+
+  const params = {
+    id,
+    mobile,
+    roleid,
+    nickname,
+    relaComNo,
+    companyNo
+  };
+
+  switch (type) {
+    case ModalTypes.update:
+      run(httpSetRole(params));
+      break;
+  }
+}
+</script>
+
+<template>
+  <PageAuth :pageName="PageName">
+    <PageContainer
+      :hooks="hooks"
+      :events="events"
+      :contentConfig="contentConfig"
+      :search-config="searchConfig"
+      :get-content-ref="ref => (instance = ref)"
+    />
+    <RoleModal ref="roleModalRef" @finance-save="handleSave" />
+  </PageAuth>
+</template>

+ 5 - 0
src/views/supplierManage/supplierAccoutQuery/types.ts

@@ -0,0 +1,5 @@
+export enum ModalTypes {
+  update,
+  preview,
+  create
+}

+ 11 - 5
src/views/system/finance/components/finance-modal.vue

@@ -1,8 +1,8 @@
 <script setup lang="ts">
 import { ElForm } from "element-plus";
-import { ref, computed, watch } from "vue";
+import { computed, ref, watch } from "vue";
 import { UnitInput } from "/@/components/Input";
-import { financeRules_NoJS, financeRules_JS } from "./../config/_rules";
+import { financeRules_JS, financeRules_NoJS } from "./../config/_rules";
 import { useCompany } from "/@/hooks/core/useCompany";
 import { useAsync } from "/@/hooks/core/useAsync";
 import { ModalTypes } from "./../types";
@@ -11,6 +11,7 @@ import { useUserInfo } from "/@/hooks/core/useUser";
 import Super from "/@/layout/components/company/super.vue";
 import { httpAdd, httpUpdate } from "/@/api/parameter/finance";
 import { xs_inv_type_list } from "/@/utils/status";
+
 const emit = defineEmits(["finance-save"]);
 
 const visible = ref(false);
@@ -54,6 +55,8 @@ const { isSuperUser } = useUserInfo();
 const formData = ref<Record<string, any>>({ ...defaultData });
 const rules = ref(financeRules_JS);
 
+const isUpdate = computed(() => modalType.value === ModalTypes.update);
+
 const companys = computed(() => {
   const allListItemIndex = companyList.value.findIndex(
     ({ companyNo }) => companyNo === ""
@@ -196,6 +199,7 @@ defineExpose({
               style="width: 100%"
               v-model="selectCompany"
               placeholder="请选择公司"
+              :disabled="isUpdate"
             >
               <ElOption
                 v-for="c in companys"
@@ -211,6 +215,7 @@ defineExpose({
               noAll
               noSet
               @change="value => (selectCompany = value.code)"
+              :disabled="isUpdate"
             />
           </ElFormItem>
 
@@ -230,21 +235,22 @@ defineExpose({
             <ElInput
               v-model="formData.company_address"
               placeholder="请输入地址"
+              :disabled="isUpdate"
             />
           </ElFormItem>
         </ElCol>
 
         <ElCol :span="12">
           <ElFormItem label="联系电话" prop="mobile">
-            <ElInput placeholder="联系电话" v-model="formData.mobile" />
+            <ElInput placeholder="联系电话" v-model="formData.mobile" :disabled="isUpdate" />
           </ElFormItem>
 
           <ElFormItem label="银行名称" prop="bank_name">
-            <ElInput placeholder="银行名称" v-model="formData.bank_name" />
+            <ElInput placeholder="银行名称" v-model="formData.bank_name" :disabled="isUpdate" />
           </ElFormItem>
 
           <ElFormItem label="银行卡号" prop="bankNo">
-            <ElInput v-model="formData.bankNo" placeholder="银行卡号" />
+            <ElInput v-model="formData.bankNo" placeholder="银行卡号" :disabled="isUpdate" />
           </ElFormItem>
         </ElCol>
       </ElRow>

+ 1 - 20
src/views/system/finance/config/content.config.ts

@@ -4,7 +4,6 @@
 import { ContentConfig } from "/@/components/PageContent";
 import {
   httpList,
-  httpAdd,
   httpUpdate,
   httpStatus
 } from "/@/api/parameter/finance";
@@ -69,29 +68,11 @@ const columns = [
     prop: "bankNo",
     minWidth: 120
   },
-  // {
-  //   label: "联系人",
-  //   prop: "contector"
-  // },
   {
     label: "企业联系方式",
     prop: "mobile",
     width: 120
   },
-  // {
-  //   label: "营业执照",
-  //   prop: "company_img",
-  //   width: 100,
-  //   cellRenderer: ({ row }) =>
-  //     h(ElImage, {
-  //       src: row.company_img,
-  //       previewSrcList: [row.company_img],
-  //       previewTeleported: true,
-  //       style: {
-  //         height: "20px"
-  //       }
-  //     })
-  // },
   {
     label: "状态",
     width: "80px",
@@ -145,9 +126,9 @@ const contentConfig: ContentConfig = {
   title: "业务公司发票",
   statusProp: "companyNo",
   columns,
+  // httpAdd,
   apis: {
     httpList,
-    httpAdd,
     httpUpdate,
     httpStatus
   }

+ 2 - 4
src/views/system/finance/index.vue

@@ -7,7 +7,6 @@ import { usePageSearch, type PageHooks, type PageEvents } from "/@/hooks/page";
 import { ModalTypes } from "./types";
 
 const pageName = "finance";
-
 const pageContentRef = ref<any>(null);
 
 const hooks: PageHooks = {
@@ -15,13 +14,12 @@ const hooks: PageHooks = {
 };
 
 const reload = () => pageContentRef.value.onSearch();
-
 const financeModalRef = ref<InstanceType<typeof FinanceModal>>(null);
 
 const events: PageEvents = {
   content: {
-    preview: data => financeModalRef.value.onDisplay(data, ModalTypes.preview),
     update: data => financeModalRef.value.onDisplay(data, ModalTypes.update),
+    preview: data => financeModalRef.value.onDisplay(data, ModalTypes.preview),
     create: () => financeModalRef.value.onDisplay(undefined, ModalTypes.create)
   }
 };
@@ -34,7 +32,7 @@ const events: PageEvents = {
       :events="events"
       :search-config="searchConfig"
       :content-config="contentConfig"
-      :getContentRef="ref => (pageContentRef = ref)"
+      :get-content-ref="ref => (pageContentRef = ref)"
     />
     <FinanceModal ref="financeModalRef" @finance-save="() => reload()" />
   </PageAuth>

+ 1 - 1
src/views/system/menuOperator/columns.tsx

@@ -27,7 +27,7 @@ export function useColumns() {
       label: "图标",
       prop: "menu_img",
       width: 80,
-      cellRenderer: ({ row }) => <IconifyIconOnline icon={row.menu_img} />
+      cellRenderer: ({ row }) => (<IconifyIconOnline icon={row.menu_img} /> )
     },
     {
       label: "path",

+ 2 - 2
src/views/system/menuOperator/components/edit-dialog.vue

@@ -291,8 +291,8 @@ defineExpose({
             <el-form-item label-width="120px" label="菜单权限等级" prop="level">
               <el-select v-model="ruleForm.level">
                 <el-option label="超管" value="1" />
-                <el-option label="企业管理" value="2" />
-                <el-option label="企业操作" value="3" />
+                <el-option label="平台端" value="2" />
+                <el-option label="供应商端" value="3" />
               </el-select>
             </el-form-item>
           </el-col>

+ 3 - 2
src/views/system/menuOperator/index.vue

@@ -10,6 +10,7 @@ const powers = ref([]);
 function handleAddChangeCheck(item: any, id: string, type: string) {
   modelRef.value.show(item, id, type);
 }
+
 onMounted(() => {
   powers.value = useUserStoreHook().getMenuActions("menuOperator");
   if (powers.value.some(i => i == "001")) {
@@ -22,11 +23,11 @@ onMounted(() => {
   <div class="main">
     <PagePower :isShow="powers.some(i => i == '001')">
       <ActionTable
-        ref="actionTableRef"
         :powers="powers"
+        ref="actionTableRef"
         @edit="handleAddChangeCheck"
-        @create="handleAddChangeCheck"
         @view="handleAddChangeCheck"
+        @create="handleAddChangeCheck"
       />
       <EditModel ref="modelRef" @reload="actionTableRef.onSearch()" />
     </PagePower>