Commit bc37d685c4d41c0e6ad4955f96a828b9222bb108

Authored by wuxw
1 parent a99eb7a5

开发完成合同功能

Showing 57 changed files with 8009 additions and 3 deletions
src/api/contract/addContractApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 保存合同信息
  4 +export function saveContract(data) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/contract/saveContract',
  8 + method: 'post',
  9 + data
  10 + }).then(response => {
  11 + const res = response.data
  12 + resolve(res)
  13 + }).catch(error => {
  14 + reject(error)
  15 + })
  16 + })
  17 +}
  18 +
  19 +// 查询合同类型
  20 +export function queryContractType(params) {
  21 + return new Promise((resolve, reject) => {
  22 + request({
  23 + url: '/contract/queryContractType',
  24 + method: 'get',
  25 + params
  26 + }).then(response => {
  27 + const res = response.data
  28 + resolve(res)
  29 + }).catch(error => {
  30 + reject(error)
  31 + })
  32 + })
  33 +}
  34 +
  35 +// 查询合同甲方信息
  36 +export function queryContractPartya(params) {
  37 + return new Promise((resolve, reject) => {
  38 + request({
  39 + url: '/contractPartya/queryContractPartya',
  40 + method: 'get',
  41 + params
  42 + }).then(response => {
  43 + const res = response.data
  44 + resolve(res)
  45 + }).catch(error => {
  46 + reject(error)
  47 + })
  48 + })
  49 +}
  50 +
  51 +// 查询合同类型规格
  52 +export function queryContractTypeSpec(params) {
  53 + return new Promise((resolve, reject) => {
  54 + request({
  55 + url: '/contract/queryContractTypeSpec',
  56 + method: 'get',
  57 + params
  58 + }).then(response => {
  59 + const res = response.data
  60 + resolve(res)
  61 + }).catch(error => {
  62 + reject(error)
  63 + })
  64 + })
  65 +}
  66 +
  67 +// 查询合同关联房屋
  68 +export function queryContractRoom(params) {
  69 + return new Promise((resolve, reject) => {
  70 + request({
  71 + url: '/contract/queryContractRoom',
  72 + method: 'get',
  73 + params
  74 + }).then(response => {
  75 + const res = response.data
  76 + resolve(res)
  77 + }).catch(error => {
  78 + reject(error)
  79 + })
  80 + })
  81 +}
  82 +
  83 +// 获取第一个审批人
  84 +export function getFirstStaff(params) {
  85 + return new Promise((resolve, reject) => {
  86 + request({
  87 + url: '/workflow/getFirstStaff',
  88 + method: 'get',
  89 + params
  90 + }).then(response => {
  91 + const res = response.data
  92 + resolve(res)
  93 + }).catch(error => {
  94 + reject(error)
  95 + })
  96 + })
  97 +}
  98 +
  99 +// 查询员工信息
  100 +export function queryStaffInfos(params) {
  101 + return new Promise((resolve, reject) => {
  102 + request({
  103 + url: '/query.staff.infos',
  104 + method: 'get',
  105 + params
  106 + }).then(response => {
  107 + const res = response.data
  108 + resolve(res)
  109 + }).catch(error => {
  110 + reject(error)
  111 + })
  112 + })
  113 +}
  114 +
  115 +// 查询组织树
  116 +export function listOrgTree(params) {
  117 + return new Promise((resolve, reject) => {
  118 + request({
  119 + url: '/org.listOrgTree',
  120 + method: 'get',
  121 + params
  122 + }).then(response => {
  123 + const res = response.data
  124 + resolve(res)
  125 + }).catch(error => {
  126 + reject(error)
  127 + })
  128 + })
  129 +}
  130 +
  131 +// 查询房屋信息
  132 +export function queryRooms(params) {
  133 + return new Promise((resolve, reject) => {
  134 + request({
  135 + url: '/room.queryRooms',
  136 + method: 'get',
  137 + params
  138 + }).then(response => {
  139 + const res = response.data
  140 + resolve(res)
  141 + }).catch(error => {
  142 + reject(error)
  143 + })
  144 + })
  145 +}
  146 +
  147 +// 查询已售房屋
  148 +export function queryRoomsWithSell(params) {
  149 + return new Promise((resolve, reject) => {
  150 + request({
  151 + url: '/room.queryRoomsWithSell',
  152 + method: 'get',
  153 + params
  154 + }).then(response => {
  155 + const res = response.data
  156 + resolve(res)
  157 + }).catch(error => {
  158 + reject(error)
  159 + })
  160 + })
  161 +}
  162 +
  163 +// 查询未售房屋
  164 +export function queryRoomsWithOutSell(params) {
  165 + return new Promise((resolve, reject) => {
  166 + request({
  167 + url: '/room.queryRoomsWithOutSell',
  168 + method: 'get',
  169 + params
  170 + }).then(response => {
  171 + const res = response.data
  172 + resolve(res)
  173 + }).catch(error => {
  174 + reject(error)
  175 + })
  176 + })
  177 +}
  178 +
  179 +// 查询业主信息
  180 +export function queryOwners(params) {
  181 + return new Promise((resolve, reject) => {
  182 + request({
  183 + url: '/owner.queryOwners',
  184 + method: 'get',
  185 + params
  186 + }).then(response => {
  187 + const res = response.data
  188 + resolve(res)
  189 + }).catch(error => {
  190 + reject(error)
  191 + })
  192 + })
  193 +}
0 194 \ No newline at end of file
... ...
src/api/contract/contractChangeDetailApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +import { getCommunityId } from '@/api/community/communityApi'
  3 +
  4 +// 查询合同列表
  5 +export function queryContract(params) {
  6 + return new Promise((resolve, reject) => {
  7 + request({
  8 + url: '/contract/queryContract',
  9 + method: 'get',
  10 + params
  11 + }).then(response => {
  12 + resolve(response.data)
  13 + }).catch(error => {
  14 + reject(error)
  15 + })
  16 + })
  17 +}
  18 +
  19 +// 查询房间信息
  20 +export function queryRooms(params, url = '/room.queryRooms') {
  21 + params.communityId = getCommunityId()
  22 + return new Promise((resolve, reject) => {
  23 + request({
  24 + url: url,
  25 + method: 'get',
  26 + params
  27 + }).then(response => {
  28 + resolve(response.data)
  29 + }).catch(error => {
  30 + reject(error)
  31 + })
  32 + })
  33 +}
  34 +
  35 +// 查询合同关联房间
  36 +export function queryContractRoom(params) {
  37 + return new Promise((resolve, reject) => {
  38 + request({
  39 + url: '/contract/queryContractRoom',
  40 + method: 'get',
  41 + params
  42 + }).then(response => {
  43 + resolve(response.data)
  44 + }).catch(error => {
  45 + reject(error)
  46 + })
  47 + })
  48 +}
  49 +
  50 +// 查询组织树
  51 +export function listOrgTree(params) {
  52 + params.communityId = getCommunityId()
  53 + return new Promise((resolve, reject) => {
  54 + request({
  55 + url: '/org.listOrgTree',
  56 + method: 'get',
  57 + params
  58 + }).then(response => {
  59 + resolve(response.data)
  60 + }).catch(error => {
  61 + reject(error)
  62 + })
  63 + })
  64 +}
  65 +
  66 +// 查询员工信息
  67 +export function queryStaffInfos(params) {
  68 + return new Promise((resolve, reject) => {
  69 + request({
  70 + url: '/query.staff.infos',
  71 + method: 'get',
  72 + params
  73 + }).then(response => {
  74 + resolve(response.data)
  75 + }).catch(error => {
  76 + reject(error)
  77 + })
  78 + })
  79 +}
  80 +
  81 +// 获取审批人
  82 +export function getFirstStaff(params) {
  83 + params.communityId = getCommunityId()
  84 + return new Promise((resolve, reject) => {
  85 + request({
  86 + url: '/workflow/getFirstStaff',
  87 + method: 'get',
  88 + params
  89 + }).then(response => {
  90 + resolve(response.data)
  91 + }).catch(error => {
  92 + reject(error)
  93 + })
  94 + })
  95 +}
  96 +
  97 +// 保存合同变更计划
  98 +export function saveContractChangePlan(data) {
  99 + return new Promise((resolve, reject) => {
  100 + request({
  101 + url: '/contract/saveContractChangePlan',
  102 + method: 'post',
  103 + data
  104 + }).then(response => {
  105 + resolve(response.data)
  106 + }).catch(error => {
  107 + reject(error)
  108 + })
  109 + })
  110 +}
0 111 \ No newline at end of file
... ...
src/api/contract/contractChangeManageApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +/**
  4 + * 查询合同变更计划列表
  5 + * @param {Object} params 查询参数
  6 + * @returns {Promise} 返回Promise对象
  7 + */
  8 +export function queryContractChangePlan(params) {
  9 + return new Promise((resolve, reject) => {
  10 + request({
  11 + url: '/contract/queryContractChangePlan',
  12 + method: 'get',
  13 + params
  14 + }).then(response => {
  15 + const res = response.data
  16 + resolve(res)
  17 + }).catch(error => {
  18 + reject(error)
  19 + })
  20 + })
  21 +}
  22 +
  23 +/**
  24 + * 查询合同类型列表
  25 + * @param {Object} params 查询参数
  26 + * @returns {Promise} 返回Promise对象
  27 + */
  28 +export function queryContractType(params) {
  29 + return new Promise((resolve, reject) => {
  30 + request({
  31 + url: '/contract/queryContractType',
  32 + method: 'get',
  33 + params
  34 + }).then(response => {
  35 + const res = response.data
  36 + resolve(res)
  37 + }).catch(error => {
  38 + reject(error)
  39 + })
  40 + })
  41 +}
  42 +
  43 +/**
  44 + * 删除合同变更计划
  45 + * @param {Object} data 删除数据
  46 + * @returns {Promise} 返回Promise对象
  47 + */
  48 +export function deleteContractChangePlan(data) {
  49 + return new Promise((resolve, reject) => {
  50 + request({
  51 + url: '/contract/deleteContractChangePlan',
  52 + method: 'post',
  53 + data
  54 + }).then(response => {
  55 + const res = response.data
  56 + resolve(res)
  57 + }).catch(error => {
  58 + reject(error)
  59 + })
  60 + })
  61 +}
0 62 \ No newline at end of file
... ...
src/api/contract/contractManageApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 查询合同列表
  4 +export function queryContract(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/contract/queryContract',
  8 + method: 'get',
  9 + params
  10 + }).then(response => {
  11 + const res = response.data
  12 + resolve({
  13 + data: res.data,
  14 + total: res.total
  15 + })
  16 + }).catch(error => {
  17 + reject(error)
  18 + })
  19 + })
  20 +}
  21 +
  22 +// 查询合同类型
  23 +export function queryContractType(params) {
  24 + return new Promise((resolve, reject) => {
  25 + request({
  26 + url: '/contract/queryContractType',
  27 + method: 'get',
  28 + params
  29 + }).then(response => {
  30 + const res = response.data
  31 + resolve({
  32 + data: res.data
  33 + })
  34 + }).catch(error => {
  35 + reject(error)
  36 + })
  37 + })
  38 +}
  39 +
  40 +// 查询合同类型规格
  41 +export function queryContractTypeSpec(params) {
  42 + return new Promise((resolve, reject) => {
  43 + request({
  44 + url: '/contract/queryContractTypeSpec',
  45 + method: 'get',
  46 + params
  47 + }).then(response => {
  48 + const res = response.data
  49 + resolve({
  50 + data: res.data
  51 + })
  52 + }).catch(error => {
  53 + reject(error)
  54 + })
  55 + })
  56 +}
  57 +
  58 +// 查询合同文件
  59 +export function queryContractFile(params) {
  60 + return new Promise((resolve, reject) => {
  61 + request({
  62 + url: '/contractFile/queryContractFile',
  63 + method: 'get',
  64 + params
  65 + }).then(response => {
  66 + const res = response.data
  67 + resolve({
  68 + data: res.data
  69 + })
  70 + }).catch(error => {
  71 + reject(error)
  72 + })
  73 + })
  74 +}
  75 +
  76 +// 更新合同
  77 +export function updateContract(data) {
  78 + return new Promise((resolve, reject) => {
  79 + request({
  80 + url: '/contract/updateContract',
  81 + method: 'post',
  82 + data
  83 + }).then(response => {
  84 + const res = response.data
  85 + if (res.code === 0) {
  86 + resolve(res)
  87 + } else {
  88 + reject(new Error(res.msg))
  89 + }
  90 + }).catch(error => {
  91 + reject(error)
  92 + })
  93 + })
  94 +}
  95 +
  96 +// 删除合同
  97 +export function deleteContract(data) {
  98 + return new Promise((resolve, reject) => {
  99 + request({
  100 + url: '/contract/deleteContract',
  101 + method: 'post',
  102 + data
  103 + }).then(response => {
  104 + const res = response.data
  105 + if (res.code === 0) {
  106 + resolve(res)
  107 + } else {
  108 + reject(new Error(res.msg))
  109 + }
  110 + }).catch(error => {
  111 + reject(error)
  112 + })
  113 + })
  114 +}
  115 +
  116 +// 上传合同文件
  117 +export function uploadContactFile(data) {
  118 + return new Promise((resolve, reject) => {
  119 + request({
  120 + url: '/uploadContactFile',
  121 + method: 'post',
  122 + data,
  123 + headers: {
  124 + 'Content-Type': 'multipart/form-data'
  125 + }
  126 + }).then(response => {
  127 + const res = response.data
  128 + resolve(res)
  129 + }).catch(error => {
  130 + reject(error)
  131 + })
  132 + })
  133 +}
0 134 \ No newline at end of file
... ...
src/api/contract/contractPartyaManageApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +import { getCommunityId } from '@/api/community/communityApi'
  3 +
  4 +// 查询合同甲方列表
  5 +export function queryContractPartya(params) {
  6 + return new Promise((resolve, reject) => {
  7 + request({
  8 + url: '/contractPartya/queryContractPartya',
  9 + method: 'get',
  10 + params: {
  11 + ...params,
  12 + communityId: getCommunityId()
  13 + }
  14 + }).then(response => {
  15 + const res = response.data
  16 + resolve(res)
  17 + }).catch(error => {
  18 + reject(error)
  19 + })
  20 + })
  21 +}
  22 +
  23 +// 添加合同甲方
  24 +export function saveContractPartya(data) {
  25 + return new Promise((resolve, reject) => {
  26 + request({
  27 + url: '/contractPartya/saveContractPartya',
  28 + method: 'post',
  29 + data: {
  30 + ...data,
  31 + communityId: getCommunityId()
  32 + }
  33 + }).then(response => {
  34 + const res = response.data
  35 + resolve(res)
  36 + }).catch(error => {
  37 + reject(error)
  38 + })
  39 + })
  40 +}
  41 +
  42 +// 修改合同甲方
  43 +export function updateContractPartya(data) {
  44 + return new Promise((resolve, reject) => {
  45 + request({
  46 + url: '/contractPartya/updateContractPartya',
  47 + method: 'post',
  48 + data: {
  49 + ...data,
  50 + communityId: getCommunityId()
  51 + }
  52 + }).then(response => {
  53 + const res = response.data
  54 + resolve(res)
  55 + }).catch(error => {
  56 + reject(error)
  57 + })
  58 + })
  59 +}
  60 +
  61 +// 删除合同甲方
  62 +export function deleteContractPartya(data) {
  63 + return new Promise((resolve, reject) => {
  64 + request({
  65 + url: '/contractPartya/deleteContractPartya',
  66 + method: 'post',
  67 + data: {
  68 + ...data,
  69 + communityId: getCommunityId()
  70 + }
  71 + }).then(response => {
  72 + const res = response.data
  73 + resolve(res)
  74 + }).catch(error => {
  75 + reject(error)
  76 + })
  77 + })
  78 +}
0 79 \ No newline at end of file
... ...
src/api/contract/contractTypeManageApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 查询合同类型列表
  4 +export function queryContractType(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/contract/queryContractType',
  8 + method: 'get',
  9 + params
  10 + }).then(response => {
  11 + const res = response.data
  12 + resolve(res)
  13 + }).catch(error => {
  14 + reject(error)
  15 + })
  16 + })
  17 +}
  18 +
  19 +// 添加合同类型
  20 +export function saveContractType(data) {
  21 + return new Promise((resolve, reject) => {
  22 + request({
  23 + url: '/contract/saveContractType',
  24 + method: 'post',
  25 + data
  26 + }).then(response => {
  27 + const res = response.data
  28 + resolve(res)
  29 + }).catch(error => {
  30 + reject(error)
  31 + })
  32 + })
  33 +}
  34 +
  35 +// 修改合同类型
  36 +export function updateContractType(data) {
  37 + return new Promise((resolve, reject) => {
  38 + request({
  39 + url: '/contract/updateContractType',
  40 + method: 'post',
  41 + data
  42 + }).then(response => {
  43 + const res = response.data
  44 + resolve(res)
  45 + }).catch(error => {
  46 + reject(error)
  47 + })
  48 + })
  49 +}
  50 +
  51 +// 删除合同类型
  52 +export function deleteContractType(data) {
  53 + return new Promise((resolve, reject) => {
  54 + request({
  55 + url: '/contract/deleteContractType',
  56 + method: 'post',
  57 + data
  58 + }).then(response => {
  59 + const res = response.data
  60 + resolve(res)
  61 + }).catch(error => {
  62 + reject(error)
  63 + })
  64 + })
  65 +}
  66 +
  67 +// 查询合同类型模板
  68 +export function queryContractTypeTemplate(params) {
  69 + return new Promise((resolve, reject) => {
  70 + request({
  71 + url: '/contract/queryContractTypeTemplate',
  72 + method: 'get',
  73 + params
  74 + }).then(response => {
  75 + const res = response.data
  76 + resolve(res)
  77 + }).catch(error => {
  78 + reject(error)
  79 + })
  80 + })
  81 +}
  82 +
  83 +// 保存合同类型模板
  84 +export function saveContractTypeTemplate(data) {
  85 + return new Promise((resolve, reject) => {
  86 + request({
  87 + url: '/contract/saveContractTypeTemplate',
  88 + method: 'post',
  89 + data
  90 + }).then(response => {
  91 + const res = response.data
  92 + resolve(res)
  93 + }).catch(error => {
  94 + reject(error)
  95 + })
  96 + })
  97 +}
  98 +
  99 +// 更新合同类型模板
  100 +export function updateContractTypeTemplate(data) {
  101 + return new Promise((resolve, reject) => {
  102 + request({
  103 + url: '/contract/updateContractTypeTemplate',
  104 + method: 'post',
  105 + data
  106 + }).then(response => {
  107 + const res = response.data
  108 + resolve(res)
  109 + }).catch(error => {
  110 + reject(error)
  111 + })
  112 + })
  113 +}
  114 +
  115 +// 打印合同模板
  116 +export function printContractTemplate(params) {
  117 + return new Promise((resolve, reject) => {
  118 + request({
  119 + url: '/contract/printContractTemplate',
  120 + method: 'get',
  121 + params
  122 + }).then(response => {
  123 + const res = response.data
  124 + resolve(res)
  125 + }).catch(error => {
  126 + reject(error)
  127 + })
  128 + })
  129 +}
0 130 \ No newline at end of file
... ...
src/api/contract/contractTypeSpecManageApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +import { getCommunityId } from '@/api/community/communityApi'
  3 +
  4 +// 查询合同类型规格列表
  5 +export function queryContractTypeSpec(params) {
  6 + return new Promise((resolve, reject) => {
  7 + request({
  8 + url: '/contract/queryContractTypeSpec',
  9 + method: 'get',
  10 + params: {
  11 + ...params,
  12 + communityId: getCommunityId()
  13 + }
  14 + }).then(response => {
  15 + const res = response.data
  16 + resolve(res)
  17 + }).catch(error => {
  18 + reject(error)
  19 + })
  20 + })
  21 +}
  22 +
  23 +// 添加合同类型规格
  24 +export function saveContractTypeSpec(data) {
  25 + return new Promise((resolve, reject) => {
  26 + request({
  27 + url: '/contract/saveContractTypeSpec',
  28 + method: 'post',
  29 + data: {
  30 + ...data,
  31 + communityId: getCommunityId()
  32 + }
  33 + }).then(response => {
  34 + const res = response.data
  35 + resolve(res)
  36 + }).catch(error => {
  37 + reject(error)
  38 + })
  39 + })
  40 +}
  41 +
  42 +// 修改合同类型规格
  43 +export function updateContractTypeSpec(data) {
  44 + return new Promise((resolve, reject) => {
  45 + request({
  46 + url: '/contract/updateContractTypeSpec',
  47 + method: 'post',
  48 + data: {
  49 + ...data,
  50 + communityId: getCommunityId()
  51 + }
  52 + }).then(response => {
  53 + const res = response.data
  54 + resolve(res)
  55 + }).catch(error => {
  56 + reject(error)
  57 + })
  58 + })
  59 +}
  60 +
  61 +// 删除合同类型规格
  62 +export function deleteContractTypeSpec(data) {
  63 + return new Promise((resolve, reject) => {
  64 + request({
  65 + url: '/contract/deleteContractTypeSpec',
  66 + method: 'post',
  67 + data: {
  68 + ...data,
  69 + communityId: getCommunityId()
  70 + }
  71 + }).then(response => {
  72 + const res = response.data
  73 + resolve(res)
  74 + }).catch(error => {
  75 + reject(error)
  76 + })
  77 + })
  78 +}
0 79 \ No newline at end of file
... ...
src/api/contract/expirationContractManageApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 查询合同列表
  4 +export function queryContract(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/contract/queryContract',
  8 + method: 'get',
  9 + params
  10 + }).then(response => {
  11 + const res = response.data
  12 + resolve(res)
  13 + }).catch(error => {
  14 + reject(error)
  15 + })
  16 + })
  17 +}
  18 +
  19 +// 查询合同类型
  20 +export function queryContractType(params) {
  21 + return new Promise((resolve, reject) => {
  22 + request({
  23 + url: '/contract/queryContractType',
  24 + method: 'get',
  25 + params
  26 + }).then(response => {
  27 + const res = response.data
  28 + resolve(res)
  29 + }).catch(error => {
  30 + reject(error)
  31 + })
  32 + })
  33 +}
  34 +
  35 +// 终止合同
  36 +export function stopContract(data) {
  37 + return new Promise((resolve, reject) => {
  38 + request({
  39 + url: '/contract/stopContract',
  40 + method: 'post',
  41 + data
  42 + }).then(response => {
  43 + const res = response.data
  44 + resolve(res)
  45 + }).catch(error => {
  46 + reject(error)
  47 + })
  48 + })
  49 +}
0 50 \ No newline at end of file
... ...
src/api/contract/newContractManageApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 查询合同列表
  4 +export function getContractList(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/contract/queryContract',
  8 + method: 'get',
  9 + params
  10 + }).then(response => {
  11 + const res = response.data
  12 + resolve(res)
  13 + }).catch(error => {
  14 + reject(error)
  15 + })
  16 + })
  17 +}
  18 +
  19 +// 查询合同类型列表
  20 +export function getContractTypeList(params) {
  21 + return new Promise((resolve, reject) => {
  22 + request({
  23 + url: '/contract/queryContractType',
  24 + method: 'get',
  25 + params
  26 + }).then(response => {
  27 + const res = response.data
  28 + resolve(res)
  29 + }).catch(error => {
  30 + reject(error)
  31 + })
  32 + })
  33 +}
  34 +
  35 +// 查询合同规格
  36 +export function getContractTypeSpec(params) {
  37 + return new Promise((resolve, reject) => {
  38 + request({
  39 + url: '/contract/queryContractTypeSpec',
  40 + method: 'get',
  41 + params
  42 + }).then(response => {
  43 + const res = response.data
  44 + resolve(res)
  45 + }).catch(error => {
  46 + reject(error)
  47 + })
  48 + })
  49 +}
  50 +
  51 +// 更新合同信息
  52 +export function updateContract(data) {
  53 + return new Promise((resolve, reject) => {
  54 + request({
  55 + url: '/contract/updateContract',
  56 + method: 'post',
  57 + data
  58 + }).then(response => {
  59 + const res = response.data
  60 + resolve(res)
  61 + }).catch(error => {
  62 + reject(error)
  63 + })
  64 + })
  65 +}
  66 +
  67 +// 删除合同
  68 +export function deleteContract(data) {
  69 + return new Promise((resolve, reject) => {
  70 + request({
  71 + url: '/contract/deleteContract',
  72 + method: 'post',
  73 + data
  74 + }).then(response => {
  75 + const res = response.data
  76 + resolve(res)
  77 + }).catch(error => {
  78 + reject(error)
  79 + })
  80 + })
  81 +}
  82 +
  83 +// 上传合同文件
  84 +export function uploadContractFile(data) {
  85 + return new Promise((resolve, reject) => {
  86 + request({
  87 + url: '/contractFile/uploadContactFile',
  88 + method: 'post',
  89 + data,
  90 + headers: {
  91 + 'Content-Type': 'multipart/form-data'
  92 + }
  93 + }).then(response => {
  94 + const res = response.data
  95 + resolve(res)
  96 + }).catch(error => {
  97 + reject(error)
  98 + })
  99 + })
  100 +}
0 101 \ No newline at end of file
... ...
src/api/contract/printContractApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +/**
  4 + * 获取合同打印模板
  5 + * @param {Object} params 请求参数
  6 + * @returns {Promise} Promise对象
  7 + */
  8 +export function getPrintContractTemplate(params) {
  9 + return new Promise((resolve, reject) => {
  10 + request({
  11 + url: '/contract/printContractTemplate',
  12 + method: 'get',
  13 + params
  14 + }).then(response => {
  15 + const res = response.data
  16 + resolve(res)
  17 + }).catch(error => {
  18 + reject(error)
  19 + })
  20 + })
  21 +}
0 22 \ No newline at end of file
... ...
src/components/contract/ChooseContract.vue 0 → 100644
  1 +<template>
  2 + <el-dialog :title="$t('chooseContract.title')" :visible.sync="dialogVisible" width="80%">
  3 + <div class="search-wrapper">
  4 + <el-input v-model="chooseContractInfo._currentContractName" :placeholder="$t('chooseContract.searchPlaceholder')"
  5 + class="search-input" clearable>
  6 + <el-button slot="append" type="primary" @click="queryContracts">
  7 + <i class="el-icon-search"></i>
  8 + {{ $t('common.search') }}
  9 + </el-button>
  10 + </el-input>
  11 + </div>
  12 +
  13 + <el-table :data="chooseContractInfo.contracts" border style="width: 100%">
  14 + <el-table-column prop="contractName" :label="$t('chooseContract.contractName')" align="center" />
  15 + <el-table-column prop="contractCode" :label="$t('chooseContract.contractCode')" align="center" />
  16 + <el-table-column prop="contractTypeName" :label="$t('chooseContract.contractType')" align="center" />
  17 + <el-table-column prop="partyA" :label="$t('chooseContract.partyA')" align="center" />
  18 + <el-table-column prop="partyB" :label="$t('chooseContract.partyB')" align="center" />
  19 + <el-table-column prop="signingTime" :label="$t('chooseContract.signingTime')" align="center" />
  20 + <el-table-column :label="$t('common.operation')" align="center" width="120">
  21 + <template slot-scope="scope">
  22 + <el-button type="primary" size="mini" @click="chooseContract(scope.row)">
  23 + {{ $t('common.select') }}
  24 + </el-button>
  25 + </template>
  26 + </el-table-column>
  27 + </el-table>
  28 +
  29 + <div class="pagination-wrapper">
  30 + <el-pagination :current-page.sync="pagination.current" :page-sizes="[10, 20, 30, 50]" :page-size="pagination.size"
  31 + :total="pagination.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
  32 + @current-change="handleCurrentChange" />
  33 + </div>
  34 + </el-dialog>
  35 +</template>
  36 +
  37 +<script>
  38 +import { queryContract } from '@/api/contract/contractChangeDetailApi'
  39 +
  40 +export default {
  41 + name: 'ChooseContract',
  42 + props: {
  43 + emitChooseContract: {
  44 + type: String,
  45 + default: ''
  46 + },
  47 + },
  48 + data() {
  49 + return {
  50 + dialogVisible: false,
  51 + chooseContractInfo: {
  52 + contracts: [],
  53 + _currentContractName: ''
  54 + },
  55 + pagination: {
  56 + current: 1,
  57 + size: 10,
  58 + total: 0
  59 + }
  60 + }
  61 + },
  62 + methods: {
  63 + open() {
  64 + this.dialogVisible = true
  65 + this.refreshChooseContractInfo()
  66 + this.loadAllContractInfo(1, 10, '')
  67 + },
  68 + chooseContract(contract) {
  69 + if (contract['name']) {
  70 + contract.contractName = contract.name
  71 + }
  72 + this.$emit('chooseContract', contract)
  73 + this.$emit('listContractData', {
  74 + contractId: contract.contractId
  75 + })
  76 + this.dialogVisible = false
  77 + },
  78 + queryContracts() {
  79 + this.loadAllContractInfo(1, 10, this.chooseContractInfo._currentContractName)
  80 + },
  81 + refreshChooseContractInfo() {
  82 + this.chooseContractInfo._currentContractName = ''
  83 + },
  84 + loadAllContractInfo(page, row, name) {
  85 + const param = {
  86 + page,
  87 + row,
  88 + contractNameLike: name
  89 + }
  90 +
  91 + queryContract(param)
  92 + .then(response => {
  93 + const contractInfo = response
  94 + this.chooseContractInfo.contracts = contractInfo.data
  95 + this.pagination.total = contractInfo.total
  96 + })
  97 + .catch(error => {
  98 + console.error('请求失败:', error)
  99 + })
  100 + },
  101 + handleSizeChange(val) {
  102 + this.pagination.size = val
  103 + this.loadAllContractInfo(this.pagination.current, val)
  104 + },
  105 + handleCurrentChange(val) {
  106 + this.pagination.current = val
  107 + this.loadAllContractInfo(val, this.pagination.size)
  108 + }
  109 + }
  110 +}
  111 +</script>
  112 +
  113 +<style scoped>
  114 +.search-wrapper {
  115 + margin-bottom: 20px;
  116 +}
  117 +
  118 +.search-input {
  119 + width: 400px;
  120 +}
  121 +
  122 +.pagination-wrapper {
  123 + margin-top: 20px;
  124 + text-align: right;
  125 +}
  126 +</style>
0 127 \ No newline at end of file
... ...
src/components/contract/ContractChangeAssets.vue 0 → 100644
  1 +<template>
  2 + <el-card class="box-card">
  3 + <div slot="header" class="flex justify-between">
  4 + <span>{{ $t('contractChangeAssets.title') }}</span>
  5 + <el-button type="primary" size="small" style="float: right" @click="selectRoom">
  6 + <i class="el-icon-plus"></i>
  7 + {{ $t('common.add') }}
  8 + </el-button>
  9 + </div>
  10 +
  11 + <el-table :data="contractChangeAssetsInfo.rooms" border style="width: 100%">
  12 + <el-table-column prop="roomNum" :label="$t('contractChangeAssets.room')" align="center">
  13 + <template slot-scope="scope">
  14 + {{ scope.row.floorNum }}-{{ scope.row.unitNum }}-{{ scope.row.roomNum }}
  15 + </template>
  16 + </el-table-column>
  17 +
  18 + <el-table-column prop="ownerName" :label="$t('contractChangeAssets.owner')" align="center" />
  19 +
  20 + <el-table-column prop="link" :label="$t('contractChangeAssets.phone')" align="center" />
  21 +
  22 + <el-table-column prop="builtUpArea" :label="$t('contractChangeAssets.area')" align="center">
  23 + <template slot-scope="scope">
  24 + {{ scope.row.builtUpArea }} {{ $t('contractChangeAssets.squareMeters') }}
  25 + </template>
  26 + </el-table-column>
  27 +
  28 + <el-table-column prop="stateName" :label="$t('contractChangeAssets.status')" align="center" />
  29 +
  30 + <el-table-column :label="$t('common.operation')" align="center" width="120">
  31 + <template slot-scope="scope">
  32 + <el-button type="danger" size="mini" @click="openDelRoomModel(scope.row)">
  33 + {{ $t('common.delete') }}
  34 + </el-button>
  35 + </template>
  36 + </el-table-column>
  37 + </el-table>
  38 + </el-card>
  39 +</template>
  40 +
  41 +<script>
  42 +export default {
  43 + name: 'ContractChangeAssets',
  44 +
  45 + data() {
  46 + return {
  47 + contractChangeAssetsInfo: {
  48 + rooms: [],
  49 + contractId: '',
  50 + planType: '3003'
  51 + }
  52 + }
  53 + },
  54 + watch: {
  55 + contractChangeAssetsInfo: {
  56 + deep: true,
  57 + handler(newVal) {
  58 + this.$emit('changeNotify', newVal)
  59 + }
  60 + }
  61 + },
  62 + methods: {
  63 + selectRoom() {
  64 + this.$emit('openSearchRoom')
  65 + },
  66 + openDelRoomModel(room) {
  67 + this.$confirm(
  68 + this.$t('contractChangeAssets.confirmDelete'),
  69 + this.$t('common.tip'),
  70 + {
  71 + confirmButtonText: this.$t('common.confirm'),
  72 + cancelButtonText: this.$t('common.cancel'),
  73 + type: 'warning'
  74 + }
  75 + ).then(() => {
  76 + this.removeRoom(room)
  77 + })
  78 + },
  79 + removeRoom(room) {
  80 + this.contractChangeAssetsInfo.rooms = this.contractChangeAssetsInfo.rooms.filter(
  81 + item => item.roomId !== room.roomId
  82 + )
  83 + },
  84 + loadContractRooms() {
  85 + // 这里应该调用API加载合同关联的房间数据
  86 + // 示例代码:
  87 + /*
  88 + getContractRooms({ contractId: this.contractChangeAssetsInfo.contractId })
  89 + .then(response => {
  90 + this.contractChangeAssetsInfo.rooms = response.data
  91 + })
  92 + */
  93 + }
  94 + },
  95 + created() {
  96 + this.$on('chooseRoom', room => {
  97 + // 检查是否已存在相同房间
  98 + const exists = this.contractChangeAssetsInfo.rooms.some(
  99 + item => item.roomId === room.roomId
  100 + )
  101 + if (!exists) {
  102 + this.contractChangeAssetsInfo.rooms.push(room)
  103 + }
  104 + })
  105 +
  106 + this.$on('contractInfo', param => {
  107 + this.contractChangeAssetsInfo.contractId = param.contractId
  108 + this.loadContractRooms()
  109 + })
  110 + }
  111 +}
  112 +</script>
  113 +
  114 +<style scoped>
  115 +.box-card {
  116 + margin-bottom: 20px;
  117 +}
  118 +</style>
0 119 \ No newline at end of file
... ...
src/components/contract/ContractChangeLease.vue 0 → 100644
  1 +<template>
  2 + <el-card class="box-card">
  3 + <div slot="header" class="flex justify-between">
  4 + <span>{{ $t('contractChangeLease.title') }}</span>
  5 + </div>
  6 + <el-form label-width="120px">
  7 + <el-row :gutter="20">
  8 + <el-col :span="24">
  9 + <el-form-item :label="$t('contractChangeLease.startTime')" required>
  10 + <el-date-picker v-model="contractChangeLeaseInfo.startTime" type="datetime"
  11 + :placeholder="$t('contractChangeLease.startTimePlaceholder')" style="width: 100%"></el-date-picker>
  12 + </el-form-item>
  13 + </el-col>
  14 + </el-row>
  15 +
  16 + <el-row :gutter="20">
  17 + <el-col :span="24">
  18 + <el-form-item :label="$t('contractChangeLease.endTime')" required>
  19 + <el-date-picker v-model="contractChangeLeaseInfo.endTime" type="datetime"
  20 + :placeholder="$t('contractChangeLease.endTimePlaceholder')" style="width: 100%"></el-date-picker>
  21 + </el-form-item>
  22 + </el-col>
  23 + </el-row>
  24 + </el-form>
  25 + </el-card>
  26 +</template>
  27 +
  28 +<script>
  29 +export default {
  30 + name: 'ContractChangeLease',
  31 + data() {
  32 + return {
  33 + contractChangeLeaseInfo: {
  34 + startTime: '',
  35 + endTime: '',
  36 + planType: '2002'
  37 + }
  38 + }
  39 + },
  40 + watch: {
  41 + contractChangeLeaseInfo: {
  42 + deep: true,
  43 + handler(newVal) {
  44 + this.$emit('changeNotify', newVal)
  45 + }
  46 + }
  47 + },
  48 + methods: {
  49 + clear() {
  50 + this.contractChangeLeaseInfo = {
  51 + startTime: '',
  52 + endTime: '',
  53 + planType: '2002'
  54 + }
  55 + }
  56 + }
  57 +}
  58 +</script>
  59 +
  60 +<style scoped>
  61 +.box-card {
  62 + margin-bottom: 20px;
  63 +}
  64 +</style>
