index.vue 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. <template>
  2. <view> 日程id : {{ rcid }}
  3. </view>
  4. <Form :rules="fieldConfigs" v-model="formData" ref="formRef" style="height: calc(100vh - 212rpx);">
  5. <table-title>校园活动区</table-title>
  6. <up-table>
  7. <up-tr>
  8. <up-th>情况描述</up-th>
  9. <Td field="qkms">
  10. <SsInput v-model="formData.qkms" placeholder="请输入情况描述" />
  11. </Td>
  12. </up-tr>
  13. <up-tr>
  14. <up-th>处理描述</up-th>
  15. <Td field="clms">
  16. <SsInput v-model="formData.clms" placeholder="请输入处理描述" />
  17. </Td>
  18. </up-tr>
  19. <up-tr>
  20. <up-th>责任人</up-th>
  21. <Td field="zrr">
  22. <SsInput v-model="formData.zrr" placeholder="请输入责任人" />
  23. </Td>
  24. </up-tr>
  25. <up-tr>
  26. <up-th>巡查类型</up-th>
  27. <Td field="xclx">
  28. <SsSelect
  29. v-model="formData.xclx"
  30. :options="xcTypeOptions"
  31. :loading="xcTypeLoading"
  32. placeholder="请选择巡查类型"
  33. @change="onXcTypeChange"
  34. />
  35. </Td>
  36. </up-tr>
  37. <up-tr>
  38. <up-th>巡查状态</up-th>
  39. <Td field="xczt">
  40. <SsSelect
  41. v-model="formData.xczt"
  42. :options="xcStatusOptions"
  43. :loading="xcStatusLoading"
  44. :disabled="!formData.xclx"
  45. placeholder="请选择巡查状态"
  46. />
  47. </Td>
  48. </up-tr>
  49. <up-tr>
  50. <up-th>datetime</up-th>
  51. <Td field="xcDatetime">
  52. <SsDatetimePicker
  53. v-model="formData.xcDatetime"
  54. mode="datetime"
  55. placeholder="请选择巡查日期时间"
  56. />
  57. </Td>
  58. </up-tr>
  59. <up-tr>
  60. <up-th>date</up-th>
  61. <Td field="xcDate">
  62. <SsDatetimePicker
  63. v-model="formData.xcDate"
  64. mode="date"
  65. placeholder="请选择巡查日期时间"
  66. />
  67. </Td>
  68. </up-tr>
  69. <up-tr>
  70. <up-th>time</up-th>
  71. <Td field="xcTime">
  72. <SsDatetimePicker
  73. v-model="formData.xcTime"
  74. mode="time"
  75. placeholder="请选择巡查时间"
  76. />
  77. </Td>
  78. </up-tr>
  79. </up-table>
  80. </Form>
  81. <!-- 联动测试区域 -->
  82. <view class="demo-section">
  83. <text class="demo-title">联动下拉选择测试</text>
  84. <view class="demo-info">
  85. <text>当前巡查类型: {{ formData.xclx || '未选择' }}</text>
  86. <text>当前巡查状态: {{ formData.xczt || '未选择' }}</text>
  87. </view>
  88. </view>
  89. <SsBottom
  90. :buttons="bottomButtons"
  91. @button-click="handleBottomAction"
  92. />
  93. </template>
  94. <script setup>
  95. import { ref } from 'vue'
  96. import { onLoad } from '@dcloudio/uni-app'
  97. import Form from '@/components/Form/index.vue'
  98. import Td from '@/components/Td/index.vue'
  99. import SsInput from '@/components/SsInput/index.vue'
  100. import SsSelect from '@/components/SsSelect/index.vue'
  101. import TableTitle from '@/components/SsTableTitle/index.vue'
  102. import SsBottom from '@/components/SsBottom/index.vue'
  103. import SsDatetimePicker from '@/components/SsDatetimePicker/index.vue'
  104. const rcid = ref(0)
  105. // 表单数据
  106. const formData = ref({
  107. qkms: '正常',
  108. clms: '无',
  109. zrr: '无',
  110. xclx: '',
  111. xczt: '',
  112. xcDate: '', // 巡查日期
  113. xcTime: '', // 巡查时间
  114. xcDatetime: '' // 巡查日期时间
  115. })
  116. // 下拉选项数据和加载状态
  117. const xcTypeOptions = ref([])
  118. const xcStatusOptions = ref([])
  119. const xcTypeLoading = ref(false)
  120. const xcStatusLoading = ref(false)
  121. // 模拟网络请求 - 获取巡查类型
  122. const loadXcTypeOptions = async () => {
  123. xcTypeLoading.value = true
  124. try {
  125. // 模拟网络延迟
  126. await new Promise(resolve => setTimeout(resolve, 1500))
  127. xcTypeOptions.value = [
  128. { n: '日常巡查', v: 'daily' },
  129. { n: '专项巡查', v: 'special' },
  130. { n: '突击巡查', v: 'emergency' },
  131. { n: '定期巡查', v: 'regular' }
  132. ]
  133. } catch (error) {
  134. console.error('加载巡查类型失败:', error)
  135. uni.showToast({
  136. title: '加载失败',
  137. icon: 'none'
  138. })
  139. } finally {
  140. xcTypeLoading.value = false
  141. }
  142. }
  143. // 模拟网络请求 - 根据巡查类型获取状态选项
  144. const loadXcStatusOptions = async (xcType) => {
  145. xcStatusLoading.value = true
  146. xcStatusOptions.value = [] // 清空之前的选项
  147. formData.value.xczt = '' // 清空已选择的状态
  148. try {
  149. // 模拟网络延迟
  150. await new Promise(resolve => setTimeout(resolve, 1000))
  151. // 根据不同的巡查类型返回不同的状态选项
  152. const statusMap = {
  153. 'daily': [
  154. { n: '日常-待巡查', v: 'daily-pending' },
  155. { n: '日常-巡查中', v: 'daily-checking' },
  156. { n: '日常-已完成', v: 'daily-completed' }
  157. ],
  158. 'special': [
  159. { n: '专项-准备中', v: 'special-preparing' },
  160. { n: '专项-执行中', v: 'special-executing' },
  161. { n: '专项-已结束', v: 'special-finished' }
  162. ],
  163. 'emergency': [
  164. { n: '突击-紧急响应', v: 'emergency-response' },
  165. { n: '突击-处理中', v: 'emergency-handling' },
  166. { n: '突击-已处置', v: 'emergency-resolved' }
  167. ],
  168. 'regular': [
  169. { n: '定期-计划中', v: 'regular-planning' },
  170. { n: '定期-进行中', v: 'regular-ongoing' },
  171. { n: '定期-已完成', v: 'regular-completed' }
  172. ]
  173. }
  174. xcStatusOptions.value = statusMap[xcType] || []
  175. } catch (error) {
  176. console.error('加载巡查状态失败:', error)
  177. uni.showToast({
  178. title: '加载失败',
  179. icon: 'none'
  180. })
  181. } finally {
  182. xcStatusLoading.value = false
  183. }
  184. }
  185. // 巡查类型变化事件
  186. const onXcTypeChange = (value, option) => {
  187. console.log('巡查类型变化:', value, option)
  188. if (value) {
  189. loadXcStatusOptions(value)
  190. } else {
  191. xcStatusOptions.value = []
  192. formData.value.xczt = ''
  193. }
  194. }
  195. const fieldConfigs = {
  196. qkms: {
  197. rules: [{ required: true, message: '情况描述不能为空' }]
  198. },
  199. clms: {
  200. rules: [{ required: true, message: '处理描述不能为空' }]
  201. },
  202. zrr: {
  203. rules: [{ required: true, message: '责任人不能为空' }]
  204. },
  205. xclx: {
  206. rules: [{ required: true, message: '请选择巡查类型' }]
  207. },
  208. xczt: {
  209. rules: [{ required: true, message: '请选择巡查状态' }]
  210. },
  211. xcDate: {
  212. rules: [{ required: true, message: '请选择巡查日期时间' }]
  213. },
  214. xcTime: {
  215. rules: [{ required: true, message: '请选择巡查时间' }]
  216. },
  217. xcDatetime: {
  218. rules: [{ required: true, message: '请选择巡查日期时间' }]
  219. },
  220. }
  221. // 获取Form组件的引用
  222. const formRef = ref(null)
  223. // 提交状态
  224. const submitting = ref(false)
  225. // 底部按钮配置
  226. const bottomButtons = [
  227. { text: '取消', action: 'cancel' },
  228. { text: '保存并提交', action: 'submit' }
  229. ]
  230. // 底部按钮事件处理
  231. const handleBottomAction = (data) => {
  232. console.log('底部按钮操作:', data)
  233. switch(data.action) {
  234. case 'cancel':
  235. uni.navigateBack() // 返回上一页
  236. break
  237. case 'submit':
  238. handleSubmit()
  239. break
  240. }
  241. }
  242. // 原来的提交表单逻辑
  243. const handleSubmit = async () => {
  244. try {
  245. submitting.value = true
  246. // 校验所有字段 - 使用配置中的规则
  247. const validationRules = {}
  248. Object.keys(fieldConfigs).forEach(field => {
  249. validationRules[field] = fieldConfigs[field].rules
  250. })
  251. // 开始校验表单
  252. if (formRef.value && formRef.value.validateForm) {
  253. try {
  254. const isValid = formRef.value.validateForm(formData.value, validationRules)
  255. if (isValid) {
  256. // 提交成功
  257. uni.showToast({
  258. title: '提交成功',
  259. icon: 'success'
  260. })
  261. console.log('表单数据:', formData.value)
  262. } else {
  263. uni.showToast({
  264. title: '请检查表单信息',
  265. icon: 'none'
  266. })
  267. }
  268. } catch (error) {
  269. console.error('validateForm执行错误:', error)
  270. }
  271. } else {
  272. console.error('formRef或validateForm不可用')
  273. }
  274. } catch (error) {
  275. console.error('提交失败:', error)
  276. uni.showToast({
  277. title: '提交失败',
  278. icon: 'error'
  279. })
  280. } finally {
  281. submitting.value = false
  282. }
  283. }
  284. onLoad((options) => {
  285. console.log('onLoad', options)
  286. rcid.value = options.rcid
  287. // 页面加载时获取巡查类型选项
  288. loadXcTypeOptions()
  289. })
  290. </script>
  291. <style lang="scss" scoped>
  292. .demo-section {
  293. margin: 30rpx;
  294. padding: 30rpx;
  295. background: #f8f9fa;
  296. border-radius: 20rpx;
  297. border: 2rpx solid #e9ecef;
  298. }
  299. .demo-title {
  300. display: block;
  301. font-size: 32rpx;
  302. font-weight: bold;
  303. color: #333;
  304. margin-bottom: 20rpx;
  305. }
  306. .demo-info {
  307. display: flex;
  308. flex-direction: column;
  309. gap: 10rpx;
  310. }
  311. .demo-info text {
  312. font-size: 28rpx;
  313. color: #666;
  314. padding: 10rpx;
  315. background: #fff;
  316. border-radius: 10rpx;
  317. }
  318. </style>