西藏巴青项目

index.vue 33KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845
  1. <template>
  2. <div class="app-container">
  3. <el-card shadow="never">
  4. <el-form ref="queryForm" :model="queryParams" size="small" :inline="true">
  5. <el-form-item prop="statYear">
  6. <template slot="label">{{ dmT("queryStatYear") }}</template>
  7. <el-select v-model="queryParams.statYear" :placeholder="dmCommon('pleaseSelect')" clearable style="width: 120px">
  8. <el-option v-for="y in yearOptions" :key="y" :label="String(y)" :value="y" />
  9. </el-select>
  10. </el-form-item>
  11. <el-form-item prop="statMonth">
  12. <template slot="label">{{ dmT("queryStatMonth") }}</template>
  13. <el-select v-model="queryParams.statMonth" :placeholder="dmCommon('pleaseSelect')" clearable style="width: 120px">
  14. <el-option v-for="m in monthOptions" :key="'q-' + m" :label="formatStatMonth(m)" :value="m" />
  15. </el-select>
  16. </el-form-item>
  17. <el-form-item prop="townDeptId">
  18. <template slot="label">{{ dmT("queryTown") }}</template>
  19. <el-select v-model="queryParams.townDeptId" :placeholder="dmCommon('pleaseSelect')" clearable filterable style="width: 180px">
  20. <el-option v-for="item in townOptions" :key="item.deptId" :label="item.deptName" :value="item.deptId" />
  21. </el-select>
  22. </el-form-item>
  23. <el-form-item prop="villageDeptId">
  24. <template slot="label">{{ dmT("queryVillage") }}</template>
  25. <el-select
  26. v-model="queryParams.villageDeptId"
  27. :placeholder="dmT('phVillageSearch')"
  28. clearable
  29. filterable
  30. style="width: 220px"
  31. >
  32. <el-option
  33. v-for="item in villageOptions"
  34. :key="'q-v-' + item.deptId"
  35. :label="item.label"
  36. :value="item.deptId"
  37. />
  38. </el-select>
  39. </el-form-item>
  40. <el-form-item>
  41. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">{{ dmCommon("search") }}</el-button>
  42. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">{{ dmCommon("reset") }}</el-button>
  43. <el-button
  44. v-hasPermi="['dataModel:livestockOwnershipHousehold:add']"
  45. type="primary"
  46. plain
  47. icon="el-icon-plus"
  48. size="mini"
  49. @click="handleAdd"
  50. >{{ dmCommon("add") }}</el-button>
  51. <el-button
  52. v-hasPermi="['dataModel:livestockOwnershipHousehold:import']"
  53. type="info"
  54. plain
  55. icon="el-icon-upload2"
  56. size="mini"
  57. @click="handleImportOpen"
  58. >{{ dmT("btnImport") }}</el-button>
  59. <el-button
  60. v-hasPermi="['dataModel:livestockOwnershipHousehold:export']"
  61. type="warning"
  62. plain
  63. icon="el-icon-download"
  64. size="mini"
  65. @click="handleExportOpen"
  66. >{{ dmCommon("export") }}</el-button>
  67. </el-form-item>
  68. </el-form>
  69. </el-card>
  70. <br />
  71. <el-card shadow="never">
  72. <el-table v-loading="loading" :data="tableList" border>
  73. <template slot="empty">
  74. <span>{{ dmT("emptyList") }}</span>
  75. </template>
  76. <el-table-column :label="dmT('colStatYear')" prop="statYear" align="center" width="90" fixed />
  77. <el-table-column :label="dmT('colStatMonth')" align="center" width="80" fixed>
  78. <template slot-scope="scope">{{ formatStatMonth(scope.row.statMonth) }}</template>
  79. </el-table-column>
  80. <el-table-column :label="dmT('colTownName')" prop="townName" align="center" min-width="100" :show-overflow-tooltip="true" />
  81. <el-table-column :label="dmT('colVillageName')" prop="villageName" align="center" min-width="100" :show-overflow-tooltip="true" />
  82. <el-table-column :label="dmT('colWithHousehold')" align="center" width="100">
  83. <template slot-scope="scope">{{ formatCount(scope.row.withLivestockHouseholdCount) }}</template>
  84. </el-table-column>
  85. <el-table-column :label="dmT('colWithPopulation')" align="center" width="100">
  86. <template slot-scope="scope">{{ formatCount(scope.row.withLivestockPopulationCount) }}</template>
  87. </el-table-column>
  88. <el-table-column :label="dmT('colWithLabor')" align="center" width="100">
  89. <template slot-scope="scope">{{ formatCount(scope.row.withLivestockLaborCount) }}</template>
  90. </el-table-column>
  91. <el-table-column :label="dmT('colWithAnimal')" align="center" width="110">
  92. <template slot-scope="scope">{{ formatCount(scope.row.withLivestockAnimalCount) }}</template>
  93. </el-table-column>
  94. <el-table-column :label="dmT('colWithoutHousehold')" align="center" width="100">
  95. <template slot-scope="scope">{{ formatCount(scope.row.withoutLivestockHouseholdCount) }}</template>
  96. </el-table-column>
  97. <el-table-column :label="dmT('colWithoutPopulation')" align="center" width="100">
  98. <template slot-scope="scope">{{ formatCount(scope.row.withoutLivestockPopulationCount) }}</template>
  99. </el-table-column>
  100. <el-table-column :label="dmT('colWithoutLabor')" align="center" width="100">
  101. <template slot-scope="scope">{{ formatCount(scope.row.withoutLivestockLaborCount) }}</template>
  102. </el-table-column>
  103. <el-table-column :label="dmCommon('colOp')" align="center" class-name="small-padding fixed-width" width="180" fixed="right">
  104. <template slot-scope="scope">
  105. <el-button v-hasPermi="['dataModel:livestockOwnershipHousehold:query']" type="text" size="mini" @click="handleView(scope.row)">{{ dmCommon("view") }}</el-button>
  106. <el-button v-hasPermi="['dataModel:livestockOwnershipHousehold:edit']" type="text" size="mini" @click="handleEdit(scope.row)">{{ dmCommon("edit") }}</el-button>
  107. <el-button v-hasPermi="['dataModel:livestockOwnershipHousehold:remove']" type="text" size="mini" @click="handleDelete(scope.row)">{{ dmCommon("delete") }}</el-button>
  108. </template>
  109. </el-table-column>
  110. </el-table>
  111. <pagination
  112. v-show="total > 0"
  113. :total="total"
  114. :page.sync="queryParams.pageNum"
  115. :limit.sync="queryParams.pageSize"
  116. @pagination="getList"
  117. />
  118. </el-card>
  119. <el-dialog :title="dialogTitle" :visible.sync="open" width="680px" append-to-body @close="cancel">
  120. <el-form :key="formKey" ref="form" :model="form" class="loh-form" label-width="120px" size="small">
  121. <div class="loh-section-title">{{ dmT("sectionBasic") }}</div>
  122. <el-form-item prop="statYear" :rules="formRules.statYear">
  123. <template slot="label">{{ dmT("formStatYear") }}</template>
  124. <el-select v-model="form.statYear" :placeholder="dmCommon('pleaseSelect')" style="width: 100%">
  125. <el-option v-for="y in yearOptions" :key="'f-' + y" :label="String(y)" :value="y" />
  126. </el-select>
  127. </el-form-item>
  128. <el-form-item prop="statMonth" :rules="formRules.statMonth">
  129. <template slot="label">{{ dmT("formStatMonth") }}</template>
  130. <el-select v-model="form.statMonth" :placeholder="dmCommon('pleaseSelect')" style="width: 100%">
  131. <el-option v-for="m in monthOptions" :key="'fm-' + m" :label="formatStatMonth(m)" :value="m" />
  132. </el-select>
  133. </el-form-item>
  134. <el-form-item prop="villageDeptId" :rules="formRules.villageDeptId">
  135. <template slot="label">{{ dmT("formVillage") }}</template>
  136. <el-select
  137. v-model="form.villageDeptId"
  138. :placeholder="dmT('phVillageSearch')"
  139. filterable
  140. clearable
  141. style="width: 100%"
  142. >
  143. <el-option
  144. v-for="item in villageOptions"
  145. :key="'f-v-' + item.deptId"
  146. :label="item.label"
  147. :value="item.deptId"
  148. />
  149. </el-select>
  150. </el-form-item>
  151. <div class="loh-section-title">{{ dmT("sectionWith") }}</div>
  152. <el-form-item prop="withLivestockHouseholdCount" :rules="formRules.count">
  153. <template slot="label">{{ dmT("formHouseholdCount") }}</template>
  154. <div class="dm-input-with-unit">
  155. <el-input-number v-model="form.withLivestockHouseholdCount" :min="0" :precision="0" controls-position="right" class="dm-input-with-unit__input" />
  156. <span class="dm-input-with-unit__suffix">{{ dmT("unitHousehold") }}</span>
  157. </div>
  158. </el-form-item>
  159. <el-form-item prop="withLivestockPopulationCount" :rules="formRules.count">
  160. <template slot="label">{{ dmT("formPopulationCount") }}</template>
  161. <div class="dm-input-with-unit">
  162. <el-input-number v-model="form.withLivestockPopulationCount" :min="0" :precision="0" controls-position="right" class="dm-input-with-unit__input" />
  163. <span class="dm-input-with-unit__suffix">{{ dmT("unitPerson") }}</span>
  164. </div>
  165. </el-form-item>
  166. <el-form-item prop="withLivestockLaborCount" :rules="formRules.count">
  167. <template slot="label">{{ dmT("formLaborCount") }}</template>
  168. <div class="dm-input-with-unit">
  169. <el-input-number v-model="form.withLivestockLaborCount" :min="0" :precision="0" controls-position="right" class="dm-input-with-unit__input" />
  170. <span class="dm-input-with-unit__suffix">{{ dmT("unitPerson") }}</span>
  171. </div>
  172. </el-form-item>
  173. <el-form-item prop="withLivestockAnimalCount" :rules="formRules.count">
  174. <template slot="label">{{ dmT("formAnimalCount") }}</template>
  175. <div class="dm-input-with-unit">
  176. <el-input-number v-model="form.withLivestockAnimalCount" :min="0" :precision="0" controls-position="right" class="dm-input-with-unit__input" />
  177. <span class="dm-input-with-unit__suffix">{{ dmT("unitHeadPiece") }}</span>
  178. </div>
  179. </el-form-item>
  180. <div class="loh-section-title">{{ dmT("sectionWithout") }}</div>
  181. <el-form-item prop="withoutLivestockHouseholdCount" :rules="formRules.count">
  182. <template slot="label">{{ dmT("formHouseholdCount") }}</template>
  183. <div class="dm-input-with-unit">
  184. <el-input-number v-model="form.withoutLivestockHouseholdCount" :min="0" :precision="0" controls-position="right" class="dm-input-with-unit__input" />
  185. <span class="dm-input-with-unit__suffix">{{ dmT("unitHousehold") }}</span>
  186. </div>
  187. </el-form-item>
  188. <el-form-item prop="withoutLivestockPopulationCount" :rules="formRules.count">
  189. <template slot="label">{{ dmT("formPopulationCount") }}</template>
  190. <div class="dm-input-with-unit">
  191. <el-input-number v-model="form.withoutLivestockPopulationCount" :min="0" :precision="0" controls-position="right" class="dm-input-with-unit__input" />
  192. <span class="dm-input-with-unit__suffix">{{ dmT("unitPerson") }}</span>
  193. </div>
  194. </el-form-item>
  195. <el-form-item prop="withoutLivestockLaborCount" :rules="formRules.count">
  196. <template slot="label">{{ dmT("formLaborCount") }}</template>
  197. <div class="dm-input-with-unit">
  198. <el-input-number v-model="form.withoutLivestockLaborCount" :min="0" :precision="0" controls-position="right" class="dm-input-with-unit__input" />
  199. <span class="dm-input-with-unit__suffix">{{ dmT("unitPerson") }}</span>
  200. </div>
  201. </el-form-item>
  202. <el-form-item prop="remark" :rules="formRules.remark">
  203. <template slot="label">{{ dmT("formRemark") }}</template>
  204. <el-input v-model="form.remark" type="textarea" :rows="2" :placeholder="dmT('phRemark')" maxlength="500" show-word-limit />
  205. </el-form-item>
  206. </el-form>
  207. <div slot="footer" class="dialog-footer">
  208. <el-button type="primary" @click="submitForm">{{ dmCommon("ok") }}</el-button>
  209. <el-button @click="cancel">{{ dmCommon("cancel") }}</el-button>
  210. </div>
  211. </el-dialog>
  212. <el-dialog :title="dmCommon('viewTitle')" :visible.sync="viewOpen" width="680px" append-to-body>
  213. <el-form class="dm-view-form loh-form" label-width="120px" size="small">
  214. <div class="loh-section-title">{{ dmT("sectionBasic") }}</div>
  215. <el-form-item :label="dmT('formStatYear')"><span>{{ viewRow.statYear || dash }}</span></el-form-item>
  216. <el-form-item :label="dmT('formStatMonth')"><span>{{ formatStatMonth(viewRow.statMonth) }}</span></el-form-item>
  217. <el-form-item :label="dmT('formTown')"><span>{{ viewRow.townName || dash }}</span></el-form-item>
  218. <el-form-item :label="dmT('formVillage')"><span>{{ viewRow.villageName || dash }}</span></el-form-item>
  219. <div class="loh-section-title">{{ dmT("sectionWith") }}</div>
  220. <el-form-item :label="dmT('formHouseholdCount')">
  221. <span>{{ formatWithUnit(formatCount(viewRow.withLivestockHouseholdCount), "unitHousehold") }}</span>
  222. </el-form-item>
  223. <el-form-item :label="dmT('formPopulationCount')">
  224. <span>{{ formatWithUnit(formatCount(viewRow.withLivestockPopulationCount), "unitPerson") }}</span>
  225. </el-form-item>
  226. <el-form-item :label="dmT('formLaborCount')">
  227. <span>{{ formatWithUnit(formatCount(viewRow.withLivestockLaborCount), "unitPerson") }}</span>
  228. </el-form-item>
  229. <el-form-item :label="dmT('formAnimalCount')">
  230. <span>{{ formatWithUnit(formatCount(viewRow.withLivestockAnimalCount), "unitHeadPiece") }}</span>
  231. </el-form-item>
  232. <div class="loh-section-title">{{ dmT("sectionWithout") }}</div>
  233. <el-form-item :label="dmT('formHouseholdCount')">
  234. <span>{{ formatWithUnit(formatCount(viewRow.withoutLivestockHouseholdCount), "unitHousehold") }}</span>
  235. </el-form-item>
  236. <el-form-item :label="dmT('formPopulationCount')">
  237. <span>{{ formatWithUnit(formatCount(viewRow.withoutLivestockPopulationCount), "unitPerson") }}</span>
  238. </el-form-item>
  239. <el-form-item :label="dmT('formLaborCount')">
  240. <span>{{ formatWithUnit(formatCount(viewRow.withoutLivestockLaborCount), "unitPerson") }}</span>
  241. </el-form-item>
  242. <el-form-item :label="dmT('formRemark')">
  243. <span class="loh-view-text">{{ viewRow.remark || dash }}</span>
  244. </el-form-item>
  245. </el-form>
  246. <div slot="footer" class="dialog-footer">
  247. <el-button v-hasPermi="['dataModel:livestockOwnershipHousehold:edit']" type="primary" @click="handleEditFromView">{{ dmCommon("edit") }}</el-button>
  248. <el-button @click="viewOpen = false">{{ dmCommon("close") }}</el-button>
  249. </div>
  250. </el-dialog>
  251. <el-dialog :title="dmT('importTitle')" :visible.sync="importOpen" width="480px" append-to-body @close="resetImport">
  252. <el-form ref="importFormRef" :model="importForm" label-width="100px" size="small">
  253. <el-form-item prop="statYear" :rules="importRules.statYear">
  254. <template slot="label">{{ dmT("importStatYear") }}</template>
  255. <el-select v-model="importForm.statYear" :placeholder="dmT('importStatYearPh')" style="width: 100%">
  256. <el-option v-for="y in yearOptions" :key="'iy-' + y" :label="String(y)" :value="y" />
  257. </el-select>
  258. </el-form-item>
  259. <el-form-item prop="statMonth" :rules="importRules.statMonth">
  260. <template slot="label">{{ dmT("importStatMonth") }}</template>
  261. <el-select v-model="importForm.statMonth" :placeholder="dmT('importStatMonthPh')" style="width: 100%">
  262. <el-option v-for="m in monthOptions" :key="'im-' + m" :label="formatStatMonth(m)" :value="m" />
  263. </el-select>
  264. </el-form-item>
  265. <p class="loh-import-tip">{{ dmT("importTip") }}</p>
  266. <el-upload ref="importUpload" drag :limit="1" accept=".xlsx,.xls" :auto-upload="false" action="#">
  267. <i class="el-icon-upload" />
  268. <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  269. <div slot="tip" class="el-upload__tip">
  270. <el-link type="primary" :underline="false" @click="handleDownloadTemplate">{{ dmT("btnDownloadTemplate") }}</el-link>
  271. </div>
  272. </el-upload>
  273. </el-form>
  274. <div slot="footer" class="dialog-footer">
  275. <el-button type="primary" :loading="importing" @click="handleImportSubmit">{{ dmCommon("ok") }}</el-button>
  276. <el-button @click="importOpen = false">{{ dmCommon("cancel") }}</el-button>
  277. </div>
  278. </el-dialog>
  279. <el-dialog :title="dmT('exportTitle')" :visible.sync="exportOpen" width="480px" append-to-body @close="resetExport">
  280. <el-form ref="exportFormRef" :model="exportForm" label-width="100px" size="small">
  281. <el-form-item prop="statYear" :rules="exportRules.statYear">
  282. <template slot="label">{{ dmT("exportStatYear") }}</template>
  283. <el-select v-model="exportForm.statYear" :placeholder="dmT('exportStatYearPh')" style="width: 100%">
  284. <el-option v-for="y in yearOptions" :key="'ey-' + y" :label="String(y)" :value="y" />
  285. </el-select>
  286. </el-form-item>
  287. <el-form-item prop="statMonth" :rules="exportRules.statMonth">
  288. <template slot="label">{{ dmT("exportStatMonth") }}</template>
  289. <el-select v-model="exportForm.statMonth" :placeholder="dmT('exportStatMonthPh')" style="width: 100%">
  290. <el-option v-for="m in monthOptions" :key="'em-' + m" :label="formatStatMonth(m)" :value="m" />
  291. </el-select>
  292. </el-form-item>
  293. <el-form-item>
  294. <template slot="label">{{ dmT("exportTown") }}</template>
  295. <el-select
  296. v-model="exportForm.townDeptId"
  297. :placeholder="dmT('exportTownPh')"
  298. clearable
  299. filterable
  300. style="width: 100%"
  301. >
  302. <el-option v-for="item in townOptions" :key="'et-' + item.deptId" :label="item.deptName" :value="item.deptId" />
  303. </el-select>
  304. </el-form-item>
  305. </el-form>
  306. <div slot="footer" class="dialog-footer">
  307. <el-button type="primary" :loading="exporting" @click="handleExportSubmit">{{ dmCommon("ok") }}</el-button>
  308. <el-button @click="exportOpen = false">{{ dmCommon("cancel") }}</el-button>
  309. </div>
  310. </el-dialog>
  311. </div>
  312. </template>
  313. <script>
  314. import dataModelLocaleMixin from "@/mixins/dataModelLocaleMixin"
  315. import {
  316. listLivestockOwnershipHousehold,
  317. getLivestockOwnershipHousehold,
  318. addLivestockOwnershipHousehold,
  319. updateLivestockOwnershipHousehold,
  320. delLivestockOwnershipHousehold,
  321. listLivestockOwnershipHouseholdYearOptions,
  322. listLivestockOwnershipHouseholdMonthOptions,
  323. listLivestockOwnershipHouseholdTownOptions,
  324. listLivestockOwnershipHouseholdVillageTree,
  325. importLivestockOwnershipHousehold,
  326. downloadLivestockOwnershipHouseholdTemplate,
  327. exportLivestockOwnershipHousehold
  328. } from "@/api/dataModel/livestockOwnershipHousehold"
  329. import { blobValidate } from "@/utils/ruoyi"
  330. import { saveAs } from "file-saver"
  331. const COUNT_PROPS = [
  332. "withLivestockHouseholdCount",
  333. "withLivestockPopulationCount",
  334. "withLivestockLaborCount",
  335. "withLivestockAnimalCount",
  336. "withoutLivestockHouseholdCount",
  337. "withoutLivestockPopulationCount",
  338. "withoutLivestockLaborCount"
  339. ]
  340. function getCurrentYearMonth() {
  341. const now = new Date()
  342. return { statYear: now.getFullYear(), statMonth: now.getMonth() + 1 }
  343. }
  344. function createEmptyForm() {
  345. const form = {
  346. id: undefined,
  347. statYear: undefined,
  348. statMonth: undefined,
  349. villageDeptId: undefined,
  350. remark: undefined
  351. }
  352. COUNT_PROPS.forEach((prop) => {
  353. form[prop] = undefined
  354. })
  355. return form
  356. }
  357. function normalizeForm(data) {
  358. const row = Object.assign(createEmptyForm(), data || {})
  359. COUNT_PROPS.forEach((prop) => {
  360. const val = row[prop]
  361. row[prop] = val == null || val === "" ? undefined : Number(val)
  362. })
  363. return row
  364. }
  365. function flattenVillageOptions(tree) {
  366. const list = []
  367. ;(tree || []).forEach((county) => {
  368. ;(county.children || []).forEach((town) => {
  369. ;(town.children || []).forEach((village) => {
  370. if (village == null || village.id == null) {
  371. return
  372. }
  373. const townName = town.label || ""
  374. const villageName = village.label || ""
  375. list.push({
  376. deptId: village.id,
  377. label: townName ? `${townName} / ${villageName}` : villageName
  378. })
  379. })
  380. })
  381. })
  382. return list
  383. }
  384. export default {
  385. name: "LivestockOwnershipHousehold",
  386. mixins: [dataModelLocaleMixin],
  387. data() {
  388. return {
  389. dmNs: "livestockOwnershipHousehold",
  390. loading: false,
  391. importing: false,
  392. exporting: false,
  393. open: false,
  394. viewOpen: false,
  395. importOpen: false,
  396. exportOpen: false,
  397. dialogEdit: false,
  398. formKey: 0,
  399. total: 0,
  400. tableList: [],
  401. yearOptions: [],
  402. monthOptions: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
  403. townOptions: [],
  404. villageOptions: [],
  405. viewRow: {},
  406. importForm: { statYear: undefined, statMonth: undefined },
  407. exportForm: { statYear: undefined, statMonth: undefined, townDeptId: undefined },
  408. queryParams: {
  409. pageNum: 1,
  410. pageSize: 20,
  411. statYear: undefined,
  412. statMonth: undefined,
  413. townDeptId: undefined,
  414. villageDeptId: undefined
  415. },
  416. form: createEmptyForm()
  417. }
  418. },
  419. computed: {
  420. dash() {
  421. return this.$t("dataModel.status.dash")
  422. },
  423. dialogTitle() {
  424. return this.dialogEdit ? this.dmT("dialogEdit") : this.dmT("dialogAdd")
  425. },
  426. formRules() {
  427. return {
  428. statYear: [{ required: true, message: this.dmT("ruleStatYearRequired"), trigger: "change" }],
  429. statMonth: [
  430. { required: true, message: this.dmT("ruleStatMonthRequired"), trigger: "change" },
  431. { validator: this.validateFormStatMonth, trigger: "change" }
  432. ],
  433. villageDeptId: [{ required: true, message: this.dmT("ruleVillageRequired"), trigger: "change" }],
  434. count: [{ validator: this.validateOptionalCount, trigger: "change" }],
  435. remark: [{ max: 500, message: this.dmCommon("ruleLen500"), trigger: "blur" }]
  436. }
  437. },
  438. importRules() {
  439. return {
  440. statYear: [{ required: true, message: this.dmT("ruleStatYearRequired"), trigger: "change" }],
  441. statMonth: [
  442. { required: true, message: this.dmT("ruleStatMonthRequired"), trigger: "change" },
  443. { validator: this.validateImportStatMonth, trigger: "change" }
  444. ]
  445. }
  446. },
  447. exportRules() {
  448. return {
  449. statYear: [{ required: true, message: this.dmT("exportStatYearRequired"), trigger: "change" }],
  450. statMonth: [
  451. { required: true, message: this.dmT("exportStatMonthRequired"), trigger: "change" },
  452. { validator: this.validateExportStatMonth, trigger: "change" }
  453. ]
  454. }
  455. }
  456. },
  457. created() {
  458. this.loadOptions()
  459. this.getList()
  460. },
  461. methods: {
  462. loadOptions() {
  463. listLivestockOwnershipHouseholdYearOptions().then((res) => {
  464. this.yearOptions = Array.isArray(res.data) ? res.data : []
  465. })
  466. listLivestockOwnershipHouseholdMonthOptions().then((res) => {
  467. if (Array.isArray(res.data) && res.data.length) {
  468. this.monthOptions = res.data
  469. }
  470. })
  471. listLivestockOwnershipHouseholdTownOptions().then((res) => {
  472. this.townOptions = Array.isArray(res.data) ? res.data : []
  473. })
  474. this.loadVillageTree()
  475. },
  476. loadVillageTree() {
  477. return listLivestockOwnershipHouseholdVillageTree()
  478. .then((res) => {
  479. const raw = res && res.data !== undefined ? res.data : res
  480. this.villageOptions = flattenVillageOptions(Array.isArray(raw) ? raw : [])
  481. if (!this.villageOptions.length) {
  482. this.$modal.msgWarning(this.dmT("villageTreeEmpty"))
  483. }
  484. })
  485. .catch(() => {
  486. this.villageOptions = []
  487. })
  488. },
  489. formatStatMonth(month) {
  490. if (month == null || month === "") {
  491. return this.dash
  492. }
  493. return this.dmT("statMonthLabel", { month })
  494. },
  495. formatCount(val) {
  496. return val == null || val === "" ? this.dash : val
  497. },
  498. isFutureStatPeriod(statYear, statMonth) {
  499. if (statYear == null || statMonth == null) {
  500. return false
  501. }
  502. const now = new Date()
  503. const y = now.getFullYear()
  504. const m = now.getMonth() + 1
  505. return statYear > y || (statYear === y && statMonth > m)
  506. },
  507. validateFormStatMonth(rule, value, callback) {
  508. if (this.isFutureStatPeriod(this.form.statYear, value)) {
  509. callback(new Error(this.dmT("ruleStatMonthFuture")))
  510. return
  511. }
  512. callback()
  513. },
  514. validateImportStatMonth(rule, value, callback) {
  515. if (this.isFutureStatPeriod(this.importForm.statYear, value)) {
  516. callback(new Error(this.dmT("ruleStatMonthFuture")))
  517. return
  518. }
  519. callback()
  520. },
  521. validateExportStatMonth(rule, value, callback) {
  522. if (this.isFutureStatPeriod(this.exportForm.statYear, value)) {
  523. callback(new Error(this.dmT("ruleStatMonthFuture")))
  524. return
  525. }
  526. callback()
  527. },
  528. validateOptionalCount(rule, value, callback) {
  529. if (value == null || value === "") {
  530. callback()
  531. return
  532. }
  533. if (typeof value !== "number" || Number.isNaN(value) || value < 0 || !Number.isInteger(value)) {
  534. callback(new Error(this.dmT("ruleCountNonNegative")))
  535. return
  536. }
  537. callback()
  538. },
  539. buildListQuery() {
  540. const q = {
  541. pageNum: this.queryParams.pageNum,
  542. pageSize: this.queryParams.pageSize
  543. }
  544. if (this.queryParams.statYear != null) {
  545. q.statYear = this.queryParams.statYear
  546. }
  547. if (this.queryParams.statMonth != null) {
  548. q.statMonth = this.queryParams.statMonth
  549. }
  550. if (this.queryParams.townDeptId != null) {
  551. q.townDeptId = this.queryParams.townDeptId
  552. }
  553. if (this.queryParams.villageDeptId != null) {
  554. q.villageDeptId = this.queryParams.villageDeptId
  555. }
  556. return q
  557. },
  558. getList() {
  559. this.loading = true
  560. listLivestockOwnershipHousehold(this.buildListQuery())
  561. .then((res) => {
  562. this.tableList = res.rows || []
  563. this.total = res.total || 0
  564. })
  565. .finally(() => {
  566. this.loading = false
  567. })
  568. },
  569. handleQuery() {
  570. this.queryParams.pageNum = 1
  571. this.getList()
  572. },
  573. resetQuery() {
  574. this.queryParams = {
  575. pageNum: 1,
  576. pageSize: 20,
  577. statYear: undefined,
  578. statMonth: undefined,
  579. townDeptId: undefined,
  580. villageDeptId: undefined
  581. }
  582. this.getList()
  583. },
  584. handleAdd() {
  585. this.dialogEdit = false
  586. this.formKey += 1
  587. this.form = createEmptyForm()
  588. const ym = getCurrentYearMonth()
  589. this.form.statYear = ym.statYear
  590. this.form.statMonth = ym.statMonth
  591. this.open = true
  592. this.$nextTick(() => {
  593. if (this.$refs.form) {
  594. this.$refs.form.clearValidate()
  595. }
  596. })
  597. },
  598. handleEdit(row) {
  599. getLivestockOwnershipHousehold(row.id).then((res) => {
  600. this.dialogEdit = true
  601. this.formKey += 1
  602. this.form = normalizeForm(res.data)
  603. this.open = true
  604. this.viewOpen = false
  605. this.$nextTick(() => {
  606. if (this.$refs.form) {
  607. this.$refs.form.clearValidate()
  608. }
  609. })
  610. })
  611. },
  612. handleView(row) {
  613. getLivestockOwnershipHousehold(row.id).then((res) => {
  614. this.viewRow = res.data || {}
  615. this.viewOpen = true
  616. })
  617. },
  618. handleEditFromView() {
  619. if (!this.viewRow || this.viewRow.id == null) {
  620. return
  621. }
  622. this.handleEdit(this.viewRow)
  623. },
  624. handleDelete(row) {
  625. this.$modal
  626. .confirm(this.dmT("confirmDelete"))
  627. .then(() => delLivestockOwnershipHousehold(row.id))
  628. .then(() => {
  629. this.$modal.msgSuccess(this.dmCommon("msgDelOk"))
  630. this.getList()
  631. })
  632. .catch(() => {})
  633. },
  634. normalizeCount(val) {
  635. return val == null || val === "" ? null : val
  636. },
  637. buildSubmitPayload() {
  638. const payload = {
  639. id: this.form.id,
  640. statYear: this.form.statYear,
  641. statMonth: this.form.statMonth,
  642. villageDeptId: this.form.villageDeptId,
  643. remark: this.form.remark
  644. }
  645. COUNT_PROPS.forEach((prop) => {
  646. payload[prop] = this.normalizeCount(this.form[prop])
  647. })
  648. return payload
  649. },
  650. submitForm() {
  651. this.$refs.form.validate((valid) => {
  652. if (!valid) {
  653. return
  654. }
  655. const payload = this.buildSubmitPayload()
  656. if (this.dialogEdit) {
  657. updateLivestockOwnershipHousehold(payload).then(() => {
  658. this.$modal.msgSuccess(this.dmCommon("msgEditOk"))
  659. this.open = false
  660. this.getList()
  661. })
  662. } else {
  663. addLivestockOwnershipHousehold(payload).then(() => {
  664. this.$modal.msgSuccess(this.dmCommon("msgAddOk"))
  665. this.open = false
  666. this.getList()
  667. })
  668. }
  669. })
  670. },
  671. cancel() {
  672. this.open = false
  673. this.form = createEmptyForm()
  674. },
  675. handleImportOpen() {
  676. const ym = getCurrentYearMonth()
  677. this.importForm = {
  678. statYear: this.queryParams.statYear != null ? this.queryParams.statYear : ym.statYear,
  679. statMonth: this.queryParams.statMonth != null ? this.queryParams.statMonth : ym.statMonth
  680. }
  681. this.importOpen = true
  682. this.$nextTick(() => {
  683. if (this.$refs.importFormRef) {
  684. this.$refs.importFormRef.clearValidate()
  685. }
  686. if (this.$refs.importUpload) {
  687. this.$refs.importUpload.clearFiles()
  688. }
  689. })
  690. },
  691. resetImport() {
  692. this.importForm = { statYear: undefined, statMonth: undefined }
  693. if (this.$refs.importUpload) {
  694. this.$refs.importUpload.clearFiles()
  695. }
  696. },
  697. handleDownloadTemplate() {
  698. downloadLivestockOwnershipHouseholdTemplate().then(async (data) => {
  699. const isBlob = blobValidate(data)
  700. if (isBlob) {
  701. saveAs(data, `livestock_ownership_household_import_template_${new Date().getTime()}.xlsx`)
  702. } else {
  703. this.$modal.msgError(this.dmT("exportFail"))
  704. }
  705. })
  706. },
  707. handleImportSubmit() {
  708. this.$refs.importFormRef.validate((valid) => {
  709. if (!valid) {
  710. return
  711. }
  712. const files = this.$refs.importUpload ? this.$refs.importUpload.uploadFiles : []
  713. if (!files || !files.length) {
  714. this.$modal.msgError(this.dmCommon("pleaseSelect"))
  715. return
  716. }
  717. const raw = files[0].raw
  718. this.importing = true
  719. this.$modal.loading(this.dmT("importLoading"))
  720. importLivestockOwnershipHousehold(raw, this.importForm.statYear, this.importForm.statMonth)
  721. .then((res) => {
  722. const data = res.data || {}
  723. const msg = this.dmT("importSummary", {
  724. insert: data.insertCount != null ? data.insertCount : 0,
  725. update: data.updateCount != null ? data.updateCount : 0,
  726. fail: data.failCount != null ? data.failCount : 0
  727. })
  728. this.$modal.msgSuccess(msg)
  729. if (data.warnMessages && data.warnMessages.length) {
  730. this.$alert(data.warnMessages.join("<br/>"), this.dmT("importWarnTitle"), { dangerouslyUseHTMLString: true })
  731. }
  732. if (data.failMessages && data.failMessages.length) {
  733. this.$alert(data.failMessages.join("<br/>"), this.dmT("importFailTitle"), { dangerouslyUseHTMLString: true })
  734. }
  735. this.importOpen = false
  736. this.getList()
  737. })
  738. .finally(() => {
  739. this.importing = false
  740. this.$modal.closeLoading()
  741. })
  742. })
  743. },
  744. handleExportOpen() {
  745. const ym = getCurrentYearMonth()
  746. this.exportForm = {
  747. statYear: this.queryParams.statYear != null ? this.queryParams.statYear : ym.statYear,
  748. statMonth: this.queryParams.statMonth != null ? this.queryParams.statMonth : ym.statMonth,
  749. townDeptId: this.queryParams.townDeptId
  750. }
  751. this.exportOpen = true
  752. this.$nextTick(() => {
  753. if (this.$refs.exportFormRef) {
  754. this.$refs.exportFormRef.clearValidate()
  755. }
  756. })
  757. },
  758. resetExport() {
  759. this.exportForm = { statYear: undefined, statMonth: undefined, townDeptId: undefined }
  760. },
  761. handleExportSubmit() {
  762. this.$refs.exportFormRef.validate((valid) => {
  763. if (!valid) {
  764. return
  765. }
  766. this.exporting = true
  767. const filename = `${this.exportForm.statYear}年${this.exportForm.statMonth}月有无畜户数据.xlsx`
  768. this.$modal.loading(this.dmT("exportLoading"))
  769. exportLivestockOwnershipHousehold(this.exportForm.statYear, this.exportForm.statMonth, this.exportForm.townDeptId)
  770. .then(async (data) => {
  771. const isBlob = blobValidate(data)
  772. if (isBlob) {
  773. saveAs(
  774. data,
  775. filename
  776. )
  777. this.exportOpen = false
  778. } else {
  779. this.$modal.msgError(this.dmT("exportFail"))
  780. }
  781. })
  782. .finally(() => {
  783. this.exporting = false
  784. this.$modal.closeLoading()
  785. })
  786. })
  787. }
  788. }
  789. }
  790. </script>
  791. <style scoped>
  792. .loh-section-title {
  793. margin: 4px 0 12px;
  794. font-weight: 600;
  795. color: #303133;
  796. }
  797. .loh-import-tip {
  798. margin: 0 0 12px;
  799. color: #909399;
  800. font-size: 12px;
  801. line-height: 1.5;
  802. }
  803. .loh-view-text {
  804. white-space: pre-wrap;
  805. word-break: break-all;
  806. }
  807. .dm-input-with-unit {
  808. display: flex;
  809. align-items: center;
  810. width: 100%;
  811. }
  812. .dm-input-with-unit__input {
  813. flex: 1;
  814. width: 100%;
  815. }
  816. .dm-input-with-unit__suffix {
  817. margin-left: 8px;
  818. color: #909399;
  819. white-space: nowrap;
  820. }
  821. .dm-input-with-unit >>> .el-input-number {
  822. width: 100%;
  823. }
  824. </style>