0 65 \ No newline at end of file
... ...
src/components/contract/ContractChangeMainBody.vue 0 → 100644
  1 +<template>
  2 + <el-card class="box-card">
  3 + <div slot="header" class="clearfix">
  4 + <span>{{ $t('contractChangeMainBody.title') }}</span>
  5 + </div>
  6 + <el-form label-width="120px">
  7 + <el-row :gutter="20">
  8 + <el-col :span="24">
  9 + <el-form-item :label="$t('contractChangeMainBody.contractName')" required>
  10 + <el-input v-model="contractChangeMainBodyInfo.contractName"
  11 + :placeholder="$t('contractChangeMainBody.contractNamePlaceholder')"></el-input>
  12 + </el-form-item>
  13 + </el-col>
  14 + </el-row>
  15 +
  16 + <el-row :gutter="20">
  17 + <el-col :span="24">
  18 + <el-form-item :label="$t('contractChangeMainBody.partyA')" required>
  19 + <el-input v-model="contractChangeMainBodyInfo.partyA"
  20 + :placeholder="$t('contractChangeMainBody.partyAPlaceholder')"></el-input>
  21 + </el-form-item>
  22 + </el-col>
  23 + </el-row>
  24 +
  25 + <el-row :gutter="20">
  26 + <el-col :span="24">
  27 + <el-form-item :label="$t('contractChangeMainBody.aContacts')" required>
  28 + <el-input v-model="contractChangeMainBodyInfo.aContacts"
  29 + :placeholder="$t('contractChangeMainBody.aContactsPlaceholder')"></el-input>
  30 + </el-form-item>
  31 + </el-col>
  32 + </el-row>
  33 +
  34 + <el-row :gutter="20">
  35 + <el-col :span="24">
  36 + <el-form-item :label="$t('contractChangeMainBody.aLink')" required>
  37 + <el-input v-model="contractChangeMainBodyInfo.aLink"
  38 + :placeholder="$t('contractChangeMainBody.aLinkPlaceholder')"></el-input>
  39 + </el-form-item>
  40 + </el-col>
  41 + </el-row>
  42 +
  43 + <el-row :gutter="20">
  44 + <el-col :span="24">
  45 + <el-form-item :label="$t('contractChangeMainBody.partyB')" required>
  46 + <el-input v-model="contractChangeMainBodyInfo.partyB"
  47 + :placeholder="$t('contractChangeMainBody.partyBPlaceholder')"></el-input>
  48 + </el-form-item>
  49 + </el-col>
  50 + </el-row>
  51 +
  52 + <el-row :gutter="20">
  53 + <el-col :span="24">
  54 + <el-form-item :label="$t('contractChangeMainBody.bContacts')" required>
  55 + <el-input v-model="contractChangeMainBodyInfo.bContacts"
  56 + :placeholder="$t('contractChangeMainBody.bContactsPlaceholder')"></el-input>
  57 + </el-form-item>
  58 + </el-col>
  59 + </el-row>
  60 +
  61 + <el-row :gutter="20">
  62 + <el-col :span="24">
  63 + <el-form-item :label="$t('contractChangeMainBody.bLink')" required>
  64 + <el-input v-model="contractChangeMainBodyInfo.bLink"
  65 + :placeholder="$t('contractChangeMainBody.bLinkPlaceholder')"></el-input>
  66 + </el-form-item>
  67 + </el-col>
  68 + </el-row>
  69 + </el-form>
  70 + </el-card>
  71 +</template>
  72 +
  73 +<script>
  74 +export default {
  75 + name: 'ContractChangeMainBody',
  76 +
  77 + data() {
  78 + return {
  79 + contractChangeMainBodyInfo: {
  80 + contractName: '',
  81 + partyA: '',
  82 + aContacts: '',
  83 + aLink: '',
  84 + partyB: '',
  85 + bContacts: '',
  86 + bLink: '',
  87 + planType: '1001'
  88 + }
  89 + }
  90 + },
  91 + watch: {
  92 + contractChangeMainBodyInfo: {
  93 + deep: true,
  94 + handler(newVal) {
  95 + this.$emit('changeMainBody', newVal)
  96 + }
  97 + }
  98 + },
  99 + methods: {
  100 + clear() {
  101 + this.contractChangeMainBodyInfo = {
  102 + contractName: '',
  103 + partyA: '',
  104 + aContacts: '',
  105 + aLink: '',
  106 + partyB: '',
  107 + bContacts: '',
  108 + bLink: '',
  109 + planType: '1001'
  110 + }
  111 + }
  112 + }
  113 +}
  114 +</script>
  115 +
  116 +<style scoped>
  117 +.box-card {
  118 + margin-bottom: 20px;
  119 +}
  120 +</style>
0 121 \ No newline at end of file
... ...
src/components/contract/StopContract.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('stopContract.dialog.title')"
  4 + :visible.sync="visible"
  5 + width="30%"
  6 + :before-close="handleClose"
  7 + >
  8 + <div class="dialog-body">
  9 + <p>{{ $t('stopContract.dialog.content') }}</p>
  10 + </div>
  11 + <span slot="footer" class="dialog-footer">
  12 + <el-button @click="handleClose">{{ $t('stopContract.button.cancel') }}</el-button>
  13 + <el-button type="primary" @click="handleConfirm">{{ $t('stopContract.button.confirm') }}</el-button>
  14 + </span>
  15 + </el-dialog>
  16 +</template>
  17 +
  18 +<script>
  19 +import { stopContract } from '@/api/contract/expirationContractManageApi'
  20 +
  21 +export default {
  22 + name: 'StopContract',
  23 + data() {
  24 + return {
  25 + visible: false,
  26 + currentContract: null
  27 + }
  28 + },
  29 + methods: {
  30 + open(contract) {
  31 + this.currentContract = contract
  32 + this.visible = true
  33 + },
  34 + handleClose() {
  35 + this.visible = false
  36 + this.currentContract = null
  37 + },
  38 + async handleConfirm() {
  39 + try {
  40 + await stopContract(this.currentContract)
  41 + this.$message.success(this.$t('stopContract.message.success'))
  42 + this.$emit('success')
  43 + this.handleClose()
  44 + } catch (error) {
  45 + this.$message.error(this.$t('stopContract.message.error'))
  46 + }
  47 + }
  48 + }
  49 +}
  50 +</script>
  51 +
  52 +<style lang="scss" scoped>
  53 +.dialog-body {
  54 + text-align: center;
  55 + padding: 20px 0;
  56 + font-size: 16px;
  57 +}
  58 +</style>
0 59 \ No newline at end of file
... ...
src/components/contract/addContractPartya.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('contractPartyaManage.add.title')"
  4 + :visible.sync="visible"
  5 + width="50%"
  6 + @close="handleClose"
  7 + >
  8 + <el-form ref="form" :model="formData" :rules="rules" label-width="120px">
  9 + <el-form-item
  10 + :label="$t('contractPartyaManage.form.partyA')"
  11 + prop="partyA"
  12 + >
  13 + <el-input
  14 + v-model="formData.partyA"
  15 + :placeholder="$t('contractPartyaManage.form.partyAPlaceholder')"
  16 + />
  17 + </el-form-item>
  18 + <el-form-item
  19 + :label="$t('contractPartyaManage.form.aContacts')"
  20 + prop="aContacts"
  21 + >
  22 + <el-input
  23 + v-model="formData.aContacts"
  24 + :placeholder="$t('contractPartyaManage.form.aContactsPlaceholder')"
  25 + />
  26 + </el-form-item>
  27 + <el-form-item
  28 + :label="$t('contractPartyaManage.form.aLink')"
  29 + prop="aLink"
  30 + >
  31 + <el-input
  32 + v-model="formData.aLink"
  33 + :placeholder="$t('contractPartyaManage.form.aLinkPlaceholder')"
  34 + />
  35 + </el-form-item>
  36 + </el-form>
  37 + <span slot="footer" class="dialog-footer">
  38 + <el-button @click="visible = false">
  39 + {{ $t('common.cancel') }}
  40 + </el-button>
  41 + <el-button type="primary" @click="handleSubmit">
  42 + {{ $t('common.confirm') }}
  43 + </el-button>
  44 + </span>
  45 + </el-dialog>
  46 +</template>
  47 +
  48 +<script>
  49 +import { saveContractPartya } from '@/api/contract/contractPartyaManageApi'
  50 +import { getCommunityId } from '@/api/community/communityApi'
  51 +
  52 +export default {
  53 + name: 'AddContractPartya',
  54 + data() {
  55 + return {
  56 + visible: false,
  57 + formData: {
  58 + partyA: '',
  59 + aContacts: '',
  60 + aLink: '',
  61 + communityId: ''
  62 + },
  63 + rules: {
  64 + partyA: [
  65 + {
  66 + required: true,
  67 + message: this.$t('contractPartyaManage.validate.partyARequired'),
  68 + trigger: 'blur'
  69 + },
  70 + {
  71 + max: 200,
  72 + message: this.$t('contractPartyaManage.validate.partyAMaxLength'),
  73 + trigger: 'blur'
  74 + }
  75 + ],
  76 + aContacts: [
  77 + {
  78 + required: true,
  79 + message: this.$t('contractPartyaManage.validate.aContactsRequired'),
  80 + trigger: 'blur'
  81 + },
  82 + {
  83 + max: 64,
  84 + message: this.$t('contractPartyaManage.validate.aContactsMaxLength'),
  85 + trigger: 'blur'
  86 + }
  87 + ],
  88 + aLink: [
  89 + {
  90 + required: true,
  91 + message: this.$t('contractPartyaManage.validate.aLinkRequired'),
  92 + trigger: 'blur'
  93 + },
  94 + {
  95 + pattern: /^1[3-9]\d{9}$/,
  96 + message: this.$t('contractPartyaManage.validate.aLinkFormat'),
  97 + trigger: 'blur'
  98 + }
  99 + ]
  100 + }
  101 + }
  102 + },
  103 + methods: {
  104 + open() {
  105 + this.visible = true
  106 + this.formData.communityId = getCommunityId()
  107 + this.$nextTick(() => {
  108 + this.$refs.form && this.$refs.form.resetFields()
  109 + })
  110 + },
  111 + handleClose() {
  112 + this.$refs.form.resetFields()
  113 + },
  114 + handleSubmit() {
  115 + this.$refs.form.validate(async valid => {
  116 + if (valid) {
  117 + try {
  118 + await saveContractPartya(this.formData)
  119 + this.$message.success(this.$t('common.addSuccess'))
  120 + this.visible = false
  121 + this.$emit('success')
  122 + } catch (error) {
  123 + this.$message.error(error.message || this.$t('common.addFailed'))
  124 + }
  125 + }
  126 + })
  127 + }
  128 + }
  129 +}
  130 +</script>
0 131 \ No newline at end of file
... ...
src/components/contract/addContractType.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('contractTypeManage.add.title')"
  4 + :visible.sync="visible"
  5 + width="50%"
  6 + @close="handleClose"
  7 + >
  8 + <el-form
  9 + ref="form"
  10 + :model="form"
  11 + :rules="rules"
  12 + label-width="120px"
  13 + >
  14 + <el-form-item
  15 + :label="$t('contractTypeManage.add.typeName')"
  16 + prop="typeName"
  17 + >
  18 + <el-input
  19 + v-model="form.typeName"
  20 + :placeholder="$t('contractTypeManage.add.typeNamePlaceholder')"
  21 + />
  22 + </el-form-item>
  23 +
  24 + <el-form-item
  25 + :label="$t('contractTypeManage.add.audit')"
  26 + prop="audit"
  27 + >
  28 + <el-select
  29 + v-model="form.audit"
  30 + :placeholder="$t('contractTypeManage.add.auditPlaceholder')"
  31 + style="width:100%"
  32 + >
  33 + <el-option
  34 + v-for="item in audits"
  35 + :key="item.statusCd"
  36 + :label="item.name"
  37 + :value="item.statusCd"
  38 + />
  39 + </el-select>
  40 + </el-form-item>
  41 +
  42 + <el-form-item
  43 + :label="$t('contractTypeManage.add.remark')"
  44 + prop="remark"
  45 + >
  46 + <el-input
  47 + v-model="form.remark"
  48 + type="textarea"
  49 + :rows="3"
  50 + :placeholder="$t('contractTypeManage.add.remarkPlaceholder')"
  51 + />
  52 + </el-form-item>
  53 + </el-form>
  54 +
  55 + <div slot="footer" class="dialog-footer">
  56 + <el-button @click="visible = false">
  57 + {{ $t('common.cancel') }}
  58 + </el-button>
  59 + <el-button type="primary" @click="saveContractTypeInfo">
  60 + {{ $t('common.save') }}
  61 + </el-button>
  62 + </div>
  63 + </el-dialog>
  64 +</template>
  65 +
  66 +<script>
  67 +import { getDict } from '@/api/community/communityApi'
  68 +import { getCommunityId } from '@/api/community/communityApi'
  69 +import { saveContractType } from '@/api/contract/contractTypeManageApi'
  70 +
  71 +export default {
  72 + name: 'AddContractType',
  73 + data() {
  74 + return {
  75 + visible: false,
  76 + form: {
  77 + typeName: '',
  78 + audit: '',
  79 + remark: '',
  80 + communityId: ''
  81 + },
  82 + audits: [],
  83 + rules: {
  84 + typeName: [
  85 + { required: true, message: this.$t('contractTypeManage.validate.typeNameRequired'), trigger: 'blur' },
  86 + { max: 64, message: this.$t('contractTypeManage.validate.typeNameMaxLength'), trigger: 'blur' }
  87 + ],
  88 + audit: [
  89 + { required: true, message: this.$t('contractTypeManage.validate.auditRequired'), trigger: 'change' }
  90 + ],
  91 + remark: [
  92 + { max: 200, message: this.$t('contractTypeManage.validate.remarkMaxLength'), trigger: 'blur' }
  93 + ]
  94 + }
  95 + }
  96 + },
  97 + methods: {
  98 + open() {
  99 + this.visible = true
  100 + this.getAuditOptions()
  101 + },
  102 + async getAuditOptions() {
  103 + try {
  104 + const data = await getDict('contract_type', 'audit')
  105 + this.audits = data
  106 + } catch (error) {
  107 + console.error('获取审核选项失败:', error)
  108 + }
  109 + },
  110 + async saveContractTypeInfo() {
  111 + this.$refs.form.validate(async valid => {
  112 + if (!valid) return
  113 +
  114 + try {
  115 + this.form.communityId = getCommunityId()
  116 + const res = await saveContractType(this.form)
  117 +
  118 + if (res.code === 0) {
  119 + this.$message.success(this.$t('common.operateSuccess'))
  120 + this.visible = false
  121 + this.$emit('success')
  122 + } else {
  123 + this.$message.error(res.msg)
  124 + }
  125 + } catch (error) {
  126 + this.$message.error(this.$t('common.operateFailed'))
  127 + }
  128 + })
  129 + },
  130 + handleClose() {
  131 + this.$refs.form.resetFields()
  132 + this.form = {
  133 + typeName: '',
  134 + audit: '',
  135 + remark: '',
  136 + communityId: ''
  137 + }
  138 + }
  139 + }
  140 +}
  141 +</script>
  142 +
  143 +<style lang="scss" scoped>
  144 +.el-select {
  145 + width: 100%;
  146 +}
  147 +</style>
0 148 \ No newline at end of file
... ...
src/components/contract/addContractTypeSpec.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('contractTypeSpecManage.add.title')"
  4 + :visible.sync="visible"
  5 + width="50%"
  6 + @close="handleClose"
  7 + >
  8 + <el-form ref="form" :model="formData" :rules="rules" label-width="120px">
  9 + <el-form-item
  10 + :label="$t('contractTypeSpecManage.add.specName')"
  11 + prop="specName"
  12 + >
  13 + <el-input
  14 + v-model="formData.specName"
  15 + :placeholder="$t('contractTypeSpecManage.add.specNamePlaceholder')"
  16 + />
  17 + </el-form-item>
  18 + <el-form-item
  19 + :label="$t('contractTypeSpecManage.add.specHoldplace')"
  20 + prop="specHoldplace"
  21 + >
  22 + <el-input
  23 + v-model="formData.specHoldplace"
  24 + :placeholder="$t('contractTypeSpecManage.add.specHoldplacePlaceholder')"
  25 + />
  26 + </el-form-item>
  27 + <el-form-item
  28 + :label="$t('contractTypeSpecManage.add.required')"
  29 + prop="required"
  30 + >
  31 + <el-select
  32 + v-model="formData.required"
  33 + :placeholder="$t('contractTypeSpecManage.add.requiredPlaceholder')"
  34 + style="width:100%"
  35 + >
  36 + <el-option
  37 + :label="$t('common.yes')"
  38 + value="Y"
  39 + />
  40 + <el-option
  41 + :label="$t('common.no')"
  42 + value="N"
  43 + />
  44 + </el-select>
  45 + </el-form-item>
  46 + <el-form-item
  47 + :label="$t('contractTypeSpecManage.add.specShow')"
  48 + prop="specShow"
  49 + >
  50 + <el-select
  51 + v-model="formData.specShow"
  52 + :placeholder="$t('contractTypeSpecManage.add.specShowPlaceholder')"
  53 + style="width:100%"
  54 + >
  55 + <el-option
  56 + :label="$t('common.yes')"
  57 + value="Y"
  58 + />
  59 + <el-option
  60 + :label="$t('common.no')"
  61 + value="N"
  62 + />
  63 + </el-select>
  64 + </el-form-item>
  65 + <el-form-item
  66 + :label="$t('contractTypeSpecManage.add.specValueType')"
  67 + prop="specValueType"
  68 + >
  69 + <el-select
  70 + v-model="formData.specValueType"
  71 + :placeholder="$t('contractTypeSpecManage.add.specValueTypePlaceholder')"
  72 + style="width:100%"
  73 + >
  74 + <el-option
  75 + :label="$t('contractTypeSpecManage.specValueType.string')"
  76 + value="1001"
  77 + />
  78 + <el-option
  79 + :label="$t('contractTypeSpecManage.specValueType.integer')"
  80 + value="2002"
  81 + />
  82 + <el-option
  83 + :label="$t('contractTypeSpecManage.specValueType.amount')"
  84 + value="3003"
  85 + />
  86 + <el-option
  87 + :label="$t('contractTypeSpecManage.specValueType.date')"
  88 + value="4004"
  89 + />
  90 + <el-option
  91 + :label="$t('contractTypeSpecManage.specValueType.time')"
  92 + value="5005"
  93 + />
  94 + </el-select>
  95 + </el-form-item>
  96 + <el-form-item
  97 + :label="$t('contractTypeSpecManage.add.specType')"
  98 + prop="specType"
  99 + >
  100 + <el-select
  101 + v-model="formData.specType"
  102 + :placeholder="$t('contractTypeSpecManage.add.specTypePlaceholder')"
  103 + style="width:100%"
  104 + >
  105 + <el-option
  106 + :label="$t('contractTypeSpecManage.specType.input')"
  107 + value="2233"
  108 + />
  109 + <el-option
  110 + :label="$t('contractTypeSpecManage.specType.select')"
  111 + value="3344"
  112 + />
  113 + </el-select>
  114 + </el-form-item>
  115 + <el-form-item
  116 + :label="$t('contractTypeSpecManage.add.listShow')"
  117 + prop="listShow"
  118 + >
  119 + <el-select
  120 + v-model="formData.listShow"
  121 + :placeholder="$t('contractTypeSpecManage.add.listShowPlaceholder')"
  122 + style="width:100%"
  123 + >
  124 + <el-option
  125 + :label="$t('common.yes')"
  126 + value="Y"
  127 + />
  128 + <el-option
  129 + :label="$t('common.no')"
  130 + value="N"
  131 + />
  132 + </el-select>
  133 + </el-form-item>
  134 + </el-form>
  135 + <span slot="footer" class="dialog-footer">
  136 + <el-button @click="visible = false">
  137 + {{ $t('common.cancel') }}
  138 + </el-button>
  139 + <el-button type="primary" @click="handleSubmit">
  140 + {{ $t('common.confirm') }}
  141 + </el-button>
  142 + </span>
  143 + </el-dialog>
  144 +</template>
  145 +
  146 +<script>
  147 +import { saveContractTypeSpec } from '@/api/contract/contractTypeSpecManageApi'
  148 +import { getCommunityId } from '@/api/community/communityApi'
  149 +
  150 +export default {
  151 + name: 'AddContractTypeSpec',
  152 + data() {
  153 + return {
  154 + visible: false,
  155 + formData: {
  156 + specName: '',
  157 + specHoldplace: '',
  158 + required: '',
  159 + specShow: '',
  160 + specValueType: '',
  161 + specType: '',
  162 + listShow: '',
  163 + contractTypeId: '',
  164 + communityId: ''
  165 + },
  166 + rules: {
  167 + specName: [
  168 + { required: true, message: this.$t('contractTypeSpecManage.validate.specNameRequired'), trigger: 'blur' },
  169 + { max: 64, message: this.$t('contractTypeSpecManage.validate.specNameMaxLength'), trigger: 'blur' }
  170 + ],
  171 + specHoldplace: [
  172 + { max: 200, message: this.$t('contractTypeSpecManage.validate.specHoldplaceMaxLength'), trigger: 'blur' }
  173 + ],
  174 + required: [
  175 + { required: true, message: this.$t('contractTypeSpecManage.validate.requiredRequired'), trigger: 'change' }
  176 + ],
  177 + specShow: [
  178 + { required: true, message: this.$t('contractTypeSpecManage.validate.specShowRequired'), trigger: 'change' }
  179 + ],
  180 + specValueType: [
  181 + { required: true, message: this.$t('contractTypeSpecManage.validate.specValueTypeRequired'), trigger: 'change' }
  182 + ],
  183 + specType: [
  184 + { required: true, message: this.$t('contractTypeSpecManage.validate.specTypeRequired'), trigger: 'change' }
  185 + ],
  186 + listShow: [
  187 + { required: true, message: this.$t('contractTypeSpecManage.validate.listShowRequired'), trigger: 'change' }
  188 + ]
  189 + }
  190 + }
  191 + },
  192 + methods: {
  193 + open(data) {
  194 + this.formData.contractTypeId = data.contractTypeId
  195 + this.formData.communityId = getCommunityId()
  196 + this.visible = true
  197 + this.$nextTick(() => {
  198 + this.$refs.form.clearValidate()
  199 + })
  200 + },
  201 + handleClose() {
  202 + this.$refs.form.resetFields()
  203 + },
  204 + handleSubmit() {
  205 + this.$refs.form.validate(async valid => {
  206 + if (valid) {
  207 + try {
  208 + await saveContractTypeSpec(this.formData)
  209 + this.$message.success(this.$t('contractTypeSpecManage.add.success'))
  210 + this.visible = false
  211 + this.$emit('success')
  212 + } catch (error) {
  213 + this.$message.error(error.message || this.$t('contractTypeSpecManage.add.error'))
  214 + }
  215 + }
  216 + })
  217 + }
  218 + }
  219 +}
  220 +</script>
0 221 \ No newline at end of file
... ...
src/components/contract/addTemplateView.vue 0 → 100644
  1 +<template>
  2 + <el-dialog :title="$t('contractTypeManage.template.title')" :visible.sync="visible" width="80%" @close="handleClose">
  3 + <el-card>
  4 + <div class="attr-buttons">
  5 + <el-button v-for="(item, index) in contractTypeAttrs" :key="index" type="primary" size="small"
  6 + @click="insertAttrs(item)">
  7 + {{ item }}
  8 + </el-button>
  9 + </div>
  10 +
  11 + <el-form label-width="120px">
  12 + <el-form-item :label="$t('contractTypeManage.template.content')">
  13 + <div class="editor-container">
  14 + <el-input type="textarea" :rows="15" v-model="context"
  15 + :placeholder="$t('contractTypeManage.template.placeholder')" />
  16 + </div>
  17 + </el-form-item>
  18 + </el-form>
  19 + </el-card>
  20 +
  21 + <div slot="footer" class="dialog-footer">
  22 + <el-button @click="visible = false">
  23 + {{ $t('common.cancel') }}
  24 + </el-button>
  25 + <el-button type="primary" @click="saveTemplateInfo">
  26 + {{ $t('common.submit') }}
  27 + </el-button>
  28 + </div>
  29 + </el-dialog>
  30 +</template>
  31 +
  32 +<script>
  33 +import { saveContractTypeTemplate, updateContractTypeTemplate, queryContractTypeTemplate,printContractTemplate } from '@/api/contract/contractTypeManageApi'
  34 +
  35 +export default {
  36 + name: 'AddTemplateView',
  37 + data() {
  38 + return {
  39 + visible: false,
  40 + contractTypeId: '',
  41 + context: '',
  42 + templateId: '',
  43 + contractTypeAttrs: [],
  44 + contractTypeSpec:[]
  45 + }
  46 + },
  47 + methods: {
  48 + open(contractType) {
  49 + this.contractTypeId = contractType.contractTypeId
  50 + this.visible = true
  51 + this._loadContractAttrs(contractType.contractTypeId)
  52 +
  53 + this._loadTemplate()
  54 + },
  55 + async _loadContractAttrs(contractTypeId) {
  56 + try {
  57 + const params = {
  58 + page: 1,
  59 + row: 1,
  60 + contractTypeId
  61 + }
  62 + const { data } = await printContractTemplate(params)
  63 + this.contractTypeAttrs = []
  64 + this.contractTypeSpec = data.contractTypeSpec
  65 + this.contractTypeSpec.forEach(e => {
  66 + const rname = e.specName
  67 + const reg = `#${rname}#`
  68 + this.contractTypeAttrs.push(reg)
  69 + })
  70 + } catch (error) {
  71 + console.error('加载合同属性失败:', error)
  72 + }
  73 + },
  74 + insertAttrs(attr) {
  75 + this.context += attr
  76 + },
  77 + async saveTemplateInfo() {
  78 + if (!this.addTemplateValidate()) {
  79 + return
  80 + }
  81 +
  82 + try {
  83 + // const url = this.templateId ? '/contract/updateContractTypeTemplate' : '/contract/saveContractTypeTemplate'
  84 + const data = {
  85 + contractTypeId: this.contractTypeId,
  86 + context: this.context,
  87 + templateId: this.templateId
  88 + }
  89 +
  90 + const res = this.templateId
  91 + ? await updateContractTypeTemplate(data)
  92 + : await saveContractTypeTemplate(data)
  93 +
  94 + if (res.code === 0) {
  95 + this.$message.success(this.$t('common.operateSuccess'))
  96 + this.visible = false
  97 + this.$emit('success')
  98 + } else {
  99 + this.$message.error(res.msg)
  100 + }
  101 + } catch (error) {
  102 + this.$message.error(this.$t('common.operateFailed'))
  103 + }
  104 + },
  105 + addTemplateValidate() {
  106 + if (!this.contractTypeId) {
  107 + this.$message.error(this.$t('contractTypeManage.validate.contractTypeRequired'))
  108 + return false
  109 + }
  110 + if (!this.context) {
  111 + this.$message.error(this.$t('contractTypeManage.validate.contentRequired'))
  112 + return false
  113 + }
  114 + return true
  115 + },
  116 + async _loadTemplate() {
  117 + try {
  118 + const params = {
  119 + page: 1,
  120 + row: 1,
  121 + contractTypeId: this.contractTypeId
  122 + }
  123 + const { data } = await queryContractTypeTemplate(params)
  124 + if (data.length > 0) {
  125 + this.templateId = data[0].templateId
  126 + this.context = data[0].context
  127 + } else {
  128 + this.templateId = ''
  129 + this.context = ''
  130 + }
  131 + } catch (error) {
  132 + console.error('加载模板失败:', error)
  133 + }
  134 + },
  135 + handleClose() {
  136 + this.contractTypeId = ''
  137 + this.context = ''
  138 + this.templateId = ''
  139 + }
  140 + }
  141 +}
  142 +</script>
  143 +
  144 +<style lang="scss" scoped>
  145 +.attr-buttons {
  146 + margin-bottom: 20px;
  147 +
  148 + .el-button {
  149 + margin-right: 10px;
  150 + margin-bottom: 10px;
  151 + }
  152 +}
  153 +
  154 +.editor-container {
  155 + ::v-deep .el-textarea__inner {
  156 + min-height: 300px;
  157 + }
  158 +}
  159 +</style>
0 160 \ No newline at end of file
... ...
src/components/contract/deleteContract.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('contractManage.delete.title')"
  4 + :visible.sync="visible"
  5 + width="30%"
  6 + :before-close="handleClose"
  7 + >
  8 + <div style="text-align:center">
  9 + <p>{{ $t('contractManage.delete.confirmMessage') }}</p>
  10 + </div>
  11 + <span slot="footer" class="dialog-footer">
  12 + <el-button @click="handleClose">{{ $t('contractManage.delete.cancel') }}</el-button>
  13 + <el-button type="primary" @click="deleteContract">{{ $t('contractManage.delete.confirm') }}</el-button>
  14 + </span>
  15 + </el-dialog>
  16 +</template>
  17 +
  18 +<script>
  19 +import { deleteContract } from '@/api/contract/contractManageApi'
  20 +import { getCommunityId } from '@/api/community/communityApi'
  21 +
  22 +export default {
  23 + name: 'DeleteContract',
  24 + data() {
  25 + return {
  26 + visible: false,
  27 + contract: {}
  28 + }
  29 + },
  30 + methods: {
  31 + open(contract) {
  32 + this.contract = { ...contract }
  33 + this.visible = true
  34 + },
  35 + handleClose() {
  36 + this.visible = false
  37 + },
  38 + async deleteContract() {
  39 + try {
  40 + const params = {
  41 + ...this.contract,
  42 + communityId: getCommunityId()
  43 + }
  44 + await deleteContract(params)
  45 + this.$message.success(this.$t('contractManage.delete.success'))
  46 + this.$emit('success')
  47 + this.handleClose()
  48 + } catch (error) {
  49 + console.error('删除合同失败:', error)
  50 + this.$message.error(error.message || this.$t('contractManage.delete.error'))
  51 + }
  52 + }
  53 + }
  54 +}
  55 +</script>
0 56 \ No newline at end of file
... ...
src/components/contract/deleteContractChangePlan.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('deleteContractChangePlan.title')"
  4 + :visible.sync="visible"
  5 + width="500px"
  6 + @close="handleClose"
  7 + >
  8 + <div class="dialog-content">
  9 + <p>{{ $t('deleteContractChangePlan.confirmText') }}</p>
  10 + </div>
  11 + <div slot="footer" class="dialog-footer">
  12 + <el-button @click="handleClose">
  13 + {{ $t('common.cancel') }}
  14 + </el-button>
  15 + <el-button type="primary" @click="handleConfirm">
  16 + {{ $t('common.confirm') }}
  17 + </el-button>
  18 + </div>
  19 + </el-dialog>
  20 +</template>
  21 +
  22 +<script>
  23 +import { deleteContractChangePlan } from '@/api/contract/contractChangeManageApi'
  24 +
  25 +export default {
  26 + name: 'DeleteContractChangePlan',
  27 + data() {
  28 + return {
  29 + visible: false,
  30 + currentData: null
  31 + }
  32 + },
  33 + methods: {
  34 + open(data) {
  35 + this.currentData = data
  36 + this.visible = true
  37 + },
  38 + async handleConfirm() {
  39 + try {
  40 + await deleteContractChangePlan(this.currentData)
  41 + this.$message.success(this.$t('deleteContractChangePlan.deleteSuccess'))
  42 + this.$emit('success')
  43 + this.handleClose()
  44 + } catch (error) {
  45 + this.$message.error(error.message || this.$t('deleteContractChangePlan.deleteError'))
  46 + }
  47 + },
  48 + handleClose() {
  49 + this.visible = false
  50 + this.currentData = null
  51 + }
  52 + }
  53 +}
  54 +</script>
  55 +
  56 +<style lang="scss" scoped>
  57 +.dialog-content {
  58 + text-align: center;
  59 + padding: 20px 0;
  60 +
  61 + p {
  62 + font-size: 16px;
  63 + color: #606266;
  64 + }
  65 +}
  66 +
  67 +.dialog-footer {
  68 + text-align: right;
  69 +}
  70 +</style>
0 71 \ No newline at end of file
... ...
src/components/contract/deleteContractPartya.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('contractPartyaManage.delete.title')"
  4 + :visible.sync="visible"
  5 + width="30%"
  6 + @close="handleClose"
  7 + >
  8 + <div class="delete-content">
  9 + <p>{{ $t('contractPartyaManage.delete.confirmText') }}</p>
  10 + </div>
  11 + <span slot="footer" class="dialog-footer">
  12 + <el-button @click="visible = false">
  13 + {{ $t('common.cancel') }}
  14 + </el-button>
  15 + <el-button type="primary" @click="handleConfirm">
  16 + {{ $t('common.confirm') }}
  17 + </el-button>
  18 + </span>
  19 + </el-dialog>
  20 +</template>
  21 +
  22 +<script>
  23 +import { deleteContractPartya } from '@/api/contract/contractPartyaManageApi'
  24 +import { getCommunityId } from '@/api/community/communityApi'
  25 +
  26 +export default {
  27 + name: 'DeleteContractPartya',
  28 + data() {
  29 + return {
  30 + visible: false,
  31 + deleteData: {
  32 + partyaId: '',
  33 + communityId: ''
  34 + }
  35 + }
  36 + },
  37 + methods: {
  38 + open(data) {
  39 + this.visible = true
  40 + this.deleteData = {
  41 + partyaId: data.partyaId,
  42 + communityId: getCommunityId()
  43 + }
  44 + },
  45 + handleClose() {
  46 + this.deleteData = {
  47 + partyaId: '',
  48 + communityId: ''
  49 + }
  50 + },
  51 + async handleConfirm() {
  52 + try {
  53 + await deleteContractPartya(this.deleteData)
  54 + this.$message.success(this.$t('common.deleteSuccess'))
  55 + this.visible = false
  56 + this.$emit('success')
  57 + } catch (error) {
  58 + this.$message.error(error.message || this.$t('common.deleteFailed'))
  59 + }
  60 + }
  61 + }
  62 +}
  63 +</script>
  64 +
  65 +<style scoped>
  66 +.delete-content {
  67 + text-align: center;
  68 + font-size: 16px;
  69 + padding: 20px 0;
  70 +}
  71 +</style>
