综合办公系统
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

index.vue 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669
  1. <!--
  2. * @Author: ysh
  3. * @Date: 2024-06-21 18:52:00
  4. * @LastEditors: Please set LastEditors
  5. * @LastEditTime: 2025-07-24 14:37:14
  6. -->
  7. <template>
  8. <div class="app-container">
  9. <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
  10. <el-form-item label="合同名称" prop="contractName">
  11. <el-input v-model="queryParams.contractName" placeholder="请输入合同名称" clearable
  12. @keyup.enter.native="handleQuery" />
  13. </el-form-item>
  14. <el-form-item label="合同编码" prop="contractCode">
  15. <el-input v-model="queryParams.contractCode" placeholder="请输入合同编码" clearable
  16. @keyup.enter.native="handleQuery" />
  17. </el-form-item>
  18. <el-form-item label="甲方单位" prop="partyAId">
  19. <el-select v-model="queryParams.partyAId" clearable filterable remote reserve-keyword placeholder="请输入单位名称"
  20. :remote-method="remoteMethod" :loading="queryLoading" style="width: 400px;" @change="handleQuery()">
  21. <el-option v-for="partyA in queryPartyAList" :key="partyA.partyAId" :label="partyA.partyAName"
  22. :value="partyA.partyAId">
  23. </el-option>
  24. </el-select>
  25. </el-form-item>
  26. <el-form-item label="工作内容" prop="queryString">
  27. <el-input v-model="queryParams.queryString" placeholder="请输入关键字" clearable @keyup.enter.native="handleQuery" />
  28. </el-form-item>
  29. <el-form-item>
  30. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  31. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  32. </el-form-item>
  33. </el-form>
  34. <el-row :gutter="10" class="mb8">
  35. <el-col :span="1.5">
  36. <el-button type="success" plain icon="el-icon-plus" size="mini" @click="handleRegister"
  37. v-hasPermi="['oa:contract:add']">登记承接合同</el-button>
  38. </el-col>
  39. <el-col :span="1.5">
  40. <el-button type="warning" plain icon="el-icon-download" size="mini" @click="exportOpen = true"
  41. v-hasPermi="['oa:contract:export']">导出</el-button>
  42. </el-col>
  43. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  44. </el-row>
  45. <el-table v-loading="loading" border :data="contractList" @selection-change="handleSelectionChange">
  46. <!-- <el-table-column label="合同id" align="center" prop="contractId" /> -->
  47. <el-table-column type="index" label="序号" width="55" align="center" />
  48. <el-table-column label="合同名称" align="center" prop="contractName" width="220px" />
  49. <el-table-column label="合同金额" align="center" prop="amount" />
  50. <el-table-column label="甲方单位" align="center" prop="partyA.partyAName" width="220px" />
  51. <el-table-column label="合同编码(公司)" align="center" prop="contractCode" />
  52. <el-table-column label="合同编号(业主)" align="center" prop="contractNumber" />
  53. <el-table-column label="拟稿日期" align="center" prop="draftTime" width="110px">
  54. <template slot-scope="scope">
  55. <span>{{ parseTime(scope.row.draftTime, '{y}-{m}-{d}') }}</span>
  56. </template>
  57. </el-table-column>
  58. <el-table-column label="签订日期" align="center" prop="signDate" width="110px">
  59. <template slot-scope="scope">
  60. <span>{{ parseTime(scope.row.signDate, '{y}-{m}-{d}') }}</span>
  61. </template>
  62. </el-table-column>
  63. <el-table-column prop="percentage" align="center" label="开票/回款进度" width="180px" sortable>
  64. <template slot-scope="scope">
  65. <div class="progress-container">
  66. <div class="progress-item">
  67. <div class="progress-header">
  68. <span class="progress-label invoice-label">
  69. <i class="el-icon-tickets"></i>开票
  70. </span>
  71. <span class="progress-amount" v-show="scope.row.invoiceAmount">
  72. {{ scope.row.invoiceAmount }}元
  73. </span>
  74. </div>
  75. <el-progress :text-inside="true" :stroke-width="20"
  76. :status="formatStatus(Number(scope.row.invoicePercentage))"
  77. :percentage="Number(scope.row.invoicePercentage)" text-color="#fff" class="custom-progress">
  78. </el-progress>
  79. </div>
  80. <div class="progress-item">
  81. <div class="progress-header">
  82. <span class="progress-label payment-label">
  83. <i class="el-icon-money"></i>回款
  84. </span>
  85. <span class="progress-amount" v-show="scope.row.paidAmount">
  86. {{ scope.row.paidAmount }}元
  87. </span>
  88. </div>
  89. <el-progress :text-inside="true" :stroke-width="20"
  90. :status="formatStatus(Number(scope.row.paidPercentage))" :percentage="Number(scope.row.paidPercentage)"
  91. text-color="#fff" class="custom-progress">
  92. </el-progress>
  93. </div>
  94. </div>
  95. </template>
  96. </el-table-column>
  97. <el-table-column label="拟稿人" align="center" prop="drafter" width="110px">
  98. <template slot-scope="scope">
  99. {{ getUserName(scope.row.drafter) }}
  100. </template>
  101. </el-table-column>
  102. <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  103. <template slot-scope="scope">
  104. <el-button size="mini" type="text" icon="el-icon-view" @click="handleView(scope.row)"
  105. v-hasPermi="['oa:contract:query']">查看</el-button>
  106. <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
  107. v-hasPermi="['oa:contract:edit']">修改</el-button>
  108. <el-button size="mini" type="text" icon="el-icon-edit-outline" @click="handleProgress(scope.row)"
  109. v-hasPermi="['oa:contract:paid']">开票/回款进度</el-button>
  110. </template>
  111. </el-table-column>
  112. </el-table>
  113. <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
  114. @pagination="getList" />
  115. <!-- 添加或修改cmc合同评审对话框 -->
  116. <el-dialog :title="title" :visible.sync="open" width="60%" append-to-body>
  117. <contract-edit :form="form" @cancel="open = false"></contract-edit>
  118. </el-dialog>
  119. <!-- 查看详情 -->
  120. <el-dialog :title="title" :visible.sync="openInfo" width="60%" append-to-body>
  121. <contract-form :taskForm="taskForm" :taskName="''" :flowDisabled="false"></contract-form>
  122. </el-dialog>
  123. <!-- 回款进度 -->
  124. <el-dialog :title="title" :visible.sync="progressOpen" width="50%" append-to-body>
  125. <payment-progress :form="progressContract" @cancel="progressOpen = false" @getList="getList"></payment-progress>
  126. </el-dialog>
  127. <!-- 导出对话框 -->
  128. <el-dialog :title="title" :visible.sync="exportOpen" width="50%" append-to-body>
  129. <el-form>
  130. <el-form-item label="选择导出字段名" label-width="120px">
  131. <div class="export-fields-container">
  132. <div class="field-selection-header">
  133. <el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange"
  134. class="check-all-btn">
  135. 全选
  136. </el-checkbox>
  137. </div>
  138. <el-checkbox-group v-model="selectedFields" @change="handleCheckedFieldsChange"
  139. class="field-checkbox-group">
  140. <div class="field-grid">
  141. <el-checkbox v-for="field in fieldsObj" :key="field.value" :label="field.value"
  142. class="field-checkbox-item">
  143. <span class="field-label">{{ field.label }}</span>
  144. </el-checkbox>
  145. </div>
  146. </el-checkbox-group>
  147. </div>
  148. </el-form-item>
  149. </el-form>
  150. <div slot="footer" class="dialog-footer">
  151. <el-button type="primary" @click="handleExport" :disabled="selectedFields.length === 0">导出</el-button>
  152. <el-button @click="exportOpen = false">取消</el-button>
  153. </div>
  154. </el-dialog>
  155. </div>
  156. </template>
  157. <script>
  158. import { listContract, listContractFuzzy, getContract, delContract, addContract, updateContract } from "@/api/oa/contract/contract";
  159. import { listPartyA } from "@/api/oa/partyA/partyA";
  160. import contractInfo from './contractInfo.vue';
  161. import ContractForm from '../../flowable/form/business/contractForm.vue';
  162. import { listDefinition } from "@/api/flowable/definition";
  163. import { definitionStart, flowXmlAndNode } from "@/api/flowable/definition";
  164. import { todoList, getNextFlowNodeByStart } from "@/api/flowable/todo";
  165. import { Snowflake } from '@/utils/snowFlake.js'
  166. import { listContractComment, addContractComment, updateContractComment } from "@/api/oa/contract/contractComment";
  167. import contractEdit from './components/edit.vue'
  168. import PaymentProgress from './components/paymentProgress.vue';
  169. import { listContractPaid } from "@/api/oa/contract/contractPaid";
  170. export default {
  171. components: { contractInfo, ContractForm, contractEdit, PaymentProgress },
  172. name: "Contract",
  173. data() {
  174. return {
  175. baseUrl: process.env.VUE_APP_BASE_API,
  176. // 遮罩层
  177. loading: true,
  178. // 选中数组
  179. ids: [],
  180. // 非单个禁用
  181. single: true,
  182. // 非多个禁用
  183. multiple: true,
  184. // 显示搜索条件
  185. showSearch: true,
  186. // 总条数
  187. total: 0,
  188. // cmc合同评审表格数据
  189. contractList: [],
  190. // 弹出层标题
  191. title: "",
  192. // 是否显示弹出层
  193. open: false,
  194. openInfo: false,
  195. // 查询参数
  196. queryParams: {
  197. pageNum: 1,
  198. pageSize: 10,
  199. contractNumber: null,
  200. amount: null,
  201. deposit: null,
  202. contractDocument: null,
  203. drafter: null,
  204. draftTime: null,
  205. signDate: null,
  206. signRemark: null,
  207. signScan: null,
  208. commentType: null,
  209. queryString: undefined,
  210. },
  211. // 表单参数
  212. form: {},
  213. // 表单校验
  214. rules: {
  215. },
  216. project: {},
  217. taskForm: {},
  218. commentList: [],
  219. commentOpen: false,
  220. queryPartyAList: [],
  221. queryLoading: true,
  222. progressContract: {},
  223. progressOpen: false,
  224. exportOpen: false,
  225. fieldsObj: [
  226. { label: '合同名称', value: 'contractName' },
  227. { label: '合同金额', value: 'amount' },
  228. { label: '甲方单位', value: 'partyAName' },
  229. { label: '合同编码(公司)', value: 'contractCode' },
  230. { label: '合同编号(业主)', value: 'contractNumber' },
  231. { label: '拟稿人', value: 'drafter' },
  232. { label: '拟稿日期', value: 'draftTime' },
  233. { label: '签订日期', value: 'signDate' },
  234. { label: '开票金额', value: 'invoiceAmount' },
  235. { label: '开票进度', value: 'invoicePercentage' },
  236. { label: '回款金额', value: 'paidAmount' },
  237. { label: '回款进度', value: 'paidPercentage' },
  238. ],
  239. selectedFields: [],
  240. checkAll: false,
  241. isIndeterminate: false
  242. };
  243. },
  244. created() {
  245. this.getList();
  246. },
  247. methods: {
  248. /** 查询cmc合同评审列表 */
  249. getList() {
  250. this.loading = true;
  251. if (this.queryParams.queryString == '' || this.queryParams.queryString == undefined || this.queryParams.queryString == null) {
  252. listContract(this.queryParams).then(response => {
  253. this.contractList = response.rows;
  254. this.total = response.total;
  255. this.loading = false;
  256. });
  257. }
  258. else {
  259. listContractFuzzy(this.queryParams).then(response => {
  260. this.contractList = response.rows;
  261. this.total = response.total;
  262. for (let contract of this.contractList) {
  263. listContractPaid({ contractId: contract.contractId }).then(res => {
  264. if (res.total > 0) {
  265. let percentage = res.rows.reduce((sum, item) => sum + Number(item.paidPercentage), 0);
  266. let paidAmount = res.rows.reduce((sum, item) => sum + Number(item.paidAmount), 0);
  267. this.$set(contract, 'percentage', Number(percentage.toFixed(2)))
  268. this.$set(contract, 'paidAmount', Number(paidAmount.toFixed(2)))
  269. } else {
  270. this.$set(contract, 'percentage', 0)
  271. }
  272. this.loading = false;
  273. })
  274. }
  275. });
  276. }
  277. },
  278. // 取消按钮
  279. cancel() {
  280. this.open = false;
  281. this.reset();
  282. },
  283. getCommentType(row) {
  284. let name = '';
  285. if (row == '0') {
  286. name = '无须评审'
  287. } else if (row == '1') {
  288. name = '会议评审'
  289. } else {
  290. name = '线上评审'
  291. }
  292. return name
  293. },
  294. // 表单重置
  295. reset() {
  296. this.form = {
  297. contractId: null,
  298. contractNumber: null,
  299. amount: null,
  300. deposit: null,
  301. contractDocument: null,
  302. drafter: null,
  303. draftTime: null,
  304. remark: null,
  305. signDate: null,
  306. signRemark: null,
  307. signScan: null,
  308. commentType: null
  309. };
  310. this.resetForm("form");
  311. },
  312. /** 搜索按钮操作 */
  313. handleQuery() {
  314. this.queryParams.pageNum = 1;
  315. this.getList();
  316. },
  317. /** 重置按钮操作 */
  318. resetQuery() {
  319. this.resetForm("queryForm");
  320. this.handleQuery();
  321. },
  322. // 多选框选中数据
  323. handleSelectionChange(selection) {
  324. this.ids = selection.map(item => item.contractId)
  325. this.single = selection.length !== 1
  326. this.multiple = !selection.length
  327. },
  328. /** 新增按钮操作 */
  329. handleAdd() {
  330. this.reset();
  331. this.open = true;
  332. this.title = "添加cmc合同评审";
  333. },
  334. handleView(row) {
  335. this.openInfo = true;
  336. this.title = "合同详情";
  337. this.form = row;
  338. this.$set(this.taskForm, 'formId', row.contractId)
  339. },
  340. /** 修改按钮操作 */
  341. handleUpdate(row) {
  342. const contractId = row.contractId || this.ids
  343. getContract(contractId).then(response => {
  344. this.form = response.data;
  345. this.open = true;
  346. this.title = "修改承接合同评审";
  347. listContractComment({ pageNum: 1, pageSize: 100, contractId: contractId }).then(res => {
  348. if (res.rows && res.rows.length != 0) {
  349. this.commentList = res.rows;
  350. }
  351. })
  352. });
  353. },
  354. // 回款进度操作
  355. handleProgress(row) {
  356. this.progressContract = row;
  357. this.title = '回款进度';
  358. this.progressOpen = true;
  359. },
  360. // 登记合同
  361. async handleRegister() {
  362. let response = await listDefinition({
  363. pageNum: 1,
  364. pageSize: 9999,
  365. name: "承接合同评审",
  366. category: "business",
  367. })
  368. if (response.data.total == 1) {
  369. let obj = response.data.records[0]
  370. this.$confirm("是否发起承接合同评审流程?", '提示', {
  371. confirmButtonText: '确定',
  372. cancelButtonText: '取消',
  373. type: 'warning'
  374. }).then(() => {
  375. this.handleStartProcess(obj)
  376. }).catch(() => { });
  377. }
  378. },
  379. handleStartProcess(row) {
  380. let formId = new Snowflake(1n, 1n, 0n).nextId().toString();
  381. getNextFlowNodeByStart({ deploymentId: row.deploymentId, variables: { formId: formId } }).then(res => {
  382. let data = res.data;
  383. const variables = {};
  384. const formData = {};
  385. formData.disabled = true;
  386. formData.formBtns = false;
  387. formData.formId = formId
  388. if (row.id) {
  389. variables.variables = formData;
  390. let routePath = this.getRoutePath(row);
  391. definitionStart(row.id, JSON.stringify(variables)).then(res => {
  392. this.$modal.msgSuccess(res.msg);
  393. let procInstanceId = res.data;
  394. todoList({
  395. pageNum: 1,
  396. pageSize: 99999999, processInsId: procInstanceId
  397. }).then(toDoRes => {
  398. let records = toDoRes.data.records;
  399. if (records.length == 1) {
  400. records = records[0]
  401. }
  402. this.$router.push({
  403. path: routePath,
  404. query: {
  405. procInsId: records.procInsId,
  406. executionId: records.executionId,
  407. deployId: records.deployId,
  408. taskId: records.taskId,
  409. taskName: records.taskName,
  410. startUser: records.startUserName + '-' + records.startDeptName,
  411. formId: formData.formId,
  412. procDefName: records.procDefName
  413. }
  414. })
  415. })
  416. })
  417. }
  418. })
  419. },
  420. getRoutePath(row) {
  421. let path;
  422. for (let p of this.publicData.pathRoute) {
  423. if (p.name == row.name) {
  424. path = p.path
  425. break
  426. } else {
  427. path = '/flowable/task/todo/detail/index'
  428. }
  429. }
  430. return path
  431. },
  432. /** 提交按钮 */
  433. submitForm() {
  434. this.$refs["form"].validate(valid => {
  435. if (valid) {
  436. if (this.form.contractId != null) {
  437. for (let comment of this.commentList) {
  438. updateContractComment(comment);
  439. }
  440. updateContract(this.form).then(response => {
  441. this.$modal.msgSuccess("修改成功");
  442. this.open = false;
  443. this.getList();
  444. });
  445. } else {
  446. addContract(this.form).then(response => {
  447. this.$modal.msgSuccess("新增成功");
  448. this.open = false;
  449. this.getList();
  450. });
  451. }
  452. }
  453. });
  454. },
  455. /** 导出按钮操作 */
  456. handleExport() {
  457. let selectFields = this.selectedFields.join(',');
  458. console.log(selectFields);
  459. this.download('oa/contract/exportSelectFields', {
  460. ...this.queryParams,
  461. selectFields: selectFields
  462. }, `contract_${new Date().getTime()}.xlsx`)
  463. },
  464. remoteMethod(val) {
  465. listPartyA({
  466. pageNum: 1,
  467. pageSize: 30,
  468. partyAName: val
  469. }).then(res => {
  470. this.queryPartyAList = res.rows;
  471. this.queryLoading = false;
  472. })
  473. },
  474. formatStatus(row) {
  475. if (!row) {
  476. row = 0
  477. return 'exception'
  478. }
  479. if (row <= 20) {
  480. return 'exception'
  481. } else if (row > 20 && row <= 50) {
  482. return 'warning'
  483. } else if (row > 50 && row <= 80) {
  484. return null
  485. } else {
  486. return 'success'
  487. }
  488. },
  489. // 全选处理
  490. handleCheckAllChange(val) {
  491. this.selectedFields = val ? this.fieldsObj.map(field => field.value) : [];
  492. this.isIndeterminate = false;
  493. },
  494. // 选择字段变化处理
  495. handleCheckedFieldsChange(value) {
  496. let checkedCount = value.length;
  497. this.checkAll = checkedCount === this.fieldsObj.length;
  498. this.isIndeterminate = checkedCount > 0 && checkedCount < this.fieldsObj.length;
  499. },
  500. }
  501. };
  502. </script>
  503. <style scoped>
  504. /* 进度显示样式 */
  505. .progress-container {
  506. padding: 8px 4px;
  507. }
  508. .progress-item {
  509. margin-bottom: 12px;
  510. }
  511. .progress-item:last-child {
  512. margin-bottom: 0;
  513. }
  514. .progress-header {
  515. display: flex;
  516. justify-content: space-between;
  517. align-items: center;
  518. margin-bottom: 4px;
  519. padding: 0 2px;
  520. }
  521. .progress-label {
  522. font-size: 12px;
  523. font-weight: 600;
  524. display: flex;
  525. align-items: center;
  526. gap: 4px;
  527. }
  528. .invoice-label {
  529. color: #409eff;
  530. }
  531. .payment-label {
  532. color: #67c23a;
  533. }
  534. .progress-label i {
  535. font-size: 14px;
  536. }
  537. .progress-amount {
  538. font-size: 11px;
  539. color: #909399;
  540. font-weight: 500;
  541. background: #f5f7fa;
  542. padding: 2px 6px;
  543. border-radius: 4px;
  544. border: 1px solid #e4e7ed;
  545. }
  546. .custom-progress {
  547. margin: 2px 0;
  548. }
  549. .custom-progress ::v-deep .el-progress-bar__outer {
  550. border-radius: 10px;
  551. overflow: hidden;
  552. }
  553. .custom-progress ::v-deep .el-progress-bar__inner {
  554. border-radius: 10px;
  555. transition: all 0.3s ease;
  556. }
  557. .custom-progress ::v-deep .el-progress__text {
  558. font-size: 11px !important;
  559. font-weight: 600;
  560. }
  561. .export-fields-container {
  562. padding: 10px;
  563. border: 1px solid #e4e7ed;
  564. border-radius: 4px;
  565. background-color: #fafafa;
  566. }
  567. .field-selection-header {
  568. padding-bottom: 12px;
  569. margin-bottom: 12px;
  570. border-bottom: 1px solid #e4e7ed;
  571. }
  572. .check-all-btn {
  573. font-weight: 600;
  574. color: #409eff;
  575. }
  576. .field-checkbox-group {
  577. width: 100%;
  578. }
  579. .field-grid {
  580. display: grid;
  581. grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  582. gap: 12px 16px;
  583. padding: 8px 0;
  584. }
  585. .field-checkbox-item {
  586. display: flex;
  587. align-items: center;
  588. padding: 8px 12px;
  589. border: 1px solid #dcdfe6;
  590. border-radius: 4px;
  591. background-color: #fff;
  592. transition: all 0.3s ease;
  593. cursor: pointer;
  594. }
  595. .field-checkbox-item:hover {
  596. border-color: #409eff;
  597. background-color: #f0f8ff;
  598. transform: translateY(-1px);
  599. box-shadow: 0 2px 8px rgba(64, 158, 255, 0.2);
  600. }
  601. .field-checkbox-item.is-checked {
  602. border-color: #409eff;
  603. background-color: #ecf5ff;
  604. }
  605. .field-label {
  606. margin-left: 8px;
  607. font-size: 14px;
  608. color: #606266;
  609. white-space: nowrap;
  610. overflow: hidden;
  611. text-overflow: ellipsis;
  612. }
  613. /* 禁用导出按钮时的样式 */
  614. .dialog-footer .el-button:disabled {
  615. opacity: 0.6;
  616. }
  617. /* 自定义复选框样式 */
  618. .field-checkbox-item ::v-deep .el-checkbox__input.is-checked .el-checkbox__inner {
  619. background-color: #409eff;
  620. border-color: #409eff;
  621. }
  622. .field-checkbox-item ::v-deep .el-checkbox__input:hover .el-checkbox__inner {
  623. border-color: #409eff;
  624. }
  625. /* 响应式设计 */
  626. @media (max-width: 768px) {
  627. .field-grid {
  628. grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  629. gap: 8px 12px;
  630. }
  631. .field-checkbox-item {
  632. padding: 6px 10px;
  633. }
  634. }
  635. </style>