0 72 \ No newline at end of file
... ...
src/components/contract/deleteContractType.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('contractTypeManage.delete.title')"
  4 + :visible.sync="visible"
  5 + width="30%"
  6 + @close="handleClose"
  7 + >
  8 + <div class="delete-content">
  9 + <el-alert
  10 + type="warning"
  11 + :closable="false"
  12 + show-icon
  13 + >
  14 + {{ $t('contractTypeManage.delete.confirmText') }}
  15 + </el-alert>
  16 + </div>
  17 +
  18 + <div slot="footer" class="dialog-footer">
  19 + <el-button @click="visible = false">
  20 + {{ $t('common.cancel') }}
  21 + </el-button>
  22 + <el-button type="danger" @click="deleteContractType">
  23 + {{ $t('common.confirmDelete') }}
  24 + </el-button>
  25 + </div>
  26 + </el-dialog>
  27 +</template>
  28 +
  29 +<script>
  30 +import { getCommunityId } from '@/api/community/communityApi'
  31 +import { deleteContractType } from '@/api/contract/contractTypeManageApi'
  32 +
  33 +export default {
  34 + name: 'DeleteContractType',
  35 + data() {
  36 + return {
  37 + visible: false,
  38 + form: {
  39 + contractTypeId: '',
  40 + communityId: ''
  41 + }
  42 + }
  43 + },
  44 + methods: {
  45 + open(row) {
  46 + this.form = {
  47 + contractTypeId: row.contractTypeId,
  48 + communityId: getCommunityId()
  49 + }
  50 + this.visible = true
  51 + },
  52 + async deleteContractType() {
  53 + try {
  54 + const res = await deleteContractType(this.form)
  55 +
  56 + if (res.code === 0) {
  57 + this.$message.success(this.$t('common.operateSuccess'))
  58 + this.visible = false
  59 + this.$emit('success')
  60 + } else {
  61 + this.$message.error(res.msg)
  62 + }
  63 + } catch (error) {
  64 + this.$message.error(this.$t('common.operateFailed'))
  65 + }
  66 + },
  67 + handleClose() {
  68 + this.form = {
  69 + contractTypeId: '',
  70 + communityId: ''
  71 + }
  72 + }
  73 + }
  74 +}
  75 +</script>
  76 +
  77 +<style lang="scss" scoped>
  78 +.delete-content {
  79 + margin-bottom: 20px;
  80 +
  81 + .el-alert {
  82 + padding: 15px;
  83 + }
  84 +}
  85 +</style>
0 86 \ No newline at end of file
... ...
src/components/contract/deleteContractTypeSpec.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('contractTypeSpecManage.delete.title')"
  4 + :visible.sync="visible"
  5 + width="30%"
  6 + @close="handleClose"
  7 + >
  8 + <div class="text-center">
  9 + <p>{{ $t('contractTypeSpecManage.delete.confirmText') }}</p>
  10 + </div>
  11 + <span slot="footer" class="dialog-footer">
  12 + <el-button @click="visible = false">
  13 + {{ $t('common.cancel') }}
  14 + </el-button>
  15 + <el-button type="primary" @click="handleConfirm">
  16 + {{ $t('common.confirm') }}
  17 + </el-button>
  18 + </span>
  19 + </el-dialog>
  20 +</template>
  21 +
  22 +<script>
  23 +import { deleteContractTypeSpec } from '@/api/contract/contractTypeSpecManageApi'
  24 +import { getCommunityId } from '@/api/community/communityApi'
  25 +
  26 +export default {
  27 + name: 'DeleteContractTypeSpec',
  28 + data() {
  29 + return {
  30 + visible: false,
  31 + formData: {
  32 + specCd: '',
  33 + communityId: ''
  34 + }
  35 + }
  36 + },
  37 + methods: {
  38 + open(data) {
  39 + this.formData = {
  40 + specCd: data.specCd,
  41 + communityId: getCommunityId()
  42 + }
  43 + this.visible = true
  44 + },
  45 + handleClose() {
  46 + this.formData = {
  47 + specCd: '',
  48 + communityId: ''
  49 + }
  50 + },
  51 + async handleConfirm() {
  52 + try {
  53 + await deleteContractTypeSpec(this.formData)
  54 + this.$message.success(this.$t('contractTypeSpecManage.delete.success'))
  55 + this.visible = false
  56 + this.$emit('success')
  57 + } catch (error) {
  58 + this.$message.error(error.message || this.$t('contractTypeSpecManage.delete.error'))
  59 + }
  60 + }
  61 + }
  62 +}
  63 +</script>
0 64 \ No newline at end of file
... ...
src/components/contract/editContract.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('contractManage.edit.title')"
  4 + :visible.sync="visible"
  5 + width="70%"
  6 + :before-close="handleClose"
  7 + >
  8 + <el-form :model="editContractInfo" label-width="120px" ref="editForm">
  9 + <el-row :gutter="20">
  10 + <el-col :span="8">
  11 + <el-form-item :label="$t('contractManage.edit.contractName')" prop="contractName" required>
  12 + <el-input
  13 + v-model="editContractInfo.contractName"
  14 + :placeholder="$t('contractManage.edit.contractNamePlaceholder')"
  15 + />
  16 + </el-form-item>
  17 + </el-col>
  18 + <el-col :span="8">
  19 + <el-form-item :label="$t('contractManage.edit.contractCode')" prop="contractCode" required>
  20 + <el-input
  21 + v-model="editContractInfo.contractCode"
  22 + :placeholder="$t('contractManage.edit.contractCodePlaceholder')"
  23 + />
  24 + </el-form-item>
  25 + </el-col>
  26 + <el-col :span="8">
  27 + <el-form-item :label="$t('contractManage.edit.contractType')" prop="contractType" required>
  28 + <el-select
  29 + v-model="editContractInfo.contractType"
  30 + :placeholder="$t('contractManage.edit.contractTypePlaceholder')"
  31 + style="width:100%"
  32 + disabled
  33 + >
  34 + <el-option
  35 + v-for="item in editContractInfo.contractTypes"
  36 + :key="item.contractTypeId"
  37 + :label="item.typeName"
  38 + :value="item.contractTypeId"
  39 + />
  40 + </el-select>
  41 + </el-form-item>
  42 + </el-col>
  43 + </el-row>
  44 +
  45 + <el-row :gutter="20">
  46 + <el-col :span="8">
  47 + <el-form-item :label="$t('contractManage.edit.partyA')" prop="partyA" required>
  48 + <el-input
  49 + v-model="editContractInfo.partyA"
  50 + :placeholder="$t('contractManage.edit.partyAPlaceholder')"
  51 + />
  52 + </el-form-item>
  53 + </el-col>
  54 + <el-col :span="8">
  55 + <el-form-item :label="$t('contractManage.edit.aContacts')" prop="aContacts" required>
  56 + <el-input
  57 + v-model="editContractInfo.aContacts"
  58 + :placeholder="$t('contractManage.edit.aContactsPlaceholder')"
  59 + />
  60 + </el-form-item>
  61 + </el-col>
  62 + <el-col :span="8">
  63 + <el-form-item :label="$t('contractManage.edit.aLink')" prop="aLink" required>
  64 + <el-input
  65 + v-model="editContractInfo.aLink"
  66 + :placeholder="$t('contractManage.edit.aLinkPlaceholder')"
  67 + />
  68 + </el-form-item>
  69 + </el-col>
  70 + </el-row>
  71 +
  72 + <el-row :gutter="20">
  73 + <el-col :span="8">
  74 + <el-form-item :label="$t('contractManage.edit.partyB')" prop="partyB" required>
  75 + <el-input
  76 + v-model="editContractInfo.partyB"
  77 + :placeholder="$t('contractManage.edit.partyBPlaceholder')"
  78 + />
  79 + </el-form-item>
  80 + </el-col>
  81 + <el-col :span="8">
  82 + <el-form-item :label="$t('contractManage.edit.bContacts')" prop="bContacts" required>
  83 + <el-input
  84 + v-model="editContractInfo.bContacts"
  85 + :placeholder="$t('contractManage.edit.bContactsPlaceholder')"
  86 + />
  87 + </el-form-item>
  88 + </el-col>
  89 + <el-col :span="8">
  90 + <el-form-item :label="$t('contractManage.edit.bLink')" prop="bLink" required>
  91 + <el-input
  92 + v-model="editContractInfo.bLink"
  93 + :placeholder="$t('contractManage.edit.bLinkPlaceholder')"
  94 + />
  95 + </el-form-item>
  96 + </el-col>
  97 + </el-row>
  98 +
  99 + <el-row :gutter="20">
  100 + <el-col :span="8">
  101 + <el-form-item :label="$t('contractManage.edit.operator')" prop="operator" required>
  102 + <el-input
  103 + v-model="editContractInfo.operator"
  104 + :placeholder="$t('contractManage.edit.operatorPlaceholder')"
  105 + />
  106 + </el-form-item>
  107 + </el-col>
  108 + <el-col :span="8">
  109 + <el-form-item :label="$t('contractManage.edit.operatorLink')" prop="operatorLink" required>
  110 + <el-input
  111 + v-model="editContractInfo.operatorLink"
  112 + :placeholder="$t('contractManage.edit.operatorLinkPlaceholder')"
  113 + />
  114 + </el-form-item>
  115 + </el-col>
  116 + <el-col :span="8">
  117 + <el-form-item :label="$t('contractManage.edit.amount')" prop="amount">
  118 + <el-input
  119 + v-model="editContractInfo.amount"
  120 + :placeholder="$t('contractManage.edit.amountPlaceholder')"
  121 + />
  122 + </el-form-item>
  123 + </el-col>
  124 + </el-row>
  125 +
  126 + <el-row :gutter="20">
  127 + <el-col :span="8">
  128 + <el-form-item :label="$t('contractManage.edit.startTime')" prop="startTime" required>
  129 + <el-date-picker
  130 + v-model="editContractInfo.startTime"
  131 + type="datetime"
  132 + :placeholder="$t('contractManage.edit.startTimePlaceholder')"
  133 + style="width:100%"
  134 + />
  135 + </el-form-item>
  136 + </el-col>
  137 + <el-col :span="8">
  138 + <el-form-item :label="$t('contractManage.edit.endTime')" prop="endTime" required>
  139 + <el-date-picker
  140 + v-model="editContractInfo.endTime"
  141 + type="datetime"
  142 + :placeholder="$t('contractManage.edit.endTimePlaceholder')"
  143 + style="width:100%"
  144 + />
  145 + </el-form-item>
  146 + </el-col>
  147 + <el-col :span="8">
  148 + <el-form-item :label="$t('contractManage.edit.signingTime')" prop="signingTime" required>
  149 + <el-date-picker
  150 + v-model="editContractInfo.signingTime"
  151 + type="datetime"
  152 + :placeholder="$t('contractManage.edit.signingTimePlaceholder')"
  153 + style="width:100%"
  154 + />
  155 + </el-form-item>
  156 + </el-col>
  157 + </el-row>
  158 +
  159 + <!-- 合同类型规格 -->
  160 + <div v-for="(item,index) in editContractInfo.contractTypeSpecs" :key="index">
  161 + <el-row :gutter="20" v-if="index % 3 === 0">
  162 + <el-col :span="8" v-for="i in 3" :key="i">
  163 + <div v-if="editContractInfo.contractTypeSpecs[index + i - 1]">
  164 + <el-form-item :label="editContractInfo.contractTypeSpecs[index + i - 1].specName">
  165 + <el-input
  166 + v-model="editContractInfo.contractTypeSpecs[index + i - 1].value"
  167 + :placeholder="editContractInfo.contractTypeSpecs[index + i - 1].specHoldplace"
  168 + />
  169 + </el-form-item>
  170 + </div>
  171 + </el-col>
  172 + </el-row>
  173 + </div>
  174 +
  175 + <!-- 合同附件 -->
  176 + <el-form-item :label="$t('contractManage.edit.contractFiles')">
  177 + <el-button type="primary" @click="addFileStep">
  178 + {{ $t('contractManage.edit.addFile') }}
  179 + </el-button>
  180 + <div v-for="(item,index) in editContractInfo.contractFilePo" :key="index" style="margin-top:10px">
  181 + <el-row :gutter="10">
  182 + <el-col :span="2">
  183 + <span>{{ $t('contractManage.edit.fileIndex', {index: index+1}) }}</span>
  184 + </el-col>
  185 + <el-col :span="10">
  186 + <input
  187 + type="file"
  188 + style="display:inline-block;width:100%"
  189 + @change="getFile($event,index)"
  190 + accept=".png,.pdf,.jpg"
  191 + />
  192 + </el-col>
  193 + <el-col :span="6">
  194 + <span>{{ item.fileRealName }}</span>
  195 + </el-col>
  196 + <el-col :span="4">
  197 + <el-button type="text" @click="deleteStep(item)">
  198 + {{ $t('contractManage.edit.deleteFile') }}
  199 + </el-button>
  200 + </el-col>
  201 + </el-row>
  202 + </div>
  203 + </el-form-item>
  204 + </el-form>
  205 +
  206 + <span slot="footer" class="dialog-footer">
  207 + <el-button @click="handleClose">{{ $t('contractManage.edit.cancel') }}</el-button>
  208 + <el-button type="primary" @click="editContract">{{ $t('contractManage.edit.save') }}</el-button>
  209 + </span>
  210 + </el-dialog>
  211 +</template>
  212 +
  213 +<script>
  214 +import { updateContract, queryContractTypeSpec, queryContractFile, uploadContactFile } from '@/api/contract/contractManageApi'
  215 +
  216 +export default {
  217 + name: 'EditContract',
  218 + data() {
  219 + return {
  220 + visible: false,
  221 + editContractInfo: {
  222 + contractId: '',
  223 + contractName: '',
  224 + contractCode: '',
  225 + contractType: '',
  226 + partyA: '',
  227 + partyB: '',
  228 + aContacts: '',
  229 + bContacts: '',
  230 + aLink: '',
  231 + bLink: '',
  232 + operator: '',
  233 + operatorLink: '',
  234 + amount: '',
  235 + startTime: '',
  236 + endTime: '',
  237 + signingTime: '',
  238 + contractTypes: [],
  239 + contractTypeSpecs: [],
  240 + tempfile: null,
  241 + contractFilePo: []
  242 + }
  243 + }
  244 + },
  245 + methods: {
  246 + open(contract) {
  247 + this.resetForm()
  248 + this.editContractInfo = {
  249 + ...this.editContractInfo,
  250 + ...contract,
  251 + contractTypes: this.editContractInfo.contractTypes
  252 + }
  253 + this.loadContractType(contract)
  254 + this.loadFiles()
  255 + this.visible = true
  256 + },
  257 + handleClose() {
  258 + this.visible = false
  259 + },
  260 + resetForm() {
  261 + this.editContractInfo = {
  262 + contractId: '',
  263 + contractName: '',
  264 + contractCode: '',
  265 + contractType: '',
  266 + partyA: '',
  267 + partyB: '',
  268 + aContacts: '',
  269 + bContacts: '',
  270 + aLink: '',
  271 + bLink: '',
  272 + operator: '',
  273 + operatorLink: '',
  274 + amount: '',
  275 + startTime: '',
  276 + endTime: '',
  277 + signingTime: '',
  278 + contractTypes: this.editContractInfo.contractTypes,
  279 + contractTypeSpecs: [],
  280 + tempfile: null,
  281 + contractFilePo: []
  282 + }
  283 + },
  284 + async loadContractType(contract) {
  285 + try {
  286 + const params = {
  287 + page: 1,
  288 + row: 100,
  289 + contractTypeId: contract.contractType
  290 + }
  291 + const { data } = await queryContractTypeSpec(params)
  292 + this.editContractInfo.contractTypeSpecs = data.map(item => {
  293 + const attr = contract.attrs.find(attr => attr.specCd === item.specCd) || {}
  294 + return {
  295 + ...item,
  296 + value: attr.value || ''
  297 + }
  298 + }).filter(item => item.specShow === 'Y')
  299 + } catch (error) {
  300 + console.error('加载合同类型规格失败:', error)
  301 + }
  302 + },
  303 + async loadFiles() {
  304 + try {
  305 + const params = {
  306 + contractId: this.editContractInfo.contractId,
  307 + page: 1,
  308 + row: 100
  309 + }
  310 + const { data } = await queryContractFile(params)
  311 + this.editContractInfo.contractFilePo = data.map((file, index) => ({
  312 + seq: index,
  313 + fileSaveName: file.fileSaveName,
  314 + fileRealName: file.fileRealName
  315 + }))
  316 + } catch (error) {
  317 + console.error('加载合同文件失败:', error)
  318 + }
  319 + },
  320 + addFileStep() {
  321 + const newFile = {
  322 + seq: this.editContractInfo.contractFilePo.length,
  323 + fileSaveName: '',
  324 + fileRealName: ''
  325 + }
  326 + this.editContractInfo.contractFilePo.push(newFile)
  327 + },
  328 + deleteStep(step) {
  329 + this.editContractInfo.contractFilePo = this.editContractInfo.contractFilePo.filter(
  330 + item => item.seq !== step.seq
  331 + )
  332 + },
  333 + getFile(event, index) {
  334 + const file = event.target.files[0]
  335 + if (!file) return
  336 +
  337 + if (!this.checkFileType(file.name.split('.').pop())) {
  338 + this.$message.error(this.$t('contractManage.edit.fileTypeError'))
  339 + return
  340 + }
  341 +
  342 + this.editContractInfo.tempfile = file
  343 + this.editContractInfo.contractFilePo[index].fileRealName = file.name
  344 + this.uploadFile(index)
  345 + },
  346 + checkFileType(fileType) {
  347 + const acceptTypes = ['png', 'pdf', 'jpg']
  348 + return acceptTypes.includes(fileType.toLowerCase())
  349 + },
  350 + async uploadFile(index) {
  351 + try {
  352 + const formData = new FormData()
  353 + formData.append('uploadFile', this.editContractInfo.tempfile)
  354 +
  355 + const fileSaveName = await uploadContactFile(formData)
  356 + this.editContractInfo.contractFilePo[index].fileSaveName = fileSaveName
  357 + this.$message.success(this.$t('contractManage.edit.uploadSuccess'))
  358 + } catch (error) {
  359 + console.error('上传文件失败:', error)
  360 + this.$message.error(this.$t('contractManage.edit.uploadError'))
  361 + }
  362 + },
  363 + async editContract() {
  364 + try {
  365 + await updateContract(this.editContractInfo)
  366 + this.$message.success(this.$t('contractManage.edit.saveSuccess'))
  367 + this.$emit('success')
  368 + this.handleClose()
  369 + } catch (error) {
  370 + console.error('保存合同失败:', error)
  371 + this.$message.error(error.message || this.$t('contractManage.edit.saveError'))
  372 + }
  373 + }
  374 + }
  375 +}
  376 +</script>
0 377 \ No newline at end of file
... ...
src/components/contract/editContractPartya.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('contractPartyaManage.edit.title')"
  4 + :visible.sync="visible"
  5 + width="50%"
  6 + @close="handleClose"
  7 + >
  8 + <el-form ref="form" :model="formData" :rules="rules" label-width="120px">
  9 + <el-form-item
  10 + :label="$t('contractPartyaManage.form.partyA')"
  11 + prop="partyA"
  12 + >
  13 + <el-input
  14 + v-model="formData.partyA"
  15 + :placeholder="$t('contractPartyaManage.form.partyAPlaceholder')"
  16 + />
  17 + </el-form-item>
  18 + <el-form-item
  19 + :label="$t('contractPartyaManage.form.aContacts')"
  20 + prop="aContacts"
  21 + >
  22 + <el-input
  23 + v-model="formData.aContacts"
  24 + :placeholder="$t('contractPartyaManage.form.aContactsPlaceholder')"
  25 + />
  26 + </el-form-item>
  27 + <el-form-item
  28 + :label="$t('contractPartyaManage.form.aLink')"
  29 + prop="aLink"
  30 + >
  31 + <el-input
  32 + v-model="formData.aLink"
  33 + :placeholder="$t('contractPartyaManage.form.aLinkPlaceholder')"
  34 + />
  35 + </el-form-item>
  36 + </el-form>
  37 + <span slot="footer" class="dialog-footer">
  38 + <el-button @click="visible = false">
  39 + {{ $t('common.cancel') }}
  40 + </el-button>
  41 + <el-button type="primary" @click="handleSubmit">
  42 + {{ $t('common.confirm') }}
  43 + </el-button>
  44 + </span>
  45 + </el-dialog>
  46 +</template>
  47 +
  48 +<script>
  49 +import { updateContractPartya } from '@/api/contract/contractPartyaManageApi'
  50 +import { getCommunityId } from '@/api/community/communityApi'
  51 +
  52 +export default {
  53 + name: 'EditContractPartya',
  54 + data() {
  55 + return {
  56 + visible: false,
  57 + formData: {
  58 + partyaId: '',
  59 + partyA: '',
  60 + aContacts: '',
  61 + aLink: '',
  62 + communityId: ''
  63 + },
  64 + rules: {
  65 + partyA: [
  66 + {
  67 + required: true,
  68 + message: this.$t('contractPartyaManage.validate.partyARequired'),
  69 + trigger: 'blur'
  70 + },
  71 + {
  72 + max: 200,
  73 + message: this.$t('contractPartyaManage.validate.partyAMaxLength'),
  74 + trigger: 'blur'
  75 + }
  76 + ],
  77 + aContacts: [
  78 + {
  79 + required: true,
  80 + message: this.$t('contractPartyaManage.validate.aContactsRequired'),
  81 + trigger: 'blur'
  82 + },
  83 + {
  84 + max: 64,
  85 + message: this.$t('contractPartyaManage.validate.aContactsMaxLength'),
  86 + trigger: 'blur'
  87 + }
  88 + ],
  89 + aLink: [
  90 + {
  91 + required: true,
  92 + message: this.$t('contractPartyaManage.validate.aLinkRequired'),
  93 + trigger: 'blur'
  94 + },
  95 + {
  96 + pattern: /^1[3-9]\d{9}$/,
  97 + message: this.$t('contractPartyaManage.validate.aLinkFormat'),
  98 + trigger: 'blur'
  99 + }
  100 + ],
  101 + partyaId: [
  102 + {
  103 + required: true,
  104 + message: this.$t('contractPartyaManage.validate.partyaIdRequired'),
  105 + trigger: 'blur'
  106 + }
  107 + ]
  108 + }
  109 + }
  110 + },
  111 + methods: {
  112 + open(data) {
  113 + this.visible = true
  114 + this.formData = {
  115 + ...data,
  116 + communityId: getCommunityId()
  117 + }
  118 + },
  119 + handleClose() {
  120 + this.$refs.form.resetFields()
  121 + },
  122 + handleSubmit() {
  123 + this.$refs.form.validate(async valid => {
  124 + if (valid) {
  125 + try {
  126 + await updateContractPartya(this.formData)
  127 + this.$message.success(this.$t('common.editSuccess'))
  128 + this.visible = false
  129 + this.$emit('success')
  130 + } catch (error) {
  131 + this.$message.error(error.message || this.$t('common.editFailed'))
  132 + }
  133 + }
  134 + })
  135 + }
  136 + }
  137 +}
  138 +</script>
0 139 \ No newline at end of file
... ...
src/components/contract/editContractType.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('contractTypeManage.edit.title')"
  4 + :visible.sync="visible"
  5 + width="50%"
  6 + @close="handleClose"
  7 + >
  8 + <el-form
  9 + ref="form"
  10 + :model="form"
  11 + :rules="rules"
  12 + label-width="120px"
  13 + >
  14 + <el-form-item
  15 + :label="$t('contractTypeManage.edit.typeName')"
  16 + prop="typeName"
  17 + >
  18 + <el-input
  19 + v-model="form.typeName"
  20 + :placeholder="$t('contractTypeManage.edit.typeNamePlaceholder')"
  21 + />
  22 + </el-form-item>
  23 +
  24 + <el-form-item
  25 + :label="$t('contractTypeManage.edit.audit')"
  26 + prop="audit"
  27 + >
  28 + <el-select
  29 + v-model="form.audit"
  30 + :placeholder="$t('contractTypeManage.edit.auditPlaceholder')"
  31 + style="width:100%"
  32 + >
  33 + <el-option
  34 + v-for="item in audits"
  35 + :key="item.statusCd"
  36 + :label="item.name"
  37 + :value="item.statusCd"
  38 + />
  39 + </el-select>
  40 + </el-form-item>
  41 +
  42 + <el-form-item
  43 + :label="$t('contractTypeManage.edit.remark')"
  44 + prop="remark"
  45 + >
  46 + <el-input
  47 + v-model="form.remark"
  48 + type="textarea"
  49 + :rows="3"
  50 + :placeholder="$t('contractTypeManage.edit.remarkPlaceholder')"
  51 + />
  52 + </el-form-item>
  53 + </el-form>
  54 +
  55 + <div slot="footer" class="dialog-footer">
  56 + <el-button @click="visible = false">
  57 + {{ $t('common.cancel') }}
  58 + </el-button>
  59 + <el-button type="primary" @click="editContractType">
  60 + {{ $t('common.save') }}
  61 + </el-button>
  62 + </div>
  63 + </el-dialog>
  64 +</template>
  65 +
  66 +<script>
  67 +import { getDict } from '@/api/community/communityApi'
  68 +import { getCommunityId } from '@/api/community/communityApi'
  69 +import { updateContractType } from '@/api/contract/contractTypeManageApi'
  70 +
  71 +export default {
  72 + name: 'EditContractType',
  73 + data() {
  74 + return {
  75 + visible: false,
  76 + form: {
  77 + contractTypeId: '',
  78 + typeName: '',
  79 + audit: '',
  80 + remark: '',
  81 + communityId: ''
  82 + },
  83 + audits: [],
  84 + rules: {
  85 + contractTypeId: [
  86 + { required: true, message: this.$t('contractTypeManage.validate.contractTypeIdRequired'), trigger: 'blur' }
  87 + ],
  88 + typeName: [
  89 + { required: true, message: this.$t('contractTypeManage.validate.typeNameRequired'), trigger: 'blur' },
  90 + { max: 64, message: this.$t('contractTypeManage.validate.typeNameMaxLength'), trigger: 'blur' }
  91 + ],
  92 + audit: [
  93 + { required: true, message: this.$t('contractTypeManage.validate.auditRequired'), trigger: 'change' }
  94 + ],
  95 + remark: [
  96 + { max: 200, message: this.$t('contractTypeManage.validate.remarkMaxLength'), trigger: 'blur' }
  97 + ]
  98 + }
  99 + }
  100 + },
  101 + methods: {
  102 + open(row) {
  103 + this.form = {
  104 + contractTypeId: row.contractTypeId,
  105 + typeName: row.typeName,
  106 + audit: row.audit,
  107 + remark: row.remark,
  108 + communityId: getCommunityId()
  109 + }
  110 + this.getAuditOptions()
  111 + this.visible = true
  112 + },
  113 + async getAuditOptions() {
  114 + try {
  115 + const data = await getDict('contract_type', 'audit')
  116 + this.audits = data
  117 + } catch (error) {
  118 + console.error('获取审核选项失败:', error)
  119 + }
  120 + },
  121 + async editContractType() {
  122 + this.$refs.form.validate(async valid => {
  123 + if (!valid) return
  124 +
  125 + try {
  126 + const res = await updateContractType(this.form)
  127 +
  128 + if (res.code === 0) {
  129 + this.$message.success(this.$t('common.operateSuccess'))
  130 + this.visible = false
  131 + this.$emit('success')
  132 + } else {
  133 + this.$message.error(res.msg)
  134 + }
  135 + } catch (error) {
  136 + this.$message.error(this.$t('common.operateFailed'))
  137 + }
  138 + })
  139 + },
  140 + handleClose() {
  141 + this.$refs.form.resetFields()
  142 + this.form = {
  143 + contractTypeId: '',
  144 + typeName: '',
  145 + audit: '',
  146 + remark: '',
  147 + communityId: ''
  148 + }
  149 + }
  150 + }
  151 +}
  152 +</script>
  153 +
  154 +<style lang="scss" scoped>
  155 +.el-select {
  156 + width: 100%;
  157 +}
  158 +</style>
0 159 \ No newline at end of file
... ...
src/components/contract/editContractTypeSpec.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('contractTypeSpecManage.edit.title')"
  4 + :visible.sync="visible"
  5 + width="50%"
  6 + @close="handleClose"
  7 + >
  8 + <el-form ref="form" :model="formData" :rules="rules" label-width="120px">
  9 + <el-form-item
  10 + :label="$t('contractTypeSpecManage.edit.specName')"
  11 + prop="specName"
  12 + >
  13 + <el-input
  14 + v-model="formData.specName"
  15 + :placeholder="$t('contractTypeSpecManage.edit.specNamePlaceholder')"
  16 + />
  17 + </el-form-item>
  18 + <el-form-item
  19 + :label="$t('contractTypeSpecManage.edit.specHoldplace')"
  20 + prop="specHoldplace"
  21 + >
  22 + <el-input
  23 + v-model="formData.specHoldplace"
  24 + :placeholder="$t('contractTypeSpecManage.edit.specHoldplacePlaceholder')"
  25 + />
  26 + </el-form-item>
  27 + <el-form-item
  28 + :label="$t('contractTypeSpecManage.edit.required')"
  29 + prop="required"
  30 + >
  31 + <el-select
  32 + v-model="formData.required"
  33 + :placeholder="$t('contractTypeSpecManage.edit.requiredPlaceholder')"
  34 + style="width:100%"
  35 + >
  36 + <el-option
  37 + :label="$t('common.yes')"
  38 + value="Y"
  39 + />
  40 + <el-option
  41 + :label="$t('common.no')"
  42 + value="N"
  43 + />
  44 + </el-select>
  45 + </el-form-item>
  46 + <el-form-item
  47 + :label="$t('contractTypeSpecManage.edit.specShow')"
  48 + prop="specShow"
  49 + >
  50 + <el-select
  51 + v-model="formData.specShow"
  52 + :placeholder="$t('contractTypeSpecManage.edit.specShowPlaceholder')"
  53 + style="width:100%"
  54 + >
  55 + <el-option
  56 + :label="$t('common.yes')"
  57 + value="Y"
  58 + />
  59 + <el-option
  60 + :label="$t('common.no')"
  61 + value="N"
  62 + />
  63 + </el-select>
  64 + </el-form-item>
  65 + <el-form-item
  66 + :label="$t('contractTypeSpecManage.edit.specValueType')"
  67 + prop="specValueType"
  68 + >
  69 + <el-select
  70 + v-model="formData.specValueType"
  71 + :placeholder="$t('contractTypeSpecManage.edit.specValueTypePlaceholder')"
  72 + style="width:100%"
  73 + >
  74 + <el-option
  75 + :label="$t('contractTypeSpecManage.specValueType.string')"
  76 + value="1001"
  77 + />
  78 + <el-option
  79 + :label="$t('contractTypeSpecManage.specValueType.integer')"
  80 + value="2002"
  81 + />
  82 + <el-option
  83 + :label="$t('contractTypeSpecManage.specValueType.amount')"
  84 + value="3003"
  85 + />
  86 + <el-option
  87 + :label="$t('contractTypeSpecManage.specValueType.date')"
  88 + value="4004"
  89 + />
  90 + <el-option
  91 + :label="$t('contractTypeSpecManage.specValueType.time')"
  92 + value="5005"
  93 + />
  94 + </el-select>
  95 + </el-form-item>
  96 + <el-form-item
  97 + :label="$t('contractTypeSpecManage.edit.specType')"
  98 + prop="specType"
  99 + >
  100 + <el-select
  101 + v-model="formData.specType"
  102 + :placeholder="$t('contractTypeSpecManage.edit.specTypePlaceholder')"
  103 + style="width:100%"
  104 + >
  105 + <el-option
  106 + :label="$t('contractTypeSpecManage.specType.input')"
  107 + value="2233"
  108 + />
  109 + <el-option
  110 + :label="$t('contractTypeSpecManage.specType.select')"
  111 + value="3344"
  112 + />
  113 + </el-select>
  114 + </el-form-item>
  115 + <el-form-item
  116 + :label="$t('contractTypeSpecManage.edit.listShow')"
  117 + prop="listShow"
  118 + >
  119 + <el-select
  120 + v-model="formData.listShow"
  121 + :placeholder="$t('contractTypeSpecManage.edit.listShowPlaceholder')"
  122 + style="width:100%"
  123 + >
  124 + <el-option
  125 + :label="$t('common.yes')"
  126 + value="Y"
  127 + />
  128 + <el-option
  129 + :label="$t('common.no')"
  130 + value="N"
  131 + />
  132 + </el-select>
  133 + </el-form-item>
  134 + </el-form>
  135 + <span slot="footer" class="dialog-footer">
  136 + <el-button @click="visible = false">
  137 + {{ $t('common.cancel') }}
  138 + </el-button>
  139 + <el-button type="primary" @click="handleSubmit">
  140 + {{ $t('common.confirm') }}
  141 + </el-button>
  142 + </span>
  143 + </el-dialog>
  144 +</template>
  145 +
  146 +<script>
  147 +import { updateContractTypeSpec } from '@/api/contract/contractTypeSpecManageApi'
  148 +import { getCommunityId } from '@/api/community/communityApi'
  149 +
  150 +export default {
  151 + name: 'EditContractTypeSpec',
  152 + data() {
  153 + return {
  154 + visible: false,
  155 + formData: {
  156 + specCd: '',
  157 + specName: '',
  158 + specHoldplace: '',
  159 + required: '',
  160 + specShow: '',
  161 + specValueType: '',
  162 + specType: '',
  163 + listShow: '',
  164 + contractTypeId: '',
  165 + communityId: ''
  166 + },
  167 + rules: {
  168 + specName: [
  169 + { required: true, message: this.$t('contractTypeSpecManage.validate.specNameRequired'), trigger: 'blur' },
  170 + { max: 64, message: this.$t('contractTypeSpecManage.validate.specNameMaxLength'), trigger: 'blur' }
  171 + ],
  172 + specHoldplace: [
  173 + { max: 200, message: this.$t('contractTypeSpecManage.validate.specHoldplaceMaxLength'), trigger: 'blur' }
  174 + ],
  175 + required: [
  176 + { required: true, message: this.$t('contractTypeSpecManage.validate.requiredRequired'), trigger: 'change' }
  177 + ],
  178 + specShow: [
  179 + { required: true, message: this.$t('contractTypeSpecManage.validate.specShowRequired'), trigger: 'change' }
  180 + ],
  181 + specValueType: [
  182 + { required: true, message: this.$t('contractTypeSpecManage.validate.specValueTypeRequired'), trigger: 'change' }
  183 + ],
  184 + specType: [
  185 + { required: true, message: this.$t('contractTypeSpecManage.validate.specTypeRequired'), trigger: 'change' }
  186 + ],
  187 + listShow: [
  188 + { required: true, message: this.$t('contractTypeSpecManage.validate.listShowRequired'), trigger: 'change' }
  189 + ],
  190 + specCd: [
  191 + { required: true, message: this.$t('contractTypeSpecManage.validate.specCdRequired'), trigger: 'blur' }
  192 + ]
  193 + }
  194 + }
  195 + },
  196 + methods: {
  197 + open(data) {
  198 + this.formData = { ...data, communityId: getCommunityId() }
  199 + this.visible = true
  200 + this.$nextTick(() => {
  201 + this.$refs.form.clearValidate()
  202 + })
  203 + },
  204 + handleClose() {
  205 + this.$refs.form.resetFields()
  206 + },
  207 + handleSubmit() {
  208 + this.$refs.form.validate(async valid => {
  209 + if (valid) {
  210 + try {
  211 + await updateContractTypeSpec(this.formData)
  212 + this.$message.success(this.$t('contractTypeSpecManage.edit.success'))
  213 + this.visible = false
  214 + this.$emit('success')
  215 + } catch (error) {
  216 + this.$message.error(error.message || this.$t('contractTypeSpecManage.edit.error'))
  217 + }
  218 + }
  219 + })
  220 + }
  221 + }
  222 +}
  223 +</script>
0 224 \ No newline at end of file
... ...
src/components/contract/orgTreeShow.vue 0 → 100644
  1 +<template>
  2 + <div class="org-tree-container">
  3 + <el-tree
  4 + ref="orgTree"
  5 + :data="orgTreeShowInfo.orgs"
  6 + :props="defaultProps"
  7 + node-key="id"
  8 + default-expand-all
  9 + highlight-current
  10 + @node-click="handleNodeClick"
  11 + ></el-tree>
  12 + </div>
  13 +</template>
  14 +
  15 +<script>
  16 +import { listOrgTree } from '@/api/contract/contractChangeDetailApi'
  17 +import { getCommunityId } from '@/api/community/communityApi'
  18 +
  19 +export default {
  20 + name: 'OrgTreeShow',
  21 + props: {
  22 + callBackListener: {
  23 + type: String,
  24 + default: ''
  25 + }
  26 + },
  27 + data() {
  28 + return {
  29 + orgTreeShowInfo: {
  30 + orgs: [],
  31 + orgId: '',
  32 + curOrg: {}
  33 + },
  34 + defaultProps: {
  35 + children: 'children',
  36 + label: 'text'
  37 + },
  38 + communityId: ''
  39 + }
  40 + },
  41 + created() {
  42 + this.communityId = getCommunityId()
  43 + },
  44 + methods: {
  45 + loadOrgsShow() {
  46 + const param = {
  47 + communityId: this.communityId
  48 + }
  49 +
  50 + listOrgTree(param)
  51 + .then(response => {
  52 + const orgs = response.data
  53 + this.orgTreeShowInfo.orgs = orgs
  54 + })
  55 + .catch(error => {
  56 + console.error('请求失败:', error)
  57 + })
  58 + },
  59 + handleNodeClick(data) {
  60 + this.orgTreeShowInfo.curOrg = data
  61 + this.orgTreeShowInfo.curOrg.orgId = data.id
  62 + this.$emit(this.callBackListener, 'switchOrg', {
  63 + orgId: data.id,
  64 + orgName: data.text
  65 + })
  66 + },
  67 + refreshTree() {
  68 + this.loadOrgsShow()
  69 + }
  70 + }
  71 +}
  72 +</script>
  73 +
  74 +<style scoped>
  75 +.org-tree-container {
  76 + height: 100%;
  77 + overflow-y: auto;
  78 +}
  79 +
  80 +.el-tree {
  81 + min-height: 400px;
  82 +}
  83 +</style>
0 84 \ No newline at end of file
... ...
src/components/contract/purchaseApprovers.vue 0 → 100644
  1 +<template>
  2 + <el-card class="box-card">
  3 + <div slot="header" class="clearfix">
  4 + <span>{{ $t('purchaseApprovers.title') }}</span>
  5 + </div>
  6 +
  7 + <div v-if="purchaseApproversInfo.orgName">
  8 + <el-form label-width="120px">
  9 + <el-form-item :label="$t('purchaseApprovers.orgName')">
  10 + <el-input v-model="purchaseApproversInfo.orgName" :placeholder="$t('purchaseApprovers.orgPlaceholder')"
  11 + readonly></el-input>
  12 + </el-form-item>
  13 +
  14 + <el-form-item :label="$t('purchaseApprovers.staffName')">
  15 + <el-input v-model="purchaseApproversInfo.staffName" :placeholder="$t('purchaseApprovers.staffPlaceholder')"
  16 + readonly></el-input>
  17 + </el-form-item>
  18 + </el-form>
  19 + </div>
  20 +
  21 + <div v-else>
  22 + <el-form label-width="120px">
  23 + <el-form-item :label="$t('purchaseApprovers.staffName')">
  24 + <el-col :span="18">
  25 + <el-input v-model="purchaseApproversInfo.staffName" :placeholder="$t('purchaseApprovers.staffPlaceholder')"
  26 + disabled></el-input>
  27 + </el-col>
  28 + <el-col :span="6">
  29 + <el-button type="primary" @click="chooseStaff">
  30 + <i class="el-icon-search"></i>
  31 + {{ $t('common.select') }}
  32 + </el-button>
  33 + </el-col>
  34 + </el-form-item>
  35 + </el-form>
  36 + </div>
  37 + </el-card>
  38 +</template>
  39 +
  40 +<script>
  41 +import { getFirstStaff } from '@/api/contract/contractChangeDetailApi'
  42 +import { getCommunityId } from '@/api/community/communityApi'
  43 +
  44 +export default {
  45 + name: 'PurchaseApprovers',
  46 + props: {
  47 + callBackListener: {
  48 + type: String,
  49 + default: ''
  50 + },
  51 + callBackFunction: {
  52 + type: String,
  53 + default: ''
  54 + },
  55 + flowType: {
  56 + type: String,
  57 + default: '60006'
  58 + }
  59 + },
  60 + data() {
  61 + return {
  62 + purchaseApproversInfo: {
  63 + flowComponent: 'purchaseApprovers',
  64 + staffId: '',
  65 + staffName: '',
  66 + orgName: '',
  67 + companyId: ''
  68 + },
  69 + communityId: ''
  70 + }
  71 + },
  72 + watch: {
  73 + purchaseApproversInfo: {
  74 + deep: true,
  75 + handler(newVal) {
  76 + console.log('purchaseApproversInfo:', newVal)
  77 + this.savePurchaseApprovers()
  78 + }
  79 + }
  80 + },
  81 + created() {
  82 + this.communityId = getCommunityId()
  83 + this.loadStaffOrg()
  84 + },
  85 + methods: {
  86 + loadStaffOrg() {
  87 + const param = {
  88 + communityId: this.communityId,
  89 + flowType: this.flowType
  90 + }
  91 +
  92 + getFirstStaff(param)
  93 + .then(response => {
  94 + if (response.code === 0) {
  95 + const data = response.data
  96 + Object.assign(this.purchaseApproversInfo, data)
  97 + this.purchaseApproversInfo.orgName = data.orgName
  98 + }
  99 + })
  100 + .catch(error => {
  101 + console.error('请求失败:', error)
  102 + })
  103 + },
  104 + purchaseApproversValidate() {
  105 + if (!this.purchaseApproversInfo.staffId) {
  106 + this.$message.error(this.$t('purchaseApprovers.staffRequired'))
  107 + return false
  108 + }
  109 + if (!this.purchaseApproversInfo.staffName) {
  110 + this.$message.error(this.$t('purchaseApprovers.staffNameRequired'))
  111 + return false
  112 + }
  113 + return true
  114 + },
  115 + savePurchaseApprovers() {
  116 + if (this.purchaseApproversValidate()) {
  117 + this.$emit(this.callBackListener, this.callBackFunction, this.purchaseApproversInfo)
  118 + }
  119 + },
  120 + chooseStaff() {
  121 + this.$emit('openSelectStaff', this.purchaseApproversInfo)
  122 + }
  123 + }
  124 +}
  125 +</script>
  126 +
  127 +<style scoped>
  128 +.box-card {
  129 + margin-bottom: 20px;
  130 +}
  131 +</style>
0 132 \ No newline at end of file
... ...
src/components/contract/searchOwner.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('contract.selectOwner')"
  4 + :visible.sync="visible"
  5 + width="80%"
  6 + :before-close="handleClose">
  7 +
  8 + <div class="search-wrapper">
  9 + <el-row :gutter="20">
  10 + <el-col :span="8">
  11 + <el-input
  12 + v-model="searchOwnerInfo.roomName"
  13 + :placeholder="$t('contract.inputRoomFullNum')">
  14 + </el-input>
  15 + </el-col>
  16 + <el-col :span="8">
  17 + <el-input
  18 + v-model="searchOwnerInfo._currentOwnerName"
  19 + :placeholder="$t('contract.inputOwnerName')">
  20 + </el-input>
  21 + </el-col>
  22 + <el-col :span="8">
  23 + <el-button type="primary" @click="searchOwners">
  24 + <i class="el-icon-search"></i>{{ $t('common.search') }}
  25 + </el-button>
  26 + <el-button @click="resetOwners">{{ $t('common.reset') }}</el-button>
  27 + </el-col>
  28 + </el-row>
  29 + </div>
  30 +
  31 + <el-table
  32 + :data="searchOwnerInfo.owners"
  33 + border
  34 + style="width: 100%"
  35 + height="400">
  36 + <el-table-column
  37 + prop="memberId"
  38 + :label="$t('contract.ownerId')"
  39 + align="center">
  40 + </el-table-column>
  41 + <el-table-column
  42 + prop="name"
  43 + :label="$t('contract.name')"
  44 + align="center">
  45 + </el-table-column>
  46 + <el-table-column
  47 + prop="personTypeName"
  48 + :label="$t('contract.personType')"
  49 + align="center">
  50 + </el-table-column>
  51 + <el-table-column
  52 + prop="personRoleName"
  53 + :label="$t('contract.personRole')"
  54 + align="center">
  55 + </el-table-column>
  56 + <el-table-column
  57 + prop="idCard"
  58 + :label="$t('contract.idCard')"
  59 + align="center">
  60 + </el-table-column>
  61 + <el-table-column
  62 + prop="link"
  63 + :label="$t('contract.contact')"
  64 + align="center">
  65 + </el-table-column>
  66 + <el-table-column
  67 + :label="$t('common.operation')"
  68 + align="center"
  69 + width="120">
  70 + <template slot-scope="scope">
  71 + <el-button
  72 + type="primary"
  73 + size="mini"
  74 + @click="chooseOwner(scope.row)">
  75 + {{ $t('contract.select') }}
  76 + </el-button>
  77 + </template>
  78 + </el-table-column>
  79 + </el-table>
  80 +
  81 + <div class="pagination-wrapper">
  82 + <el-pagination
  83 + @size-change="handleSizeChange"
  84 + @current-change="handleCurrentChange"
  85 + :current-page="page.current"
  86 + :page-sizes="[10, 20, 30, 50]"
  87 + :page-size="page.size"
  88 + layout="total, sizes, prev, pager, next, jumper"
  89 + :total="page.total">
  90 + </el-pagination>
  91 + </div>
  92 + </el-dialog>
  93 +</template>
  94 +
  95 +<script>
  96 +import { queryOwners } from '@/api/contract/addContractApi'
  97 +
  98 +export default {
  99 + name: 'SearchOwner',
  100 + props: {
  101 + emitChooseOwner: String,
  102 + emitLoadData: String
  103 + },
  104 + data() {
  105 + return {
  106 + visible: false,
  107 + searchOwnerInfo: {
  108 + owners: [],
  109 + _currentOwnerName: '',
  110 + roomName: '',
  111 + ownerTypeCd: '1001'
  112 + },
  113 + page: {
  114 + current: 1,
  115 + size: 10,
  116 + total: 0
  117 + }
  118 + }
  119 + },
  120 + methods: {
  121 + open(params = {}) {
  122 + this.visible = true
  123 + this._refreshSearchOwnerData()
  124 + if (params.hasOwnProperty('ownerTypeCd')) {
  125 + this.searchOwnerInfo.ownerTypeCd = params.ownerTypeCd
  126 + }
  127 + this._loadAllOwnerInfo(1, 10)
  128 + },
  129 + handleClose() {
  130 + this.visible = false
  131 + },
  132 + _loadAllOwnerInfo(_page, _row) {
  133 + const params = {
  134 + page: _page,
  135 + row: _row,
  136 + communityId: this.$store.getters.communityId,
  137 + name: this.searchOwnerInfo._currentOwnerName.trim(),
  138 + roomName: this.searchOwnerInfo.roomName.trim(),
  139 + ownerTypeCd: this.searchOwnerInfo.ownerTypeCd
  140 + }
  141 +
  142 + queryOwners(params).then(response => {
  143 + this.searchOwnerInfo.owners = response.data
  144 + this.page.total = response.records
  145 + this.page.current = _page
  146 + this.page.size = _row
  147 + })
  148 + },
  149 + chooseOwner(owner) {
  150 + this.$emit('chooseOwner', owner)
  151 + this.$emit(this.emitLoadData, 'listOwnerData', {
  152 + ownerId: owner.ownerId
  153 + })
  154 + this.visible = false
  155 + },
  156 + searchOwners() {
  157 + this._loadAllOwnerInfo(1, 10)
  158 + },
  159 + resetOwners() {
  160 + this.searchOwnerInfo.roomName = ""
  161 + this.searchOwnerInfo._currentOwnerName = ""
  162 + this._loadAllOwnerInfo(1, 10)
  163 + },
  164 + _refreshSearchOwnerData() {
  165 + this.searchOwnerInfo = {
  166 + owners: [],
  167 + _currentOwnerName: '',
  168 + roomName: '',
  169 + ownerTypeCd: '1001'
  170 + }
  171 + },
  172 + handleSizeChange(val) {
  173 + this.page.size = val
  174 + this._loadAllOwnerInfo(this.page.current, val)
  175 + },
  176 + handleCurrentChange(val) {
  177 + this._loadAllOwnerInfo(val, this.page.size)
  178 + }
  179 + }
  180 +}
  181 +</script>
  182 +
  183 +<style scoped>
  184 +.search-wrapper {
  185 + margin-bottom: 20px;
  186 +}
  187 +
  188 +.pagination-wrapper {
  189 + margin-top: 20px;
  190 + text-align: right;
  191 +}
  192 +
  193 +.el-button + .el-button {
  194 + margin-left: 10px;
  195 +}
  196 +</style>
0 197 \ No newline at end of file
... ...
src/components/contract/searchRoom.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('searchRoom.title')"
  4 + :visible.sync="dialogVisible"
  5 + width="80%"
  6 + @close="handleClose"
  7 + >
  8 + <el-form v-if="searchRoomInfo.showSearchCondition" inline>
  9 + <el-form-item :label="$t('searchRoom.buildingNo')">
  10 + <el-input
  11 + v-model="searchRoomInfo._currentFloorNum"
  12 + :placeholder="$t('searchRoom.buildingNoPlaceholder')"
  13 + :readonly="searchRoomInfo.floorNumInputReadonly"
  14 + ></el-input>
  15 + </el-form-item>
  16 +
  17 + <el-form-item :label="$t('searchRoom.roomNo')">
  18 + <el-input
  19 + v-model="searchRoomInfo._currentRoomNum"
  20 + :placeholder="$t('searchRoom.roomNoPlaceholder')"
  21 + ></el-input>
  22 + </el-form-item>
  23 +
  24 + <el-form-item>
  25 + <el-button type="primary" @click="searchRooms">
  26 + <i class="el-icon-search"></i>
  27 + {{ $t('common.search') }}
  28 + </el-button>
  29 + <el-button @click="resetRooms">
  30 + <i class="el-icon-refresh"></i>
  31 + {{ $t('common.reset') }}
  32 + </el-button>
  33 + </el-form-item>
  34 + </el-form>
  35 +
  36 + <el-table :data="searchRoomInfo.rooms" border>
  37 + <el-table-column
  38 + prop="roomId"
  39 + :label="$t('searchRoom.roomId')"
  40 + align="center"
  41 + />
  42 +
  43 + <el-table-column
  44 + prop="floorNum"
  45 + :label="$t('searchRoom.buildingNo')"
  46 + align="center"
  47 + >
  48 + <template slot-scope="scope">
  49 + {{ scope.row.floorNum }}{{ $t('searchRoom.building') }}
  50 + </template>
  51 + </el-table-column>
  52 +
  53 + <el-table-column
  54 + prop="unitNum"
  55 + :label="$t('searchRoom.unitNo')"
  56 + align="center"
  57 + >
  58 + <template slot-scope="scope">
  59 + {{ scope.row.unitNum }}{{ $t('searchRoom.unit') }}
  60 + </template>
  61 + </el-table-column>
  62 +
  63 + <el-table-column
  64 + prop="roomNum"
  65 + :label="$t('searchRoom.roomNo')"
  66 + align="center"
  67 + >
  68 + <template slot-scope="scope">
  69 + {{ scope.row.roomNum }}{{ $t('searchRoom.room') }}
  70 + </template>
  71 + </el-table-column>
  72 +
  73 + <el-table-column
  74 + prop="layer"
  75 + :label="$t('searchRoom.floor')"
  76 + align="center"
  77 + >
  78 + <template slot-scope="scope">
  79 + {{ scope.row.layer }}{{ $t('searchRoom.floorUnit') }}
  80 + </template>
  81 + </el-table-column>
  82 +
  83 + <el-table-column
  84 + :label="$t('common.operation')"
  85 + align="center"
  86 + width="120"
  87 + >
  88 + <template slot-scope="scope">
  89 + <el-button
  90 + type="primary"
  91 + size="mini"
  92 + @click="chooseRoom(scope.row)"
  93 + >
  94 + {{ $t('common.select') }}
  95 + </el-button>
  96 + </template>
  97 + </el-table-column>
  98 + </el-table>
  99 +
  100 + <div class="pagination-wrapper">
  101 + <el-pagination
  102 + :current-page="pagination.current"
  103 + :page-sizes="[10, 20, 30, 50]"
  104 + :page-size="pagination.size"
  105 + :total="pagination.total"
  106 + layout="total, sizes, prev, pager, next, jumper"
  107 + @size-change="handleSizeChange"
  108 + @current-change="handleCurrentChange"
  109 + />
  110 + </div>
  111 + </el-dialog>
  112 +</template>
  113 +
  114 +<script>
  115 +import { queryRooms } from '@/api/contract/contractChangeDetailApi'
  116 +import { getCommunityId } from '@/api/community/communityApi'
  117 +
  118 +export default {
  119 + name: 'SearchRoom',
  120 + props: {
  121 + emitChooseRoom: {
  122 + type: String,
  123 + default: ''
  124 + },
  125 + emitLoadData: {
  126 + type: String,
  127 + default: ''
  128 + },
  129 + roomFlag: {
  130 + type: String,
  131 + default: ''
  132 + },
  133 + showSearchCondition: {
  134 + type: String,
  135 + default: 'true'
  136 + }
  137 + },
  138 + data() {
  139 + return {
  140 + dialogVisible: false,
  141 + searchRoomInfo: {
  142 + rooms: [],
  143 + _currentRoomNum: '',
  144 + _currentFloorNum: '',
  145 + floorNumInputReadonly: false,
  146 + showSearchCondition: this.showSearchCondition === 'true'
  147 + },
  148 + pagination: {
  149 + current: 1,
  150 + size: 10,
  151 + total: 0
  152 + },
  153 + communityId: ''
  154 + }
  155 + },
  156 + created() {
  157 + this.communityId = getCommunityId()
  158 + },
  159 + methods: {
  160 + open() {
  161 + this.dialogVisible = true
  162 + this.refreshSearchRoomData()
  163 + this.loadAllRoomInfo(1, 10)
  164 + },
  165 + chooseRoom(room) {
  166 + this.$emit(this.emitChooseRoom, 'chooseRoom', room)
  167 + this.$emit(this.emitLoadData, 'listRoomData', {
  168 + roomId: room.roomId
  169 + })
  170 + this.dialogVisible = false
  171 + },
  172 + searchRooms() {
  173 + this.loadAllRoomInfo(1, 15, this.searchRoomInfo._currentRoomNum)
  174 + },
  175 + resetRooms() {
  176 + this.searchRoomInfo._currentFloorNum = ''
  177 + this.searchRoomInfo._currentRoomNum = ''
  178 + this.loadAllRoomInfo(1, 15)
  179 + },
  180 + handleSizeChange(val) {
  181 + this.pagination.size = val
  182 + this.loadAllRoomInfo(this.pagination.current, val)
  183 + },
  184 + handleCurrentChange(val) {
  185 + this.pagination.current = val
  186 + this.loadAllRoomInfo(val, this.pagination.size)
  187 + },
  188 + handleClose() {
  189 + this.searchRoomInfo._currentRoomNum = ''
  190 + },
  191 + refreshSearchRoomData() {
  192 + this.searchRoomInfo._currentRoomNum = ''
  193 + },
  194 + loadAllRoomInfo(page, row, roomNum) {
  195 + const params = {
  196 + page,
  197 + row,
  198 + communityId: this.communityId,
  199 + roomNum,
  200 + floorNum: this.searchRoomInfo._currentFloorNum,
  201 + roomFlag: this.roomFlag
  202 + }
  203 +
  204 + let url = '/room.queryRooms'
  205 + if (this.roomFlag === '1') {
  206 + url = '/room.queryRoomsWithSell'
  207 + } else if (this.roomFlag === '2') {
  208 + url = '/room.queryRoomsWithOutSell'
  209 + }
  210 +
  211 + queryRooms(params, url)
  212 + .then(response => {
  213 + const roomInfo = response.data
  214 + this.searchRoomInfo.rooms = roomInfo.rooms
  215 + this.pagination.total = roomInfo.records
  216 + })
  217 + .catch(error => {
  218 + console.error('请求失败:', error)
  219 + })
  220 + }
  221 + }
  222 +}
  223 +</script>
  224 +
  225 +<style scoped>
  226 +.pagination-wrapper {
  227 + margin-top: 20px;
  228 + text-align: right;
  229 +}
  230 +</style>
0 231 \ No newline at end of file
... ...
src/components/contract/selectStaff.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('selectStaff.title')"
  4 + :visible.sync="dialogVisible"
  5 + width="80%"
  6 + >
  7 + <el-row>
  8 + <el-col :span="12" class="border-right">
  9 + <div class="text-center">
  10 + <h4>{{ $t('selectStaff.orgInfo') }}</h4>
  11 + </div>
  12 + <div class="tree-container">
  13 + <org-tree-show
  14 + ref="orgTreeShow"
  15 + :call-back-listener="callBackListener"
  16 + />
  17 + </div>
  18 + </el-col>
  19 +
  20 + <el-col :span="12">
  21 + <div class="text-center">
  22 + <h4>{{ $t('selectStaff.staffInfo') }}</h4>
  23 + </div>
  24 + <div class="staff-list">
  25 + <div
  26 + v-for="(item, index) in selectStaffInfo.staffs"
  27 + :key="index"
  28 + class="staff-item"
  29 + :class="{ 'selected': selectStaffInfo.curStaffId === item.staffId }"
  30 + @click="changeStaff(item)"
  31 + >
  32 + <div>
  33 + <i class="el-icon-user"></i>
  34 + {{ item.name }}
  35 + </div>
  36 + <div>{{ item.tel }}</div>
  37 + </div>
  38 + </div>
  39 + </el-col>
  40 + </el-row>
  41 +
  42 + <div
  43 + v-if="selectStaffInfo.staff.from === 'bpmn' ||
  44 + selectStaffInfo.staff.from === 'purchase' ||
  45 + selectStaffInfo.staff.from === 'contract'"
  46 + slot="footer"
  47 + class="dialog-footer"
  48 + >
  49 + <el-button @click="firstUser">
  50 + {{ $t('selectStaff.submitter') }}
  51 + </el-button>
  52 + <el-button type="primary" @click="customUser">
  53 + {{ $t('selectStaff.dynamicAssign') }}
  54 + </el-button>
  55 + </div>
  56 + </el-dialog>
  57 +</template>
  58 +
  59 +<script>
  60 +import { queryStaffInfos } from '@/api/contract/contractChangeDetailApi'
  61 +import OrgTreeShow from '@/components/contract/OrgTreeShow'
  62 +
  63 +export default {
  64 + name: 'SelectStaff',
  65 + components: {
  66 + OrgTreeShow
  67 + },
  68 + data() {
  69 + return {
  70 + dialogVisible: false,
  71 + selectStaffInfo: {
  72 + staffs: [],
  73 + curStaffId: '',
  74 + curStaffName: '',
  75 + staff: {}
  76 + },
  77 + callBackListener: 'selectStaff'
  78 + }
  79 + },
  80 + methods: {
  81 + open(staff) {
  82 + this.selectStaffInfo.staff = staff
  83 + this.dialogVisible = true
  84 + this.$refs.orgTreeShow.loadOrgsShow()
  85 + },
  86 + changeStaff(item) {
  87 + this.selectStaffInfo.curStaffId = item.staffId
  88 + this.selectStaffInfo.curStaffName = item.name
  89 +
  90 + if (this.selectStaffInfo.staff) {
  91 + this.selectStaffInfo.staff.staffId = item.userId
  92 + this.selectStaffInfo.staff.staffName = item.userName
  93 + this.selectStaffInfo.staff.staffTel = item.tel
  94 +
  95 + if (this.selectStaffInfo.staff.call) {
  96 + this.selectStaffInfo.staff.call(this.selectStaffInfo.staff)
  97 + }
  98 + }
  99 +
  100 + this.dialogVisible = false
  101 + },
  102 + loadStaff(org) {
  103 + const param = {
  104 + page: 1,
  105 + rows: 50,
  106 + orgId: org.orgId
  107 + }
  108 +
  109 + queryStaffInfos(param)
  110 + .then(response => {
  111 + const staffInfo = response.data
  112 + this.selectStaffInfo.staffs = staffInfo.staffs
  113 + if (staffInfo.staffs.length > 0) {
  114 + this.selectStaffInfo.curStaffId = staffInfo.staffs[0].orgId
  115 + }
  116 + })
  117 + .catch(error => {
  118 + console.error('请求失败:', error)
  119 + })
  120 + },
  121 + firstUser() {
  122 + if (this.selectStaffInfo.staff) {
  123 + this.selectStaffInfo.staff.staffId = '${startUserId}'
  124 + this.selectStaffInfo.staff.staffName = this.$t('selectStaff.submitter')
  125 +
  126 + if (this.selectStaffInfo.staff.call) {
  127 + this.selectStaffInfo.staff.call(this.selectStaffInfo.staff)
  128 + }
  129 + }
  130 + this.dialogVisible = false
  131 + },
  132 + customUser() {
  133 + if (this.selectStaffInfo.staff) {
  134 + this.selectStaffInfo.staff.staffId = '${nextUserId}'
  135 + this.selectStaffInfo.staff.staffName = this.$t('selectStaff.dynamicAssign')
  136 +
  137 + if (this.selectStaffInfo.staff.call) {
  138 + this.selectStaffInfo.staff.call(this.selectStaffInfo.staff)
  139 + }
  140 + }
  141 + this.dialogVisible = false
  142 + }
  143 + },
  144 + created() {
  145 + this.$on('switchOrg', param => {
  146 + this.loadStaff(param)
  147 + })
  148 + }
  149 +}
  150 +</script>
  151 +
  152 +<style scoped>
  153 +.border-right {
  154 + border-right: 1px solid #eee;
  155 + padding-right: 20px;
  156 +}
  157 +
  158 +.tree-container {
  159 + height: 400px;
  160 + overflow-y: auto;
  161 +}
  162 +
  163 +.staff-list {
  164 + height: 400px;
  165 + overflow-y: auto;
  166 + padding-left: 20px;
  167 +}
  168 +
  169 +.staff-item {
  170 + padding: 10px;
  171 + margin-bottom: 5px;
  172 + cursor: pointer;
  173 + border-radius: 4px;
  174 +}
  175 +
  176 +.staff-item:hover {
  177 + background-color: #f5f7fa;
  178 +}
  179 +
  180 +.staff-item.selected {
  181 + background-color: #ecf5ff;
  182 + color: #409eff;
  183 +}
  184 +
  185 +.text-center {
  186 + text-align: center;
  187 + margin-bottom: 15px;
  188 +}
  189 +
  190 +.dialog-footer {
  191 + text-align: right;
  192 +}
  193 +</style>
0 194 \ No newline at end of file
... ...
src/i18n/contractI18n.js 0 → 100644
  1 +import { messages as contractTypeManageMessages } from '../views/contract/contractTypeManageLang'
  2 +import { messages as contractTypeSpecManageMessages } from '../views/contract/contractTypeSpecManageLang'
  3 +import { messages as contractPartyaManageMessages } from '../views/contract/contractPartyaManageLang'
  4 +import { messages as newContractManageMessages } from '../views/contract/newContractManageLang'
  5 +import { messages as printContractMessages } from '../views/contract/printContractLang'
  6 +import { messages as addContractMessages } from '../views/contract/addContractLang'
  7 +import { messages as contractManageMessages } from '../views/contract/contractManageLang'
  8 +import { messages as contractChangeManageMessages } from '../views/contract/contractChangeManageLang'
  9 +import { messages as contractChangeDetailMessages } from '../views/contract/contractChangeDetailLang'
  10 +import { messages as expirationContractManageMessages } from '../views/contract/expirationContractManageLang'
  11 +
  12 +export const messages ={
  13 + en:{
  14 + ...contractTypeManageMessages.en,
  15 + ...contractTypeSpecManageMessages.en,
  16 + ...contractPartyaManageMessages.en,
  17 + ...newContractManageMessages.en,
  18 + ...printContractMessages.en,
  19 + ...addContractMessages.en,
  20 + ...contractManageMessages.en,
  21 + ...contractChangeManageMessages.en,
  22 + ...contractChangeDetailMessages.en,
  23 + ...expirationContractManageMessages.en,
  24 + },
  25 + zh:{
  26 + ...contractTypeManageMessages.zh,
  27 + ...contractTypeSpecManageMessages.zh,
  28 + ...contractPartyaManageMessages.zh,
  29 + ...newContractManageMessages.zh,
  30 + ...printContractMessages.zh,
  31 + ...addContractMessages.zh,
  32 + ...contractManageMessages.zh,
  33 + ...contractChangeManageMessages.zh,
  34 + ...contractChangeDetailMessages.zh,
  35 + ...expirationContractManageMessages.zh,
  36 + }
  37 +}
0 38 \ No newline at end of file
... ...
src/i18n/index.js
... ... @@ -207,6 +207,7 @@ import { messages as printEquipmentAccountLabelMessages } from &#39;../views/resourc
207 207 import {messages as inspectioni18n} from './inspectionI18n'
208 208 import {messages as machineI18n} from './machineI18n'
209 209 import {messages as oaI18n} from './oaI18n'
  210 +import {messages as contractI18n} from './contractI18n'
210 211  
211 212 Vue.use(VueI18n)
212 213  
... ... @@ -418,6 +419,7 @@ const messages = {
418 419 ...inspectioni18n.en,
419 420 ...machineI18n.en,
420 421 ...oaI18n.en,
  422 + ...contractI18n.en,
421 423 },
422 424 zh: {
423 425 ...loginMessages.zh,
... ... @@ -625,6 +627,7 @@ const messages = {
625 627 ...inspectioni18n.zh,
626 628 ...machineI18n.zh,
627 629 ...oaI18n.zh,
  630 + ...contractI18n.zh,
628 631 }
629 632 }
630 633  
... ...
src/router/contractRouter.js 0 → 100644
  1 +export default [
  2 + {
  3 + path: '/pages/admin/contractTypeManage',
  4 + name: '/pages/admin/contractTypeManage',
  5 + component: () => import('@/views/contract/contractTypeManageList.vue')
  6 + },
  7 + {
  8 + path: '/views/contract/contractTypeSpecManage',
  9 + name: '/views/contract/contractTypeSpecManage',
  10 + component: () => import('@/views/contract/contractTypeSpecManageList.vue')
  11 + },
  12 + {
  13 + path: '/pages/admin/contractPartyaManage',
  14 + name: '/pages/admin/contractPartyaManage',
  15 + component: () => import('@/views/contract/contractPartyaManageList.vue')
  16 + },
  17 + {
  18 + path: '/pages/admin/newContractManage',
  19 + name: '/pages/admin/newContractManage',
  20 + component: () => import('@/views/contract/newContractManageList.vue')
  21 + },
  22 + {
  23 + path: '/views/contract/addContract',
  24 + name: '/views/contract/addContract',
  25 + component: () => import('@/views/contract/addContractList.vue')
  26 + },
  27 + {
  28 + path: '/pages/admin/contractManage',
  29 + name: '/pages/admin/contractManage',
  30 + component: () => import('@/views/contract/contractManageList.vue')
  31 + },
  32 + {
  33 + path: '/pages/admin/contractChangeManage',
  34 + name: '/pages/admin/contractChangeManage',
  35 + component: () => import('@/views/contract/contractChangeManageList.vue')
  36 + },
  37 + {
  38 + path: '/views/contract/contractChangeDetail',
  39 + name: '/views/contract/contractChangeDetail',
  40 + component: () => import('@/views/contract/contractChangeDetailList.vue')
  41 + },
  42 + {
  43 + path: '/pages/admin/expirationContractManage',
  44 + name: '/pages/admin/expirationContractManage',
  45 + component: () => import('@/views/contract/expirationContractManageList.vue')
  46 + },
  47 +]
0 48 \ No newline at end of file
... ...
src/router/index.js
... ... @@ -6,6 +6,7 @@ import printEquipmentAccountLabel from &#39;@/views/resource/printEquipmentAccountLa
6 6 import inspectionRouter from './inspectionRouter'
7 7 import machineRouter from './machineRouter'
8 8 import oaRouter from './oaRouter'
  9 +import contractRouter from './contractRouter'
9 10  
10 11 Vue.use(VueRouter)
11 12  
... ... @@ -928,6 +929,7 @@ const routes = [
928 929 ...inspectionRouter,
929 930 ...machineRouter,
930 931 ...oaRouter,
  932 + ...contractRouter,
931 933 // 其他子路由可以在这里添加
932 934 ]
933 935 },
... ... @@ -956,10 +958,15 @@ const routes = [
956 958 component: () => import('@/views/oa/printQuestionAnswerDetailList.vue')
957 959 },
958 960 {
959   - path:'/views/oa/printOwnerVoting',
960   - name:'/views/oa/printOwnerVoting',
  961 + path: '/views/oa/printOwnerVoting',
  962 + name: '/views/oa/printOwnerVoting',
961 963 component: () => import('@/views/oa/printOwnerVotingList.vue')
962   - },
  964 + },
  965 + {
  966 + path: '/views/contract/printContract',
  967 + name: '/views/contract/printContract',
  968 + component: () => import('@/views/contract/printContractList.vue')
  969 + },
963 970 ]
964 971  
965 972 const router = new VueRouter({
... ...
src/views/contract/addContractLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + contract: {
  4 + renewContract: 'Renew Contract',
  5 + draftContract: 'Draft Contract',
  6 + parentContractName: 'Parent Contract Name',
  7 + parentContractCode: 'Parent Contract Code',
  8 + parentContractStatus: 'Parent Contract Status',
  9 + contractName: 'Contract Name',
  10 + requiredContractName: 'Required, please fill in contract name',
  11 + contractCode: 'Contract Code',
  12 + requiredContractCode: 'Required, please fill in contract code',
  13 + contractType: 'Contract Type',
  14 + requiredContractType: 'Required, please select contract type',
  15 + partyA: 'Party A',
  16 + requiredPartyA: 'Required, please select Party A',
  17 + partyAContact: 'Party A Contact',
  18 + partyAPhone: 'Party A Phone',
  19 + partyB: 'Party B',
  20 + partyBContact: 'Party B Contact',
  21 + partyBPhone: 'Party B Phone',
  22 + operator: 'Operator',
  23 + operatorPhone: 'Operator Phone',
  24 + contractAmount: 'Contract Amount',
  25 + startTime: 'Start Time',
  26 + requiredStartTime: 'Required, please fill in start time',
  27 + endTime: 'End Time',
  28 + requiredEndTime: 'Required, please fill in end time',
  29 + signingTime: 'Signing Time',
  30 + requiredSigningTime: 'Required, please fill in signing time',
  31 + contractAttachments: 'Contract Attachments',
  32 + addAttachment: 'Add Attachment',
  33 + attachment: 'Attachment',
  34 + deleteAttachment: 'Delete Attachment',
  35 + relatedRooms: 'Related Rooms',
  36 + add: 'Add',
  37 + room: 'Room',
  38 + owner: 'Owner',
  39 + phone: 'Phone',
  40 + builtUpArea: 'Built-up Area',
  41 + squareMeter: 'Square Meter',
  42 + roomStatus: 'Room Status',
  43 + select: 'Select',
  44 + approverInfo: 'Approver Information',
  45 + organization: 'Organization',
  46 + requiredOrganization: 'Required, please fill in organization',
  47 + staff: 'Staff',
  48 + requiredStaff: 'Required, please fill in staff',
  49 + requiredNextHandler: 'Required, please select next handler',
  50 + selectStaff: 'Select Staff',
  51 + orgInfo: 'Organization Information',
  52 + staffInfo: 'Staff Information',
  53 + submitter: 'Submitter',
  54 + dynamicAssign: 'Dynamic Assign',
  55 + selectRoom: 'Select Room',
  56 + inputBuildingNum: 'Input building number',
  57 + inputRoomNum: 'Input room number',
  58 + roomId: 'Room ID',
  59 + buildingNum: 'Building Number',
  60 + building: 'Building',
  61 + unitNum: 'Unit Number',
  62 + unit: 'Unit',
  63 + roomNum: 'Room Number',
  64 + floor: 'Floor',
  65 + floorUnit: 'Floor',
  66 + selectOwner: 'Select Owner',
  67 + inputRoomFullNum: 'Input room full number (Building-Unit-Room)',
  68 + inputOwnerName: 'Input owner name',
  69 + ownerId: 'Owner ID',
  70 + name: 'Name',
  71 + personType: 'Person Type',
  72 + personRole: 'Person Role',
  73 + idCard: 'ID Card',
  74 + contact: 'Contact',
  75 + submitSuccess: 'Submit successfully',
  76 + invalidFileType: 'Operation failed, please upload image or PDF format files',
  77 + required: 'Required'
  78 + }
  79 + },
  80 + zh: {
  81 + contract: {
  82 + renewContract: '续签合同',
  83 + draftContract: '起草合同',
  84 + parentContractName: '父合同名称',
  85 + parentContractCode: '父合同编号',
  86 + parentContractStatus: '父合同状态',
  87 + contractName: '合同名称',
  88 + requiredContractName: '必填,请填写合同名称',
  89 + contractCode: '合同编号',
  90 + requiredContractCode: '必填,请填写合同编号',
  91 + contractType: '合同类型',
  92 + requiredContractType: '必填,请选择合同类型',
  93 + partyA: '甲方',
  94 + requiredPartyA: '必填,请选择甲方',
  95 + partyAContact: '甲方联系人',
  96 + partyAPhone: '甲方联系电话',
  97 + partyB: '乙方',
  98 + partyBContact: '乙方联系人',
  99 + partyBPhone: '乙方联系电话',
  100 + operator: '经办人',
  101 + operatorPhone: '联系电话',
  102 + contractAmount: '合同金额',
  103 + startTime: '开始时间',
  104 + requiredStartTime: '必填,请填写开始时间',
  105 + endTime: '结束时间',
  106 + requiredEndTime: '必填,请填写结束时间',
  107 + signingTime: '签订时间',
  108 + requiredSigningTime: '必填,请填写签订时间',
  109 + contractAttachments: '合同附件',
  110 + addAttachment: '添加附件',
  111 + attachment: '附件',
  112 + deleteAttachment: '删除附件',
  113 + relatedRooms: '关联房屋',
  114 + add: '添加',
  115 + room: '房屋',
  116 + owner: '业主',
  117 + phone: '电话',
  118 + builtUpArea: '建筑面积',
  119 + squareMeter: '平方米',
  120 + roomStatus: '房屋状态',
  121 + select: '选择',
  122 + approverInfo: '审批人信息',
  123 + organization: '所属组织',
  124 + requiredOrganization: '必填,请填写所属组织',
  125 + staff: '员工',
  126 + requiredStaff: '必填,请填写所属员工',
  127 + requiredNextHandler: '必填,请选择下一处理人',
  128 + selectStaff: '选择员工',
  129 + orgInfo: '组织信息',
  130 + staffInfo: '员工信息',
  131 + submitter: '提交者',
  132 + dynamicAssign: '动态指定',
  133 + selectRoom: '选择房屋',
  134 + inputBuildingNum: '输入小区楼编号',
  135 + inputRoomNum: '输入房屋编号',
  136 + roomId: '房屋ID',
  137 + buildingNum: '楼栋编号',
  138 + building: '号楼',
  139 + unitNum: '单元编号',
  140 + unit: '单元',
  141 + roomNum: '房屋编号',
  142 + floor: '楼层',
  143 + floorUnit: '层',
  144 + selectOwner: '选择业主',
  145 + inputRoomFullNum: '输入房屋编号(楼栋-单元-房屋)',
  146 + inputOwnerName: '输入业主名称',
  147 + ownerId: '业主编号',
  148 + name: '名称',
  149 + personType: '人员类型',
  150 + personRole: '人员角色',
  151 + idCard: '证件号',
  152 + contact: '联系方式',
  153 + submitSuccess: '提交成功',
  154 + invalidFileType: '操作失败,请上传图片、PDF格式的文件',
  155 + required: '必填'
  156 + }
  157 + }
  158 +}
0 159 \ No newline at end of file
... ...
src/views/contract/addContractList.vue 0 → 100644
  1 +<template>
  2 + <div class="add-contract-container">
  3 + <el-card class="box-card">
  4 + <div slot="header" class="flex justify-between">
  5 + <span>{{ addContractInfo.parentContractCode ? $t('contract.renewContract') : $t('contract.draftContract')
  6 + }}</span>
  7 + <el-button style="float: right; padding: 3px 0" type="text" @click="_goBack">
  8 + <i class="el-icon-close"></i>{{ $t('common.back') }}
  9 + </el-button>
  10 + </div>
  11 +
  12 + <el-form ref="form" :model="addContractInfo" label-width="120px">
  13 + <!-- Parent Contract Info -->
  14 + <el-row v-if="addContractInfo.parentContractCode" :gutter="20">
  15 + <el-col :span="8">
  16 + <el-form-item :label="$t('contract.parentContractName')">
  17 + <el-input v-model="addContractInfo.parentContractName" disabled></el-input>
  18 + </el-form-item>
  19 + </el-col>
  20 + <el-col :span="8">
  21 + <el-form-item :label="$t('contract.parentContractCode')">
  22 + <el-input v-model="addContractInfo.parentContractCode" disabled></el-input>
  23 + </el-form-item>
  24 + </el-col>
  25 + <el-col :span="8">
  26 + <el-form-item :label="$t('contract.parentContractStatus')">
  27 + <el-input v-model="addContractInfo.parentStateName" disabled></el-input>
  28 + </el-form-item>
  29 + </el-col>
  30 + </el-row>
  31 +
  32 + <!-- Basic Contract Info -->
  33 + <el-row :gutter="20">
  34 + <el-col :span="8">
  35 + <el-form-item :label="$t('contract.contractName')" prop="contractName" required>
  36 + <el-input v-model="addContractInfo.contractName"
  37 + :placeholder="$t('contract.requiredContractName')"></el-input>
  38 + </el-form-item>
  39 + </el-col>
  40 + <el-col :span="8">
  41 + <el-form-item :label="$t('contract.contractCode')" prop="contractCode" required>
  42 + <el-input v-model="addContractInfo.contractCode"
  43 + :placeholder="$t('contract.requiredContractCode')"></el-input>
  44 + </el-form-item>
  45 + </el-col>
  46 + <el-col :span="8">
  47 + <el-form-item :label="$t('contract.contractType')" prop="contractType" required>
  48 + <el-select v-model="addContractInfo.contractType" :placeholder="$t('contract.requiredContractType')"
  49 + style="width:100%" @change="_changeContractType">
  50 + <el-option v-for="item in addContractInfo.contractTypes" :key="item.contractTypeId" :label="item.typeName"
  51 + :value="item.contractTypeId">
  52 + </el-option>
  53 + </el-select>
  54 + </el-form-item>
  55 + </el-col>
  56 + </el-row>
  57 +
  58 + <!-- Party A Info -->
  59 + <el-row :gutter="20">
  60 + <el-col :span="8">
  61 + <el-form-item :label="$t('contract.partyA')" prop="partyA" required>
  62 + <el-select v-model="addContractInfo.partyA" :placeholder="$t('contract.requiredPartyA')" style="width:100%"
  63 + @change="_changeContractPartyA">
  64 + <el-option v-for="item in addContractInfo.contractPartyAs" :key="item.partyA" :label="item.partyA"
  65 + :value="item.partyA">
  66 + </el-option>
  67 + </el-select>
  68 + </el-form-item>
  69 + </el-col>
  70 + <el-col :span="8">
  71 + <el-form-item :label="$t('contract.partyAContact')" prop="aContacts" required>
  72 + <el-input v-model="addContractInfo.aContacts" disabled></el-input>
  73 + </el-form-item>
  74 + </el-col>
  75 + <el-col :span="8">
  76 + <el-form-item :label="$t('contract.partyAPhone')" prop="aLink" required>
  77 + <el-input v-model="addContractInfo.aLink" disabled></el-input>
  78 + </el-form-item>
  79 + </el-col>
  80 + </el-row>
  81 +
  82 + <!-- Party B Info -->
  83 + <el-row :gutter="20">
  84 + <el-col :span="8">
  85 + <el-form-item :label="$t('contract.partyB')" prop="partyB" required>
  86 + <el-input v-model="addContractInfo.partyB" disabled style="width:70%"></el-input>
  87 + <el-button type="primary" size="small" @click="_searchOwner">{{ $t('contract.select') }}</el-button>
  88 + </el-form-item>
  89 + </el-col>
  90 + <el-col :span="8">
  91 + <el-form-item :label="$t('contract.partyBContact')" prop="bContacts" required>
  92 + <el-input v-model="addContractInfo.bContacts" disabled></el-input>
  93 + </el-form-item>
  94 + </el-col>
  95 + <el-col :span="8">
  96 + <el-form-item :label="$t('contract.partyBPhone')" prop="bLink" required>
  97 + <el-input v-model="addContractInfo.bLink" disabled></el-input>
  98 + </el-form-item>
  99 + </el-col>
  100 + </el-row>
  101 +
  102 + <!-- Operator Info -->
  103 + <el-row :gutter="20">
  104 + <el-col :span="8">
  105 + <el-form-item :label="$t('contract.operator')" prop="operator" required>
  106 + <el-input v-model="addContractInfo.operator"></el-input>
  107 + </el-form-item>
  108 + </el-col>
  109 + <el-col :span="8">
  110 + <el-form-item :label="$t('contract.operatorPhone')" prop="operatorLink" required>
  111 + <el-input v-model="addContractInfo.operatorLink"></el-input>
  112 + </el-form-item>
  113 + </el-col>
  114 + <el-col :span="8">
  115 + <el-form-item :label="$t('contract.contractAmount')">
  116 + <el-input v-model="addContractInfo.amount"></el-input>
  117 + </el-form-item>
  118 + </el-col>
  119 + </el-row>
  120 +
  121 + <!-- Time Info -->
  122 + <el-row :gutter="20">
  123 + <el-col :span="8">
  124 + <el-form-item :label="$t('contract.startTime')" prop="startTime" required>
  125 + <el-date-picker v-model="addContractInfo.startTime" type="date" value-format="yyyy-MM-dd" style="width:100%"
  126 + :placeholder="$t('contract.requiredStartTime')">
  127 + </el-date-picker>
  128 + </el-form-item>
  129 + </el-col>
  130 + <el-col :span="8">
  131 + <el-form-item :label="$t('contract.endTime')" prop="endTime" required>
  132 + <el-date-picker v-model="addContractInfo.endTime" type="date" value-format="yyyy-MM-dd" style="width:100%"
  133 + :placeholder="$t('contract.requiredEndTime')">
  134 + </el-date-picker>
  135 + </el-form-item>
  136 + </el-col>
  137 + <el-col :span="8">
  138 + <el-form-item :label="$t('contract.signingTime')" prop="signingTime" required>
  139 + <el-date-picker v-model="addContractInfo.signingTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" style="width:100%"
  140 + :placeholder="$t('contract.requiredSigningTime')">
  141 + </el-date-picker>
  142 + </el-form-item>
  143 + </el-col>
  144 + </el-row>
  145 +
  146 + <!-- Contract Specs -->
  147 + <div v-for="(item, index) in addContractInfo.contractTypeSpecs" :key="index">
  148 + <el-row :gutter="20" v-if="index % 3 == 0">
  149 + <el-col :span="8" v-for="i in 3" :key="i">
  150 + <el-form-item :label="addContractInfo.contractTypeSpecs[index + i - 1].specName"
  151 + v-if="index + i - 1 < addContractInfo.contractTypeSpecs.length">
  152 + <el-input v-model="addContractInfo.contractTypeSpecs[index + i - 1].value"></el-input>
  153 + </el-form-item>
  154 + </el-col>
  155 + </el-row>
  156 + </div>
  157 +
  158 + <!-- Contract Attachments -->
  159 + <el-form-item :label="$t('contract.contractAttachments')">
  160 + <el-button type="primary" @click="addFileStep">
  161 + <i class="el-icon-plus"></i>{{ $t('contract.addAttachment') }}
  162 + </el-button>
  163 + <div v-for="(item, index) in addContractInfo.contractFilePo" :key="index" style="margin-top:10px">
  164 + <el-row>
  165 + <el-col :span="2">
  166 + <span>{{ $t('contract.attachment') }}{{ index + 1 }}</span>
  167 + </el-col>
  168 + <el-col :span="10">
  169 + <input type="file" @change="getFile($event, index)" accept=".png,.pdf,.jpg">
  170 + </el-col>
  171 + <el-col :span="10">
  172 + <span>{{ item.fileRealName }}</span>
  173 + </el-col>
  174 + <el-col :span="2">
  175 + <el-button type="text" @click="deleteStep(item)">{{ $t('contract.deleteAttachment') }}</el-button>
  176 + </el-col>
  177 + </el-row>
  178 + </div>
  179 + </el-form-item>
  180 + </el-form>
  181 + </el-card>
  182 +
  183 + <!-- Related Rooms -->
  184 + <el-card class="box-card" style="margin-top:20px">
  185 + <div slot="header" class="clearfix">
  186 + <span>{{ $t('contract.relatedRooms') }}</span>
  187 + <el-button style="float: right; padding: 3px 0" type="text" @click="_selectRoom">
  188 + <i class="el-icon-plus"></i>{{ $t('contract.add') }}
  189 + </el-button>
  190 + </div>
  191 +
  192 + <el-table :data="addContractInfo.rooms" border style="width:100%">
  193 + <el-table-column prop="floorNum" :label="$t('contract.room')" align="center">
  194 + <template slot-scope="scope">
  195 + {{ scope.row.floorNum }}-{{ scope.row.unitNum }}-{{ scope.row.roomNum }}
  196 + </template>
  197 + </el-table-column>
  198 + <el-table-column prop="ownerName" :label="$t('contract.owner')" align="center"></el-table-column>
  199 + <el-table-column prop="link" :label="$t('contract.phone')" align="center"></el-table-column>
  200 + <el-table-column prop="builtUpArea" :label="$t('contract.builtUpArea')" align="center">
  201 + <template slot-scope="scope">
  202 + {{ scope.row.builtUpArea }}{{ $t('contract.squareMeter') }}
  203 + </template>
  204 + </el-table-column>
  205 + <el-table-column prop="stateName" :label="$t('contract.roomStatus')" align="center"></el-table-column>
  206 + <el-table-column :label="$t('common.operation')" align="center" width="120">
  207 + <template slot-scope="scope">
  208 + <el-button size="mini" type="danger" @click="_openDelRoomModel(scope.row)">{{ $t('common.delete')
  209 + }}</el-button>
  210 + </template>
  211 + </el-table-column>
  212 + </el-table>
  213 + </el-card>
  214 +
  215 + <!-- Approvers -->
  216 + <div v-show="addContractInfo.audit == '1001'">
  217 + <purchase-approvers ref="purchaseApprovers" :flow-type="50005" @notify3="handleNotify"></purchase-approvers>
  218 + </div>
  219 +
  220 + <!-- Buttons -->
  221 + <div class="text-right" style="margin-top:20px">
  222 + <el-button @click="_goBack" style="margin-right:20px">{{ $t('common.back') }}</el-button>
  223 + <el-button type="primary" @click="saveContractInfo">{{ $t('common.submit') }}</el-button>
  224 + </div>
  225 +
  226 + <!-- Modals -->
  227 + <search-room ref="searchRoom" @chooseRoom="handleChooseRoom"></search-room>
  228 + <search-owner ref="searchOwner" @chooseOwner="handleChooseOwner"></search-owner>
  229 + </div>
  230 +</template>
  231 +
  232 +<script>
  233 +import { getCommunityId } from '@/api/community/communityApi'
  234 +import { saveContract, queryContractType, queryContractPartya, queryContractTypeSpec, queryContractRoom } from '@/api/contract/addContractApi'
  235 +import PurchaseApprovers from '@/components/contract/purchaseApprovers'
  236 +import SearchRoom from '@/components/room/searchRoom'
  237 +import SearchOwner from '@/components/owner/SearchOwner'
  238 +
  239 +export default {
  240 + name: 'AddContractList',
  241 + components: {
  242 + PurchaseApprovers,
  243 + SearchRoom,
  244 + SearchOwner
  245 + },
  246 + data() {
  247 + return {
  248 + addContractInfo: {
  249 + contractId: '',
  250 + contractName: '',
  251 + contractCode: '',
  252 + contractType: '',
  253 + partyA: '',
  254 + partyB: '',
  255 + aContacts: '',
  256 + bContacts: '',
  257 + aLink: '',
  258 + bLink: '',
  259 + operator: '',
  260 + operatorLink: '',
  261 + amount: '',
  262 + startTime: '',
  263 + endTime: '',
  264 + signingTime: '',
  265 + contractTypes: [],
  266 + contractTypeSpecs: [],
  267 + objType: '1111',
  268 + objId: '-1',
  269 + contractParentId: '',
  270 + parentContractCode: '',
  271 + parentContractName: '',
  272 + parentStateName: '',
  273 + rooms: [],
  274 + contractFilePo: [],
  275 + tempfile: '',
  276 + contractPartyAs: [],
  277 + audit: '',
  278 + staffName: '',
  279 + nextUserId: ''
  280 + },
  281 + communityId: ''
  282 + }
  283 + },
  284 + created() {
  285 + this.communityId = getCommunityId()
  286 + this._loadAddContractType()
  287 + this._loadAddContractParkA()
  288 + if (this.$route.query.contractId) {
  289 + this.addContractInfo.contractParentId = this.$route.query.contractId
  290 + this.addContractInfo.parentContractCode = this.$route.query.contractCode
  291 + this.addContractInfo.parentContractName = this.$route.query.contractName
  292 + this.addContractInfo.parentStateName = this.$route.query.stateName
  293 + this._queryRoom()
  294 + this._listContracts()
  295 + }
  296 + },
  297 + methods: {
  298 + _loadAddContractType() {
  299 + queryContractType({ page: 1, row: 100 }).then(response => {
  300 + this.addContractInfo.contractTypes = response.data
  301 + })
  302 + },
  303 + _loadAddContractParkA() {
  304 + queryContractPartya({ page: 1, row: 100 }).then(response => {
  305 + this.addContractInfo.contractPartyAs = response.data
  306 + })
  307 + },
  308 + _changeContractType() {
  309 + this.addContractInfo.contractTypes.forEach(item => {
  310 + if (this.addContractInfo.contractType == item.contractTypeId) {
  311 + this.addContractInfo.audit = item.audit
  312 + }
  313 + })
  314 +
  315 + this.addContractInfo.contractTypeSpecs = []
  316 + queryContractTypeSpec({
  317 + page: 1,
  318 + row: 100,
  319 + contractTypeId: this.addContractInfo.contractType
  320 + }).then(response => {
  321 + response.data.forEach(item => {
  322 + item.value = ''
  323 + if (item.specShow == 'Y') {
  324 + item.values = []
  325 + this.addContractInfo.contractTypeSpecs.push(item)
  326 + }
  327 + })
  328 + })
  329 + },
  330 + _queryRoom() {
  331 + queryContractRoom({
  332 + contractId: this.$route.query.contractId,
  333 + page: 1,
  334 + row: 100
  335 + }).then(response => {
  336 + this.addContractInfo.rooms = response.data
  337 + })
  338 + },
  339 + _selectRoom() {
  340 + this.$refs.searchRoom.open()
  341 + },
  342 + _searchOwner() {
  343 + this.$refs.searchOwner.open()
  344 + },
  345 + handleChooseRoom(room) {
  346 + this.addContractInfo.rooms.push(room)
  347 + },
  348 + handleChooseOwner(owner) {
  349 + this.addContractInfo.partyB = owner.name
  350 + this.addContractInfo.bContacts = owner.name
  351 + this.addContractInfo.bLink = owner.link
  352 + this.addContractInfo.objId = owner.ownerId
  353 + },
  354 + handleNotify(info) {
  355 + this.addContractInfo.nextUserId = info.staffId
  356 + this.addContractInfo.staffName = info.staffName
  357 + },
  358 + _openDelRoomModel(room) {
  359 + this.addContractInfo.rooms = this.addContractInfo.rooms.filter(item => item.roomId != room.roomId)
  360 + },
  361 + addFileStep() {
  362 + this.addContractInfo.contractFilePo.push({
  363 + seq: this.addContractInfo.contractFilePo.length,
  364 + fileSaveName: '',
  365 + fileRealName: ''
  366 + })
  367 + },
  368 + deleteStep(step) {
  369 + this.addContractInfo.contractFilePo = this.addContractInfo.contractFilePo.filter(item => item.seq != step.seq)
  370 + },
  371 + getFile(e, index) {
  372 + this.addContractInfo.tempfile = e.target.files[0]
  373 + this.addContractInfo.contractFilePo[index].fileRealName = this.addContractInfo.tempfile.name
  374 + this._importData(index)
  375 + },
  376 + _importData(index) {
  377 + console.log(index)
  378 + const _fileName = this.addContractInfo.tempfile.name
  379 + const _suffix = _fileName.substring(_fileName.lastIndexOf('.') + 1)
  380 + if (!this.checkFileType(_suffix.toLowerCase())) {
  381 + this.$message.error(this.$t('contract.invalidFileType'))
  382 + return
  383 + }
  384 +
  385 + const formData = new FormData()
  386 + formData.append("uploadFile", this.addContractInfo.tempfile)
  387 +
  388 + // 这里需要实现文件上传逻辑
  389 + // uploadContactFile(formData).then(response => {
  390 + // this.addContractInfo.contractFilePo[index].fileSaveName = response.data
  391 + // this.$message.success(this.$t('contract.uploadSuccess'))
  392 + // })
  393 + },
  394 + checkFileType(fileType) {
  395 + return ['png', 'pdf', 'jpg'].includes(fileType)
  396 + },
  397 + _changeContractPartyA() {
  398 + const partyA = this.addContractInfo.partyA
  399 + this.addContractInfo.contractPartyAs.forEach(item => {
  400 + if (partyA == item.partyA) {
  401 + this.addContractInfo.aLink = item.aLink
  402 + this.addContractInfo.aContacts = item.aContacts
  403 + }
  404 + })
  405 + },
  406 + _listContracts() {
  407 + // 需要实现查询合同详情逻辑
  408 + },
  409 + saveContractInfo() {
  410 + if (!this.validateForm()) {
  411 + return
  412 + }
  413 +
  414 + this.addContractInfo.communityId = this.communityId
  415 + saveContract(this.addContractInfo).then(response => {
  416 + if (response.code === 0) {
  417 + this.$message.success(this.$t('contract.submitSuccess'))
  418 + this._goBack()
  419 + } else {
  420 + this.$message.error(response.msg)
  421 + }
  422 + })
  423 + },
  424 + validateForm() {
  425 + // 实现表单验证逻辑
  426 + return true
  427 + },
  428 + _goBack() {
  429 + this.$router.go(-1)
  430 + }
  431 + }
  432 +}
  433 +</script>
  434 +
  435 +<style scoped>
  436 +.add-contract-container {
  437 + padding: 20px;
  438 +}
  439 +
  440 +.box-card {
  441 + margin-bottom: 20px;
  442 +}
  443 +
  444 +.text-right {
  445 + text-align: right;
  446 +}
  447 +</style>
0 448 \ No newline at end of file
... ...
src/views/contract/contractChangeDetailLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + contractChangeDetail: {
  4 + contractInfo: 'Contract Information',
  5 + selectContract: 'Select Contract',
  6 + contractName: 'Contract Name',
  7 + contractCode: 'Contract Code',
  8 + contractType: 'Contract Type',
  9 + partyA: 'Party A',
  10 + partyB: 'Party B',
  11 + aContacts: 'Party A Contact',
  12 + bContacts: 'Party B Contact',
  13 + aLink: 'Party A Phone',
  14 + bLink: 'Party B Phone',
  15 + operator: 'Operator',
  16 + operatorLink: 'Operator Phone',
  17 + amount: 'Amount',
  18 + startTime: 'Start Time',
  19 + endTime: 'End Time',
  20 + signingTime: 'Signing Time',
  21 + changeRemark: 'Change Remark',
  22 + changeRemarkPlaceholder: 'Required, please fill in the change remark',
  23 + changeRemarkRequired: 'Change remark is required'
  24 + },
  25 + contractChangeMainBody: {
  26 + title: 'Main Body Change',
  27 + contractName: 'Contract Name',
  28 + contractNamePlaceholder: 'Required, please fill in contract name',
  29 + partyA: 'Party A',
  30 + partyAPlaceholder: 'Required, please fill in Party A',
  31 + aContacts: 'Party A Contact',
  32 + aContactsPlaceholder: 'Required, please fill in Party A contact',
  33 + aLink: 'Party A Phone',
  34 + aLinkPlaceholder: 'Required, please fill in Party A phone',
  35 + partyB: 'Party B',
  36 + partyBPlaceholder: 'Required, please fill in Party B',
  37 + bContacts: 'Party B Contact',
  38 + bContactsPlaceholder: 'Required, please fill in Party B contact',
  39 + bLink: 'Party B Phone',
  40 + bLinkPlaceholder: 'Required, please fill in Party B phone'
  41 + },
  42 + contractChangeLease: {
  43 + title: 'Lease Adjustment',
  44 + startTime: 'Start Time',
  45 + startTimePlaceholder: 'Required, please select start time',
  46 + endTime: 'End Time',
  47 + endTimePlaceholder: 'Required, please select end time'
  48 + },
  49 + contractChangeAssets: {
  50 + title: 'Related Rooms',
  51 + room: 'Room',
  52 + owner: 'Owner',
  53 + phone: 'Phone',
  54 + area: 'Area',
  55 + status: 'Status',
  56 + squareMeters: 'Square Meters',
  57 + confirmDelete: 'Are you sure to delete this room?'
  58 + },
  59 + searchRoom: {
  60 + title: 'Select Room',
  61 + buildingNo: 'Building No',
  62 + buildingNoPlaceholder: 'Input building number',
  63 + roomNo: 'Room No',
  64 + roomNoPlaceholder: 'Input room number',
  65 + roomId: 'Room ID',
  66 + building: 'Building',
  67 + unit: 'Unit',
  68 + room: 'Room',
  69 + floorUnit: 'Floor'
  70 + },
  71 + purchaseApprovers: {
  72 + title: 'Approver Information',
  73 + orgName: 'Organization',
  74 + staffName: 'Staff',
  75 + orgPlaceholder: 'Required, please fill in organization',
  76 + staffPlaceholder: 'Required, please select staff',
  77 + staffRequired: 'Staff is required',
  78 + staffNameRequired: 'Staff name is required'
  79 + },
  80 + selectStaff: {
  81 + title: 'Select Staff',
  82 + orgInfo: 'Organization Information',
  83 + staffInfo: 'Staff Information',
  84 + submitter: 'Submitter',
  85 + dynamicAssign: 'Dynamic Assignment'
  86 + },
  87 + chooseContract: {
  88 + title: 'Select Contract',
  89 + searchPlaceholder: 'Input contract name',
  90 + contractName: 'Contract Name',
  91 + contractCode: 'Contract Code',
  92 + contractType: 'Contract Type',
  93 + partyA: 'Party A',
  94 + partyB: 'Party B',
  95 + signingTime: 'Signing Time'
  96 + }
  97 + },
  98 + zh: {
  99 + contractChangeDetail: {
  100 + contractInfo: '合同信息',
  101 + selectContract: '选择合同',
  102 + contractName: '合同名称',
  103 + contractCode: '合同编号',
  104 + contractType: '合同类型',
  105 + partyA: '甲方',
  106 + partyB: '乙方',
  107 + aContacts: '甲方联系人',
  108 + bContacts: '乙方联系人',
  109 + aLink: '甲方联系电话',
  110 + bLink: '乙方联系电话',
  111 + operator: '经办人',
  112 + operatorLink: '联系电话',
  113 + amount: '合同金额',
  114 + startTime: '开始时间',
  115 + endTime: '结束时间',
  116 + signingTime: '签订时间',
  117 + changeRemark: '变更说明',
  118 + changeRemarkPlaceholder: '必填,请填写变更说明',
  119 + changeRemarkRequired: '变更说明不能为空'
  120 + },
  121 + contractChangeMainBody: {
  122 + title: '主体变更',
  123 + contractName: '合同名称',
  124 + contractNamePlaceholder: '必填,请填写合同名称',
  125 + partyA: '甲方',
  126 + partyAPlaceholder: '必填,请填写甲方',
  127 + aContacts: '甲方联系人',
  128 + aContactsPlaceholder: '必填,请填写甲方联系人',
  129 + aLink: '甲方联系电话',
  130 + aLinkPlaceholder: '必填,请填写甲方联系电话',
  131 + partyB: '乙方',
  132 + partyBPlaceholder: '必填,请填写乙方',
  133 + bContacts: '乙方联系人',
  134 + bContactsPlaceholder: '必填,请填写乙方联系人',
  135 + bLink: '乙方联系电话',
  136 + bLinkPlaceholder: '必填,请填写乙方联系电话'
  137 + },
  138 + contractChangeLease: {
  139 + title: '租期调整',
  140 + startTime: '开始时间',
  141 + startTimePlaceholder: '必填,请选择开始时间',
  142 + endTime: '结束时间',
  143 + endTimePlaceholder: '必填,请选择结束时间'
  144 + },
  145 + contractChangeAssets: {
  146 + title: '关联房屋',
  147 + room: '房屋',
  148 + owner: '业主',
  149 + phone: '电话',
  150 + area: '建筑面积',
  151 + status: '房屋状态',
  152 + squareMeters: '平方米',
  153 + confirmDelete: '确定删除该房屋吗?'
  154 + },
  155 + searchRoom: {
  156 + title: '选择房屋',
  157 + buildingNo: '楼栋编号',
  158 + buildingNoPlaceholder: '输入楼栋编号',
  159 + roomNo: '房屋编号',
  160 + roomNoPlaceholder: '输入房屋编号',
  161 + roomId: '房屋ID',
  162 + building: '号楼',
  163 + unit: '单元',
  164 + room: '室',
  165 + floorUnit: '层'
  166 + },
  167 + purchaseApprovers: {
  168 + title: '审批人信息',
  169 + orgName: '所属组织',
  170 + staffName: '员工',
  171 + orgPlaceholder: '必填,请填写所属组织',
  172 + staffPlaceholder: '必填,请选择员工',
  173 + staffRequired: '员工不能为空',
  174 + staffNameRequired: '员工名称不能为空'
  175 + },
  176 + selectStaff: {
  177 + title: '选择员工',
  178 + orgInfo: '组织信息',
  179 + staffInfo: '员工信息',
  180 + submitter: '提交者',
  181 + dynamicAssign: '动态指定'
  182 + },
  183 + chooseContract: {
  184 + title: '选择合同信息',
  185 + searchPlaceholder: '输入合同信息名称',
  186 + contractName: '合同名称',
  187 + contractCode: '合同编号',
  188 + contractType: '合同类型',
  189 + partyA: '甲方',
  190 + partyB: '乙方',
  191 + signingTime: '签订时间'
  192 + }
  193 + }
  194 +}
0 195 \ No newline at end of file
... ...
src/views/contract/contractChangeDetailList.vue 0 → 100644
  1 +<template>
  2 + <div class="contract-change-detail-container">
  3 + <el-card class="box-card">
  4 + <div slot="header" class="flex justify-between">
  5 + <span>{{ $t('contractChangeDetail.contractInfo') }}</span>
  6 + <div class="card-header-actions">
  7 + <el-button type="primary" size="small" @click="openSelectContractInfoModel">
  8 + <i class="el-icon-search"></i>
  9 + {{ $t('contractChangeDetail.selectContract') }}
  10 + </el-button>
  11 + <el-button type="primary" size="small" @click="goBack">
  12 + <i class="el-icon-close"></i>
  13 + {{ $t('common.back') }}
  14 + </el-button>
  15 + </div>
  16 + </div>
  17 + <el-form>
  18 + <el-row :gutter="20">
  19 + <el-col :span="8">
  20 + <el-form-item :label="$t('contractChangeDetail.contractName')">
  21 + <span>{{ contractChangeDetailInfo.contractName }}</span>
  22 + </el-form-item>
  23 + </el-col>
  24 + <el-col :span="8">
  25 + <el-form-item :label="$t('contractChangeDetail.contractCode')">
  26 + <span>{{ contractChangeDetailInfo.contractCode }}</span>
  27 + </el-form-item>
  28 + </el-col>
  29 + <el-col :span="8">
  30 + <el-form-item :label="$t('contractChangeDetail.contractType')">
  31 + <span>{{ contractChangeDetailInfo.contractTypeName }}</span>
  32 + </el-form-item>
  33 + </el-col>
  34 + </el-row>
  35 +
  36 + <el-row :gutter="20">
  37 + <el-col :span="8">
  38 + <el-form-item :label="$t('contractChangeDetail.partyA')">
  39 + <span>{{ contractChangeDetailInfo.partyA }}</span>
  40 + </el-form-item>
  41 + </el-col>
  42 + <el-col :span="8">
  43 + <el-form-item :label="$t('contractChangeDetail.aContacts')">
  44 + <span>{{ contractChangeDetailInfo.aContacts }}</span>
  45 + </el-form-item>
  46 + </el-col>
  47 + <el-col :span="8">
  48 + <el-form-item :label="$t('contractChangeDetail.aLink')">
  49 + <span>{{ contractChangeDetailInfo.aLink }}</span>
  50 + </el-form-item>
  51 + </el-col>
  52 + </el-row>
  53 +
  54 + <el-row :gutter="20">
  55 + <el-col :span="8">
  56 + <el-form-item :label="$t('contractChangeDetail.partyB')">
  57 + <span>{{ contractChangeDetailInfo.partyB }}</span>
  58 + </el-form-item>
  59 + </el-col>
  60 + <el-col :span="8">
  61 + <el-form-item :label="$t('contractChangeDetail.bContacts')">
  62 + <span>{{ contractChangeDetailInfo.bContacts }}</span>
  63 + </el-form-item>
  64 + </el-col>
  65 + <el-col :span="8">
  66 + <el-form-item :label="$t('contractChangeDetail.bLink')">
  67 + <span>{{ contractChangeDetailInfo.bLink }}</span>
  68 + </el-form-item>
  69 + </el-col>
  70 + </el-row>
  71 +
  72 + <el-row :gutter="20">
  73 + <el-col :span="8">
  74 + <el-form-item :label="$t('contractChangeDetail.operator')">
  75 + <span>{{ contractChangeDetailInfo.operator }}</span>
  76 + </el-form-item>
  77 + </el-col>
  78 + <el-col :span="8">
  79 + <el-form-item :label="$t('contractChangeDetail.operatorLink')">
  80 + <span>{{ contractChangeDetailInfo.operatorLink }}</span>
  81 + </el-form-item>
  82 + </el-col>
  83 + <el-col :span="8">
  84 + <el-form-item :label="$t('contractChangeDetail.amount')">
  85 + <span>{{ contractChangeDetailInfo.amount }}</span>
  86 + </el-form-item>
  87 + </el-col>
  88 + </el-row>
  89 +
  90 + <el-row :gutter="20">
  91 + <el-col :span="8">
  92 + <el-form-item :label="$t('contractChangeDetail.startTime')">
  93 + <span>{{ contractChangeDetailInfo.startTime }}</span>
  94 + </el-form-item>
  95 + </el-col>
  96 + <el-col :span="8">
  97 + <el-form-item :label="$t('contractChangeDetail.endTime')">
  98 + <span>{{ contractChangeDetailInfo.endTime }}</span>
  99 + </el-form-item>
  100 + </el-col>
  101 + <el-col :span="8">
  102 + <el-form-item :label="$t('contractChangeDetail.signingTime')">
  103 + <span>{{ contractChangeDetailInfo.signingTime }}</span>
  104 + </el-form-item>
  105 + </el-col>
  106 + </el-row>
  107 + </el-form>
  108 + </el-card>
  109 +
  110 + <!-- 主体变更 -->
  111 + <contract-change-main-body v-if="contractChangeDetailInfo.param === 'contractChangeMainBody'"
  112 + ref="contractChangeMainBody" @changeMainBody="handlerMainBody" />
  113 +
  114 + <!-- 租期调整 -->
  115 + <contract-change-lease v-show="contractChangeDetailInfo.param === 'contractChangeLease'" ref="contractChangeLease"
  116 + @changeNotify="handlerMainBody" />
  117 +
  118 + <!-- 资产调整 -->
  119 + <contract-change-assets v-show="contractChangeDetailInfo.param === 'contractChangeAssets'" ref="contractChangeAssets"
  120 + @changeNotify="handlerMainBody" />
  121 +
  122 + <el-card class="box-card">
  123 + <div slot="header" class="flex justify-between">
  124 + <span>{{ $t('contractChangeDetail.changeRemark') }}</span>
  125 + </div>
  126 + <el-form>
  127 + <el-form-item :label="$t('contractChangeDetail.changeRemark')">
  128 + <el-input v-model="newContract.changeRemark" type="textarea" :rows="5"
  129 + :placeholder="$t('contractChangeDetail.changeRemarkPlaceholder')"></el-input>
  130 + </el-form-item>
  131 + </el-form>
  132 + </el-card>
  133 +
  134 + <purchase-approvers v-if="contractChangeDetailInfo.audit === '1001'" ref="purchaseApprovers"
  135 + :call-back-listener="contractChangeDetail" :call-back-function="notify3" flow-type="60006" />
  136 +
  137 + <el-row>
  138 + <el-col :span="22">
  139 + <div class="submit-btn-wrapper">
  140 + <el-button type="primary" @click="submitChangeContract">
  141 + {{ $t('common.submit') }}
  142 + </el-button>
  143 + </div>
  144 + </el-col>
  145 + </el-row>
  146 +
  147 + <choose-contract ref="chooseContract" :emitChooseContract="contractChangeDetailInfo"
  148 + @chooseContract="chooseContract" />
  149 + </div>
  150 +</template>
  151 +
  152 +<script>
  153 +import { saveContractChangePlan } from '@/api/contract/contractChangeDetailApi'
  154 +import ContractChangeMainBody from '@/components/contract/ContractChangeMainBody'
  155 +import ContractChangeLease from '@/components/contract/ContractChangeLease'
  156 +import ContractChangeAssets from '@/components/contract/ContractChangeAssets'
  157 +import PurchaseApprovers from '@/components/contract/purchaseApprovers'
  158 +import ChooseContract from '@/components/contract/ChooseContract'
  159 +import { getCommunityId } from '@/api/community/communityApi'
  160 +
  161 +export default {
  162 + name: 'ContractChangeDetailList',
  163 + components: {
  164 + ContractChangeMainBody,
  165 + ContractChangeLease,
  166 + ContractChangeAssets,
  167 + PurchaseApprovers,
  168 + ChooseContract
  169 + },
  170 + data() {
  171 + return {
  172 + contractChangeDetailInfo: {
  173 + contractId: '',
  174 + contractName: '',
  175 + contractCode: '',
  176 + contractType: '',
  177 + contractTypeName: '',
  178 + partyA: '',
  179 + partyB: '',
  180 + aContacts: '',
  181 + bContacts: '',
  182 + aLink: '',
  183 + bLink: '',
  184 + operator: '',
  185 + operatorLink: '',
  186 + amount: '',
  187 + startTime: '',
  188 + endTime: '',
  189 + signingTime: '',
  190 + param: '',
  191 + planType: '',
  192 + rooms: [],
  193 + audit: '',
  194 + staffName: '',
  195 + nextUserId: ''
  196 + },
  197 + newContract: {
  198 + changeRemark: ''
  199 + },
  200 + communityId: ''
  201 + }
  202 + },
  203 + created() {
  204 + this.communityId = getCommunityId()
  205 + const param = this.$route.query.param
  206 + this.contractChangeDetailInfo.param = param
  207 + },
  208 + methods: {
  209 + openSelectContractInfoModel() {
  210 + this.$refs.chooseContract.open()
  211 + },
  212 + submitChangeContract() {
  213 + if (!this.validateForm()) {
  214 + return
  215 + }
  216 +
  217 + this.newContract.nextUserId = this.contractChangeDetailInfo.nextUserId
  218 + this.newContract.staffName = this.contractChangeDetailInfo.staffName
  219 +
  220 + saveContractChangePlan(this.newContract)
  221 + .then(response => {
  222 + if (response.code === 0) {
  223 + this.$message.success(this.$t('common.submitSuccess'))
  224 + this.goBack()
  225 + } else {
  226 + this.$message.error(response.msg)
  227 + }
  228 + })
  229 + .catch(error => {
  230 + console.error('Error submitting contract change:', error)
  231 + this.$message.error(this.$t('common.submitFailed'))
  232 + })
  233 + },
  234 + validateForm() {
  235 + // 这里添加表单验证逻辑
  236 + if (!this.newContract.changeRemark) {
  237 + this.$message.error(this.$t('contractChangeDetail.changeRemarkRequired'))
  238 + return false
  239 + }
  240 + return true
  241 + },
  242 + goBack() {
  243 + this.$router.go(-1)
  244 + },
  245 + handlerMainBody(item) {
  246 + const changeRemark = this.newContract.changeRemark
  247 + this.newContract = JSON.parse(JSON.stringify(this.contractChangeDetailInfo))
  248 + this.newContract.changeRemark = changeRemark
  249 + if (item['rooms']) {
  250 + this.newContract.rooms = item.rooms
  251 + }
  252 + Object.assign(this.newContract, item)
  253 + },
  254 + notify3(info) {
  255 + this.contractChangeDetailInfo.nextUserId = info.staffId
  256 + this.contractChangeDetailInfo.staffName = info.staffName
  257 + },
  258 + chooseContract(contract) {
  259 + this.contractChangeDetailInfo.contractId = contract.contractId
  260 + this.contractChangeDetailInfo.contractName = contract.contractName
  261 + this.contractChangeDetailInfo.contractCode = contract.contractCode
  262 + this.contractChangeDetailInfo.contractType = contract.contractType
  263 + this.contractChangeDetailInfo.contractTypeName = contract.contractTypeName
  264 + this.contractChangeDetailInfo.partyA = contract.partyA
  265 + this.contractChangeDetailInfo.partyB = contract.partyB
  266 + this.contractChangeDetailInfo.aContacts = contract.aContacts
  267 + this.contractChangeDetailInfo.bContacts = contract.bContacts
  268 + this.contractChangeDetailInfo.aLink = contract.aLink
  269 + this.contractChangeDetailInfo.bLink = contract.bLink
  270 + this.contractChangeDetailInfo.operator = contract.operator
  271 + this.contractChangeDetailInfo.operatorLink = contract.operatorLink
  272 + this.contractChangeDetailInfo.amount = contract.amount
  273 + this.contractChangeDetailInfo.startTime = contract.startTime
  274 + this.contractChangeDetailInfo.endTime = contract.endTime
  275 + this.contractChangeDetailInfo.signingTime = contract.signingTime
  276 + }
  277 + }
  278 +}
  279 +</script>
  280 +
  281 +<style lang="scss" scoped>
  282 +.contract-change-detail-container {
  283 + padding: 20px;
  284 +
  285 + .box-card {
  286 + margin-bottom: 20px;
  287 + }
  288 +
  289 + .card-header-actions {
  290 + float: right;
  291 + }
  292 +
  293 + .submit-btn-wrapper {
  294 + text-align: right;
  295 + margin-top: 20px;
  296 + margin-bottom: 20px;
  297 + }
  298 +
  299 + .el-form-item {
  300 + margin-bottom: 0;
  301 + }
  302 +}
  303 +</style>
0 304 \ No newline at end of file
... ...
src/views/contract/contractChangeManageLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + contractChangeManage: {
  4 + search: {
  5 + title: 'Search Conditions',
  6 + contractName: 'Please enter contract name',
  7 + contractCode: 'Please enter contract code',
  8 + contractType: 'Please select contract type'
  9 + },
  10 + list: {
  11 + title: 'Contract Change Information',
  12 + mainBodyChange: 'Main Body Change',
  13 + leaseAdjustment: 'Lease Adjustment',
  14 + assetsChange: 'Assets Change'
  15 + },
  16 + table: {
  17 + contractName: 'Contract Name',
  18 + contractCode: 'Contract Code',
  19 + contractType: 'Contract Type',
  20 + partyA: 'Party A',
  21 + partyB: 'Party B',
  22 + changeType: 'Change Type',
  23 + changePerson: 'Change Person',
  24 + applyTime: 'Apply Time',
  25 + remark: 'Remark',
  26 + state: 'State'
  27 + },
  28 + note: 'Note: Please set up the contract change process in System Management > Process Management before using this function',
  29 + fetchError: 'Failed to get contract change list'
  30 + },
  31 + deleteContractChangePlan: {
  32 + title: 'Confirm Operation',
  33 + confirmText: 'Are you sure to delete the contract change information?',
  34 + deleteSuccess: 'Delete successfully',
  35 + deleteError: 'Failed to delete contract change'
  36 + }
  37 + },
  38 + zh: {
  39 + contractChangeManage: {
  40 + search: {
  41 + title: '查询条件',
  42 + contractName: '请输入合同名称',
  43 + contractCode: '请输入合同编号',
  44 + contractType: '请选择合同类型'
  45 + },
  46 + list: {
  47 + title: '合同变更信息',
  48 + mainBodyChange: '主体变更',
  49 + leaseAdjustment: '租期调整',
  50 + assetsChange: '资产变更'
  51 + },
  52 + table: {
  53 + contractName: '合同名称',
  54 + contractCode: '合同编号',
  55 + contractType: '合同类型',
  56 + partyA: '甲方',
  57 + partyB: '乙方',
  58 + changeType: '变更类型',
  59 + changePerson: '变更人',
  60 + applyTime: '申请时间',
  61 + remark: '说明',
  62 + state: '状态'
  63 + },
  64 + note: '注意:此功能使用前请先到系统管理>流程管理中设置合同变更流程',
  65 + fetchError: '获取合同变更列表失败'
  66 + },
  67 + deleteContractChangePlan: {
  68 + title: '请确认您的操作',
  69 + confirmText: '确定删除合同变更信息?',
  70 + deleteSuccess: '删除成功',
  71 + deleteError: '删除合同变更失败'
  72 + }
  73 + }
  74 +}
0 75 \ No newline at end of file
... ...
src/views/contract/contractChangeManageList.vue 0 → 100644
  1 +<template>
  2 + <div class="contract-change-manage-container">
  3 + <!-- 查询条件 -->
  4 + <el-card class="search-wrapper">
  5 + <div slot="header" class="flex justify-between">
  6 + <span>{{ $t('contractChangeManage.search.title') }}</span>
  7 + </div>
  8 + <el-row :gutter="20">
  9 + <el-col :span="6">
  10 + <el-input v-model="searchForm.contractName" :placeholder="$t('contractChangeManage.search.contractName')"
  11 + clearable @keyup.enter.native="handleSearch" />
  12 + </el-col>
  13 + <el-col :span="6">
  14 + <el-input v-model="searchForm.contractCode" :placeholder="$t('contractChangeManage.search.contractCode')"
  15 + clearable @keyup.enter.native="handleSearch" />
  16 + </el-col>
  17 + <el-col :span="6">
  18 + <el-select v-model="searchForm.contractType" :placeholder="$t('contractChangeManage.search.contractType')"
  19 + style="width:100%" clearable>
  20 + <el-option v-for="item in contractTypes" :key="item.contractTypeId" :label="item.typeName"
  21 + :value="item.contractTypeId" />
  22 + </el-select>
  23 + </el-col>
  24 + <el-col :span="6">
  25 + <el-button type="primary" @click="handleSearch">
  26 + {{ $t('common.search') }}
  27 + </el-button>
  28 + <el-button @click="handleReset">
  29 + {{ $t('common.reset') }}
  30 + </el-button>
  31 + </el-col>
  32 + </el-row>
  33 + </el-card>
  34 +
  35 + <!-- 合同变更信息 -->
  36 + <el-card class="list-wrapper">
  37 + <div slot="header" class="flex justify-between">
  38 + <span>{{ $t('contractChangeManage.list.title') }}</span>
  39 + <div style="float: right;">
  40 + <el-button type="primary" size="small" @click="handleToChangePage('contractChangeMainBody')">
  41 + <i class="el-icon-plus"></i>
  42 + {{ $t('contractChangeManage.list.mainBodyChange') }}
  43 + </el-button>
  44 + <el-button type="primary" size="small" @click="handleToChangePage('contractChangeLease')">
  45 + <i class="el-icon-plus"></i>
  46 + {{ $t('contractChangeManage.list.leaseAdjustment') }}
  47 + </el-button>
  48 + <el-button type="primary" size="small" @click="handleToChangePage('contractChangeAssets')">
  49 + <i class="el-icon-plus"></i>
  50 + {{ $t('contractChangeManage.list.assetsChange') }}
  51 + </el-button>
  52 + </div>
  53 + </div>
  54 +
  55 + <el-table v-loading="loading" :data="tableData" border style="width: 100%">
  56 + <el-table-column prop="contractName" :label="$t('contractChangeManage.table.contractName')" align="center" />
  57 + <el-table-column prop="contractCode" :label="$t('contractChangeManage.table.contractCode')" align="center" />
  58 + <el-table-column prop="contractTypeName" :label="$t('contractChangeManage.table.contractType')" align="center" />
  59 + <el-table-column prop="partyA" :label="$t('contractChangeManage.table.partyA')" align="center" />
  60 + <el-table-column prop="partyB" :label="$t('contractChangeManage.table.partyB')" align="center" />
  61 + <el-table-column prop="planTypeName" :label="$t('contractChangeManage.table.changeType')" align="center" />
  62 + <el-table-column prop="changePersonName" :label="$t('contractChangeManage.table.changePerson')" align="center" />
  63 + <el-table-column prop="createTime" :label="$t('contractChangeManage.table.applyTime')" align="center" />
  64 + <el-table-column prop="remark" :label="$t('contractChangeManage.table.remark')" align="center" />
  65 + <el-table-column prop="stateName" :label="$t('contractChangeManage.table.state')" align="center" />
  66 + <el-table-column :label="$t('common.operation')" align="center" width="180">
  67 + <template slot-scope="scope">
  68 + <el-button v-if="scope.row.state === '11'" type="text" size="small"
  69 + @click="handleOpenDeleteDialog(scope.row)">
  70 + {{ $t('common.cancel') }}
  71 + </el-button>
  72 + <el-button type="text" size="small" @click="handleToDetails(scope.row)">
  73 + {{ $t('common.detail') }}
  74 + </el-button>
  75 + </template>
  76 + </el-table-column>
  77 + </el-table>
  78 +
  79 + <el-pagination :current-page="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size"
  80 + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
  81 + @current-change="handleCurrentChange" />
  82 +
  83 + <div class="note">
  84 + {{ $t('contractChangeManage.note') }}
  85 + </div>
  86 + </el-card>
  87 +
  88 + <!-- 删除确认对话框 -->
  89 + <delete-contract-change-plan ref="deleteDialog" @success="handleSuccess" />
  90 + </div>
  91 +</template>
  92 +
  93 +<script>
  94 +import { queryContractChangePlan, queryContractType } from '@/api/contract/contractChangeManageApi'
  95 +import DeleteContractChangePlan from '@/components/contract/deleteContractChangePlan'
  96 +
  97 +export default {
  98 + name: 'ContractChangeManageList',
  99 + components: {
  100 + DeleteContractChangePlan
  101 + },
  102 + data() {
  103 + return {
  104 + loading: false,
  105 + searchForm: {
  106 + contractName: '',
  107 + contractCode: '',
  108 + contractType: ''
  109 + },
  110 + tableData: [],
  111 + contractTypes: [],
  112 + page: {
  113 + current: 1,
  114 + size: 10,
  115 + total: 0
  116 + }
  117 + }
  118 + },
  119 + created() {
  120 + this.getList()
  121 + this.getContractTypes()
  122 + },
  123 + methods: {
  124 + async getList() {
  125 + try {
  126 + this.loading = true
  127 + const params = {
  128 + page: this.page.current,
  129 + row: this.page.size,
  130 + ...this.searchForm
  131 + }
  132 + const { data, total } = await queryContractChangePlan(params)
  133 + this.tableData = data
  134 + this.page.total = total
  135 + } catch (error) {
  136 + this.$message.error(this.$t('contractChangeManage.fetchError'))
  137 + } finally {
  138 + this.loading = false
  139 + }
  140 + },
  141 + async getContractTypes() {
  142 + try {
  143 + const params = {
  144 + page: 1,
  145 + row: 50
  146 + }
  147 + const { data } = await queryContractType(params)
  148 + this.contractTypes = data
  149 + } catch (error) {
  150 + console.error('获取合同类型失败:', error)
  151 + }
  152 + },
  153 + handleSearch() {
  154 + this.page.current = 1
  155 + this.getList()
  156 + },
  157 + handleReset() {
  158 + this.searchForm = {
  159 + contractName: '',
  160 + contractCode: '',
  161 + contractType: ''
  162 + }
  163 + this.handleSearch()
  164 + },
  165 + handleToChangePage(type) {
  166 + this.$router.push(`/views/contract/contractChangeDetail?param=${type}`)
  167 + },
  168 + handleToDetails(row) {
  169 + this.$router.push(`/views/contract/contractChangeDetail?planId=${row.planId}`)
  170 + },
  171 + handleOpenDeleteDialog(row) {
  172 + this.$refs.deleteDialog.open(row)
  173 + },
  174 + handleSuccess() {
  175 + this.getList()
  176 + },
  177 + handleSizeChange(val) {
  178 + this.page.size = val
  179 + this.getList()
  180 + },
  181 + handleCurrentChange(val) {
  182 + this.page.current = val
  183 + this.getList()
  184 + }
  185 + }
  186 +}
  187 +</script>
  188 +
  189 +<style lang="scss" scoped>
  190 +.contract-change-manage-container {
  191 + padding: 20px;
  192 +
  193 + .search-wrapper {
  194 + margin-bottom: 20px;
  195 + }
  196 +
  197 + .list-wrapper {
  198 + margin-bottom: 20px;
  199 +
  200 + .note {
  201 + margin-top: 20px;
  202 + color: #909399;
  203 + font-size: 14px;
  204 + }
  205 + }
  206 +
  207 + .el-pagination {
  208 + margin-top: 20px;
  209 + text-align: right;
  210 + }
  211 +}
  212 +</style>
0 213 \ No newline at end of file
... ...
src/views/contract/contractManageLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + contractManage: {
  4 + search: {
  5 + title: 'Search Conditions',
  6 + hide: 'Hide',
  7 + more: 'More',
  8 + search: 'Search',
  9 + reset: 'Reset'
  10 + },
  11 + list: {
  12 + title: 'Contract Information'
  13 + },
  14 + contractNamePlaceholder: 'Please enter contract name',
  15 + contractCodePlaceholder: 'Please enter contract number',
  16 + contractTypePlaceholder: 'Please select contract type',
  17 + partyBPlaceholder: 'Please enter party B',
  18 + startTimePlaceholder: 'Please enter start time',
  19 + endTimePlaceholder: 'Please enter end time',
  20 + parentContractCodePlaceholder: 'Please enter parent contract number',
  21 + fetchError: 'Failed to fetch contract data',
  22 + table: {
  23 + contractName: 'Contract Name',
  24 + contractCode: 'Contract Number',
  25 + parentContractCode: 'Parent Contract Number',
  26 + contractType: 'Contract Type',
  27 + operator: 'Operator',
  28 + amount: 'Contract Amount',
  29 + partyB: 'Party B',
  30 + validityPeriod: 'Validity Period',
  31 + createTime: 'Creation Time',
  32 + status: 'Status',
  33 + operation: 'Operation'
  34 + },
  35 + operation: {
  36 + fee: 'Fee',
  37 + view: 'View',
  38 + print: 'Print',
  39 + delete: 'Delete'
  40 + },
  41 + edit: {
  42 + title: 'Edit Contract',
  43 + contractName: 'Contract Name',
  44 + contractNamePlaceholder: 'Required, please enter contract name',
  45 + contractCode: 'Contract Number',
  46 + contractCodePlaceholder: 'Required, please enter contract number',
  47 + contractType: 'Contract Type',
  48 + contractTypePlaceholder: 'Required, please select contract type',
  49 + partyA: 'Party A',
  50 + partyAPlaceholder: 'Required, please enter party A',
  51 + aContacts: 'Party A Contact',
  52 + aContactsPlaceholder: 'Required, please enter party A contact',
  53 + aLink: 'Party A Contact Phone',
  54 + aLinkPlaceholder: 'Required, please enter party A contact phone',
  55 + partyB: 'Party B',
  56 + partyBPlaceholder: 'Required, please enter party B',
  57 + bContacts: 'Party B Contact',
  58 + bContactsPlaceholder: 'Required, please enter party B contact',
  59 + bLink: 'Party B Contact Phone',
  60 + bLinkPlaceholder: 'Required, please enter party B contact phone',
  61 + operator: 'Operator',
  62 + operatorPlaceholder: 'Required, please enter operator',
  63 + operatorLink: 'Contact Phone',
  64 + operatorLinkPlaceholder: 'Required, please enter contact phone',
  65 + amount: 'Contract Amount',
  66 + amountPlaceholder: 'Optional, please enter contract amount',
  67 + startTime: 'Start Time',
  68 + startTimePlaceholder: 'Required, please enter start time',
  69 + endTime: 'End Time',
  70 + endTimePlaceholder: 'Required, please enter end time',
  71 + signingTime: 'Signing Time',
  72 + signingTimePlaceholder: 'Required, please enter signing time',
  73 + contractFiles: 'Contract Attachments',
  74 + addFile: 'Add Attachment',
  75 + fileIndex: 'No.{index}',
  76 + deleteFile: 'Delete Attachment',
  77 + cancel: 'Cancel',
  78 + save: 'Save',
  79 + saveSuccess: 'Contract saved successfully',
  80 + saveError: 'Failed to save contract',
  81 + fileTypeError: 'Only PNG, PDF, JPG files are allowed',
  82 + uploadSuccess: 'File uploaded successfully',
  83 + uploadError: 'Failed to upload file'
  84 + },
  85 + delete: {
  86 + title: 'Confirm Operation',
  87 + confirmMessage: 'Are you sure to delete this contract?',
  88 + cancel: 'Cancel',
  89 + confirm: 'Confirm',
  90 + success: 'Contract deleted successfully',
  91 + error: 'Failed to delete contract'
  92 + }
  93 + }
  94 + },
  95 + zh: {
  96 + contractManage: {
  97 + search: {
  98 + title: '查询条件',
  99 + hide: '隐藏',
  100 + more: '更多',
  101 + search: '查询',
  102 + reset: '重置'
  103 + },
  104 + list: {
  105 + title: '合同信息'
  106 + },
  107 + contractNamePlaceholder: '请输入合同名称',
  108 + contractCodePlaceholder: '请输入合同编号',
  109 + contractTypePlaceholder: '请选择合同类型',
  110 + partyBPlaceholder: '请输入合同乙方',
  111 + startTimePlaceholder: '请输入起草开始时间',
  112 + endTimePlaceholder: '请输入起草结束时间',
  113 + parentContractCodePlaceholder: '请输入父合同编号',
  114 + fetchError: '获取合同数据失败',
  115 + table: {
  116 + contractName: '合同名称',
  117 + contractCode: '合同编号',
  118 + parentContractCode: '父合同编号',
  119 + contractType: '合同类型',
  120 + operator: '经办人',
  121 + amount: '合同金额',
  122 + partyB: '合同乙方',
  123 + validityPeriod: '有效期',
  124 + createTime: '起草时间',
  125 + status: '状态',
  126 + operation: '操作'
  127 + },
  128 + operation: {
  129 + fee: '费用',
  130 + view: '查看',
  131 + print: '打印',
  132 + delete: '删除'
  133 + },
  134 + edit: {
  135 + title: '编辑合同',
  136 + contractName: '合同名称',
  137 + contractNamePlaceholder: '必填,请填写合同名称',
  138 + contractCode: '合同编号',
  139 + contractCodePlaceholder: '必填,请填写合同编号',
  140 + contractType: '合同类型',
  141 + contractTypePlaceholder: '必填,请选择合同类型',
  142 + partyA: '甲方',
  143 + partyAPlaceholder: '必填,请填写甲方',
  144 + aContacts: '甲方联系人',
  145 + aContactsPlaceholder: '必填,请填写甲方联系人',
  146 + aLink: '甲方联系电话',
  147 + aLinkPlaceholder: '必填,请填写甲方联系电话',
  148 + partyB: '乙方',
  149 + partyBPlaceholder: '必填,请填写乙方',
  150 + bContacts: '乙方联系人',
  151 + bContactsPlaceholder: '必填,请填写乙方联系人',
  152 + bLink: '乙方联系电话',
  153 + bLinkPlaceholder: '必填,请填写乙方联系电话',
  154 + operator: '经办人',
  155 + operatorPlaceholder: '必填,请填写经办人',
  156 + operatorLink: '联系电话',
  157 + operatorLinkPlaceholder: '必填,请填写联系电话',
  158 + amount: '合同金额',
  159 + amountPlaceholder: '选填,请填写合同金额',
  160 + startTime: '开始时间',
  161 + startTimePlaceholder: '必填,请填写开始时间',
  162 + endTime: '结束时间',
  163 + endTimePlaceholder: '必填,请填写结束时间',
  164 + signingTime: '签订时间',
  165 + signingTimePlaceholder: '必填,请填写签订时间',
  166 + contractFiles: '合同附件',
  167 + addFile: '添加附件',
  168 + fileIndex: '第{index}个',
  169 + deleteFile: '删除附件',
  170 + cancel: '取消',
  171 + save: '保存',
  172 + saveSuccess: '合同保存成功',
  173 + saveError: '合同保存失败',
  174 + fileTypeError: '仅支持PNG、PDF、JPG格式文件',
  175 + uploadSuccess: '文件上传成功',
  176 + uploadError: '文件上传失败'
  177 + },
  178 + delete: {
  179 + title: '请确认您的操作',
  180 + confirmMessage: '确定删除合同信息',
  181 + cancel: '点错了',
  182 + confirm: '确认删除',
  183 + success: '合同删除成功',
  184 + error: '合同删除失败'
  185 + }
  186 + }
  187 + }
  188 +}
0 189 \ No newline at end of file
... ...
src/views/contract/contractManageList.vue 0 → 100644
  1 +<template>
  2 + <div class="contract-manage-container">
  3 + <!-- 查询条件 -->
  4 + <el-card class="search-card">
  5 + <div slot="header" class="flex justify-between">
  6 + <span>{{ $t('contractManage.search.title') }}</span>
  7 + <el-button type="text" style="float: right; padding: 3px 0" @click="toggleMoreCondition">
  8 + {{ contractManageInfo.moreCondition ? $t('common.hide') : $t('common.more') }}
  9 + </el-button>
  10 + </div>
  11 + <el-row :gutter="20">
  12 + <el-col :span="6">
  13 + <el-input v-model="contractManageInfo.conditions.contractNameLike"
  14 + :placeholder="$t('contractManage.contractNamePlaceholder')" clearable />
  15 + </el-col>
  16 + <el-col :span="8">
  17 + <el-input v-model="contractManageInfo.conditions.contractCodeLike"
  18 + :placeholder="$t('contractManage.contractCodePlaceholder')" clearable />
  19 + </el-col>
  20 + <el-col :span="6">
  21 + <el-select v-model="contractManageInfo.conditions.contractType"
  22 + :placeholder="$t('contractManage.contractTypePlaceholder')" style="width:100%">
  23 + <el-option v-for="item in contractManageInfo.contractTypes" :key="item.contractTypeId" :label="item.typeName"
  24 + :value="item.contractTypeId" />
  25 + </el-select>
  26 + </el-col>
  27 + <el-col :span="4">
  28 + <el-button type="primary" @click="queryContractMethod">
  29 + <i class="el-icon-search"></i>
  30 + {{ $t('common.search') }}
  31 + </el-button>
  32 + <el-button @click="resetContractMethod">
  33 + <i class="el-icon-refresh"></i>
  34 + {{ $t('common.reset') }}
  35 + </el-button>
  36 + </el-col>
  37 + </el-row>
  38 +
  39 + <el-row v-show="contractManageInfo.moreCondition" :gutter="20" style="margin-top:20px">
  40 + <el-col :span="6">
  41 + <el-input v-model="contractManageInfo.conditions.partyBLike"
  42 + :placeholder="$t('contractManage.partyBPlaceholder')" clearable />
  43 + </el-col>
  44 + <el-col :span="8">
  45 + <el-date-picker v-model="contractManageInfo.conditions.queryStartTime" type="datetime"
  46 + :placeholder="$t('contractManage.startTimePlaceholder')" style="width:100%" />
  47 + </el-col>
  48 + <el-col :span="6">
  49 + <el-date-picker v-model="contractManageInfo.conditions.queryEndTime" type="datetime"
  50 + :placeholder="$t('contractManage.endTimePlaceholder')" style="width:100%" />
  51 + </el-col>
  52 + </el-row>
  53 +
  54 + <el-row v-show="contractManageInfo.moreCondition" :gutter="20" style="margin-top:20px">
  55 + <el-col :span="6">
  56 + <el-input v-model="contractManageInfo.conditions.parentContractCodeLike"
  57 + :placeholder="$t('contractManage.parentContractCodePlaceholder')" clearable />
  58 + </el-col>
  59 + </el-row>
  60 + </el-card>
  61 +
  62 + <!-- 合同列表 -->
  63 + <el-card class="list-card">
  64 + <div slot="header" class="flex justify-between">
  65 + <span>{{ $t('contractManage.list.title') }}</span>
  66 + </div>
  67 +
  68 + <el-table :data="contractManageInfo.contracts" border style="width: 100%" v-loading="loading">
  69 + <el-table-column prop="contractName" :label="$t('contractManage.table.contractName')" align="center" />
  70 + <el-table-column prop="contractCode" :label="$t('contractManage.table.contractCode')" align="center" />
  71 + <el-table-column prop="parentContractCode" :label="$t('contractManage.table.parentContractCode')" align="center">
  72 + <template slot-scope="scope">
  73 + {{ scope.row.parentContractCode || '-' }}
  74 + </template>
  75 + </el-table-column>
  76 + <el-table-column prop="contractTypeName" :label="$t('contractManage.table.contractType')" align="center" />
  77 + <el-table-column prop="operator" :label="$t('contractManage.table.operator')" align="center">
  78 + <template slot-scope="scope">
  79 + {{ scope.row.operator }}({{ scope.row.operatorLink }})
  80 + </template>
  81 + </el-table-column>
  82 + <el-table-column prop="amount" :label="$t('contractManage.table.amount')" align="center" />
  83 + <el-table-column prop="partyB" :label="$t('contractManage.table.partyB')" align="center">
  84 + <template slot-scope="scope">
  85 + {{ scope.row.partyB }}({{ scope.row.bLink }})
  86 + </template>
  87 + </el-table-column>
  88 + <el-table-column :label="$t('contractManage.table.validityPeriod')" align="center">
  89 + <template slot-scope="scope">
  90 + {{ scope.row.startTime }}<br />~{{ scope.row.endTime }}
  91 + </template>
  92 + </el-table-column>
  93 + <el-table-column prop="createTime" :label="$t('contractManage.table.createTime')" align="center" />
  94 + <el-table-column prop="stateName" :label="$t('contractManage.table.status')" align="center" />
  95 + <el-table-column :label="$t('contractManage.table.operation')" align="center" width="220">
  96 + <template slot-scope="scope">
  97 + <el-button-group>
  98 + <el-button size="mini" @click="openContractFee(scope.row)">
  99 + {{ $t('contractManage.operation.fee') }}
  100 + </el-button>
  101 + <el-button size="mini" @click="viewContract(scope.row)">
  102 + {{ $t('contractManage.operation.view') }}
  103 + </el-button>
  104 + <el-button size="mini" @click="printContract(scope.row)">
  105 + {{ $t('contractManage.operation.print') }}
  106 + </el-button>
  107 + <el-button size="mini" type="danger" @click="openDeleteContractModel(scope.row)">
  108 + {{ $t('contractManage.operation.delete') }}
  109 + </el-button>
  110 + </el-button-group>
  111 + </template>
  112 + </el-table-column>
  113 + </el-table>
  114 +
  115 + <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="page.current"
  116 + :page-sizes="[10, 20, 30, 50]" :page-size="page.size" layout="total, sizes, prev, pager, next, jumper"
  117 + :total="page.total" style="margin-top:20px;text-align:right" />
  118 + </el-card>
  119 +
  120 + <!-- 子组件 -->
  121 + <edit-contract ref="editContract" @success="handleSuccess" />
  122 + <delete-contract ref="deleteContract" @success="handleSuccess" />
  123 + </div>
  124 +</template>
  125 +
  126 +<script>
  127 +import { queryContract, queryContractType } from '@/api/contract/contractManageApi'
  128 +import EditContract from '@/components/contract/editContract'
  129 +import DeleteContract from '@/components/contract/deleteContract'
  130 +
  131 +export default {
  132 + name: 'ContractManageList',
  133 + components: {
  134 + EditContract,
  135 + DeleteContract
  136 + },
  137 + data() {
  138 + return {
  139 + loading: false,
  140 + contractManageInfo: {
  141 + contracts: [],
  142 + moreCondition: false,
  143 + conditions: {
  144 + contractNameLike: '',
  145 + contractCodeLike: '',
  146 + contractType: '',
  147 + partyBLike: '',
  148 + queryStartTime: '',
  149 + queryEndTime: '',
  150 + parentContractCodeLike: ''
  151 + },
  152 + contractTypes: []
  153 + },
  154 + page: {
  155 + current: 1,
  156 + size: 10,
  157 + total: 0
  158 + }
  159 + }
  160 + },
  161 + created() {
  162 + this.listContracts()
  163 + this.listContractTypes()
  164 + },
  165 + methods: {
  166 + async listContracts() {
  167 + try {
  168 + this.loading = true
  169 + const params = {
  170 + page: this.page.current,
  171 + row: this.page.size,
  172 + ...this.contractManageInfo.conditions
  173 + }
  174 + const { data, total } = await queryContract(params)
  175 + this.contractManageInfo.contracts = data
  176 + this.page.total = total
  177 + } catch (error) {
  178 + this.$message.error(this.$t('contractManage.fetchError'))
  179 + } finally {
  180 + this.loading = false
  181 + }
  182 + },
  183 + async listContractTypes() {
  184 + try {
  185 + const params = {
  186 + page: 1,
  187 + row: 50
  188 + }
  189 + const { data } = await queryContractType(params)
  190 + this.contractManageInfo.contractTypes = data
  191 + } catch (error) {
  192 + console.error('获取合同类型失败:', error)
  193 + }
  194 + },
  195 + toggleMoreCondition() {
  196 + this.contractManageInfo.moreCondition = !this.contractManageInfo.moreCondition
  197 + },
  198 + queryContractMethod() {
  199 + this.page.current = 1
  200 + this.listContracts()
  201 + },
  202 + resetContractMethod() {
  203 + this.contractManageInfo.conditions = {
  204 + contractNameLike: '',
  205 + contractCodeLike: '',
  206 + contractType: '',
  207 + partyBLike: '',
  208 + queryStartTime: '',
  209 + queryEndTime: '',
  210 + parentContractCodeLike: ''
  211 + }
  212 + this.listContracts()
  213 + },
  214 + handleSizeChange(val) {
  215 + this.page.size = val
  216 + this.listContracts()
  217 + },
  218 + handleCurrentChange(val) {
  219 + this.page.current = val
  220 + this.listContracts()
  221 + },
  222 + openContractFee(contract) {
  223 + this.$router.push({
  224 + path: '/property/listContractFee',
  225 + query: {
  226 + contractId: contract.contractId,
  227 + contractCode: contract.contractCode
  228 + }
  229 + })
  230 + },
  231 + viewContract(contract) {
  232 + this.$router.push({
  233 + path: '/contract/contractDetail',
  234 + query: {
  235 + contractId: contract.contractId
  236 + }
  237 + })
  238 + },
  239 + printContract(contract) {
  240 + window.open(`/#/views/contract/printContract?contractTypeId=${contract.contractType}&contractId=${contract.contractId}`)
  241 + },
  242 + openDeleteContractModel(contract) {
  243 + this.$refs.deleteContract.open(contract)
  244 + },
  245 + handleSuccess() {
  246 + this.listContracts()
  247 + }
  248 + }
  249 +}
  250 +</script>
  251 +
  252 +<style lang="scss" scoped>
  253 +.contract-manage-container {
  254 + padding: 20px;
  255 +
  256 + .search-card {
  257 + margin-bottom: 20px;
  258 + }
  259 +
  260 + .list-card {
  261 + margin-bottom: 20px;
  262 + }
  263 +}
  264 +</style>
0 265 \ No newline at end of file
... ...
src/views/contract/contractPartyaManageLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + contractPartyaManage: {
  4 + search: {
  5 + title: 'Search Conditions',
  6 + partyA: 'Party A',
  7 + aContacts: 'Party A Contact',
  8 + aLink: 'Contact Phone'
  9 + },
  10 + list: {
  11 + title: 'Contract Party A'
  12 + },
  13 + table: {
  14 + partyA: 'Party A',
  15 + aContacts: 'Party A Contact',
  16 + aLink: 'Contact Phone'
  17 + },
  18 + form: {
  19 + partyA: 'Party A',
  20 + partyAPlaceholder: 'Please enter Party A',
  21 + aContacts: 'Party A Contact',
  22 + aContactsPlaceholder: 'Please enter Party A Contact',
  23 + aLink: 'Contact Phone',
  24 + aLinkPlaceholder: 'Please enter Contact Phone'
  25 + },
  26 + validate: {
  27 + partyARequired: 'Party A is required',
  28 + partyAMaxLength: 'Party A is too long',
  29 + aContactsRequired: 'Party A Contact is required',
  30 + aContactsMaxLength: 'Party A Contact cannot exceed 64 characters',
  31 + aLinkRequired: 'Contact Phone is required',
  32 + aLinkFormat: 'Invalid Contact Phone format',
  33 + partyaIdRequired: 'Party A ID is required'
  34 + },
  35 + add: {
  36 + title: 'Add Party A'
  37 + },
  38 + edit: {
  39 + title: 'Edit Party A'
  40 + },
  41 + delete: {
  42 + title: 'Confirm Operation',
  43 + confirmText: 'Are you sure to delete this Party A?'
  44 + },
  45 + fetchError: 'Failed to fetch Party A data'
  46 + }
  47 + },
  48 + zh: {
  49 + contractPartyaManage: {
  50 + search: {
  51 + title: '查询条件',
  52 + partyA: '甲方',
  53 + aContacts: '甲方联系人',
  54 + aLink: '联系电话'
  55 + },
  56 + list: {
  57 + title: '合同甲方'
  58 + },
  59 + table: {
  60 + partyA: '甲方',
  61 + aContacts: '甲方联系人',
  62 + aLink: '联系电话'
  63 + },
  64 + form: {
  65 + partyA: '甲方',
  66 + partyAPlaceholder: '请输入甲方',
  67 + aContacts: '甲方联系人',
  68 + aContactsPlaceholder: '请输入甲方联系人',
  69 + aLink: '联系电话',
  70 + aLinkPlaceholder: '请输入联系电话'
  71 + },
  72 + validate: {
  73 + partyARequired: '甲方不能为空',
  74 + partyAMaxLength: '甲方太长',
  75 + aContactsRequired: '甲方联系人不能为空',
  76 + aContactsMaxLength: '甲方联系人不能超过64个字符',
  77 + aLinkRequired: '联系电话不能为空',
  78 + aLinkFormat: '联系电话格式错误',
  79 + partyaIdRequired: '甲方编号不能为空'
  80 + },
  81 + add: {
  82 + title: '添加甲方'
  83 + },
  84 + edit: {
  85 + title: '修改甲方'
  86 + },
  87 + delete: {
  88 + title: '请确认您的操作',
  89 + confirmText: '确定删除合同甲方吗?'
  90 + },
  91 + fetchError: '获取甲方数据失败'
  92 + }
  93 + }
  94 +}
0 95 \ No newline at end of file
... ...
src/views/contract/contractPartyaManageList.vue 0 → 100644
  1 +<template>
  2 + <div class="contract-partya-manage-container">
  3 + <el-row :gutter="20">
  4 + <el-col :span="24">
  5 + <el-card>
  6 + <div slot="header" class="flex justify-between">
  7 + <span>{{ $t('contractPartyaManage.search.title') }}</span>
  8 + </div>
  9 + <el-form :inline="true" :model="searchForm" class="search-form text-left">
  10 + <el-form-item>
  11 + <el-input v-model="searchForm.partyA" :placeholder="$t('contractPartyaManage.search.partyA')" clearable />
  12 + </el-form-item>
  13 + <el-form-item>
  14 + <el-input v-model="searchForm.aContacts" :placeholder="$t('contractPartyaManage.search.aContacts')"
  15 + clearable />
  16 + </el-form-item>
  17 + <el-form-item>
  18 + <el-input v-model="searchForm.aLink" :placeholder="$t('contractPartyaManage.search.aLink')" clearable />
  19 + </el-form-item>
  20 + <el-form-item>
  21 + <el-button type="primary" @click="handleSearch">
  22 + {{ $t('common.search') }}
  23 + </el-button>
  24 + <el-button @click="handleReset">
  25 + {{ $t('common.reset') }}
  26 + </el-button>
  27 + </el-form-item>
  28 + </el-form>
  29 + </el-card>
  30 + </el-col>
  31 + </el-row>
  32 +
  33 + <el-row :gutter="20" >
  34 + <el-col :span="24">
  35 + <el-card>
  36 + <div slot="header" class="flex justify-between">
  37 + <span>{{ $t('contractPartyaManage.list.title') }}</span>
  38 + <el-button type="primary" size="small" style="float: right;" @click="handleAdd">
  39 + {{ $t('common.add') }}
  40 + </el-button>
  41 + </div>
  42 + <el-table v-loading="loading" :data="tableData" border style="width: 100%">
  43 + <el-table-column prop="partyA" :label="$t('contractPartyaManage.table.partyA')" align="center" />
  44 + <el-table-column prop="aContacts" :label="$t('contractPartyaManage.table.aContacts')" align="center" />
  45 + <el-table-column prop="aLink" :label="$t('contractPartyaManage.table.aLink')" align="center" />
  46 + <el-table-column :label="$t('common.operation')" align="center" width="200">
  47 + <template slot-scope="scope">
  48 + <el-button size="mini" type="primary" @click="handleEdit(scope.row)">
  49 + {{ $t('common.edit') }}
  50 + </el-button>
  51 + <el-button size="mini" type="danger" @click="handleDelete(scope.row)">
  52 + {{ $t('common.delete') }}
  53 + </el-button>
  54 + </template>
  55 + </el-table-column>
  56 + </el-table>
  57 + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size"
  58 + :total="page.total" layout="total, sizes, prev, pager, next, jumper" style="margin-top: 20px;"
  59 + @size-change="handleSizeChange" @current-change="handleCurrentChange" />
  60 + </el-card>
  61 + </el-col>
  62 + </el-row>
  63 +
  64 + <add-contract-partya ref="addContractPartya" @success="handleSuccess" />
  65 + <edit-contract-partya ref="editContractPartya" @success="handleSuccess" />
  66 + <delete-contract-partya ref="deleteContractPartya" @success="handleSuccess" />
  67 + </div>
  68 +</template>
  69 +
  70 +<script>
  71 +import { queryContractPartya } from '@/api/contract/contractPartyaManageApi'
  72 +import AddContractPartya from '@/components/contract/addContractPartya'
  73 +import EditContractPartya from '@/components/contract/editContractPartya'
  74 +import DeleteContractPartya from '@/components/contract/deleteContractPartya'
  75 +import { getCommunityId } from '@/api/community/communityApi'
  76 +
  77 +export default {
  78 + name: 'ContractPartyaManageList',
  79 + components: {
  80 + AddContractPartya,
  81 + EditContractPartya,
  82 + DeleteContractPartya
  83 + },
  84 + data() {
  85 + return {
  86 + loading: false,
  87 + searchForm: {
  88 + partyA: '',
  89 + aContacts: '',
  90 + aLink: ''
  91 + },
  92 + tableData: [],
  93 + page: {
  94 + current: 1,
  95 + size: 10,
  96 + total: 0
  97 + },
  98 + communityId: ''
  99 + }
  100 + },
  101 + created() {
  102 + this.communityId = getCommunityId()
  103 + this.getList()
  104 + },
  105 + methods: {
  106 + async getList() {
  107 + try {
  108 + this.loading = true
  109 + const params = {
  110 + page: this.page.current,
  111 + row: this.page.size,
  112 + partyA: this.searchForm.partyA,
  113 + aContacts: this.searchForm.aContacts,
  114 + aLink: this.searchForm.aLink,
  115 + communityId: this.communityId
  116 + }
  117 + const { data, total } = await queryContractPartya(params)
  118 + this.tableData = data
  119 + this.page.total = total
  120 + } catch (error) {
  121 + this.$message.error(this.$t('contractPartyaManage.fetchError'))
  122 + } finally {
  123 + this.loading = false
  124 + }
  125 + },
  126 + handleSearch() {
  127 + this.page.current = 1
  128 + this.getList()
  129 + },
  130 + handleReset() {
  131 + this.searchForm = {
  132 + partyA: '',
  133 + aContacts: '',
  134 + aLink: ''
  135 + }
  136 + this.handleSearch()
  137 + },
  138 + handleAdd() {
  139 + this.$refs.addContractPartya.open()
  140 + },
  141 + handleEdit(row) {
  142 + this.$refs.editContractPartya.open(row)
  143 + },
  144 + handleDelete(row) {
  145 + this.$refs.deleteContractPartya.open(row)
  146 + },
  147 + handleSuccess() {
  148 + this.getList()
  149 + },
  150 + handleSizeChange(val) {
  151 + this.page.size = val
  152 + this.getList()
  153 + },
  154 + handleCurrentChange(val) {
  155 + this.page.current = val
  156 + this.getList()
  157 + }
  158 + }
  159 +}
  160 +</script>
  161 +
  162 +<style lang="scss" scoped>
  163 +.contract-partya-manage-container {
  164 + padding: 20px;
  165 +
  166 + .search-form {
  167 + .el-form-item {
  168 + margin-bottom: 0;
  169 + }
  170 + }
  171 +
  172 + .el-card {
  173 + margin-bottom: 20px;
  174 + }
  175 +}
  176 +</style>
0 177 \ No newline at end of file
... ...
src/views/contract/contractTypeManageLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + contractTypeManage: {
  4 + search: {
  5 + title: 'Search Conditions',
  6 + typeNamePlaceholder: 'Please enter type name',
  7 + auditPlaceholder: 'Please select audit status'
  8 + },
  9 + list: {
  10 + title: 'Contract Types',
  11 + setAudit: 'Set Auditor'
  12 + },
  13 + table: {
  14 + typeName: 'Type Name',
  15 + audit: 'Audit Status',
  16 + remark: 'Description',
  17 + createTime: 'Create Time',
  18 + specInfo: 'Spec Info',
  19 + template: 'Template'
  20 + },
  21 + add: {
  22 + title: 'Add Contract Type',
  23 + typeName: 'Type Name',
  24 + typeNamePlaceholder: 'Required, please enter type name',
  25 + audit: 'Audit Status',
  26 + auditPlaceholder: 'Please select audit status',
  27 + remark: 'Description',
  28 + remarkPlaceholder: 'Optional, please enter description'
  29 + },
  30 + edit: {
  31 + title: 'Edit Contract Type',
  32 + typeName: 'Type Name',
  33 + typeNamePlaceholder: 'Required, please enter type name',
  34 + audit: 'Audit Status',
  35 + auditPlaceholder: 'Please select audit status',
  36 + remark: 'Description',
  37 + remarkPlaceholder: 'Optional, please enter description'
  38 + },
  39 + delete: {
  40 + title: 'Confirm Operation',
  41 + confirmText: 'Are you sure to delete this contract type?'
  42 + },
  43 + template: {
  44 + title: 'Contract Template',
  45 + content: 'Template Content',
  46 + placeholder: 'Required, please enter contract template'
  47 + },
  48 + validate: {
  49 + contractTypeIdRequired: 'Contract type ID is required',
  50 + typeNameRequired: 'Type name is required',
  51 + typeNameMaxLength: 'Type name cannot exceed 64 characters',
  52 + auditRequired: 'Audit status is required',
  53 + remarkMaxLength: 'Description cannot exceed 200 characters',
  54 + contentRequired: 'Template content is required',
  55 + contractTypeRequired: 'Contract type is required'
  56 + },
  57 + fetchError: 'Failed to fetch contract types'
  58 + }
  59 + },
  60 + zh: {
  61 + contractTypeManage: {
  62 + search: {
  63 + title: '查询条件',
  64 + typeNamePlaceholder: '请输入类型名称',
  65 + auditPlaceholder: '请选择审核状态'
  66 + },
  67 + list: {
  68 + title: '合同类型',
  69 + setAudit: '设置审核人员'
  70 + },
  71 + table: {
  72 + typeName: '类型名称',
  73 + audit: '是否审核',
  74 + remark: '描述',
  75 + createTime: '创建时间',
  76 + specInfo: '扩展信息',
  77 + template: '合同模板'
  78 + },
  79 + add: {
  80 + title: '添加合同类型',
  81 + typeName: '类型名称',
  82 + typeNamePlaceholder: '必填,请填写类型名称',
  83 + audit: '是否审核',
  84 + auditPlaceholder: '请选择审核状态',
  85 + remark: '描述',
  86 + remarkPlaceholder: '选填,请填写描述'
  87 + },
  88 + edit: {
  89 + title: '修改合同类型',
  90 + typeName: '类型名称',
  91 + typeNamePlaceholder: '必填,请填写类型名称',
  92 + audit: '是否审核',
  93 + auditPlaceholder: '请选择审核状态',
  94 + remark: '描述',
  95 + remarkPlaceholder: '选填,请填写描述'
  96 + },
  97 + delete: {
  98 + title: '请确认您的操作',
  99 + confirmText: '确定删除该合同类型吗?'
  100 + },
  101 + template: {
  102 + title: '合同模板',
  103 + content: '模板内容',
  104 + placeholder: '必填,请输入合同模板'
  105 + },
  106 + validate: {
  107 + contractTypeIdRequired: '合同类型ID不能为空',
  108 + typeNameRequired: '类型名称不能为空',
  109 + typeNameMaxLength: '类型名称不能超过64个字符',
  110 + auditRequired: '审核状态不能为空',
  111 + remarkMaxLength: '描述不能超过200个字符',
  112 + contentRequired: '模板内容必填',
  113 + contractTypeRequired: '合同类型不能为空'
  114 + },
  115 + fetchError: '获取合同类型失败'
  116 + }
  117 + }
  118 +}
0 119 \ No newline at end of file
... ...
src/views/contract/contractTypeManageList.vue 0 → 100644
  1 +<template>
  2 + <div class="contract-type-manage-container">
  3 + <!-- 查询条件 -->
  4 + <el-card class="search-card">
  5 + <div slot="header" class="flex justify-between">
  6 + <span>{{ $t('contractTypeManage.search.title') }}</span>
  7 + </div>
  8 + <el-row :gutter="20">
  9 + <el-col :span="6">
  10 + <el-input v-model="conditions.typeName" :placeholder="$t('contractTypeManage.search.typeNamePlaceholder')"
  11 + clearable />
  12 + </el-col>
  13 + <el-col :span="6">
  14 + <el-select v-model="conditions.audit" :placeholder="$t('contractTypeManage.search.auditPlaceholder')"
  15 + style="width:100%">
  16 + <el-option v-for="item in audits" :key="item.statusCd" :label="item.name" :value="item.statusCd" />
  17 + </el-select>
  18 + </el-col>
  19 + <el-col :span="4">
  20 + <el-button type="primary" @click="_queryContractTypeMethod">
  21 + <i class="el-icon-search"></i>
  22 + {{ $t('common.search') }}
  23 + </el-button>
  24 + <el-button @click="_resetContractTypeMethod">
  25 + <i class="el-icon-refresh"></i>
  26 + {{ $t('common.reset') }}
  27 + </el-button>
  28 + </el-col>
  29 + </el-row>
  30 + </el-card>
  31 +
  32 + <!-- 合同类型列表 -->
  33 + <el-card class="list-card">
  34 + <div slot="header" class="flex justify-between">
  35 + <span>{{ $t('contractTypeManage.list.title') }}</span>
  36 + <div style="float: right;">
  37 + <el-button v-if="hasPrivilege('502020061767630003')" type="primary" size="small" @click="_toAuditPage">
  38 + <i class="el-icon-setting"></i>
  39 + {{ $t('contractTypeManage.list.setAudit') }}
  40 + </el-button>
  41 + <el-button type="primary" size="small" @click="_openAddContractTypeModal">
  42 + <i class="el-icon-plus"></i>
  43 + {{ $t('common.add') }}
  44 + </el-button>
  45 + </div>
  46 + </div>
  47 +
  48 + <el-table :data="contractTypes" border style="width: 100%">
  49 + <el-table-column prop="typeName" :label="$t('contractTypeManage.table.typeName')" align="center" />
  50 + <el-table-column prop="auditName" :label="$t('contractTypeManage.table.audit')" align="center" />
  51 + <el-table-column prop="remark" :label="$t('contractTypeManage.table.remark')" align="center" />
  52 + <el-table-column prop="createTime" :label="$t('contractTypeManage.table.createTime')" align="center" />
  53 + <el-table-column :label="$t('common.operation')" align="center" width="300">
  54 + <template slot-scope="scope">
  55 + <el-button size="mini" @click="_openContractTypeSpecModel(scope.row)">
  56 + {{ $t('contractTypeManage.table.specInfo') }}
  57 + </el-button>
  58 + <el-button size="mini" @click="_openContractTemplate(scope.row)">
  59 + {{ $t('contractTypeManage.table.template') }}
  60 + </el-button>
  61 + <el-button size="mini" type="primary" @click="_openEditContractTypeModel(scope.row)">
  62 + {{ $t('common.edit') }}
  63 + </el-button>
  64 + <el-button size="mini" type="danger" @click="_openDeleteContractTypeModel(scope.row)">
  65 + {{ $t('common.delete') }}
  66 + </el-button>
  67 + </template>
  68 + </el-table-column>
  69 + </el-table>
  70 +
  71 + <el-pagination :current-page.sync="page.current" :page-sizes="[10, 20, 30, 50]" :page-size="page.size"
  72 + :total="page.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
  73 + @current-change="handleCurrentChange" />
  74 + </el-card>
  75 +
  76 + <!-- 子组件 -->
  77 + <add-template-view ref="addTemplateView" @success="handleSuccess" />
  78 + <add-contract-type ref="addContractType" @success="handleSuccess" />
  79 + <edit-contract-type ref="editContractType" @success="handleSuccess" />
  80 + <delete-contract-type ref="deleteContractType" @success="handleSuccess" />
  81 + </div>
  82 +</template>
  83 +
  84 +<script>
  85 +import { getDict } from '@/api/community/communityApi'
  86 +import { getCommunityId } from '@/api/community/communityApi'
  87 +import {
  88 + queryContractType,
  89 + //queryContractTypeTemplate,
  90 +
  91 +} from '@/api/contract/contractTypeManageApi'
  92 +import AddTemplateView from '@/components/contract/addTemplateView'
  93 +import AddContractType from '@/components/contract/addContractType'
  94 +import EditContractType from '@/components/contract/editContractType'
  95 +import DeleteContractType from '@/components/contract/deleteContractType'
  96 +
  97 +export default {
  98 + name: 'ContractTypeManageList',
  99 + components: {
  100 + AddTemplateView,
  101 + AddContractType,
  102 + EditContractType,
  103 + DeleteContractType
  104 + },
  105 + data() {
  106 + return {
  107 + componentShow: 'contractTypeList',
  108 + contractTypes: [],
  109 + contractTypeAttrs: [],
  110 + contractTypeSpec: '',
  111 + templatecontent: '',
  112 + audits: [],
  113 + conditions: {
  114 + typeName: '',
  115 + audit: '',
  116 + contractTypeId: ''
  117 + },
  118 + page: {
  119 + current: 1,
  120 + size: 10,
  121 + total: 0
  122 + },
  123 + communityId: ''
  124 + }
  125 + },
  126 + created() {
  127 + this.communityId = getCommunityId()
  128 + this._initData()
  129 + },
  130 + methods: {
  131 + async _initData() {
  132 + try {
  133 + const auditData = await getDict('contract_type', 'audit')
  134 + this.audits = auditData
  135 + this._listContractTypes(this.page.current, this.page.size)
  136 + } catch (error) {
  137 + console.error('初始化数据失败:', error)
  138 + }
  139 + },
  140 + async _listContractTypes(page, size) {
  141 + try {
  142 + const params = {
  143 + page,
  144 + row: size,
  145 + typeName: this.conditions.typeName.trim(),
  146 + audit: this.conditions.audit.trim(),
  147 + communityId: this.communityId
  148 + }
  149 + const { data, total } = await queryContractType(params)
  150 + this.contractTypes = data
  151 + this.page.total = total
  152 + } catch (error) {
  153 + this.$message.error(this.$t('contractTypeManage.fetchError'))
  154 + }
  155 + },
  156 + _queryContractTypeMethod() {
  157 + this.page.current = 1
  158 + this._listContractTypes(this.page.current, this.page.size)
  159 + },
  160 + _resetContractTypeMethod() {
  161 + this.conditions = {
  162 + typeName: '',
  163 + audit: '',
  164 + contractTypeId: ''
  165 + }
  166 + this._listContractTypes(this.page.current, this.page.size)
  167 + },
  168 + _openAddContractTypeModal() {
  169 +
  170 + this.$refs.addContractType.open()
  171 + },
  172 + _openEditContractTypeModel(row) {
  173 + this.$refs.editContractType.open(row)
  174 + },
  175 + _openDeleteContractTypeModel(row) {
  176 + this.$refs.deleteContractType.open(row)
  177 + },
  178 + _openContractTypeSpecModel(row) {
  179 + this.$router.push(`/views/contract/contractTypeSpecManage?contractTypeId=${row.contractTypeId}`)
  180 + },
  181 + _toAuditPage() {
  182 + this.$router.push('/admin/workflowManage?tab=流程管理')
  183 + },
  184 +
  185 + _openContractTemplate(row) {
  186 + this.componentShow = ''
  187 + this.$refs.addTemplateView.open(row)
  188 +
  189 + },
  190 + handleSizeChange(val) {
  191 + this.page.size = val
  192 + this._listContractTypes(this.page.current, this.page.size)
  193 + },
  194 + handleCurrentChange(val) {
  195 + this.page.current = val
  196 + this._listContractTypes(this.page.current, this.page.size)
  197 + },
  198 + handleSuccess() {
  199 + this._listContractTypes(this.page.current, this.page.size)
  200 + }
  201 + }
  202 +}
  203 +</script>
  204 +
  205 +<style lang="scss" scoped>
  206 +.contract-type-manage-container {
  207 + padding: 20px;
  208 +
  209 + .search-card {
  210 + margin-bottom: 20px;
  211 + }
  212 +
  213 + .list-card {
  214 + margin-bottom: 20px;
  215 + }
  216 +
  217 + .el-pagination {
  218 + margin-top: 20px;
  219 + text-align: right;
  220 + }
  221 +}
  222 +</style>
0 223 \ No newline at end of file
... ...
src/views/contract/contractTypeSpecManageLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + contractTypeSpecManage: {
  4 + search: {
  5 + title: 'Search Conditions',
  6 + specCd: 'Spec ID',
  7 + specName: 'Spec Name',
  8 + specShow: 'Spec Display',
  9 + all: 'All',
  10 + yes: 'Yes',
  11 + no: 'No'
  12 + },
  13 + table: {
  14 + title: 'Contract Extension Information',
  15 + specCd: 'Spec ID',
  16 + specName: 'Spec Name',
  17 + required: 'Required',
  18 + specShow: 'Display',
  19 + specValueType: 'Value Type',
  20 + specType: 'Spec Type',
  21 + listShow: 'Query Display',
  22 + operation: 'Operation'
  23 + },
  24 + add: {
  25 + title: 'Add',
  26 + specName: 'Spec Name',
  27 + specNamePlaceholder: 'Required, please enter spec name',
  28 + specHoldplace: 'Description',
  29 + specHoldplacePlaceholder: 'Optional, please enter description',
  30 + required: 'Required',
  31 + requiredPlaceholder: 'Required, please select required',
  32 + specShow: 'Display',
  33 + specShowPlaceholder: 'Required, please select display',
  34 + specValueType: 'Value Type',
  35 + specValueTypePlaceholder: 'Required, please select value type',
  36 + specType: 'Spec Type',
  37 + specTypePlaceholder: 'Required, please select spec type',
  38 + listShow: 'Query Display',
  39 + listShowPlaceholder: 'Required, please select query display',
  40 + success: 'Add successfully',
  41 + error: 'Add failed'
  42 + },
  43 + edit: {
  44 + title: 'Edit',
  45 + specName: 'Spec Name',
  46 + specNamePlaceholder: 'Required, please enter spec name',
  47 + specHoldplace: 'Description',
  48 + specHoldplacePlaceholder: 'Optional, please enter description',
  49 + required: 'Required',
  50 + requiredPlaceholder: 'Required, please select required',
  51 + specShow: 'Display',
  52 + specShowPlaceholder: 'Required, please select display',
  53 + specValueType: 'Value Type',
  54 + specValueTypePlaceholder: 'Required, please select value type',
  55 + specType: 'Spec Type',
  56 + specTypePlaceholder: 'Required, please select spec type',
  57 + listShow: 'Query Display',
  58 + listShowPlaceholder: 'Required, please select query display',
  59 + success: 'Edit successfully',
  60 + error: 'Edit failed'
  61 + },
  62 + delete: {
  63 + title: 'Confirm Operation',
  64 + confirmText: 'Are you sure to delete this contract type spec?',
  65 + success: 'Delete successfully',
  66 + error: 'Delete failed'
  67 + },
  68 + specValueType: {
  69 + string: 'String',
  70 + integer: 'Integer',
  71 + amount: 'Amount',
  72 + date: 'Date',
  73 + time: 'Time'
  74 + },
  75 + specType: {
  76 + input: 'Input',
  77 + select: 'Select'
  78 + },
  79 + validate: {
  80 + specNameRequired: 'Spec name is required',
  81 + specNameMaxLength: 'Spec name is too long',
  82 + specHoldplaceMaxLength: 'Description is too long',
  83 + requiredRequired: 'Required is required',
  84 + specShowRequired: 'Display is required',
  85 + specValueTypeRequired: 'Value type is required',
  86 + specTypeRequired: 'Spec type is required',
  87 + listShowRequired: 'Query display is required',
  88 + specCdRequired: 'Spec is required'
  89 + },
  90 + fetchError: 'Failed to fetch data'
  91 + }
  92 + },
  93 + zh: {
  94 + contractTypeSpecManage: {
  95 + search: {
  96 + title: '查询条件',
  97 + specCd: '规格ID',
  98 + specName: '规格名称',
  99 + specShow: '规格是否显示',
  100 + all: '全部',
  101 + yes: '是',
  102 + no: '否'
  103 + },
  104 + table: {
  105 + title: '合同扩展信息',
  106 + specCd: '规格ID',
  107 + specName: '规格名称',
  108 + required: '必填',
  109 + specShow: '规格是否展示',
  110 + specValueType: '值类型',
  111 + specType: '规格类型',
  112 + listShow: '查询显示',
  113 + operation: '操作'
  114 + },
  115 + add: {
  116 + title: '添加',
  117 + specName: '规格名称',
  118 + specNamePlaceholder: '必填,请填写规格名称',
  119 + specHoldplace: '说明',
  120 + specHoldplacePlaceholder: '选填,请填写说明',
  121 + required: '必填',
  122 + requiredPlaceholder: '必填,请选择必填',
  123 + specShow: '展示',
  124 + specShowPlaceholder: '必填,请选择展示',
  125 + specValueType: '值类型',
  126 + specValueTypePlaceholder: '必填,请选择值类型',
  127 + specType: '规格类型',
  128 + specTypePlaceholder: '必填,请选择规格类型',
  129 + listShow: '查询显示',
  130 + listShowPlaceholder: '必填,请选择查询显示',
  131 + success: '添加成功',
  132 + error: '添加失败'
  133 + },
  134 + edit: {
  135 + title: '修改',
  136 + specName: '规格名称',
  137 + specNamePlaceholder: '必填,请填写规格名称',
  138 + specHoldplace: '说明',
  139 + specHoldplacePlaceholder: '选填,请填写说明',
  140 + required: '必填',
  141 + requiredPlaceholder: '必填,请选择必填',
  142 + specShow: '展示',
  143 + specShowPlaceholder: '必填,请选择展示',
  144 + specValueType: '值类型',
  145 + specValueTypePlaceholder: '必填,请选择值类型',
  146 + specType: '规格类型',
  147 + specTypePlaceholder: '必填,请选择规格类型',
  148 + listShow: '查询显示',
  149 + listShowPlaceholder: '必填,请选择查询显示',
  150 + success: '修改成功',
  151 + error: '修改失败'
  152 + },
  153 + delete: {
  154 + title: '请确认您的操作',
  155 + confirmText: '确定删除合同类型属性?',
  156 + success: '删除成功',
  157 + error: '删除失败'
  158 + },
  159 + specValueType: {
  160 + string: '字符串',
  161 + integer: '整数',
  162 + amount: '金额',
  163 + date: '日期',
  164 + time: '时间'
  165 + },
  166 + specType: {
  167 + input: '文本框',
  168 + select: '选择框'
  169 + },
  170 + validate: {
  171 + specNameRequired: '规格名称不能为空',
  172 + specNameMaxLength: '规格名称太长',
  173 + specHoldplaceMaxLength: '说明不能超过500位',
  174 + requiredRequired: '必填不能为空',
  175 + specShowRequired: '展示不能为空',
  176 + specValueTypeRequired: '值类型不能为空',
  177 + specTypeRequired: '规格类型不能为空',
  178 + listShowRequired: '查询显示不能为空',
  179 + specCdRequired: '规格不能为空'
  180 + },
  181 + fetchError: '获取数据失败'
  182 + }
  183 + }
  184 +}
0 185 \ No newline at end of file
... ...
src/views/contract/contractTypeSpecManageList.vue 0 → 100644
  1 +<template>
  2 + <div class="contract-type-spec-manage-container">
  3 + <el-card class="search-card">
  4 + <div slot="header" class="flex justify-between">
  5 + <span>{{ $t('contractTypeSpecManage.search.title') }}</span>
  6 + </div>
  7 + <el-row :gutter="20">
  8 + <el-col :span="6">
  9 + <el-input v-model="searchForm.specCd" :placeholder="$t('contractTypeSpecManage.search.specCd')" clearable />
  10 + </el-col>
  11 + <el-col :span="6">
  12 + <el-input v-model="searchForm.specName" :placeholder="$t('contractTypeSpecManage.search.specName')" clearable />
  13 + </el-col>
  14 + <el-col :span="6">
  15 + <el-select v-model="searchForm.specShow" :placeholder="$t('contractTypeSpecManage.search.specShow')"
  16 + style="width:100%">
  17 + <el-option :label="$t('contractTypeSpecManage.search.all')" value="" />
  18 + <el-option :label="$t('contractTypeSpecManage.search.yes')" value="Y" />
  19 + <el-option :label="$t('contractTypeSpecManage.search.no')" value="N" />
  20 + </el-select>
  21 + </el-col>
  22 + <el-col :span="6">
  23 + <el-button type="primary" @click="handleSearch">
  24 + {{ $t('common.search') }}
  25 + </el-button>
  26 + <el-button @click="handleReset">
  27 + {{ $t('common.reset') }}
  28 + </el-button>
  29 + </el-col>
  30 + </el-row>
  31 + </el-card>
  32 +
  33 + <el-card class="table-card">
  34 + <div slot="header" class="flex justify-between">
  35 + <span>{{ $t('contractTypeSpecManage.table.title') }}</span>
  36 + <div style="float:right">
  37 + <el-button type="primary" size="small" @click="handleGoBack">
  38 + {{ $t('common.back') }}
  39 + </el-button>
  40 + <el-button type="primary" size="small" @click="handleAdd">
  41 + {{ $t('common.add') }}
  42 + </el-button>
  43 + </div>
  44 + </div>
  45 + <el-table v-loading="loading" :data="tableData" border style="width:100%">
  46 + <el-table-column prop="specCd" :label="$t('contractTypeSpecManage.table.specCd')" align="center" />
  47 + <el-table-column prop="specName" :label="$t('contractTypeSpecManage.table.specName')" align="center" />
  48 + <el-table-column prop="required" :label="$t('contractTypeSpecManage.table.required')" align="center">
  49 + <template slot-scope="scope">
  50 + {{ scope.row.required === 'Y' ? $t('common.yes') : $t('common.no') }}
  51 + </template>
  52 + </el-table-column>
  53 + <el-table-column prop="specShow" :label="$t('contractTypeSpecManage.table.specShow')" align="center">
  54 + <template slot-scope="scope">
  55 + {{ scope.row.specShow === 'Y' ? $t('common.yes') : $t('common.no') }}
  56 + </template>
  57 + </el-table-column>
  58 + <el-table-column prop="specValueType" :label="$t('contractTypeSpecManage.table.specValueType')" align="center">
  59 + <template slot-scope="scope">
  60 + {{ formatSpecValueType(scope.row.specValueType) }}
  61 + </template>
  62 + </el-table-column>
  63 + <el-table-column prop="specType" :label="$t('contractTypeSpecManage.table.specType')" align="center">
  64 + <template slot-scope="scope">
  65 + {{ formatSpecType(scope.row.specType) }}
  66 + </template>
  67 + </el-table-column>
  68 + <el-table-column prop="listShow" :label="$t('contractTypeSpecManage.table.listShow')" align="center">
  69 + <template slot-scope="scope">
  70 + {{ scope.row.listShow === 'Y' ? $t('common.yes') : $t('common.no') }}
  71 + </template>
  72 + </el-table-column>
  73 + <el-table-column :label="$t('common.operation')" align="center" width="200">
  74 + <template slot-scope="scope">
  75 + <el-button size="mini" type="primary" @click="handleEdit(scope.row)">
  76 + {{ $t('common.edit') }}
  77 + </el-button>
  78 + <el-button size="mini" type="danger" @click="handleDelete(scope.row)">
  79 + {{ $t('common.delete') }}
  80 + </el-button>
  81 + </template>
  82 + </el-table-column>
  83 + </el-table>
  84 + <el-pagination :current-page="pagination.current" :page-sizes="[10, 20, 30, 50]" :page-size="pagination.size"
  85 + :total="pagination.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
  86 + @current-change="handleCurrentChange" />
  87 + </el-card>
  88 +
  89 + <add-contract-type-spec ref="addDialog" @success="handleSuccess" />
  90 + <edit-contract-type-spec ref="editDialog" @success="handleSuccess" />
  91 + <delete-contract-type-spec ref="deleteDialog" @success="handleSuccess" />
  92 + </div>
  93 +</template>
  94 +
  95 +<script>
  96 +import { queryContractTypeSpec } from '@/api/contract/contractTypeSpecManageApi'
  97 +import AddContractTypeSpec from '@/components/contract/addContractTypeSpec'
  98 +import EditContractTypeSpec from '@/components/contract/editContractTypeSpec'
  99 +import DeleteContractTypeSpec from '@/components/contract/deleteContractTypeSpec'
  100 +
  101 +export default {
  102 + name: 'ContractTypeSpecManageList',
  103 + components: {
  104 + AddContractTypeSpec,
  105 + EditContractTypeSpec,
  106 + DeleteContractTypeSpec
  107 + },
  108 + data() {
  109 + return {
  110 + loading: false,
  111 + searchForm: {
  112 + specCd: '',
  113 + specName: '',
  114 + specShow: '',
  115 + contractTypeId: this.$route.query.contractTypeId || ''
  116 + },
  117 + tableData: [],
  118 + pagination: {
  119 + current: 1,
  120 + size: 10,
  121 + total: 0
  122 + },
  123 + typeName: this.$route.query.typeName || ''
  124 + }
  125 + },
  126 + created() {
  127 + this.getList()
  128 + },
  129 + methods: {
  130 + async getList() {
  131 + try {
  132 + this.loading = true
  133 + const params = {
  134 + ...this.searchForm,
  135 + page: this.pagination.current,
  136 + row: this.pagination.size
  137 + }
  138 + const { data, total } = await queryContractTypeSpec(params)
  139 + this.tableData = data
  140 + this.pagination.total = total
  141 + } catch (error) {
  142 + this.$message.error(this.$t('contractTypeSpecManage.fetchError'))
  143 + } finally {
  144 + this.loading = false
  145 + }
  146 + },
  147 + handleSearch() {
  148 + this.pagination.current = 1
  149 + this.getList()
  150 + },
  151 + handleReset() {
  152 + this.searchForm = {
  153 + specCd: '',
  154 + specName: '',
  155 + specShow: '',
  156 + contractTypeId: this.$route.query.contractTypeId || ''
  157 + }
  158 + this.handleSearch()
  159 + },
  160 + handleSizeChange(val) {
  161 + this.pagination.size = val
  162 + this.getList()
  163 + },
  164 + handleCurrentChange(val) {
  165 + this.pagination.current = val
  166 + this.getList()
  167 + },
  168 + handleAdd() {
  169 + this.$refs.addDialog.open({
  170 + contractTypeId: this.searchForm.contractTypeId
  171 + })
  172 + },
  173 + handleEdit(row) {
  174 + this.$refs.editDialog.open(row)
  175 + },
  176 + handleDelete(row) {
  177 + this.$refs.deleteDialog.open(row)
  178 + },
  179 + handleGoBack() {
  180 + this.$router.go(-1)
  181 + },
  182 + handleSuccess() {
  183 + this.getList()
  184 + },
  185 + formatSpecValueType(type) {
  186 + const map = {
  187 + '1001': this.$t('contractTypeSpecManage.specValueType.string'),
  188 + '2002': this.$t('contractTypeSpecManage.specValueType.integer'),
  189 + '3003': this.$t('contractTypeSpecManage.specValueType.amount'),
  190 + '4004': this.$t('contractTypeSpecManage.specValueType.date'),
  191 + '5005': this.$t('contractTypeSpecManage.specValueType.time')
  192 + }
  193 + return map[type] || type
  194 + },
  195 + formatSpecType(type) {
  196 + const map = {
  197 + '2233': this.$t('contractTypeSpecManage.specType.input'),
  198 + '3344': this.$t('contractTypeSpecManage.specType.select')
  199 + }
  200 + return map[type] || type
  201 + }
  202 + }
  203 +}
  204 +</script>
  205 +
  206 +<style lang="scss" scoped>
  207 +.contract-type-spec-manage-container {
  208 + padding: 20px;
  209 +
  210 + .search-card {
  211 + margin-bottom: 20px;
  212 + }
  213 +
  214 + .table-card {
  215 + margin-bottom: 20px;
  216 + }
  217 +
  218 + .el-pagination {
  219 + margin-top: 20px;
  220 + text-align: right;
  221 + }
  222 +}
  223 +</style>
0 224 \ No newline at end of file
... ...
src/views/contract/expirationContractManageLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + expirationContractManage: {
  4 + search: {
  5 + title: 'Search Conditions',
  6 + contractNameLike: 'Please enter contract name',
  7 + contractCode: 'Please enter contract code',
  8 + contractType: 'Please select contract type'
  9 + },
  10 + list: {
  11 + title: 'Expiration Contracts'
  12 + },
  13 + table: {
  14 + contractName: 'Contract Name',
  15 + contractCode: 'Contract Code',
  16 + contractType: 'Contract Type',
  17 + partyA: 'Party A',
  18 + partyB: 'Party B',
  19 + operator: 'Operator',
  20 + amount: 'Amount',
  21 + startTime: 'Start Time',
  22 + endTime: 'End Time',
  23 + status: 'Status'
  24 + },
  25 + button: {
  26 + renew: 'Renew',
  27 + stop: 'Stop'
  28 + },
  29 + fetchError: 'Failed to fetch contract data'
  30 + },
  31 + stopContract: {
  32 + dialog: {
  33 + title: 'Confirm Operation',
  34 + content: 'Are you sure to stop this contract? It cannot be restarted after stopping!'
  35 + },
  36 + button: {
  37 + cancel: 'Cancel',
  38 + confirm: 'Confirm Stop'
  39 + },
  40 + message: {
  41 + success: 'Contract stopped successfully',
  42 + error: 'Failed to stop contract'
  43 + }
  44 + }
  45 + },
  46 + zh: {
  47 + expirationContractManage: {
  48 + search: {
  49 + title: '查询条件',
  50 + contractNameLike: '请输入合同名称',
  51 + contractCode: '请输入合同编号',
  52 + contractType: '请选择合同类型'
  53 + },
  54 + list: {
  55 + title: '到期合同'
  56 + },
  57 + table: {
  58 + contractName: '合同名称',
  59 + contractCode: '合同编号',
  60 + contractType: '合同类型',
  61 + partyA: '甲方',
  62 + partyB: '乙方',
  63 + operator: '经办人',
  64 + amount: '合同金额',
  65 + startTime: '开始时间',
  66 + endTime: '结束时间',
  67 + status: '状态'
  68 + },
  69 + button: {
  70 + renew: '续签',
  71 + stop: '终止'
  72 + },
  73 + fetchError: '获取合同数据失败'
  74 + },
  75 + stopContract: {
  76 + dialog: {
  77 + title: '确认操作',
  78 + content: '确定要终止此合同吗?终止后将无法重新启动!'
  79 + },
  80 + button: {
  81 + cancel: '取消',
  82 + confirm: '确认终止'
  83 + },
  84 + message: {
  85 + success: '合同终止成功',
  86 + error: '合同终止失败'
  87 + }
  88 + }
  89 + }
  90 +}
0 91 \ No newline at end of file
... ...
src/views/contract/expirationContractManageList.vue 0 → 100644
  1 +<template>
  2 + <div class="expiration-contract-manage-container">
  3 + <!-- 查询条件 -->
  4 + <el-card class="search-wrapper">
  5 + <div slot="header" class="flex justify-between">
  6 + <span>{{ $t('expirationContractManage.search.title') }}</span>
  7 + </div>
  8 + <el-row :gutter="20">
  9 + <el-col :span="6">
  10 + <el-input v-model.trim="searchForm.contractNameLike"
  11 + :placeholder="$t('expirationContractManage.search.contractNameLike')" clearable />
  12 + </el-col>
  13 + <el-col :span="6">
  14 + <el-input v-model.trim="searchForm.contractCode"
  15 + :placeholder="$t('expirationContractManage.search.contractCode')" clearable />
  16 + </el-col>
  17 + <el-col :span="6">
  18 + <el-select v-model="searchForm.contractType" :placeholder="$t('expirationContractManage.search.contractType')"
  19 + style="width:100%">
  20 + <el-option v-for="item in contractTypes" :key="item.contractTypeId" :label="item.typeName"
  21 + :value="item.contractTypeId" />
  22 + </el-select>
  23 + </el-col>
  24 + <el-col :span="6">
  25 + <el-button type="primary" @click="handleSearch">
  26 + <i class="el-icon-search"></i>
  27 + {{ $t('common.search') }}
  28 + </el-button>
  29 + <el-button @click="handleReset">
  30 + <i class="el-icon-refresh"></i>
  31 + {{ $t('common.reset') }}
  32 + </el-button>
  33 + </el-col>
  34 + </el-row>
  35 + </el-card>
  36 +
  37 + <!-- 到期合同列表 -->
  38 + <el-card class="list-wrapper">
  39 + <div slot="header" class="flex justify-between">
  40 + <span>{{ $t('expirationContractManage.list.title') }}</span>
  41 + </div>
  42 + <el-table v-loading="loading" :data="tableData" border style="width: 100%">
  43 + <el-table-column prop="contractName" :label="$t('expirationContractManage.table.contractName')" align="center" />
  44 + <el-table-column prop="contractCode" :label="$t('expirationContractManage.table.contractCode')" align="center" />
  45 + <el-table-column prop="contractTypeName" :label="$t('expirationContractManage.table.contractType')"
  46 + align="center" />
  47 + <el-table-column prop="partyA" :label="$t('expirationContractManage.table.partyA')" align="center" />
  48 + <el-table-column prop="partyB" :label="$t('expirationContractManage.table.partyB')" align="center" />
  49 + <el-table-column prop="operator" :label="$t('expirationContractManage.table.operator')" align="center" />
  50 + <el-table-column prop="amount" :label="$t('expirationContractManage.table.amount')" align="center" />
  51 + <el-table-column prop="startTime" :label="$t('expirationContractManage.table.startTime')" align="center" />
  52 + <el-table-column prop="endTime" :label="$t('expirationContractManage.table.endTime')" align="center" />
  53 + <el-table-column prop="stateName" :label="$t('expirationContractManage.table.status')" align="center" />
  54 + <el-table-column :label="$t('common.operation')" align="center" width="200">
  55 + <template slot-scope="scope">
  56 + <el-button size="mini" type="primary" @click="handleRenew(scope.row)">
  57 + {{ $t('expirationContractManage.button.renew') }}
  58 + </el-button>
  59 + <el-button size="mini" type="danger" @click="handleStop(scope.row)">
  60 + {{ $t('expirationContractManage.button.stop') }}
  61 + </el-button>
  62 + </template>
  63 + </el-table-column>
  64 + </el-table>
  65 +
  66 + <el-pagination :current-page.sync="pagination.current" :page-sizes="[10, 20, 30, 50]" :page-size="pagination.size"
  67 + :total="pagination.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
  68 + @current-change="handleCurrentChange" />
  69 + </el-card>
  70 +
  71 + <!-- 终止合同弹窗 -->
  72 + <stop-contract ref="stopContractDialog" @success="handleSuccess" />
  73 + </div>
  74 +</template>
  75 +
  76 +<script>
  77 +import { queryContract, queryContractType } from '@/api/contract/expirationContractManageApi'
  78 +import StopContract from '@/components/contract/StopContract'
  79 +
  80 +export default {
  81 + name: 'ExpirationContractManageList',
  82 + components: {
  83 + StopContract
  84 + },
  85 + data() {
  86 + return {
  87 + loading: false,
  88 + searchForm: {
  89 + contractNameLike: '',
  90 + contractCode: '',
  91 + contractType: '',
  92 + expiration: '1'
  93 + },
  94 + tableData: [],
  95 + contractTypes: [],
  96 + pagination: {
  97 + current: 1,
  98 + size: 10,
  99 + total: 0
  100 + }
  101 + }
  102 + },
  103 + created() {
  104 + this.getList()
  105 + this.getContractTypes()
  106 + },
  107 + methods: {
  108 + async getList() {
  109 + try {
  110 + this.loading = true
  111 + const params = {
  112 + page: this.pagination.current,
  113 + row: this.pagination.size,
  114 + ...this.searchForm
  115 + }
  116 + const { data, total } = await queryContract(params)
  117 + this.tableData = data
  118 + this.pagination.total = total
  119 + } catch (error) {
  120 + this.$message.error(this.$t('expirationContractManage.fetchError'))
  121 + } finally {
  122 + this.loading = false
  123 + }
  124 + },
  125 + async getContractTypes() {
  126 + try {
  127 + const { data } = await queryContractType({
  128 + page: 1,
  129 + row: 50
  130 + })
  131 + this.contractTypes = data
  132 + } catch (error) {
  133 + console.error('获取合同类型失败:', error)
  134 + }
  135 + },
  136 + handleSearch() {
  137 + this.pagination.current = 1
  138 + this.getList()
  139 + },
  140 + handleReset() {
  141 + this.searchForm = {
  142 + contractNameLike: '',
  143 + contractCode: '',
  144 + contractType: '',
  145 + expiration: '1'
  146 + }
  147 + this.handleSearch()
  148 + },
  149 + handleSizeChange(val) {
  150 + this.pagination.size = val
  151 + this.getList()
  152 + },
  153 + handleCurrentChange(val) {
  154 + this.pagination.current = val
  155 + this.getList()
  156 + },
  157 + handleRenew(row) {
  158 + this.$router.push({
  159 + path: '/pages/admin/addContract',
  160 + query: {
  161 + contractId: row.contractId,
  162 + contractCode: row.contractCode,
  163 + contractName: row.contractName,
  164 + stateName: row.stateName
  165 + }
  166 + })
  167 + },
  168 + handleStop(row) {
  169 + this.$refs.stopContractDialog.open(row)
  170 + },
  171 + handleSuccess() {
  172 + this.getList()
  173 + }
  174 + }
  175 +}
  176 +</script>
  177 +
  178 +<style lang="scss" scoped>
  179 +.expiration-contract-manage-container {
  180 + padding: 20px;
  181 +
  182 + .search-wrapper {
  183 + margin-bottom: 20px;
  184 +
  185 + .el-row {
  186 + margin-bottom: 0;
  187 + }
  188 + }
  189 +
  190 + .list-wrapper {
  191 + .el-pagination {
  192 + margin-top: 20px;
  193 + text-align: right;
  194 + }
  195 + }
  196 +}
  197 +</style>
0 198 \ No newline at end of file
... ...
src/views/contract/newContractManageLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + newContractManage: {
  4 + search: {
  5 + title: 'Search Conditions',
  6 + contractNamePlaceholder: 'Please enter contract name',
  7 + contractCodePlaceholder: 'Please enter contract code',
  8 + contractTypePlaceholder: 'Please select contract type'
  9 + },
  10 + list: {
  11 + title: 'Draft Contract Information',
  12 + draft: 'Draft',
  13 + note: 'Note: Please go to System Management > Process Management to set up contract application renewal before using this function'
  14 + },
  15 + table: {
  16 + contractName: 'Contract Name',
  17 + contractCode: 'Contract Code',
  18 + parentContractCode: 'Parent Contract Code',
  19 + contractType: 'Contract Type',
  20 + operator: 'Operator',
  21 + amount: 'Contract Amount',
  22 + startTime: 'Start Time',
  23 + endTime: 'End Time',
  24 + state: 'Status'
  25 + },
  26 + edit: {
  27 + title: 'Edit Contract',
  28 + contractName: 'Contract Name',
  29 + contractNamePlaceholder: 'Required, please fill in contract name',
  30 + contractCode: 'Contract Code',
  31 + contractCodePlaceholder: 'Required, please fill in contract code',
  32 + contractType: 'Contract Type',
  33 + contractTypePlaceholder: 'Required, please select contract type',
  34 + partyA: 'Party A',
  35 + partyAPlaceholder: 'Required, please fill in Party A',
  36 + partyB: 'Party B',
  37 + partyBPlaceholder: 'Required, please fill in Party B',
  38 + aContacts: 'Party A Contact',
  39 + aContactsPlaceholder: 'Required, please fill in Party A contact',
  40 + bContacts: 'Party B Contact',
  41 + bContactsPlaceholder: 'Required, please fill in Party B contact',
  42 + aLink: 'Party A Phone',
  43 + aLinkPlaceholder: 'Required, please fill in Party A phone',
  44 + bLink: 'Party B Phone',
  45 + bLinkPlaceholder: 'Required, please fill in Party B phone',
  46 + operator: 'Operator',
  47 + operatorPlaceholder: 'Required, please fill in operator',
  48 + operatorLink: 'Operator Phone',
  49 + operatorLinkPlaceholder: 'Required, please fill in operator phone',
  50 + amount: 'Contract Amount',
  51 + amountPlaceholder: 'Optional, please fill in contract amount',
  52 + startTime: 'Start Time',
  53 + startTimePlaceholder: 'Required, please fill in start time',
  54 + endTime: 'End Time',
  55 + endTimePlaceholder: 'Required, please fill in end time',
  56 + signingTime: 'Signing Time',
  57 + signingTimePlaceholder: 'Required, please fill in signing time',
  58 + contractFile: 'Contract Attachment',
  59 + addFile: 'Add Attachment',
  60 + upload: 'Upload',
  61 + deleteFile: 'Delete',
  62 + fileIndex: 'No.{index}'
  63 + },
  64 + delete: {
  65 + title: 'Confirm Operation',
  66 + confirmText: 'Are you sure to delete the contract information?',
  67 + success: 'Delete successfully',
  68 + error: 'Delete failed'
  69 + },
  70 + validate: {
  71 + contractNameRequired: 'Contract name cannot be empty',
  72 + contractNameMaxLength: 'Contract name cannot exceed 200 characters',
  73 + contractCodeRequired: 'Contract code cannot be empty',
  74 + contractCodeMaxLength: 'Contract code cannot exceed 30 characters',
  75 + contractTypeRequired: 'Contract type cannot be empty',
  76 + partyARequired: 'Party A cannot be empty',
  77 + partyAMaxLength: 'Party A name is too long',
  78 + partyBRequired: 'Party B cannot be empty',
  79 + partyBMaxLength: 'Party B name is too long',
  80 + aContactsRequired: 'Party A contact cannot be empty',
  81 + aContactsMaxLength: 'Party A contact length exceeds 64 characters',
  82 + bContactsRequired: 'Party B contact cannot be empty',
  83 + bContactsMaxLength: 'Party B contact length exceeds 64 characters',
  84 + aLinkRequired: 'Party A phone cannot be empty',
  85 + bLinkRequired: 'Party B phone cannot be empty',
  86 + operatorRequired: 'Operator cannot be empty',
  87 + operatorMaxLength: 'Operator exceeds 64 characters',
  88 + operatorLinkRequired: 'Operator phone cannot be empty',
  89 + amountFormat: 'Contract amount format error, such as 1.50',
  90 + startTimeRequired: 'Start time cannot be empty',
  91 + endTimeRequired: 'End time cannot be empty',
  92 + signingTimeRequired: 'Signing time cannot be empty',
  93 + fileTypeError: 'Operation failed, please upload image or PDF format file'
  94 + },
  95 + uploadSuccess: 'Upload successfully',
  96 + uploadError: 'Upload failed',
  97 + updateSuccess: 'Update successfully',
  98 + updateError: 'Update failed',
  99 + fetchError: 'Failed to fetch contract data'
  100 + }
  101 + },
  102 + zh: {
  103 + newContractManage: {
  104 + search: {
  105 + title: '查询条件',
  106 + contractNamePlaceholder: '请输入合同名称',
  107 + contractCodePlaceholder: '请输入合同编号',
  108 + contractTypePlaceholder: '请选择合同类型'
  109 + },
  110 + list: {
  111 + title: '起草合同信息',
  112 + draft: '起草',
  113 + note: '注意:此功能使用前请先到系统管理>流程管理中设置合同申请续签'
  114 + },
  115 + table: {
  116 + contractName: '合同名称',
  117 + contractCode: '合同编号',
  118 + parentContractCode: '父合同编号',
  119 + contractType: '合同类型',
  120 + operator: '经办人',
  121 + amount: '合同金额',
  122 + startTime: '开始时间',
  123 + endTime: '结束时间',
  124 + state: '状态'
  125 + },
  126 + edit: {
  127 + title: '编辑合同',
  128 + contractName: '合同名称',
  129 + contractNamePlaceholder: '必填,请填写合同名称',
  130 + contractCode: '合同编号',
  131 + contractCodePlaceholder: '必填,请填写合同编号',
  132 + contractType: '合同类型',
  133 + contractTypePlaceholder: '必填,请选择合同类型',
  134 + partyA: '甲方',
  135 + partyAPlaceholder: '必填,请填写甲方',
  136 + partyB: '乙方',
  137 + partyBPlaceholder: '必填,请填写乙方',
  138 + aContacts: '甲方联系人',
  139 + aContactsPlaceholder: '必填,请填写甲方联系人',
  140 + bContacts: '乙方联系人',
  141 + bContactsPlaceholder: '必填,请填写乙方联系人',
  142 + aLink: '甲方联系电话',
  143 + aLinkPlaceholder: '必填,请填写甲方联系电话',
  144 + bLink: '乙方联系电话',
  145 + bLinkPlaceholder: '必填,请填写乙方联系电话',
  146 + operator: '经办人',
  147 + operatorPlaceholder: '必填,请填写经办人',
  148 + operatorLink: '联系电话',
  149 + operatorLinkPlaceholder: '必填,请填写联系电话',
  150 + amount: '合同金额',
  151 + amountPlaceholder: '选填,请填写合同金额',
  152 + startTime: '开始时间',
  153 + startTimePlaceholder: '必填,请填写开始时间',
  154 + endTime: '结束时间',
  155 + endTimePlaceholder: '必填,请填写结束时间',
  156 + signingTime: '签订时间',
  157 + signingTimePlaceholder: '必填,请填写签订时间',
  158 + contractFile: '合同附件',
  159 + addFile: '添加附件',
  160 + upload: '上传',
  161 + deleteFile: '删除',
  162 + fileIndex: '第{index}个'
  163 + },
  164 + delete: {
  165 + title: '请确认您的操作',
  166 + confirmText: '确定删除合同信息',
  167 + success: '删除成功',
  168 + error: '删除失败'
  169 + },
  170 + validate: {
  171 + contractNameRequired: '合同名称不能为空',
  172 + contractNameMaxLength: '合同名称不能超过200位',
  173 + contractCodeRequired: '合同编号不能为空',
  174 + contractCodeMaxLength: '合同编号错误',
  175 + contractTypeRequired: '合同类型不能为空',
  176 + partyARequired: '甲方不能为空',
  177 + partyAMaxLength: '甲方名称太长',
  178 + partyBRequired: '乙方不能为空',
  179 + partyBMaxLength: '乙方名称太长',
  180 + aContactsRequired: '甲方联系人不能为空',
  181 + aContactsMaxLength: '甲方联系人长度超过64位',
  182 + bContactsRequired: '乙方联系人不能为空',
  183 + bContactsMaxLength: '乙方联系人长度超过64位',
  184 + aLinkRequired: '甲方联系电话不能为空',
  185 + bLinkRequired: '乙方联系电话不能为空',
  186 + operatorRequired: '经办人不能为空',
  187 + operatorMaxLength: '经办人超过64位',
  188 + operatorLinkRequired: '联系电话不能为空',
  189 + amountFormat: '合同金额格式错误,如1.50',
  190 + startTimeRequired: '开始时间不能为空',
  191 + endTimeRequired: '结束时间不能为空',
  192 + signingTimeRequired: '签订时间不能为空',
  193 + fileTypeError: '操作失败,请上传图片、PDF格式的文件'
  194 + },
  195 + uploadSuccess: '上传成功',
  196 + uploadError: '上传失败',
  197 + updateSuccess: '修改成功',
  198 + updateError: '修改失败',
  199 + fetchError: '获取合同数据失败'
  200 + }
  201 + }
  202 +}
0 203 \ No newline at end of file
... ...
src/views/contract/newContractManageList.vue 0 → 100644
  1 +<template>
  2 + <div class="new-contract-manage-container">
  3 + <!-- 查询条件 -->
  4 + <el-card class="search-card">
  5 + <div slot="header" class="flex justify-between">
  6 + <span>{{ $t('newContractManage.search.title') }}</span>
  7 + </div>
  8 + <el-row :gutter="20">
  9 + <el-col :span="6">
  10 + <el-input v-model.trim="searchForm.contractNameLike"
  11 + :placeholder="$t('newContractManage.search.contractNamePlaceholder')" clearable />
  12 + </el-col>
  13 + <el-col :span="6">
  14 + <el-input v-model.trim="searchForm.contractCode"
  15 + :placeholder="$t('newContractManage.search.contractCodePlaceholder')" clearable />
  16 + </el-col>
  17 + <el-col :span="6">
  18 + <el-select v-model="searchForm.contractType"
  19 + :placeholder="$t('newContractManage.search.contractTypePlaceholder')" style="width:100%">
  20 + <el-option v-for="item in contractTypes" :key="item.contractTypeId" :label="item.typeName"
  21 + :value="item.contractTypeId" />
  22 + </el-select>
  23 + </el-col>
  24 + <el-col :span="6">
  25 + <el-button type="primary" @click="handleSearch">
  26 + <i class="el-icon-search"></i>
  27 + {{ $t('common.search') }}
  28 + </el-button>
  29 + <el-button @click="handleReset">
  30 + <i class="el-icon-refresh"></i>
  31 + {{ $t('common.reset') }}
  32 + </el-button>
  33 + </el-col>
  34 + </el-row>
  35 + </el-card>
  36 +
  37 + <!-- 合同列表 -->
  38 + <el-card class="table-card">
  39 + <div slot="header" class="flex justify-between">
  40 + <span>{{ $t('newContractManage.list.title') }}</span>
  41 + <el-button type="primary" size="small" @click="handleAdd">
  42 + <i class="el-icon-plus"></i>
  43 + {{ $t('newContractManage.list.draft') }}
  44 + </el-button>
  45 + </div>
  46 +
  47 + <el-table v-loading="loading" :data="tableData" border style="width:100%">
  48 + <el-table-column prop="contractName" :label="$t('newContractManage.table.contractName')" align="center" />
  49 + <el-table-column prop="contractCode" :label="$t('newContractManage.table.contractCode')" align="center" />
  50 + <el-table-column prop="parentContractCode" :label="$t('newContractManage.table.parentContractCode')"
  51 + align="center">
  52 + <template slot-scope="scope">
  53 + {{ scope.row.parentContractCode || '-' }}
  54 + </template>
  55 + </el-table-column>
  56 + <el-table-column prop="contractTypeName" :label="$t('newContractManage.table.contractType')" align="center" />
  57 + <el-table-column prop="operator" :label="$t('newContractManage.table.operator')" align="center" />
  58 + <el-table-column prop="amount" :label="$t('newContractManage.table.amount')" align="center" />
  59 + <el-table-column prop="startTime" :label="$t('newContractManage.table.startTime')" align="center" />
  60 + <el-table-column prop="endTime" :label="$t('newContractManage.table.endTime')" align="center" />
  61 + <el-table-column prop="stateName" :label="$t('newContractManage.table.state')" align="center" />
  62 + <el-table-column :label="$t('common.operation')" align="center" width="220">
  63 + <template slot-scope="scope">
  64 + <el-button size="mini" type="primary" @click="handleEdit(scope.row)">
  65 + {{ $t('common.edit') }}
  66 + </el-button>
  67 + <el-button size="mini" type="danger" @click="handleDelete(scope.row)">
  68 + {{ $t('common.delete') }}
  69 + </el-button>
  70 + <el-button size="mini" @click="handlePrint(scope.row)">
  71 + {{ $t('common.print') }}
  72 + </el-button>
  73 + </template>
  74 + </el-table-column>
  75 + </el-table>
  76 +
  77 + <div class="note-text">
  78 + {{ $t('newContractManage.list.note') }}
  79 + </div>
  80 +
  81 + <el-pagination :current-page="pagination.current" :page-sizes="[10, 20, 30, 50]" :page-size="pagination.size"
  82 + :total="pagination.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
  83 + @current-change="handleCurrentChange" />
  84 + </el-card>
  85 +
  86 + <!-- 编辑合同组件 -->
  87 + <edit-contract ref="editContract" @success="fetchData" />
  88 +
  89 + <!-- 删除合同组件 -->
  90 + <delete-contract ref="deleteContract" @success="fetchData" />
  91 + </div>
  92 +</template>
  93 +
  94 +<script>
  95 +import { getContractList, getContractTypeList } from '@/api/contract/newContractManageApi'
  96 +import EditContract from '@/components/contract/editContract'
  97 +import DeleteContract from '@/components/contract/deleteContract'
  98 +import { getCommunityId } from '@/api/community/communityApi'
  99 +
  100 +export default {
  101 + name: 'NewContractManageList',
  102 + components: {
  103 + EditContract,
  104 + DeleteContract
  105 + },
  106 + data() {
  107 + return {
  108 + loading: false,
  109 + searchForm: {
  110 + contractNameLike: '',
  111 + contractCode: '',
  112 + contractType: '',
  113 + state: ''
  114 + },
  115 + tableData: [],
  116 + contractTypes: [],
  117 + pagination: {
  118 + current: 1,
  119 + size: 10,
  120 + total: 0
  121 + },
  122 + communityId: ''
  123 + }
  124 + },
  125 + created() {
  126 + this.communityId = getCommunityId()
  127 + this.fetchData()
  128 + this.fetchContractTypes()
  129 + },
  130 + methods: {
  131 + async fetchData() {
  132 + try {
  133 + this.loading = true
  134 + const params = {
  135 + page: this.pagination.current,
  136 + row: this.pagination.size,
  137 + ...this.searchForm,
  138 + communityId: this.communityId
  139 + }
  140 + const { data, total } = await getContractList(params)
  141 + this.tableData = data
  142 + this.pagination.total = total
  143 + } catch (error) {
  144 + this.$message.error(this.$t('newContractManage.fetchError'))
  145 + } finally {
  146 + this.loading = false
  147 + }
  148 + },
  149 + async fetchContractTypes() {
  150 + try {
  151 + const params = {
  152 + page: 1,
  153 + row: 100
  154 + }
  155 + const { data } = await getContractTypeList(params)
  156 + this.contractTypes = data
  157 + } catch (error) {
  158 + console.error('获取合同类型失败:', error)
  159 + }
  160 + },
  161 + handleSearch() {
  162 + this.pagination.current = 1
  163 + this.fetchData()
  164 + },
  165 + handleReset() {
  166 + this.searchForm = {
  167 + contractNameLike: '',
  168 + contractCode: '',
  169 + contractType: '',
  170 + state: ''
  171 + }
  172 + this.handleSearch()
  173 + },
  174 + handleAdd() {
  175 + this.$router.push('/views/contract/addContract')
  176 + },
  177 + handleEdit(row) {
  178 + this.$refs.editContract.open(row)
  179 + },
  180 + handleDelete(row) {
  181 + this.$refs.deleteContract.open(row)
  182 + },
  183 + handlePrint(row) {
  184 + window.open(`/#/views/contract/printContract?contractTypeId=${row.contractType}&contractId=${row.contractId}`)
  185 + },
  186 + handleSizeChange(val) {
  187 + this.pagination.size = val
  188 + this.fetchData()
  189 + },
  190 + handleCurrentChange(val) {
  191 + this.pagination.current = val
  192 + this.fetchData()
  193 + }
  194 + }
  195 +}
  196 +</script>
  197 +
  198 +<style lang="scss" scoped>
  199 +.new-contract-manage-container {
  200 + padding: 20px;
  201 +
  202 + .search-card {
  203 + margin-bottom: 20px;
  204 + }
  205 +
  206 + .table-card {
  207 + margin-bottom: 20px;
  208 + }
  209 +
  210 + .note-text {
  211 + margin: 15px 0;
  212 + color: #999;
  213 + font-size: 14px;
  214 + }
  215 +
  216 + .el-pagination {
  217 + margin-top: 20px;
  218 + text-align: right;
  219 + }
  220 +}
  221 +</style>
0 222 \ No newline at end of file
... ...
src/views/contract/printContractLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + printContract: {
  4 + title: 'Contract Print',
  5 + print: 'Print',
  6 + close: 'Close',
  7 + noTemplate: 'This contract does not have a template set, please set it in the contract template under the contract type'
  8 + }
  9 + },
  10 + zh: {
  11 + printContract: {
  12 + title: '合同打印',
  13 + print: '打印',
  14 + close: '关闭',
  15 + noTemplate: '此合同未设置合同模板,请到合同类型下的合同模板中设置'
  16 + }
  17 + }
  18 +}
0 19 \ No newline at end of file
... ...
src/views/contract/printContractList.vue 0 → 100644
  1 +<template>
  2 + <div class="print-contract-container">
  3 + <el-card class="box-card">
  4 + <div slot="header" class="clearfix">
  5 + <h2>{{ $t('printContract.title') }}</h2>
  6 + </div>
  7 +
  8 + <el-row v-if="printContractInfo.context" class="margin-top">
  9 + <el-col :span="24">
  10 + <div v-html="printContractInfo.context"></div>
  11 + </el-col>
  12 + </el-row>
  13 +
  14 + <el-row v-else class="margin-top">
  15 + <el-col :span="24" class="text-center">
  16 + <div>{{ $t('printContract.noTemplate') }}</div>
  17 + </el-col>
  18 + </el-row>
  19 +
  20 + <div id="print-btn" class="button-group">
  21 + <el-button
  22 + type="primary"
  23 + class="float-right"
  24 + @click="_printContractDiv"
  25 + >
  26 + <i class="el-icon-printer"></i>&nbsp;{{ $t('printContract.print') }}
  27 + </el-button>
  28 + <el-button
  29 + type="warning"
  30 + class="float-right"
  31 + style="margin-right:20px;"
  32 + @click="_closePage"
  33 + >
  34 + {{ $t('printContract.close') }}
  35 + </el-button>
  36 + </div>
  37 + </el-card>
  38 + </div>
  39 +</template>
  40 +
  41 +<script>
  42 +import { getPrintContractTemplate } from '@/api/contract/printContractApi'
  43 +import { getCommunityId } from '@/api/community/communityApi'
  44 +
  45 +export default {
  46 + name: 'PrintContractList',
  47 + data() {
  48 + return {
  49 + templatecontent: '',
  50 + contractdata: '',
  51 + contractTypeSpec: '',
  52 + baseRepalce: [],
  53 + attrs: [],
  54 + printContractInfo: {
  55 + contractId: '',
  56 + contractTypeId: '',
  57 + context: ''
  58 + },
  59 + printFlag: '0',
  60 + communityId: ''
  61 + }
  62 + },
  63 + created() {
  64 + this.communityId = getCommunityId()
  65 + this.printContractInfo.contractTypeId = this.$route.query.contractTypeId
  66 + this.printContractInfo.contractId = this.$route.query.contractId
  67 + this._loadContract()
  68 + },
  69 + methods: {
  70 + _loadContract() {
  71 + const param = {
  72 + page: 1,
  73 + row: 1,
  74 + contractId: this.printContractInfo.contractId,
  75 + contractTypeId: this.printContractInfo.contractTypeId,
  76 + communityId: this.communityId
  77 + }
  78 +
  79 + getPrintContractTemplate(param)
  80 + .then(res => {
  81 + const _data = res.data
  82 + this.templatecontent = _data.contractTypeTemplate[0].context
  83 + this.contractdata = _data.contract[0]
  84 + this.attrs = _data.contract[0].attrs
  85 + this.contractTypeSpec = _data.contractTypeSpec
  86 +
  87 + this.contractTypeSpec.forEach(e => {
  88 + const rname = e.specName
  89 + const rspecCd = e.specCd
  90 + this.attrs.forEach(ea => {
  91 + if (rspecCd === ea.specCd) {
  92 + const reg = new RegExp('#' + rname + '#', 'g')
  93 + this.templatecontent = this.templatecontent.replace(reg, ea.value)
  94 + }
  95 + })
  96 + })
  97 +
  98 + this.baseRepalce = _data.baseRepalce
  99 + if (this.baseRepalce) {
  100 + this.baseRepalce.forEach(e => {
  101 + const rname = e.name
  102 + const rkey = e.key
  103 + const contractarr = Object.keys(this.contractdata)
  104 + for (const a in contractarr) {
  105 + if (rkey === contractarr[a]) {
  106 + const reg = new RegExp('#' + rname + '#', 'g')
  107 + this.templatecontent = this.templatecontent.replace(reg, this.contractdata[contractarr[a]])
  108 + }
  109 + }
  110 + })
  111 + }
  112 +
  113 + this.printContractInfo.context = this.templatecontent
  114 + })
  115 + .catch(error => {
  116 + console.error('请求失败:', error)
  117 + })
  118 + },
  119 +
  120 + _printContractDiv() {
  121 + this.printFlag = '1'
  122 + document.getElementById('print-btn').style.display = 'none'
  123 + window.print()
  124 + window.opener = null
  125 + window.close()
  126 + },
  127 +
  128 + _closePage() {
  129 + window.opener = null
  130 + window.close()
  131 + }
  132 + }
  133 +}
  134 +</script>
  135 +
  136 +<style lang="scss" scoped>
  137 +.print-contract-container {
  138 + padding: 20px;
  139 +
  140 + .box-card {
  141 + margin-bottom: 20px;
  142 + }
  143 +
  144 + .margin-top {
  145 + margin-top: 20px;
  146 + }
  147 +
  148 + .text-center {
  149 + text-align: center;
  150 + }
  151 +
  152 + .float-right {
  153 + float: right;
  154 + }
  155 +
  156 + .button-group {
  157 + margin-top: 20px;
  158 + overflow: hidden;
  159 + }
  160 +}
  161 +</style>
0 162 \ No newline at end of file
... ...